# 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 timeit import default_timer as timer from decimal import Decimal import operator from itertools import groupby _ZERO = Decimal('0.0') class AuxiliaryBookStart(ModelView): 'Auxiliary Book Start' __name__ = 'account_co_reports.print_auxiliary_book.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=['fiscalyear', 'end_period']) end_period = fields.Many2One('account.period', 'End Period', domain=[ ('fiscalyear', '=', Eval('fiscalyear')), ('start_date', '>=', (Eval('start_period'), 'start_date')) ], depends=['fiscalyear', 'start_period']) start_account = fields.Many2One('account.account', 'Start Account', domain=[ ('type', '!=', None), ('code', '!=', None), ]) end_account = fields.Many2One('account.account', 'End Account', domain=[ ('type', '!=', None), ('code', '!=', None), ]) start_code = fields.Char('Start Code Account') end_code = fields.Char('End Code Account') party = fields.Many2One('party.party', 'Party') 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') @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 PrintAuxiliaryBook(Wizard): 'Print Auxiliary Book' __name__ = 'account_co_reports.print_auxiliary_book' start = StateView('account_co_reports.print_auxiliary_book.start', 'account_co_reports.print_auxiliary_book_start_view_form', [ Button('Cancel', 'end', 'tryton-cancel'), Button('Print', 'print_', 'tryton-print', default=True), ] ) print_ = StateReport('account_co_reports.auxiliary_book') def _search_records(self): pass 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 if not self.start.party: party = None else: party = self.start.party.id start_account_id = None if self.start.start_account: start_account_id = self.start.start_account.id end_account_id = None if self.start.end_account: end_account_id = self.start.end_account.id data = { 'ids': [], 'company': self.start.company.id, 'fiscalyear': self.start.fiscalyear.id, 'start_period': start_period, 'end_period': end_period, 'posted': self.start.posted, 'start_account': start_account_id, 'end_account': end_account_id, 'party': party, 'empty_account': self.start.empty_account, 'fiscalyearname': self.start.fiscalyear.name } return action, data def transition_print_(self): return 'end' class AuxiliaryBook(Report): __name__ = 'account_co_reports.auxiliary_book' @classmethod def get_context(cls, records, header, data): start = timer() report_context = super().get_context(records, header, data) pool = Pool() Account = pool.get('account.account') Period = pool.get('account.period') Company = pool.get('company.company') Party = pool.get('party.party') company = Company(data['company']) start_period_name = None end_period_name = None dom_accounts = [ ('company', '=', data['company']), ('type', '!=', None), ] start_code = None if data['start_account']: start_acc = Account(data['start_account']) start_code = start_acc.code dom_accounts.append( ('code', '>=', start_acc.code) ) end_code = None if data['end_account']: end_acc = Account(data['end_account']) end_code = end_acc.code dom_accounts.append( ('code', '<=', end_acc.code) ) accounts = Account.search(dom_accounts, order=[('code', 'ASC')]) party = None if data['party']: party, = Party.search([('id', '=', data['party'])]) # -------------------------------------------------------------- start_period_ids = [0] 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_ids += [p.id for p in start_periods] start_period_name = start_period.name with Transaction().set_context( fiscalyear=data['fiscalyear'], periods=start_period_ids, party=data['party'], posted=data['posted']): start_accounts = Account.browse(accounts) end1 = timer() delta1 = (end1 - start) print('Delta 1.... ', delta1) id2start_account = {} for account in start_accounts: id2start_account[account.id] = account # -------------------------------------------------------------- end_period_ids = [] if data['end_period']: end_period = Period(data['end_period']) end_periods = Period.search([ ('fiscalyear', '=', data['fiscalyear']), ('end_date', '<=', end_period.start_date), ]) if end_period not in end_periods: end_periods.append(end_period) end_period_name = end_period.name else: end_periods = Period.search([ ('fiscalyear', '=', data['fiscalyear']), ]) end_period_ids = [p.id for p in end_periods] with Transaction().set_context( fiscalyear=data['fiscalyear'], periods=end_period_ids, party=data['party'], posted=data['posted']): end_accounts = Account.browse(accounts) end2 = timer() delta2 = (end2 - end1) print('Delta 2.... ', delta2) id2end_account = {} for account in end_accounts: id2end_account[account.id] = account if not data['empty_account']: accounts_ids = [a.id for a in accounts] account2lines = dict(cls.get_lines(accounts, end_periods, data['posted'], data['party'])) accounts_ = account2lines.keys() accounts = Account.browse( [a for a in accounts_ids if a in accounts_] ) end3 = timer() delta3 = (end3 - end2) print('Delta 3.... ', delta3) account_id2lines = cls.lines(accounts, list(set(end_periods).difference(set(start_periods))), data['posted'], data['party']) report_context['start_period_name'] = start_period_name report_context['end_period_name'] = end_period_name report_context['start_code'] = start_code report_context['end_code'] = end_code report_context['party'] = party report_context['accounts'] = accounts report_context['id2start_account'] = id2start_account report_context['id2end_account'] = id2end_account report_context['digits'] = company.currency.digits report_context['lines'] = lambda account_id: account_id2lines[account_id] report_context['company'] = company end4 = timer() delta4 = (end4 - end3) print('Delta 4.... ', delta4) end = timer() delta_total = (end - start) print('tiempo total --- :', delta_total) return report_context @classmethod def get_lines(cls, accounts, periods, posted, party=None): MoveLine = Pool().get('account.move.line') clause = [ ('account', 'in', [a.id for a in accounts]), ('period', 'in', [p.id for p in periods]), ] if party: clause.append(('party', '=', party)) if posted: clause.append(('move.state', '=', 'posted')) lines = MoveLine.search_read(clause, order=[ ('account', 'ASC'), ('date', 'ASC'), ], fields_names=[ 'description', 'move.number', 'account', 'debit', 'credit', 'date', 'party.name', 'move_origin.rec_name', ]) key = operator.itemgetter('account') lines.sort(key=key) val = groupby(lines, key) return val @classmethod def lines(cls, accounts, periods, posted, party=None): res = dict((a.id, []) for a in accounts) account2lines = cls.get_lines(accounts, periods, posted, party) for account_id, lines in account2lines: balance = _ZERO rec_append = res[account_id].append for line in lines: balance += line['debit'] - line['credit'] line['balance'] = balance rec_append(line) return res