diff --git a/account_supplier_invoice_check_duplicates/README.rst b/account_supplier_invoice_check_duplicates/README.rst new file mode 100644 index 00000000..7a3ee19b --- /dev/null +++ b/account_supplier_invoice_check_duplicates/README.rst @@ -0,0 +1,29 @@ +.. image:: https://img.shields.io/badge/license-AGPL--3-blue.png + :target: https://www.gnu.org/licenses/agpl + :alt: License: AGPL-3 + +==================================== +Supplier Invoices - Check duplicates +==================================== + +This module adds logic to prevent entering two times the same supplier invoice. + +By default a duplicate is detected when there is already an open or paid invoice +with + +- same supplier +- same supplier invoice number + +In case no supplier invoice number has been encoded extra checks are added to detect duplicates : + +- same date +- same amount + +This logic can be customized via the _get_dup_domain method. + +The duplicate checking can be bypassed via the 'Force Encoding' flag. + +Known issues / Roadmap +====================== + +- Align this module with the OCA 'account_invoice_supplier_ref_unique' module. diff --git a/account_supplier_invoice_check_duplicates/__init__.py b/account_supplier_invoice_check_duplicates/__init__.py new file mode 100644 index 00000000..0650744f --- /dev/null +++ b/account_supplier_invoice_check_duplicates/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/account_supplier_invoice_check_duplicates/__manifest__.py b/account_supplier_invoice_check_duplicates/__manifest__.py new file mode 100644 index 00000000..7826761d --- /dev/null +++ b/account_supplier_invoice_check_duplicates/__manifest__.py @@ -0,0 +1,23 @@ +# Copyright 2009-2019 Noviat. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + 'name': 'Supplier Invoice - Check Duplicates', + 'version': '11.0.1.0.0', + 'category': 'Accounting & Finance', + 'website': 'https://www.noviat.com', + 'author': 'Noviat', + 'license': 'AGPL-3', + 'complexity': 'normal', + 'summary': 'Supplier Invoice - Check Duplicates', + 'data': [ + 'views/account_invoice_views.xml', + ], + 'depends': [ + 'account_supplier_invoice_number', + ], + 'excludes': [ + 'account_invoice_supplier_ref_unique', + ], + 'installable': True, +} diff --git a/account_supplier_invoice_check_duplicates/models/__init__.py b/account_supplier_invoice_check_duplicates/models/__init__.py new file mode 100644 index 00000000..8e072db8 --- /dev/null +++ b/account_supplier_invoice_check_duplicates/models/__init__.py @@ -0,0 +1 @@ +from . import account_invoice diff --git a/account_supplier_invoice_check_duplicates/models/account_invoice.py b/account_supplier_invoice_check_duplicates/models/account_invoice.py new file mode 100644 index 00000000..fdb65f69 --- /dev/null +++ b/account_supplier_invoice_check_duplicates/models/account_invoice.py @@ -0,0 +1,69 @@ +# Copyright 2009-2019 Noviat. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models, _ +from odoo.exceptions import UserError + + +class AccountInvoice(models.Model): + _inherit = 'account.invoice' + + force_encoding = fields.Boolean( + string='Force Encoding', + readonly=True, states={'draft': [('readonly', False)]}, + help="Accept the encoding of this invoice although " + "it looks like a duplicate.") + + def _check_duplicate_supplier_reference(self): + """ + Replace the standard addons _check_duplicate_supplier_reference + since this one is too restrictive (blocking) for certain use cases. + """ + for invoice in self: + if invoice.type in ('in_invoice', 'in_refund') \ + and not invoice.force_encoding: + invoice._check_si_duplicate() + + def _get_dup_domain(self): + """ + Override this method to customize customer specific + duplicate check query. + """ + return [ + ('type', '=', self.type), + ('commercial_partner_id', '=', self.commercial_partner_id.id), + ('state', 'in', ['open', 'paid']), + ('company_id', '=', self.company_id.id), + ('id', '!=', self.id)] + + def _get_dup_domain_extra(self): + """ + Extra search term to detect duplicates in case no + supplier_invoice_number has been specified. + """ + return [('date_invoice', '=', self.date_invoice), + ('amount_total', '=', self.amount_total)] + + def _get_dup(self): + """ + Override this method to customize customer specific + duplicate check logic + """ + # find duplicates by date, amount + domain = self._get_dup_domain() + # add supplier invoice number + if self.supplier_invoice_number: + dom_dups = domain + [ + ('supplier_invoice_number', 'ilike', + self.supplier_invoice_number)] + else: + dom_dups = domain + self._get_dup_domain_extra() + return self.search(dom_dups) + + def _check_si_duplicate(self): + dups = self._get_dup() + if dups: + raise UserError(_( + "This Supplier Invoice has already been encoded !" + "\nDuplicate Invoice: %s") + % ', '.join([x.number for x in dups])) diff --git a/account_supplier_invoice_check_duplicates/static/description/icon.png b/account_supplier_invoice_check_duplicates/static/description/icon.png new file mode 100644 index 00000000..32740c0c Binary files /dev/null and b/account_supplier_invoice_check_duplicates/static/description/icon.png differ diff --git a/account_supplier_invoice_check_duplicates/views/account_invoice_views.xml b/account_supplier_invoice_check_duplicates/views/account_invoice_views.xml new file mode 100644 index 00000000..77b6c3a7 --- /dev/null +++ b/account_supplier_invoice_check_duplicates/views/account_invoice_views.xml @@ -0,0 +1,15 @@ + + + + + account.invoice.supplier.form.inherit + account.invoice + + + + + + + + +