Files
Odoo-Modules/fusion_plating/fusion_plating/models/fp_job_step_move.py
gsinghpal e718a47e3e fix(sub12b): to_step_id required → ondelete='restrict'
Odoo 19 disallows ondelete='set null' on a required M2O. Switched to
restrict — destination steps can't be unlinked while move-log rows
reference them, which is the right audit-safety behavior anyway.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 21:19:58 -04:00

105 lines
4.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- 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 FpJobStepMove(models.Model):
"""Chain-of-custody log — one row per part-batch move.
Sub 12b: every Move Parts / Move Rack click commits one (or, for
rack moves, one-per-batch atomic) row here. Sub 12c walks these in
chronological order to render the customer CoC PDF.
"""
_name = 'fp.job.step.move'
_description = 'Fusion Plating — Job Step Move (Chain-of-Custody)'
_inherit = ['mail.thread']
_order = 'move_datetime desc, id desc'
name = fields.Char(
string='Move Reference',
default=lambda self: self.env['ir.sequence'].next_by_code(
'fp.job.step.move') or '/',
readonly=True, copy=False,
)
job_id = fields.Many2one('fp.job', string='Job',
required=True, ondelete='cascade', index=True)
from_step_id = fields.Many2one('fp.job.step', string='From Step',
ondelete='set null', index=True)
to_step_id = fields.Many2one('fp.job.step', string='To Step',
ondelete='restrict', index=True, required=True)
from_tank_id = fields.Many2one('fusion.plating.tank',
related='from_step_id.tank_id', store=True)
to_tank_id = fields.Many2one('fusion.plating.tank', string='To Tank',
ondelete='set null')
transfer_type = fields.Selection([
('step', 'Step'),
('hold', 'Hold'),
('scrap', 'Scrap'),
('rework', 'Rework'),
('split', 'Split'),
('return', 'Return'),
], string='Transfer Type', default='step', required=True)
qty_moved = fields.Integer(string='Qty Moved', required=True)
qty_available_at_move = fields.Integer(string='Qty Available')
to_location = fields.Selection([
('global', 'Global'),
('quarantine', 'Quarantine'),
('staging_a', 'Staging A'),
('staging_b', 'Staging B'),
('shipping_dock', 'Shipping Dock'),
('scrap_bin', 'Scrap Bin'),
], string='To Location', default='global')
photo_evidence_id = fields.Many2one('ir.attachment',
string='Photo Evidence', ondelete='set null')
customer_wo_count = fields.Integer(string='# Customer WOs')
rack_id = fields.Many2one('fusion.plating.rack',
string='Rack', ondelete='set null', index=True)
unrack_after_move = fields.Boolean(string='Unrack After Move')
moved_by_user_id = fields.Many2one('res.users', string='Moved By',
default=lambda self: self.env.user, required=True)
move_datetime = fields.Datetime(string='Move Time',
default=fields.Datetime.now, required=True, index=True)
transition_input_value_ids = fields.One2many(
'fp.job.step.move.input.value', 'move_id',
string='Transition Input Values',
)
class FpJobStepMoveInputValue(models.Model):
"""Captured value for one transition-input prompt.
Each row = one author-defined prompt × one move. Snapshot of what
the operator typed at move-time. Used by Sub 12c CoC report.
"""
_name = 'fp.job.step.move.input.value'
_description = 'Fusion Plating — Captured Transition Input Value'
_order = 'move_id, id'
move_id = fields.Many2one('fp.job.step.move', string='Move',
required=True, ondelete='cascade', index=True)
template_input_id = fields.Many2one(
'fp.step.template.transition.input',
string='Template Input', ondelete='set null',
help='What was originally asked (template-level reference).')
node_input_id = fields.Many2one(
'fusion.plating.process.node.input',
string='Node Input', ondelete='set null',
help='Snapshot of the authored prompt at job-creation time.')
value_text = fields.Char(string='Text Value')
value_number = fields.Float(string='Number Value')
value_boolean = fields.Boolean(string='Yes/No Value')
value_date = fields.Datetime(string='Date Value')
value_attachment_id = fields.Many2one('ir.attachment',
string='Attachment Value', ondelete='set null')