Refactor account code filtering to support alphanumeric codes and move zero-balance summary account exclusion from SQL to Python for broader compatibility.

This commit is contained in:
Suherdy Yacob 2026-02-10 16:24:32 +07:00
parent d56be74d87
commit 593ae621b3
4 changed files with 40 additions and 32 deletions

View File

@ -15,10 +15,11 @@ By default, Odoo hides accounts that have no activity or balance. This module en
1. **Show All Accounts**: Automatically injects accounts with zero balance into reports if they are missing from the standard view. 1. **Show All Accounts**: Automatically injects accounts with zero balance into reports if they are missing from the standard view.
2. **Smart Filtering for Summary Accounts**: 2. **Smart Filtering for Summary Accounts**:
* Accounts ending in `0` (e.g., `100000`, `111000`) are treated as "View" or "Summary" accounts. * Accounts ending in `0` (e.g., `100000`, `111000`, `A10`) are treated as "View" or "Summary" accounts.
* These accounts are **excluded** if they have no balance and no activity. * These accounts are **excluded** if they have no balance and no activity.
* They are **included** only if they have a non-zero balance or activity in the selected period. * They are **included** only if they have a non-zero balance or activity in the selected period.
* This prevents report clutter while keeping necessary headers visible when active. * This prevents report clutter while keeping necessary headers visible when active.
* Supports both numeric and alphanumeric account codes.
3. **Global Compatibility**: 3. **Global Compatibility**:
* Works with **General Ledger** and **Trial Balance** via a specialized handler. * Works with **General Ledger** and **Trial Balance** via a specialized handler.
* Works with **Balance Sheet** and generic reports via a global report extension. * Works with **Balance Sheet** and generic reports via a global report extension.
@ -36,8 +37,8 @@ By default, Odoo hides accounts that have no activity or balance. This module en
## Technical Details ## Technical Details
* **Models Extended**: * **Models Extended**:
* `account.general.ledger.report.handler`: Overrides `_query_values` to inject missing empty accounts. * `account.general.ledger.report.handler`: Overrides `_query_values` to inject missing empty accounts. Uses Python-side filtering to exclude 0-balance accounts ending in '0', ensuring broad compatibility with different database configurations.
* `account.report`: Overrides `_get_lines` to post-filter summary accounts (ending in '0') that may have been included by standard logic but are actually zeroed out. * `account.report`: Overrides `_get_lines` to post-filter summary accounts (ending in '0') that may have been included by standard logic but are actually zeroed out. Uses Python-side filtering to support alphanumeric codes.
## Dependencies ## Dependencies

View File

@ -1,6 +1,6 @@
{ {
'name': 'Account Report Show All', 'name': 'Account Report Show All',
'version': '17.0.1.0.0', 'version': '17.0.1.0.1',
'category': 'Accounting/Reporting', 'category': 'Accounting/Reporting',
'summary': 'Show all accounts in General Ledger and Trial Balance', 'summary': 'Show all accounts in General Ledger and Trial Balance',
'description': """ 'description': """

View File

@ -57,7 +57,7 @@ class GeneralLedgerCustomHandler(models.AbstractModel):
domain = [ domain = [
*self.env['account.account']._check_company_domain(report.get_report_company_ids(options)), *self.env['account.account']._check_company_domain(report.get_report_company_ids(options)),
('id', 'not in', list(existing_account_ids)), ('id', 'not in', list(existing_account_ids)),
('code', 'not like', '%0') # Filter out unused accounts ending with 0. Used accounts (with balance) are already included by super(). # ('code', 'not like', '%0') # Removed incorrect domain
] ]
if options.get('filter_search_bar'): if options.get('filter_search_bar'):
@ -99,6 +99,8 @@ class GeneralLedgerCustomHandler(models.AbstractModel):
} }
for account in missing_accounts: for account in missing_accounts:
if account.code and account.code.endswith('0'):
continue
# We need a separate copy of the values for each account/column_group to avoid reference issues # We need a separate copy of the values for each account/column_group to avoid reference issues
# (though strictly speaking they are all 0 so it might not matter, but safer to copy) # (though strictly speaking they are all 0 so it might not matter, but safer to copy)

View File

@ -29,7 +29,7 @@ class AccountReport(models.Model):
code_part = parts[0] if parts else '' code_part = parts[0] if parts else ''
# Logic: Hide if code ends with '0' AND has no balance # Logic: Hide if code ends with '0' AND has no balance
if code_part.isdigit() and code_part.endswith('0'): if code_part.endswith('0'):
has_balance = False has_balance = False
for col in line.get('columns', []): for col in line.get('columns', []):
val = col.get('no_format') val = col.get('no_format')
@ -45,9 +45,13 @@ class AccountReport(models.Model):
# If we keep it, track the account ID # If we keep it, track the account ID
# Usually report lines for accounts have 'res_id' pointing to account.account id # Usually report lines for accounts have 'res_id' pointing to account.account id
if keep_line and line.get('res_model') == 'account.account': if keep_line:
seen_account_ids.add(line.get('res_id')) res_model = line.get('res_model')
elif keep_line: res_id = line.get('res_id')
if res_model == 'account.account' and res_id:
seen_account_ids.add(res_id)
else:
# Fallback for complex IDs or different formats # Fallback for complex IDs or different formats
line_id = line.get('id', '') line_id = line.get('id', '')
@ -62,11 +66,9 @@ class AccountReport(models.Model):
elif '~account.account~' in line_id: elif '~account.account~' in line_id:
try: try:
# Split by | and find the part with account.account # Split by | and find the part with account.account
# This is a bit manual but robust enough for this format
parts = line_id.split('|') parts = line_id.split('|')
for p in parts: for p in parts:
if '~account.account~' in p: if '~account.account~' in p:
# p might be '~account.account~3743'
acc_id_str = p.split('~account.account~')[-1] acc_id_str = p.split('~account.account~')[-1]
acc_id = int(acc_id_str) acc_id = int(acc_id_str)
seen_account_ids.add(acc_id) seen_account_ids.add(acc_id)
@ -83,7 +85,7 @@ class AccountReport(models.Model):
domain = [ domain = [
('company_id', 'in', self.env.companies.ids), ('company_id', 'in', self.env.companies.ids),
('id', 'not in', list(seen_account_ids)), ('id', 'not in', list(seen_account_ids)),
('code', 'not like', '%0') # ('code', 'not like', '%0') # Removed as it excludes valid accounts on some DBs
] ]
missing_accounts = self.env['account.account'].search(domain) missing_accounts = self.env['account.account'].search(domain)
@ -110,6 +112,9 @@ class AccountReport(models.Model):
# Add missing accounts to account_lines # Add missing accounts to account_lines
for account in missing_accounts: for account in missing_accounts:
if account.code and account.code.endswith('0'):
continue
new_line = { new_line = {
'id': f'account.account_{account.id}', 'id': f'account.account_{account.id}',
'name': f'{account.code} {account.name}', 'name': f'{account.code} {account.name}',