From 846c2d6a939a29502f084566a139b2d15494de14 Mon Sep 17 00:00:00 2001 From: laurentbarontini Date: Sun, 7 Jun 2026 06:22:15 +0200 Subject: [PATCH] Planned status --- modules/purchase_trade/lot.py | 48 ++++++++++++++----- modules/purchase_trade/tests/test_module.py | 15 ++++++ .../purchase_trade/view/lot_report_list.xml | 2 +- 3 files changed, 53 insertions(+), 12 deletions(-) diff --git a/modules/purchase_trade/lot.py b/modules/purchase_trade/lot.py index 255df31..36f8563 100755 --- a/modules/purchase_trade/lot.py +++ b/modules/purchase_trade/lot.py @@ -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' diff --git a/modules/purchase_trade/tests/test_module.py b/modules/purchase_trade/tests/test_module.py index ca906b6..b656936 100644 --- a/modules/purchase_trade/tests/test_module.py +++ b/modules/purchase_trade/tests/test_module.py @@ -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' diff --git a/modules/purchase_trade/view/lot_report_list.xml b/modules/purchase_trade/view/lot_report_list.xml index 1df3276..21cdf2b 100755 --- a/modules/purchase_trade/view/lot_report_list.xml +++ b/modules/purchase_trade/view/lot_report_list.xml @@ -25,7 +25,7 @@ - +