folder rename

This commit is contained in:
gsinghpal
2026-04-16 20:53:53 -04:00
parent 3f3ddcbab4
commit 7c7ef06057
634 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
# Copyright 2026 Nexa Systems Inc.
# License OPL-1 (Odoo Proprietary License v1.0)
from . import fp_jurisdiction
from . import fp_regulator
from . import fp_permit
from . import fp_permit_condition
from . import fp_discharge_limit
from . import fp_discharge_sample
from . import fp_discharge_sample_line
from . import fp_waste_stream
from . import fp_waste_manifest
from . import fp_pollutant_inventory
from . import fp_compliance_event
from . import fp_spill_register
from . import fp_facility

View File

@@ -0,0 +1,49 @@
# -*- coding: utf-8 -*-
# Copyright 2026 Nexa Systems Inc.
# License OPL-1 (Odoo Proprietary License v1.0)
from odoo import api, fields, models
class FpComplianceEvent(models.Model):
_name = 'fusion.plating.compliance.event'
_description = 'Fusion Plating - Compliance Event'
_inherit = ['mail.thread', 'mail.activity.mixin']
_order = 'due_date, id'
name = fields.Char(string='Title', required=True, tracking=True)
event_type = fields.Selection(
[('report_due', 'Report Due'), ('permit_renewal', 'Permit Renewal'),
('sample_due', 'Sample Due'), ('audit', 'Audit'), ('inspection', 'Inspection'),
('training_expiry', 'Training Expiry'), ('other', 'Other')],
string='Type', required=True, default='report_due', tracking=True,
)
facility_id = fields.Many2one('fusion.plating.facility', string='Facility', ondelete='cascade', tracking=True)
company_id = fields.Many2one('res.company', related='facility_id.company_id', store=True, readonly=True)
due_date = fields.Date(string='Due', required=True, tracking=True)
owner_id = fields.Many2one('res.users', string='Owner', tracking=True)
state = fields.Selection(
[('upcoming', 'Upcoming'), ('due', 'Due'), ('overdue', 'Overdue'),
('done', 'Done'), ('skipped', 'Skipped')],
string='Status', default='upcoming', required=True, tracking=True,
)
permit_id = fields.Many2one('fusion.plating.permit', string='Related Permit', ondelete='set null')
regulator_id = fields.Many2one('fusion.plating.regulator', string='Regulator', ondelete='set null')
notes = fields.Html(string='Notes')
@api.model
def _cron_refresh_states(self):
today = fields.Date.context_today(self)
events = self.search([('state', 'in', ('upcoming', 'due'))])
for ev in events:
if not ev.due_date:
continue
if ev.due_date < today:
ev.state = 'overdue'
elif ev.due_date == today:
ev.state = 'due'
def action_mark_done(self):
self.write({'state': 'done'})
def action_skip(self):
self.write({'state': 'skipped'})

View File

@@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
# Copyright 2026 Nexa Systems Inc.
# License OPL-1 (Odoo Proprietary License v1.0)
from odoo import fields, models
class FpDischargeLimit(models.Model):
_name = 'fusion.plating.discharge.limit'
_description = 'Fusion Plating - Discharge Limit'
_order = 'jurisdiction_id, parameter, discharge_point'
name = fields.Char(string='Name', required=True)
parameter = fields.Char(string='Parameter', required=True)
jurisdiction_id = fields.Many2one('fusion.plating.jurisdiction', string='Jurisdiction', ondelete='restrict')
regulation_ref = fields.Char(string='Regulation Reference')
discharge_point = fields.Selection(
[('sanitary', 'Sanitary Sewer'), ('storm', 'Storm Sewer'),
('combined', 'Combined Sewer'), ('air', 'Air Emission'), ('other', 'Other')],
string='Discharge Point', default='sanitary', required=True,
)
limit_value = fields.Float(string='Limit', digits=(16, 4))
uom = fields.Char(string='UoM')
limit_type = fields.Selection(
[('max', 'Maximum'), ('min', 'Minimum'), ('range', 'Range'), ('ceiling', 'Hard Ceiling')],
string='Limit Type', default='max', required=True,
)
min_value = fields.Float(string='Min Value', digits=(16, 4))
reference_url = fields.Char(string='Source URL')
notes = fields.Text(string='Notes')
active = fields.Boolean(default=True)

