diff --git a/fusion_plating/fusion_plating_configurator/__manifest__.py b/fusion_plating/fusion_plating_configurator/__manifest__.py index d9265b35..81de69aa 100644 --- a/fusion_plating/fusion_plating_configurator/__manifest__.py +++ b/fusion_plating/fusion_plating_configurator/__manifest__.py @@ -5,7 +5,7 @@ { 'name': 'Fusion Plating — Configurator', - 'version': '19.0.22.8.0', + 'version': '19.0.23.0.0', 'category': 'Manufacturing/Plating', 'summary': 'Quotation configurator with part catalog, coating configs, and formula-based pricing engine.', 'description': """ @@ -44,6 +44,7 @@ Provides: 'views/fp_part_catalog_views.xml', 'views/fp_process_node_part_scoped_views.xml', 'views/fp_pricing_rule_views.xml', + 'views/fp_additional_charge_type_views.xml', 'views/fp_quote_configurator_views.xml', 'views/sale_order_views.xml', 'views/res_partner_views.xml', @@ -59,6 +60,7 @@ Provides: 'views/fp_configurator_menu.xml', 'views/fp_so_job_sort_views.xml', 'data/fp_sale_description_template_data.xml', + 'data/fp_additional_charge_type_data.xml', ], 'assets': { 'web.assets_backend': [ diff --git a/fusion_plating/fusion_plating_configurator/data/fp_additional_charge_type_data.xml b/fusion_plating/fusion_plating_configurator/data/fp_additional_charge_type_data.xml new file mode 100644 index 00000000..4e29e0c4 --- /dev/null +++ b/fusion_plating/fusion_plating_configurator/data/fp_additional_charge_type_data.xml @@ -0,0 +1,7 @@ + + + + Tooling Charge + 1 + + diff --git a/fusion_plating/fusion_plating_configurator/models/__init__.py b/fusion_plating/fusion_plating_configurator/models/__init__.py index d0c473df..7372dbc7 100644 --- a/fusion_plating/fusion_plating_configurator/models/__init__.py +++ b/fusion_plating/fusion_plating_configurator/models/__init__.py @@ -9,6 +9,7 @@ from . import fp_pricing_complexity_surcharge from . import fp_pricing_rule from . import fp_sale_description_template from . import fp_part_description_version +from . import fp_additional_charge_type from . import fp_so_job_sort from . import fp_quote_configurator from . import fp_serial diff --git a/fusion_plating/fusion_plating_configurator/models/fp_additional_charge_type.py b/fusion_plating/fusion_plating_configurator/models/fp_additional_charge_type.py new file mode 100644 index 00000000..b428de9a --- /dev/null +++ b/fusion_plating/fusion_plating_configurator/models/fp_additional_charge_type.py @@ -0,0 +1,29 @@ +# -*- 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 fields, models + + +class FpAdditionalChargeType(models.Model): + """A configurable, reusable 'additional charge' label (Tooling, Rush, + Setup, …) picked on the order-entry summary. Searchable + quick-create. + + Spec: docs/superpowers/specs/2026-05-29-configurable-charge-tax-lot-pricing-design.md + """ + _name = 'fp.additional.charge.type' + _description = 'Fusion Plating — Additional Charge Type' + _order = 'sequence, name' + + name = fields.Char(string='Charge Type', required=True) + default_amount = fields.Monetary( + string='Default Amount', currency_field='currency_id', + help='Optional amount pre-filled when this type is picked on an ' + 'order. The operator can override it.', + ) + currency_id = fields.Many2one( + 'res.currency', default=lambda self: self.env.company.currency_id, + ) + active = fields.Boolean(default=True) + sequence = fields.Integer(default=10) diff --git a/fusion_plating/fusion_plating_configurator/security/ir.model.access.csv b/fusion_plating/fusion_plating_configurator/security/ir.model.access.csv index 3d4e0676..c454510e 100644 --- a/fusion_plating/fusion_plating_configurator/security/ir.model.access.csv +++ b/fusion_plating/fusion_plating_configurator/security/ir.model.access.csv @@ -47,3 +47,6 @@ access_fp_so_job_sort_manager,fp.so.job.sort.manager,model_fp_so_job_sort,fusion access_fp_part_description_version_user,fp.part.description.version.user,model_fp_part_description_version,base.group_user,1,0,0,0 access_fp_part_description_version_estimator,fp.part.description.version.estimator,model_fp_part_description_version,fusion_plating.group_fp_sales_rep,1,1,1,0 access_fp_part_description_version_manager,fp.part.description.version.manager,model_fp_part_description_version,fusion_plating.group_fp_manager,1,1,1,1 +access_fp_additional_charge_type_user,fp.additional.charge.type.user,model_fp_additional_charge_type,base.group_user,1,0,0,0 +access_fp_additional_charge_type_estimator,fp.additional.charge.type.estimator,model_fp_additional_charge_type,fusion_plating.group_fp_sales_rep,1,1,1,0 +access_fp_additional_charge_type_manager,fp.additional.charge.type.manager,model_fp_additional_charge_type,fusion_plating.group_fp_manager,1,1,1,1 diff --git a/fusion_plating/fusion_plating_configurator/tests/__init__.py b/fusion_plating/fusion_plating_configurator/tests/__init__.py index 4efa20ce..2302a87b 100644 --- a/fusion_plating/fusion_plating_configurator/tests/__init__.py +++ b/fusion_plating/fusion_plating_configurator/tests/__init__.py @@ -8,3 +8,4 @@ from . import test_express_so_line_fields from . import test_express_sale_order_fields from . import test_express_wizard_fields from . import test_part_description_history +from . import test_charge_tax_lot diff --git a/fusion_plating/fusion_plating_configurator/tests/test_charge_tax_lot.py b/fusion_plating/fusion_plating_configurator/tests/test_charge_tax_lot.py new file mode 100644 index 00000000..3909c110 --- /dev/null +++ b/fusion_plating/fusion_plating_configurator/tests/test_charge_tax_lot.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Nexa Systems Inc. +# License OPL-1 (Odoo Proprietary License v1.0) +"""Configurable charge + order-level tax + lot pricing (spec 2026-05-29).""" +from odoo.tests.common import TransactionCase, tagged + + +@tagged('post_install', '-at_install', 'fp_charge_tax_lot') +class TestChargeTaxLot(TransactionCase): + + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.partner = cls.env['res.partner'].create({'name': 'ChargeCust'}) + cls.tax13 = cls.env['account.tax'].create({ + 'name': 'FP Test 13%', + 'amount': 13.0, + 'amount_type': 'percent', + 'type_tax_use': 'sale', + }) + + # ----- Task 1: charge type model ----- + def test_charge_type_quick_create_and_default(self): + ct = self.env['fp.additional.charge.type'].create({ + 'name': 'Rush Fee', 'default_amount': 75.0, + }) + self.assertEqual(ct.name, 'Rush Fee') + self.assertEqual(ct.default_amount, 75.0) + cid, cname = self.env['fp.additional.charge.type'].name_create('Setup') + self.assertTrue(cid) diff --git a/fusion_plating/fusion_plating_configurator/views/fp_additional_charge_type_views.xml b/fusion_plating/fusion_plating_configurator/views/fp_additional_charge_type_views.xml new file mode 100644 index 00000000..4f5c80e9 --- /dev/null +++ b/fusion_plating/fusion_plating_configurator/views/fp_additional_charge_type_views.xml @@ -0,0 +1,29 @@ + + + + fp.additional.charge.type.list + fp.additional.charge.type + + + + + + + + + + + + + Additional Charge Types + fp.additional.charge.type + list + + + +