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.
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.
* 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.
* Supports both numeric and alphanumeric account codes.
3. **Global Compatibility**:
* Works with **General Ledger** and **Trial Balance** via a specialized handler.
* 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
* **Models Extended**:
* `account.general.ledger.report.handler`: Overrides `_query_values` to inject missing empty accounts.
* `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.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. Uses Python-side filtering to support alphanumeric codes.
## Dependencies

View File

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

View File

@ -57,7 +57,7 @@ class GeneralLedgerCustomHandler(models.AbstractModel):
domain = [
*self.env['account.account']._check_company_domain(report.get_report_company_ids(options)),
('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'):
@ -99,6 +99,8 @@ class GeneralLedgerCustomHandler(models.AbstractModel):
}
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
# (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 ''
# 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
for col in line.get('columns', []):
val = col.get('no_format')
@ -45,32 +45,34 @@ class AccountReport(models.Model):
# If we keep it, track the 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':
seen_account_ids.add(line.get('res_id'))
elif keep_line:
# Fallback for complex IDs or different formats
line_id = line.get('id', '')
if keep_line:
res_model = line.get('res_model')
res_id = line.get('res_id')
# 1. Standard Odoo 'account.account_ID'
if line_id.startswith('account.account_'):
try:
acc_id = int(line_id.split('_')[-1])
seen_account_ids.add(acc_id)
except: pass
# 2. Complex Report Engine ID: e.g. ~account.report~12|~account.account~3743
elif '~account.account~' in line_id:
try:
# Split by | and find the part with account.account
# This is a bit manual but robust enough for this format
parts = line_id.split('|')
for p in parts:
if '~account.account~' in p:
# p might be '~account.account~3743'
acc_id_str = p.split('~account.account~')[-1]
acc_id = int(acc_id_str)
seen_account_ids.add(acc_id)
except: pass
if res_model == 'account.account' and res_id:
seen_account_ids.add(res_id)
else:
# Fallback for complex IDs or different formats
line_id = line.get('id', '')
# 1. Standard Odoo 'account.account_ID'
if line_id.startswith('account.account_'):
try:
acc_id = int(line_id.split('_')[-1])
seen_account_ids.add(acc_id)
except: pass
# 2. Complex Report Engine ID: e.g. ~account.report~12|~account.account~3743
elif '~account.account~' in line_id:
try:
# Split by | and find the part with account.account
parts = line_id.split('|')
for p in parts:
if '~account.account~' in p:
acc_id_str = p.split('~account.account~')[-1]
acc_id = int(acc_id_str)
seen_account_ids.add(acc_id)
except: pass
if keep_line:
filtered_lines.append(line)
@ -83,7 +85,7 @@ class AccountReport(models.Model):
domain = [
('company_id', 'in', self.env.companies.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)
@ -110,6 +112,9 @@ class AccountReport(models.Model):
# Add missing accounts to account_lines
for account in missing_accounts:
if account.code and account.code.endswith('0'):
continue
new_line = {
'id': f'account.account_{account.id}',
'name': f'{account.code} {account.name}',