diff --git a/modules/purchase_trade/docs/template-properties.md b/modules/purchase_trade/docs/template-properties.md index 892f657..151734e 100644 --- a/modules/purchase_trade/docs/template-properties.md +++ b/modules/purchase_trade/docs/template-properties.md @@ -319,8 +319,11 @@ Source code: `modules/purchase_trade/stock.py` Usage typique: - templates shipment relies a l'assurance +- `report_insurance_amount`: montant affiche dans `Amount insured` (priorite a + `110%` du total incoming, fallback fee `Insurance`) - `report_insurance_incoming_amount`: somme `incoming_moves` de - `quantity * unit_price` + `quantity * unit_price`, avec fallback lot + (`lot.line.unit_price * lot.get_current_quantity_converted()`) - `report_insurance_amount_insured`: `110%` de `report_insurance_incoming_amount` - base de travail pour un certificat d'assurance lie a un shipment diff --git a/modules/purchase_trade/docs/template-rules.md b/modules/purchase_trade/docs/template-rules.md index b52c904..908e03e 100644 --- a/modules/purchase_trade/docs/template-rules.md +++ b/modules/purchase_trade/docs/template-rules.md @@ -151,9 +151,14 @@ Derniere mise a jour: `2026-04-02` - Source de verite du montant assure: - sommer les montants des `incoming_moves` du shipment - montant d'un move = `move.quantity * move.unit_price` + - si `move.unit_price` est vide, fallback via lot: + `lot.line.unit_price * lot.get_current_quantity_converted()` - exposer au moins: - le montant total des incoming moves - le montant assure a `110%` de ce total + - pour le placeholder `Amount insured`, `report_insurance_amount` doit + afficher ce `110%`, avec fallback fee `Insurance` si aucun montant + incoming n'est calculable ### TR-016 - Hypotheses actuelles pour le certificat d'assurance shipment diff --git a/modules/purchase_trade/stock.py b/modules/purchase_trade/stock.py index 4efd498..352408a 100755 --- a/modules/purchase_trade/stock.py +++ b/modules/purchase_trade/stock.py @@ -491,13 +491,32 @@ class ShipmentIn(metaclass=PoolMeta): total = Decimal('0.0') currency = None for move in (self.incoming_moves or []): - quantity = Decimal(str(getattr(move, 'quantity', 0) or 0)) - unit_price = Decimal(str(getattr(move, 'unit_price', 0) or 0)) - total += (quantity * unit_price) - if not currency: - currency = getattr(move, 'currency', None) + move_amount, move_currency = self._get_report_incoming_move_amount( + move) + total += move_amount + if not currency and move_currency: + currency = move_currency return total, currency + def _get_report_incoming_move_amount(self, move): + quantity = Decimal(str(getattr(move, 'quantity', 0) or 0)) + unit_price = getattr(move, 'unit_price', None) + if unit_price not in (None, ''): + move_currency = getattr(move, 'currency', None) + return quantity * Decimal(str(unit_price or 0)), move_currency + + lot = getattr(move, 'lot', None) + line = getattr(lot, 'line', None) if lot else None + if not lot or not line: + return Decimal('0.0'), None + + lot_quantity = Decimal(str( + lot.get_current_quantity_converted() or 0)) + line_unit_price = Decimal(str(getattr(line, 'unit_price', 0) or 0)) + trade = getattr(line, 'purchase', None) + line_currency = getattr(trade, 'currency', None) if trade else None + return lot_quantity * line_unit_price, line_currency + @staticmethod def _get_report_currency_text(currency): return ( @@ -574,6 +593,13 @@ class ShipmentIn(metaclass=PoolMeta): @property def report_insurance_amount(self): + insured_amount, insured_currency = self._get_report_incoming_amount_data() + if insured_amount: + insured_amount *= Decimal('1.10') + currency_text = self._get_report_currency_text(insured_currency) + amount_text = self._format_report_amount(insured_amount) + return ' '.join(part for part in [currency_text, amount_text] if part) + fee = self._get_report_insurance_fee() if not fee: return '' diff --git a/modules/purchase_trade/tests/test_module.py b/modules/purchase_trade/tests/test_module.py index 96a5954..b32841a 100644 --- a/modules/purchase_trade/tests/test_module.py +++ b/modules/purchase_trade/tests/test_module.py @@ -509,6 +509,27 @@ class PurchaseTradeTestCase(ModuleTestCase): shipment.report_insurance_issue_place_and_date, 'GENEVA, 06-04-2026') + def test_shipment_insurance_amount_fallback_uses_lot_and_incoming_moves(self): + 'insurance amount falls back to lot unit price and shipment quantities' + ShipmentIn = Pool().get('stock.shipment.in') + shipment = ShipmentIn() + + purchase_currency = Mock(rec_name='USD') + purchase = Mock(currency=purchase_currency) + line = Mock(unit_price=Decimal('100'), purchase=purchase) + lot = Mock(line=line) + lot.get_current_quantity_converted = Mock(return_value=Decimal('5')) + move = Mock(quantity=Decimal('0'), unit_price=None, currency=None, lot=lot) + shipment.incoming_moves = [move] + shipment.fees = [] + + self.assertEqual( + shipment.report_insurance_incoming_amount, 'USD 500.00') + self.assertEqual( + shipment.report_insurance_amount_insured, 'USD 550.00') + self.assertEqual( + shipment.report_insurance_amount, 'USD 550.00') + def test_sale_report_multi_line_helpers_aggregate_all_lines(self): 'sale report helpers aggregate quantity, price lines and shipment periods' Sale = Pool().get('sale.sale')