Linkage
This commit is contained in:
@@ -775,10 +775,16 @@ class ShipmentIn(metaclass=PoolMeta):
|
||||
fields.One2Many('valuation.valuation.line', '', "Pnl"),
|
||||
'get_pnl_lines')
|
||||
lotqt = fields.One2Many('lot.qt','lot_shipment_in',"Lots")
|
||||
quantity = fields.Function(fields.Numeric("Quantity"),'get_quantity')
|
||||
unit = fields.Function(fields.Many2One('product.uom',"Unit"),'get_unit')
|
||||
bl_date = fields.Date("BL date")
|
||||
bl_number = fields.Char("BL number")
|
||||
quantity = fields.Function(fields.Numeric("Quantity"),'get_quantity')
|
||||
unit = fields.Function(fields.Many2One('product.uom',"Unit"),'get_unit')
|
||||
list_from_locations = fields.Function(
|
||||
fields.Char("From"), 'get_list_from_locations')
|
||||
list_to_locations = fields.Function(
|
||||
fields.Char("To"), 'get_list_to_locations')
|
||||
list_purchase_suppliers = fields.Function(
|
||||
fields.Char("Supplier"), 'get_list_purchase_suppliers')
|
||||
bl_date = fields.Date("BL date")
|
||||
bl_number = fields.Char("BL number")
|
||||
etl = fields.Date("Est. Loading")
|
||||
eta = fields.Date("🏗️ETA POL")
|
||||
etad = fields.Date("⚓ETA")
|
||||
@@ -2058,7 +2064,9 @@ class ShipmentIn(metaclass=PoolMeta):
|
||||
self._report_number(purchase),
|
||||
self._report_number(sale),
|
||||
]))
|
||||
return ' '.join(part for part in ['Linkage', numbers, reference] if part)
|
||||
vessel = self._report_rec_name(getattr(self, 'vessel', None))
|
||||
return ' '.join(part for part in [
|
||||
'Linkage', numbers, reference, vessel] if part)
|
||||
|
||||
@property
|
||||
def report_linkage_desk(self):
|
||||
@@ -3064,6 +3072,54 @@ class ShipmentIn(metaclass=PoolMeta):
|
||||
lines.append(line)
|
||||
return lines
|
||||
|
||||
@staticmethod
|
||||
def _list_rec_names(records):
|
||||
names = []
|
||||
seen = set()
|
||||
for record in records:
|
||||
name = (
|
||||
getattr(record, 'rec_name', None)
|
||||
or getattr(record, 'name', None)
|
||||
or getattr(record, 'vessel_name', None))
|
||||
if not name or name in seen:
|
||||
continue
|
||||
seen.add(name)
|
||||
names.append(name)
|
||||
return ', '.join(names)
|
||||
|
||||
def get_list_from_locations(self, name=None):
|
||||
locations = []
|
||||
for lot_qt in getattr(self, 'lotqt', []) or []:
|
||||
location = (
|
||||
getattr(lot_qt, 'planned_from_location', None)
|
||||
or getattr(self, 'from_location', None))
|
||||
if location:
|
||||
locations.append(location)
|
||||
if not locations and getattr(self, 'from_location', None):
|
||||
locations.append(self.from_location)
|
||||
return self._list_rec_names(locations)
|
||||
|
||||
def get_list_to_locations(self, name=None):
|
||||
locations = []
|
||||
for lot_qt in getattr(self, 'lotqt', []) or []:
|
||||
location = (
|
||||
getattr(lot_qt, 'planned_to_location', None)
|
||||
or getattr(self, 'to_location', None))
|
||||
if location:
|
||||
locations.append(location)
|
||||
if not locations and getattr(self, 'to_location', None):
|
||||
locations.append(self.to_location)
|
||||
return self._list_rec_names(locations)
|
||||
|
||||
def get_list_purchase_suppliers(self, name=None):
|
||||
suppliers = []
|
||||
for line in self._get_purchase_lines_from_lots():
|
||||
purchase = getattr(line, 'purchase', None)
|
||||
supplier = getattr(purchase, 'party', None)
|
||||
if supplier:
|
||||
suppliers.append(supplier)
|
||||
return self._list_rec_names(suppliers)
|
||||
|
||||
def _get_sale_lines_from_lots(self):
|
||||
lines = []
|
||||
seen = set()
|
||||
@@ -4917,6 +4973,11 @@ class LotReportLinkageRecord:
|
||||
def _get_report_linkage_lots(self):
|
||||
return [self.lot]
|
||||
|
||||
@property
|
||||
def vessel(self):
|
||||
shipment = getattr(self.lot, 'lot_shipment_in', None)
|
||||
return getattr(shipment, 'vessel', None)
|
||||
|
||||
_get_report_linkage_purchase_lines = (
|
||||
ShipmentIn._get_report_linkage_purchase_lines)
|
||||
_get_report_linkage_sale_lines = ShipmentIn._get_report_linkage_sale_lines
|
||||
|
||||
@@ -13,6 +13,22 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<field name="inherit" ref="stock.shipment_in_view_tree"/>
|
||||
<field name="name">shipment_in_tree</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain" id="stock.act_shipment_in_form_domain_all">
|
||||
<field name="sequence" eval="1"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain" id="stock.act_shipment_in_form_domain_draft">
|
||||
<field name="sequence" eval="2"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain" id="act_shipment_in_form_domain_started">
|
||||
<field name="name">Started</field>
|
||||
<field name="sequence" eval="3"/>
|
||||
<field name="domain" eval="[('state', '=', 'started')]" pyson="1"/>
|
||||
<field name="count" eval="True"/>
|
||||
<field name="act_window" ref="stock.act_shipment_in_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain" id="stock.act_shipment_in_form_domain_received">
|
||||
<field name="sequence" eval="4"/>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="lot_qt_planned_view_tree">
|
||||
<field name="model">lot.qt</field>
|
||||
<field name="type">tree</field>
|
||||
|
||||
@@ -7497,9 +7497,11 @@ description</t></is></c>
|
||||
line=purchase_line,
|
||||
sale_line=sale_line)
|
||||
shipment.incoming_moves = [SimpleNamespace(lot=lot)]
|
||||
shipment.vessel = SimpleNamespace(vessel_name='MV ATLANTIC')
|
||||
|
||||
self.assertEqual(
|
||||
shipment.report_linkage_title, 'Linkage P-10/S-20 26.0001')
|
||||
shipment.report_linkage_title,
|
||||
'Linkage P-10/S-20 26.0001 MV ATLANTIC')
|
||||
self.assertEqual(shipment.report_linkage_desk, 'Sulfuric Acid')
|
||||
self.assertEqual(shipment.report_linkage_book, 'H2SO4 Chile FY26')
|
||||
self.assertEqual(
|
||||
@@ -7702,6 +7704,7 @@ description</t></is></c>
|
||||
sale_line=sale_line,
|
||||
lot_shipment_in=SimpleNamespace(
|
||||
bl_date=datetime.date(2026, 4, 30),
|
||||
vessel=SimpleNamespace(vessel_name='MV ATLANTIC'),
|
||||
fees=[]),
|
||||
move=None)
|
||||
lot_report = SimpleNamespace(
|
||||
@@ -7715,12 +7718,12 @@ description</t></is></c>
|
||||
|
||||
self.assertEqual(
|
||||
record.report_linkage_title,
|
||||
'Linkage P-10/S-20 26.0001 - PROVISIONAL')
|
||||
'Linkage P-10/S-20 26.0001 MV ATLANTIC - PROVISIONAL')
|
||||
final_record = stock_module.LotReportLinkageRecord(
|
||||
physical_lot, lot_report, linkage_status='FINAL')
|
||||
self.assertEqual(
|
||||
final_record.report_linkage_title,
|
||||
'Linkage P-10/S-20 26.0001 - FINAL')
|
||||
'Linkage P-10/S-20 26.0001 MV ATLANTIC - FINAL')
|
||||
self.assertEqual(record.report_linkage_bl_date, 'Thursday, April 30, 2026')
|
||||
self.assertIn('Purchases', record.report_linkage_summary_groups)
|
||||
self.assertIn('Sales', record.report_linkage_summary_groups)
|
||||
@@ -10530,6 +10533,44 @@ description</t></is></c>
|
||||
)),
|
||||
[])
|
||||
|
||||
def test_shipment_in_list_columns_use_planned_lots_and_purchase_supplier(self):
|
||||
'shipment list helper columns aggregate lot plans and purchase supplier'
|
||||
ShipmentIn = Pool().get('stock.shipment.in')
|
||||
|
||||
supplier = Mock(rec_name='SUMITOMO')
|
||||
purchase = Mock(party=supplier)
|
||||
purchase_line = Mock(id=10, purchase=purchase)
|
||||
lot_p = Mock(line=purchase_line)
|
||||
shipment = ShipmentIn()
|
||||
shipment.from_location = Mock(rec_name='Fallback From')
|
||||
shipment.to_location = Mock(rec_name='Fallback To')
|
||||
shipment.lotqt = [
|
||||
Mock(
|
||||
lot_p=lot_p,
|
||||
planned_from_location=Mock(rec_name='Aomori'),
|
||||
planned_to_location=Mock(rec_name='Stockton')),
|
||||
Mock(
|
||||
lot_p=lot_p,
|
||||
planned_from_location=Mock(rec_name='Sagano'),
|
||||
planned_to_location=Mock(rec_name='Stockton')),
|
||||
]
|
||||
|
||||
self.assertEqual(shipment.get_list_from_locations(), 'Aomori, Sagano')
|
||||
self.assertEqual(shipment.get_list_to_locations(), 'Stockton')
|
||||
self.assertEqual(shipment.get_list_purchase_suppliers(), 'SUMITOMO')
|
||||
|
||||
def test_shipment_in_list_locations_fallback_to_shipment_locations(self):
|
||||
'shipment list location helpers fallback when no planned lots exist'
|
||||
ShipmentIn = Pool().get('stock.shipment.in')
|
||||
|
||||
shipment = ShipmentIn()
|
||||
shipment.from_location = Mock(rec_name='Kobe')
|
||||
shipment.to_location = Mock(rec_name='Rotterdam')
|
||||
shipment.lotqt = []
|
||||
|
||||
self.assertEqual(shipment.get_list_from_locations(), 'Kobe')
|
||||
self.assertEqual(shipment.get_list_to_locations(), 'Rotterdam')
|
||||
|
||||
def test_invoice_report_transportation_uses_truck_label(self):
|
||||
'invoice_melya Transportation displays By Truck for truck shipments'
|
||||
Invoice = Pool().get('account.invoice')
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
<field name="r_operator" width="130" optional="1"/>
|
||||
<field name="r_bl_date" width="90" optional="1"/>
|
||||
<field name="r_bl_number" width="110" optional="1"/>
|
||||
<field name="r_shipping_status" widget="badge" string="Shipping status" badge_colors="shipped:#16a34a,unshipped:#ef4444,planned:#06b6d4,scheduled:#f59e0b" width="120"/>
|
||||
<field name="r_shipping_status" widget="badge" string="Shipping status" badge_colors="shipped:#16a34a,unshipped:#ef4444,planned:#06b6d4,scheduled:#f59e0b,received:#cbd5d5" width="120"/>
|
||||
<field name="r_lot_status"/>
|
||||
<field name="r_lot_av" width="80" optional="1" tree_invisible="1"/>
|
||||
<field name="r_purchase_currency_symbol" tree_invisible="1"/>
|
||||
|
||||
@@ -4,5 +4,16 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<data>
|
||||
<xpath expr="/tree/field[@name='number']" position="after">
|
||||
<field name="bl_number"/>
|
||||
<field name="bl_date" optional="1"/>
|
||||
</xpath>
|
||||
<xpath expr="/tree/field[@name='reference']" position="after">
|
||||
<field name="vessel" string="Vessel name" optional="1"/>
|
||||
<field name="list_from_locations" optional="1"/>
|
||||
<field name="list_to_locations" optional="1"/>
|
||||
</xpath>
|
||||
<xpath expr="/tree/field[@name='supplier']" position="replace">
|
||||
<field name="carrier_" string="SSCO/Owner" expand="2" optional="0"/>
|
||||
<field name="supplier" string="Broker" optional="1"/>
|
||||
<field name="list_purchase_suppliers" optional="1"/>
|
||||
</xpath>
|
||||
</data>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user