View File

@@ -0,0 +1,66 @@
# -*- coding: utf-8 -*-
# Copyright 2026 Nexa Systems Inc.
# License OPL-1 (Odoo Proprietary License v1.0)
from odoo import api, fields, models
class FpDischargeSample(models.Model):
_name = 'fusion.plating.discharge.sample'
_description = 'Fusion Plating - Discharge Sample'
_inherit = ['mail.thread', 'mail.activity.mixin']
_order = 'sample_date desc, id desc'
name = fields.Char(string='Reference', required=True, copy=False, default=lambda s: s._default_name(), tracking=True)
facility_id = fields.Many2one('fusion.plating.facility', string='Facility', required=True, ondelete='restrict', tracking=True)
company_id = fields.Many2one('res.company', related='facility_id.company_id', store=True, readonly=True)
sample_date = fields.Datetime(string='Sample Date', required=True, default=fields.Datetime.now, tracking=True)
sample_point = fields.Char(string='Sample Point')
collected_by_id = fields.Many2one('res.users', string='Collected By')
chain_of_custody_ref = fields.Char(string='Chain of Custody #')
lab_id = fields.Many2one('res.partner', string='Lab', domain=[('is_company', '=', True)])
lab_report_ref = fields.Char(string='Lab Report #')
received_date = fields.Date(string='Results Received')
state = fields.Selection(
[('draft', 'Draft'), ('sent_to_lab', 'Sent to Lab'), ('results_in', 'Results In'),
('escalated', 'Escalated'), ('closed', 'Closed')],
string='Status', default='draft', required=True, tracking=True,
)
line_ids = fields.One2many('fusion.plating.discharge.sample.line', 'sample_id', string='Parameters', copy=True)
worst_status = fields.Selection(
[('ok', 'OK'), ('warning', 'Warning'), ('out_of_spec', 'Out of Spec'), ('pending', 'Pending')],
string='Worst Result', compute='_compute_worst_status', store=True,
)
notes = fields.Html(string='Notes')
attachment_ids = fields.Many2many(
'ir.attachment', 'fp_discharge_sample_attachment_rel', 'sample_id', 'attachment_id', string='Attachments',
)
active = fields.Boolean(default=True)
@api.model
def _default_name(self):
seq = self.env['ir.sequence'].next_by_code('fusion.plating.discharge.sample')
return seq or '/'
@api.depends('line_ids', 'line_ids.status')
def _compute_worst_status(self):
order = ['out_of_spec', 'warning', 'pending', 'ok']
for rec in self:
statuses = [l.status for l in rec.line_ids if l.status]
worst = 'pending'
for s in order:
if s in statuses:
worst = s
break
rec.worst_status = worst if statuses else 'pending'
def action_send_to_lab(self):
self.write({'state': 'sent_to_lab'})
def action_results_in(self):
self.write({'state': 'results_in', 'received_date': fields.Date.context_today(self)})
def action_escalate(self):
self.write({'state': 'escalated'})
def action_close(self):
self.write({'state': 'closed'})

View File

