Files
Odoo-Modules/fusion_plating/fusion_plating/models/fp_step_kind.py
gsinghpal 586f05d567 chnages
2026-05-04 02:14:34 -04:00

283 lines
10 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
from ._fp_uom_selection import FP_UOM_SELECTION
class FpStepKind(models.Model):
"""User-extensible Step Kind catalog.
Replaces the hardcoded `default_kind` Selection on fp.step.template
and fusion.plating.process.node. Each kind carries a list of default
inputs that get seeded onto a step template when the kind is picked.
"""
_name = 'fp.step.kind'
_description = 'Fusion Plating — Step Kind'
_order = 'sequence, name'
code = fields.Char(
string='Code', required=True, index=True,
help='Stable lowercase technical key. Used by automation rules and '
'workflow-state triggers (e.g. "cleaning", "plate"). Lower-case'
' enforced; underscores allowed.',
)
name = fields.Char(string='Name', required=True, translate=True)
sequence = fields.Integer(string='Sequence', default=10)
active = fields.Boolean(string='Active', default=True)
description = fields.Html(string='Description')
icon = fields.Selection(
selection='_get_icon_selection',
string='Icon',
default='fa-cog',
)
company_id = fields.Many2one(
'res.company', string='Company',
default=lambda self: self.env.company,
)
default_input_ids = fields.One2many(
'fp.step.kind.default.input', 'kind_id',
string='Default Inputs', copy=True,
help='Auto-seeded onto a step template when this kind is picked '
'(via the "Seed Defaults" action).',
)
template_count = fields.Integer(
string='Templates', compute='_compute_template_count')
_sql_constraints = [
('fp_step_kind_code_company_uniq',
'unique(code, company_id)',
'Step kind code must be unique within a company.'),
]
# Curated FontAwesome 4 icon catalog for the visual icon picker.
# Bigger than the 24 historical fp.process.node list — covers
# manufacturing, lab, quality, shipping, safety, time, status etc.
# FA4 ships with Odoo (no extra deps). Key = CSS class, Value = label.
_ICON_SELECTION = [
# Process / chemistry
('fa-flask', 'Flask / Chemistry'),
('fa-tint', 'Drop / Liquid'),
('fa-tachometer', 'Gauge / Measure'),
('fa-thermometer-half', 'Temp / Heat'),
('fa-fire', 'Fire / Bake'),
('fa-snowflake-o', 'Cold / Freeze'),
('fa-bolt', 'Bolt / Electric'),
('fa-plug', 'Plug / Power'),
('fa-magnet', 'Magnet'),
('fa-bullseye', 'Target / Blast'),
('fa-shower', 'Shower / Clean'),
('fa-bathtub', 'Bathtub / Soak'),
('fa-tachometer', 'Tachometer'),
# Equipment / shop
('fa-industry', 'Industry / Line'),
('fa-wrench', 'Wrench / Operation'),
('fa-cog', 'Gear / General'),
('fa-cogs', 'Gears / System'),
('fa-sitemap', 'Sitemap / Process'),
('fa-cubes', 'Cubes / Batch'),
('fa-cube', 'Cube / Part'),
('fa-th', 'Grid / Racking'),
('fa-th-large', 'Large Grid'),
('fa-server', 'Server / Rack'),
('fa-database', 'Database / Tank'),
('fa-archive', 'Archive / Box'),
('fa-recycle', 'Recycle / Reuse'),
('fa-balance-scale', 'Scale / Balance'),
# Masking / surface
('fa-paint-brush', 'Paint / Masking'),
('fa-eraser', 'Eraser / De-Masking'),
('fa-shield', 'Shield / Protect'),
('fa-diamond', 'Diamond / Plating'),
('fa-circle-o-notch', 'Coating Layer'),
# Inspection / quality
('fa-search', 'Search / Inspect'),
('fa-search-plus', 'Search Plus'),
('fa-eye', 'Eye / Visual'),
('fa-eye-slash', 'Eye Slash / Hidden'),
('fa-camera', 'Camera / Photo'),
('fa-check', 'Check'),
('fa-check-circle', 'Check / Approve'),
('fa-check-square-o', 'Checkbox'),
('fa-times', 'Reject / Cancel'),
('fa-times-circle', 'Reject Circle'),
('fa-exclamation-triangle', 'Warning'),
('fa-exclamation-circle', 'Alert'),
('fa-info-circle', 'Info'),
('fa-question-circle', 'Question'),
('fa-bug', 'Bug / Defect'),
('fa-flag', 'Flag'),
('fa-flag-checkered', 'Finish / Done'),
('fa-trophy', 'Trophy / Pass'),
('fa-thumbs-up', 'Thumbs Up'),
('fa-thumbs-down', 'Thumbs Down'),
('fa-star', 'Star'),
('fa-bookmark', 'Bookmark'),
('fa-certificate', 'Certificate'),
# Time
('fa-clock-o', 'Clock / Wait'),
('fa-hourglass-half', 'Hourglass'),
('fa-hourglass-end', 'Hourglass End'),
('fa-calendar', 'Calendar'),
('fa-calendar-check-o', 'Scheduled'),
('fa-history', 'History'),
# Safety / handling
('fa-hand-paper-o', 'Hand / Manual'),
('fa-hand-stop-o', 'Stop Hand'),
('fa-life-ring', 'Safety / Life Ring'),
('fa-medkit', 'First Aid'),
('fa-user-md', 'Inspector'),
('fa-lock', 'Lock / Hold'),
('fa-unlock', 'Unlock / Release'),
('fa-key', 'Key'),
# Documentation / certs
('fa-file-text-o', 'Document'),
('fa-file-pdf-o', 'PDF'),
('fa-file-image-o', 'Image File'),
('fa-clipboard', 'Clipboard'),
('fa-list-alt', 'Checklist'),
('fa-list-ul', 'List'),
('fa-tags', 'Tags'),
('fa-tag', 'Tag'),
('fa-barcode', 'Barcode'),
('fa-qrcode', 'QR Code'),
('fa-pencil', 'Pencil'),
('fa-edit', 'Edit'),
('fa-print', 'Print'),
('fa-paperclip', 'Attach'),
# Shipping / logistics
('fa-truck', 'Truck / Receiving'),
('fa-paper-plane', 'Ship / Send'),
('fa-plane', 'Plane / Airfreight'),
('fa-ship', 'Ship'),
('fa-shopping-cart', 'Cart'),
('fa-shopping-bag', 'Bag / Pack'),
('fa-gift', 'Gift / Package'),
('fa-suitcase', 'Suitcase'),
('fa-globe', 'Global'),
('fa-map-marker', 'Location'),
('fa-road', 'In Transit'),
# Status / process flow
('fa-play-circle', 'Start'),
('fa-pause-circle', 'Pause / Hold'),
('fa-stop-circle', 'Stop'),
('fa-step-forward', 'Step Forward'),
('fa-fast-forward', 'Fast Forward'),
('fa-refresh', 'Refresh / Repeat'),
('fa-undo', 'Undo / Rework'),
('fa-share', 'Hand-off'),
('fa-arrow-right', 'Arrow Right'),
('fa-arrow-down', 'Arrow Down'),
('fa-long-arrow-right', 'Long Arrow Right'),
('fa-random', 'Random / Mix'),
('fa-exchange', 'Exchange'),
('fa-sort-amount-asc', 'Sort Asc'),
('fa-sort-amount-desc', 'Sort Desc'),
('fa-tasks', 'Tasks'),
# Misc useful
('fa-sun-o', 'Sun / Dry'),
('fa-moon-o', 'Moon / Night'),
('fa-cloud', 'Cloud'),
('fa-leaf', 'Leaf / Eco'),
('fa-tree', 'Tree'),
('fa-bell', 'Bell / Alert'),
('fa-bullhorn', 'Announce'),
('fa-trash', 'Trash / Discard'),
('fa-plus-circle', 'Add'),
('fa-minus-circle', 'Remove'),
('fa-circle', 'Circle'),
('fa-square', 'Square'),
('fa-asterisk', 'Asterisk'),
('fa-cutlery', 'Cutlery / Bend'),
('fa-link', 'Link / Adhesion'),
('fa-chain-broken', 'Broken Chain'),
('fa-anchor', 'Anchor'),
('fa-ban', 'Ban / Forbidden'),
]
@api.model
def _get_icon_selection(self):
return self._ICON_SELECTION
@api.depends()
def _compute_template_count(self):
Tpl = self.env['fp.step.template']
for k in self:
k.template_count = Tpl.search_count([('kind_id', '=', k.id)])
@api.model_create_multi
def create(self, vals_list):
for v in vals_list:
if v.get('code'):
v['code'] = v['code'].lower().strip().replace(' ', '_')
return super().create(vals_list)
def write(self, vals):
if vals.get('code'):
vals['code'] = vals['code'].lower().strip().replace(' ', '_')
return super().write(vals)
def action_open_templates(self):
self.ensure_one()
return {
'type': 'ir.actions.act_window',
'name': _('Step Templates — %s') % self.name,
'res_model': 'fp.step.template',
'view_mode': 'list,form',
'domain': [('kind_id', '=', self.id)],
'context': {'default_kind_id': self.id},
}
class FpStepKindDefaultInput(models.Model):
"""Default input prototype attached to a step kind.
When a recipe author picks a kind on a step template and clicks
'Seed Defaults', these get copied into the template's input list
(idempotent — skips by name).
"""
_name = 'fp.step.kind.default.input'
_description = 'Fusion Plating — Step Kind Default Input'
_order = 'sequence, name'
name = fields.Char(string='Name', required=True, translate=True)
kind_id = fields.Many2one(
'fp.step.kind', string='Kind',
required=True, ondelete='cascade', index=True,
)
input_type = fields.Selection([
('text', 'Text'),
('number', 'Number'),
('boolean', 'Yes/No'),
('selection', 'Selection'),
('date', 'Date / Time'),
('signature', 'Signature'),
('time_hms', 'Time (HH:MM:SS)'),
('time_seconds', 'Time (seconds)'),
('temperature', 'Temperature'),
('thickness', 'Thickness'),
('pass_fail', 'Pass / Fail'),
('photo', 'Photo'),
('multi_point_thickness', 'Multi-Point Thickness (avg)'),
('bath_chemistry_panel', 'Bath Chemistry Panel'),
('ph', 'pH'),
], string='Input Type', required=True, default='text')
target_unit = fields.Selection(FP_UOM_SELECTION, string='Target Unit')
required = fields.Boolean(string='Required', default=False)
hint = fields.Char(string='Hint')
selection_options = fields.Text(string='Selection Options',
help='Comma-separated when input_type is "selection".')
sequence = fields.Integer(string='Sequence', default=10)