Two distinct entities were both labelled 'Work Centre' (US/UK spelling
the only differentiator — confusing). Renamed by purpose, model IDs
unchanged so all 12+9 existing cross-refs keep working:
fusion.plating.work.center → 'Production Line'
Physical shop-layout grouping that owns tanks. Examples: 'Line 1 —
EN', 'Anodize Line', 'Prep Bay'. Has tank_ids (O2M),
supported_process_ids (M2M), capacity_per_day. The thing tanks live
in.
fp.work.centre → 'Routing Station'
Per-job-step routing entity (post-Sub-11 mrp.workcenter replacement).
Has 'kind' selection (wet_line / bake / mask / rack / inspect),
cost_per_hour for fp.job.step rollup, default_bath_id +
default_tank_id for release-ready validation. The thing a job step
routes through.
Conceptually a Production Line CONTAINS many Routing Stations (e.g.
'EN Line' production line has wet-line, bake, inspect routing
stations on it).
Updated:
- _description on both models
- string= on the name fields
- list/form/search view strings
- act_window names ('Production Lines' / 'Routing Stations')
- menu items in fp_menu.xml + fp_jobs_menu.xml
- doc comments in both model files explaining the distinction
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
75 lines
2.1 KiB
Python
75 lines
2.1 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 fields, models
|
|
|
|
|
|
class FpWorkCenter(models.Model):
|
|
"""A physical production line inside a facility.
|
|
|
|
Examples: "Line 1 — EN", "Anodize Line", "Prep Bay", "Bake Station",
|
|
"Inspection Booth", "Shipping Dock". Production lines group tanks
|
|
and provide daily-capacity scheduling. This is the SHOP-LAYOUT
|
|
entity — distinct from `fp.work.centre` which is the per-job-step
|
|
routing station with cost-per-hour rollup.
|
|
"""
|
|
_name = 'fusion.plating.work.center'
|
|
_description = 'Fusion Plating — Production Line'
|
|
_order = 'facility_id, sequence, name'
|
|
|
|
name = fields.Char(
|
|
string='Production Line',
|
|
required=True,
|
|
)
|
|
code = fields.Char(
|
|
string='Code',
|
|
required=True,
|
|
)
|
|
facility_id = fields.Many2one(
|
|
'fusion.plating.facility',
|
|
string='Facility',
|
|
required=True,
|
|
ondelete='cascade',
|
|
)
|
|
sequence = fields.Integer(
|
|
string='Sequence',
|
|
default=10,
|
|
)
|
|
active = fields.Boolean(
|
|
string='Active',
|
|
default=True,
|
|
)
|
|
supported_process_ids = fields.Many2many(
|
|
'fusion.plating.process.type',
|
|
'fp_work_center_process_rel',
|
|
'work_center_id',
|
|
'process_type_id',
|
|
string='Supported Processes',
|
|
)
|
|
tank_ids = fields.One2many(
|
|
'fusion.plating.tank',
|
|
'work_center_id',
|
|
string='Tanks',
|
|
)
|
|
tank_count = fields.Integer(
|
|
compute='_compute_tank_count',
|
|
)
|
|
capacity_per_day = fields.Float(
|
|
string='Capacity / Day',
|
|
help='Theoretical throughput (parts, jobs, or square metres per day) — unit depends on shop.',
|
|
)
|
|
|
|
_sql_constraints = [
|
|
(
|
|
'fp_work_center_code_facility_uniq',
|
|
'unique(code, facility_id)',
|
|
'Work center code must be unique within a facility.',
|
|
),
|
|
]
|
|
|
|
def _compute_tank_count(self):
|
|
for rec in self:
|
|
rec.tank_count = len(rec.tank_ids)
|