oc_template/modules/account_co_reports/trial_balance.py

281 lines
10 KiB
Python
Raw Permalink Normal View History

2024-06-15 11:00:00 -05:00
# The COPYRIGHT file at the top level of this repository contains the full
# copyright notices and license terms.
from trytond.model import ModelView, fields
from trytond.wizard import Wizard, StateView, Button, StateReport
from trytond.report import Report
from trytond.pool import Pool, PoolMeta
from trytond.transaction import Transaction
from trytond.pyson import Eval
from decimal import Decimal
import operator
from itertools import groupby
class PrintTrialBalanceStart(ModelView):
'Print Trial Balance'
__name__ = 'account.print_trial_balance.start'
fiscalyear = fields.Many2One('account.fiscalyear', 'Fiscal Year',
required=True)
start_period = fields.Many2One('account.period', 'Start Period',
domain=[
('fiscalyear', '=', Eval('fiscalyear')),
('start_date', '<=', (Eval('end_period'), 'start_date'))
],
depends=['end_period', 'fiscalyear'])
end_period = fields.Many2One('account.period', 'End Period',
domain=[
('fiscalyear', '=', Eval('fiscalyear')),
('start_date', '>=', (Eval('start_period'), 'start_date'))
],
depends=['start_period', 'fiscalyear'])
company = fields.Many2One('company.company', 'Company', required=True)
posted = fields.Boolean('Posted Move', help='Show only posted move')
empty_account = fields.Boolean('Empty Account',
help='With account without move')
detailed = fields.Boolean('Detailed',
help='Include the accounts of kind view')
accounts_with_balance = fields.Boolean('Accounts with Balance',
help='Show accounts with balances in previous periods')
@staticmethod
def default_fiscalyear():
FiscalYear = Pool().get('account.fiscalyear')
return FiscalYear.find(
Transaction().context.get('company'), exception=False)
@staticmethod
def default_company():
return Transaction().context.get('company')
@staticmethod
def default_posted():
return False
@staticmethod
def default_empty_account():
return False
@fields.depends('fiscalyear')
def on_change_fiscalyear(self):
self.start_period = None
self.end_period = None
class PrintTrialBalance(Wizard):
'Print Trial Balance'
__name__ = 'account.print_trial_balance'
start = StateView('account.print_trial_balance.start',
'account_co_reports.print_trial_balance_start_view_form', [
Button('Cancel', 'end', 'tryton-cancel'),
Button('Print', 'print_', 'tryton-print', default=True),
])
print_ = StateReport('account_co_reports.trial_balance_classic')
def do_print_(self, action):
if self.start.start_period:
start_period = self.start.start_period.id
else:
start_period = None
if self.start.end_period:
end_period = self.start.end_period.id
else:
end_period = None
data = {
'company': self.start.company.id,
'fiscalyear': self.start.fiscalyear.id,
'start_period': start_period,
'end_period': end_period,
'posted': self.start.posted,
'empty_account': self.start.empty_account,
'accounts_with_balance': self.start.accounts_with_balance,
'detailed': self.start.detailed,
}
return action, data
def transition_print_(self):
return 'end'
class TrialBalanceClassic(Report):
__name__ = 'account_co_reports.trial_balance_classic'
@classmethod
def get_context(cls, records, header, data):
report_context = super(TrialBalanceClassic, cls).get_context(records, header, data)
pool = Pool()
Account = pool.get('account.account')
Period = pool.get('account.period')
Company = pool.get('company.company')
Fiscalyear = pool.get('account.fiscalyear')
company = Company(data['company'])
dom_accounts = [
('company', '=', data['company']),
('code', '!=', None),
]
if not data['detailed']:
dom_accounts.append(('closed', '=', False))
accounts = Account.search(dom_accounts)
start_periods = []
if data['start_period']:
start_period = Period(data['start_period'])
start_periods = Period.search([
('fiscalyear', '=', data['fiscalyear']),
('end_date', '<=', start_period.start_date),
])
else:
fiscalyear = Fiscalyear(data['fiscalyear'])
start_periods = Period.search([
('fiscalyear', '=', data['fiscalyear']),
('end_date', '<=', fiscalyear.start_date),
])
if data['end_period']:
end_period = Period(data['end_period'])
end_periods = Period.search([
('fiscalyear', '=', data['fiscalyear']),
('end_date', '<=', end_period.start_date),
])
end_periods = list(set(end_periods).difference(
set(start_periods)))
if end_period not in end_periods:
end_periods.append(end_period)
else:
end_periods = Period.search([
('fiscalyear', '=', data['fiscalyear']),
])
end_periods = list(set(end_periods).difference(
set(start_periods)))
start_period_ids = [p.id for p in start_periods] or [0]
end_period_ids = [p.id for p in end_periods]
with Transaction().set_context(
fiscalyear=data['fiscalyear'],
periods=start_period_ids,
posted=data['posted']):
start_accounts = Account.browse(accounts)
with Transaction().set_context(
fiscalyear=None,
periods=end_period_ids,
posted=data['posted']):
in_accounts = Account.browse(accounts)
with Transaction().set_context(
fiscalyear=data['fiscalyear'],
periods=start_period_ids + end_period_ids,
posted=data['posted']):
end_accounts = Account.browse(accounts)
to_remove = []
if not data['empty_account']:
for account in in_accounts:
if account.debit == Decimal('0.0') \
and account.credit == Decimal('0.0'):
to_remove.append(account.id)
if not data['detailed']:
accounts = cls._accounts(data, to_remove,
start_accounts, in_accounts, end_accounts)
else:
accounts = cls._accounts_view(data, to_remove,
start_accounts, in_accounts, end_accounts)
periods = end_periods
report_context['accounts'] = accounts
periods.sort(key=operator.attrgetter('start_date'))
report_context['start_period'] = periods[0]
periods.sort(key=operator.attrgetter('end_date'))
report_context['end_period'] = periods[-1]
report_context['company'] = company
report_context['digits'] = company.currency.digits
report_context['sumto'] = lambda accounts, field: cls.sumto(accounts, field)
return report_context
@classmethod
def _accounts_view(cls, data, to_remove,
start_accounts, in_accounts, end_accounts):
dict_accounts = dict()
for start_account, in_account, end_account in zip(
start_accounts, in_accounts, end_accounts):
empty_account = all([
start_account.balance == 0,
in_account.debit == 0,
in_account.credit == 0,
end_account.balance == 0
])
if start_account.closed == False and empty_account:
continue
if start_account.closed == True:
start_balance = []
end_balance = []
debit = []
credit = []
else:
start_balance = [start_account.balance]
debit = [in_account.debit]
credit = [in_account.credit]
end_balance = [end_account.balance]
def sum_amount_to_parent(acc):
try:
dict_accounts[acc.parent]['debit'].extend(debit)
dict_accounts[acc.parent]['credit'].extend(credit)
dict_accounts[acc.parent]['start_balance'].extend(start_balance)
dict_accounts[acc.parent]['end_balance'].extend(end_balance)
if acc.parent.parent and acc.parent.code:
sum_amount_to_parent(acc.parent)
except:
pass
if start_account.closed == False and start_account.parent \
and not empty_account:
sum_amount_to_parent(start_account)
dict_accounts[start_account] = {
'code': start_account.code,
'name': start_account.name,
'start_balance': start_balance,
'debit': debit,
'credit': credit,
'end_balance': end_balance,
}
return dict_accounts.values()
@classmethod
def _accounts(cls, data, to_remove,
start_accounts, in_accounts, end_accounts):
accounts = []
for start_account, in_account, end_account in zip(
start_accounts, in_accounts, end_accounts):
if in_account.id in to_remove:
if not data['accounts_with_balance'] or \
start_account.balance == Decimal('0.0'):
continue
accounts.append({
'code': start_account.code,
'name': start_account.name,
'start_balance': [start_account.balance],
'debit': [in_account.debit],
'credit': [in_account.credit],
'end_balance': [end_account.balance],
})
return accounts
@classmethod
def sumto(cls, accounts, field):
amount = Decimal('0.0')
for account in accounts:
amount += sum(account[field])
return amount