feat(plating): Sub 5 — order-line fields (serial, job#, thickness, revision)

Four new fields on every sale.order.line, propagated through to MO,
Delivery, and Invoice for end-to-end traceability:

- fp.serial registry (new model in configurator) with smart-button
  traceability to Sale Order, MO, Delivery, Invoice, Part. M2O on SO
  line; optional; user types a customer serial or clicks Generate
  Serial for a sequence-backed one. Reverse O2M links split across
  configurator (invoice) / bridge_mrp (MO) / logistics (delivery) so
  module load order is respected.
- x_fc_job_number on SO line, auto-sequenced FP-JOB-NNNNN on SO
  confirm. Editable — shops can override for customer/legacy schemes.
- fp.coating.thickness (new child of fp.coating.config) with per-
  config discrete thickness options; x_fc_thickness_id on SO line
  domain-filtered to the line's coating. Auto-clears when coating
  changes.
- x_fc_revision_snapshot Char on SO line, frozen from
  x_fc_part_catalog_id.revision at save. Protects historical SOs from
  later catalog edits. Secondary "Revision" picker on the tree view
  lets users switch between prior revisions of the same part number;
  the Part M2O still surfaces only is_latest_revision rows.

Reports (CoC, packing slip, invoice, BoL) pick up all four via the
Sub 2 customer_line_header macro — one macro edit, four reports.

Smoke on entech: 11 assertions pass including revision snapshot,
generate-serial button, typed-serial create-on-fly, coating→thickness
domain reset, SO confirm auto job#, and MO traceability carry.

Module version bumps:
  fusion_plating_configurator  → 19.0.12.0.0
  fusion_plating_bridge_mrp    → 19.0.11.0.0
  fusion_plating_logistics     → 19.0.2.0.0 (+depends configurator)
  fusion_plating_reports       → 19.0.5.1.0

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsinghpal
2026-04-22 23:04:44 -04:00
parent bb9bcf45f8
commit 25c3f6f8d1
29 changed files with 934 additions and 21 deletions

View File

@@ -141,6 +141,25 @@ class FpDirectOrderLine(models.TransientModel):
compute='_compute_is_missing_info',
)
# ---- Sub 5 — Serial / Job# / Thickness -------------------------------
# These mirror the SO-line fields and are carried over when the wizard
# creates the sale order. Serial stays optional; Job# is left blank
# here and gets auto-assigned by action_confirm on the SO.
serial_id = fields.Many2one(
'fp.serial',
string='Serial Number',
ondelete='set null',
help='Optional. Typing a value offers to create a new serial on '
'the fly, or hit "Generate Serial" to auto-sequence.',
)
job_number = fields.Char(string='Job #')
thickness_id = fields.Many2one(
'fp.coating.thickness',
string='Thickness',
domain="[('coating_config_id', '=', coating_config_id)]",
ondelete='set null',
)
# ---- Computes ----
@api.depends('quantity', 'unit_price')
def _compute_line_subtotal(self):
@@ -157,6 +176,22 @@ class FpDirectOrderLine(models.TransientModel):
and rec.quantity
)
@api.onchange('coating_config_id')
def _onchange_coating_clears_thickness(self):
for rec in self:
if (rec.thickness_id
and rec.thickness_id.coating_config_id != rec.coating_config_id):
rec.thickness_id = False
def action_generate_serial(self):
"""Create an auto-sequenced fp.serial and assign it to this line."""
self.ensure_one()
if self.serial_id:
return False
seq = self.env['ir.sequence'].next_by_code('fp.serial') or 'FP-SN-0000'
self.serial_id = self.env['fp.serial'].create({'name': seq}).id
return False
# ---- Onchange ----
@api.onchange('quote_id')
def _onchange_quote_id(self):

View File

@@ -279,6 +279,11 @@ class FpDirectOrderWizard(models.TransientModel):
'x_fc_start_at_node_id': line.start_at_node_id.id or False,
'x_fc_is_one_off': line.is_one_off,
'x_fc_quote_id': line.quote_id.id or False,
# Sub 5 — carry serial / job# / thickness onto the SO line.
# Revision snapshot auto-fills on SO-line create from the part.
'x_fc_serial_id': line.serial_id.id or False,
'x_fc_job_number': line.job_number or False,
'x_fc_thickness_id': line.thickness_id.id or False,
}))
# 5. Create — stays in draft / quotation. Sub 1: user reviews

View File

@@ -106,6 +106,14 @@
<field name="internal_description"
optional="hide"/>
<field name="coating_config_id"/>
<field name="thickness_id"
options="{'no_create': True}"
invisible="not coating_config_id"
optional="show"/>
<field name="serial_id"
options="{'no_create_edit': False}"
optional="show"/>
<field name="job_number" optional="hide"/>
<field name="treatment_ids"
widget="many2many_tags"
optional="hide"/>