@@ -0,0 +1,56 @@
# -*- coding: utf-8 -*-
# Copyright 2026 Nexa Systems Inc.
# License OPL-1 (Odoo Proprietary License v1.0)
from odoo import api, fields, models
class FpDischargeSampleLine(models.Model):
_name = 'fusion.plating.discharge.sample.line'
_description = 'Fusion Plating - Discharge Sample Line'
_order = 'sample_id, id'
sample_id = fields.Many2one('fusion.plating.discharge.sample', string='Sample', required=True, ondelete='cascade')
limit_id = fields.Many2one('fusion.plating.discharge.limit', string='Limit', ondelete='restrict')
parameter = fields.Char(string='Parameter', related='limit_id.parameter', store=True, readonly=False)
value = fields.Float(string='Result', digits=(16, 4))
uom = fields.Char(string='UoM')
status = fields.Selection(
[('ok', 'OK'), ('warning', 'Warning'), ('out_of_spec', 'Out of Spec'), ('pending', 'Pending')],
string='Status', compute='_compute_status', store=True,
)
notes = fields.Char(string='Note')
@api.depends('value', 'limit_id', 'limit_id.limit_value', 'limit_id.limit_type', 'limit_id.min_value')
def _compute_status(self):
for rec in self:
if not rec.limit_id:
rec.status = 'pending'
continue
limit = rec.limit_id
lt = limit.limit_type
lv = limit.limit_value or 0.0
if lt == 'max' or lt == 'ceiling':
if lv <= 0:
rec.status = 'pending'
elif rec.value >= lv:
rec.status = 'out_of_spec'
elif rec.value >= 0.8 * lv:
rec.status = 'warning'
else:
rec.status = 'ok'
elif lt == 'min':
if rec.value < lv:
rec.status = 'out_of_spec'
elif rec.value <= 1.2 * lv:
rec.status = 'warning'
else:
rec.status = 'ok'
elif lt == 'range':
if rec.value < (limit.min_value or 0.0) or rec.value > lv:
rec.status = 'out_of_spec'
elif rec.value >= 0.8 * lv:
rec.status = 'warning'
else:
rec.status = 'ok'
else:
rec.status = 'pending'

View File

@@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
# Copyright 2026 Nexa Systems Inc.
# License OPL-1 (Odoo Proprietary License v1.0)
from odoo import api, fields, models
class FpFacility(models.Model):
_inherit = 'fusion.plating.facility'
x_fp_eca_number = fields.Char(string='ECA / Approval Number')
x_fp_sewer_permit_number = fields.Char(string='Sewer Permit Number')
x_fp_waste_generator_number = fields.Char(string='Waste Generator Number')
x_fp_compliance_notes = fields.Html(string='Compliance Notes')
permit_ids = fields.One2many('fusion.plating.permit', 'facility_id', string='Permits')
waste_stream_ids = fields.One2many('fusion.plating.waste.stream', 'facility_id', string='Waste Streams')
discharge_sample_ids = fields.One2many('fusion.plating.discharge.sample', 'facility_id', string='Discharge Samples')
compliance_event_ids = fields.One2many('fusion.plating.compliance.event', 'facility_id', string='Compliance Events')
spill_register_ids = fields.One2many('fusion.plating.spill.register', 'facility_id', string='Spill Register')
permit_count = fields.Integer(string='Permits', compute='_compute_compliance_counts')
compliance_event_count = fields.Integer(string='Compliance Events', compute='_compute_compliance_counts')
waste_stream_count = fields.Integer(string='Waste Streams', compute='_compute_compliance_counts')
discharge_sample_count = fields.Integer(string='Samples', compute='_compute_compliance_counts')
spill_count = fields.Integer(string='Spills', compute='_compute_compliance_counts')
@api.depends('permit_ids', 'compliance_event_ids', 'waste_stream_ids',
'discharge_sample_ids', 'spill_register_ids')
def _compute_compliance_counts(self):
for rec in self:
rec.permit_count = len(rec.permit_ids)
rec.compliance_event_count = len(rec.compliance_event_ids)
rec.waste_stream_count = len(rec.waste_stream_ids)
rec.discharge_sample_count = len(rec.discharge_sample_ids)
rec.spill_count = len(rec.spill_register_ids)

View File

