feat(jobs): Sub 14 — configurable workflow state bar (Path B)
Replaces the generic Draft/Confirmed/In Progress/Done statusbar with
a shop-configurable list of plating-specific milestones. Bar advances
automatically as recipe steps complete; no manual button clicks.
What ships
==========
* New model: fp.job.workflow.state
Catalog of milestones (name, code, sequence, color, triggers).
Triggers can be:
- trigger_default_kinds: "receiving,inspect" matches by step.default_kind
- trigger_first_step_started: any wet/bake/mask/rack step started
- trigger_all_steps_done: every non-cancelled step in done/skipped
- block_when_quality_hold: held back while NCR/hold open
Plus per-recipe-node override (see below).
* Default 7-state seed (data/fp_workflow_state_data.xml):
Draft → Confirmed → Received → In Progress → Inspected → Shipped → Done
noupdate=1 so per-shop edits survive module upgrade.
* Recipe-side trigger field on fusion.plating.process.node:
triggers_workflow_state_id (Many2one, optional)
Wins over default_kind matching. Lets the recipe author pin a
specific step as a milestone trigger even when default_kind isn't
set or doesn't match. Exposed in the Recipe Tree Editor properties
panel (dropdown sourced from the catalog).
* fp.job.workflow_state_id (computed, stored)
Iterates the catalog in sequence order; lands at the highest passed
milestone. Recomputes on step state / kind / recipe_node / quality
hold changes. Replaces fp.job.state on the form's statusbar.
* Settings UI: Configuration > Workflow States
Standard list+form pages so admins can add / edit / deactivate
states. Manager-group write permission, supervisor read.
What this does NOT do
=====================
* Doesn't drop fp.job.state — that field still drives the internal
state machine (button_confirm, action_cancel, etc.). Only the
UI statusbar is reassigned.
* No migration for existing jobs — they auto-recompute on next read
because workflow_state_id is a stored compute with the right
api.depends. Existing WH/JOB/00342 will display its current
workflow state on next page load.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -48,6 +48,16 @@
|
||||
invisible="state in ('draft', 'cancelled')"/>
|
||||
</xpath>
|
||||
|
||||
<!-- Sub 14 — Replace the generic Draft/Confirmed/In Progress/Done
|
||||
statusbar with the configurable workflow_state_id bar.
|
||||
Operators see meaningful plating milestones (Received,
|
||||
Inspected, Shipped, etc.) instead of generic Odoo states. -->
|
||||
<xpath expr="//header/field[@name='state']" position="replace">
|
||||
<field name="workflow_state_id"
|
||||
widget="statusbar"
|
||||
options="{'clickable': '0'}"/>
|
||||
</xpath>
|
||||
|
||||
<!-- Surface part / coating / recipe on the header so the
|
||||
floor knows WHAT they're plating without diving into
|
||||
Source. The "Reference Product" line in core is just
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2026 Nexa Systems Inc.
|
||||
License OPL-1 (Odoo Proprietary License v1.0)
|
||||
Sub 14 — Workflow state catalog UI (admin / Settings).
|
||||
-->
|
||||
<odoo>
|
||||
|
||||
<!-- ====================== List view ====================== -->
|
||||
<record id="view_fp_workflow_state_list" model="ir.ui.view">
|
||||
<field name="name">fp.job.workflow.state.list</field>
|
||||
<field name="model">fp.job.workflow.state</field>
|
||||
<field name="arch" type="xml">
|
||||
<list string="Workflow States" default_order="sequence, id">
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="color" widget="badge"
|
||||
decoration-info="color == 'blue'"
|
||||
decoration-success="color == 'success' or color == 'green'"
|
||||
decoration-warning="color == 'yellow' or color == 'orange'"
|
||||
decoration-danger="color == 'danger'"
|
||||
decoration-muted="color == 'grey'"/>
|
||||
<field name="trigger_default_kinds"/>
|
||||
<field name="trigger_first_step_started"/>
|
||||
<field name="trigger_all_steps_done"/>
|
||||
<field name="block_when_quality_hold"/>
|
||||
<field name="is_initial"/>
|
||||
<field name="is_terminal"/>
|
||||
<field name="active" widget="boolean_toggle"/>
|
||||
</list>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- ====================== Form view ====================== -->
|
||||
<record id="view_fp_workflow_state_form" model="ir.ui.view">
|
||||
<field name="name">fp.job.workflow.state.form</field>
|
||||
<field name="model">fp.job.workflow.state</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Workflow State">
|
||||
<sheet>
|
||||
<div class="oe_title">
|
||||
<label for="name"/>
|
||||
<h1><field name="name" placeholder="Received"/></h1>
|
||||
</div>
|
||||
<group>
|
||||
<group string="Identity">
|
||||
<field name="code" placeholder="received"/>
|
||||
<field name="sequence"/>
|
||||
<field name="color" widget="badge"/>
|
||||
<field name="active"/>
|
||||
</group>
|
||||
<group string="Lifecycle role">
|
||||
<field name="is_initial"/>
|
||||
<field name="is_terminal"/>
|
||||
<field name="block_when_quality_hold"/>
|
||||
</group>
|
||||
</group>
|
||||
<group string="Trigger conditions">
|
||||
<field name="trigger_default_kinds"
|
||||
placeholder="receiving, inspect"/>
|
||||
<field name="trigger_first_step_started"/>
|
||||
<field name="trigger_all_steps_done"/>
|
||||
<p class="text-muted oe_grey mt-2">
|
||||
<strong>How triggers combine:</strong> a state is "passed"
|
||||
when EITHER the special trigger is true, OR every
|
||||
recipe step matching the listed default_kinds (or
|
||||
tagged via the per-node override on the recipe) is
|
||||
in done/skipped/cancelled state.
|
||||
<br/>
|
||||
<em>block_when_quality_hold</em>: holds back the
|
||||
advance even if the trigger conditions are met,
|
||||
until all open quality holds on the job are closed.
|
||||
</p>
|
||||
</group>
|
||||
<group string="Notes">
|
||||
<field name="description" nolabel="1"
|
||||
placeholder="What this milestone represents and when it should fire..."/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- ====================== Action + Menu ====================== -->
|
||||
<record id="action_fp_workflow_state" model="ir.actions.act_window">
|
||||
<field name="name">Workflow States</field>
|
||||
<field name="res_model">fp.job.workflow.state</field>
|
||||
<field name="view_mode">list,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
Create your first workflow state.
|
||||
</p>
|
||||
<p>
|
||||
Workflow states are the milestones that appear on the
|
||||
status bar of every plating job. Each state passes
|
||||
automatically when its trigger conditions are met
|
||||
(recipe step kind finishes, all steps done, etc.).
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_fp_workflow_state"
|
||||
name="Workflow States"
|
||||
parent="fusion_plating.menu_fp_config"
|
||||
action="action_fp_workflow_state"
|
||||
sequence="80"/>
|
||||
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user