folder rename
This commit is contained in:
BIN
fusion_plating/fusion_plating_batch/.DS_Store
vendored
Normal file
BIN
fusion_plating/fusion_plating_batch/.DS_Store
vendored
Normal file
Binary file not shown.
6
fusion_plating/fusion_plating_batch/__init__.py
Normal file
6
fusion_plating/fusion_plating_batch/__init__.py
Normal file
@@ -0,0 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2026 Nexa Systems Inc.
|
||||
# License OPL-1 (Odoo Proprietary License v1.0)
|
||||
# Part of the Fusion Plating product family.
|
||||
|
||||
from . import models
|
||||
30
fusion_plating/fusion_plating_batch/__manifest__.py
Normal file
30
fusion_plating/fusion_plating_batch/__manifest__.py
Normal file
@@ -0,0 +1,30 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2026 Nexa Systems Inc.
|
||||
# License OPL-1 (Odoo Proprietary License v1.0)
|
||||
# Part of the Fusion Plating product family.
|
||||
|
||||
{
|
||||
'name': 'Fusion Plating — Batch Processing',
|
||||
'version': '19.0.1.0.0',
|
||||
'category': 'Manufacturing/Plating',
|
||||
'summary': 'Group parts into rack or barrel loads for tank processing.',
|
||||
'author': 'Nexa Systems Inc.',
|
||||
'website': 'https://www.nexasystems.ca',
|
||||
'maintainer': 'Nexa Systems Inc.',
|
||||
'support': 'support@nexasystems.ca',
|
||||
'license': 'OPL-1',
|
||||
'depends': [
|
||||
'fusion_plating',
|
||||
],
|
||||
'data': [
|
||||
'security/fp_batch_security.xml',
|
||||
'security/ir.model.access.csv',
|
||||
'data/fp_sequence_data.xml',
|
||||
'views/fp_batch_chemistry_views.xml',
|
||||
'views/fp_batch_views.xml',
|
||||
'views/fp_menu.xml',
|
||||
],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
'application': False,
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2026 Nexa Systems Inc.
|
||||
License OPL-1 (Odoo Proprietary License v1.0)
|
||||
Part of the Fusion Plating product family.
|
||||
-->
|
||||
<odoo noupdate="1">
|
||||
|
||||
<record id="seq_fp_batch" model="ir.sequence">
|
||||
<field name="name">Fusion Plating: Batch</field>
|
||||
<field name="code">fusion.plating.batch</field>
|
||||
<field name="prefix">BATCH-</field>
|
||||
<field name="padding">4</field>
|
||||
<field name="company_id" eval="False"/>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
7
fusion_plating/fusion_plating_batch/models/__init__.py
Normal file
7
fusion_plating/fusion_plating_batch/models/__init__.py
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2026 Nexa Systems Inc.
|
||||
# License OPL-1 (Odoo Proprietary License v1.0)
|
||||
# Part of the Fusion Plating product family.
|
||||
|
||||
from . import fp_batch
|
||||
from . import fp_batch_chemistry
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
141
fusion_plating/fusion_plating_batch/models/fp_batch.py
Normal file
141
fusion_plating/fusion_plating_batch/models/fp_batch.py
Normal file
@@ -0,0 +1,141 @@
|
||||
# -*- 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 FpBatch(models.Model):
|
||||
"""A rack or barrel load of parts being processed through a tank.
|
||||
|
||||
Lifecycle:
|
||||
|
||||
draft → loading → in_process → unloading → complete
|
||||
↗
|
||||
(any non-complete state) → cancelled
|
||||
"""
|
||||
_name = 'fusion.plating.batch'
|
||||
_description = 'Plating Batch (Rack/Barrel Load)'
|
||||
_inherit = ['mail.thread', 'mail.activity.mixin']
|
||||
_order = 'create_date desc'
|
||||
|
||||
name = fields.Char(
|
||||
string='Batch Reference',
|
||||
required=True,
|
||||
copy=False,
|
||||
readonly=True,
|
||||
default=lambda self: self.env['ir.sequence'].next_by_code(
|
||||
'fusion.plating.batch') or '/',
|
||||
tracking=True,
|
||||
)
|
||||
facility_id = fields.Many2one(
|
||||
'fusion.plating.facility',
|
||||
string='Facility',
|
||||
required=True,
|
||||
tracking=True,
|
||||
)
|
||||
bath_id = fields.Many2one(
|
||||
'fusion.plating.bath',
|
||||
string='Bath',
|
||||
required=True,
|
||||
tracking=True,
|
||||
)
|
||||
tank_id = fields.Many2one(
|
||||
'fusion.plating.tank',
|
||||
string='Tank',
|
||||
related='bath_id.tank_id',
|
||||
store=True,
|
||||
readonly=True,
|
||||
)
|
||||
process_type_id = fields.Many2one(
|
||||
related='bath_id.process_type_id',
|
||||
store=True,
|
||||
readonly=True,
|
||||
)
|
||||
state = fields.Selection(
|
||||
selection=[
|
||||
('draft', 'Draft'),
|
||||
('loading', 'Loading'),
|
||||
('in_process', 'In Process'),
|
||||
('unloading', 'Unloading'),
|
||||
('complete', 'Complete'),
|
||||
('cancelled', 'Cancelled'),
|
||||
],
|
||||
string='Status',
|
||||
default='draft',
|
||||
required=True,
|
||||
tracking=True,
|
||||
)
|
||||
rack_ref = fields.Char(string='Rack / Barrel Ref')
|
||||
part_count = fields.Integer(string='Part Count')
|
||||
start_time = fields.Datetime(string='Process Start', tracking=True)
|
||||
end_time = fields.Datetime(string='Process End', tracking=True)
|
||||
duration_minutes = fields.Float(
|
||||
string='Duration (min)',
|
||||
compute='_compute_duration',
|
||||
store=True,
|
||||
)
|
||||
chemistry_ids = fields.One2many(
|
||||
'fusion.plating.batch.chemistry',
|
||||
'batch_id',
|
||||
string='Chemistry Readings',
|
||||
)
|
||||
chemistry_count = fields.Integer(
|
||||
string='Readings',
|
||||
compute='_compute_chemistry_count',
|
||||
)
|
||||
operator_id = fields.Many2one(
|
||||
'res.users',
|
||||
string='Operator',
|
||||
default=lambda self: self.env.user,
|
||||
tracking=True,
|
||||
)
|
||||
company_id = fields.Many2one(
|
||||
'res.company',
|
||||
string='Company',
|
||||
default=lambda self: self.env.company,
|
||||
)
|
||||
notes = fields.Html(string='Notes')
|
||||
active = fields.Boolean(default=True)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Compute
|
||||
# -------------------------------------------------------------------------
|
||||
@api.depends('start_time', 'end_time')
|
||||
def _compute_duration(self):
|
||||
for rec in self:
|
||||
if rec.start_time and rec.end_time:
|
||||
delta = rec.end_time - rec.start_time
|
||||
rec.duration_minutes = delta.total_seconds() / 60.0
|
||||
else:
|
||||
rec.duration_minutes = 0.0
|
||||
|
||||
@api.depends('chemistry_ids')
|
||||
def _compute_chemistry_count(self):
|
||||
for rec in self:
|
||||
rec.chemistry_count = len(rec.chemistry_ids)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Actions
|
||||
# -------------------------------------------------------------------------
|
||||
def action_start_loading(self):
|
||||
self.write({'state': 'loading'})
|
||||
|
||||
def action_start_process(self):
|
||||
self.write({
|
||||
'state': 'in_process',
|
||||
'start_time': fields.Datetime.now(),
|
||||
})
|
||||
|
||||
def action_start_unloading(self):
|
||||
self.write({
|
||||
'state': 'unloading',
|
||||
'end_time': fields.Datetime.now(),
|
||||
})
|
||||
|
||||
def action_complete(self):
|
||||
self.write({'state': 'complete'})
|
||||
|
||||
def action_cancel(self):
|
||||
self.write({'state': 'cancelled'})
|
||||
@@ -0,0 +1,75 @@
|
||||
# -*- 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 FpBatchChemistry(models.Model):
|
||||
"""A single chemistry reading taken during batch processing."""
|
||||
_name = 'fusion.plating.batch.chemistry'
|
||||
_description = 'Batch Chemistry Reading'
|
||||
_order = 'reading_time desc, id desc'
|
||||
|
||||
batch_id = fields.Many2one(
|
||||
'fusion.plating.batch',
|
||||
string='Batch',
|
||||
required=True,
|
||||
ondelete='cascade',
|
||||
)
|
||||
parameter_id = fields.Many2one(
|
||||
'fusion.plating.bath.parameter',
|
||||
string='Parameter',
|
||||
required=True,
|
||||
)
|
||||
value = fields.Float(string='Value', required=True)
|
||||
reading_time = fields.Datetime(
|
||||
string='Reading Time',
|
||||
default=fields.Datetime.now,
|
||||
)
|
||||
status = fields.Selection(
|
||||
selection=[
|
||||
('pass', 'Pass'),
|
||||
('warning', 'Warning'),
|
||||
('fail', 'Fail'),
|
||||
],
|
||||
string='Status',
|
||||
compute='_compute_status',
|
||||
store=True,
|
||||
)
|
||||
notes = fields.Char(string='Notes')
|
||||
|
||||
@api.depends('parameter_id', 'value')
|
||||
def _compute_status(self):
|
||||
"""Compare value against parameter target range.
|
||||
|
||||
Uses the parameter's default target range and warning tolerance.
|
||||
A reading within [target_min, target_max] is a pass. If it falls
|
||||
within the warning tolerance band outside that range, it is a
|
||||
warning. Otherwise it is a fail.
|
||||
"""
|
||||
for rec in self:
|
||||
if not rec.parameter_id:
|
||||
rec.status = 'pass'
|
||||
continue
|
||||
param = rec.parameter_id
|
||||
target_min = param.target_min
|
||||
target_max = param.target_max
|
||||
if not target_min and not target_max:
|
||||
rec.status = 'pass'
|
||||
continue
|
||||
# Value within target range = pass
|
||||
if target_min <= rec.value <= target_max:
|
||||
rec.status = 'pass'
|
||||
continue
|
||||
# Calculate warning band from tolerance %
|
||||
tolerance = (param.warning_tolerance or 0.0) / 100.0
|
||||
span = target_max - target_min if target_max != target_min else abs(target_max) or 1.0
|
||||
margin = span * tolerance
|
||||
warning_min = target_min - margin
|
||||
warning_max = target_max + margin
|
||||
if warning_min <= rec.value <= warning_max:
|
||||
rec.status = 'warning'
|
||||
else:
|
||||
rec.status = 'fail'
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2026 Nexa Systems Inc.
|
||||
License OPL-1 (Odoo Proprietary License v1.0)
|
||||
Part of the Fusion Plating product family.
|
||||
-->
|
||||
<odoo>
|
||||
|
||||
<!-- ================================================================== -->
|
||||
<!-- RECORD RULE — Multi-company isolation on batches -->
|
||||
<!-- ================================================================== -->
|
||||
<record id="fp_batch_company_rule" model="ir.rule">
|
||||
<field name="name">Fusion Plating: Batch — multi-company</field>
|
||||
<field name="model_id" ref="model_fusion_plating_batch"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|', ('company_id', '=', False), ('company_id', 'in', company_ids)]</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
@@ -0,0 +1,7 @@
|
||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_fp_batch_operator,fp.batch.operator,model_fusion_plating_batch,fusion_plating.group_fusion_plating_operator,1,1,1,0
|
||||
access_fp_batch_supervisor,fp.batch.supervisor,model_fusion_plating_batch,fusion_plating.group_fusion_plating_supervisor,1,1,1,0
|
||||
access_fp_batch_manager,fp.batch.manager,model_fusion_plating_batch,fusion_plating.group_fusion_plating_manager,1,1,1,1
|
||||
access_fp_batch_chemistry_operator,fp.batch.chemistry.operator,model_fusion_plating_batch_chemistry,fusion_plating.group_fusion_plating_operator,1,1,1,0
|
||||
access_fp_batch_chemistry_supervisor,fp.batch.chemistry.supervisor,model_fusion_plating_batch_chemistry,fusion_plating.group_fusion_plating_supervisor,1,1,1,0
|
||||
access_fp_batch_chemistry_manager,fp.batch.chemistry.manager,model_fusion_plating_batch_chemistry,fusion_plating.group_fusion_plating_manager,1,1,1,1
|
||||
|
@@ -0,0 +1,87 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2026 Nexa Systems Inc.
|
||||
License OPL-1 (Odoo Proprietary License v1.0)
|
||||
Part of the Fusion Plating product family.
|
||||
-->
|
||||
<odoo>
|
||||
|
||||
<!-- ===== LIST ===== -->
|
||||
<record id="view_fp_batch_chemistry_list" model="ir.ui.view">
|
||||
<field name="name">fp.batch.chemistry.list</field>
|
||||
<field name="model">fusion.plating.batch.chemistry</field>
|
||||
<field name="arch" type="xml">
|
||||
<list string="Chemistry Readings"
|
||||
decoration-success="status == 'pass'"
|
||||
decoration-warning="status == 'warning'"
|
||||
decoration-danger="status == 'fail'">
|
||||
<field name="batch_id"/>
|
||||
<field name="parameter_id"/>
|
||||
<field name="value"/>
|
||||
<field name="reading_time"/>
|
||||
<field name="status" widget="badge"
|
||||
decoration-success="status == 'pass'"
|
||||
decoration-warning="status == 'warning'"
|
||||
decoration-danger="status == 'fail'"/>
|
||||
<field name="notes"/>
|
||||
</list>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- ===== FORM ===== -->
|
||||
<record id="view_fp_batch_chemistry_form" model="ir.ui.view">
|
||||
<field name="name">fp.batch.chemistry.form</field>
|
||||
<field name="model">fusion.plating.batch.chemistry</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Chemistry Reading">
|
||||
<sheet>
|
||||
<group>
|
||||
<group>
|
||||
<field name="batch_id"/>
|
||||
<field name="parameter_id"/>
|
||||
<field name="value"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="reading_time"/>
|
||||
<field name="status" widget="badge"
|
||||
decoration-success="status == 'pass'"
|
||||
decoration-warning="status == 'warning'"
|
||||
decoration-danger="status == 'fail'"/>
|
||||
<field name="notes"/>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- ===== SEARCH ===== -->
|
||||
<record id="view_fp_batch_chemistry_search" model="ir.ui.view">
|
||||
<field name="name">fp.batch.chemistry.search</field>
|
||||
<field name="model">fusion.plating.batch.chemistry</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Chemistry Readings">
|
||||
<field name="batch_id"/>
|
||||
<field name="parameter_id"/>
|
||||
<separator/>
|
||||
<filter string="Pass" name="pass" domain="[('status','=','pass')]"/>
|
||||
<filter string="Warning" name="warning" domain="[('status','=','warning')]"/>
|
||||
<filter string="Fail" name="fail" domain="[('status','=','fail')]"/>
|
||||
<group>
|
||||
<filter string="Batch" name="group_batch" context="{'group_by':'batch_id'}"/>
|
||||
<filter string="Parameter" name="group_parameter" context="{'group_by':'parameter_id'}"/>
|
||||
<filter string="Status" name="group_status" context="{'group_by':'status'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- ===== ACTION ===== -->
|
||||
<record id="action_fp_batch_chemistry" model="ir.actions.act_window">
|
||||
<field name="name">Chemistry Readings</field>
|
||||
<field name="res_model">fusion.plating.batch.chemistry</field>
|
||||
<field name="view_mode">list,form</field>
|
||||
<field name="search_view_id" ref="view_fp_batch_chemistry_search"/>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
202
fusion_plating/fusion_plating_batch/views/fp_batch_views.xml
Normal file
202
fusion_plating/fusion_plating_batch/views/fp_batch_views.xml
Normal file
@@ -0,0 +1,202 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2026 Nexa Systems Inc.
|
||||
License OPL-1 (Odoo Proprietary License v1.0)
|
||||
Part of the Fusion Plating product family.
|
||||
-->
|
||||
<odoo>
|
||||
|
||||
<!-- ===== LIST ===== -->
|
||||
<record id="view_fp_batch_list" model="ir.ui.view">
|
||||
<field name="name">fp.batch.list</field>
|
||||
<field name="model">fusion.plating.batch</field>
|
||||
<field name="arch" type="xml">
|
||||
<list string="Batches"
|
||||
decoration-muted="state == 'cancelled'"
|
||||
decoration-success="state == 'complete'">
|
||||
<field name="name"/>
|
||||
<field name="facility_id"/>
|
||||
<field name="bath_id"/>
|
||||
<field name="tank_id" optional="show"/>
|
||||
<field name="rack_ref" optional="show"/>
|
||||
<field name="part_count"/>
|
||||
<field name="operator_id" widget="many2one_avatar_user"/>
|
||||
<field name="state" widget="badge"
|
||||
decoration-info="state == 'draft'"
|
||||
decoration-warning="state == 'loading'"
|
||||
decoration-primary="state == 'in_process'"
|
||||
decoration-success="state in ('unloading','complete')"
|
||||
decoration-danger="state == 'cancelled'"/>
|
||||
<field name="duration_minutes" optional="show" widget="float_time"/>
|
||||
<field name="start_time" optional="hide"/>
|
||||
<field name="end_time" optional="hide"/>
|
||||
</list>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- ===== FORM ===== -->
|
||||
<record id="view_fp_batch_form" model="ir.ui.view">
|
||||
<field name="name">fp.batch.form</field>
|
||||
<field name="model">fusion.plating.batch</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Batch">
|
||||
<header>
|
||||
<button name="action_start_loading" string="Start Loading"
|
||||
type="object" class="oe_highlight"
|
||||
invisible="state != 'draft'"/>
|
||||
<button name="action_start_process" string="Start Process"
|
||||
type="object" class="oe_highlight"
|
||||
invisible="state != 'loading'"/>
|
||||
<button name="action_start_unloading" string="Unload"
|
||||
type="object" class="oe_highlight"
|
||||
invisible="state != 'in_process'"/>
|
||||
<button name="action_complete" string="Complete"
|
||||
type="object" class="oe_highlight"
|
||||
invisible="state != 'unloading'"/>
|
||||
<button name="action_cancel" string="Cancel"
|
||||
type="object"
|
||||
invisible="state in ('complete','cancelled')"/>
|
||||
<field name="state" widget="statusbar"
|
||||
statusbar_visible="draft,loading,in_process,unloading,complete"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="%(fusion_plating_batch.action_fp_batch_chemistry)d"
|
||||
type="action" class="oe_stat_button" icon="fa-flask"
|
||||
context="{'search_default_batch_id': id}">
|
||||
<field name="chemistry_count" widget="statinfo" string="Readings"/>
|
||||
</button>
|
||||
</div>
|
||||
<div class="oe_title">
|
||||
<label for="name"/>
|
||||
<h1><field name="name" readonly="1"/></h1>
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="facility_id"/>
|
||||
<field name="bath_id" domain="[('facility_id','=',facility_id)]"/>
|
||||
<field name="tank_id"/>
|
||||
<field name="process_type_id"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="rack_ref"/>
|
||||
<field name="part_count"/>
|
||||
<field name="operator_id"/>
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
</group>
|
||||
</group>
|
||||
<group>
|
||||
<group>
|
||||
<field name="start_time"/>
|
||||
<field name="end_time"/>
|
||||
<field name="duration_minutes" widget="float_time"/>
|
||||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Chemistry Readings">
|
||||
<field name="chemistry_ids">
|
||||
<list editable="bottom">
|
||||
<field name="parameter_id"/>
|
||||
<field name="value"/>
|
||||
<field name="reading_time"/>
|
||||
<field name="status" widget="badge"
|
||||
decoration-success="status == 'pass'"
|
||||
decoration-warning="status == 'warning'"
|
||||
decoration-danger="status == 'fail'"/>
|
||||
<field name="notes"/>
|
||||
</list>
|
||||
</field>
|
||||
</page>
|
||||
<page string="Notes">
|
||||
<field name="notes"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
<chatter/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- ===== KANBAN ===== -->
|
||||
<record id="view_fp_batch_kanban" model="ir.ui.view">
|
||||
<field name="name">fp.batch.kanban</field>
|
||||
<field name="model">fusion.plating.batch</field>
|
||||
<field name="arch" type="xml">
|
||||
<kanban default_group_by="state" class="o_fp_batch_kanban">
|
||||
<field name="id"/>
|
||||
<field name="name"/>
|
||||
<field name="facility_id"/>
|
||||
<field name="bath_id"/>
|
||||
<field name="rack_ref"/>
|
||||
<field name="part_count"/>
|
||||
<field name="state"/>
|
||||
<field name="operator_id"/>
|
||||
<field name="duration_minutes"/>
|
||||
<templates>
|
||||
<t t-name="card">
|
||||
<div class="o_fp_card o_fp_batch_card">
|
||||
<div class="d-flex justify-content-between align-items-start">
|
||||
<strong class="o_fp_card_title"><field name="name"/></strong>
|
||||
</div>
|
||||
<div class="small text-muted">
|
||||
<field name="bath_id"/>
|
||||
</div>
|
||||
<div class="small">
|
||||
<i class="fa fa-cubes me-1 text-muted"/>
|
||||
<field name="rack_ref"/>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between mt-2 small">
|
||||
<span class="text-muted">Parts</span>
|
||||
<span class="fw-bold"><field name="part_count"/></span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between small">
|
||||
<span class="text-muted">Operator</span>
|
||||
<field name="operator_id" widget="many2one_avatar_user"/>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- ===== SEARCH ===== -->
|
||||
<record id="view_fp_batch_search" model="ir.ui.view">
|
||||
<field name="name">fp.batch.search</field>
|
||||
<field name="model">fusion.plating.batch</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Batches">
|
||||
<field name="name"/>
|
||||
<field name="bath_id"/>
|
||||
<field name="facility_id"/>
|
||||
<field name="rack_ref"/>
|
||||
<field name="operator_id"/>
|
||||
<separator/>
|
||||
<filter string="Draft" name="draft" domain="[('state','=','draft')]"/>
|
||||
<filter string="Loading" name="loading" domain="[('state','=','loading')]"/>
|
||||
<filter string="In Process" name="in_process" domain="[('state','=','in_process')]"/>
|
||||
<filter string="Unloading" name="unloading" domain="[('state','=','unloading')]"/>
|
||||
<filter string="Complete" name="complete" domain="[('state','=','complete')]"/>
|
||||
<filter string="Cancelled" name="cancelled" domain="[('state','=','cancelled')]"/>
|
||||
<separator/>
|
||||
<filter string="Archived" name="inactive" domain="[('active','=',False)]"/>
|
||||
<group>
|
||||
<filter string="Facility" name="group_facility" context="{'group_by':'facility_id'}"/>
|
||||
<filter string="Bath" name="group_bath" context="{'group_by':'bath_id'}"/>
|
||||
<filter string="Status" name="group_state" context="{'group_by':'state'}"/>
|
||||
<filter string="Operator" name="group_operator" context="{'group_by':'operator_id'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- ===== ACTION ===== -->
|
||||
<record id="action_fp_batch" model="ir.actions.act_window">
|
||||
<field name="name">Batches</field>
|
||||
<field name="res_model">fusion.plating.batch</field>
|
||||
<field name="view_mode">kanban,list,form</field>
|
||||
<field name="search_view_id" ref="view_fp_batch_search"/>
|
||||
<field name="context">{'search_default_draft': 1, 'search_default_loading': 1, 'search_default_in_process': 1, 'search_default_unloading': 1}</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
16
fusion_plating/fusion_plating_batch/views/fp_menu.xml
Normal file
16
fusion_plating/fusion_plating_batch/views/fp_menu.xml
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2026 Nexa Systems Inc.
|
||||
License OPL-1 (Odoo Proprietary License v1.0)
|
||||
Part of the Fusion Plating product family.
|
||||
-->
|
||||
<odoo>
|
||||
|
||||
<!-- Batches menu item under Plating > Operations -->
|
||||
<menuitem id="menu_fp_batches"
|
||||
name="Batches"
|
||||
parent="fusion_plating.menu_fp_operations"
|
||||
action="action_fp_batch"
|
||||
sequence="15"/>
|
||||
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user