92 lines
2.9 KiB
Python
92 lines
2.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 odoo import api, fields, models
|
|
|
|
|
|
class FpChainOfCustody(models.Model):
|
|
"""A single custody event — the audit trail for parts in transit.
|
|
|
|
A chain of custody record is created every time parts change hands:
|
|
received from the customer, loaded on a vehicle, entered a facility,
|
|
transferred between facilities, or delivered to the customer.
|
|
|
|
These records are append-only in practice and form the evidence
|
|
trail that quality and compliance audits rely on. They are linked
|
|
to either a pickup request or a delivery (or both, for a full
|
|
round-trip).
|
|
"""
|
|
_name = 'fusion.plating.chain.of.custody'
|
|
_description = 'Fusion Plating — Chain of Custody Event'
|
|
_order = 'event_datetime desc, id desc'
|
|
_rec_name = 'display_name'
|
|
|
|
name = fields.Char(
|
|
string='Reference',
|
|
)
|
|
display_name = fields.Char(
|
|
compute='_compute_display_name',
|
|
store=True,
|
|
)
|
|
event_datetime = fields.Datetime(
|
|
string='Event Time',
|
|
required=True,
|
|
default=fields.Datetime.now,
|
|
)
|
|
event_type = fields.Selection(
|
|
[
|
|
('received_from_customer', 'Received from Customer'),
|
|
('entered_facility', 'Entered Facility'),
|
|
('exited_facility', 'Exited Facility'),
|
|
('loaded_on_vehicle', 'Loaded on Vehicle'),
|
|
('delivered_to_customer', 'Delivered to Customer'),
|
|
('transferred_between_facilities', 'Transferred Between Facilities'),
|
|
],
|
|
string='Event Type',
|
|
required=True,
|
|
)
|
|
from_party = fields.Char(
|
|
string='From',
|
|
)
|
|
to_party = fields.Char(
|
|
string='To',
|
|
)
|
|
pickup_request_id = fields.Many2one(
|
|
'fusion.plating.pickup.request',
|
|
string='Pickup Request',
|
|
ondelete='set null',
|
|
)
|
|
delivery_id = fields.Many2one(
|
|
'fusion.plating.delivery',
|
|
string='Delivery',
|
|
ondelete='set null',
|
|
)
|
|
facility_id = fields.Many2one(
|
|
'fusion.plating.facility',
|
|
string='Facility',
|
|
)
|
|
company_id = fields.Many2one(
|
|
'res.company',
|
|
related='facility_id.company_id',
|
|
store=True,
|
|
readonly=True,
|
|
)
|
|
recorded_by_id = fields.Many2one(
|
|
'res.users',
|
|
string='Recorded By',
|
|
default=lambda self: self.env.user,
|
|
)
|
|
notes = fields.Text(
|
|
string='Notes',
|
|
)
|
|
|
|
@api.depends('event_type', 'event_datetime', 'from_party', 'to_party')
|
|
def _compute_display_name(self):
|
|
selection = dict(self._fields['event_type']._description_selection(self.env))
|
|
for rec in self:
|
|
label = selection.get(rec.event_type, rec.event_type or '')
|
|
when = fields.Datetime.to_string(rec.event_datetime) if rec.event_datetime else ''
|
|
rec.display_name = f'{label} @ {when}' if when else label
|