140 lines
4.3 KiB
Python
140 lines
4.3 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 FpExposureMonitoring(models.Model):
|
|
"""An exposure monitoring sample.
|
|
|
|
A monitoring event captures one measurement of a worker's or area's
|
|
exposure to a hazardous agent — air contaminant, biological marker,
|
|
noise or vibration. The result is compared against an Occupational
|
|
Exposure Limit (OEL), most commonly the time-weighted average (TWA)
|
|
or short-term exposure limit (STEL) published by the relevant
|
|
jurisdiction (e.g. Ontario Reg. 833 in Canada).
|
|
|
|
The percent-of-OEL is calculated automatically and the record is
|
|
classified as below, approaching or exceeding the limit, providing
|
|
an early warning when controls need to be tightened.
|
|
"""
|
|
_name = 'fusion.plating.exposure.monitoring'
|
|
_description = 'Fusion Plating — Exposure Monitoring'
|
|
_inherit = ['mail.thread', 'mail.activity.mixin']
|
|
_order = 'sample_date desc, id desc'
|
|
_rec_name = 'name'
|
|
|
|
name = fields.Char(
|
|
string='Reference',
|
|
required=True,
|
|
copy=False,
|
|
readonly=True,
|
|
default=lambda self: self._default_name(),
|
|
tracking=True,
|
|
)
|
|
employee_id = fields.Many2one(
|
|
'hr.employee',
|
|
string='Employee',
|
|
ondelete='set null',
|
|
tracking=True,
|
|
)
|
|
facility_id = fields.Many2one(
|
|
'fusion.plating.facility',
|
|
string='Facility',
|
|
tracking=True,
|
|
)
|
|
sample_date = fields.Date(
|
|
string='Sample Date',
|
|
required=True,
|
|
default=fields.Date.context_today,
|
|
tracking=True,
|
|
)
|
|
sample_type = fields.Selection(
|
|
[
|
|
('personal_air', 'Personal Air'),
|
|
('area_air', 'Area Air'),
|
|
('biological', 'Biological'),
|
|
('noise', 'Noise'),
|
|
('vibration', 'Vibration'),
|
|
],
|
|
string='Sample Type',
|
|
default='personal_air',
|
|
required=True,
|
|
tracking=True,
|
|
)
|
|
substance = fields.Char(
|
|
string='Substance / Agent',
|
|
tracking=True,
|
|
)
|
|
concentration = fields.Float(
|
|
string='Concentration',
|
|
tracking=True,
|
|
)
|
|
uom = fields.Char(
|
|
string='Unit of Measure',
|
|
help='Free-text unit, e.g. mg/m3, ppm, dBA.',
|
|
)
|
|
oel_reference = fields.Char(
|
|
string='OEL Reference',
|
|
help='Citation for the exposure limit, e.g. "Ontario Reg. 833 TWA".',
|
|
)
|
|
oel_limit = fields.Float(
|
|
string='OEL Limit',
|
|
)
|
|
percent_of_oel = fields.Float(
|
|
string='% of OEL',
|
|
compute='_compute_percent_of_oel',
|
|
store=True,
|
|
)
|
|
result = fields.Selection(
|
|
[
|
|
('below', 'Below'),
|
|
('approaching', 'Approaching'),
|
|
('exceed', 'Exceeds'),
|
|
],
|
|
string='Result',
|
|
compute='_compute_result',
|
|
store=True,
|
|
tracking=True,
|
|
)
|
|
notes = fields.Html(
|
|
string='Notes',
|
|
)
|
|
company_id = fields.Many2one(
|
|
'res.company',
|
|
string='Company',
|
|
default=lambda self: self.env.company,
|
|
)
|
|
active = fields.Boolean(default=True)
|
|
|
|
# ==========================================================================
|
|
# Defaults
|
|
# ==========================================================================
|
|
@api.model
|
|
def _default_name(self):
|
|
seq = self.env['ir.sequence'].next_by_code('fusion.plating.exposure.monitoring')
|
|
return seq or '/'
|
|
|
|
# ==========================================================================
|
|
# Computes
|
|
# ==========================================================================
|
|
@api.depends('concentration', 'oel_limit')
|
|
def _compute_percent_of_oel(self):
|
|
for rec in self:
|
|
if rec.oel_limit:
|
|
rec.percent_of_oel = (rec.concentration / rec.oel_limit) * 100.0
|
|
else:
|
|
rec.percent_of_oel = 0.0
|
|
|
|
@api.depends('percent_of_oel')
|
|
def _compute_result(self):
|
|
for rec in self:
|
|
if rec.percent_of_oel >= 100.0:
|
|
rec.result = 'exceed'
|
|
elif rec.percent_of_oel >= 50.0:
|
|
rec.result = 'approaching'
|
|
else:
|
|
rec.result = 'below'
|