Skip to content

feat: Belgian Charts of Accounts (commercial + non-profit, FR + NL)#54679

Open
maasanto wants to merge 5 commits intofrappe:developfrom
maasanto:feat/be-pcmn-from-official-source
Open

feat: Belgian Charts of Accounts (commercial + non-profit, FR + NL)#54679
maasanto wants to merge 5 commits intofrappe:developfrom
maasanto:feat/be-pcmn-from-official-source

Conversation

@maasanto
Copy link
Copy Markdown
Contributor

Summary

Replaces the Belgian chart placeholder unverified/be_l10nbe_chart_template.json (FR-only labels, no account numbers, no account_type) with four validated charts in verified/, derived from the official Plan Comptable Minimum Normalisé (PCMN) published by the Commission des Normes Comptables (CNC-CBN). The two PCMN variants distinguished by the legislator are both shipped, each in French and Dutch:

Commercial entities (Annex 1 of AR 21/10/2018):

  • be_plan_comptable_minimum_normalise_entreprises.json — French
  • be_minimum_genormaliseerd_rekeningstelsel_ondernemingen.json — Dutch

Associations and foundations (Annex 3, distinct equity & income classes — fonds affectés instead of capital, cotisations/dons/legs/subsides instead of generic revenue):

  • be_plan_comptable_minimum_normalise_associations_fondations.json
  • be_minimum_genormaliseerd_rekeningstelsel_verenigingen_stichtingen.json

Each chart carries account_number, account_type (Tax for 411/451; Bank/Cash/Receivable/Payable/Equity/Stock/Fixed Asset/Income/Expense/Depreciation per class), and root_type declared at the top-level group.

Legal source: AR du 21 octobre 2018 enacting articles III.82 to III.95 of the Code de droit économique, consolidated with AR du 29 avril 2019. Public-domain status per article XI.172 §2 of the Code de droit économique, which excludes official acts from copyright.

Approach

Class 1 and 4 split: Frappe expects a single root_type per top-level group, but PCMN classes 1 (equity + provisions/long-term debt) and 4 (receivables + payables) mix asset and liability roots. They are split into two top-level groups, mirroring dz_plan_comptable_general_avec_code.json. The non-profit variant labels Class 1 equity as "FONDS ASSOCIATIFS ET DE LA FONDATION" / "VERENIGINGSFONDS EN STICHTINGSFONDS" (no capital concept).

Bank group placeholder: account 55 "Établissements de crédit" / "Kredietinstellingen" is exposed as a Bank group with a single child 5500 "Banque" / "Bank". The official PCMN leaves 55 unsubdivided — entities create their own sub-codes — but Frappe needs at least one is_group=1, account_type=Bank node so the setup wizard can attach the company bank account. Users rename / extend (5501, 5502, …) as needed.

@maasanto maasanto requested a review from ruthra-kumar as a code owner April 30, 2026 12:14
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 30, 2026

📝 Walkthrough

Walkthrough

