From caec4cf6f8708c7b72ec7223ce562c2c6deae9e0 Mon Sep 17 00:00:00 2001 From: fcayre Date: Mon, 28 May 2018 17:46:32 +0200 Subject: [PATCH] [FIX] contract_payment_auto: transaction create must always get a token (#167) When a contrat had no payment token but the corresponding partner had one, the transaction was created without an acquirer, leading to an integrity error in postgres. This change makes sure the token used to test the ability to pay an invoice is passed along to the transaction creation call. Tests were also added to check the ability to use the contract token if present, but the partner's in the opposite case. This change fixes #165. --- contract_payment_auto/__manifest__.py | 2 +- .../models/account_analytic_account.py | 5 ++- .../tests/test_account_analytic_account.py | 35 +++++++++++++++++-- 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/contract_payment_auto/__manifest__.py b/contract_payment_auto/__manifest__.py index 0efcab79..01e19a74 100644 --- a/contract_payment_auto/__manifest__.py +++ b/contract_payment_auto/__manifest__.py @@ -5,7 +5,7 @@ { "name": "Contract - Auto Payment", "summary": "Adds automatic payments to contracts.", - "version": "10.0.1.0.0", + "version": "10.0.1.0.1", "category": "Contract Management", "license": "AGPL-3", "author": "LasLabs, " diff --git a/contract_payment_auto/models/account_analytic_account.py b/contract_payment_auto/models/account_analytic_account.py index dc0ec207..04a7b74b 100644 --- a/contract_payment_auto/models/account_analytic_account.py +++ b/contract_payment_auto/models/account_analytic_account.py @@ -91,7 +91,7 @@ class AccountAnalyticAccount(models.Model): return transaction = self.env['payment.transaction'].create( - self._get_tx_vals(invoice), + self._get_tx_vals(invoice, token), ) valid_states = ['authorized', 'done'] @@ -136,10 +136,9 @@ class AccountAnalyticAccount(models.Model): return @api.multi - def _get_tx_vals(self, invoice): + def _get_tx_vals(self, invoice, token): """ Return values for create of payment.transaction for invoice.""" amount_due = invoice.residual - token = self.payment_token_id partner = token.partner_id reference = self.env['payment.transaction'].get_next_reference( invoice.number, diff --git a/contract_payment_auto/tests/test_account_analytic_account.py b/contract_payment_auto/tests/test_account_analytic_account.py index 0b7768d3..55302126 100644 --- a/contract_payment_auto/tests/test_account_analytic_account.py +++ b/contract_payment_auto/tests/test_account_analytic_account.py @@ -45,6 +45,13 @@ class TestAccountAnalyticAccount(common.HttpCase): 'acquirer_id': self.acquirer.id, 'acquirer_ref': 'Test', }) + self.other_payment_token = self.env['payment.token'].create({ + 'name': 'Test Other Token', + 'partner_id': self.partner.id, + 'active': True, + 'acquirer_id': self.acquirer.id, + 'acquirer_ref': 'OtherTest', + }) self.contract = self.Model.create({ 'name': 'Test Contract', 'partner_id': self.partner.id, @@ -182,12 +189,33 @@ class TestAccountAnalyticAccount(common.HttpCase): res = self.contract._pay_invoice(invoice) self.assertIs(res, None) - def test_pay_invoice_success(self): - """ It should return True on success. """ + def assert_successful_pay_invoice(self, expected_token=None): with self._mock_transaction(s2s_side_effect=True): invoice = self._create_invoice(True) res = self.contract._pay_invoice(invoice) self.assertTrue(res) + if expected_token is not None: + Transactions = self.contract.env['payment.transaction'] + tx_vals = Transactions.create.call_args[0][0] + self.assertEqual(tx_vals.get('payment_token_id'), + expected_token.id) + + def test_pay_invoice_success(self): + """ It should return True on success. """ + self.assert_successful_pay_invoice() + + def test_pay_invoice_with_contract_token(self): + """ When contract and partner have a token, contract's is used. """ + self.partner.payment_token_id = self.other_payment_token + self.contract.payment_token_id = self.payment_token + self.assert_successful_pay_invoice(expected_token=self.payment_token) + + def test_pay_invoice_with_partner_token_success(self): + """ When contract has no related token, it should use partner's. """ + self.contract.payment_token_id = False + self.partner.payment_token_id = self.other_payment_token + self.assert_successful_pay_invoice( + expected_token=self.other_payment_token) @mute_logger(account_analytic_account.__name__) def test_pay_invoice_exception(self): @@ -243,7 +271,8 @@ class TestAccountAnalyticAccount(common.HttpCase): def test_get_tx_vals(self): """ It should return a dict. """ self.assertIsInstance( - self.contract._get_tx_vals(self._create_invoice()), + self.contract._get_tx_vals(self._create_invoice(), + self.contract.payment_token_id), dict, )