# -*- 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 from odoo.addons.fusion_plating.models._fp_uom_selection import FP_UOM_SELECTION class FpChemical(models.Model): """Physical chemical container in the shop's chemical inventory. A chemical record represents a managed container — drum, tote, jug, cylinder — of a specific product, stored in a specific facility and location, with on-hand quantity and reorder thresholds. It links to the Safety Data Sheet that governs handling, and may optionally link to the Odoo product/stock record when the same chemistry is also tracked as inventory. Storage compatibility (acid vs base, oxidizer vs flammable, etc.) is captured via a self-referential many2many of incompatible chemicals so a future workflow can warn on co-located storage. """ _name = 'fusion.plating.chemical' _description = 'Fusion Plating — Chemical' _inherit = ['mail.thread', 'mail.activity.mixin'] _order = 'name' name = fields.Char( string='Chemical', required=True, tracking=True, ) sds_id = fields.Many2one( 'fusion.plating.sds', string='Safety Data Sheet', tracking=True, ) product_id = fields.Many2one( 'product.product', string='Stock Product', help='Optional link to the Odoo product when the chemistry is also ' 'tracked as inventory.', ) facility_id = fields.Many2one( 'fusion.plating.facility', string='Facility', tracking=True, ) location = fields.Char( string='Storage Location', help='Free-text storage location, e.g. "Acid Cabinet 2" or "Drum bay B".', ) container_size = fields.Float( string='Container Size', help='Numerical size of one container, expressed in the unit ' 'selected below (e.g. 200 with unit "L" for a 200 L drum).', ) container_uom = fields.Selection( FP_UOM_SELECTION, string='Container UoM', help='Unit of measure for the container size — pick from the ' 'curated list to keep inventory consistent (L, kg, lb, gal).', ) quantity_on_hand = fields.Float( string='Quantity On Hand', tracking=True, ) reorder_point = fields.Float( string='Reorder Point', help='When quantity on hand falls below this level, the chemical ' 'should be reordered.', ) incompatible_with_ids = fields.Many2many( 'fusion.plating.chemical', 'fp_chemical_incompat_rel', 'chemical_id', 'incompatible_id', string='Incompatible With', help='Chemicals that must not be stored next to this one.', ) needs_reorder = fields.Boolean( string='Needs Reorder', compute='_compute_needs_reorder', store=True, ) company_id = fields.Many2one( 'res.company', string='Company', default=lambda self: self.env.company, ) active = fields.Boolean(default=True) notes = fields.Html(string='Notes') @api.depends('quantity_on_hand', 'reorder_point') def _compute_needs_reorder(self): for rec in self: rec.needs_reorder = bool( rec.reorder_point and rec.quantity_on_hand <= rec.reorder_point )