diff --git a/modules/purchase_trade/lot.py b/modules/purchase_trade/lot.py
index 9035662..939dc14 100755
--- a/modules/purchase_trade/lot.py
+++ b/modules/purchase_trade/lot.py
@@ -1210,8 +1210,8 @@ class Lot(metaclass=PoolMeta):
# super().write(*args)
# lots = sum(args[::2], [])
-class LotQt(
- ModelSQL, ModelView):
+class LotQt(
+ ModelSQL, ModelView):
"Lots Qt"
__name__ = 'lot.qt'
@@ -1356,6 +1356,72 @@ class LotQt(
or self.lot_shipment_out
or self.lot_shipment_internal)
+ @classmethod
+ def link_to_transport(cls, source, quantity, shipment_origin):
+ quantity = abs(Decimal(str(quantity or 0))).quantize(
+ Decimal("0.00001"))
+ available = abs(Decimal(str(source.lot_quantity or 0))).quantize(
+ Decimal("0.00001"))
+ if not quantity or quantity > available:
+ raise UserError("Quantity to link exceeds available quantity.")
+
+ shipment_model, shipment_id = str(shipment_origin).split(',', 1)
+ shipment_field = {
+ 'stock.shipment.in': 'lot_shipment_in',
+ 'stock.shipment.out': 'lot_shipment_out',
+ 'stock.shipment.internal': 'lot_shipment_internal',
+ }.get(shipment_model)
+ if not shipment_field:
+ raise UserError("Shipment type is not supported.")
+ shipment_id = int(shipment_id)
+ signed_quantity = quantity
+ if Decimal(str(source.lot_quantity or 0)) < 0:
+ signed_quantity = -quantity
+
+ if source.is_planned_transport():
+ values = cls._split_plan_values(
+ source, signed_quantity, {
+ 'planned_from_location': cls._record_id(
+ source.planned_from_location),
+ 'planned_to_location': cls._record_id(
+ source.planned_to_location),
+ 'planned_transport_type': source.planned_transport_type,
+ 'planned_from_date': source.planned_from_date,
+ 'planned_to_date': source.planned_to_date,
+ 'planned_note': source.planned_note,
+ })
+ values[shipment_field] = shipment_id
+ linked, = cls.create([values])
+ source.lot_quantity -= signed_quantity
+ if abs(source.lot_quantity) < Decimal("0.00001"):
+ source.lot_quantity = 0
+ cls.save([source])
+ return linked
+
+ plan_lot = source.lot_p or source.lot_s
+ plan_mode = 'both' if source.lot_p else 'only sale'
+ if not plan_lot.updateVirtualPart(
+ signed_quantity, shipment_origin,
+ source.lot_s, plan_mode):
+ plan_lot.createVirtualPart(
+ signed_quantity, shipment_origin,
+ source.lot_s, plan_mode)
+ plan_lot.updateVirtualPart(
+ -signed_quantity, None, source.lot_s, plan_mode)
+ domain = [
+ ('lot_p', '=', source.lot_p),
+ ('lot_s', '=', source.lot_s),
+ (shipment_field, '=', shipment_id),
+ ]
+ linked = cls.search(domain)
+ if not linked:
+ raise UserError("The linked transport quantity was not created.")
+ return linked[0]
+
+ @staticmethod
+ def _record_id(record):
+ return record.id if record else None
+
@classmethod
def _split_plan_values(cls, source, quantity, values):
return {
@@ -3302,7 +3368,7 @@ class LotContext(ModelView):
return super().get_context(fields_names=fields_names)
-class LotShipping(Wizard):
+class LotShipping(Wizard):
"Link lot to transport"
__name__ = "lot.shipping"
@@ -3325,14 +3391,20 @@ class LotShipping(Wizard):
def default_ship(self, fields):
values = {}
planned_from_locations = {
- record.r_planned_from_location.id
+ location.id
for record in self.records
- if record.r_planned_from_location
+ for location in [
+ record.r_planned_from_location
+ or getattr(record.r_purchase, 'from_location', None)]
+ if location
}
planned_to_locations = {
- record.r_planned_to_location.id
+ location.id
for record in self.records
- if record.r_planned_to_location
+ for location in [
+ record.r_planned_to_location
+ or getattr(record.r_purchase, 'to_location', None)]
+ if location
}
if len(planned_from_locations) == 1:
values['planned_from_location'] = next(iter(
@@ -3368,6 +3440,12 @@ class LotShipping(Wizard):
values['from_location'] = self.ship.planned_from_location.id
if self.ship.planned_to_location:
values['to_location'] = self.ship.planned_to_location.id
+ bl_number = getattr(self.ship, 'shipment_bl_number', None)
+ bl_date = getattr(self.ship, 'shipment_bl_date', None)
+ if bl_number:
+ values['bl_number'] = bl_number
+ if bl_date:
+ values['bl_date'] = bl_date
return values
def _create_shipment_in(self):
@@ -3375,34 +3453,6 @@ class LotShipping(Wizard):
shipment, = ShipmentIn.create([self._shipment_in_create_values()])
self.ship.shipment_in = shipment
- def _scheduled_lotqt_values(self, lqt, quantity):
- values = {
- 'lot_p': self._record_id(lqt.lot_p),
- 'lot_s': self._record_id(lqt.lot_s),
- 'lot_quantity': quantity,
- 'lot_unit': self._record_id(lqt.lot_unit),
- 'lot_av': lqt.lot_av,
- 'lot_status': lqt.lot_status,
- 'lot_visible': lqt.lot_visible,
- 'planned_from_location': self._record_id(
- lqt.planned_from_location),
- 'planned_to_location': self._record_id(lqt.planned_to_location),
- 'planned_transport_type': lqt.planned_transport_type,
- 'planned_from_date': lqt.planned_from_date,
- 'planned_to_date': lqt.planned_to_date,
- 'planned_note': lqt.planned_note,
- }
- if self.ship.shipment == 'in':
- values['lot_shipment_in'] = self.ship.shipment_in.id
- elif self.ship.shipment == 'out':
- values['lot_shipment_out'] = self.ship.shipment_out.id
- elif self.ship.shipment == 'int':
- values['lot_shipment_internal'] = self.ship.shipment_internal.id
- return values
-
- def _create_scheduled_lotqt(self, LotQt, lqt, quantity):
- LotQt.create([self._scheduled_lotqt_values(lqt, quantity)])
-
def transition_shipping(self):
Lot = Pool().get('lot.lot')
LotQt = Pool().get('lot.qt')
@@ -3478,41 +3528,8 @@ class LotShipping(Wizard):
affected_lines.append(l.sale_line)
else:
lqt = LotQt(r.id - 10000000)
- available_to_ship = abs(Decimal(str(
- lqt.lot_quantity or 0)))
- if shipped_quantity > available_to_ship:
- raise UserError(
- "Quantity to link exceeds available quantity.")
- plan_lot = lqt.lot_p
- plan_mode = 'both'
- if not plan_lot:
- plan_lot = lqt.lot_s
- plan_mode = 'only sale'
- signed_shipped_quantity = shipped_quantity
- if Decimal(str(lqt.lot_quantity or 0)) < 0:
- signed_shipped_quantity = -shipped_quantity
- #Increase forecasted virtual part shipped
- if lqt.is_planned_transport():
- self._create_scheduled_lotqt(
- LotQt, lqt, signed_shipped_quantity)
- else:
- if not plan_lot.updateVirtualPart(
- signed_shipped_quantity, shipment_origin,
- lqt.lot_s, plan_mode):
- logger.info("LotShipping2:%s", shipped_quantity)
- plan_lot.createVirtualPart(
- signed_shipped_quantity, shipment_origin,
- lqt.lot_s, plan_mode)
- #Decrease forecasted virtual part non shipped
- if lqt.is_planned_transport():
- lqt.lot_quantity -= signed_shipped_quantity
- if abs(lqt.lot_quantity) < Decimal("0.00001"):
- lqt.lot_quantity = 0
- LotQt.save([lqt])
- else:
- plan_lot.updateVirtualPart(
- -signed_shipped_quantity, None,
- lqt.lot_s, plan_mode)
+ LotQt.link_to_transport(
+ lqt, shipped_quantity, shipment_origin)
if lqt.lot_p and lqt.lot_p.line:
affected_lines.append(lqt.lot_p.line)
if lqt.lot_s and lqt.lot_s.sale_line:
@@ -4261,7 +4278,7 @@ class LotUnship(Wizard):
def end(self):
return 'reload'
-class LotAdding(Wizard):
+class LotAdding(Wizard):
"Adding physical lots"
__name__ = "lot.add"
@@ -4295,14 +4312,11 @@ class LotAdding(Wizard):
lqt = LotQt(i - 10000000)
if not lqt.lot_p:
raise UserError("To add physical lot to sale, use action 'Apply matching'!")
- if not lqt.has_shipment():
- raise UserError(
- "Please link the quantity to transport before adding "
- "physical lots.")
lot = lqt.lot_p
+ purchase = lot.line.purchase
unit = lot.lot_unit_line.id
- quantity = lqt.lot_quantity
- sh_in = lqt.lot_shipment_in.id if lqt.lot_shipment_in else None
+ quantity = lqt.lot_quantity
+ sh_in = lqt.lot_shipment_in.id if lqt.lot_shipment_in else None
sh_int = lqt.lot_shipment_internal.id if lqt.lot_shipment_internal else None
sh_out = lqt.lot_shipment_out.id if lqt.lot_shipment_out else None
else:
@@ -4314,12 +4328,58 @@ class LotAdding(Wizard):
'shipment_in':sh_in,
'shipment_internal':sh_int,
'shipment_out':sh_out,
+ 'transport_missing': not any((sh_in, sh_int, sh_out)),
+ 'shipment_supplier': (
+ purchase.party.id
+ if not any((sh_in, sh_int, sh_out)) and purchase.party
+ else None),
+ 'transport_from_location': (
+ (lqt.planned_from_location or purchase.from_location).id
+ if not any((sh_in, sh_int, sh_out))
+ and (lqt.planned_from_location or purchase.from_location)
+ else None),
+ 'transport_to_location': (
+ (lqt.planned_to_location or purchase.to_location).id
+ if not any((sh_in, sh_int, sh_out))
+ and (lqt.planned_to_location or purchase.to_location)
+ else None),
}
- def transition_adding(self):
+ def transition_adding(self):
if self.records:
LotQt = Pool().get('lot.qt')
lqt = LotQt(self.records[0].id - 10000000)
+ if not lqt.has_shipment():
+ shipment = self.add.shipment_in
+ if self.add.create_new_shipment and shipment:
+ raise UserError(
+ "Choose either an existing shipment or create a new "
+ "shipment.")
+ if self.add.create_new_shipment:
+ if not self.add.shipment_supplier:
+ raise UserError("Shipment supplier is required.")
+ ShipmentIn = Pool().get('stock.shipment.in')
+ values = {
+ 'supplier': self.add.shipment_supplier.id,
+ }
+ if self.add.transport_from_location:
+ values['from_location'] = (
+ self.add.transport_from_location.id)
+ if self.add.transport_to_location:
+ values['to_location'] = self.add.transport_to_location.id
+ if self.add.shipment_bl_number:
+ values['bl_number'] = self.add.shipment_bl_number
+ if self.add.shipment_bl_date:
+ values['bl_date'] = self.add.shipment_bl_date
+ shipment, = ShipmentIn.create([values])
+ if not shipment:
+ raise UserError(
+ "Select a Shipment In or create a new shipment.")
+ Lot = Pool().get('lot.lot')
+ with Lot.skip_quantity_consistency():
+ lqt = LotQt.link_to_transport(
+ lqt, abs(Decimal(str(lqt.lot_quantity or 0))),
+ 'stock.shipment.in,%s' % shipment.id)
LotQt.add_physical_lots(
lqt, self.add.lots, self.add.unlink_remainder)
return 'end'
@@ -4327,13 +4387,44 @@ class LotAdding(Wizard):
def end(self):
return 'reload'
-class LotAddLot(ModelView):
+class LotAddLot(ModelView):
"Add physical lots"
__name__ = "lot.add.lot"
unit = fields.Many2One('product.uom',"Unit",readonly=True)
quantity = fields.Numeric("Quantity available",digits='unit',readonly=True)
unlink_remainder = fields.Boolean("Unlink remaining quantity")
- shipment_in = fields.Many2One('stock.shipment.in',"Shipment In",states={'invisible': ~Eval('shipment_in')})
+ transport_missing = fields.Boolean("Transport missing", readonly=True)
+ create_new_shipment = fields.Boolean(
+ "Create a new shipment",
+ states={'invisible': ~Eval('transport_missing')})
+ shipment_supplier = fields.Many2One(
+ 'party.party', "Shipment supplier",
+ states={
+ 'invisible': ~(
+ Eval('transport_missing') & Eval('create_new_shipment')),
+ 'required': (
+ Eval('transport_missing') & Eval('create_new_shipment')),
+ })
+ transport_from_location = fields.Many2One(
+ 'stock.location', "From location", readonly=True,
+ states={'invisible': ~Eval('transport_missing')})
+ transport_to_location = fields.Many2One(
+ 'stock.location', "To location", readonly=True,
+ states={'invisible': ~Eval('transport_missing')})
+ shipment_bl_number = fields.Char(
+ "BL number",
+ states={'invisible': ~(
+ Eval('transport_missing') & Eval('create_new_shipment'))})
+ shipment_bl_date = fields.Date(
+ "BL date",
+ states={'invisible': ~(
+ Eval('transport_missing') & Eval('create_new_shipment'))})
+ shipment_in = fields.Many2One(
+ 'stock.shipment.in', "Shipment In",
+ states={
+ 'invisible': ~Eval('transport_missing') & ~Eval('shipment_in'),
+ 'readonly': ~Eval('transport_missing'),
+ })
shipment_internal = fields.Many2One('stock.shipment.internal',"Shipment Internal",states={'invisible': ~Eval('shipment_internal')})
shipment_out = fields.Many2One('stock.shipment.out',"Shipment Out",states={'invisible': ~Eval('shipment_out')})
lots = fields.One2Many('lot.add.line','lal',"Lots")
@@ -4341,6 +4432,10 @@ class LotAddLot(ModelView):
@classmethod
def default_unlink_remainder(cls):
return True
+
+ @classmethod
+ def default_create_new_shipment(cls):
+ return False
class LotAddLine(ModelView):
"Lots"
diff --git a/modules/purchase_trade/stock.py b/modules/purchase_trade/stock.py
index e7eb5bd..38b6afe 100755
--- a/modules/purchase_trade/stock.py
+++ b/modules/purchase_trade/stock.py
@@ -713,8 +713,12 @@ class CharterParty(ModelSQL, ModelView):
class ShipmentIn(metaclass=PoolMeta):
__name__ = 'stock.shipment.in'
- from_location = fields.Many2One('stock.location', 'From location')
- to_location = fields.Many2One('stock.location', 'To location')
+ from_location = fields.Many2One(
+ 'stock.location', 'From location',
+ domain=[('type', '!=', 'customer')])
+ to_location = fields.Many2One(
+ 'stock.location', 'To location',
+ domain=[('type', '!=', 'supplier')])
shipment_type = fields.Function(fields.Selection([
(None, ''),
('dropship', 'Dropship'),
diff --git a/modules/purchase_trade/tests/test_module.py b/modules/purchase_trade/tests/test_module.py
index dea188e..11e7a65 100644
--- a/modules/purchase_trade/tests/test_module.py
+++ b/modules/purchase_trade/tests/test_module.py
@@ -372,6 +372,22 @@ class PurchaseTradeTestCase(ModuleTestCase):
'planned_to_location': 20,
})
+ def test_lot_shipping_defaults_purchase_locations_without_plan(self):
+ 'link to transport falls back to purchase locations without a plan'
+ wizard = lot_module.LotShipping()
+ wizard.records = [Mock(
+ r_planned_from_location=None,
+ r_planned_to_location=None,
+ r_purchase=Mock(
+ from_location=Mock(id=10),
+ to_location=Mock(id=20)),
+ )]
+
+ self.assertEqual(wizard.default_ship(None), {
+ 'planned_from_location': 10,
+ 'planned_to_location': 20,
+ })
+
def test_lot_shipping_defaults_uniform_planned_locations(self):
'link to transport carries uniform planned locations from selection'
wizard = lot_module.LotShipping()
@@ -509,6 +525,47 @@ class PurchaseTradeTestCase(ModuleTestCase):
Lot.assert_lines_quantity_consistency.assert_called_once_with([
lot.line])
+ def test_lot_shipping_open_quantity_uses_shared_transport_link(self):
+ 'standalone link action keeps linking open lot.qt quantities'
+ wizard = lot_module.LotShipping()
+ shipment = Mock(id=40)
+ wizard.ship = Mock(
+ shipment='in',
+ shipment_in=shipment,
+ shipment_out=None,
+ shipment_internal=None,
+ create_new_shipment=False,
+ quantity=None,
+ )
+ wizard.records = [Mock(
+ id=10000007,
+ r_lot_shipment_in=None,
+ r_lot_quantity=Decimal('125'),
+ r_lot_matched=Decimal('0'),
+ )]
+ purchase_line = Mock()
+ source = Mock(
+ lot_p=Mock(line=purchase_line),
+ lot_s=None,
+ )
+ Lot = Mock()
+ Lot.skip_quantity_consistency.return_value.__enter__ = Mock()
+ Lot.skip_quantity_consistency.return_value.__exit__ = Mock()
+ LotQt = Mock(return_value=source)
+ Move = Mock()
+ pool = Mock()
+ pool.get.side_effect = [Lot, LotQt, Move]
+
+ with patch('trytond.modules.purchase_trade.lot.Pool',
+ return_value=pool):
+ state = wizard.transition_shipping()
+
+ self.assertEqual(state, 'end')
+ LotQt.link_to_transport.assert_called_once_with(
+ source, Decimal('125.00000'), 'stock.shipment.in,40')
+ Lot.assert_lines_quantity_consistency.assert_called_once_with([
+ purchase_line])
+
def test_lot_unship_restores_planned_open_quantity(self):
'unlinking a planned scheduled lot.qt returns it to planned'
wizard = lot_module.LotUnship()
@@ -648,14 +705,10 @@ class PurchaseTradeTestCase(ModuleTestCase):
def test_lot_shipping_scheduled_lotqt_keeps_planned_locations(self):
'scheduled lot.qt keeps the planned from and to locations'
- wizard = lot_module.LotShipping()
- wizard.ship = Mock(
- shipment='in',
- shipment_in=Mock(id=40),
- shipment_out=None,
- shipment_internal=None,
- )
+ LotQt = Pool().get('lot.qt')
+ linked = Mock()
lqt = Mock(
+ lot_quantity=Decimal('125'),
lot_p=Mock(id=1),
lot_s=Mock(id=2),
lot_unit=Mock(id=3),
@@ -669,11 +722,15 @@ class PurchaseTradeTestCase(ModuleTestCase):
planned_to_date=datetime.date(2026, 7, 5),
planned_note='POL to POD',
)
- LotQt = Mock()
+ lqt.is_planned_transport.return_value = True
- wizard._create_scheduled_lotqt(LotQt, lqt, Decimal('125'))
+ with patch.object(
+ LotQt, 'create', return_value=[linked]) as create, \
+ patch.object(LotQt, 'save') as save:
+ result = LotQt.link_to_transport(
+ lqt, Decimal('125'), 'stock.shipment.in,40')
- LotQt.create.assert_called_once_with([{
+ create.assert_called_once_with([{
'lot_p': 1,
'lot_s': 2,
'lot_quantity': Decimal('125'),
@@ -689,6 +746,124 @@ class PurchaseTradeTestCase(ModuleTestCase):
'planned_note': 'POL to POD',
'lot_shipment_in': 40,
}])
+ save.assert_called_once_with([lqt])
+ self.assertEqual(lqt.lot_quantity, 0)
+ self.assertIs(result, linked)
+
+ def test_add_physical_lot_defaults_transport_from_purchase(self):
+ 'add physical lot proposes shipment creation from purchase values'
+ wizard = lot_module.LotAdding()
+ purchase = Mock(
+ party=Mock(id=30),
+ from_location=Mock(id=10),
+ to_location=Mock(id=20),
+ )
+ lqt = Mock(
+ lot_p=Mock(line=Mock(
+ purchase=purchase,
+ unit=Mock(id=3))),
+ lot_quantity=Decimal('125'),
+ lot_shipment_in=None,
+ lot_shipment_internal=None,
+ lot_shipment_out=None,
+ planned_from_location=None,
+ planned_to_location=None,
+ )
+ lqt.lot_p.lot_unit_line = Mock(id=3)
+ LotQt = Mock(return_value=lqt)
+ pool = Mock()
+ pool.get.side_effect = [Mock(), LotQt]
+
+ with patch('trytond.modules.purchase_trade.lot.Pool',
+ return_value=pool), patch(
+ 'trytond.modules.purchase_trade.lot.Transaction'
+ ) as TransactionMock:
+ TransactionMock.return_value.context = {
+ 'active_ids': [10000007]}
+ values = wizard.default_add(None)
+
+ self.assertTrue(values['transport_missing'])
+ self.assertEqual(values['shipment_supplier'], 30)
+ self.assertEqual(values['transport_from_location'], 10)
+ self.assertEqual(values['transport_to_location'], 20)
+
+ def test_add_physical_lot_links_existing_shipment_before_add(self):
+ 'add physical lot can link an existing shipment in one transaction'
+ wizard = lot_module.LotAdding()
+ shipment = Mock(id=40)
+ source = Mock(lot_quantity=Decimal('125'))
+ source.has_shipment.return_value = False
+ linked = Mock()
+ LotQt = Mock(return_value=source)
+ LotQt.link_to_transport.return_value = linked
+ Lot = Mock()
+ Lot.skip_quantity_consistency.return_value.__enter__ = Mock()
+ Lot.skip_quantity_consistency.return_value.__exit__ = Mock()
+ pool = Mock()
+ pool.get.side_effect = [LotQt, Lot]
+ wizard.records = [Mock(id=10000007)]
+ wizard.add = Mock(
+ shipment_in=shipment,
+ create_new_shipment=False,
+ lots=[Mock()],
+ unlink_remainder=True,
+ )
+
+ with patch('trytond.modules.purchase_trade.lot.Pool',
+ return_value=pool):
+ state = wizard.transition_adding()
+
+ self.assertEqual(state, 'end')
+ LotQt.link_to_transport.assert_called_once_with(
+ source, Decimal('125'), 'stock.shipment.in,40')
+ LotQt.add_physical_lots.assert_called_once_with(
+ linked, wizard.add.lots, True)
+
+ def test_add_physical_lot_creates_shipment_with_optional_bl(self):
+ 'add physical lot creates and links a shipment with optional BL data'
+ wizard = lot_module.LotAdding()
+ shipment = Mock(id=40)
+ source = Mock(lot_quantity=Decimal('125'))
+ source.has_shipment.return_value = False
+ linked = Mock()
+ LotQt = Mock(return_value=source)
+ LotQt.link_to_transport.return_value = linked
+ ShipmentIn = Mock()
+ ShipmentIn.create.return_value = [shipment]
+ Lot = Mock()
+ Lot.skip_quantity_consistency.return_value.__enter__ = Mock()
+ Lot.skip_quantity_consistency.return_value.__exit__ = Mock()
+ pool = Mock()
+ pool.get.side_effect = [LotQt, ShipmentIn, Lot]
+ wizard.records = [Mock(id=10000007)]
+ wizard.add = Mock(
+ shipment_in=None,
+ create_new_shipment=True,
+ shipment_supplier=Mock(id=30),
+ transport_from_location=Mock(id=10),
+ transport_to_location=Mock(id=20),
+ shipment_bl_number='BL-2026-01',
+ shipment_bl_date=datetime.date(2026, 6, 22),
+ lots=[Mock()],
+ unlink_remainder=True,
+ )
+
+ with patch('trytond.modules.purchase_trade.lot.Pool',
+ return_value=pool):
+ state = wizard.transition_adding()
+
+ self.assertEqual(state, 'end')
+ ShipmentIn.create.assert_called_once_with([{
+ 'supplier': 30,
+ 'from_location': 10,
+ 'to_location': 20,
+ 'bl_number': 'BL-2026-01',
+ 'bl_date': datetime.date(2026, 6, 22),
+ }])
+ LotQt.link_to_transport.assert_called_once_with(
+ source, Decimal('125'), 'stock.shipment.in,40')
+ LotQt.add_physical_lots.assert_called_once_with(
+ linked, wizard.add.lots, True)
@with_transaction()
def test_get_mtm_applies_component_ratio_as_percentage(self):
@@ -2604,6 +2779,18 @@ class PurchaseTradeTestCase(ModuleTestCase):
self.assertEqual(shipment.get_shipment_type(), 'inbound')
+ @with_transaction()
+ def test_shipment_in_location_domains_follow_trade_direction(self):
+ 'shipment locations exclude invalid trade counterpart directions'
+ ShipmentIn = Pool().get('stock.shipment.in')
+
+ self.assertEqual(
+ ShipmentIn.from_location.domain,
+ [('type', '!=', 'customer')])
+ self.assertEqual(
+ ShipmentIn.to_location.domain,
+ [('type', '!=', 'supplier')])
+
@with_transaction()
def test_lot_report_shipment_type_uses_linked_shipment(self):
'lot report shipment type mirrors the linked shipment_in'
diff --git a/modules/purchase_trade/view/lot_add_start_form.xml b/modules/purchase_trade/view/lot_add_start_form.xml
index bb95a5b..d2cabee 100755
--- a/modules/purchase_trade/view/lot_add_start_form.xml
+++ b/modules/purchase_trade/view/lot_add_start_form.xml
@@ -7,6 +7,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+