diff --git a/CHANGELOG b/CHANGELOG index 2d6c1b4e03..e429f0cc80 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +* Use invoice date to enforce sequence on customer invoice * Prevent delete tax identifier used on invoice * Raise a warning when validating supplier invoice with same reference * Add support for Python 3.10 diff --git a/invoice.py b/invoice.py index 26b88779a8..aedbd35dbd 100644 --- a/invoice.py +++ b/invoice.py @@ -1083,10 +1083,10 @@ class Invoice(Workflow, ModelSQL, ModelView, TaxableMixin): with Transaction().set_context(company=company.id): today = Date.today() - def accounting_date(invoice): - return invoice.accounting_date or invoice.invoice_date or today + def invoice_date(invoice): + return invoice.invoice_date or today - grouped_invoices = sorted(grouped_invoices, key=accounting_date) + grouped_invoices = sorted(grouped_invoices, key=invoice_date) for invoice in grouped_invoices: # Posted and paid invoices are tested by check_modify so we can @@ -1106,20 +1106,14 @@ class Invoice(Workflow, ModelSQL, ModelView, TaxableMixin): invoice.invoice_date = today invoice.number, invoice.sequence = invoice.get_next_number() if invoice.type == 'out' and invoice.sequence not in sequences: - date = accounting_date(invoice) + date = invoice_date(invoice) # Do not need to lock the table # because sequence.get_id is sequential after_invoices = cls.search([ ('sequence', '=', invoice.sequence), - ['OR', - ('accounting_date', '>', date), - [ - ('accounting_date', '=', None), - ('invoice_date', '>', date), - ], - ], + ('invoice_date', '>', date), ], - limit=1, order=[('accounting_date', 'DESC')]) + limit=1, order=[('invoice_date', 'DESC')]) if after_invoices: after_invoice, = after_invoices raise InvoiceNumberError( diff --git a/message.xml b/message.xml index e96332a25a..3a74e9ea3e 100644 --- a/message.xml +++ b/message.xml @@ -22,7 +22,7 @@ this repository contains the full copyright notices and license terms. --> To post invoice "%(invoice)s", you must define a sequence on fiscal year "%(fiscalyear)s". - To number the invoice "%(invoice)s", you must set an accounting date after "%(date)s" because the sequence "%(sequence)s" has already been used for invoice "%(after_invoice)s". + To number the invoice "%(invoice)s", you must set an invoice date after "%(date)s" because the sequence "%(sequence)s" has already been used for invoice "%(after_invoice)s". You cannot modify invoice "%(invoice)s" because it is posted, paid or cancelled. diff --git a/tests/scenario_invoice_customer_sequential.rst b/tests/scenario_invoice_customer_sequential.rst index 7f8ae45649..e54579a259 100644 --- a/tests/scenario_invoice_customer_sequential.rst +++ b/tests/scenario_invoice_customer_sequential.rst @@ -53,7 +53,7 @@ Create invoice invoice second period and next year:: >>> invoice = Invoice(type='out') >>> invoice.party = party - >>> invoice.accounting_date = fiscalyear.periods[1].start_date + >>> invoice.invoice_date = fiscalyear.periods[1].start_date >>> line = invoice.lines.new() >>> line.quantity = 1 >>> line.unit_price = Decimal('10') @@ -62,7 +62,7 @@ Create invoice invoice second period and next year:: >>> invoice = Invoice(type='out') >>> invoice.party = party - >>> invoice.accounting_date = next_fiscalyear.periods[0].start_date + >>> invoice.invoice_date = next_fiscalyear.periods[0].start_date >>> line = invoice.lines.new() >>> line.quantity = 1 >>> line.unit_price = Decimal('20') @@ -73,7 +73,7 @@ Try to post invoice on first period:: >>> invoice = Invoice(type='out') >>> invoice.party = party - >>> invoice.accounting_date = fiscalyear.periods[0].start_date + >>> invoice.invoice_date = fiscalyear.periods[0].start_date >>> line = invoice.lines.new() >>> line.quantity = 1 >>> line.unit_price = Decimal('5') @@ -87,5 +87,5 @@ Try to post invoice on first period:: Post invoice on the third period:: - >>> invoice.accounting_date = fiscalyear.periods[2].start_date + >>> invoice.invoice_date = fiscalyear.periods[2].start_date >>> invoice.click('post')