# -*- 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'