feat(numbering): wire CoC/RCV/DLV/PU into parent-numbered mixin + rename counters

Per-model counter fields on sale.order renamed to x_fc_pn_*_count
to avoid collision with pre-existing compute fields of the same
short name in bridge_mrp / receiving / configurator (silent
compute-override was suppressing the storage). 4 child models
(fp.certificate, fp.receiving, fusion.plating.delivery,
fusion.plating.pickup.request) now derive names as PFX-<parent>
with -NN suffix from the 2nd onward.

fusion.plating.pickup.request gains a sale_order_id field
(optional) so pickups created against an SO get parent-derived
names, while standalone pickups (pre-SO) fall back to PU/YYYY/NNNN.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsinghpal
2026-05-12 13:30:37 -04:00
parent 765a0a4c82
commit 0d85063b5e
17 changed files with 489 additions and 64 deletions

View File

@@ -51,7 +51,7 @@ class AccountMove(models.Model):
return 'CN' if self.move_type == 'out_refund' else 'IN'
def _fp_parent_counter_field(self):
return 'x_fc_cn_count' if self.move_type == 'out_refund' else 'x_fc_invoice_count'
return 'x_fc_pn_cn_count' if self.move_type == 'out_refund' else 'x_fc_pn_invoice_count'
# =================================================================
# Create override: block off-flow + assign parent-derived name

View File

@@ -17,6 +17,15 @@ class ResUsers(models.Model):
'a different value and saves, it persists here for every '
'future job and step.',
)
x_fc_signature_image = fields.Binary(
string='Plating Signature',
attachment=True,
help='Drawn or uploaded signature image. Used in WO detail and '
'certificate reports for any signature-type prompt this user '
'signed off on; falls back to typed initials when blank. '
'Capture it once in user preferences; it stamps every '
'future sign-off automatically.',
)
@api.model
def _fp_default_initials(self):

View File

@@ -55,17 +55,24 @@ class SaleOrder(models.Model):
# Per-model counters — monotonic, never decrement. Source of truth
# for the next sibling's x_fc_doc_index. Updated via row-locked SQL
# in fp.parent.numbered.mixin so concurrent creates can't drift.
x_fc_wo_count = fields.Integer(string='WO Count', readonly=True, copy=False, default=0)
x_fc_invoice_count = fields.Integer(string='Invoice Count', readonly=True, copy=False, default=0)
x_fc_cn_count = fields.Integer(string='Credit Note Count', readonly=True, copy=False, default=0)
x_fc_cert_count = fields.Integer(string='Certificate Count', readonly=True, copy=False, default=0)
x_fc_delivery_count = fields.Integer(string='Delivery Count', readonly=True, copy=False, default=0)
x_fc_receiving_count = fields.Integer(string='Receiving Count', readonly=True, copy=False, default=0)
x_fc_pickup_count = fields.Integer(string='Pickup Count', readonly=True, copy=False, default=0)
x_fc_ncr_count = fields.Integer(string='NCR Count', readonly=True, copy=False, default=0)
x_fc_capa_count = fields.Integer(string='CAPA Count', readonly=True, copy=False, default=0)
x_fc_hold_count = fields.Integer(string='Hold Count', readonly=True, copy=False, default=0)
x_fc_rma_count = fields.Integer(string='RMA Count', readonly=True, copy=False, default=0)
#
# Naming: `x_fc_pn_*_count` — the `pn_` infix distinguishes our
# storage counters from pre-existing compute fields (e.g. the
# `x_fc_delivery_count` compute in bridge_mrp, `x_fc_ncr_count`
# in configurator, `x_fc_receiving_count` in fp_receiving) which
# are surface counters for smart buttons. Distinct names avoid
# the silent compute-override that made Tasks 3+9 fail until 9.5.
x_fc_pn_wo_count = fields.Integer(string='Parent: WO Count', readonly=True, copy=False, default=0)
x_fc_pn_invoice_count = fields.Integer(string='Parent: Invoice Count', readonly=True, copy=False, default=0)
x_fc_pn_cn_count = fields.Integer(string='Parent: Credit Note Count', readonly=True, copy=False, default=0)
x_fc_pn_cert_count = fields.Integer(string='Parent: Certificate Count', readonly=True, copy=False, default=0)
x_fc_pn_delivery_count = fields.Integer(string='Parent: Delivery Count', readonly=True, copy=False, default=0)
x_fc_pn_receiving_count = fields.Integer(string='Parent: Receiving Count', readonly=True, copy=False, default=0)
x_fc_pn_pickup_count = fields.Integer(string='Parent: Pickup Count', readonly=True, copy=False, default=0)
x_fc_pn_ncr_count = fields.Integer(string='Parent: NCR Count', readonly=True, copy=False, default=0)
x_fc_pn_capa_count = fields.Integer(string='Parent: CAPA Count', readonly=True, copy=False, default=0)
x_fc_pn_hold_count = fields.Integer(string='Parent: Hold Count', readonly=True, copy=False, default=0)
x_fc_pn_rma_count = fields.Integer(string='Parent: RMA Count', readonly=True, copy=False, default=0)
# ------------------------------------------------------------------
# Phase 4 (Sub 11) — workflow-stage field + assigned-manager field
@@ -507,10 +514,10 @@ class SaleOrder(models.Model):
# WO additions pick up from here via the mixin standard path.
if parent and n_groups:
self.env.cr.execute(
"UPDATE sale_order SET x_fc_wo_count = %s WHERE id = %s",
"UPDATE sale_order SET x_fc_pn_wo_count = %s WHERE id = %s",
(n_groups, self.id),
)
self.invalidate_recordset(['x_fc_wo_count'])
self.invalidate_recordset(['x_fc_pn_wo_count'])
return True
# ------------------------------------------------------------------