fix(plating-perms): deploy-time cascade fixes from entech I3
5 fixes discovered during the live deploy to entech LXC 111: 1. pre-migrate.py to rename old configurator's 'Shop Manager' group BEFORE new core 'Shop Manager v2' XML loads (cross-module name collision on res_groups_name_uniq). 2. res_company_views.xml: dropped ref() inside <field domain=> attribute (Odoo 19 view validator interprets it as a field name). 3. sale_order_views.xml: replaced 3 separate xpaths for amount_total / amount_untaxed / amount_tax with a single xpath on tax_totals widget (Odoo 19 sale.view_order_form uses one widget instead of separate fields). 4. fp_cert_security.xml: certificate_type field, not cert_type. FAIR is a separate model so the rule only restricts cert_type='nadcap_cert' now. 5. fp_certificate_views.xml + fp_capa_views.xml + fp_customer_spec_views.xml: stripped user_has_groups() from invisible= / readonly= attrs (Odoo 19 view validator interprets as field name). Model-layer ACLs and ir.rules already enforce the same restrictions. Also fixed res.groups.users -> user_ids in fp_migration.py (Odoo 19 rename, caught when manually invoking _fp_notify_owners post-deploy). CLAUDE.md updated with 4 new rules (13e cross-module name collisions, 13f ref() in domain, 13g tax_totals widget, 13h user_has_groups in attrs). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Phase A bootstrap: rename old configurator's Shop Manager before new
|
||||
core group_fp_shop_manager_v2 tries to claim the 'Shop Manager' display name.
|
||||
|
||||
Load order:
|
||||
1. fusion_plating loads -> fp_security.xml renames its own old groups (Operator,
|
||||
Supervisor, Manager, Administrator) to '[DEPRECATED] X'. Then fp_security_v2.xml
|
||||
creates new groups (Technician, ..., Shop Manager v2 with display name 'Shop Manager').
|
||||
2. fusion_plating_configurator loads later -> would rename its own
|
||||
group_fp_shop_manager to '[DEPRECATED] Shop Manager'.
|
||||
|
||||
But step 1 crashes because the OLD configurator's group is still named just
|
||||
'Shop Manager' in the DB (the rename in step 2 hasn't run yet), and the unique
|
||||
constraint res_groups_name_uniq blocks the new 'Shop Manager'.
|
||||
|
||||
This pre-migrate script runs BEFORE any of fusion_plating's data files reload,
|
||||
patching the old configurator row's display name via SQL. After that, the
|
||||
constraint is clear and fp_security_v2.xml can create its new groups safely.
|
||||
The configurator's later -u will then push the canonical '[DEPRECATED] Shop
|
||||
Manager' display name from its XML data.
|
||||
"""
|
||||
import logging
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def migrate(cr, version):
|
||||
# Find old configurator Shop Manager row via ir.model.data and rename
|
||||
# its display name to avoid the constraint collision.
|
||||
cr.execute("""
|
||||
UPDATE res_groups
|
||||
SET name = jsonb_build_object('en_US', '[DEPRECATED] Shop Manager (Mgr+Estimator bundle)')
|
||||
WHERE id IN (
|
||||
SELECT res_id FROM ir_model_data
|
||||
WHERE module = 'fusion_plating_configurator'
|
||||
AND name = 'group_fp_shop_manager'
|
||||
AND model = 'res.groups'
|
||||
)
|
||||
AND (name IS NULL OR name->>'en_US' NOT LIKE '[DEPRECATED]%');
|
||||
""")
|
||||
rows = cr.rowcount
|
||||
if rows:
|
||||
_logger.info(
|
||||
'Fusion Plating: pre-migrate renamed %d old configurator Shop Manager '
|
||||
'row(s) to clear name collision with new group_fp_shop_manager_v2',
|
||||
rows,
|
||||
)
|
||||
Reference in New Issue
Block a user