Melya template

This commit is contained in:
2026-07-07 08:40:18 +02:00
parent 2ffd99b03a
commit ae39ff2f7d
3 changed files with 152 additions and 14 deletions

View File

@@ -1024,6 +1024,92 @@ class ShipmentIn(metaclass=PoolMeta):
getattr(lot_qt, 'lot_s', None)))
return sales
def _get_report_physical_lots(self):
lots = []
seen = set()
for move in (self.incoming_moves or []):
lot = getattr(move, 'lot', None)
if not lot or getattr(lot, 'lot_type', None) != 'physic':
continue
lot_id = getattr(lot, 'id', None)
key = lot_id if lot_id is not None else id(lot)
if key in seen:
continue
seen.add(key)
lots.append(lot)
return lots
def _get_report_invoice_lines_from_physical_lots(self):
lines = []
seen = set()
for lot in self._get_report_physical_lots():
for name in (
'sale_invoice_line',
'sale_invoice_line_prov',
'invoice_line',
'invoice_line_prov'):
line = getattr(lot, name, None)
if not line:
continue
line_id = getattr(line, 'id', None)
key = line_id if line_id is not None else id(line)
if key in seen:
continue
seen.add(key)
lines.append(line)
break
return lines
@staticmethod
def _get_report_invoice_line_snapshot_quantity(line):
invoice = getattr(line, 'invoice', None)
weights = getattr(invoice, '_get_report_invoice_line_weights', None)
if callable(weights):
quantity, _ = weights(line)
unit_getter = getattr(invoice, '_get_report_invoice_line_unit', None)
unit = unit_getter(line) if callable(unit_getter) else None
return Decimal(str(quantity or 0)), unit
snapshots = list(getattr(line, 'lot_weight_snapshots', []) or [])
if snapshots:
quantity = sum(
Decimal(str(getattr(snapshot, 'net_quantity', 0) or 0))
for snapshot in snapshots)
unit = getattr(snapshots[0], 'unit', None)
return quantity, unit
report_net = getattr(line, 'report_net', '')
try:
quantity = Decimal(str(report_net or 0))
except Exception:
quantity = Decimal(0)
if not quantity:
quantity = Decimal(str(getattr(line, 'quantity', 0) or 0))
return quantity, getattr(line, 'unit', None)
@staticmethod
def _get_report_unit_text(unit):
return (
getattr(unit, 'symbol', None)
or getattr(unit, 'rec_name', None)
or getattr(unit, 'name', None)
or '')
def _get_report_insurance_invoice_quantity(self):
total = Decimal(0)
unit = None
matched = False
for line in self._get_report_invoice_lines_from_physical_lots():
quantity, line_unit = self._get_report_invoice_line_snapshot_quantity(
line)
total += quantity
if not unit and line_unit:
unit = line_unit
matched = True
if not matched:
return None, None
return total, unit
def _get_report_weight_totals(self):
net = Decimal('0')
gross = Decimal('0')
@@ -1091,20 +1177,49 @@ class ShipmentIn(metaclass=PoolMeta):
@property
def report_insurance_account_of(self):
line = self._get_report_trade_line()
trade = getattr(line, 'sale', None) or getattr(line, 'purchase', None)
party = getattr(trade, 'party', None) if trade else None
if party:
return party.rec_name or ''
return getattr(self.supplier, 'rec_name', '') or ''
company = getattr(self, 'company', None)
party = getattr(company, 'party', None) if company else None
if not party:
return ''
address_get = getattr(party, 'address_get', None)
address = address_get() if callable(address_get) else None
return (
getattr(address, 'party_name', None)
or getattr(address, 'party_full_name', None)
or getattr(party, 'rec_name', None)
or '')
@property
def report_insurance_goods_description(self):
name = self.report_product_name
description = self.report_product_description
if description and description != name:
return ' - '.join(part for part in [name, description] if part)
return name or description
product = (
' - '.join(part for part in [name, description] if part)
if description and description != name else name or description)
quantity, unit = self._get_report_insurance_invoice_quantity()
if quantity is None:
return product
quantity_text = self._format_report_quantity(quantity, '0.0001')
unit_text = self._get_report_unit_text(unit)
quantity_label = ''.join(
part for part in [quantity_text, unit_text] if part)
return ' '.join(part for part in [quantity_label, product] if part)
@property
def report_insurance_invoice_number(self):
numbers = []
seen = set()
for line in self._get_report_invoice_lines_from_physical_lots():
invoice = getattr(line, 'invoice', None)
number = (
getattr(invoice, 'number', None)
or getattr(invoice, 'rec_name', None)
or '')
if not number or number in seen:
continue
seen.add(number)
numbers.append(number)
return ' '.join(numbers)
@property
def report_insurance_loading_port(self):

View File

