Files
Odoo-Modules/fusion-plating/fusion_plating/models/fp_tank.py
gsinghpal be611876ad changes
2026-04-12 09:09:50 -04:00

171 lines
4.9 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 FpTank(models.Model):
"""A physical vessel that holds a bath.
Tanks are long-lived assets. Baths come and go inside a tank. The
separation lets a shop dump an exhausted bath without losing the
tank's history, QR code, or equipment records.
Each tank carries a unique QR code for operator scanning at the
shop-floor station.
"""
_name = 'fusion.plating.tank'
_description = 'Fusion Plating — Tank'
_inherit = ['mail.thread', 'mail.activity.mixin']
_order = 'facility_id, work_center_id, sequence, code'
name = fields.Char(
string='Tank',
required=True,
tracking=True,
)
code = fields.Char(
string='Code',
required=True,
tracking=True,
help='Short unique tank identifier (e.g. "T-01", "EN-A1").',
)
qr_code = fields.Char(
string='QR Code',
help='Scannable identifier. Defaults to code, can be set to a longer URI.',
)
sequence = fields.Integer(
string='Sequence',
default=10,
)
active = fields.Boolean(
string='Active',
default=True,
)
facility_id = fields.Many2one(
'fusion.plating.facility',
string='Facility',
required=True,
ondelete='restrict',
tracking=True,
)
work_center_id = fields.Many2one(
'fusion.plating.work.center',
string='Work Center',
domain="[('facility_id','=',facility_id)]",
ondelete='restrict',
tracking=True,
)
# ----- Physical properties --------------------------------------------
volume = fields.Float(
string='Volume',
help='Working volume.',
)
volume_uom = fields.Selection(
[
('l', 'Litres'),
('gal_us', 'US gallons'),
('gal_imp', 'Imperial gallons'),
('m3', 'Cubic metres'),
],
string='Volume Unit',
default='l',
)
material = fields.Selection(
[
('polypro', 'Polypropylene'),
('pvc', 'PVC'),
('pvdf', 'PVDF'),
('ss', 'Stainless Steel'),
('lined_steel', 'Lined Steel'),
('glass', 'Glass'),
('other', 'Other'),
],
string='Construction',
)
heating_type = fields.Selection(
[
('none', 'None'),
('immersion', 'Immersion Heater'),
('steam_coil', 'Steam Coil'),
('jacket', 'Jacketed'),
('external', 'External Heat Exchanger'),
],
string='Heating',
default='none',
)
has_filtration = fields.Boolean(
string='Has Filtration',
)
has_rectifier = fields.Boolean(
string='Has Rectifier',
help='Required for electrolytic processes (chrome, anodize, strike).',
)
# ----- State ----------------------------------------------------------
state = fields.Selection(
[
('empty', 'Empty'),
('filled', 'Filled'),
('in_use', 'In Use'),
('draining', 'Draining'),
('maintenance', 'Maintenance'),
('out_of_service', 'Out of Service'),
],
string='Status',
default='empty',
tracking=True,
)
# ----- Relations ------------------------------------------------------
bath_ids = fields.One2many(
'fusion.plating.bath',
'tank_id',
string='Bath History',
)
current_bath_id = fields.Many2one(
'fusion.plating.bath',
string='Current Bath',
compute='_compute_current_bath',
store=True,
)
current_process_id = fields.Many2one(
'fusion.plating.process.type',
string='Current Process',
related='current_bath_id.process_type_id',
store=True,
)
bath_count = fields.Integer(
compute='_compute_bath_count',
)
_sql_constraints = [
(
'fp_tank_code_facility_uniq',
'unique(code, facility_id)',
'Tank code must be unique within a facility.',
),
]
@api.depends('bath_ids', 'bath_ids.state')
def _compute_current_bath(self):
for rec in self:
active = rec.bath_ids.filtered(
lambda b: b.state in ('operational', 'under_review')
)
rec.current_bath_id = active[:1].id if active else False
def _compute_bath_count(self):
for rec in self:
rec.bath_count = len(rec.bath_ids)
@api.model_create_multi
def create(self, vals_list):
for vals in vals_list:
if not vals.get('qr_code') and vals.get('code'):
vals['qr_code'] = f"FP-TANK:{vals['code']}"
return super().create(vals_list)