[FIX] account: Prevent messing invoices when writing account_id

When writing an account from the editable groupby list view, prevent
the user to messing up the invoices by writing receivable accounts everywhere.
This commit is contained in:
Laurent Smet
2019-09-30 14:31:22 +00:00
parent 14116b3b9e
commit 790da8b463
2 changed files with 42 additions and 1 deletions
+17 -1
View File
@@ -3133,8 +3133,12 @@ class AccountMoveLine(models.Model):
PROTECTED_FIELDS_LOCK_DATE = PROTECTED_FIELDS_TAX_LOCK_DATE + ['account_id', 'journal_id', 'amount_currency', 'currency_id', 'partner_id']
PROTECTED_FIELDS_RECONCILIATION = ('account_id', 'date', 'debit', 'credit', 'amount_currency', 'currency_id')
if ('account_id' in vals) and self.env['account.account'].browse(vals['account_id']).deprecated:
account_to_write = self.env['account.account'].browse(vals['account_id']) if 'account_id' in vals else None
# Check writing a deprecated account.
if account_to_write and account_to_write.deprecated:
raise UserError(_('You cannot use a deprecated account.'))
# when making a reconciliation on an existing liquidity journal item, mark the payment as reconciled
for line in self:
if line.parent_state == 'posted':
@@ -3160,6 +3164,18 @@ class AccountMoveLine(models.Model):
if any(field_will_change(line, field_name) for field_name in PROTECTED_FIELDS_RECONCILIATION):
line._check_reconciliation()
# Check switching receivable / payable accounts.
if account_to_write:
account_type = line.account_id.user_type_id.type
if line.move_id.is_sale_document(include_receipts=True):
if (account_type == 'receivable' and account_to_write.user_type_id.type != account_type) \
or (account_type != 'receivable' and account_to_write.user_type_id.type == 'receivable'):
raise UserError(_("You can only set an account having the receivable type on payment terms lines for customer invoice."))
if line.move_id.is_purchase_document(include_receipts=True):
if (account_type == 'payable' and account_to_write.user_type_id.type != account_type) \
or (account_type != 'payable' and account_to_write.user_type_id.type == 'payable'):
raise UserError(_("You can only set an account having the payable type on payment terms lines for vendor bill."))
result = super(AccountMoveLine, self).write(vals)
for line in self:
@@ -3,6 +3,7 @@ from odoo.addons.account.tests.invoice_test_common import InvoiceTestCommon
from odoo.tests.common import Form
from odoo.tests import tagged
from odoo import fields
from odoo.exceptions import UserError
from unittest.mock import patch
@@ -1154,6 +1155,30 @@ class TestAccountMoveOutInvoiceOnchanges(InvoiceTestCommon):
'currency_id': self.currency_data['currency'].id,
})
def test_out_invoice_write_2(self):
''' Ensure to not messing the invoice when writing a bad account type. '''
move = self.env['account.move'].create({
'type': 'out_invoice',
'partner_id': self.partner_a.id,
'invoice_line_ids': [
(0, None, self.product_line_vals_1),
]
})
receivable_lines = move.line_ids.filtered(lambda line: line.account_id.user_type_id.type == 'receivable')
not_receivable_lines = move.line_ids - receivable_lines
# Write a receivable account on a not-receivable line.
with self.assertRaises(UserError), self.cr.savepoint():
not_receivable_lines.write({'account_id': receivable_lines[0].account_id.copy().id})
# Write a not-receivable account on a receivable line.
with self.assertRaises(UserError), self.cr.savepoint():
receivable_lines.write({'account_id': not_receivable_lines[0].account_id.copy().id})
# Write another receivable account on a receivable line.
receivable_lines.write({'account_id': receivable_lines[0].account_id.copy().id})
def test_out_invoice_post_1(self):
''' Check the invoice_date will be set automatically at the post date. '''
frozen_today = fields.Date.today()