oc_template/modules/account_co_reports/trial_balance_detailed.py

332 lines
12 KiB
Python
Raw Normal View History

2024-06-15 11:00:00 -05:00
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from decimal import Decimal
from sql.conditionals import Coalesce
from sql.aggregate import Sum
from collections import OrderedDict
from trytond.model import ModelView, ModelSQL, fields
from trytond.wizard import Wizard, StateView, Button, StateReport
from trytond.transaction import Transaction
from trytond.report import Report
from trytond.pyson import Eval, PYSONEncoder
from trytond.pool import Pool, PoolMeta
class PrintTrialBalanceDetailedStart(ModelView):
'Print Trial Balance Detailed'
__name__ = 'account_co_reports.print_trial_balance_detailed.start'
fiscalyear = fields.Many2One('account.fiscalyear', 'Fiscal Year',
required=True, depends=['start_period', 'end_period'])
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'])
party = fields.Many2One('party.party', 'Party')
accounts = fields.Many2Many('account.account', None, None, 'Accounts',
domain=[
('type', '!=', ''),
])
company = fields.Many2One('company.company', 'Company', required=True)
posted = fields.Boolean('Posted Move', help='Show only posted move')
by_reference = fields.Boolean('By Reference', help='Show all moves by reference ignoring the parties')
empty_account = fields.Boolean('Empty Account',
help='With account without move')
@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_by_reference():
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 PrintTrialBalanceDetailed(Wizard):
'Print Trial Balance Detailed'
__name__ = 'account_co_reports.print_trial_balance_detailed'
start = StateView('account_co_reports.print_trial_balance_detailed.start',
'account_co_reports.print_trial_balance_detailed_start_view_form', [
Button('Cancel', 'end', 'tryton-cancel'),
Button('Print', 'print_', 'tryton-print', default=True),
])
print_ = StateReport('account_co_reports.trial_balance_detailed')
def do_print_(self, action):
start_period = None
end_period = None
party_id = None
accounts_ids = []
if self.start.start_period:
start_period = self.start.start_period.id
if self.start.end_period:
end_period = self.start.end_period.id
if self.start.party:
party_id = self.start.party.id
if self.start.accounts:
accounts_ids = [acc.id for acc in self.start.accounts]
data = {
'company': self.start.company.id,
'fiscalyear': self.start.fiscalyear.id,
'start_period': start_period,
'end_period': end_period,
'party': party_id,
'accounts': accounts_ids,
'posted': self.start.posted,
'empty_account': self.start.empty_account,
'by_reference': self.start.by_reference,
}
return action, data
def transition_print_(self):
return 'end'
class TrialBalanceDetailed(Report):
__name__ = 'account_co_reports.trial_balance_detailed'
@classmethod
def get_context(cls, records, header, data):
report_context = super(TrialBalanceDetailed, cls).get_context(records, header, data)
pool = Pool()
Account = pool.get('account.account')
Move = pool.get('account.move')
Line = pool.get('account.move.line')
Period = pool.get('account.period')
Company = pool.get('company.company')
Party = pool.get('party.party')
FiscalYear = pool.get('account.fiscalyear')
cursor = Transaction().connection.cursor()
move = Move.__table__()
line = Line.__table__()
start_period_name = None
end_period_name = None
# ----- Set Periods -----
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),
])
start_period_name = start_period.name
else:
fiscalyear = FiscalYear(data['fiscalyear'])
start_periods = Period.search([
('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)))
end_period_name = end_period.name
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)))
# Select Query for In
in_periods = [p.id for p in end_periods]
join1 = line.join(move)
join1.condition = join1.right.id == line.move
entity = line.party
default_entity = 0
if not data['party'] and data['by_reference']:
entity = line.reference
default_entity = '0'
select1 = join1.select(
line.account, Coalesce(entity, default_entity), Sum(line.debit), Sum(line.credit),
group_by=(line.account, entity),
order_by=line.account,
)
select1.where = (join1.right.period.in_(in_periods))
if data['party']:
select1.where = select1.where & (line.party == data['party'])
if data['accounts']:
select1.where = select1.where & (line.account.in_(data['accounts']))
cursor.execute(*select1)
result_in = cursor.fetchall()
# Select Query for Start
start_periods_ids = [p.id for p in start_periods]
result_start = []
if start_periods_ids:
join1 = line.join(move)
join1.condition = join1.right.id == line.move
select2 = join1.select(
line.account, Coalesce(entity, default_entity), Sum(line.debit) - Sum(line.credit),
group_by=(line.account, entity),
order_by=line.account,
)
select2.where = (join1.right.period.in_(start_periods_ids))
if data['party']:
select2.where = select2.where & (line.party == data['party'])
if data['accounts']:
select2.where = select2.where & (line.account.in_(data['accounts']))
cursor.execute(*select2)
result_start = cursor.fetchall()
all_result = result_in + result_start
accs_ids = []
parties_ids = []
for r in all_result:
accs_ids.append(r[0])
parties_ids.append(r[1])
accounts = OrderedDict()
# Prepare accounts
if accs_ids:
acc_records = Account.search_read([
('id', 'in', list(set(accs_ids))),
('active', 'in', [False, True]),
], order=[('code', 'ASC')], fields_names=['code', 'name'])
for acc in acc_records:
accounts[acc['id']] = [
acc,
{},
{
'debits': [],
'credits': [],
'start_balance': [],
'end_balance': [],
}
]
if not data['by_reference']:
parties_obj = Party.search_read([
('id', 'in', parties_ids),
('active', 'in', [False, True]),
], fields_names=['name'])
parties = {p['id'] : p for p in parties_obj}
else:
parties = {p : p for p in parties_ids}
def _get_process_result(kind, values):
for val in values:
party_id = 0
id_number = '---'
party_name = '---'
if not data['by_reference']:
if val[1]:
party_id = val[1]
if Party(party_id).identifiers:
id_number = Party(party_id).identifiers[0].code
else:
id_number = ''
party_name = parties[party_id]['name']
else:
party_id = val[1]
id_number = val[1]
party_name = val[1]
acc_id = val[0]
debit = 0
credit = 0
start_balance = 0
if kind == 'in':
debit = val[2]
credit = val[3]
amount = debit - credit
else: # kind == start
start_balance = val[2]
amount = val[2]
if debit == credit == start_balance == 0:
continue
if party_id not in accounts[acc_id][1].keys():
end_balance = start_balance + debit - credit
rec = {
'id_number': id_number,
'party': party_name,
'start_balance': start_balance,
'debit': debit,
'credit': credit,
'end_balance': end_balance,
}
accounts[acc_id][1][party_id] = rec
amount = end_balance
else:
dictval = accounts[acc_id][1][party_id]
if kind == 'in':
dictval['debit'] = debit
dictval['credit'] = credit
else:
dictval['start_balance'] = start_balance
end_balance = dictval['start_balance'] + dictval['debit'] - dictval['credit']
dictval['end_balance'] = end_balance
accounts[acc_id][2]['debits'].append(debit)
accounts[acc_id][2]['credits'].append(credit)
accounts[acc_id][2]['start_balance'].append(start_balance)
accounts[acc_id][2]['end_balance'].append(amount)
_get_process_result(kind='in', values=result_in)
_get_process_result(kind='start', values=result_start)
if accounts:
records = accounts.values()
else:
records = accounts
report_context['accounts'] = records
report_context['fiscalyear'] = FiscalYear(data['fiscalyear'])
report_context['start_period'] = start_period_name
report_context['end_period'] = end_period_name
report_context['company'] = Company(data['company'])
return report_context