diff --git a/account_cutoff_accrual_order_base/models/order_line_mixin.py b/account_cutoff_accrual_order_base/models/order_line_mixin.py index 56be1261662..132fa21ac9a 100644 --- a/account_cutoff_accrual_order_base/models/order_line_mixin.py +++ b/account_cutoff_accrual_order_base/models/order_line_mixin.py @@ -17,8 +17,18 @@ class OrderLineCutoffAccrualMixin(models.AbstractModel): is_cutoff_accrual_excluded = fields.Boolean( string="Do not generate cut-off entries", readonly=True, + inverse=lambda r: r._inverse_is_cutoff_accrual_excluded(), ) + def _inverse_is_cutoff_accrual_excluded(self): + for rec in self: + if rec.is_cutoff_accrual_excluded: + rec.account_cutoff_line_ids.filtered( + lambda line: line.parent_id.state != "done" + ).unlink() + else: + rec._update_cutoff_accrual() + def _get_cutoff_accrual_partner(self): self.ensure_one() return self.order_id.partner_id @@ -262,15 +272,3 @@ def _update_cutoff_accrual(self, date=False): values.append(data) if values: self.env["account.cutoff.line"].create(values) - - def write(self, vals): - res = super().write(vals) - if "is_cutoff_accrual_excluded" in vals: - if vals["is_cutoff_accrual_excluded"]: - self.account_cutoff_line_ids.filtered( - lambda line: line.parent_id.state != "done" - ).unlink() - else: - for rec in self: - rec._update_cutoff_accrual() - return res diff --git a/account_cutoff_accrual_purchase/models/purchase_order_line.py b/account_cutoff_accrual_purchase/models/purchase_order_line.py index 0513c677765..63e2b52b5e7 100644 --- a/account_cutoff_accrual_purchase/models/purchase_order_line.py +++ b/account_cutoff_accrual_purchase/models/purchase_order_line.py @@ -19,6 +19,16 @@ class PurchaseOrderLine(models.Model): readonly=True, ) + is_cutoff_accrual_excluded = fields.Boolean( + compute="_compute_is_cutoff_accrual_excluded", + store=True, + ) + + @api.depends("order_id.force_invoiced") + def _compute_is_cutoff_accrual_excluded(self): + for rec in self: + rec.is_cutoff_accrual_excluded = rec.order_id.force_invoiced + def _get_cutoff_accrual_lines_domain(self): domain = super()._get_cutoff_accrual_lines_domain() domain.append(("order_id.state", "in", ("purchase", "done"))) diff --git a/account_cutoff_accrual_sale/models/sale_order.py b/account_cutoff_accrual_sale/models/sale_order.py index e061782ee21..f597c58d437 100644 --- a/account_cutoff_accrual_sale/models/sale_order.py +++ b/account_cutoff_accrual_sale/models/sale_order.py @@ -9,6 +9,7 @@ class SaleOrder(models.Model): def write(self, vals): res = super().write(vals) + # Force inverse trigger on sale.order.line is_cutoff_accrual_excluded if "force_invoiced" in vals: self.order_line.is_cutoff_accrual_excluded = vals["force_invoiced"] return res diff --git a/account_cutoff_accrual_sale/models/sale_order_line.py b/account_cutoff_accrual_sale/models/sale_order_line.py index 66f1664929f..2d379090f53 100644 --- a/account_cutoff_accrual_sale/models/sale_order_line.py +++ b/account_cutoff_accrual_sale/models/sale_order_line.py @@ -19,6 +19,16 @@ class SaleOrderLine(models.Model): readonly=True, ) + is_cutoff_accrual_excluded = fields.Boolean( + compute="_compute_is_cutoff_accrual_excluded", + store=True, + ) + + @api.depends("order_id.force_invoiced") + def _compute_is_cutoff_accrual_excluded(self): + for rec in self: + rec.is_cutoff_accrual_excluded = rec.order_id.force_invoiced + def _get_cutoff_accrual_partner(self): return self.order_id.partner_invoice_id diff --git a/account_cutoff_accrual_sale/tests/test_cutoff_revenue.py b/account_cutoff_accrual_sale/tests/test_cutoff_revenue.py index eee88e48fda..9d62ed93ccb 100644 --- a/account_cutoff_accrual_sale/tests/test_cutoff_revenue.py +++ b/account_cutoff_accrual_sale/tests/test_cutoff_revenue.py @@ -3,6 +3,8 @@ from datetime import timedelta +from odoo import Command + from .common import TestAccountCutoffAccrualSaleCommon @@ -279,3 +281,26 @@ def test_accrued_revenue_on_so_force_invoiced_before_but_posted(self): # Remove Force invoiced, lines should be created self.so.force_invoiced = False self.assertEqual(len(cutoff.line_ids), 0, "no cutoff line should be generated") + + def test_accrued_revenue_on_so_force_invoiced_line_added(self): + """Test cutoff when SO is force invoiced and line is added""" + cutoff = self.revenue_cutoff + self.so.action_confirm() + self.so.force_invoiced = True + p = self.env.ref("product.expense_product") + self.so.order_line = [ + Command.create( + { + "name": p.name, + "product_id": p.id, + "product_uom_qty": 1, + "product_uom": p.uom_id.id, + "price_unit": self.price, + "tax_id": [Command.set(self.tax_sale.ids)], + }, + ) + ] + cutoff.get_lines() + self.assertEqual(len(cutoff.line_ids), 0, "0 cutoff line should be found") + for sol in self.so.order_line: + self.assertEqual(sol.is_cutoff_accrual_excluded, True)