account_report_show_all/models/account_general_ledger.py

119 lines
5.1 KiB
Python

# -*- coding: utf-8 -*-
from odoo import models, api
class GeneralLedgerCustomHandler(models.AbstractModel):
_inherit = 'account.general.ledger.report.handler'
def _query_values(self, report, options):
# 1. Get existing values from super (accounts with moves/balances)
results = super()._query_values(report, options)
# 2. Filter out accounts ending in '0' that have 0.0 balance.
filtered_results = []
possible_removals = 0
for account, values in results:
if account.code and account.code.endswith('0'):
has_balance = False
# Check ALL column groups
for col_group_key, col_group_values in values.items():
# For GL, we usually care if there is ANY activity or balance in the period/range displayed.
# Check 'sum' (Period Activity/Balance for the column)
sum_vals = col_group_values.get('sum', {})
if not self.env.company.currency_id.is_zero(sum_vals.get('balance', 0.0)) or \
not self.env.company.currency_id.is_zero(sum_vals.get('debit', 0.0)) or \
not self.env.company.currency_id.is_zero(sum_vals.get('credit', 0.0)):
has_balance = True
break
# Check 'initial_balance'
init_vals = col_group_values.get('initial_balance', {})
if not self.env.company.currency_id.is_zero(init_vals.get('balance', 0.0)):
has_balance = True
break
# Check 'unaffected_earnings' (current year earnings usually)
unaff_vals = col_group_values.get('unaffected_earnings', {})
if not self.env.company.currency_id.is_zero(unaff_vals.get('balance', 0.0)):
has_balance = True
break
if not has_balance:
continue # Skip this account if no relevant numbers found
filtered_results.append((account, values))
results = filtered_results
# Extract IDs of accounts already in results
existing_account_ids = {account.id for account, _ in results}
# 2. Find missing accounts
# We need all accounts for the current company(ies)
# We respect the search filter if present (handled in super via existing_account_ids check essentially,
# but we need to re-apply filter to find *unused* accounts matching the filter)
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().
]
if options.get('filter_search_bar'):
domain.append(('name', 'ilike', options['filter_search_bar']))
# 3. Create empty result structure for missing accounts
# The structure expected is:
# values_by_column_group is a dict {column_group_key: values}
# values is a dict with keys like 'sum', 'initial_balance', 'unaffected_earnings'
# 'sum': {'debit': 0.0, 'credit': 0.0, 'balance': 0.0, 'amount_currency': 0.0}
missing_accounts = self.env['account.account'].search(domain)
if not missing_accounts:
return results
# Construct the empty value dictionary structure
# We need to replicate the structure for each column group
empty_values_template = {
'sum': {
'debit': 0.0,
'credit': 0.0,
'balance': 0.0,
'amount_currency': 0.0,
# 'max_date': None # Optional
},
'initial_balance': {
'debit': 0.0,
'credit': 0.0,
'balance': 0.0,
'amount_currency': 0.0,
},
'unaffected_earnings': {
'debit': 0.0,
'credit': 0.0,
'balance': 0.0,
'amount_currency': 0.0,
}
}
for account in missing_accounts:
# 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)
account_values = {}
for column_group_key in options['column_groups']:
# deeply copy the template
account_values[column_group_key] = {
key: val.copy() for key, val in empty_values_template.items()
}
results.append((account, account_values))
# Re-sort results by account code to ensure correct order
# The original results are sorted, we appended new ones at the end.
results.sort(key=lambda x: x[0].code)
return results