Planned status
This commit is contained in:
@@ -2020,8 +2020,24 @@ class LotQt(
|
||||
wh &= ((ls.sale_line > 0) & (lp.line > 0))
|
||||
elif type=='not matched':
|
||||
wh &= (((ls.sale_line > 0) & (lp.line == None)) | ((ls.sale_line == None) & (lp.line > 0)))
|
||||
PlannedTransport = (
|
||||
(lqt.planned_from_location != None)
|
||||
| (lqt.planned_to_location != None)
|
||||
| (lqt.planned_transport_type != None)
|
||||
| (lqt.planned_from_date != None)
|
||||
| (lqt.planned_to_date != None)
|
||||
| (lqt.planned_note != None))
|
||||
NotPlannedTransport = (
|
||||
(lqt.planned_from_location == None)
|
||||
& (lqt.planned_to_location == None)
|
||||
& (lqt.planned_transport_type == None)
|
||||
& (lqt.planned_from_date == None)
|
||||
& (lqt.planned_to_date == None)
|
||||
& (lqt.planned_note == None))
|
||||
if shipping_status == 'unshipped':
|
||||
wh &= (lqt.lot_shipment_in == None)
|
||||
wh &= ((lqt.lot_shipment_in == None) & NotPlannedTransport)
|
||||
elif shipping_status == 'planned':
|
||||
wh &= ((lqt.lot_shipment_in == None) & PlannedTransport)
|
||||
elif shipping_status == 'scheduled':
|
||||
wh &= ((lqt.lot_shipment_in != None) & (si.state == 'draft'))
|
||||
elif shipping_status == 'shipped':
|
||||
@@ -2052,14 +2068,16 @@ class LotQt(
|
||||
AvQt = Case(((lqt.lot_p>0) & (lqt.lot_s>0), 0),else_=Case((lqt.lot_p>0,lqt.lot_quantity),else_=-lqt.lot_quantity))
|
||||
MaQt = Case(((lqt.lot_p>0) & (lqt.lot_s>0), lqt.lot_quantity),else_=0)
|
||||
ShippingStatus = Case(
|
||||
(lqt.lot_shipment_in == None, 'unshipped'),
|
||||
((lqt.lot_shipment_in == None) & PlannedTransport, 'planned'),
|
||||
else_=Case(
|
||||
(si.state == 'draft', 'scheduled'),
|
||||
(lqt.lot_shipment_in == None, 'unshipped'),
|
||||
else_=Case(
|
||||
(si.state == 'started', 'shipped'),
|
||||
(si.state == 'draft', 'scheduled'),
|
||||
else_=Case(
|
||||
(si.state.in_(['received', 'done']), 'received'),
|
||||
else_=None))))
|
||||
(si.state == 'started', 'shipped'),
|
||||
else_=Case(
|
||||
(si.state.in_(['received', 'done']), 'received'),
|
||||
else_=None)))))
|
||||
query = (
|
||||
lqt.join(lp,'LEFT',condition=lqt.lot_p == lp.id)
|
||||
.join(pl,'LEFT',condition=lp.line == pl.id)
|
||||
@@ -2166,8 +2184,10 @@ class LotQt(
|
||||
wh2 &= (lp.sale_line != None)
|
||||
elif type=='not matched':
|
||||
wh2 &= (lp.sale_line == None)
|
||||
if shipping_status == 'unshipped':
|
||||
if shipping_status in {'unshipped', 'planned'}:
|
||||
wh2 &= (lp.lot_shipment_in == None)
|
||||
if shipping_status == 'planned':
|
||||
wh2 &= False
|
||||
elif shipping_status == 'scheduled':
|
||||
wh2 &= ((lp.lot_shipment_in != None) & (si.state == 'draft'))
|
||||
elif shipping_status == 'shipped':
|
||||
@@ -2505,6 +2525,7 @@ class LotReport(
|
||||
r_shipping_status = fields.Selection([
|
||||
(None, ''),
|
||||
('unshipped', 'Unshipped'),
|
||||
('planned', 'Planned'),
|
||||
('scheduled', 'Scheduled'),
|
||||
('shipped', 'Shipped'),
|
||||
('received', 'Received'),
|
||||
@@ -2824,6 +2845,7 @@ class LotContext(ModelView):
|
||||
shipping_status = fields.Selection([
|
||||
('all', 'All'),
|
||||
('unshipped', 'Unshipped'),
|
||||
('planned', 'Planned'),
|
||||
('scheduled', 'Scheduled'),
|
||||
('shipped', 'Shipped'),
|
||||
('received', 'Received'),
|
||||
@@ -3091,6 +3113,13 @@ class LotPlanTransport(Wizard):
|
||||
return 'plan'
|
||||
return 'end'
|
||||
|
||||
@staticmethod
|
||||
def _append_lotqt_affected_lines(lotqt, affected_lines):
|
||||
if lotqt.lot_p and lotqt.lot_p.line:
|
||||
affected_lines.append(lotqt.lot_p.line)
|
||||
if lotqt.lot_s and lotqt.lot_s.sale_line:
|
||||
affected_lines.append(lotqt.lot_s.sale_line)
|
||||
|
||||
def default_plan(self, fields):
|
||||
if not self.records:
|
||||
return {}
|
||||
@@ -3143,15 +3172,12 @@ class LotPlanTransport(Wizard):
|
||||
raise UserError(
|
||||
"Only open quantity lines can be planned.")
|
||||
lotqt = LotQt(record.id - 10000000)
|
||||
self._append_lotqt_affected_lines(lotqt, affected_lines)
|
||||
if self.plan.cancel_plan:
|
||||
LotQt.cancel_transport_plan(lotqt)
|
||||
else:
|
||||
LotQt.plan_to_transport(
|
||||
lotqt, self.plan.quantity, plan_values)
|
||||
if lotqt.lot_p and lotqt.lot_p.line:
|
||||
affected_lines.append(lotqt.lot_p.line)
|
||||
if lotqt.lot_s and lotqt.lot_s.sale_line:
|
||||
affected_lines.append(lotqt.lot_s.sale_line)
|
||||
Lot.assert_lines_quantity_consistency(affected_lines)
|
||||
return 'end'
|
||||
|
||||
|
||||
@@ -191,6 +191,21 @@ class PurchaseTradeTestCase(ModuleTestCase):
|
||||
create.assert_not_called()
|
||||
delete.assert_called_once_with([planned])
|
||||
|
||||
def test_plan_transport_collects_affected_lines_before_cancel(self):
|
||||
'plan transport wizard can keep affected lines before deleting lot.qt'
|
||||
wizard = lot_module.LotPlanTransport()
|
||||
purchase_line = Mock()
|
||||
sale_line = Mock()
|
||||
lotqt = Mock(
|
||||
lot_p=Mock(line=purchase_line),
|
||||
lot_s=Mock(sale_line=sale_line),
|
||||
)
|
||||
affected_lines = []
|
||||
|
||||
wizard._append_lotqt_affected_lines(lotqt, affected_lines)
|
||||
|
||||
self.assertEqual(affected_lines, [purchase_line, sale_line])
|
||||
|
||||
@with_transaction()
|
||||
def test_get_mtm_applies_component_ratio_as_percentage(self):
|
||||
'get_mtm treats component ratio as a percentage'
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
</field>
|
||||
<field name="r_vessel" width="130" optional="1"/>
|
||||
<field name="r_operator" width="130" optional="1"/>
|
||||
<field name="r_shipping_status" widget="badge" string="Shipping status" badge_colors="shipped:#16a34a,unshipped:#ef4444,scheduled:#f59e0b" width="120"/>
|
||||
<field name="r_shipping_status" widget="badge" string="Shipping status" badge_colors="shipped:#16a34a,unshipped:#ef4444,planned:#06b6d4,scheduled:#f59e0b" width="120"/>
|
||||
<field name="r_lot_status"/>
|
||||
<field name="r_lot_av" width="80" optional="1" tree_invisible="1"/>
|
||||
<field name="r_lot_quantity" symbol="r_lot_unit_line" width="120" sum="1"/>
|
||||
|
||||
Reference in New Issue
Block a user