diff options
| -rw-r--r-- | addons/account/models/account_payment.py | 62 | ||||
| -rw-r--r-- | addons/account/tests/test_account_payment.py | 230 |
2 files changed, 208 insertions, 84 deletions
diff --git a/addons/account/models/account_payment.py b/addons/account/models/account_payment.py index 46f04073bcd..15bd9198373 100644 --- a/addons/account/models/account_payment.py +++ b/addons/account/models/account_payment.py @@ -187,23 +187,32 @@ class AccountPayment(models.Model): self.journal_id.display_name)) # Compute amounts. - write_off_amount = write_off_line_vals.get('amount', 0.0) + write_off_amount_currency = write_off_line_vals.get('amount', 0.0) if self.payment_type == 'inbound': # Receive money. - counterpart_amount = -self.amount - write_off_amount *= -1 + liquidity_amount_currency = self.amount elif self.payment_type == 'outbound': # Send money. - counterpart_amount = self.amount + liquidity_amount_currency = -self.amount + write_off_amount_currency *= -1 else: - counterpart_amount = 0.0 - write_off_amount = 0.0 + liquidity_amount_currency = write_off_amount_currency = 0.0 - balance = self.currency_id._convert(counterpart_amount, self.company_id.currency_id, self.company_id, self.date) - counterpart_amount_currency = counterpart_amount - write_off_balance = self.currency_id._convert(write_off_amount, self.company_id.currency_id, self.company_id, self.date) - write_off_amount_currency = write_off_amount + write_off_balance = self.currency_id._convert( + write_off_amount_currency, + self.company_id.currency_id, + self.company_id, + self.date, + ) + liquidity_balance = self.currency_id._convert( + liquidity_amount_currency, + self.company_id.currency_id, + self.company_id, + self.date, + ) + counterpart_amount_currency = -liquidity_amount_currency - write_off_amount_currency + counterpart_balance = -liquidity_balance - write_off_balance currency_id = self.currency_id.id if self.is_internal_transfer: @@ -236,33 +245,33 @@ class AccountPayment(models.Model): { 'name': liquidity_line_name or default_line_name, 'date_maturity': self.date, - 'amount_currency': -counterpart_amount_currency, + 'amount_currency': liquidity_amount_currency, 'currency_id': currency_id, - 'debit': balance < 0.0 and -balance or 0.0, - 'credit': balance > 0.0 and balance or 0.0, + 'debit': liquidity_balance if liquidity_balance > 0.0 else 0.0, + 'credit': -liquidity_balance if liquidity_balance < 0.0 else 0.0, 'partner_id': self.partner_id.id, - 'account_id': self.journal_id.payment_debit_account_id.id if balance < 0.0 else self.journal_id.payment_credit_account_id.id, + 'account_id': self.journal_id.payment_credit_account_id.id if liquidity_balance < 0.0 else self.journal_id.payment_debit_account_id.id, }, # Receivable / Payable. { 'name': self.payment_reference or default_line_name, 'date_maturity': self.date, - 'amount_currency': counterpart_amount_currency + write_off_amount_currency if currency_id else 0.0, + 'amount_currency': counterpart_amount_currency, 'currency_id': currency_id, - 'debit': balance + write_off_balance > 0.0 and balance + write_off_balance or 0.0, - 'credit': balance + write_off_balance < 0.0 and -balance - write_off_balance or 0.0, + 'debit': counterpart_balance if counterpart_balance > 0.0 else 0.0, + 'credit': -counterpart_balance if counterpart_balance < 0.0 else 0.0, 'partner_id': self.partner_id.id, 'account_id': self.destination_account_id.id, }, ] - if write_off_balance: + if not self.currency_id.is_zero(write_off_amount_currency): # Write-off line. line_vals_list.append({ 'name': write_off_line_vals.get('name') or default_line_name, - 'amount_currency': -write_off_amount_currency, + 'amount_currency': write_off_amount_currency, 'currency_id': currency_id, - 'debit': write_off_balance < 0.0 and -write_off_balance or 0.0, - 'credit': write_off_balance > 0.0 and write_off_balance or 0.0, + 'debit': write_off_balance if write_off_balance > 0.0 else 0.0, + 'credit': -write_off_balance if write_off_balance < 0.0 else 0.0, 'partner_id': self.partner_id.id, 'account_id': write_off_line_vals.get('account_id'), }) @@ -713,16 +722,21 @@ class AccountPayment(models.Model): # This allows to create a new payment with custom 'line_ids'. if writeoff_lines: + counterpart_amount = sum(counterpart_lines.mapped('amount_currency')) writeoff_amount = sum(writeoff_lines.mapped('amount_currency')) - counterpart_amount = counterpart_lines['amount_currency'] - if writeoff_amount > 0.0 and counterpart_amount > 0.0: + + # To be consistent with the payment_difference made in account.payment.register, + # 'writeoff_amount' needs to be signed regarding the 'amount' field before the write. + # Since the write is already done at this point, we need to base the computation on accounting values. + if (counterpart_amount > 0.0) == (writeoff_amount > 0.0): sign = -1 else: sign = 1 + writeoff_amount = abs(writeoff_amount) * sign write_off_line_vals = { 'name': writeoff_lines[0].name, - 'amount': writeoff_amount * sign, + 'amount': writeoff_amount, 'account_id': writeoff_lines[0].account_id.id, } else: diff --git a/addons/account/tests/test_account_payment.py b/addons/account/tests/test_account_payment.py index 15bb5ae81cd..b2a0df04492 100644 --- a/addons/account/tests/test_account_payment.py +++ b/addons/account/tests/test_account_payment.py @@ -324,93 +324,203 @@ class TestAccountPayment(AccountTestInvoicingCommon): }, ]) - def test_payment_move_sync_writeoff_sign(self): - copy_receivable = self.copy_account(self.company_data['default_account_receivable']) + def test_inbound_payment_sync_writeoff_debit_sign(self): + payment = self.env['account.payment'].create({ + 'amount': 100.0, + 'payment_type': 'inbound', + 'partner_type': 'customer', + }) - pay_form = Form(self.env['account.payment'].with_context(default_journal_id=self.company_data['default_journal_bank'].id)) - pay_form.amount = 50.0 - pay_form.payment_type = 'inbound' - pay_form.partner_type = 'customer' - pay_form.destination_account_id = copy_receivable - payment = pay_form.save() + # ==== Edit the account.move.line ==== - expected_payment_values = { - 'amount': 50.0, + liquidity_lines, counterpart_lines, writeoff_lines = payment._seek_for_lines() + payment.move_id.write({ + 'line_ids': [ + (1, liquidity_lines.id, {'debit': 100.0}), + (1, counterpart_lines.id, {'credit': 125.0}), + (0, 0, {'debit': 25.0, 'account_id': self.company_data['default_account_revenue'].id}), + ], + }) + + self.assertRecordValues(payment, [{ 'payment_type': 'inbound', 'partner_type': 'customer', - 'payment_reference': False, - 'is_reconciled': False, - 'currency_id': self.company_data['currency'].id, - 'partner_id': False, - 'destination_account_id': copy_receivable.id, - 'payment_method_id': self.env.ref('account.account_payment_method_manual_in').id, - } - expected_move_values = { - 'currency_id': self.company_data['currency'].id, - 'partner_id': False, - } - expected_liquidity_line = { - 'debit': 50.0, - 'credit': 0.0, - 'amount_currency': 50.0, - 'currency_id': self.company_data['currency'].id, - 'account_id': self.payment_debit_account_id.id, - } - expected_counterpart_line = { - 'debit': 0.0, - 'credit': 50.0, - 'amount_currency': -50.0, - 'currency_id': self.company_data['currency'].id, - 'account_id': self.partner_a.property_account_payable_id.id, - } + 'amount': 100.0, + }]) + + # ==== Edit the account.payment amount ==== + + payment.write({ + 'partner_type': 'supplier', + 'amount': 100.1, + 'destination_account_id': self.company_data['default_account_payable'].id, + }) + + self.assertRecordValues(payment.line_ids.sorted('balance'), [ + { + 'debit': 0.0, + 'credit': 125.1, + 'account_id': self.company_data['default_account_payable'].id, + }, + { + 'debit': 25.0, + 'credit': 0.0, + 'account_id': self.company_data['default_account_revenue'].id, + }, + { + 'debit': 100.1, + 'credit': 0.0, + 'account_id': self.payment_debit_account_id.id, + }, + ]) + + def test_inbound_payment_sync_writeoff_credit_sign(self): + payment = self.env['account.payment'].create({ + 'amount': 100.0, + 'payment_type': 'inbound', + 'partner_type': 'customer', + }) # ==== Edit the account.move.line ==== - move_form = Form(payment.move_id) - with move_form.line_ids.edit(0) as line_form: - line_form.currency_id = self.company_data['currency'] - line_form.amount_currency = 100.0 - with move_form.line_ids.edit(1) as line_form: - line_form.currency_id = self.company_data['currency'] - line_form.amount_currency = -75.0 - line_form.account_id = copy_receivable - with move_form.line_ids.new() as line_form: - line_form.currency_id = self.company_data['currency'] - line_form.amount_currency = -25.0 - line_form.account_id = self.company_data['default_account_revenue'] - move_form.save() + liquidity_lines, counterpart_lines, writeoff_lines = payment._seek_for_lines() + payment.move_id.write({ + 'line_ids': [ + (1, liquidity_lines.id, {'debit': 100.0}), + (1, counterpart_lines.id, {'credit': 75.0}), + (0, 0, {'credit': 25.0, 'account_id': self.company_data['default_account_revenue'].id}), + ], + }) self.assertRecordValues(payment, [{ - **expected_payment_values, + 'payment_type': 'inbound', + 'partner_type': 'customer', 'amount': 100.0, }]) # ==== Edit the account.payment amount ==== - pay_form = Form(payment) - pay_form.partner_type = 'supplier' - pay_form.amount = 100.1 - pay_form.partner_id = self.partner_a - payment = pay_form.save() + payment.write({ + 'partner_type': 'supplier', + 'amount': 100.1, + 'destination_account_id': self.company_data['default_account_payable'].id, + }) + self.assertRecordValues(payment.line_ids.sorted('balance'), [ { - **expected_counterpart_line, 'debit': 0.0, 'credit': 75.1, - 'amount_currency': -75.1, + 'account_id': self.company_data['default_account_payable'].id, }, { 'debit': 0.0, 'credit': 25.0, - 'amount_currency': -25.0, - 'currency_id': self.company_data['currency'].id, 'account_id': self.company_data['default_account_revenue'].id, }, { - **expected_liquidity_line, 'debit': 100.1, 'credit': 0.0, - 'amount_currency': 100.1, + 'account_id': self.payment_debit_account_id.id, + }, + ]) + + def test_outbound_payment_sync_writeoff_debit_sign(self): + payment = self.env['account.payment'].create({ + 'amount': 100.0, + 'payment_type': 'outbound', + 'partner_type': 'supplier', + }) + + # ==== Edit the account.move.line ==== + + liquidity_lines, counterpart_lines, writeoff_lines = payment._seek_for_lines() + payment.move_id.write({ + 'line_ids': [ + (1, liquidity_lines.id, {'credit': 100.0}), + (1, counterpart_lines.id, {'debit': 75.0}), + (0, 0, {'debit': 25.0, 'account_id': self.company_data['default_account_revenue'].id}), + ], + }) + + self.assertRecordValues(payment, [{ + 'payment_type': 'outbound', + 'partner_type': 'supplier', + 'amount': 100.0, + }]) + + # ==== Edit the account.payment amount ==== + + payment.write({ + 'partner_type': 'customer', + 'amount': 100.1, + 'destination_account_id': self.company_data['default_account_receivable'].id, + }) + + self.assertRecordValues(payment.line_ids.sorted('balance'), [ + { + 'debit': 0.0, + 'credit': 100.1, + 'account_id': self.payment_credit_account_id.id, + }, + { + 'debit': 25.0, + 'credit': 0.0, + 'account_id': self.company_data['default_account_revenue'].id, + }, + { + 'debit': 75.1, + 'credit': 0.0, + 'account_id': self.company_data['default_account_receivable'].id, + }, + ]) + + def test_outbound_payment_sync_writeoff_credit_sign(self): + payment = self.env['account.payment'].create({ + 'amount': 100.0, + 'payment_type': 'outbound', + 'partner_type': 'supplier', + }) + + # ==== Edit the account.move.line ==== + + liquidity_lines, counterpart_lines, writeoff_lines = payment._seek_for_lines() + payment.move_id.write({ + 'line_ids': [ + (1, liquidity_lines.id, {'credit': 100.0}), + (1, counterpart_lines.id, {'debit': 125.0}), + (0, 0, {'credit': 25.0, 'account_id': self.company_data['default_account_revenue'].id}), + ], + }) + + self.assertRecordValues(payment, [{ + 'payment_type': 'outbound', + 'partner_type': 'supplier', + 'amount': 100.0, + }]) + + # ==== Edit the account.payment amount ==== + + payment.write({ + 'partner_type': 'customer', + 'amount': 100.1, + 'destination_account_id': self.company_data['default_account_receivable'].id, + }) + + self.assertRecordValues(payment.line_ids.sorted('balance'), [ + { + 'debit': 0.0, + 'credit': 100.1, + 'account_id': self.payment_credit_account_id.id, + }, + { + 'debit': 0.0, + 'credit': 25.0, + 'account_id': self.company_data['default_account_revenue'].id, + }, + { + 'debit': 125.1, + 'credit': 0.0, + 'account_id': self.company_data['default_account_receivable'].id, }, ]) |