@@ -6318,7 +6318,24 @@ class PurchaseTradeTestCase(ModuleTestCase):
)
product = Mock(name='COTTON UPLAND', description='RAW WHITE COTTON')
line = Mock(product=product, sale=sale)
lot = Mock(sale_line=line, line=None)
invoice = Mock(number='INV-001')
snapshot_unit = Mock(symbol='mt', rec_name='MT')
invoice_line = Mock(
invoice=invoice,
lot_weight_snapshots=[
Mock(net_quantity=Decimal('24.0000'), unit=snapshot_unit),
],
)
lot = Mock(
id=1,
lot_type='physic',
sale_line=line,
line=None,
sale_invoice_line=invoice_line,
sale_invoice_line_prov=None,
invoice_line=None,
invoice_line_prov=None,
)
move = Mock(lot=lot, product=product)
shipment.incoming_moves = [move]
shipment.moves = [move]
@@ -6343,19 +6360,24 @@ class PurchaseTradeTestCase(ModuleTestCase):
shipment.company = Mock(
party=Mock(
rec_name='MELYA SA',
address_get=Mock(return_value=Mock(city='GENEVA')),
address_get=Mock(return_value=Mock(
city='GENEVA',
party_name='MELYA INTERNATIONAL TRADING SA')),
)
)
self.assertEqual(
shipment.report_insurance_certificate_number, 'BL-001')
self.assertEqual(
shipment.report_insurance_account_of, 'SGT FR')
shipment.report_insurance_account_of,
'MELYA INTERNATIONAL TRADING SA')
self.assertEqual(
shipment.report_insurance_goods_description,
'COTTON UPLAND - RAW WHITE COTTON')
'24mt COTTON UPLAND - RAW WHITE COTTON')
self.assertEqual(
shipment.report_insurance_order_reference, 'P-12 S-34')
self.assertEqual(
shipment.report_insurance_invoice_number, 'INV-001')
self.assertEqual(
shipment.report_insurance_amount, 'USD 1234.56')
self.assertEqual(

View File

@@ -1031,12 +1031,13 @@
</text:sequence-decls>
<text:p text:style-name="P46"/>
<text:h text:style-name="Heading_20_1" text:outline-level="1">Certificate of Insurance No. <text:span text:style-name="Police_20_par_20_défaut"><text:span text:style-name="T3"><text:placeholder text:placeholder-type="text">&lt;records[0].report_insurance_certificate_number or &apos;&apos;&gt;</text:placeholder></text:span></text:span></text:h>
<text:h text:style-name="Heading_20_3" text:outline-level="3">This is to certify that we have insured for account of <text:span text:style-name="Police_20_par_20_défaut"><text:span text:style-name="T3"><text:placeholder text:placeholder-type="text">&lt;records[0].company.party.rec_name if records[0].company and records[0].company.party else &apos;&apos;&gt;</text:placeholder></text:span></text:span></text:h>
<text:h text:style-name="Heading_20_3" text:outline-level="3">This is to certify that we have insured for account of <text:span text:style-name="Police_20_par_20_défaut"><text:span text:style-name="T3"><text:placeholder text:placeholder-type="text">&lt;records[0].report_insurance_account_of or &apos;&apos;&gt;</text:placeholder></text:span></text:span></text:h>
<text:p text:style-name="P19"/>
<text:p text:style-name="P20"/>
<text:p text:style-name="P21"><text:span text:style-name="Police_20_par_20_défaut"><text:span text:style-name="T12">Marine Insurance</text:span></text:span><text:span text:style-name="Police_20_par_20_défaut"><text:span text:style-name="T13"> </text:span></text:span><text:span text:style-name="Police_20_par_20_défaut"><text:span text:style-name="T12">Policy</text:span></text:span><text:span text:style-name="Police_20_par_20_défaut"><text:span text:style-name="T14"> </text:span></text:span><text:span text:style-name="Police_20_par_20_défaut"><text:span text:style-name="T12">No. 4.008.227.782<text:tab/>the following shipment: Description of goods and/or</text:span></text:span><text:span text:style-name="Police_20_par_20_défaut"><text:span text:style-name="T15"> </text:span></text:span><text:span text:style-name="Police_20_par_20_défaut"><text:span text:style-name="T12">services:</text:span></text:span></text:p>
<text:p text:style-name="Text_20_body"><text:span text:style-name="Police_20_par_20_défaut"><text:span text:style-name="T16"><text:s text:c="2"/></text:span></text:span><text:span text:style-name="Police_20_par_20_défaut"><text:span text:style-name="T5"><text:placeholder text:placeholder-type="text">&lt;records[0].report_insurance_goods_description or &apos;&apos;&gt;</text:placeholder></text:span></text:span></text:p>
<text:p text:style-name="Text_20_body"><text:span text:style-name="Police_20_par_20_défaut"><text:span text:style-name="T12">Order reference: </text:span></text:span><text:span text:style-name="Police_20_par_20_défaut"><text:span text:style-name="T5"><text:placeholder text:placeholder-type="text">&lt;records[0].report_insurance_order_reference or &apos;&apos;&gt;</text:placeholder></text:span></text:span></text:p>
<text:p text:style-name="Text_20_body"><text:span text:style-name="Police_20_par_20_défaut"><text:span text:style-name="T12">Invoice no: </text:span></text:span><text:span text:style-name="Police_20_par_20_défaut"><text:span text:style-name="T5"><text:placeholder text:placeholder-type="text">&lt;records[0].report_insurance_invoice_number or &apos;&apos;&gt;</text:placeholder></text:span></text:span></text:p>
<text:p text:style-name="P22"/>
<text:p text:style-name="P22"/>
<text:p text:style-name="P22"/>