Task 16's security group rehoming (fusion_accounting → fusion_accounting_core) only existed in post-migration. That flow fails on fresh pre-Phase-0 upgrades: data-load runs before post-migration and looks up group xml-ids by (module, name); if the row still has module='fusion_accounting', Odoo creates a duplicate res.groups record under module='fusion_accounting_core'. The subsequent post-migration UPDATE...SET module='fusion_accounting_core' then trips the (module, name) unique constraint on ir_model_data, rolling back the whole transaction. Pre-migration runs BEFORE data-load, renames the five security xml-ids (module_category, privilege, three groups) to the new module, so data-load finds the existing rows and UPDATEs them in place. Existing user-group links via res_groups_users_rel are preserved. The post-migration is kept as an idempotent safety net (docstring updated to reflect the new division of labour). Verified on westin-v19 by simulating the pre-Phase-0 state (UPDATE ir_model_data SET module='fusion_accounting' ...) and re-running the upgrade: 5 rows renamed cleanly, zero duplicates, no errors. Made-with: Cursor
48 lines
1.5 KiB
Python
48 lines
1.5 KiB
Python
"""Safety-net reassignment of security xml-ids to fusion_accounting_core.
|
|
|
|
The actual rename lives in pre-migration.py — it MUST run before data-load
|
|
to avoid creating duplicate res.groups records and hitting the (module,
|
|
name) unique constraint on ir_model_data. This post-migration is a
|
|
belt-and-suspenders no-op for the common case: if pre-migration already
|
|
ran, this UPDATE matches zero rows.
|
|
|
|
It also catches a rare edge case: fusion_accounting_ai.post-migration.py
|
|
runs an identical UPDATE to cover cross-module upgrade ordering, so both
|
|
modules redundantly ensure the rows land in the right module regardless
|
|
of which upgrade runs first.
|
|
|
|
Idempotent: running it a second time matches zero rows.
|
|
"""
|
|
|
|
import logging
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
SECURITY_NAMES = (
|
|
'module_category_fusion_accounting',
|
|
'res_groups_privilege_fusion_accounting',
|
|
'group_fusion_accounting_user',
|
|
'group_fusion_accounting_manager',
|
|
'group_fusion_accounting_admin',
|
|
)
|
|
|
|
|
|
def migrate(cr, version):
|
|
cr.execute(
|
|
"""
|
|
UPDATE ir_model_data
|
|
SET module = 'fusion_accounting_core'
|
|
WHERE module = 'fusion_accounting'
|
|
AND name = ANY(%s)
|
|
""",
|
|
(list(SECURITY_NAMES),),
|
|
)
|
|
moved = cr.rowcount
|
|
_logger.info(
|
|
"fusion_accounting_core post-migration: reassigned %d security rows "
|
|
"from module='fusion_accounting' to module='fusion_accounting_core' "
|
|
"(usually zero; pre-migration already handled the rename)",
|
|
moved,
|
|
)
|