@@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
# Copyright 2026 Nexa Systems Inc.
# License OPL-1 (Odoo Proprietary License v1.0)
from odoo import api, fields, models
class FpJurisdiction(models.Model):
_name = 'fusion.plating.jurisdiction'
_description = 'Fusion Plating - Jurisdiction'
_parent_store = True
_parent_name = 'parent_id'
_order = 'parent_path, name'
_rec_name = 'display_name'
name = fields.Char(string='Name', required=True, translate=True)
code = fields.Char(string='Code', required=True)
parent_id = fields.Many2one('fusion.plating.jurisdiction', string='Parent', ondelete='restrict', index=True)
parent_path = fields.Char(index=True, unaccent=False)
child_ids = fields.One2many('fusion.plating.jurisdiction', 'parent_id', string='Children')
level = fields.Selection(
[('country', 'Country'), ('province', 'Province / State'), ('municipality', 'Municipality')],
string='Level', required=True, default='country',
)
active = fields.Boolean(string='Active', default=True)
display_name = fields.Char(compute='_compute_display_name', store=True, recursive=True)
_sql_constraints = [
('fp_jurisdiction_code_uniq', 'unique(code)', 'Jurisdiction code must be unique.'),
]
@api.depends('name', 'code', 'parent_id.display_name')
def _compute_display_name(self):
for rec in self:
if rec.parent_id:
rec.display_name = f'{rec.parent_id.display_name} / {rec.name}'
else:
rec.display_name = rec.name or ''

View File

@@ -0,0 +1,86 @@
# -*- coding: utf-8 -*-
# Copyright 2026 Nexa Systems Inc.
# License OPL-1 (Odoo Proprietary License v1.0)
from odoo import api, fields, models
class FpPermit(models.Model):
_name = 'fusion.plating.permit'
_description = 'Fusion Plating - Regulatory Permit'
_inherit = ['mail.thread', 'mail.activity.mixin']
_order = 'expiry_date, name'
name = fields.Char(string='Title', required=True, tracking=True)
permit_type = fields.Selection(
[('eca', 'Environmental Compliance Approval'),
('sewer', 'Sewer Use Permit'),
('waste_generator', 'Waste Generator Registration'),
('air', 'Air Permit'),
('water', 'Water Taking / Discharge'),
('fire', 'Fire / Hazmat'),
('other', 'Other')],
string='Type', required=True, default='eca', tracking=True,
)
number = fields.Char(string='Permit Number', tracking=True)
facility_id = fields.Many2one('fusion.plating.facility', string='Facility', required=True, ondelete='cascade', tracking=True)
company_id = fields.Many2one('res.company', related='facility_id.company_id', store=True, readonly=True)
regulator_id = fields.Many2one('fusion.plating.regulator', string='Regulator', ondelete='restrict', tracking=True)
jurisdiction_id = fields.Many2one('fusion.plating.jurisdiction', string='Jurisdiction', ondelete='restrict')
issue_date = fields.Date(string='Issued', tracking=True)
expiry_date = fields.Date(string='Expires', tracking=True)
state = fields.Selection(
[('draft', 'Draft'), ('pending', 'Pending'), ('active', 'Active'),
('expired', 'Expired'), ('revoked', 'Revoked')],
string='Status', default='draft', required=True, tracking=True,
)
renewal_reminder_days = fields.Integer(string='Reminder (days before expiry)', default=60)
days_until_expiry = fields.Integer(string='Days Until Expiry', compute='_compute_days_until_expiry')
is_expiring_soon = fields.Boolean(string='Expiring Soon', compute='_compute_days_until_expiry', search='_search_is_expiring_soon')
condition_ids = fields.One2many('fusion.plating.permit.condition', 'permit_id', string='Conditions', copy=True)
condition_count = fields.Integer(compute='_compute_condition_count')
attachment_ids = fields.Many2many(
'ir.attachment', 'fp_permit_attachment_rel', 'permit_id', 'attachment_id', string='Attachments',
)
notes = fields.Html(string='Notes')
active = fields.Boolean(default=True)
@api.depends('expiry_date')
def _compute_days_until_expiry(self):
today = fields.Date.context_today(self)
for rec in self:
if rec.expiry_date:
delta = (rec.expiry_date - today).days
rec.days_until_expiry = delta
rec.is_expiring_soon = 0 <= delta <= (rec.renewal_reminder_days or 60)
else:
rec.days_until_expiry = 0
rec.is_expiring_soon = False
def _search_is_expiring_soon(self, operator, value):
today = fields.Date.context_today(self)
permits = self.search([('expiry_date', '!=', False)])
soon_ids = []
for p in permits:
delta = (p.expiry_date - today).days
if 0 <= delta <= (p.renewal_reminder_days or 60):
soon_ids.append(p.id)
if (operator == '=' and value) or (operator == '!=' and not value):
return [('id', 'in', soon_ids)]
return [('id', 'not in', soon_ids)]
@api.depends('condition_ids')
def _compute_condition_count(self):
for rec in self:
rec.condition_count = len(rec.condition_ids)
def action_activate(self):
self.write({'state': 'active'})
def action_set_pending(self):
self.write({'state': 'pending'})
def action_revoke(self):
self.write({'state': 'revoked'})
def action_mark_expired(self):
self.write({'state': 'expired'})

