feat(configurator): fp.pricing.rule — formula-based pricing engine with complexity surcharges

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsinghpal
2026-04-12 18:28:43 -04:00
parent 2e80fd3ca1
commit 2fa7f2aa2e
5 changed files with 218 additions and 1 deletions

View File

@@ -1,2 +1,131 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo></odoo>
<!--
Copyright 2026 Nexa Systems Inc.
License OPL-1 (Odoo Proprietary License v1.0)
Part of the Fusion Plating product family.
-->
<odoo>
<!-- ===== Pricing Rule List View ===== -->
<record id="view_fp_pricing_rule_list" model="ir.ui.view">
<field name="name">fp.pricing.rule.list</field>
<field name="model">fp.pricing.rule</field>
<field name="arch" type="xml">
<list string="Pricing Rules" decoration-muted="not active">
<field name="sequence" widget="handle"/>
<field name="name"/>
<field name="coating_config_id"/>
<field name="substrate_material"/>
<field name="certification_level"/>
<field name="pricing_method"/>
<field name="currency_id" column_invisible="1"/>
<field name="base_rate"/>
<field name="minimum_charge"/>
<field name="active" widget="boolean_toggle"/>
</list>
</field>
</record>
<!-- ===== Pricing Rule Form View ===== -->
<record id="view_fp_pricing_rule_form" model="ir.ui.view">
<field name="name">fp.pricing.rule.form</field>
<field name="model">fp.pricing.rule</field>
<field name="arch" type="xml">
<form string="Pricing Rule">
<sheet>
<widget name="web_ribbon" title="Archived" bg_color="text-bg-danger" invisible="active"/>
<div class="oe_title">
<label for="name"/>
<h1><field name="name" placeholder="e.g. EN Mid-Phos Aluminium — Commercial"/></h1>
</div>
<group string="Filters">
<group>
<field name="coating_config_id"/>
<field name="substrate_material"/>
<field name="certification_level"/>
</group>
<group>
<div class="text-muted" colspan="2">
Leave filter fields blank to create a global rule
that matches any configuration.
</div>
</group>
</group>
<group string="Pricing">
<group>
<field name="pricing_method"/>
<field name="currency_id" invisible="1"/>
<field name="base_rate"/>
<field name="thickness_factor"/>
</group>
<group>
<field name="masking_rate_per_zone"/>
<field name="setup_fee"/>
<field name="minimum_charge"/>
<field name="rush_surcharge_percent"/>
</group>
</group>
<notebook>
<page string="Complexity Surcharges" name="surcharges">
<field name="complexity_surcharge_ids">
<list editable="bottom">
<field name="complexity"/>
<field name="surcharge_percent"/>
</list>
</field>
</page>
<page string="Notes" name="notes">
<field name="notes" placeholder="Internal notes about this pricing rule..."/>
</page>
</notebook>
<group>
<field name="sequence"/>
<field name="active" widget="boolean_toggle"/>
</group>
</sheet>
</form>
</field>
</record>
<!-- ===== Pricing Rule Search View ===== -->
<record id="view_fp_pricing_rule_search" model="ir.ui.view">
<field name="name">fp.pricing.rule.search</field>
<field name="model">fp.pricing.rule</field>
<field name="arch" type="xml">
<search>
<field name="name"/>
<field name="coating_config_id"/>
<separator/>
<filter string="Per Square Inch" name="per_sqin" domain="[('pricing_method','=','per_sqin')]"/>
<filter string="Per Square Foot" name="per_sqft" domain="[('pricing_method','=','per_sqft')]"/>
<filter string="Per Piece" name="per_piece" domain="[('pricing_method','=','per_piece')]"/>
<filter string="Flat Rate" name="flat_rate" domain="[('pricing_method','=','flat_rate')]"/>
<separator/>
<filter string="Archived" name="inactive" domain="[('active','=',False)]"/>
<group>
<filter string="Coating Config" name="group_coating_config" context="{'group_by':'coating_config_id'}"/>
<filter string="Pricing Method" name="group_pricing_method" context="{'group_by':'pricing_method'}"/>
</group>
</search>
</field>
</record>
<!-- ===== Window Action ===== -->
<record id="action_fp_pricing_rule" model="ir.actions.act_window">
<field name="name">Pricing Rules</field>
<field name="res_model">fp.pricing.rule</field>
<field name="view_mode">list,form</field>
<field name="search_view_id" ref="view_fp_pricing_rule_search"/>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
No pricing rules defined yet
</p>
<p>
Define formula-based pricing rules matched by coating
configuration, substrate material, and certification level.
The first matching rule (by sequence) wins.
</p>
</field>
</record>
</odoo>