diff --git a/modules/purchase_trade/fee.py b/modules/purchase_trade/fee.py index 8557467..0e30740 100755 --- a/modules/purchase_trade/fee.py +++ b/modules/purchase_trade/fee.py @@ -846,11 +846,46 @@ class Fee(ModelSQL,ModelView): @classmethod def delete(cls, fees): purchase_lines, sale_lines = cls._collect_pnl_lines(fees=fees) + purchases = cls._get_generated_purchases_to_delete(fees) super().delete(fees) + if purchases: + Purchase = Pool().get('purchase.purchase') + Purchase.delete(purchases) cls._regenerate_fee_pnl_for_lines(purchase_lines, sale_lines) + @classmethod + def _get_generated_purchases_to_delete(cls, fees): + purchases = [] + seen = set() + for fee in fees: + purchase = getattr(fee, 'purchase', None) + if not cls._is_generated_purchase_for_fee(fee, purchase): + continue + purchase_id = getattr(purchase, 'id', id(purchase)) + if purchase_id in seen: + continue + seen.add(purchase_id) + purchases.append(purchase) + return purchases + + @staticmethod + def _is_generated_purchase_for_fee(fee, purchase): + if getattr(fee, 'type', None) != 'ordered' or not purchase: + return False + if getattr(purchase, 'line_type', 'service') != 'service': + return False + lines = list(getattr(purchase, 'lines', []) or []) + if not lines: + return False + fee_id = getattr(fee, 'id', fee) + for line in lines: + line_fee = getattr(line, 'fee_', None) + if getattr(line_fee, 'id', line_fee) != fee_id: + return False + return True + def _get_account_move_fee(self,lot,in_out='in',amt = None): - pool = Pool() + pool = Pool() AccountMove = pool.get('account.move') Date = pool.get('ir.date') Period = pool.get('account.period') diff --git a/modules/purchase_trade/purchase.py b/modules/purchase_trade/purchase.py index 2e28d2b..9d39500 100755 --- a/modules/purchase_trade/purchase.py +++ b/modules/purchase_trade/purchase.py @@ -315,7 +315,7 @@ class Purchase(metaclass=PoolMeta): fields.Boolean("Visible"), 'on_change_with_company_visible') lc_date = fields.Date("LC date") product_origin = fields.Char( - "Origin", states={'invisible': Eval('company_visible'),}) + "Origin", states={'invisible': ~Eval('company_visible'),}) @fields.depends('company', '_parent_company.party') def on_change_with_company_visible(self, name=None): diff --git a/modules/purchase_trade/sale.py b/modules/purchase_trade/sale.py index 8048ee4..9ec5768 100755 --- a/modules/purchase_trade/sale.py +++ b/modules/purchase_trade/sale.py @@ -279,7 +279,7 @@ class Sale(metaclass=PoolMeta): fields.Boolean("Visible"), 'on_change_with_company_visible') lc_date = fields.Date("LC date") product_origin = fields.Char( - "Origin", states={'invisible': Eval('company_visible'),}) + "Origin", states={'invisible': ~Eval('company_visible'),}) @fields.depends('company', '_parent_company.party') def on_change_with_company_visible(self, name=None): diff --git a/modules/purchase_trade/tests/test_module.py b/modules/purchase_trade/tests/test_module.py index 3dfc417..bfe28c7 100644 --- a/modules/purchase_trade/tests/test_module.py +++ b/modules/purchase_trade/tests/test_module.py @@ -2655,6 +2655,38 @@ class PurchaseTradeTestCase(ModuleTestCase): {'label': 'FREIGHT value in EUR', 'amount': Decimal('25')}, ]) + def test_fee_delete_detects_generated_ordered_purchase(self): + 'ordered fee deletion targets only its generated service purchase' + Fee = Pool().get('fee.fee') + + fee = Fee() + fee.id = 10 + fee.type = 'ordered' + purchase = Mock( + id=20, + line_type='service', + lines=[Mock(fee_=fee)]) + fee.purchase = purchase + + self.assertEqual( + Fee._get_generated_purchases_to_delete([fee]), + [purchase]) + + def test_fee_delete_ignores_unrelated_purchase(self): + 'ordered fee deletion does not delete purchases with unrelated lines' + Fee = Pool().get('fee.fee') + + fee = Fee() + fee.id = 10 + fee.type = 'ordered' + purchase = Mock( + id=20, + line_type='service', + lines=[Mock(fee_=Mock(id=99))]) + fee.purchase = purchase + + self.assertEqual(Fee._get_generated_purchases_to_delete([fee]), []) + def test_sale_report_converts_mixed_units_for_total_and_words(self): 'sale report totals prefer the virtual lot unit as common unit' Sale = Pool().get('sale.sale')