This change replaces a single unverified Belgian chart-of-accounts template with four new verified templates. The unverified file be_l10nbe_chart_template.json (1539 lines) is removed from the unverified directory. Four new verified chart-of-accounts JSON files are added, providing hierarchical account structures for Belgium: two variants for enterprises and two for associations/foundations. Each template defines accounting classes 1–7 with corresponding root types (Equity, Liability, Asset, Expense, Income) and detailed account hierarchies including account numbers and types.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the primary change: introducing verified Belgian charts of accounts in both commercial and non-profit variants with French and Dutch labels.
Description check ✅ Passed The description comprehensively details the changeset, explaining the replacement of the unverified placeholder with four validated PCMN charts, implementation approaches, and legal justification.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@erpnext/accounts/doctype/account/chart_of_accounts/verified/be_minimum_genormaliseerd_rekeningstelsel_ondernemingen.json`:
- Around line 1446-1448: The account name for account_number "752" currently
contains a placeholder ("Meerwaarden op de [...] realisatie van vlottende
activa"); replace the literal "[...]" with the finalized Dutch wording so the
imported account label is correct—locate the JSON object keyed by that exact
string (or the entry with "account_number": "752") and update the account name
to the final phrasing before merging.
- Around line 1255-1262: Restore a child entry for account 6630 under the
"Minderwaarden op de realisatie van vaste activa" mapping: change the current
mapping so "Minderwaarde op de realisatie van immateriële en materiële vaste
activa" has "account_number": "6630" (Expense Account) and add/ensure the other
child (financial fixed assets) keeps "account_number": "6631" (Expense Account);
keep the parent entry "account_number": "663" as-is and ensure both child keys
exist under that parent so 6630 is present alongside 6631.

In
`@erpnext/accounts/doctype/account/chart_of_accounts/verified/be_minimum_genormaliseerd_rekeningstelsel_verenigingen_stichtingen.json`:
- Around line 537-568: The Class 5 section ("KLASSE 5 : GELDBELEGGINGEN EN
LIQUIDE MIDDELEN") must match other BE charts: reintroduce the missing 529 entry
under this section (e.g., a "Geselecteerde waarderingen" or the appropriate
label with "account_number": "529") and replace the standalone "Bank" leaf with
a "55" Bank group object that contains the "5500" child (retain
"account_number": "5500" and "account_type": "Bank" under that group); update
keys accordingly so the structure mirrors the other BE charts and preserves
grouping semantics instead of leaving 5500 as a top-level leaf.

In
`@erpnext/accounts/doctype/account/chart_of_accounts/verified/be_plan_comptable_minimum_normalise_associations_fondations.json`:
- Around line 955-965: The JSON group key contains a pasted prefix artifact
"6690                            Charges d’exploitation portées à l’actif au
titre de frais de restructuration (-)"; rename that key to the clean label
"Charges d’exploitation portées à l’actif au titre de frais de restructuration
(-)" (remove the leading "6690" and padding) and move its value object unchanged
under the cleaned key, keeping the nested entries ("Charges d’exploitation
portées à l’actif au titre de frais de restructuration (-)", "Charges
financières non récurrentes portées à l'actif au titre de frais de
restructuration (-)", "account_number": "669", "account_type": "Expense
Account") intact; ensure you don’t create a duplicate key elsewhere in the file
and remove the original padded-key entry.
- Around line 537-571: The "Banque" account with account_number "5500" is
defined as a standalone leaf under "CLASSE 5 : PLACEMENTS DE TRÉSORERIE ET
VALEURS DISPONIBLES" but the setup wizard expects bank accounts to be nested
under a Bank group "55"; update the JSON so that instead of a direct "5500" leaf
you add a parent entry for "55" (root/Bank group) containing "5500" as a child
(e.g., move the "Banque" node under a new "55" group) and ensure the new parent
has account_type "Bank" and the child retains account_number "5500" and its
label "Banque".
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: b21baeda-165f-46a0-be40-9c62965268b9

📥 Commits

Reviewing files that changed from the base of the PR and between f38eca9 and 7a00a5e.

📒 Files selected for processing (5)
  • erpnext/accounts/doctype/account/chart_of_accounts/unverified/be_l10nbe_chart_template.json
  • erpnext/accounts/doctype/account/chart_of_accounts/verified/be_minimum_genormaliseerd_rekeningstelsel_ondernemingen.json
  • erpnext/accounts/doctype/account/chart_of_accounts/verified/be_minimum_genormaliseerd_rekeningstelsel_verenigingen_stichtingen.json
  • erpnext/accounts/doctype/account/chart_of_accounts/verified/be_plan_comptable_minimum_normalise_associations_fondations.json
  • erpnext/accounts/doctype/account/chart_of_accounts/verified/be_plan_comptable_minimum_normalise_entreprises.json
💤 Files with no reviewable changes (1)
  • erpnext/accounts/doctype/account/chart_of_accounts/unverified/be_l10nbe_chart_template.json

Comment on lines +1255 to +1262
"Minderwaarden op de realisatie van vaste activa": {
"Minderwaarde op de realisatie van immateriële en materiële vaste activa": {
"account_number": "6631",
"account_type": "Expense Account"
},
"account_number": "663",
"account_type": "Expense Account"
},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Restore account 6630 in this branch.

This mapping assigns 6631 to the immateriële/materiële child and leaves no 6630 account at all. The other Belgium variants in this PR keep 6630 for immateriële/materiële vaste activa and 6631 for financiële vaste activa.

Suggested fix
             "Minderwaarden op de realisatie van vaste activa": {
                 "Minderwaarde op de realisatie van immateriële en materiële vaste activa": {
-                    "account_number": "6631",
+                    "account_number": "6630",
+                    "account_type": "Expense Account"
+                },
+                "Minderwaarde op de realisatie van financiële vaste activa": {
+                    "account_number": "6631",
                     "account_type": "Expense Account"
                 },
                 "account_number": "663",
                 "account_type": "Expense Account"
             },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@erpnext/accounts/doctype/account/chart_of_accounts/verified/be_minimum_genormaliseerd_rekeningstelsel_ondernemingen.json`