View File

@@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
# Copyright 2026 Nexa Systems Inc.
# License OPL-1 (Odoo Proprietary License v1.0)
from odoo import fields, models
class FpPermitCondition(models.Model):
_name = 'fusion.plating.permit.condition'
_description = 'Fusion Plating - Permit Condition'
_order = 'permit_id, sequence, id'
permit_id = fields.Many2one('fusion.plating.permit', string='Permit', required=True, ondelete='cascade')
sequence = fields.Integer(default=10)
name = fields.Char(string='Condition', required=True)
description = fields.Html(string='Description')
frequency = fields.Selection(
[('one_time', 'One-time'), ('daily', 'Daily'), ('weekly', 'Weekly'),
('monthly', 'Monthly'), ('quarterly', 'Quarterly'),
('semi_annual', 'Semi-Annual'), ('annual', 'Annual'), ('on_demand', 'On Demand')],
string='Frequency', default='annual',
)
next_due_date = fields.Date(string='Next Due')
owner_id = fields.Many2one('res.users', string='Owner')
status = fields.Selection(
[('upcoming', 'Upcoming'), ('due', 'Due'), ('overdue', 'Overdue'), ('done', 'Done')],
string='Status', default='upcoming',
)

View File

@@ -0,0 +1,51 @@
# -*- coding: utf-8 -*-
# Copyright 2026 Nexa Systems Inc.
# License OPL-1 (Odoo Proprietary License v1.0)
from odoo import api, fields, models
class FpPollutantInventory(models.Model):
_name = 'fusion.plating.pollutant.inventory'
_description = 'Fusion Plating - Pollutant Inventory Entry'
_order = 'year desc, facility_id, substance'
name = fields.Char(string='Reference', compute='_compute_name', store=True)
year = fields.Integer(string='Year', required=True, default=lambda s: fields.Date.context_today(s).year)
facility_id = fields.Many2one('fusion.plating.facility', string='Facility', required=True, ondelete='cascade')
company_id = fields.Many2one('res.company', related='facility_id.company_id', store=True, readonly=True)
substance = fields.Char(string='Substance', required=True)
cas_number = fields.Char(string='CAS #')
manufactured_kg = fields.Float(string='Manufactured (kg)', digits=(16, 3))
processed_kg = fields.Float(string='Processed (kg)', digits=(16, 3))
used_kg = fields.Float(string='Used (kg)', digits=(16, 3))
released_kg = fields.Float(string='Released (kg)', digits=(16, 3))
transferred_kg = fields.Float(string='Transferred (kg)', digits=(16, 3))
threshold_kg = fields.Float(string='Threshold (kg)')
threshold_exceeded = fields.Boolean(string='Threshold Exceeded', compute='_compute_threshold_exceeded', store=True)
notes = fields.Text(string='Notes')
_sql_constraints = [
('fp_pollutant_inv_uniq', 'unique(facility_id, year, substance)',
'Pollutant inventory must be unique per facility / year / substance.'),
]
@api.depends('year', 'substance', 'facility_id')
def _compute_name(self):
for rec in self:
parts = []
if rec.year:
parts.append(str(rec.year))
if rec.substance:
parts.append(rec.substance)
if rec.facility_id:
parts.append(rec.facility_id.code or rec.facility_id.name or '')
rec.name = ' / '.join(p for p in parts if p) or '/'
@api.depends('manufactured_kg', 'processed_kg', 'used_kg', 'threshold_kg')
def _compute_threshold_exceeded(self):
for rec in self:
if rec.threshold_kg and rec.threshold_kg > 0:
total = (rec.manufactured_kg or 0.0) + (rec.processed_kg or 0.0) + (rec.used_kg or 0.0)
rec.threshold_exceeded = total >= rec.threshold_kg
else:
rec.threshold_exceeded = False

