Files
2026-04-16 20:53:53 -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})