feat(invoicing): managers (+QM+Owner) can create customer invoices

Grant Odoo Billing (account.group_account_invoice) to group_fp_manager via
implied_ids; Quality Manager + Owner inherit it. Billing only (not Accountant);
the SO-origin workflow gate in fusion_plating_jobs is unchanged, so managers
invoice from the Sale Order's Create Invoice action. Tests assert Manager/Owner
get Billing and Shop Manager does not.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
gsinghpal
2026-05-29 20:33:40 -04:00
parent b2186ab032
commit 1e9ffccd6b
5 changed files with 118 additions and 3 deletions

View File

@@ -5,7 +5,7 @@
{
'name': 'Fusion Plating — Invoicing',
'version': '19.0.3.7.0',
'version': '19.0.3.8.0',
'category': 'Manufacturing/Plating',
'summary': 'Invoice strategy engine with deposit, progress billing, net terms, COD/prepay, and account holds.',
'description': """

View File

@@ -14,9 +14,15 @@
<field name="user_ids" eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"/>
</record>
<!-- Backward-compat: new Manager role implies old Accounting group. -->
<!-- Backward-compat: new Manager role implies old Accounting group.
2026-05-29: Manager (+ QM + Owner via implication) also gets Odoo's
Billing group so they can create customer invoices from a Sale
Order. Billing only — not Accountant. The SO-origin workflow gate
in fusion_plating_jobs is unchanged (off-SO invoices still blocked).
Spec: docs/superpowers/specs/2026-05-29-manager-invoice-permission-design.md -->
<record id="fusion_plating.group_fp_manager" model="res.groups">
<field name="implied_ids" eval="[(4, ref('fusion_plating_invoicing.group_fp_accounting'))]"/>
<field name="implied_ids" eval="[(4, ref('fusion_plating_invoicing.group_fp_accounting')),
(4, ref('account.group_account_invoice'))]"/>
</record>
</odoo>

View File

@@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
from . import test_manager_invoice_permission

View File

@@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
# Copyright 2026 Nexa Systems Inc.
# License OPL-1 (Odoo Proprietary License v1.0)
"""Manager (+ QM + Owner) imply Odoo Billing so they can invoice.
Spec: docs/superpowers/specs/2026-05-29-manager-invoice-permission-design.md
"""
from odoo.tests.common import TransactionCase, tagged
@tagged('post_install', '-at_install', 'fp_invoice_perm')
class TestManagerInvoicePermission(TransactionCase):
def _user_with(self, group_xmlid):
return self.env['res.users'].create({
'name': 'PermUser',
'login': 'perm_%s' % group_xmlid.split('.')[-1],
'group_ids': [(6, 0, [self.env.ref(group_xmlid).id])],
})
def test_manager_has_billing_group(self):
manager = self._user_with('fusion_plating.group_fp_manager')
self.assertTrue(
manager.has_group('account.group_account_invoice'),
"Manager should imply Odoo Billing (account.group_account_invoice)",
)
def test_owner_inherits_billing(self):
owner = self._user_with('fusion_plating.group_fp_owner')
self.assertTrue(owner.has_group('account.group_account_invoice'))
def test_shop_manager_does_not_get_billing(self):
# Shop Manager is BELOW Manager — must NOT inherit Billing
# ("managers and ABOVE" scope).
shop = self._user_with('fusion_plating.group_fp_shop_manager_v2')
self.assertFalse(shop.has_group('account.group_account_invoice'))