diff --git a/modules/account_invoice/invoice_ict.fodt b/modules/account_invoice/invoice_ict.fodt index 04f0604..d94583a 100644 --- a/modules/account_invoice/invoice_ict.fodt +++ b/modules/account_invoice/invoice_ict.fodt @@ -3930,15 +3930,15 @@ Goods description - QUANTITY: <format_number(invoice.report_lbs, invoice.party.lang) if invoice.report_lbs != '' else ''>LBS (<format_number(invoice.report_net, invoice.party.lang) if invoice.report_net != '' else ''> MTS) - <for each="line in invoice.report_quantity_lines.splitlines()"> - <line> - </for> + QUANTITY: <format_number(invoice.report_lbs, invoice.party.lang) if invoice.report_lbs != '' else ''>LBS (<format_number(invoice.report_net, invoice.party.lang) if invoice.report_net != '' else ''> <invoice.report_weight_unit_upper>) + <invoice.report_description_upper or invoice.report_product_description>CROP <invoice.report_crop_name> <invoice.report_attributes_name> - <for each="line in invoice.report_rate_lines.splitlines()"> - At <line> - </for> + <for each="block in invoice.report_trade_blocks"> + <block[0]> + At <block[1]> + + </for> <invoice.report_incoterm> @@ -3957,10 +3957,10 @@ BALES - Gross KGS + Gross <invoice.report_weight_unit_upper> - NET KGS + NET <invoice.report_weight_unit_upper> diff --git a/modules/purchase_trade/invoice.py b/modules/purchase_trade/invoice.py index 084c27f..9087841 100644 --- a/modules/purchase_trade/invoice.py +++ b/modules/purchase_trade/invoice.py @@ -191,6 +191,19 @@ class Invoice(metaclass=PoolMeta): details.append(detail) return '\n'.join(details) + @property + def report_trade_blocks(self): + sale = self._get_report_sale() + if sale and getattr(sale, 'report_trade_blocks', None): + return sale.report_trade_blocks + blocks = [] + quantity_lines = self.report_quantity_lines.splitlines() + rate_lines = self.report_rate_lines.splitlines() + for index, quantity_line in enumerate(quantity_lines): + price_line = rate_lines[index] if index < len(rate_lines) else '' + blocks.append((quantity_line, price_line)) + return blocks + @property def report_rate_currency_upper(self): line = self._get_report_invoice_line() @@ -337,6 +350,17 @@ class Invoice(metaclass=PoolMeta): return '' return round(Decimal(net) * Decimal('2204.62'),2) + @property + def report_weight_unit_upper(self): + sale = self._get_report_sale() + if sale and getattr(sale, 'report_quantity_unit_upper', None): + return sale.report_quantity_unit_upper + line = self._get_report_trade_line() or self._get_report_invoice_line() + unit = getattr(line, 'unit', None) if line else None + if unit and unit.rec_name: + return unit.rec_name.upper() + return 'KGS' + @property def report_bl_date(self): shipment = self._get_report_shipment() diff --git a/modules/purchase_trade/sale.py b/modules/purchase_trade/sale.py index 56ea13d..0b18cae 100755 --- a/modules/purchase_trade/sale.py +++ b/modules/purchase_trade/sale.py @@ -440,12 +440,19 @@ class Sale(metaclass=PoolMeta): if line and line.unit: return line.unit.rec_name.upper() return '' + + def _get_report_line_quantity(self, line): + phys_lots = [l for l in line.lots if l.lot_type == 'physic'] + if phys_lots: + return sum(Decimal(str(l.get_current_quantity() or 0)) + for l in phys_lots) + return Decimal(str(line.quantity or 0)) @property def report_qt(self): lines = self._get_report_lines() if lines: - total = sum(Decimal(str(line.quantity or 0)) for line in lines) + total = sum(self._get_report_line_quantity(line) for line in lines) return quantity_to_words(total) return '' @@ -456,10 +463,11 @@ class Sale(metaclass=PoolMeta): return '' details = [] for line in lines: + current_quantity = self._get_report_line_quantity(line) quantity = self._format_report_number( - line.quantity, keep_trailing_decimal=True) + current_quantity, keep_trailing_decimal=True) unit = line.unit.rec_name.upper() if line.unit and line.unit.rec_name else '' - words = quantity_to_words(Decimal(str(line.quantity or 0))) + words = quantity_to_words(current_quantity) period = line.del_period.description if getattr(line, 'del_period', None) else '' detail = ' '.join( part for part in [ @@ -523,6 +531,28 @@ class Sale(metaclass=PoolMeta): if lines: return '\n'.join(self._format_report_price_line(line) for line in lines) return '' + + @property + def report_trade_blocks(self): + lines = self._get_report_lines() + blocks = [] + for line in lines: + current_quantity = self._get_report_line_quantity(line) + quantity = self._format_report_number( + current_quantity, keep_trailing_decimal=True) + unit = line.unit.rec_name.upper() if line.unit and line.unit.rec_name else '' + words = quantity_to_words(current_quantity) + period = line.del_period.description if getattr(line, 'del_period', None) else '' + quantity_line = ' '.join( + part for part in [ + quantity, + unit, + f"({words})", + f"- {period}" if period else '', + ] if part) + price_line = self._format_report_price_line(line) + blocks.append((quantity_line, price_line)) + return blocks @property def report_delivery(self): diff --git a/modules/purchase_trade/tests/test_module.py b/modules/purchase_trade/tests/test_module.py index 85bfd07..2b0b42a 100644 --- a/modules/purchase_trade/tests/test_module.py +++ b/modules/purchase_trade/tests/test_module.py @@ -279,5 +279,36 @@ class PurchaseTradeTestCase(ModuleTestCase): self.assertEqual(sale.report_net, Decimal('2000')) self.assertEqual(sale.report_gross, Decimal('2000')) + def test_sale_report_trade_blocks_use_lot_current_quantity(self): + 'sale trade blocks use current lot quantity for quantity display' + Sale = Pool().get('sale.sale') + + lot = Mock() + lot.lot_type = 'physic' + lot.get_current_quantity.return_value = Decimal('950') + line = Mock() + line.type = 'line' + line.lots = [lot] + line.quantity = Decimal('1000') + line.unit = Mock(rec_name='MT') + line.del_period = Mock(description='MARCH 2026') + line.price_type = 'priced' + line.linked_currency = Mock(rec_name='USC') + line.linked_unit = Mock(rec_name='POUND') + line.linked_price = Decimal('8.3000') + line.unit_price = Decimal('0') + line.get_pricing_text = 'ON ICE Cotton #2 MARCH 2026' + + sale = Sale() + sale.currency = Mock(rec_name='USD') + sale.lines = [line] + + self.assertEqual( + sale.report_trade_blocks, + [( + '950.0 MT (NINE HUNDRED AND FIFTY METRIC TONS) - MARCH 2026', + 'USC 8.3000 PER POUND (EIGHT USC AND THIRTY CENTS) ON ICE Cotton #2 MARCH 2026', + )]) + del ModuleTestCase