Link to transport
This commit is contained in:
@@ -2958,11 +2958,9 @@ class LotShipping(Wizard):
|
||||
'lot.shipping.start',
|
||||
'purchase_trade.shipping_view_form', [
|
||||
Button("Cancel", 'end', 'tryton-cancel'),
|
||||
Button("New shipment & link", 'create_shipment', 'tryton-add'),
|
||||
Button("Link", 'shipping', 'tryton-ok', default=True),
|
||||
])
|
||||
|
||||
create_shipment = StateTransition()
|
||||
shipping = StateTransition()
|
||||
|
||||
def transition_start(self):
|
||||
@@ -2986,25 +2984,21 @@ class LotShipping(Wizard):
|
||||
def _record_id(record):
|
||||
return record.id if record else None
|
||||
|
||||
def _unique_supplier(self):
|
||||
suppliers = {}
|
||||
for record in self.records:
|
||||
supplier = getattr(record, 'r_supplier', None)
|
||||
if supplier:
|
||||
suppliers[supplier.id] = supplier
|
||||
if len(suppliers) == 1:
|
||||
return next(iter(suppliers.values()))
|
||||
if not suppliers:
|
||||
raise UserError("Supplier is required to create a shipment.")
|
||||
raise UserError(
|
||||
"Please select lots with the same supplier to create a shipment.")
|
||||
def _selected_shipment(self):
|
||||
if self.ship.shipment == 'in':
|
||||
return self.ship.shipment_in
|
||||
if self.ship.shipment == 'out':
|
||||
return self.ship.shipment_out
|
||||
if self.ship.shipment == 'int':
|
||||
return self.ship.shipment_internal
|
||||
|
||||
def _shipment_in_create_values(self):
|
||||
if self.ship.shipment != 'in':
|
||||
raise UserError("Shipment creation is only available for Shipment In.")
|
||||
supplier = self._unique_supplier()
|
||||
if not self.ship.shipment_supplier:
|
||||
raise UserError("Shipment supplier is required.")
|
||||
values = {
|
||||
'supplier': self._record_id(supplier),
|
||||
'supplier': self._record_id(self.ship.shipment_supplier),
|
||||
}
|
||||
if self.ship.planned_from_location:
|
||||
values['from_location'] = self.ship.planned_from_location.id
|
||||
@@ -3012,13 +3006,10 @@ class LotShipping(Wizard):
|
||||
values['to_location'] = self.ship.planned_to_location.id
|
||||
return values
|
||||
|
||||
def transition_create_shipment(self):
|
||||
def _create_shipment_in(self):
|
||||
ShipmentIn = Pool().get('stock.shipment.in')
|
||||
if self.ship.shipment_in:
|
||||
return self.transition_shipping()
|
||||
shipment, = ShipmentIn.create([self._shipment_in_create_values()])
|
||||
self.ship.shipment_in = shipment
|
||||
return self.transition_shipping()
|
||||
|
||||
def transition_shipping(self):
|
||||
Lot = Pool().get('lot.lot')
|
||||
@@ -3027,6 +3018,11 @@ class LotShipping(Wizard):
|
||||
affected_lines = []
|
||||
if not self.ship.shipment:
|
||||
pass
|
||||
if self.ship.create_new_shipment and self._selected_shipment():
|
||||
raise UserError(
|
||||
"Choose either an existing shipment or create a new shipment.")
|
||||
if self.ship.create_new_shipment:
|
||||
self._create_shipment_in()
|
||||
with Lot.skip_quantity_consistency():
|
||||
for r in self.records:
|
||||
if r.r_lot_shipment_in:
|
||||
@@ -3041,15 +3037,15 @@ class LotShipping(Wizard):
|
||||
shipped_quantity = Decimal(str(r.r_lot_matched)).quantize(Decimal("0.00001"))
|
||||
if self.ship.shipment == 'in':
|
||||
if not self.ship.shipment_in:
|
||||
UserError("Shipment not known!")
|
||||
raise UserError("Shipment not known!")
|
||||
shipment_origin = 'stock.shipment.in,'+str(self.ship.shipment_in.id)
|
||||
elif self.ship.shipment == 'out':
|
||||
if not self.ship.shipment_out:
|
||||
UserError("Shipment not known!")
|
||||
raise UserError("Shipment not known!")
|
||||
shipment_origin = 'stock.shipment.out,'+str(self.ship.shipment_out.id)
|
||||
elif self.ship.shipment == 'int':
|
||||
if not self.ship.shipment_internal:
|
||||
UserError("Shipment not known!")
|
||||
raise UserError("Shipment not known!")
|
||||
shipment_origin = 'stock.shipment.internal,'+str(self.ship.shipment_internal.id)
|
||||
if r.id < 10000000 :
|
||||
l = Lot(r.id)
|
||||
@@ -3137,6 +3133,16 @@ class LotShippingStart(ModelView):
|
||||
shipment_in = fields.Many2One('stock.shipment.in',"Shipment In", states={'invisible': (Eval('shipment') != 'in')})
|
||||
shipment_out = fields.Many2One('stock.shipment.out',"Shipment Out", states={'invisible': (Eval('shipment') != 'out')})
|
||||
shipment_internal = fields.Many2One('stock.shipment.internal',"Shipment Internal", states={'invisible': (Eval('shipment') != 'int')})
|
||||
create_new_shipment = fields.Boolean(
|
||||
"Create a new shipment",
|
||||
states={'invisible': Eval('shipment') != 'in'})
|
||||
shipment_supplier = fields.Many2One(
|
||||
'party.party', "Shipment supplier",
|
||||
states={
|
||||
'invisible': ~Bool(Eval('create_new_shipment')),
|
||||
'required': Bool(Eval('create_new_shipment')),
|
||||
},
|
||||
depends=['create_new_shipment'])
|
||||
planned_from_location = fields.Many2One(
|
||||
'stock.location', "Planned From", readonly=True)
|
||||
planned_to_location = fields.Many2One(
|
||||
@@ -3152,6 +3158,10 @@ class LotShippingStart(ModelView):
|
||||
def default_shipment(cls):
|
||||
return 'in'
|
||||
|
||||
@classmethod
|
||||
def default_create_new_shipment(cls):
|
||||
return False
|
||||
|
||||
|
||||
class LotPlanTransport(Wizard):
|
||||
"Plan lot to transport"
|
||||
|
||||
@@ -219,27 +219,33 @@ class PurchaseTradeTestCase(ModuleTestCase):
|
||||
'planned_to_location': 20,
|
||||
})
|
||||
|
||||
def test_lot_shipping_create_shipment_links_planned_locations(self):
|
||||
'link to transport creates shipment in and links planned locations'
|
||||
def test_lot_shipping_link_creates_shipment_from_dialog_supplier(self):
|
||||
'link to transport creates shipment in from dialog supplier'
|
||||
wizard = lot_module.LotShipping()
|
||||
supplier = Mock(id=30)
|
||||
created_shipment = Mock(id=40)
|
||||
ShipmentIn = Mock()
|
||||
ShipmentIn.create.return_value = [created_shipment]
|
||||
wizard.records = [Mock(r_supplier=supplier)]
|
||||
wizard.records = []
|
||||
wizard.ship = Mock(
|
||||
shipment='in',
|
||||
shipment_in=None,
|
||||
shipment_out=None,
|
||||
shipment_internal=None,
|
||||
create_new_shipment=True,
|
||||
shipment_supplier=supplier,
|
||||
planned_from_location=Mock(id=10),
|
||||
planned_to_location=Mock(id=20),
|
||||
)
|
||||
|
||||
with patch('trytond.modules.purchase_trade.lot.Pool') as PoolMock:
|
||||
PoolMock.return_value.get.return_value = ShipmentIn
|
||||
with patch.object(
|
||||
wizard, 'transition_shipping', return_value='end'
|
||||
) as transition_shipping:
|
||||
state = wizard.transition_create_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 = [Lot, Mock(), Mock(), ShipmentIn]
|
||||
with patch('trytond.modules.purchase_trade.lot.Pool',
|
||||
return_value=pool):
|
||||
state = wizard.transition_shipping()
|
||||
|
||||
self.assertEqual(state, 'end')
|
||||
ShipmentIn.create.assert_called_once_with([{
|
||||
@@ -248,7 +254,22 @@ class PurchaseTradeTestCase(ModuleTestCase):
|
||||
'to_location': 20,
|
||||
}])
|
||||
self.assertEqual(wizard.ship.shipment_in, created_shipment)
|
||||
transition_shipping.assert_called_once_with()
|
||||
Lot.assert_lines_quantity_consistency.assert_called_once_with([])
|
||||
|
||||
def test_lot_shipping_rejects_existing_and_new_shipment(self):
|
||||
'link to transport rejects choosing existing shipment and create new'
|
||||
wizard = lot_module.LotShipping()
|
||||
wizard.ship = Mock(
|
||||
shipment='in',
|
||||
shipment_in=Mock(id=40),
|
||||
shipment_out=None,
|
||||
shipment_internal=None,
|
||||
create_new_shipment=True,
|
||||
shipment_supplier=Mock(id=30),
|
||||
)
|
||||
|
||||
with self.assertRaises(UserError):
|
||||
wizard.transition_shipping()
|
||||
|
||||
@with_transaction()
|
||||
def test_get_mtm_applies_component_ratio_as_percentage(self):
|
||||
|
||||
@@ -4,6 +4,10 @@
|
||||
<field name="shipment"/>
|
||||
<label name="shipment_in"/>
|
||||
<field name="shipment_in" context="{'lot_shipping_planned_from_location': Eval('planned_from_location'), 'lot_shipping_planned_to_location': Eval('planned_to_location')}"/>
|
||||
<label name="create_new_shipment"/>
|
||||
<field name="create_new_shipment"/>
|
||||
<label name="shipment_supplier"/>
|
||||
<field name="shipment_supplier"/>
|
||||
<label name="shipment_out"/>
|
||||
<field name="shipment_out"/>
|
||||
<label name="shipment_internal"/>
|
||||
|
||||
Reference in New Issue
Block a user