diff --git a/modules/purchase_trade/service.py b/modules/purchase_trade/service.py index b723172..52b420b 100644 --- a/modules/purchase_trade/service.py +++ b/modules/purchase_trade/service.py @@ -534,10 +534,13 @@ class ContractFactory: @staticmethod def _get_shipment_origin(ct): - if ct.shipment_in: - return 'stock.shipment.in,%s' % ct.shipment_in.id - if ct.shipment_internal: - return 'stock.shipment.internal,%s' % ct.shipment_internal.id - if ct.shipment_out: - return 'stock.shipment.out,%s' % ct.shipment_out.id + shipment_in = getattr(ct, 'shipment_in', None) + shipment_internal = getattr(ct, 'shipment_internal', None) + shipment_out = getattr(ct, 'shipment_out', None) + if shipment_in: + return 'stock.shipment.in,%s' % shipment_in.id + if shipment_internal: + return 'stock.shipment.internal,%s' % shipment_internal.id + if shipment_out: + return 'stock.shipment.out,%s' % shipment_out.id return None diff --git a/modules/purchase_trade/tests/test_module.py b/modules/purchase_trade/tests/test_module.py index f2d1c50..6eeaaa2 100644 --- a/modules/purchase_trade/tests/test_module.py +++ b/modules/purchase_trade/tests/test_module.py @@ -6045,6 +6045,14 @@ class PurchaseTradeTestCase(ModuleTestCase): self.assertEqual(line.from_del, '2026-05-01') self.assertEqual(line.to_del, '2026-05-31') + def test_contract_factory_shipment_origin_accepts_partial_context(self): + 'custom duplicate matched mirror can omit shipment fields' + class ContractsStartMock: + pass + + self.assertIsNone( + ContractFactory._get_shipment_origin(ContractsStartMock())) + def test_lot_matching_rejects_purchase_quantity_above_available(self): 'apply matching cannot consume more than available purchase quantity' class LotQtMock: