fix(nexa_coa_setup): clean GL codes — 119100/119900->115200/115900, 511105->511100

Three odd code positions that were chosen to dodge l10n_ca collisions are
now cleaned up:
- Due From Shareholder       119100 -> 115200 (115xxx is where receivables belong)
- Due From Associated Corps  119900 -> 115900
- Cloud Infrastructure       511105 -> 511100 (legacy 'Inside Purchases'
                                       renamed to 511100.OLD)

Applied to prod via scripts/fix_gl_codes.py (now committed).

Module XML updated: <field name='code'> values match new codes; XMLIDs
(acct_119100, acct_119900, acct_511105) preserved so existing
ir.model.data rows on prod still map to the right records.

pre_init_hook augmented with _L10N_CA_FORCE_CLEAR_CODES set so a fresh
install on a new DB also force-clears 511100 (which would otherwise be
blocked by the postings-exist guard).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsinghpal
2026-05-12 20:02:54 -04:00
parent 092423d7de
commit 749c0335fa
3 changed files with 72 additions and 16 deletions

View File

@@ -4,14 +4,12 @@ import logging
_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 account codes that collide with the Nexa CoA design. Each 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 account.
# Currently 115100 stays as l10n_ca 'Customers Account' (240 postings, AR
# control) — Nexa shareholder receivable sits at 115200 instead.
_L10N_CA_COLLISION_CODES = [
"118100", "118200", "118300",
"213100", "214100",
@@ -19,12 +17,18 @@ _L10N_CA_COLLISION_CODES = [
"311100", "311200", "311300",
"411100", "411200", "411300",
"413100", "413200", "413300",
"511110", "511120", "511130", "511140", "511200", "511210",
"511100", "511110", "511120", "511130", "511140", "511200", "511210",
"512100", "512110", "512200",
"611100", "611200", "611300",
"612100", "612200",
]
# Codes that MUST be cleared even if they have postings (force-suffix to .OLD).
# Use sparingly — historical reports lose the original name. Only for codes
# where the Nexa account at that code is the canonical one going forward and
# any prior posting is a misclassification the user will re-class later.
_L10N_CA_FORCE_CLEAR_CODES = {"511100"}
def pre_init_hook(env):
"""Run BEFORE XML data is loaded. Clear l10n_ca account codes that would
@@ -47,7 +51,8 @@ def _clear_l10n_ca_collisions(env):
not_found += 1
continue
usage = env["account.move.line"].search_count([("account_id", "=", acc.id)])
if usage > 0:
force = code in _L10N_CA_FORCE_CLEAR_CODES
if usage > 0 and not force:
_logger.info(
"nexa_coa_setup: keeping l10n_ca account %s (%s) — %d postings exist",
code, acc.name, usage,
@@ -64,6 +69,11 @@ def _clear_l10n_ca_collisions(env):
"active": False,
})
cleared += 1
if force and usage > 0:
_logger.info(
"nexa_coa_setup: force-cleared %s despite %d postings (in FORCE_CLEAR set)",
code, usage,
)
_logger.info(
"nexa_coa_setup: collision sweep — cleared %d, kept-with-postings %d, not-found %d",
cleared, kept_with_postings, not_found,