feat(plating): split templates vs part-scoped processes + Process smart button
Two user-reported gaps: 1. The Process Recipes list was about to be flooded by part-scoped clones as soon as parts started carrying customised processes — thousands of clones would bury the handful of real shared templates (General Processing, Anodize, etc.). Fix: the main Process Recipes action now narrows to part_catalog_id = False so shared templates stay alone in that view. A sibling menu "Part Processes" (Plating → Operations → Part Processes) shows the inverse list — every part-cloned process, grouped by part — so admins can audit clones without cluttering the templates list. Search view gains two toggle filters (Shared Templates / Part-Scoped) and a "Group by Part" option. The node list gains an optional "Part" column. Split across modules: core owns the base search / tree / action (unchanged); configurator owns all the part_catalog_id-dependent pieces (filter extensions, list column, narrower domain, "Part Processes" action + menu). Keeps the dependency direction clean — configurator always depends on core, never the other way. 2. Added a "Process" smart button to the part form's button box. Shows either a green check (composed) or "None" (not yet composed) and opens the part-scoped Composer on click. Gives users one-tap access from any part form without hunting through the Process tab. fusion_plating → 19.0.8.0.0 fusion_plating_configurator → 19.0.13.1.0 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
|
||||
{
|
||||
'name': 'Fusion Plating',
|
||||
'version': '19.0.7.4.0',
|
||||
'version': '19.0.8.0.0',
|
||||
'category': 'Manufacturing/Plating',
|
||||
'summary': 'Core plating / metal finishing ERP: facilities, processes, tanks, baths, jobs, operators.',
|
||||
'description': """
|
||||
|
||||
@@ -161,6 +161,7 @@
|
||||
domain="[('node_type', '=', 'sub_process')]"/>
|
||||
<filter name="operations" string="Operations"
|
||||
domain="[('node_type', '=', 'operation')]"/>
|
||||
<separator/>
|
||||
<filter name="archived" string="Archived"
|
||||
domain="[('active', '=', False)]"/>
|
||||
<filter name="group_type" string="Type"
|
||||
@@ -169,11 +170,17 @@
|
||||
context="{'group_by': 'process_type_id'}"/>
|
||||
<filter name="group_wc" string="Work Centre"
|
||||
context="{'group_by': 'work_center_id'}"/>
|
||||
<!-- Part-scoped filters live in fusion_plating_configurator;
|
||||
the part_catalog_id field is declared there (core
|
||||
can't see it without a circular dep). -->
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- ===== WINDOW ACTION — Recipe list ===== -->
|
||||
<!-- Domain only narrows by node_type in core. The configurator
|
||||
module adds the part_catalog_id = False narrowing via a
|
||||
view/action inherit (see fusion_plating_configurator). -->
|
||||
<record id="action_fp_process_recipe" model="ir.actions.act_window">
|
||||
<field name="name">Process Recipes</field>
|
||||
<field name="res_model">fusion.plating.process.node</field>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
{
|
||||
'name': 'Fusion Plating — Configurator',
|
||||
'version': '19.0.13.0.0',
|
||||
'version': '19.0.13.1.0',
|
||||
'category': 'Manufacturing/Plating',
|
||||
'summary': 'Quotation configurator with part catalog, coating configs, and formula-based pricing engine.',
|
||||
'description': """
|
||||
@@ -42,6 +42,7 @@ Provides:
|
||||
'data/fp_treatment_data.xml',
|
||||
'views/fp_treatment_views.xml',
|
||||
'views/fp_part_catalog_views.xml',
|
||||
'views/fp_process_node_part_scoped_views.xml',
|
||||
'views/fp_coating_config_views.xml',
|
||||
'views/fp_pricing_rule_views.xml',
|
||||
'views/fp_customer_price_list_views.xml',
|
||||
|
||||
@@ -83,6 +83,26 @@
|
||||
context="{'search_default_part_catalog_id': id, 'default_part_catalog_id': id}">
|
||||
<field name="description_template_count" widget="statinfo" string="Descriptions"/>
|
||||
</button>
|
||||
<!-- Sub 3 follow-up: Process smart button. Click
|
||||
opens the part-scoped Process Composer so
|
||||
users have a one-tap path from any part
|
||||
form to its process tree. -->
|
||||
<button name="action_open_part_composer"
|
||||
type="object"
|
||||
class="oe_stat_button"
|
||||
icon="fa-sitemap">
|
||||
<div class="o_stat_info">
|
||||
<span class="o_stat_value"
|
||||
invisible="default_process_id">
|
||||
None
|
||||
</span>
|
||||
<span class="o_stat_value text-success"
|
||||
invisible="not default_process_id">
|
||||
<i class="fa fa-check-circle"/>
|
||||
</span>
|
||||
<span class="o_stat_text">Process</span>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<widget name="web_ribbon" title="Archived" bg_color="text-bg-danger" invisible="active"/>
|
||||
<widget name="web_ribbon" title="Superseded" bg_color="text-bg-warning" invisible="is_latest_revision"/>
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
<?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.
|
||||
|
||||
Separates shared recipe templates from part-scoped clones in the
|
||||
backend so thousands of part clones don't bury the 5–10 real
|
||||
templates in the main Recipes list.
|
||||
|
||||
* Narrow the existing Process Recipes action to templates only
|
||||
(part_catalog_id = False).
|
||||
* Add a sibling "Part Processes" menu + action for audit /
|
||||
administration of every clone, grouped by part by default.
|
||||
* Extend the search view with template / part-scoped toggles
|
||||
so admins can cross between the two lists without switching
|
||||
menus.
|
||||
-->
|
||||
<odoo>
|
||||
|
||||
<!-- ========== Extend search view: add part_catalog_id filters ========== -->
|
||||
<record id="view_fp_process_node_search_part_scoped"
|
||||
model="ir.ui.view">
|
||||
<field name="name">fusion.plating.process.node.search.part.scoped</field>
|
||||
<field name="model">fusion.plating.process.node</field>
|
||||
<field name="inherit_id"
|
||||
ref="fusion_plating.view_fp_process_node_search"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//filter[@name='operations']" position="after">
|
||||
<separator/>
|
||||
<filter name="templates_only"
|
||||
string="Shared Templates"
|
||||
domain="[('part_catalog_id', '=', False)]"/>
|
||||
<filter name="part_scoped"
|
||||
string="Part-Scoped"
|
||||
domain="[('part_catalog_id', '!=', False)]"/>
|
||||
</xpath>
|
||||
<xpath expr="//filter[@name='group_wc']" position="after">
|
||||
<filter name="group_part" string="Part"
|
||||
context="{'group_by': 'part_catalog_id'}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- ========== Extend list view: surface part column ========== -->
|
||||
<record id="view_fp_process_node_tree_part_scoped"
|
||||
model="ir.ui.view">
|
||||
<field name="name">fusion.plating.process.node.tree.part.scoped</field>
|
||||
<field name="model">fusion.plating.process.node</field>
|
||||
<field name="inherit_id"
|
||||
ref="fusion_plating.view_fp_process_node_tree"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='name']" position="after">
|
||||
<field name="part_catalog_id" string="Part" optional="show"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- ========== Narrow main Recipes action to templates only ========== -->
|
||||
<record id="fusion_plating.action_fp_process_recipe"
|
||||
model="ir.actions.act_window">
|
||||
<field name="domain">[('node_type', '=', 'recipe'), ('part_catalog_id', '=', False)]</field>
|
||||
<field name="context">{'default_node_type': 'recipe', 'search_default_recipes_only': 1, 'search_default_templates_only': 1}</field>
|
||||
</record>
|
||||
|
||||
<!-- ========== NEW action — Part Processes ========== -->
|
||||
<record id="action_fp_process_recipe_part_scoped"
|
||||
model="ir.actions.act_window">
|
||||
<field name="name">Part Processes</field>
|
||||
<field name="res_model">fusion.plating.process.node</field>
|
||||
<field name="view_mode">list,form</field>
|
||||
<field name="domain">[('node_type', '=', 'recipe'), ('part_catalog_id', '!=', False)]</field>
|
||||
<field name="context">{'search_default_part_scoped': 1, 'search_default_group_part': 1}</field>
|
||||
<field name="search_view_id"
|
||||
ref="fusion_plating.view_fp_process_node_search"/>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
No part-customised processes yet
|
||||
</p>
|
||||
<p>
|
||||
This view lists every process tree that has been
|
||||
composed for a specific part via the part form's
|
||||
<b>Compose</b> button. Each row is a clone of a shared
|
||||
template with per-part tweaks. To browse the shared
|
||||
templates themselves, use <b>Process Recipes</b>.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_fp_process_part_scoped"
|
||||
name="Part Processes"
|
||||
parent="fusion_plating.menu_fp_operations"
|
||||
action="action_fp_process_recipe_part_scoped"
|
||||
sequence="6"/>
|
||||
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user