From 04e9d7dc031cd7bab99e57e0cefa6ac383e0060a Mon Sep 17 00:00:00 2001 From: laurentbarontini Date: Thu, 23 Apr 2026 14:22:24 +0200 Subject: [PATCH] Fee FI bug --- modules/purchase_trade/fee.py | 32 ++++++++++++++------- modules/purchase_trade/tests/test_module.py | 31 ++++++++++++++++++++ 2 files changed, 53 insertions(+), 10 deletions(-) diff --git a/modules/purchase_trade/fee.py b/modules/purchase_trade/fee.py index b8da907..48bed22 100755 --- a/modules/purchase_trade/fee.py +++ b/modules/purchase_trade/fee.py @@ -317,14 +317,26 @@ class Fee(ModelSQL,ModelView): if self.product: return self.product.template.landed_cost - def get_quantity(self,name=None): - qt = self.get_fee_lots_qt() - if qt: - return qt - LotQt = Pool().get('lot.qt') - lqts = LotQt.search(['lot_shipment_in','=',self.shipment_in.id]) - if lqts: - return Decimal(lqts[0].lot_quantity) + def get_quantity(self,name=None): + qt = self.get_fee_lots_qt() + if qt: + return qt + line = self.line or self.sale_line + if line and line.lots: + return sum( + Decimal(lot.get_current_quantity_converted(0, self.unit)) + for lot in line.lots) + LotQt = Pool().get('lot.qt') + if self.shipment_in: + lqts = LotQt.search(['lot_shipment_in','=',self.shipment_in.id]) + if lqts: + return Decimal(lqts[0].lot_quantity) + + def _get_amount_quantity(self): + quantity = self.quantity + if quantity is None: + quantity = self.get_quantity() + return Decimal(quantity or 0) def get_amount(self,name=None): Date = Pool().get('ir.date') @@ -358,7 +370,7 @@ class Fee(ModelSQL,ModelView): compounding='simple' ) - return round(factor * self.line.unit_price * (self.quantity if self.quantity else 0) * sign,2) + return round(factor * self.line.unit_price * self._get_amount_quantity() * sign,2) if self.sale_line: if self.sale_line.sale.payment_term: beg_date = self.fee_date if self.fee_date else Date.today() @@ -374,7 +386,7 @@ class Fee(ModelSQL,ModelView): compounding='simple' ) logger.info("FACTOR:%s",factor) - return round(factor * self.sale_line.unit_price * (self.quantity if self.quantity else 0) * sign,2) + return round(factor * self.sale_line.unit_price * self._get_amount_quantity() * sign,2) elif self.mode == 'perqt': if self.shipment_in: diff --git a/modules/purchase_trade/tests/test_module.py b/modules/purchase_trade/tests/test_module.py index 9e1a428..1d36da8 100644 --- a/modules/purchase_trade/tests/test_module.py +++ b/modules/purchase_trade/tests/test_module.py @@ -224,6 +224,37 @@ class PurchaseTradeTestCase(ModuleTestCase): self.assertEqual(values[0]['amount'], Decimal('0')) + def test_purchase_rate_fee_amount_uses_virtual_lot_quantity(self): + 'purchase rate fee amount falls back to the purchase virtual lot quantity' + Fee = Pool().get('fee.fee') + fee = Fee() + fee.mode = 'rate' + fee.price = Decimal('12') + fee.fee_date = datetime.date(2026, 4, 23) + fee.quantity = None + fee.unit = Mock() + fee.shipment_in = None + lot = Mock() + lot.get_current_quantity_converted.return_value = Decimal('10') + fee.line = Mock( + unit_price=Decimal('100'), + lots=[lot], + estimated_date=[ + Mock( + trigger='bldate', + estimated_date=datetime.date(2026, 5, 23), + fin_int_delta=10, + ), + ], + ) + fee.sale_line = None + + with patch('trytond.modules.purchase_trade.fee.Pool') as PoolMock: + PoolMock.return_value.get.return_value = Mock( + today=Mock(return_value=datetime.date(2026, 4, 23))) + + self.assertEqual(fee.get_amount(), Decimal('13.33')) + def test_create_pnl_price_from_line_ignores_finished_matched_sale_line(self): 'purchase valuation does not add sale-side pnl when the matched sale line is finished' Valuation = Pool().get('valuation.valuation')