# -*- coding: utf-8 -*- # Copyright 2026 Nexa Systems Inc. # License OPL-1 (Odoo Proprietary License v1.0) # Part of the Fusion Plating product family. # # Phase 1 (Sub 11) — relocated from fusion_plating_bridge_mrp. # MRP-flavoured fields (production_id, workorder_id) replaced by their # native fp.job / fp.job.step equivalents. from odoo import api, fields, models, _ class FpJobConsumption(models.Model): """A single consumable drawdown charged to a plating job. Sources include bath replenishment applied against a job, masking tape rolls, PPE, nickel salts — anything that has a cost and should roll into job costing. Kept deliberately lightweight: one row per event, cost derived from `product.standard_price` at log time (snapshot, not reactive). """ _name = 'fp.job.consumption' _description = 'Fusion Plating — Job Consumption' _order = 'logged_date desc, id desc' job_id = fields.Many2one( 'fp.job', string='Work Order', required=True, ondelete='cascade', index=True, ) step_id = fields.Many2one( 'fp.job.step', string='Job Step', domain="[('job_id', '=', job_id)]", ondelete='set null', ) product_id = fields.Many2one( 'product.product', string='Product', required=True, domain="[('sale_ok', '=', False)]", ) product_name = fields.Char( string='Product Name (snapshot)', help='Free-text product label if no inventory product is linked.', ) quantity = fields.Float(string='Quantity', required=True, digits=(12, 3)) uom_id = fields.Many2one( 'uom.uom', string='UoM', ) currency_id = fields.Many2one( 'res.currency', required=True, default=lambda self: self.env.company.currency_id, ) unit_cost = fields.Monetary( string='Unit Cost (snapshot)', currency_field='currency_id', help='Taken from product.standard_price at log time.', ) total_cost = fields.Monetary( string='Total Cost', currency_field='currency_id', compute='_compute_total_cost', store=True, ) logged_date = fields.Datetime( string='Logged', default=fields.Datetime.now, ) logged_by_id = fields.Many2one( 'res.users', string='Logged By', default=lambda self: self.env.user, ) source = fields.Selection( [('replenishment', 'Bath Replenishment'), ('masking', 'Masking Material'), ('ppe', 'PPE / Consumables'), ('chemistry', 'Process Chemistry'), ('other', 'Other')], string='Source', default='other', required=True, ) replenishment_id = fields.Many2one( 'fusion.plating.bath.replenishment.suggestion', string='Replenishment Suggestion', ondelete='set null', ) notes = fields.Char(string='Notes') @api.depends('quantity', 'unit_cost') def _compute_total_cost(self): for rec in self: rec.total_cost = round((rec.quantity or 0) * (rec.unit_cost or 0), 2) @api.depends('product_id', 'product_name', 'quantity', 'job_id') def _compute_display_name(self): for rec in self: label = rec.product_id.display_name or rec.product_name or 'Consumption' qty = ('%g' % rec.quantity) if rec.quantity else '' job = rec.job_id.name or '' bits = [label] if qty: bits.append('×' + qty) if job: bits.append('(%s)' % job) rec.display_name = ' '.join(bits) @api.onchange('product_id') def _onchange_product(self): if self.product_id: self.product_name = self.product_id.display_name self.unit_cost = self.product_id.standard_price or 0.0 self.uom_id = self.product_id.uom_id or False