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

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'