Pricing:
- Quality inherit on fp.pricing.rule adds customer_spec_id + recipe_id
- Quality inherit on fp.quote.configurator adds customer_spec_id field
+ extends _find_matching_rule with priority chain:
spec (+8) > recipe (+6) > coating (+4) > material (+2) > cert (+1)
- View inherit surfaces both new pickers on the rule form
Quality points:
- fp.quality.point now has customer_spec_ids + recipe_ids M2M filters
- Matcher (_matches + _find_matching) accepts new args
- Hook overrides on SO confirm + job confirm/done + step finish
pass spec/recipe context through to the matcher
- View surfaces both new M2M widgets
Job:
- jobs/sale_order.py wires x_fc_customer_spec_id from SO line to
fp.job.customer_spec_id on action_confirm
Cert:
- Quality inherit on fp.certificate adds customer_spec_id field +
create() override auto-fills spec_reference from spec.code+revision
Resolution priority: explicit spec_reference > cert.customer_spec_id
> SO line spec (with print_on_cert) > legacy coating fallback
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
62 lines
2.4 KiB
Python
62 lines
2.4 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Copyright 2026 Nexa Systems Inc.
|
|
# License OPL-1 (Odoo Proprietary License v1.0)
|
|
# Part of the Fusion Plating product family.
|
|
|
|
from odoo import api, fields, models
|
|
|
|
|
|
class FpCertificate(models.Model):
|
|
"""Add Specification linkage + auto-fill spec_reference from it.
|
|
|
|
Lives in fusion_plating_quality because customer.spec lives here.
|
|
Quality already depends on certificates, so the inverse direction
|
|
works.
|
|
"""
|
|
_inherit = 'fp.certificate'
|
|
|
|
customer_spec_id = fields.Many2one(
|
|
'fusion.plating.customer.spec',
|
|
string='Specification',
|
|
help='Snapshot of the specification the cert was issued against. '
|
|
'Drives the spec_reference printed on the CoC.',
|
|
)
|
|
|
|
@api.model_create_multi
|
|
def create(self, vals_list):
|
|
"""Auto-fill spec_reference from the SO line's customer_spec_id.
|
|
|
|
Resolution order (first match wins):
|
|
1. Explicit spec_reference passed in vals.
|
|
2. customer_spec_id (this field) → format "code Rev rev".
|
|
3. SO line x_fc_customer_spec_id (with print_on_cert=True).
|
|
4. Existing legacy fall-back lives in the parent module
|
|
(reads x_fc_coating_config_id.spec_reference). Untouched.
|
|
"""
|
|
SaleOrder = self.env['sale.order']
|
|
for vals in vals_list:
|
|
if vals.get('spec_reference'):
|
|
continue
|
|
spec = False
|
|
# 2. Explicit spec on the cert.
|
|
if vals.get('customer_spec_id'):
|
|
spec = self.env['fusion.plating.customer.spec'].browse(
|
|
vals['customer_spec_id'],
|
|
).exists()
|
|
# 3. SO line's spec.
|
|
if not spec and vals.get('sale_order_id'):
|
|
so = SaleOrder.browse(vals['sale_order_id'])
|
|
if 'x_fc_customer_spec_id' in so.order_line._fields:
|
|
spec = so.order_line.mapped(
|
|
'x_fc_customer_spec_id',
|
|
).filtered('print_on_cert')[:1]
|
|
if spec and not vals.get('customer_spec_id'):
|
|
vals['customer_spec_id'] = spec.id
|
|
if spec:
|
|
ref = spec.code or ''
|
|
if spec.revision:
|
|
ref = f'{ref} Rev {spec.revision}' if ref else f'Rev {spec.revision}'
|
|
if ref:
|
|
vals['spec_reference'] = ref
|
|
return super().create(vals_list)
|