02.04.26
This commit is contained in:
@@ -3931,9 +3931,14 @@
|
|||||||
</table:table-cell>
|
</table:table-cell>
|
||||||
<table:table-cell table:style-name="Tableau5.A1" office:value-type="string">
|
<table:table-cell table:style-name="Tableau5.A1" office:value-type="string">
|
||||||
<text:p text:style-name="P26">QUANTITY: <text:placeholder text:placeholder-type="text"><format_number(invoice.report_lbs, invoice.party.lang) if invoice.report_lbs != '' else ''></text:placeholder><text:s/>LBS (<text:placeholder text:placeholder-type="text"><format_number(invoice.report_net, invoice.party.lang) if invoice.report_net != '' else ''></text:placeholder> MTS)</text:p>
|
<text:p text:style-name="P26">QUANTITY: <text:placeholder text:placeholder-type="text"><format_number(invoice.report_lbs, invoice.party.lang) if invoice.report_lbs != '' else ''></text:placeholder><text:s/>LBS (<text:placeholder text:placeholder-type="text"><format_number(invoice.report_net, invoice.party.lang) if invoice.report_net != '' else ''></text:placeholder> MTS)</text:p>
|
||||||
|
<text:p text:style-name="P26"><text:placeholder text:placeholder-type="text"><for each="line in invoice.report_quantity_lines.splitlines()"></text:placeholder></text:p>
|
||||||
|
<text:p text:style-name="P26"><text:placeholder text:placeholder-type="text"><line></text:placeholder></text:p>
|
||||||
|
<text:p text:style-name="P26"><text:placeholder text:placeholder-type="text"></for></text:placeholder></text:p>
|
||||||
<text:p text:style-name="P21"><text:placeholder text:placeholder-type="text"><invoice.report_description_upper or invoice.report_product_description></text:placeholder><text:s/>CROP <text:placeholder text:placeholder-type="text"><invoice.report_crop_name></text:placeholder></text:p>
|
<text:p text:style-name="P21"><text:placeholder text:placeholder-type="text"><invoice.report_description_upper or invoice.report_product_description></text:placeholder><text:s/>CROP <text:placeholder text:placeholder-type="text"><invoice.report_crop_name></text:placeholder></text:p>
|
||||||
<text:p text:style-name="P21"><text:placeholder text:placeholder-type="text"><invoice.report_attributes_name></text:placeholder></text:p>
|
<text:p text:style-name="P21"><text:placeholder text:placeholder-type="text"><invoice.report_attributes_name></text:placeholder></text:p>
|
||||||
<text:p text:style-name="P18">At <text:placeholder text:placeholder-type="text"><invoice.report_rate_currency_upper></text:placeholder><text:s/><text:placeholder text:placeholder-type="text"><invoice.report_rate_value></text:placeholder><text:s/>PER <text:placeholder text:placeholder-type="text"><invoice.report_rate_unit_upper></text:placeholder><text:s/>(<text:placeholder text:placeholder-type="text"><invoice.report_rate_price_words></text:placeholder>) <text:placeholder text:placeholder-type="text"><invoice.report_rate_pricing_text></text:placeholder></text:p>
|
<text:p text:style-name="P18"><text:placeholder text:placeholder-type="text"><for each="line in invoice.report_rate_lines.splitlines()"></text:placeholder></text:p>
|
||||||
|
<text:p text:style-name="P18">At <text:placeholder text:placeholder-type="text"><line></text:placeholder></text:p>
|
||||||
|
<text:p text:style-name="P18"><text:placeholder text:placeholder-type="text"></for></text:placeholder></text:p>
|
||||||
<text:p text:style-name="P18"/>
|
<text:p text:style-name="P18"/>
|
||||||
<text:p text:style-name="P18"/>
|
<text:p text:style-name="P18"/>
|
||||||
<text:p text:style-name="P32"><text:placeholder text:placeholder-type="text"><invoice.report_incoterm></text:placeholder></text:p>
|
<text:p text:style-name="P32"><text:placeholder text:placeholder-type="text"><invoice.report_incoterm></text:placeholder></text:p>
|
||||||
@@ -4009,7 +4014,9 @@
|
|||||||
<table:table-column table:style-name="Tableau8.B"/>
|
<table:table-column table:style-name="Tableau8.B"/>
|
||||||
<table:table-row table:style-name="Tableau8.1">
|
<table:table-row table:style-name="Tableau8.1">
|
||||||
<table:table-cell table:style-name="Tableau8.A1" office:value-type="string">
|
<table:table-cell table:style-name="Tableau8.A1" office:value-type="string">
|
||||||
<text:p text:style-name="P14">At <text:placeholder text:placeholder-type="text"><invoice.report_rate_currency_upper></text:placeholder><text:s/><text:placeholder text:placeholder-type="text"><invoice.report_rate_value></text:placeholder><text:s/>PER <text:placeholder text:placeholder-type="text"><invoice.report_rate_unit_upper></text:placeholder><text:s/>(<text:placeholder text:placeholder-type="text"><invoice.report_rate_price_words></text:placeholder>) <text:placeholder text:placeholder-type="text"><invoice.report_rate_pricing_text></text:placeholder></text:p>
|
<text:p text:style-name="P14"><text:placeholder text:placeholder-type="text"><for each="line in invoice.report_rate_lines.splitlines()"></text:placeholder></text:p>
|
||||||
|
<text:p text:style-name="P14">At <text:placeholder text:placeholder-type="text"><line></text:placeholder></text:p>
|
||||||
|
<text:p text:style-name="P14"><text:placeholder text:placeholder-type="text"></for></text:placeholder></text:p>
|
||||||
<text:p text:style-name="P14"/>
|
<text:p text:style-name="P14"/>
|
||||||
<text:p text:style-name="P14">FREIGHT VALUE: <text:placeholder text:placeholder-type="text"><invoice.report_freight_currency_symbol></text:placeholder><text:s/><text:placeholder text:placeholder-type="text"><format_number(invoice.report_freight_amount, invoice.party.lang) if invoice.report_freight_amount != '' else ''></text:placeholder></text:p>
|
<text:p text:style-name="P14">FREIGHT VALUE: <text:placeholder text:placeholder-type="text"><invoice.report_freight_currency_symbol></text:placeholder><text:s/><text:placeholder text:placeholder-type="text"><format_number(invoice.report_freight_amount, invoice.party.lang) if invoice.report_freight_amount != '' else ''></text:placeholder></text:p>
|
||||||
<text:p text:style-name="P14"/>
|
<text:p text:style-name="P14"/>
|
||||||
|
|||||||
@@ -94,6 +94,10 @@ Source code: `modules/purchase_trade/invoice.py`
|
|||||||
- Usage: poids net converti en LBS
|
- Usage: poids net converti en LBS
|
||||||
- Source de verite: conversion de `report_net`
|
- Source de verite: conversion de `report_net`
|
||||||
|
|
||||||
|
- `report_quantity_lines`
|
||||||
|
- Usage: detail quantite multi-lignes pour les templates facture
|
||||||
|
- Source de verite: `sale.report_quantity_lines` si vente source, sinon aggregation des `account.invoice.line`
|
||||||
|
|
||||||
### Bloc prix type `sale_ict`
|
### Bloc prix type `sale_ict`
|
||||||
|
|
||||||
- `report_rate_currency_upper`
|
- `report_rate_currency_upper`
|
||||||
@@ -116,6 +120,10 @@ Source code: `modules/purchase_trade/invoice.py`
|
|||||||
- Usage: texte de pricing additionnel
|
- Usage: texte de pricing additionnel
|
||||||
- Source de verite: premiere `account.invoice.line` de type `line`
|
- Source de verite: premiere `account.invoice.line` de type `line`
|
||||||
|
|
||||||
|
- `report_rate_lines`
|
||||||
|
- Usage: detail multi-lignes du bloc `At ... PER ...`
|
||||||
|
- Source de verite: `sale.report_price_lines` si vente source, sinon aggregation des `account.invoice.line`
|
||||||
|
|
||||||
### Logistique / shipment
|
### Logistique / shipment
|
||||||
|
|
||||||
- `report_shipment`
|
- `report_shipment`
|
||||||
@@ -245,6 +253,7 @@ Source code: `modules/purchase_trade/sale.py`
|
|||||||
- `report_qt`
|
- `report_qt`
|
||||||
- `report_total_quantity`
|
- `report_total_quantity`
|
||||||
- `report_quantity_unit_upper`
|
- `report_quantity_unit_upper`
|
||||||
|
- `report_quantity_lines`
|
||||||
- `report_nb_bale`
|
- `report_nb_bale`
|
||||||
- `report_deal`
|
- `report_deal`
|
||||||
- `report_packing`
|
- `report_packing`
|
||||||
|
|||||||
@@ -6,12 +6,30 @@ from trytond.pool import Pool, PoolMeta
|
|||||||
class Invoice(metaclass=PoolMeta):
|
class Invoice(metaclass=PoolMeta):
|
||||||
__name__ = 'account.invoice'
|
__name__ = 'account.invoice'
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _format_report_number(value, digits='0.0000', keep_trailing_decimal=False,
|
||||||
|
strip_trailing_zeros=True):
|
||||||
|
value = Decimal(str(value or 0)).quantize(Decimal(digits))
|
||||||
|
text = format(value, 'f')
|
||||||
|
if strip_trailing_zeros:
|
||||||
|
text = text.rstrip('0').rstrip('.')
|
||||||
|
if keep_trailing_decimal and '.' not in text:
|
||||||
|
text += '.0'
|
||||||
|
return text or '0'
|
||||||
|
|
||||||
def _get_report_invoice_line(self):
|
def _get_report_invoice_line(self):
|
||||||
for line in self.lines or []:
|
for line in self.lines or []:
|
||||||
if getattr(line, 'type', None) == 'line':
|
if getattr(line, 'type', None) == 'line':
|
||||||
return line
|
return line
|
||||||
return self.lines[0] if self.lines else None
|
return self.lines[0] if self.lines else None
|
||||||
|
|
||||||
|
def _get_report_invoice_lines(self):
|
||||||
|
lines = [
|
||||||
|
line for line in (self.lines or [])
|
||||||
|
if getattr(line, 'type', None) == 'line'
|
||||||
|
]
|
||||||
|
return lines or list(self.lines or [])
|
||||||
|
|
||||||
def _get_report_purchase(self):
|
def _get_report_purchase(self):
|
||||||
purchases = list(self.purchases or [])
|
purchases = list(self.purchases or [])
|
||||||
return purchases[0] if purchases else None
|
return purchases[0] if purchases else None
|
||||||
@@ -146,6 +164,32 @@ class Invoice(metaclass=PoolMeta):
|
|||||||
return trade.report_price
|
return trade.report_price
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
@property
|
||||||
|
def report_quantity_lines(self):
|
||||||
|
sale = self._get_report_sale()
|
||||||
|
if sale and getattr(sale, 'report_quantity_lines', None):
|
||||||
|
return sale.report_quantity_lines
|
||||||
|
details = []
|
||||||
|
for line in self._get_report_invoice_lines():
|
||||||
|
quantity = getattr(line, 'report_net', '')
|
||||||
|
if quantity == '':
|
||||||
|
quantity = getattr(line, 'quantity', '')
|
||||||
|
if quantity == '':
|
||||||
|
continue
|
||||||
|
quantity_text = self._format_report_number(
|
||||||
|
quantity, keep_trailing_decimal=True)
|
||||||
|
unit = getattr(line, 'unit', None)
|
||||||
|
unit_name = unit.rec_name.upper() if unit and unit.rec_name else ''
|
||||||
|
lbs = getattr(line, 'report_lbs', '')
|
||||||
|
parts = [quantity_text, unit_name]
|
||||||
|
if lbs != '':
|
||||||
|
parts.append(
|
||||||
|
f"({self._format_report_number(lbs, digits='0.01')} LBS)")
|
||||||
|
detail = ' '.join(part for part in parts if part)
|
||||||
|
if detail:
|
||||||
|
details.append(detail)
|
||||||
|
return '\n'.join(details)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def report_rate_currency_upper(self):
|
def report_rate_currency_upper(self):
|
||||||
line = self._get_report_invoice_line()
|
line = self._get_report_invoice_line()
|
||||||
@@ -181,6 +225,35 @@ class Invoice(metaclass=PoolMeta):
|
|||||||
return line.report_rate_pricing_text
|
return line.report_rate_pricing_text
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
@property
|
||||||
|
def report_rate_lines(self):
|
||||||
|
sale = self._get_report_sale()
|
||||||
|
if sale and getattr(sale, 'report_price_lines', None):
|
||||||
|
return sale.report_price_lines
|
||||||
|
details = []
|
||||||
|
for line in self._get_report_invoice_lines():
|
||||||
|
currency = getattr(line, 'report_rate_currency_upper', '') or ''
|
||||||
|
value = getattr(line, 'report_rate_value', '')
|
||||||
|
value_text = ''
|
||||||
|
if value != '':
|
||||||
|
value_text = self._format_report_number(
|
||||||
|
value, strip_trailing_zeros=False)
|
||||||
|
unit = getattr(line, 'report_rate_unit_upper', '') or ''
|
||||||
|
words = getattr(line, 'report_rate_price_words', '') or ''
|
||||||
|
pricing_text = getattr(line, 'report_rate_pricing_text', '') or ''
|
||||||
|
detail = ' '.join(
|
||||||
|
part for part in [
|
||||||
|
currency,
|
||||||
|
value_text,
|
||||||
|
'PER' if unit else '',
|
||||||
|
unit,
|
||||||
|
f"({words})" if words else '',
|
||||||
|
pricing_text,
|
||||||
|
] if part)
|
||||||
|
if detail:
|
||||||
|
details.append(detail)
|
||||||
|
return '\n'.join(details)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def report_payment_date(self):
|
def report_payment_date(self):
|
||||||
trade = self._get_report_trade()
|
trade = self._get_report_trade()
|
||||||
|
|||||||
@@ -408,6 +408,29 @@ class Sale(metaclass=PoolMeta):
|
|||||||
total = sum(Decimal(str(line.quantity or 0)) for line in lines)
|
total = sum(Decimal(str(line.quantity or 0)) for line in lines)
|
||||||
return quantity_to_words(total)
|
return quantity_to_words(total)
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
@property
|
||||||
|
def report_quantity_lines(self):
|
||||||
|
lines = self._get_report_lines()
|
||||||
|
if not lines:
|
||||||
|
return ''
|
||||||
|
details = []
|
||||||
|
for line in lines:
|
||||||
|
quantity = self._format_report_number(
|
||||||
|
line.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)))
|
||||||
|
period = line.del_period.description if getattr(line, 'del_period', None) else ''
|
||||||
|
detail = ' '.join(
|
||||||
|
part for part in [
|
||||||
|
quantity,
|
||||||
|
unit,
|
||||||
|
f"({words})",
|
||||||
|
f"- {period}" if period else '',
|
||||||
|
] if part)
|
||||||
|
if detail:
|
||||||
|
details.append(detail)
|
||||||
|
return '\n'.join(details)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def report_nb_bale(self):
|
def report_nb_bale(self):
|
||||||
|
|||||||
@@ -185,6 +185,12 @@ class PurchaseTradeTestCase(ModuleTestCase):
|
|||||||
self.assertEqual(sale.report_quantity_unit_upper, 'MT')
|
self.assertEqual(sale.report_quantity_unit_upper, 'MT')
|
||||||
self.assertEqual(sale.report_qt, 'TWO THOUSAND METRIC TONS')
|
self.assertEqual(sale.report_qt, 'TWO THOUSAND METRIC TONS')
|
||||||
self.assertEqual(sale.report_nb_bale, '')
|
self.assertEqual(sale.report_nb_bale, '')
|
||||||
|
self.assertEqual(
|
||||||
|
sale.report_quantity_lines.splitlines(),
|
||||||
|
[
|
||||||
|
'1000.0 MT (ONE THOUSAND METRIC TONS) - MARCH 2026',
|
||||||
|
'1000.0 MT (ONE THOUSAND METRIC TONS) - MAY 2026',
|
||||||
|
])
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
sale.report_shipment_periods.splitlines(),
|
sale.report_shipment_periods.splitlines(),
|
||||||
['MARCH 2026', 'MAY 2026'])
|
['MARCH 2026', 'MAY 2026'])
|
||||||
|
|||||||
@@ -4095,6 +4095,15 @@
|
|||||||
<text:p text:style-name="P39">
|
<text:p text:style-name="P39">
|
||||||
<text:placeholder text:placeholder-type="text"><sale.report_nb_bale></text:placeholder>
|
<text:placeholder text:placeholder-type="text"><sale.report_nb_bale></text:placeholder>
|
||||||
</text:p>
|
</text:p>
|
||||||
|
<text:p text:style-name="P39">
|
||||||
|
<text:placeholder text:placeholder-type="text"><for each="line in sale.report_quantity_lines.splitlines()"></text:placeholder>
|
||||||
|
</text:p>
|
||||||
|
<text:p text:style-name="P39">
|
||||||
|
<text:placeholder text:placeholder-type="text"><line></text:placeholder>
|
||||||
|
</text:p>
|
||||||
|
<text:p text:style-name="P39">
|
||||||
|
<text:placeholder text:placeholder-type="text"></for></text:placeholder>
|
||||||
|
</text:p>
|
||||||
<text:p text:style-name="P39" />
|
<text:p text:style-name="P39" />
|
||||||
</table:table-cell>
|
</table:table-cell>
|
||||||
</table:table-row>
|
</table:table-row>
|
||||||
|
|||||||
Reference in New Issue
Block a user