Files
Odoo-Modules/fusion_plating/fusion_plating_nuclear/models/fp_nuclear_pedigree.py
gsinghpal 8c76a16366 chore(plating): de-dash shipped code + intake-neutral customer emails
Replace em-dashes and en-dashes with hyphens across 789 shipped source
files (py/xml/js/scss) so the delivered module reads as human-written;
em-dashes had become a recognizable AI-generated tell. Internal .md dev
notes are excluded. The WO-sticker mojibake strippers keep their dash
search targets (now written — / –). No logic changes: comments
and display strings only; validated with py_compile + lxml parse.

Rewrite the 7 customer notification emails to be intake-neutral
(ship-in / drop-off / pickup) and repair-aware, and fix the Shipped
email documents line (packing slip vs bill of lading; certificate only
when issued). Subjects use a hyphen separator.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 00:16:19 -04:00

123 lines
3.9 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 dateutil.relativedelta import relativedelta
from odoo import api, fields, models
class FpNuclearPedigree(models.Model):
"""Nuclear Pedigree Traceability Record.
Nuclear pedigree is the unbroken chain of traceability from the raw
material a plated part was made from, through every processing
step, to the finished and shipped component. Nuclear operators use
pedigree records decades after shipment - long after the original
work order has aged out of normal systems - which is why the
retention clock is driven by the N299 level rather than a generic
document-retention rule.
Once the record is locked (typically at ship), the fields above the
chatter are read-only and all downstream edits should go through
the normal change-control process.
"""
_name = 'fusion.plating.nuclear.pedigree'
_description = 'Fusion Plating - Nuclear Pedigree Record'
_inherit = ['mail.thread', 'mail.activity.mixin']
_order = 'ship_date desc, id desc'
name = fields.Char(
string='Job / Lot Ref',
required=True,
tracking=True,
)
part_number = fields.Char(
string='Part Number',
tracking=True,
)
lot_serial = fields.Char(
string='Lot / Serial',
tracking=True,
)
customer_id = fields.Many2one(
'res.partner',
string='Customer',
required=True,
tracking=True,
)
n299_level_id = fields.Many2one(
'fusion.plating.n299.level',
string='CSA N299 Level',
tracking=True,
)
raw_material_cert_refs = fields.Char(
string='Raw Material Cert Refs',
help='Mill test report, CMTR, or material certificate reference(s).',
)
raw_material_heat_no = fields.Char(
string='Raw Material Heat No',
)
process_steps_json = fields.Text(
string='Process Steps',
help='Structured trail of each processing step the part went '
'through (station, operator, timestamp, parameters).',
)
operators_log = fields.Text(
string='Operators Log',
)
chemistry_cert_refs = fields.Char(
string='Chemistry Cert Refs',
)
test_results = fields.Html(
string='Test Results',
)
ship_date = fields.Date(
string='Ship Date',
tracking=True,
)
retention_until_date = fields.Date(
string='Retain Until',
compute='_compute_retention_until_date',
store=True,
help='Ship date plus the retention period of the assigned N299 level.',
)
attachment_ids = fields.Many2many(
'ir.attachment',
'fp_nuclear_pedigree_attachment_rel',
'pedigree_id',
'attachment_id',
string='Supporting Documents',
)
locked = fields.Boolean(
string='Locked',
default=False,
tracking=True,
help='Once the part has shipped, lock the pedigree to prevent '
'modification. Further changes must go through formal '
'change control.',
)
company_id = fields.Many2one(
'res.company',
string='Company',
default=lambda self: self.env.company,
)
active = fields.Boolean(default=True)
@api.depends('ship_date', 'n299_level_id.retention_years')
def _compute_retention_until_date(self):
for rec in self:
if rec.ship_date and rec.n299_level_id and rec.n299_level_id.retention_years:
rec.retention_until_date = rec.ship_date + relativedelta(
years=rec.n299_level_id.retention_years
)
else:
rec.retention_until_date = False
def action_lock(self):
self.write({'locked': True})
def action_unlock(self):
self.write({'locked': False})