diff --git a/auditlog/models/rule.py b/auditlog/models/rule.py index 0336ed3e551..32ff17c746c 100644 --- a/auditlog/models/rule.py +++ b/auditlog/models/rule.py @@ -71,10 +71,12 @@ def __enter__(self): don't swap them all out here. """ self._original_cache = self._transaction.cache - # Copy the sets of records, which are popped on recompute but do not - # copy the keys because they do not match the original field object - # afterwards. - self._original_tocompute = defaultdict(OrderedSet) + # Also swap out the list of fields to recompute. Their compute methods + # may depend on fields in the cache that are not yet flushed, and as is + # the case with account.bank.statement.line's _compute_internal_index, + # may not be resilient to some of the values (c.q. 'date') missing. + self._original_tocompute = self._transaction.tocompute + self._transaction.tocompute = defaultdict(OrderedSet) for key, value in self._transaction.tocompute.items(): self._original_tocompute[key] = OrderedSet(value) temporary_cache = api.Cache() diff --git a/test_auditlog/tests/__init__.py b/test_auditlog/tests/__init__.py index febd48f594d..9678814e1ad 100644 --- a/test_auditlog/tests/__init__.py +++ b/test_auditlog/tests/__init__.py @@ -1,2 +1,3 @@ +from . import test_account_bank_statement_line from . import test_account_move_reverse from . import test_product_tax_multicompany diff --git a/test_auditlog/tests/test_account_bank_statement_line.py b/test_auditlog/tests/test_account_bank_statement_line.py new file mode 100644 index 00000000000..01d724212de --- /dev/null +++ b/test_auditlog/tests/test_account_bank_statement_line.py @@ -0,0 +1,52 @@ +from odoo.tests import tagged + +from odoo.addons.account.tests.common import AccountTestInvoicingCommon +from odoo.addons.auditlog.tests.common import AuditLogRuleCommon + + +@tagged("post_install", "-at_install") +class TestAccountBankStatementLine(AccountTestInvoicingCommon, AuditLogRuleCommon): + def setUp(self): + super().setUp() + self.rule = self.env["auditlog.rule"].create( + { + "name": __name__, + "model_id": self.env.ref("account.model_account_move").id, + "log_read": True, + "log_create": True, + "log_write": True, + "log_unlink": True, + "log_type": "full", + } + ) + self.rule.subscribe() + + def test_create_statement_line(self): + """Statement line can be created with logging on journal entries enabled. + + Because we swap out the cache when fetching previous values during full + logging using the ThrowAwayCache, some values that are assumed by + compute methods (c.q. 'date' in account.bank.statement.line's + _compute_internal_index) might be missing. If a recompute of those fields + is inadvertently triggered when using the ThrowAwayCache, the missing + values will raise an exception (in this case: `AttributeError: 'bool' + object has no attribute 'strftime'`). This test verifies that the queued + recomputes are consistent with the values in the cache such that this + exception does not occur. + """ + partner = self.env["res.partner"].create({"name": "test"}) + stmt = self.env["account.bank.statement"].create( + {"journal_id": self.company_data["default_journal_bank"].id} + ) + line = self.env["account.bank.statement.line"].create( + { + "date": "2023-04-01", + "account_number": "NL45 TRIO 0198100000", + "amount": 5.75, + "journal_id": self.company_data["default_journal_bank"].id, + "payment_ref": "1234", + "partner_id": partner.id, + "statement_id": stmt.id, + }, + ) + line.flush_recordset()