diff --git a/addons/account/models/account_payment.py b/addons/account/models/account_payment.py index e50468271b9f42084bc7e2f8b189704b04efd610..ddb9a240a5bba2d1504a7c67e8a653befb485ce8 100644 --- a/addons/account/models/account_payment.py +++ b/addons/account/models/account_payment.py @@ -132,6 +132,12 @@ class account_payment(models.Model): if payment.amount < 0: raise ValidationError(_('The payment amount cannot be negative.')) + @api.constrains('invoice_ids') + def _check_invoices(self): + for payment in self: + if any(invoice.company_id != payment.company_id for invoice in payment.invoice_ids): + raise ValidationError(_('You can only register payments for invoices in the same company')) + @api.model def _get_method_codes_using_bank_account(self): return [] @@ -206,14 +212,14 @@ class account_payment(models.Model): # context for partner_bank_account_id properly when provided with a # default partner_id. Without it, the onchange recomputes the bank account # uselessly and might assign a different value to it. - if self.partner_id and len(self.partner_id.bank_ids) > 0: - self.partner_bank_account_id = self.partner_id.bank_ids[0] - elif self.partner_id and len(self.partner_id.commercial_partner_id.bank_ids) > 0: - self.partner_bank_account_id = self.partner_id.commercial_partner_id.bank_ids[0] - else: - self.partner_bank_account_id = False + filter_company = lambda x: x.company_id is False or x.company_id == self.company_id + self.partner_bank_account_id = ( + self.partner_id.bank_ids.filtered(filter_company) + or self.partner_id.commercial_partner_id.bank_ids.filtered(filter_company) + )[:1] if self.payment_type == 'inbound' and self.invoice_ids: - partner_ids = [self.invoice_ids[0].company_id.partner_id.id, self.invoice_ids[0].company_id.partner_id.commercial_partner_id.id] + partner_ids = [self.invoice_ids[0].company_id.partner_id.id, + self.invoice_ids[0].company_id.partner_id.commercial_partner_id.id] else: partner_ids = [self.partner_id.id, self.partner_id.commercial_partner_id.id] return {'domain': {'partner_bank_account_id': [('partner_id', 'in', partner_ids)]}} diff --git a/addons/account/tests/test_payment.py b/addons/account/tests/test_payment.py index c0635f883cac8b7a3705ff82e37ca48c5d143597..21e798a6d338541aec77fc35f527e20211665c1c 100644 --- a/addons/account/tests/test_payment.py +++ b/addons/account/tests/test_payment.py @@ -44,6 +44,9 @@ class TestPayment(AccountingTestCase): self.form_payment = Form(self.env['account.payment']) + self.bank = self.env['res.bank'].create({'name': 'Test Bank'}) + + def create_invoice(self, amount=100, type='out_invoice', currency_id=None, partner=None, account_id=None): """ Returns an open invoice """ invoice = self.env['account.move'].create({ @@ -59,6 +62,19 @@ class TestPayment(AccountingTestCase): invoice.post() return invoice + def create_payment(self, partner=None, journal=None): + """ Returns a payment """ + payment = self.env['account.payment'].create({ + 'payment_date': time.strftime('%Y') + '-01-01', + 'payment_method_id': self.payment_method_manual_in.id, + 'payment_type': 'inbound', + 'partner_type': 'customer', + 'amount': 1000, + 'partner_id': partner.id or self.partner_agrolait.id, + 'journal_id': journal.id or self.bank_journal_usd, + }) + return payment + def reconcile(self, liquidity_aml, amount=0.0, amount_currency=0.0, currency_id=None): """ Reconcile a journal entry corresponding to a payment with its bank statement line """ bank_stmt = self.acc_bank_stmt_model.create({ @@ -592,3 +608,65 @@ class TestPayment(AccountingTestCase): (inv1_receivable + pay_receivable).reconcile() self.assertEquals(inv1.amount_residual, 500) self.assertEquals(inv1.amount_residual_signed, 1500) + + def trigger_onchange_partner(self, payment): + payment_form = Form(payment) + payment_form.partner_id = payment_form.partner_id + payment_form.save() + + def test_payment_onchange_partner_with_multi_company_bank_accounts(self): + """ + When registering a payment, the partner bank account shouldn't be from an other company. + The result should be that a bank account from company B is : + - not used for a payment with company A + - is used for a payment with company B + """ + company_a = self.env['res.company'].create({'name': 'Company A'}) + bank_journal_a = self.env['account.journal'].create({ + 'name': "Company's journal", + 'type': 'bank', + 'code': 'a', + 'company_id': company_a.id, + }) + company_b = self.env['res.company'].create({'name': 'Company B'}) + bank_journal_b = self.env['account.journal'].create({ + 'name': "Company's journal", + 'type': 'bank', + 'code': 'a', + 'company_id': company_b.id, + }) + + # Case 1 : partner A has a commercial partner B with a bank account from company B + partner_b = self.env['res.partner'].create({'name': 'Partner B'}) + partner_a = self.env['res.partner'].create({'name': 'Partner A'}) + bank_account_b = self.env["res.partner.bank"].create({ + "acc_number": "BE6853900754", + "bank_id": self.bank.id, + 'partner_id': partner_b.id, + "company_id": company_b.id, + }) + partner_a.commercial_partner_id = partner_b + + payment_a = self.create_payment(partner_a, bank_journal_a) + self.trigger_onchange_partner(payment_a) + self.assertFalse(payment_a.partner_bank_account_id.id) + + payment_b = self.create_payment(partner_a, bank_journal_b) + self.trigger_onchange_partner(payment_b) + self.assertEqual(payment_b.partner_bank_account_id.id, bank_account_b.id) + + # Case 2 : partner C has a bank account from company B + partner_c = self.env['res.partner'].create({'name': 'Partner C'}) + bank_account_c = self.env["res.partner.bank"].create({ + "acc_number": "BE39103123456719", + "bank_id": self.bank.id, + "partner_id": partner_c.id, + "company_id": company_b.id, + }) + payment_c = self.create_payment(partner_c, bank_journal_a) + self.trigger_onchange_partner(payment_c) + self.assertFalse(payment_c.partner_bank_account_id.id) + + payment_d = self.create_payment(partner_c, bank_journal_b) + self.trigger_onchange_partner(payment_d) + self.assertEqual(payment_d.partner_bank_account_id.id, bank_account_c.id)