feat(bridge_mrp): shop-role auto-routing + tablet worker mode (CHUNK 4/4)
Completes the worker-access story. Handoffs now route themselves.
New model fp.work.role with 8 seeded defaults (noupdate so shops can
rename/prune):
masking · racking · plating_op · demask · oven · derack ·
inspection · rework
Each one has a code, icon, description, sequence, active flag.
Config menu: Configuration → Shop Roles (manager-only).
Field additions:
hr.employee.x_fc_work_role_ids (Many2many) — tag workers with the
roles they perform. One-person shop: one employee, every role.
Specialised shop: one role per employee. Cross-trained: multiple.
fusion.plating.process.node.x_fc_work_role_id (Many2one) — tag
each recipe operation with the role that performs it.
mrp.workorder.x_fc_work_role_id (Many2one) — copied from the recipe
operation on WO generation.
Auto-assignment on WO generation:
_generate_workorders_from_recipe() now copies the operation's role
onto the WO, then calls _fp_pick_worker_for_role() which picks the
least-loaded employee (active WO count) with that role. WO lands in
their Tablet "My Queue" the moment the MO is confirmed. No manual
routing needed for the common case.
Tablet Station — worker mode:
/fp/shopfloor/tablet_overview now filters to WOs where
x_fc_assigned_user_id == env.user when the field is populated.
KPIs (WOs Ready / In Progress) reflect the logged-in worker's load,
not shop-wide totals. "My Queue" rows carry wo_state + can_start +
can_finish so inline Start/Finish buttons appear.
New JS handlers onStartWo / onFinishWo call /fp/shopfloor/start_wo
and /fp/shopfloor/stop_wo (finish=true). One-tap progression.
Views:
hr.employee form gets a "Shop Roles" notebook page with many2many_tags.
Process node form gets x_fc_work_role_id inline after work_center_id.
Work Order form shows role + assigned worker.
Smoke-tested end-to-end on WH/MO/00010:
Masking → Administrator (masking role)
Racking → Administrator (racking role)
E-Nickel → Andrew (plating_op, least-loaded tiebreaker)
Demask → Administrator (masking)
Oven bake → Andrew (oven)
Derack → Administrator (racking fallback)
Post-plate QA → Administrator (inspection)
80 existing WOs backfilled with role + worker via name-match.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
<?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 id="view_fp_work_role_list" model="ir.ui.view">
|
||||
<field name="name">fp.work.role.list</field>
|
||||
<field name="model">fp.work.role</field>
|
||||
<field name="arch" type="xml">
|
||||
<list editable="bottom">
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="code"/>
|
||||
<field name="name"/>
|
||||
<field name="icon" optional="show"/>
|
||||
<field name="description"/>
|
||||
<field name="active" widget="boolean_toggle"/>
|
||||
</list>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_fp_work_role_form" model="ir.ui.view">
|
||||
<field name="name">fp.work.role.form</field>
|
||||
<field name="model">fp.work.role</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<sheet>
|
||||
<div class="oe_title">
|
||||
<label for="name"/>
|
||||
<h1><field name="name" placeholder="e.g. Plating Operator"/></h1>
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="code" placeholder="plating_op"/>
|
||||
<field name="icon"/>
|
||||
<field name="sequence"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="active" widget="boolean_toggle"/>
|
||||
</group>
|
||||
</group>
|
||||
<group>
|
||||
<field name="description"
|
||||
placeholder="Short operator-facing description of what this role covers."/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_fp_work_role" model="ir.actions.act_window">
|
||||
<field name="name">Shop Roles</field>
|
||||
<field name="res_model">fp.work.role</field>
|
||||
<field name="view_mode">list,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
Define the roles on your shop floor
|
||||
</p>
|
||||
<p>
|
||||
Tag each employee with the roles they can perform and tag each
|
||||
recipe step with the role that performs it. Work orders will
|
||||
auto-route to the right worker when an MO is confirmed.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_fp_work_roles"
|
||||
name="Shop Roles"
|
||||
parent="fusion_plating.menu_fp_config"
|
||||
action="action_fp_work_role"
|
||||
sequence="55"
|
||||
groups="fusion_plating.group_fusion_plating_manager"/>
|
||||
|
||||
<!-- Employee form — add roles section -->
|
||||
<record id="view_hr_employee_form_fp_roles" model="ir.ui.view">
|
||||
<field name="name">hr.employee.form.fp.roles</field>
|
||||
<field name="model">hr.employee</field>
|
||||
<field name="inherit_id" ref="hr.view_employee_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//notebook" position="inside">
|
||||
<page string="Shop Roles" name="fp_shop_roles">
|
||||
<group>
|
||||
<field name="x_fc_work_role_ids" widget="many2many_tags"
|
||||
options="{'no_create_edit': True}"
|
||||
placeholder="Tag the shop roles this employee performs..."/>
|
||||
<div class="text-muted" colspan="2">
|
||||
Work orders tagged with these roles will auto-assign to
|
||||
this employee (or to another employee with the same role,
|
||||
whichever is least loaded).
|
||||
</div>
|
||||
</group>
|
||||
</page>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Process node form — add role field -->
|
||||
<record id="view_fp_process_node_form_fp_roles" model="ir.ui.view">
|
||||
<field name="name">fusion.plating.process.node.form.fp.roles</field>
|
||||
<field name="model">fusion.plating.process.node</field>
|
||||
<field name="inherit_id" ref="fusion_plating.view_fp_process_node_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='work_center_id']" position="after">
|
||||
<field name="x_fc_work_role_id"
|
||||
options="{'no_create_edit': True}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Work Order form — show role + assigned worker -->
|
||||
<record id="view_mrp_workorder_form_fp_roles" model="ir.ui.view">
|
||||
<field name="name">mrp.workorder.form.fp.roles</field>
|
||||
<field name="model">mrp.workorder</field>
|
||||
<field name="inherit_id" ref="fusion_plating_bridge_mrp.view_mrp_workorder_form_fp_bridge"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//sheet//field[@name='x_fc_customer_id']" position="after">
|
||||
<field name="x_fc_work_role_id" readonly="1"/>
|
||||
<field name="x_fc_assigned_user_id"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user