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:
@@ -24,14 +24,14 @@ class FpDelivery(models.Model):
|
||||
"""
|
||||
_name = 'fusion.plating.delivery'
|
||||
_description = 'Fusion Plating — Delivery'
|
||||
_inherit = ['mail.thread', 'mail.activity.mixin']
|
||||
_inherit = ['mail.thread', 'mail.activity.mixin', 'fp.parent.numbered.mixin']
|
||||
_order = 'scheduled_date desc, id desc'
|
||||
|
||||
name = fields.Char(
|
||||
string='Reference',
|
||||
required=True,
|
||||
copy=False,
|
||||
default=lambda self: self._default_name(),
|
||||
default='New',
|
||||
tracking=True,
|
||||
)
|
||||
partner_id = fields.Many2one(
|
||||
@@ -159,8 +159,49 @@ class FpDelivery(models.Model):
|
||||
compute='_compute_custody_count',
|
||||
)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Parent-numbered mixin hooks (2026-05-12 numbering hierarchy)
|
||||
# ------------------------------------------------------------------
|
||||
def _fp_parent_sale_order(self):
|
||||
"""No direct sale_order_id on this model — resolve via
|
||||
job_ref → fp.job.name → job.sale_order_id."""
|
||||
if not self.job_ref or 'fp.job' not in self.env:
|
||||
return self.env['sale.order']
|
||||
job = self.env['fp.job'].sudo().search(
|
||||
[('name', '=', self.job_ref)], limit=1,
|
||||
)
|
||||
return job.sale_order_id if job else self.env['sale.order']
|
||||
|
||||
def _fp_name_prefix(self):
|
||||
return 'DLV'
|
||||
|
||||
def _fp_parent_counter_field(self):
|
||||
return 'x_fc_pn_delivery_count'
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
"""Parent-derived name (DLV-<parent>[-NN]) with legacy-sequence
|
||||
fallback for deliveries that don't link back to an SO."""
|
||||
for vals in vals_list:
|
||||
if not vals.get('name'):
|
||||
vals['name'] = 'New'
|
||||
records = super().create(vals_list)
|
||||
for rec in records:
|
||||
if rec.name and rec.name != 'New':
|
||||
continue
|
||||
if not rec._fp_assign_parent_name():
|
||||
seq = self.env['ir.sequence'].next_by_code('fusion.plating.delivery') or 'New'
|
||||
self.env.cr.execute(
|
||||
"UPDATE fusion_plating_delivery SET name = %s WHERE id = %s",
|
||||
(seq, rec.id),
|
||||
)
|
||||
rec.invalidate_recordset(['name'])
|
||||
return records
|
||||
|
||||
@api.model
|
||||
def _default_name(self):
|
||||
"""Retained for any legacy caller. New code should rely on
|
||||
create() — the parent-numbered mixin sets the name there."""
|
||||
seq = self.env['ir.sequence'].next_by_code('fusion.plating.delivery')
|
||||
return seq or '/'
|
||||
|
||||
|
||||
@@ -21,16 +21,26 @@ class FpPickupRequest(models.Model):
|
||||
"""
|
||||
_name = 'fusion.plating.pickup.request'
|
||||
_description = 'Fusion Plating — Pickup Request'
|
||||
_inherit = ['mail.thread', 'mail.activity.mixin']
|
||||
_inherit = ['mail.thread', 'mail.activity.mixin', 'fp.parent.numbered.mixin']
|
||||
_order = 'requested_date desc, id desc'
|
||||
|
||||
name = fields.Char(
|
||||
string='Reference',
|
||||
required=True,
|
||||
copy=False,
|
||||
default=lambda self: self._default_name(),
|
||||
default='New',
|
||||
tracking=True,
|
||||
)
|
||||
sale_order_id = fields.Many2one(
|
||||
'sale.order',
|
||||
string='Sale Order',
|
||||
ondelete='set null',
|
||||
index=True,
|
||||
help='Sale order this pickup is associated with. Pickup may be '
|
||||
'created BEFORE the SO exists; in that case the '
|
||||
'parent-number naming falls back to the standalone '
|
||||
'PU/YYYY/NNNN sequence and the link can be set later.',
|
||||
)
|
||||
partner_id = fields.Many2one(
|
||||
'res.partner',
|
||||
string='Customer',
|
||||
@@ -126,8 +136,39 @@ class FpPickupRequest(models.Model):
|
||||
compute='_compute_custody_count',
|
||||
)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Parent-numbered mixin hooks
|
||||
# ------------------------------------------------------------------
|
||||
def _fp_parent_sale_order(self):
|
||||
return self.sale_order_id
|
||||
|
||||
def _fp_name_prefix(self):
|
||||
return 'PU'
|
||||
|
||||
def _fp_parent_counter_field(self):
|
||||
return 'x_fc_pn_pickup_count'
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
for vals in vals_list:
|
||||
if not vals.get('name'):
|
||||
vals['name'] = 'New'
|
||||
records = super().create(vals_list)
|
||||
for rec in records:
|
||||
if rec.name and rec.name != 'New':
|
||||
continue
|
||||
if not rec._fp_assign_parent_name():
|
||||
seq = self.env['ir.sequence'].next_by_code('fusion.plating.pickup.request') or 'New'
|
||||
self.env.cr.execute(
|
||||
"UPDATE fusion_plating_pickup_request SET name = %s WHERE id = %s",
|
||||
(seq, rec.id),
|
||||
)
|
||||
rec.invalidate_recordset(['name'])
|
||||
return records
|
||||
|
||||
@api.model
|
||||
def _default_name(self):
|
||||
"""Retained for legacy callers; new flow uses the create() override."""
|
||||
seq = self.env['ir.sequence'].next_by_code('fusion.plating.pickup.request')
|
||||
return seq or '/'
|
||||
|
||||
|
||||
Reference in New Issue
Block a user