View File

@@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
# Copyright 2026 Nexa Systems Inc.
# License OPL-1 (Odoo Proprietary License v1.0)
from odoo import fields, models
class FpRegulator(models.Model):
_name = 'fusion.plating.regulator'
_description = 'Fusion Plating - Regulator'
_order = 'jurisdiction_id, name'
name = fields.Char(string='Name', required=True, translate=True)
code = fields.Char(string='Code')
jurisdiction_id = fields.Many2one('fusion.plating.jurisdiction', string='Jurisdiction', ondelete='restrict')
category = fields.Selection(
[('environmental', 'Environmental'), ('health_safety', 'Health & Safety'),
('water', 'Water'), ('waste', 'Waste'), ('labour', 'Labour'),
('transport', 'Transport'), ('other', 'Other')],
string='Category', default='environmental',
)
website = fields.Char(string='Website')
contact_info = fields.Text(string='Contact Information')
active = fields.Boolean(default=True)

View File

@@ -0,0 +1,49 @@
# -*- coding: utf-8 -*-
# Copyright 2026 Nexa Systems Inc.
# License OPL-1 (Odoo Proprietary License v1.0)
from odoo import api, fields, models
class FpSpillRegister(models.Model):
_name = 'fusion.plating.spill.register'
_description = 'Fusion Plating - Spill Register'
_inherit = ['mail.thread', 'mail.activity.mixin']
_order = 'spill_date desc, id desc'
name = fields.Char(string='Reference', required=True, copy=False, default=lambda s: s._default_name(), tracking=True)
facility_id = fields.Many2one('fusion.plating.facility', string='Facility', required=True, ondelete='restrict', tracking=True)
company_id = fields.Many2one('res.company', related='facility_id.company_id', store=True, readonly=True)
spill_date = fields.Datetime(string='Spill Date', required=True, default=fields.Datetime.now, tracking=True)
reported_by_id = fields.Many2one('res.users', string='Reported By', default=lambda s: s.env.user)
substance = fields.Char(string='Substance', tracking=True)
quantity = fields.Float(string='Quantity', digits=(16, 3))
uom = fields.Char(string='UoM', default='L')
location = fields.Char(string='Location')
containment_action = fields.Text(string='Containment Action')
regulator_notified = fields.Boolean(string='Regulator Notified', tracking=True)
regulator_notification_date = fields.Datetime(string='Notification Sent')
root_cause = fields.Text(string='Root Cause')
corrective_action = fields.Text(string='Corrective Action')
capa_ref = fields.Char(string='CAPA Reference')
state = fields.Selection(
[('reported', 'Reported'), ('contained', 'Contained'),
('investigation', 'Investigation'), ('closed', 'Closed')],
string='Status', default='reported', required=True, tracking=True,
)
attachment_ids = fields.Many2many(
'ir.attachment', 'fp_spill_register_attachment_rel', 'spill_id', 'attachment_id', string='Attachments',
)
@api.model
def _default_name(self):
seq = self.env['ir.sequence'].next_by_code('fusion.plating.spill.register')
return seq or '/'
def action_contain(self):
self.write({'state': 'contained'})
def action_investigate(self):
self.write({'state': 'investigation'})
def action_close(self):
self.write({'state': 'closed'})

