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>
3.5 KiB
Managers Can Create Invoices (grant Billing group)
Date: 2026-05-29
Status: Approved — implementing directly (single security record; no separate plan)
Module: fusion_plating_invoicing
Goal
Let the plating Manager role (and Quality Manager + Owner, who inherit it) create customer invoices from a confirmed Sale Order.
Background — why managers can't invoice today (verified 2026-05-29)
- Creating an
account.moveof a customer type requires one of Odoo's accounting groups (minimum: Billing =account.group_account_invoice). - No plating role grants any Odoo accounting group. A repo-wide grep for
account.group_account*infusion_plating*/security/returns nothing. group_fp_managerimplies only the legacy plating-internalgroup_fp_accounting(fusion_plating_invoicing/security/fp_invoicing_security.xml:18-20), which itself chains to the deprecatedgroup_fusion_plating_supervisor— not to any Odoo accounting group. So it grants noaccount.moverights.- Result: when a Manager opens a confirmed SO and clicks Create Invoice, Odoo's
_create_invoices()tries to create anaccount.moveand the Manager hits anAccessErrorfor lacking Billing. - Separately,
fusion_plating_jobs/models/account_move.py::_fp_validate_customer_invoiceblocks off-SO customer-invoice creation for all users (parent-number audit trail). This is a workflow gate, not a permission gate — it is not the manager blocker and stays unchanged.
Decision
Grant account.group_account_invoice (Billing) to group_fp_manager via implied_ids.
- Cascade: Quality Manager → implies Manager, Owner → implies Quality Manager, so QM and Owner inherit Billing automatically. Shop Manager, Sales Manager, Technician, Operator, and below are unaffected.
- Level — Billing only: create/edit/post customer invoices + credit notes. Explicitly
not Accountant (
account.group_account_user): no vendor bills, manual journal entries, bank reconciliation, accounting reports, or period close. - Path unchanged: managers invoice from the SO (
Create Invoiceaction), which the_fp_validate_customer_invoiceworkflow gate already permits viafp_from_so_invoice. Standalone off-SO invoices remain blocked for everyone.
Implementation
Extend the existing additive implied_ids write on group_fp_manager in
fusion_plating_invoicing/security/fp_invoicing_security.xml:
<record id="fusion_plating.group_fp_manager" model="res.groups">
<field name="implied_ids" eval="[(4, ref('fusion_plating_invoicing.group_fp_accounting')),
(4, ref('account.group_account_invoice'))]"/>
</record>
(4, id) (Command.link) is additive + idempotent across install/-u. fusion_plating_invoicing
already depends transitively on account (it overrides account.move), so ref('account.…')
resolves. Bump the module version.
Testing
TransactionCase in fusion_plating_invoicing/tests/: create a user holding only
group_fp_manager, assert user.has_group('account.group_account_invoice') is True (proves
the implication landed). Then a live entech check: a Manager creates an invoice from a
confirmed SO without an AccessError.
Out of scope
- Relaxing the SO-origin workflow gate (intentional; preserves the parent-number audit trail).
- Accountant-level access (vendor bills, journals, reconciliation, reports).
- Granting invoicing to Shop Manager / Sales Manager / below.