Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions supplier_invoice_portal/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import controllers
15 changes: 15 additions & 0 deletions supplier_invoice_portal/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
'name': "Supplier Portal",
'version': '1.0',
'author': "Dhrudeep",
'category': "Supplier Portal",
'summary': "The task is that the supplier will login with portal user and will upload PDF + XML from portal to create a draft vendor bill",
'depends': ['website', 'account'],
'data': [
'views/portal_home_inherit.xml',
'views/supplier_upload_templates.xml',
],
'license': 'LGPL-3',
'installable': True,
'application': False,
}
1 change: 1 addition & 0 deletions supplier_invoice_portal/controllers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import main
82 changes: 82 additions & 0 deletions supplier_invoice_portal/controllers/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# supplier_invoice_portal/controllers/main.py
import base64

from odoo import http
from odoo.http import request


class SupplierInvoicePortal(http.Controller):

@http.route("/my/supplier/invoice/upload", type="http", auth="user", website=True)
def supplier_invoice_upload_form(self, **kw):
# allow only portal users
if not request.env.user.has_group("base.group_portal"):
return request.redirect("/web/login")

companies = request.env.user.company_ids.sorted(lambda c: c.name)
return request.render("supplier_invoice_portal.supplier_invoice_upload_form", {
"companies": companies,
"error": kw.get("error"),
"success": kw.get("success"),
})

@http.route("/my/supplier/invoice/upload/submit", type="http", auth="user", methods=["POST"], website=True, csrf=True)
def supplier_invoice_upload_submit(self, **post):
if not request.env.user.has_group("base.group_portal"):
return request.redirect("/web/login")

company_id = int(post.get("company_id") or 0)
allowed_company_ids = request.env.user.company_ids.ids

pdf_file = request.httprequest.files.get("pdf_file")
xml_file = request.httprequest.files.get("xml_file")

pdf_name = (pdf_file.filename or "").lower()
xml_name = (xml_file.filename or "").lower()

# validations check
if not pdf_name.endswith(".pdf"):
return request.redirect("/my/supplier/invoice/upload?error=PDF+must+be+.pdf+file")

if not xml_name.endswith(".xml"):
return request.redirect("/my/supplier/invoice/upload?error=XML+must+be+.xml+file")

if not company_id or company_id not in allowed_company_ids:
return request.redirect("/my/supplier/invoice/upload?error=Invalid+company+selected")

if not pdf_file or not pdf_file.filename:
return request.redirect("/my/supplier/invoice/upload?error=Please+upload+PDF+file")

if not xml_file or not xml_file.filename:
return request.redirect("/my/supplier/invoice/upload?error=Please+upload+XML+file")

partner = request.env.user.partner_id

# Vendor Bill draft
bill = request.env["account.move"].sudo().create({
"move_type": "in_invoice",
"partner_id": partner.id,
"company_id": company_id,
})

self._create_attachment(bill, pdf_file)
self._create_attachment(bill, xml_file)

return request.redirect("/my/supplier/invoice/upload?success=Invoice+submitted+successfully")

def _create_attachment(self, bill, file_storage):
content = file_storage.read() or b""
filename = file_storage.filename

# for preview pdf
mimetype = getattr(file_storage, "mimetype",
None) or "application/octet-stream"

request.env["ir.attachment"].sudo().create({
"name": filename,
"type": "binary",
"datas": base64.b64encode(content),
"mimetype": mimetype,
"res_model": "account.move",
"res_id": bill.id,
})
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions supplier_invoice_portal/views/portal_home_inherit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<odoo>
<template id="portal_my_home_inherit_supplier_invoice" inherit_id="portal.portal_my_home" name="Portal: add Upload Vendor Invoice card">
<xpath expr="//div[contains(@class,'o_portal_docs')]" position="inside">
<t t-call="portal.portal_docs_entry">
<t t-set="icon" t-value="'/supplier_invoice_portal/static/src/image/invoice.png'"/>
<t t-set="title">Upload Vendor Invoice</t>
<t t-set="text">Upload PDF + XML to create a draft bill</t>
<t t-set="url" t-value="'/my/supplier/invoice/upload'"/>
<t t-set="config_card" t-value="True"/>
</t>
</xpath>
</template>
</odoo>
48 changes: 48 additions & 0 deletions supplier_invoice_portal/views/supplier_upload_templates.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<odoo>
<template id="supplier_invoice_upload_form" name="Supplier Invoice Upload Form">
<t t-call="portal.portal_layout">
<div class="container mt-4 mb-4">
<h3>Upload Vendor Invoice</h3>

<t t-if="error">
<div class="alert alert-danger" role="alert">
<t t-esc="error"/>
</div>
</t>
<t t-if="success">
<div class="alert alert-success" role="alert">
<t t-esc="success"/>
</div>
</t>

<form action="/my/supplier/invoice/upload/submit" method="post" enctype="multipart/form-data" class="mt-3">
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>

<div class="mb-3">
<label class="form-label">Select organization</label>
<select class="form-select" name="company_id" required="required">
<option value="">-- Select --</option>
<t t-foreach="companies" t-as="c">
<option t-att-value="c.id">
<t t-esc="c.name"/>
</option>
</t>
</select>
</div>

<div class="mb-3">
<label class="form-label">Upload PDF</label>
<input class="form-control" type="file" name="pdf_file" accept="application/pdf" required="required"/>
</div>

<div class="mb-3">
<label class="form-label">Upload XML</label>
<input class="form-control" type="file" name="xml_file" accept=".xml,application/xml,text/xml" required="required"/>
</div>

<button class="btn btn-primary" type="submit">Submit</button>
</form>
</div>
</t>
</template>
</odoo>