around lines 1255 - 1262, Restore a child entry for account 6630 under the
"Minderwaarden op de realisatie van vaste activa" mapping: change the current
mapping so "Minderwaarde op de realisatie van immateriële en materiële vaste
activa" has "account_number": "6630" (Expense Account) and add/ensure the other
child (financial fixed assets) keeps "account_number": "6631" (Expense Account);
keep the parent entry "account_number": "663" as-is and ensure both child keys
exist under that parent so 6630 is present alongside 6631.

Comment on lines +1446 to +1448
"Meerwaarden op de [...] realisatie van vlottende activa": {
"account_number": "752",
"account_type": "Income Account"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Replace the [...] placeholder before merge.

The literal placeholder will be imported as part of the account name. This should be the finalized Dutch label for account 752.

Suggested fix
-                "Meerwaarden op de [...] realisatie van vlottende activa": {
+                "Meerwaarden op de realisatie van vlottende activa": {
                     "account_number": "752",
                     "account_type": "Income Account"
                 },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"Meerwaarden op de [...] realisatie van vlottende activa": {
"account_number": "752",
"account_type": "Income Account"
"Meerwaarden op de realisatie van vlottende activa": {
"account_number": "752",
"account_type": "Income Account"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@erpnext/accounts/doctype/account/chart_of_accounts/verified/be_minimum_genormaliseerd_rekeningstelsel_ondernemingen.json`
around lines 1446 - 1448, The account name for account_number "752" currently
contains a placeholder ("Meerwaarden op de [...] realisatie van vlottende
activa"); replace the literal "[...]" with the finalized Dutch wording so the
imported account label is correct—locate the JSON object keyed by that exact
string (or the entry with "account_number": "752") and update the account name
to the final phrasing before merging.

Comment on lines +537 to +568
"KLASSE 5 : GELDBELEGGINGEN EN LIQUIDE MIDDELEN": {
"root_type": "Asset",
"Aanschaffingswaarde": {
"account_number": "520"
},
"Geboekte waardeverminderingen (-)": {
"account_number": "539"
},
"Nog te storten bedragen (-)": {
"account_number": "511"
},
"Op meer dan één jaar": {
"account_number": "530"
},
"Op meer dan een maand en op ten hoogste één jaar": {
"account_number": "531"
},
"Op ten hoogste één maand": {
"account_number": "532"
},
"tot 577 Kassen-contanten": {
"account_number": "570",
"account_type": "Cash"
},
"Kassen-zegels": {
"account_number": "578",
"account_type": "Cash"
},
"Bank": {
"account_number": "5500",
"account_type": "Bank"
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Mirror the Class 5 structure used by the other BE charts.

This variant drops two real pieces of the treasury section: 529 is missing entirely, and 5500 is a standalone Bank leaf instead of a 55 Bank group. That changes the imported chart shape relative to the French association file and the enterprise charts.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@erpnext/accounts/doctype/account/chart_of_accounts/verified/be_minimum_genormaliseerd_rekeningstelsel_verenigingen_stichtingen.json`
around lines 537 - 568, The Class 5 section ("KLASSE 5 : GELDBELEGGINGEN EN
LIQUIDE MIDDELEN") must match other BE charts: reintroduce the missing 529 entry
under this section (e.g., a "Geselecteerde waarderingen" or the appropriate
label with "account_number": "529") and replace the standalone "Bank" leaf with
a "55" Bank group object that contains the "5500" child (retain
"account_number": "5500" and "account_type": "Bank" under that group); update
keys accordingly so the structure mirrors the other BE charts and preserves
grouping semantics instead of leaving 5500 as a top-level leaf.

Comment on lines +537 to +571
"CLASSE 5 : PLACEMENTS DE TRÉSORERIE ET VALEURS DISPONIBLES": {
"root_type": "Asset",
"Valeur d'acquisition": {
"account_number": "520"
},
"Réductions de valeurs actées (-)": {
"account_number": "529"
},
"Montants non appelés (-)": {
"account_number": "511"
},
"Réductions de valeur actées (-)": {
"account_number": "539"
},
"De plus d'un an": {
"account_number": "530"
},
"De plus d'un mois et à un an au plus": {
"account_number": "531"
},
"D'un mois au plus": {
"account_number": "532"
},
"à 577 Caisses-espèces": {
"account_number": "570",
"account_type": "Cash"
},
"Caisses-timbres": {
"account_number": "578",
"account_type": "Cash"
},
"Banque": {
"account_number": "5500",
"account_type": "Bank"
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Wrap 5500 in a 55 Bank parent here.

The PR objective calls out 55 as the Bank group the setup wizard attaches company bank accounts under. In this variant 5500 is a standalone leaf, so there is no parent Bank group for that flow.

Suggested structure
-            "Banque": {
-                "account_number": "5500",
-                "account_type": "Bank"
-            }
+            "Établissements de crédit": {
+                "Banque": {
+                    "account_number": "5500",
+                    "account_type": "Bank"
+                },
+                "account_number": "55",
+                "account_type": "Bank"
+            }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"CLASSE 5 : PLACEMENTS DE TRÉSORERIE ET VALEURS DISPONIBLES": {
"root_type": "Asset",
"Valeur d'acquisition": {
"account_number": "520"
},
"Réductions de valeurs actées (-)": {
"account_number": "529"
},
"Montants non appelés (-)": {
"account_number": "511"
},
"Réductions de valeur actées (-)": {
"account_number": "539"
},
"De plus d'un an": {
"account_number": "530"
},
"De plus d'un mois et à un an au plus": {
"account_number": "531"
},
"D'un mois au plus": {
"account_number": "532"
},
"à 577 Caisses-espèces": {
"account_number": "570",
"account_type": "Cash"
},
"Caisses-timbres": {
"account_number": "578",
"account_type": "Cash"
},
"Banque": {
"account_number": "5500",
"account_type": "Bank"
}
"CLASSE 5 : PLACEMENTS DE TRÉSORERIE ET VALEURS DISPONIBLES": {
"root_type": "Asset",
"Valeur d'acquisition": {
"account_number": "520"
},
"Réductions de valeurs actées (-)": {
"account_number": "529"
},
"Montants non appelés (-)": {
"account_number": "511"
},
"Réductions de valeur actées (-)": {
"account_number": "539"
},
"De plus d'un an": {
"account_number": "530"
},
"De plus d'un mois et à un an au plus": {
"account_number": "531"
},
"D'un mois au plus": {
"account_number": "532"
},
"à 577 Caisses-espèces": {
"account_number": "570",
"account_type": "Cash"
},
"Caisses-timbres": {
"account_number": "578",
"account_type": "Cash"
},
"Établissements de crédit": {
"Banque": {
"account_number": "5500",
"account_type": "Bank"
},
"account_number": "55",
"account_type": "Bank"
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@erpnext/accounts/doctype/account/chart_of_accounts/verified/be_plan_comptable_minimum_normalise_associations_fondations.json`
around lines 537 - 571, The "Banque" account with account_number "5500" is
defined as a standalone leaf under "CLASSE 5 : PLACEMENTS DE TRÉSORERIE ET
VALEURS DISPONIBLES" but the setup wizard expects bank accounts to be nested
under a Bank group "55"; update the JSON so that instead of a direct "5500" leaf
you add a parent entry for "55" (root/Bank group) containing "5500" as a child
(e.g., move the "Banque" node under a new "55" group) and ensure the new parent
has account_type "Bank" and the child retains account_number "5500" and its
label "Banque".

Comment on lines +955 to +965
"6690                            Charges d’exploitation portées à l’actif au titre de frais de restructuration (-)": {
"Charges d’exploitation portées à l’actif au titre de frais de restructuration (-)": {
"account_number": "6690",
"account_type": "Expense Account"
},
"Charges financières non récurrentes portées à l'actif au titre de frais de restructuration (-)": {
"account_number": "6691",
"account_type": "Expense Account"
},
"account_number": "669",
"account_type": "Expense Account"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Remove the 6690/padding artifact from this group label.

This key looks copied from a formatted source line rather than a finalized account name. If imported as-is, users will see the literal 6690 prefix and spacing in the account tree.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@erpnext/accounts/doctype/account/chart_of_accounts/verified/be_plan_comptable_minimum_normalise_associations_fondations.json`
around lines 955 - 965, The JSON group key contains a pasted prefix artifact
"6690                            Charges d’exploitation portées à l’actif au
titre de frais de restructuration (-)"; rename that key to the clean label
"Charges d’exploitation portées à l’actif au titre de frais de restructuration
(-)" (remove the leading "6690" and padding) and move its value object unchanged
under the cleaned key, keeping the nested entries ("Charges d’exploitation
portées à l’actif au titre de frais de restructuration (-)", "Charges
financières non récurrentes portées à l'actif au titre de frais de
restructuration (-)", "account_number": "669", "account_type": "Expense
Account") intact; ensure you don’t create a duplicate key elsewhere in the file
and remove the original padded-key entry.

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 30, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 79.75%. Comparing base (da08125) to head (7a00a5e).
⚠️ Report is 4 commits behind head on develop.

Additional details and impacted files
@@             Coverage Diff             @@
##           develop   #54679      +/-   ##
===========================================
- Coverage    79.76%   79.75%   -0.01%     
===========================================
  Files         1160     1160              
  Lines       126444   126446       +2     
===========================================
  Hits        100853   100853              
- Misses       25591    25593       +2     
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant