feat(nexa_coa_setup): pre_init_hook to clear l10n_ca code collisions
Bakes the staging-side one-off collision clearing into the module install itself so production install will execute the same sweep automatically. For each of the 29 l10n_ca codes that conflict with Nexa's planned chart: - If the account has zero postings: suffix code with '.OLD', mark inactive, rename to '(l10n_ca LEGACY) <original>' - If the account has postings (currently 115100 AR control with 240 lines and 511100 Inside Purchases with 1 line): leave alone (Nexa renumbered to 119100 / 511105 in the XML) Idempotent — pre_init_hook re-running has no effect (already-suffixed codes are skipped). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,2 +1,2 @@
|
|||||||
from . import models
|
from . import models
|
||||||
from .hooks import post_init_hook
|
from .hooks import pre_init_hook, post_init_hook
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
"data/09_res_partner.xml",
|
"data/09_res_partner.xml",
|
||||||
"data/10_account_reconcile_model.xml",
|
"data/10_account_reconcile_model.xml",
|
||||||
],
|
],
|
||||||
|
"pre_init_hook": "pre_init_hook",
|
||||||
"post_init_hook": "post_init_hook",
|
"post_init_hook": "post_init_hook",
|
||||||
"installable": True,
|
"installable": True,
|
||||||
"application": False,
|
"application": False,
|
||||||
|
|||||||
@@ -4,6 +4,72 @@ import logging
|
|||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
# l10n_ca account codes that collide with the Nexa CoA design and that
|
||||||
|
# l10n_ca pre-loads with 'income_other'/'expense'/etc. types we don't want.
|
||||||
|
# Each of these is checked at pre_init: if it has zero postings we suffix
|
||||||
|
# its code with '.OLD' and archive it so our XML can claim the code.
|
||||||
|
# Codes with postings are LEFT ALONE — we renumbered the Nexa code instead
|
||||||
|
# (115100 stays as l10n_ca 'Customers Account' AR; Nexa shareholder receivable
|
||||||
|
# moved to 119100. 511100 stays as l10n_ca 'Inside Purchases'; Nexa Cloud
|
||||||
|
# Infrastructure moved to 511105).
|
||||||
|
_L10N_CA_COLLISION_CODES = [
|
||||||
|
"118100", "118200", "118300",
|
||||||
|
"213100", "214100",
|
||||||
|
"221200",
|
||||||
|
"311100", "311200", "311300",
|
||||||
|
"411100", "411200", "411300",
|
||||||
|
"413100", "413200", "413300",
|
||||||
|
"511110", "511120", "511130", "511140", "511200", "511210",
|
||||||
|
"512100", "512110", "512200",
|
||||||
|
"611100", "611200", "611300",
|
||||||
|
"612100", "612200",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def pre_init_hook(env):
|
||||||
|
"""Run BEFORE XML data is loaded. Clear l10n_ca account codes that would
|
||||||
|
collide with Nexa's chart of accounts."""
|
||||||
|
_logger.info("nexa_coa_setup: pre_init_hook starting")
|
||||||
|
_clear_l10n_ca_collisions(env)
|
||||||
|
_logger.info("nexa_coa_setup: pre_init_hook complete")
|
||||||
|
|
||||||
|
|
||||||
|
def _clear_l10n_ca_collisions(env):
|
||||||
|
"""For each colliding code: if it has zero postings, rename to NNNNNN.OLD
|
||||||
|
and set inactive. If it has postings, leave alone (Nexa code was renumbered
|
||||||
|
in the XML to avoid the conflict)."""
|
||||||
|
cleared = 0
|
||||||
|
kept_with_postings = 0
|
||||||
|
not_found = 0
|
||||||
|
for code in _L10N_CA_COLLISION_CODES:
|
||||||
|
acc = env["account.account"].search([("code", "=", code)], limit=1)
|
||||||
|
if not acc:
|
||||||
|
not_found += 1
|
||||||
|
continue
|
||||||
|
usage = env["account.move.line"].search_count([("account_id", "=", acc.id)])
|
||||||
|
if usage > 0:
|
||||||
|
_logger.info(
|
||||||
|
"nexa_coa_setup: keeping l10n_ca account %s (%s) — %d postings exist",
|
||||||
|
code, acc.name, usage,
|
||||||
|
)
|
||||||
|
kept_with_postings += 1
|
||||||
|
continue
|
||||||
|
new_code = f"{code}.OLD"
|
||||||
|
# Skip if already suffixed (idempotency)
|
||||||
|
if acc.code.endswith(".OLD"):
|
||||||
|
continue
|
||||||
|
acc.write({
|
||||||
|
"code": new_code,
|
||||||
|
"name": f"(l10n_ca LEGACY) {acc.name or acc.display_name}",
|
||||||
|
"active": False,
|
||||||
|
})
|
||||||
|
cleared += 1
|
||||||
|
_logger.info(
|
||||||
|
"nexa_coa_setup: collision sweep — cleared %d, kept-with-postings %d, not-found %d",
|
||||||
|
cleared, kept_with_postings, not_found,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def post_init_hook(env):
|
def post_init_hook(env):
|
||||||
"""Imperative one-shot operations after module data is loaded.
|
"""Imperative one-shot operations after module data is loaded.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user