View File

@@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-
# Copyright 2026 Nexa Systems Inc.
# License OPL-1 (Odoo Proprietary License v1.0)
from odoo import api, fields, models
class FpWasteManifest(models.Model):
_name = 'fusion.plating.waste.manifest'
_description = 'Fusion Plating - Waste Manifest'
_inherit = ['mail.thread', 'mail.activity.mixin']
_order = 'ship_date desc, id desc'
name = fields.Char(string='Reference', required=True, copy=False, default=lambda s: s._default_name(), tracking=True)
waste_stream_id = fields.Many2one('fusion.plating.waste.stream', string='Waste Stream', required=True, ondelete='restrict', tracking=True)
facility_id = fields.Many2one('fusion.plating.facility', related='waste_stream_id.facility_id', store=True, readonly=True)
company_id = fields.Many2one('res.company', related='facility_id.company_id', store=True, readonly=True)
ship_date = fields.Date(string='Ship Date', default=fields.Date.context_today, tracking=True)
quantity = fields.Float(string='Quantity', digits=(16, 3))
uom = fields.Char(string='UoM', default='kg')
carrier_id = fields.Many2one('res.partner', string='Carrier', domain=[('is_company', '=', True)], tracking=True)
receiver_id = fields.Many2one('res.partner', string='Receiver', domain=[('is_company', '=', True)], tracking=True)
manifest_number = fields.Char(string='Manifest #', tracking=True)
state = fields.Selection(
[('draft', 'Draft'), ('shipped', 'Shipped'), ('received', 'Received'), ('closed', 'Closed')],
string='Status', default='draft', required=True, tracking=True,
)
attachment_ids = fields.Many2many(
'ir.attachment', 'fp_waste_manifest_attachment_rel', 'manifest_id', 'attachment_id', string='Attachments',
)
notes = fields.Html(string='Notes')
@api.model
def _default_name(self):
seq = self.env['ir.sequence'].next_by_code('fusion.plating.waste.manifest')
return seq or '/'
def action_ship(self):
self.write({'state': 'shipped'})
def action_receive(self):
self.write({'state': 'received'})
def action_close(self):
self.write({'state': 'closed'})

View File

@@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
# Copyright 2026 Nexa Systems Inc.
# License OPL-1 (Odoo Proprietary License v1.0)
from odoo import fields, models
class FpWasteStream(models.Model):
_name = 'fusion.plating.waste.stream'
_description = 'Fusion Plating - Waste Stream'
_order = 'facility_id, name'
name = fields.Char(string='Stream', required=True)
code = fields.Char(string='Code')
facility_id = fields.Many2one('fusion.plating.facility', string='Facility', required=True, ondelete='cascade')
company_id = fields.Many2one('res.company', related='facility_id.company_id', store=True, readonly=True)
waste_class = fields.Char(string='Waste Class')
description = fields.Text(string='Description')
physical_state = fields.Selection(
[('liquid', 'Liquid'), ('solid', 'Solid'), ('sludge', 'Sludge'), ('gas', 'Gas')],
string='Physical State', default='liquid',
)
generation_rate = fields.Float(string='Generation Rate')
generation_uom = fields.Char(string='Rate UoM', default='kg/day')
disposal_method = fields.Char(string='Disposal Method')
approved_carrier_id = fields.Many2one('res.partner', string='Approved Carrier', domain=[('is_company', '=', True)])
approved_facility_id = fields.Many2one('res.partner', string='Approved Receiving Facility', domain=[('is_company', '=', True)])
manifest_ids = fields.One2many('fusion.plating.waste.manifest', 'waste_stream_id', string='Manifests')
active = fields.Boolean(default=True)