diff --git a/addons/account/i18n/account.pot b/addons/account/i18n/account.pot index 7268a73d031..f3f1112580a 100644 --- a/addons/account/i18n/account.pot +++ b/addons/account/i18n/account.pot @@ -12382,6 +12382,12 @@ msgstr "" msgid "You cannot delete an entry which has been posted once." msgstr "" +#. module: account +#: code:addons/account/models/account_move.py:0 +#, python-format +msgid "You cannot delete an item linked to a posted entry." +msgstr "" + #. module: account #: code:addons/account/models/res_config_settings.py:0 #, python-format diff --git a/addons/account/models/account_bank_statement.py b/addons/account/models/account_bank_statement.py index f500d32886b..dc45bbbd247 100644 --- a/addons/account/models/account_bank_statement.py +++ b/addons/account/models/account_bank_statement.py @@ -1187,7 +1187,7 @@ class AccountBankStatementLine(models.Model): to_delete_commands = [(2, line.id) for line in suspense_lines + other_lines] # Cleanup previous lines. - self.move_id.with_context(check_move_validity=False, skip_account_move_synchronization=True).write({ + self.move_id.with_context(check_move_validity=False, skip_account_move_synchronization=True, force_delete=True).write({ 'line_ids': to_delete_commands + to_create_commands, 'to_check': to_check, }) @@ -1232,7 +1232,7 @@ class AccountBankStatementLine(models.Model): self.payment_ids.unlink() for st_line in self: - st_line.write({ + st_line.with_context(force_delete=True).write({ 'to_check': False, 'line_ids': [(5, 0)] + [(0, 0, line_vals) for line_vals in st_line._prepare_move_line_default_vals()], }) diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py index 630e29e4427..ab23a2678c9 100644 --- a/addons/account/models/account_move.py +++ b/addons/account/models/account_move.py @@ -3771,6 +3771,10 @@ class AccountMoveLine(models.Model): def unlink(self): moves = self.mapped('move_id') + # Prevent deleting lines on posted entries + if not self.env.context.get('force_delete', False) and any(m.state == 'posted' for m in moves): + raise UserError(_('You cannot delete an item linked to a posted entry.')) + # Check the lines are not reconciled (partially or not). self._check_reconciliation() diff --git a/addons/account/tests/test_account_move_entry.py b/addons/account/tests/test_account_move_entry.py index 68100eb6589..554ad39fec1 100644 --- a/addons/account/tests/test_account_move_entry.py +++ b/addons/account/tests/test_account_move_entry.py @@ -498,6 +498,7 @@ class TestAccountMove(AccountTestInvoicingCommon): copies[4].name = 'XMISC/2019/10005' copies[5].name = 'XMISC/2019/10006' + copies[4].button_draft() copies[4].with_context(force_delete=True).unlink() copies[5].button_draft() @@ -661,3 +662,13 @@ class TestAccountMove(AccountTestInvoicingCommon): {'name': 'included_tax_line', 'debit': 200.0, 'credit': 0.0, 'tax_ids': [], 'tax_line_id': self.included_percent_tax.id}, {'name': 'credit_line_1', 'debit': 0.0, 'credit': 1200.0, 'tax_ids': [], 'tax_line_id': False}, ]) + + def test_misc_prevent_unlink_posted_items(self): + # You cannot remove journal items if the related journal entry is posted. + self.test_move.action_post() + with self.assertRaises(UserError), self.cr.savepoint(): + self.test_move.line_ids.unlink() + + # You can remove journal items if the related journal entry is draft. + self.test_move.button_draft() + self.test_move.line_ids.unlink()