76 lines
2.5 KiB
Python
76 lines
2.5 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 FpBatchChemistry(models.Model):
|
|
"""A single chemistry reading taken during batch processing."""
|
|
_name = 'fusion.plating.batch.chemistry'
|
|
_description = 'Batch Chemistry Reading'
|
|
_order = 'reading_time desc, id desc'
|
|
|
|
batch_id = fields.Many2one(
|
|
'fusion.plating.batch',
|
|
string='Batch',
|
|
required=True,
|
|
ondelete='cascade',
|
|
)
|
|
parameter_id = fields.Many2one(
|
|
'fusion.plating.bath.parameter',
|
|
string='Parameter',
|
|
required=True,
|
|
)
|
|
value = fields.Float(string='Value', required=True)
|
|
reading_time = fields.Datetime(
|
|
string='Reading Time',
|
|
default=fields.Datetime.now,
|
|
)
|
|
status = fields.Selection(
|
|
selection=[
|
|
('pass', 'Pass'),
|
|
('warning', 'Warning'),
|
|
('fail', 'Fail'),
|
|
],
|
|
string='Status',
|
|
compute='_compute_status',
|
|
store=True,
|
|
)
|
|
notes = fields.Char(string='Notes')
|
|
|
|
@api.depends('parameter_id', 'value')
|
|
def _compute_status(self):
|
|
"""Compare value against parameter target range.
|
|
|
|
Uses the parameter's default target range and warning tolerance.
|
|
A reading within [target_min, target_max] is a pass. If it falls
|
|
within the warning tolerance band outside that range, it is a
|
|
warning. Otherwise it is a fail.
|
|
"""
|
|
for rec in self:
|
|
if not rec.parameter_id:
|
|
rec.status = 'pass'
|
|
continue
|
|
param = rec.parameter_id
|
|
target_min = param.target_min
|
|
target_max = param.target_max
|
|
if not target_min and not target_max:
|
|
rec.status = 'pass'
|
|
continue
|
|
# Value within target range = pass
|
|
if target_min <= rec.value <= target_max:
|
|
rec.status = 'pass'
|
|
continue
|
|
# Calculate warning band from tolerance %
|
|
tolerance = (param.warning_tolerance or 0.0) / 100.0
|
|
span = target_max - target_min if target_max != target_min else abs(target_max) or 1.0
|
|
margin = span * tolerance
|
|
warning_min = target_min - margin
|
|
warning_max = target_max + margin
|
|
if warning_min <= rec.value <= warning_max:
|
|
rec.status = 'warning'
|
|
else:
|
|
rec.status = 'fail'
|