From cf4bd94d0328f12f69085085e885c90fa4b2089b Mon Sep 17 00:00:00 2001 From: laurentbarontini Date: Tue, 14 Jul 2026 12:02:07 +0200 Subject: [PATCH] Bug lot.qt --- modules/purchase_trade/__init__.py | 10 +- modules/purchase_trade/stock.py | 214 +------------------- modules/purchase_trade/tests/test_module.py | 80 +------- 3 files changed, 8 insertions(+), 296 deletions(-) diff --git a/modules/purchase_trade/__init__.py b/modules/purchase_trade/__init__.py index e11277b..d13a854 100755 --- a/modules/purchase_trade/__init__.py +++ b/modules/purchase_trade/__init__.py @@ -204,15 +204,12 @@ def register(): stock.ImportSoFStart, stock.RevaluateStart, stock.Account, - stock.AccountMoveLine, - stock.AccountMove, - stock.ContainerType, + stock.AccountMoveLine, + stock.AccountMove, + stock.ContainerType, stock.ShipmentContainer, lot.Lot, lot.LotQt, - # Temporarily disabled: added by 1b292e4 for linkage reports, but it - # may leave lot.qt without the base ModelSQL fields in some pools. - # stock.LotQt, lot.LotReport, lot.LotContext, lot.LotShippingStart, @@ -368,7 +365,6 @@ def register(): stock.ShipmentCOOReport, stock.ShipmentPackingListReport, stock.ShipmentLinkageReport, - stock.LotQtLinkageReport, stock.LotReportLinkageReport, module='purchase_trade', type_='report') diff --git a/modules/purchase_trade/stock.py b/modules/purchase_trade/stock.py index c6053f6..ffd8929 100755 --- a/modules/purchase_trade/stock.py +++ b/modules/purchase_trade/stock.py @@ -2898,214 +2898,6 @@ class FindVessel(Wizard): return action, {} -class LotQt(metaclass=PoolMeta): - __name__ = 'lot.qt' - - @staticmethod - def _report_record_key(record): - return ShipmentIn._report_record_key(record) - - @classmethod - def _report_unique_records(cls, records): - return ShipmentIn._report_unique_records(records) - - @staticmethod - def _report_linkage_lot_purchase_line(lot): - return ShipmentIn._report_linkage_lot_purchase_line(lot) - - @staticmethod - def _report_linkage_lot_sale_line(lot): - return ShipmentIn._report_linkage_lot_sale_line(lot) - - @staticmethod - def _report_rec_name(record): - return ShipmentIn._report_rec_name(record) - - @classmethod - def _report_number(cls, record): - return ShipmentIn._report_number(record) - - @staticmethod - def _report_date(value): - return ShipmentIn._report_date(value) - - @staticmethod - def _report_amount(value): - return ShipmentIn._report_amount(value) - - @staticmethod - def _report_price(value): - return ShipmentIn._report_price(value) - - @classmethod - def _report_currency_code(cls, record): - return ShipmentIn._report_currency_code(record) - - @classmethod - def _report_unit_symbol(cls, line): - return ShipmentIn._report_unit_symbol(line) - - @classmethod - def _report_line_quantity(cls, line): - return ShipmentIn._report_line_quantity(line) - - @classmethod - def _report_line_amount(cls, line): - return ShipmentIn._report_line_amount(line) - - @classmethod - def _report_fee_amount(cls, fee): - return ShipmentIn._report_fee_amount(fee) - - @classmethod - def _report_linkage_fee_label(cls, fee): - return ShipmentIn._report_linkage_fee_label(fee) - - @classmethod - def _report_column(cls, rows, index, amount=False): - return ShipmentIn._report_column(rows, index, amount=amount) - - @classmethod - def _report_table_rows(cls, rows, names, amount_names=()): - return ShipmentIn._report_table_rows(rows, names, amount_names) - - @staticmethod - def _format_report_quantity(value, digits='0.001'): - return ShipmentIn._format_report_quantity(value, digits=digits) - - @staticmethod - def _get_report_unit_text(unit): - return ShipmentIn._get_report_unit_text(unit) - - def _get_report_primary_move(self): - return getattr(self, 'lot_move', None) - - def _get_report_linkage_lots(self): - return self._report_unique_records(( - getattr(self, 'lot_p', None), - getattr(self, 'lot_s', None), - )) - - _get_report_linkage_purchase_lines = ( - ShipmentIn._get_report_linkage_purchase_lines) - _get_report_linkage_sale_lines = ShipmentIn._get_report_linkage_sale_lines - _get_report_linkage_purchase = ShipmentIn._get_report_linkage_purchase - _get_report_linkage_sale = ShipmentIn._get_report_linkage_sale - _get_report_linkage_product = ShipmentIn._get_report_linkage_product - - def _get_report_linkage_fees(self): - fees = [] - seen = set() - - def add_fee(fee): - if not fee: - return - key = self._report_record_key(fee) - if key in seen: - return - seen.add(key) - fees.append(fee) - - shipment = getattr(self, 'lot_shipment_in', None) - for fee in getattr(shipment, 'fees', []) or []: - add_fee(fee) - for line in ( - self._get_report_linkage_purchase_lines() - + self._get_report_linkage_sale_lines()): - for fee in getattr(line, 'fees', []) or []: - add_fee(fee) - return fees - - _get_report_linkage_summary_rows = ( - ShipmentIn._get_report_linkage_summary_rows) - _get_report_linkage_movement_rows = ( - ShipmentIn._get_report_linkage_movement_rows) - _get_report_linkage_movement_row = ( - ShipmentIn._get_report_linkage_movement_row) - _get_report_linkage_pricing_rows = ( - ShipmentIn._get_report_linkage_pricing_rows) - _get_report_linkage_detail_rows = ( - ShipmentIn._get_report_linkage_detail_rows) - _get_report_linkage_detail_row = ( - ShipmentIn._get_report_linkage_detail_row) - _get_report_linkage_fee_detail_row = ( - ShipmentIn._get_report_linkage_fee_detail_row) - - report_linkage_title = ShipmentIn.report_linkage_title - report_linkage_desk = ShipmentIn.report_linkage_desk - report_linkage_book = ShipmentIn.report_linkage_book - report_linkage_strategy = ShipmentIn.report_linkage_strategy - - @property - def report_linkage_bl_date(self): - shipment = getattr(self, 'lot_shipment_in', None) - bl_date = getattr(shipment, 'bl_date', None) - if not bl_date: - move = getattr(self, 'lot_move', None) - bl_date = getattr(move, 'bldate', None) - return bl_date and bl_date.strftime('%A, %B %d, %Y') or '' - - report_linkage_trading_unit = ShipmentIn.report_linkage_trading_unit - report_linkage_finance_user = ShipmentIn.report_linkage_finance_user - report_linkage_summary_groups = ShipmentIn.report_linkage_summary_groups - report_linkage_summary_cost_types = ( - ShipmentIn.report_linkage_summary_cost_types) - report_linkage_summary_estimated = ( - ShipmentIn.report_linkage_summary_estimated) - report_linkage_summary_validated = ( - ShipmentIn.report_linkage_summary_validated) - report_linkage_summary_rows = ShipmentIn.report_linkage_summary_rows - report_linkage_movement_types = ShipmentIn.report_linkage_movement_types - report_linkage_movement_references = ( - ShipmentIn.report_linkage_movement_references) - report_linkage_movement_counterparts = ( - ShipmentIn.report_linkage_movement_counterparts) - report_linkage_movement_commodities = ( - ShipmentIn.report_linkage_movement_commodities) - report_linkage_movement_quantities = ( - ShipmentIn.report_linkage_movement_quantities) - report_linkage_movement_deliveries = ( - ShipmentIn.report_linkage_movement_deliveries) - report_linkage_movement_basis = ShipmentIn.report_linkage_movement_basis - report_linkage_movement_periods = ( - ShipmentIn.report_linkage_movement_periods) - report_linkage_movement_from_dates = ( - ShipmentIn.report_linkage_movement_from_dates) - report_linkage_movement_to_dates = ( - ShipmentIn.report_linkage_movement_to_dates) - report_linkage_movement_rows = ShipmentIn.report_linkage_movement_rows - report_linkage_bank_deal = ShipmentIn.report_linkage_bank_deal - report_linkage_bank_type = ShipmentIn.report_linkage_bank_type - report_linkage_bank_name = ShipmentIn.report_linkage_bank_name - report_linkage_lc_type = ShipmentIn.report_linkage_lc_type - report_linkage_lc_number = ShipmentIn.report_linkage_lc_number - report_linkage_lc_amount = ShipmentIn.report_linkage_lc_amount - report_linkage_lc_expiry_date = ShipmentIn.report_linkage_lc_expiry_date - report_linkage_pricing_deals = ShipmentIn.report_linkage_pricing_deals - report_linkage_pricing_sides = ShipmentIn.report_linkage_pricing_sides - report_linkage_pricing_types = ShipmentIn.report_linkage_pricing_types - report_linkage_pricing_symbols = ShipmentIn.report_linkage_pricing_symbols - report_linkage_pricing_periods = ShipmentIn.report_linkage_pricing_periods - report_linkage_pricing_input_prices = ( - ShipmentIn.report_linkage_pricing_input_prices) - report_linkage_pricing_rows = ShipmentIn.report_linkage_pricing_rows - report_linkage_detail_groups = ShipmentIn.report_linkage_detail_groups - report_linkage_detail_cost_types = ( - ShipmentIn.report_linkage_detail_cost_types) - report_linkage_detail_counterparts = ( - ShipmentIn.report_linkage_detail_counterparts) - report_linkage_detail_sources = ShipmentIn.report_linkage_detail_sources - report_linkage_detail_unit_prices = ( - ShipmentIn.report_linkage_detail_unit_prices) - report_linkage_detail_quantities = ( - ShipmentIn.report_linkage_detail_quantities) - report_linkage_detail_estimated = ( - ShipmentIn.report_linkage_detail_estimated) - report_linkage_detail_validated = ( - ShipmentIn.report_linkage_detail_validated) - report_linkage_detail_rows = ShipmentIn.report_linkage_detail_rows - - class ShipmentOut(metaclass=PoolMeta): __name__ = 'stock.shipment.out' @@ -4639,9 +4431,7 @@ class ShipmentLinkageReport(ShipmentTemplateReportMixin, BaseSupplierShipping): 'shipment_linkage_report_template', 'stock') -class LotQtLinkageReport(ShipmentTemplateReportMixin, BaseSupplierShipping): - __name__ = 'lot.qt.linkage' - +class LinkageTemplateReport(ShipmentTemplateReportMixin, BaseSupplierShipping): @classmethod def _resolve_configured_report_path(cls, action): return cls._resolve_template_path( @@ -4858,7 +4648,7 @@ class LotReportLinkageRecord: report_linkage_detail_rows = ShipmentIn.report_linkage_detail_rows -class LotReportLinkageReport(LotQtLinkageReport): +class LotReportLinkageReport(LinkageTemplateReport): __name__ = 'lot.report.linkage' @classmethod diff --git a/modules/purchase_trade/tests/test_module.py b/modules/purchase_trade/tests/test_module.py index d2e287f..d6fc592 100644 --- a/modules/purchase_trade/tests/test_module.py +++ b/modules/purchase_trade/tests/test_module.py @@ -6764,83 +6764,9 @@ description self.assertIn('80.000 USD/MT', shipment.report_linkage_pricing_input_prices) self.assertIn('100.000 USD/MT', shipment.report_linkage_pricing_input_prices) - def test_lotqt_linkage_helpers_use_single_matching(self): - 'lot.qt linkage helpers expose only the selected matching' - LotQt = Pool().get('lot.qt') - lotqt = LotQt() - - currency = SimpleNamespace(code='USD') - unit = SimpleNamespace(symbol='MT') - product = SimpleNamespace( - rec_name='Sulphuric Acid', - name='Sulphuric Acid', - code='H2SO4') - purchase = SimpleNamespace( - id=1, - number='P-10', - reference='26.0001', - currency=currency, - party=SimpleNamespace(rec_name='SUPPLIER SA'), - to_location=SimpleNamespace(rec_name='Odda'), - incoterm=SimpleNamespace(code='FOB'), - operator=SimpleNamespace(rec_name='Operator A')) - sale = SimpleNamespace( - id=2, - number='S-20', - reference='26.0001', - currency=currency, - party=SimpleNamespace(rec_name='CLIENT SA'), - to_location=SimpleNamespace(rec_name='Mejillones'), - incoterm=SimpleNamespace(code='CFR')) - period = SimpleNamespace(rec_name='Chile FY26') - purchase_line = SimpleNamespace( - id=11, - product=product, - purchase=purchase, - quantity_theorical=Decimal('100'), - quantity=Decimal('100'), - unit_price=Decimal('80'), - unit=unit, - price_type='fixed', - del_period=period, - period_at='laycan', - from_del=datetime.date(2026, 4, 30), - to_del=datetime.date(2026, 5, 8), - fees=[], - mtm=[]) - sale_line = SimpleNamespace( - id=12, - product=product, - sale=sale, - quantity_theorical=Decimal('100'), - quantity=Decimal('100'), - unit_price=Decimal('100'), - unit=unit, - price_type='fixed', - del_period=period, - period_at='laycan', - from_del=datetime.date(2026, 4, 30), - to_del=datetime.date(2026, 4, 30), - fees=[], - mtm=[]) - lotqt.lot_p = SimpleNamespace(id=101, line=purchase_line) - lotqt.lot_s = SimpleNamespace(id=102, sale_line=sale_line) - lotqt.lot_shipment_in = SimpleNamespace( - bl_date=datetime.date(2026, 4, 30), - fees=[]) - - self.assertEqual( - lotqt.report_linkage_title, 'Linkage P-10/S-20 26.0001') - self.assertEqual(lotqt.report_linkage_desk, 'Sulphuric Acid') - self.assertEqual(lotqt.report_linkage_book, 'H2SO4 Chile FY26') - self.assertEqual( - lotqt.report_linkage_bl_date, 'Thursday, April 30, 2026') - self.assertIn('Purchases', lotqt.report_linkage_summary_groups) - self.assertIn('Sales', lotqt.report_linkage_summary_groups) - self.assertIn('P-10', lotqt.report_linkage_movement_references) - self.assertIn('S-20', lotqt.report_linkage_movement_references) - self.assertIn('80.000 USD/MT', lotqt.report_linkage_pricing_input_prices) - self.assertIn('100.000 USD/MT', lotqt.report_linkage_pricing_input_prices) + def test_linkage_report_does_not_extend_lotqt_model(self): + 'linkage report must not alter the lot.qt ORM model' + self.assertFalse(hasattr(stock_module, 'LotQt')) def test_lot_report_linkage_rejects_non_physical_lines(self): 'lot.report linkage report is only available for physical lines'