feat(jobs): mirror delivery_method/ship_via/invoice_strategy on fp.job

Tier 3 of the SO->fp.job persistence audit. Three logistics/billing
fields surface on fp.job as related read-only (not stored) mirrors:

- x_fc_delivery_method - Local Delivery / Shipping Partner / Customer
  Pickup. Cargo classification used by logistics planning.
- x_fc_ship_via - Carrier name (UPS, FedEx, customer pickup, etc.).
- x_fc_invoice_strategy - Deposit / Progress / Net Terms / COD-Prepay.
  Read by the invoicing module's hooks; mirroring on the WO is for
  manager visibility only.

These were intentionally chosen as related (not stored persisted)
because the SO is the authoritative source - the existing downstream
code (delivery + invoicing modules) already reads them off SO directly.
A stored copy would risk drift. Related auto-follows SO updates.

Same three fields also mirrored on sale.order.line as stored related
for per-line list visibility.

Closes the SO->fp.job persistence audit. All 10 operational fields
identified now flow through to the WO (7 stored + populated at confirm,
3 related read-only).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsinghpal
2026-05-12 08:39:12 -04:00
parent 15eac309ee
commit cba9a6da6b
6 changed files with 45 additions and 3 deletions

View File

@@ -5,7 +5,7 @@
{ {
'name': 'Fusion Plating', 'name': 'Fusion Plating',
'version': '19.0.18.15.7', 'version': '19.0.18.15.8',
'category': 'Manufacturing/Plating', 'category': 'Manufacturing/Plating',
'summary': 'Core plating / metal finishing ERP: facilities, processes, tanks, baths, jobs, operators.', 'summary': 'Core plating / metal finishing ERP: facilities, processes, tanks, baths, jobs, operators.',
'description': """ 'description': """

View File

@@ -43,6 +43,9 @@
<field name="x_fc_rush_order"/> <field name="x_fc_rush_order"/>
<field name="x_fc_planned_start_date"/> <field name="x_fc_planned_start_date"/>
<field name="x_fc_internal_deadline"/> <field name="x_fc_internal_deadline"/>
<field name="x_fc_delivery_method"/>
<field name="x_fc_ship_via"/>
<field name="x_fc_invoice_strategy"/>
</group> </group>
<group name="x_fc_notes" string="Notes"> <group name="x_fc_notes" string="Notes">
<field name="x_fc_internal_note" nolabel="1" placeholder="Internal note (not shown to customer)…"/> <field name="x_fc_internal_note" nolabel="1" placeholder="Internal note (not shown to customer)…"/>

View File

@@ -5,7 +5,7 @@
{ {
'name': 'Fusion Plating — Configurator', 'name': 'Fusion Plating — Configurator',
'version': '19.0.18.10.1', 'version': '19.0.18.10.2',
'category': 'Manufacturing/Plating', 'category': 'Manufacturing/Plating',
'summary': 'Quotation configurator with part catalog, coating configs, and formula-based pricing engine.', 'summary': 'Quotation configurator with part catalog, coating configs, and formula-based pricing engine.',
'description': """ 'description': """

View File

@@ -684,3 +684,22 @@ class SaleOrderLine(models.Model):
readonly=True, readonly=True,
store=True, store=True,
) )
x_fc_delivery_method = fields.Selection(
related='order_id.x_fc_delivery_method',
string='Delivery Method',
readonly=True,
store=True,
)
x_fc_ship_via = fields.Char(
related='order_id.x_fc_ship_via',
string='Ship Via',
readonly=True,
store=True,
)
x_fc_invoice_strategy = fields.Selection(
related='order_id.x_fc_invoice_strategy',
string='Invoice Strategy',
readonly=True,
store=True,
)

View File

@@ -3,7 +3,7 @@
# License OPL-1 (Odoo Proprietary License v1.0) # License OPL-1 (Odoo Proprietary License v1.0)
{ {
'name': 'Fusion Plating — Native Jobs', 'name': 'Fusion Plating — Native Jobs',
'version': '19.0.8.21.3', 'version': '19.0.8.21.4',
'category': 'Manufacturing/Plating', 'category': 'Manufacturing/Plating',
'summary': 'Native plating job model — replaces mrp.production / mrp.workorder bridge.', 'summary': 'Native plating job model — replaces mrp.production / mrp.workorder bridge.',
'author': 'Nexa Systems Inc.', 'author': 'Nexa Systems Inc.',

View File

@@ -23,6 +23,26 @@ _logger = logging.getLogger(__name__)
class FpJob(models.Model): class FpJob(models.Model):
_inherit = 'fp.job' _inherit = 'fp.job'
# ---- Tier 3 mirrors from sale.order -----------------------------
# Related (not stored) — pure display mirrors. Values may change on
# the SO after job confirm (e.g. customer changes carrier preference)
# and the WO should reflect the latest; related auto-follows.
x_fc_delivery_method = fields.Selection(
related='sale_order_id.x_fc_delivery_method',
string='Delivery Method',
readonly=True,
)
x_fc_ship_via = fields.Char(
related='sale_order_id.x_fc_ship_via',
string='Ship Via',
readonly=True,
)
x_fc_invoice_strategy = fields.Selection(
related='sale_order_id.x_fc_invoice_strategy',
string='Invoice Strategy',
readonly=True,
)
part_catalog_id = fields.Many2one( part_catalog_id = fields.Many2one(
'fp.part.catalog', 'fp.part.catalog',
string='Part', string='Part',