From dfe4c7094b89fe07b0d85b72dd6895fdda4742e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20=C3=89vrard?= Date: Fri, 16 Aug 2013 11:33:24 +0200 Subject: [PATCH] Make statements aware of negative amounts in invoice lines review820002 --- statement.py | 46 ++++++++++++---------- tests/scenario_account_statement.rst | 59 ++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 21 deletions(-) diff --git a/statement.py b/statement.py index 7233a52264..30284cdcc6 100644 --- a/statement.py +++ b/statement.py @@ -212,27 +212,27 @@ class Statement(Workflow, ModelSQL, ModelView): invoice_id2amount_to_pay = {} for invoice in invoices: with Transaction().set_context(date=invoice.currency_date): - invoice_id2amount_to_pay[invoice.id] = ( + if invoice.type in ('out_invoice', 'in_credit_note'): + sign = -1 + else: + sign = 1 + invoice_id2amount_to_pay[invoice.id] = sign * ( Currency.compute(invoice.currency, invoice.amount_to_pay, self.journal.currency)) for line in self.lines or []: if line.invoice and line.id: amount_to_pay = invoice_id2amount_to_pay[line.invoice.id] - if abs(line.amount) > amount_to_pay: - res['lines'].setdefault('update', []) - if self.journal.currency.is_zero(amount_to_pay): - res['lines']['update'].append({ + res['lines'].setdefault('update', []) + if (not self.journal.currency.is_zero(amount_to_pay) + and (line.amount >= 0) == (amount_to_pay <= 0)): + res['lines']['update'].append({ 'id': line.id, - 'invoice': None, - }) - else: - res['lines']['update'].append({ - 'id': line.id, - 'amount': (amount_to_pay - if line.amount >= 0 - else -amount_to_pay), + 'amount': (amount_to_pay.copy_sign(line.amount) + if abs(line.amount) > abs(amount_to_pay) + else line.amount) }) + if abs(line.amount) > abs(amount_to_pay): res['lines'].setdefault('add', []) vals = {} for field_name, field in Line._fields.iteritems(): @@ -248,15 +248,19 @@ class Statement(Workflow, ModelSQL, ModelView): else: vals[field_name] = value del vals['id'] - vals['amount'] = (abs(line.amount) - - amount_to_pay) - if line.amount < 0: - vals['amount'] = - vals['amount'] + vals['amount'] = line.amount + amount_to_pay vals['invoice'] = None del vals['invoice.rec_name'] res['lines']['add'].append(vals) - invoice_id2amount_to_pay[line.invoice.id] = \ - amount_to_pay - abs(line.amount) + invoice_id2amount_to_pay[line.invoice.id] = 0 + else: + invoice_id2amount_to_pay[line.invoice.id] = ( + line.amount + amount_to_pay) + else: + res['lines']['update'].append({ + 'id': line.id, + 'invoice': None, + }) return res @classmethod @@ -477,7 +481,7 @@ class Line(ModelSQL, ModelView): amount_to_pay = Currency.compute(self.invoice.currency, self.invoice.amount_to_pay, self.statement.journal.currency) - if amount_to_pay < abs(self.amount): + if abs(amount_to_pay) < abs(self.amount): lang, = Lang.search([ ('code', '=', Transaction().language), ]) @@ -493,7 +497,7 @@ class Line(ModelSQL, ModelView): self.amount, self.statement.company.currency) reconcile_lines = self.invoice.get_reconcile_lines_for_amount( - abs(amount)) + amount) for move_line in move.lines: if move_line.account == self.invoice.account: diff --git a/tests/scenario_account_statement.rst b/tests/scenario_account_statement.rst index e272685736..6c9081a91d 100644 --- a/tests/scenario_account_statement.rst +++ b/tests/scenario_account_statement.rst @@ -303,3 +303,62 @@ Test invoice state:: >>> supplier_invoice.reload() >>> supplier_invoice.state u'paid' + +Let's test the negative amount version of the supplier/customer invoices:: + + >>> customer_invoice3 = Invoice(type='out_invoice') + >>> customer_invoice3.party = customer + >>> customer_invoice3.payment_term = payment_term + >>> invoice_line = InvoiceLine() + >>> customer_invoice3.lines.append(invoice_line) + >>> invoice_line.quantity = 1 + >>> invoice_line.unit_price = Decimal('-120') + >>> invoice_line.account = revenue + >>> invoice_line.description = 'Test' + >>> customer_invoice3.save() + >>> Invoice.post([customer_invoice3.id], config.context) + >>> customer_invoice3.state + u'posted' + + >>> supplier_invoice2 = Invoice(type='in_invoice') + >>> supplier_invoice2.party = supplier + >>> supplier_invoice2.payment_term = payment_term + >>> invoice_line = InvoiceLine() + >>> supplier_invoice2.lines.append(invoice_line) + >>> invoice_line.quantity = 1 + >>> invoice_line.unit_price = Decimal('-40') + >>> invoice_line.account = expense + >>> invoice_line.description = 'Test' + >>> supplier_invoice2.invoice_date = today + >>> supplier_invoice2.save() + >>> Invoice.post([supplier_invoice2.id], config.context) + >>> supplier_invoice2.state + u'posted' + + >>> statement = Statement(journal=statement_journal, + ... end_balance=Decimal('0'), + ... ) + + >>> statement_line = StatementLine() + >>> statement.lines.append(statement_line) + >>> statement_line.date = today + >>> statement_line.party = customer + >>> statement_line.account = receivable + >>> statement_line.amount = Decimal(-120) + >>> statement_line.invoice = customer_invoice3 + >>> statement_line.invoice.id == customer_invoice3.id + True + + >>> statement_line = StatementLine() + >>> statement.lines.append(statement_line) + >>> statement_line.date = today + >>> statement_line.party = supplier + >>> statement_line.account = payable + >>> statement_line.amount = Decimal(50) + >>> statement_line.invoice = supplier_invoice2 + >>> statement_line.amount == Decimal(40) + True + >>> len(statement.lines) + 3 + >>> statement.lines[-1].amount == 10 + 0