# 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