trytonpsk-account_col/account.py

2212 lines
80 KiB
Python
Raw Normal View History

2020-04-07 15:34:03 +02: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 datetime import date
2021-09-09 06:33:19 +02:00
from timeit import default_timer as timer
2020-04-07 15:34:03 +02:00
import operator
from sql.aggregate import Sum
from sql.conditionals import Coalesce
from collections import OrderedDict
from itertools import izip, groupby
2021-05-31 19:40:08 +02:00
from trytond.i18n import gettext
2020-04-07 15:34:03 +02:00
from trytond.model import ModelView, ModelSQL, fields
from trytond.wizard import Wizard, StateView, Button, StateReport
from trytond.report import Report
2021-05-31 19:40:08 +02:00
from trytond.pyson import Eval, Bool, PYSONEncoder
2020-04-07 15:34:03 +02:00
from trytond.transaction import Transaction
from trytond.pool import Pool, PoolMeta
2021-05-31 19:40:08 +02:00
from trytond.modules.account.account import BalanceSheetContext
from trytond.exceptions import UserError
2021-05-31 19:40:08 +02:00
from .exceptions import (BadOperationError, DontWriteAccountError)
2020-04-07 15:34:03 +02:00
_ZERO = Decimal('0.0')
def compute_report(data, domain, codes, kind='income'):
pool = Pool()
Fiscalyear = pool.get('account.fiscalyear')
Period = pool.get('account.period')
Account = pool.get('account.account')
period = None
amount_profit = 0
res = {}
ctx = {
'posted': data['posted'],
}
if data.get('period'):
period = Period(data['period'])
periods = Period.search([
('start_date', '<=', period.start_date),
])
periods_ids = [period.id]
periods_ids.extend([p.id for p in periods])
ctx['periods'] = periods_ids
elif data.get('periods'):
ctx['periods'] = data.get('periods')
else:
ctx['fiscalyear'] = data['fiscalyear']
if data.get('detailed'):
len_code = 6
else:
len_code = 5
domain.append(
2021-05-31 19:40:08 +02:00
('type', '=', None),
2020-04-07 15:34:03 +02:00
)
view_accounts = Account.search(domain)
2020-12-02 00:26:07 +01:00
reduce_ids = [a.id for a in view_accounts if len(a.code) <= len_code]
2020-04-07 15:34:03 +02:00
with Transaction().set_context(ctx):
accounts = Account.search([
('id', 'in', reduce_ids),
], order=[('code', 'ASC')]
)
if data.get('account_profit'):
account_profit = Account(data['account_profit'])
profit_accounts = Account.search(['OR',
('code', 'in', ['4', '5', '6', '7']),
])
amount_profit = sum([a.balance for a in profit_accounts])
records = []
for a in accounts:
if (len(a.code) == 1) or not(a.balance == 0 and len(a.code) >= (len_code - 1)):
if kind == 'income':
a.balance = a.balance * (-1)
records.append(a)
res['records'] = records
main_accounts = Account.search(['OR',
('code', 'in', codes),
])
# Crea una cuenta virtual temporal con la utilidad para ponerla en el Balance
if data.get('account_profit'):
tree_account_assets = []
def _add_parents(acc):
if acc in res['records']:
acc = res['records'].pop(res['records'].index(acc))
acc.balance = acc.balance + amount_profit
tree_account_assets.append(acc)
if acc.parent and acc.parent.code:
_add_parents(acc.parent)
# Split records for keep order
_add_parents(account_profit)
res['records'].extend(tree_account_assets)
new_records = [(rec.code, rec) for rec in res['records']]
def getKey(item):
return item[1]
new_records.sort(key=operator.itemgetter(0))
res['records'] = [nr[1] for nr in new_records]
global_result = sum([a.balance for a in main_accounts]) + amount_profit
if kind == 'income':
global_result = global_result * (-1)
res['global_result'] = global_result
fiscalyear = Fiscalyear(data['fiscalyear'])
if period:
res['start_date'] = period.start_date
res['end_date'] = period.end_date
else:
periods_dates = []
for p in fiscalyear.periods:
periods_dates.extend([p.start_date, p.end_date])
res['start_date'] = min(periods_dates)
res['end_date'] = max(periods_dates)
res['period'] = period
res['fiscalyear'] = fiscalyear
return res
2021-05-31 19:40:08 +02:00
class Account(ModelSQL, ModelView):
2020-04-07 15:34:03 +02:00
__name__ = 'account.account'
cashflow = fields.Many2One('account.account.cashflow', 'Cashflow',
ondelete="RESTRICT", states={
2021-05-31 19:40:08 +02:00
'invisible': ~Bool(Eval('type')),
2020-04-07 15:34:03 +02:00
},
domain=[
('company', '=', Eval('company')),
2021-05-31 19:40:08 +02:00
], depends=['type', 'company'])
2020-04-07 15:34:03 +02:00
classification = fields.Selection([
('', ''),
('ifrs', 'Ifrs'),
('colgaap', 'Colgaap'),
], 'Classification')
2020-07-08 19:00:33 +02:00
@classmethod
def __setup__(cls):
super(Account, cls).__setup__()
2021-08-24 23:13:47 +02:00
fields_names = [
'name', 'template_override', 'party_required', 'type',
]
cls._check_modify_exclude = fields_names
2020-07-08 19:00:33 +02:00
@classmethod
def copy(cls, records, default=None):
2021-05-31 19:40:08 +02:00
raise BadOperationError(gettext('account_col.msg_bad_operation'))
2020-07-08 19:00:33 +02:00
return super(Account, cls).copy(records, default=default)
2021-07-21 00:20:36 +02:00
@fields.depends('type')
def on_change_with_deferral(self, name=None):
return (self.type
and self.type.statement in {'balance', 'off-balance', 'income'})
2021-08-09 16:13:19 +02:00
@classmethod
def create(cls, vlist):
for vals in vlist:
if vals['type'] and vals['code'] and vals['code'][0] in ['4', '5', '6', '7']:
vals['party_required'] = True
return super(Account, cls).create(vlist)
@classmethod
def write(cls, records, vlist):
2021-08-20 00:02:21 +02:00
if vlist.get('type') and vlist.get('code') and vlist['code'][0] in ['4', '5', '6', '7']:
2021-08-09 16:13:19 +02:00
vlist['party_required'] = True
2021-08-25 22:01:41 +02:00
# fields_modify = list(set(vlist.keys()) - set(cls._check_modify_exclude))
# if len(fields_modify) > 0:
# cls.check_account_to_write(records)
2021-08-09 16:13:19 +02:00
return super(Account, cls).write(records, vlist)
2021-07-21 00:20:36 +02:00
@classmethod
def check_account_to_write(cls, accounts):
pool = Pool()
Line = pool.get('account.move.line')
for account in accounts:
lines = Line.search([('account', '=', account.id)])
2021-05-31 19:40:08 +02:00
if account.type and lines:
raise DontWriteAccountError(
gettext('account_col.msg_dont_write_account',
account=account.rec_name))
2020-04-07 15:34:03 +02:00
class AuxiliaryBookStart(ModelView):
'Auxiliary Book Start'
__name__ = 'account_col.print_auxiliary_book.start'
fiscalyear = fields.Many2One('account.fiscalyear', 'Fiscal Year',
2020-12-02 00:26:07 +01:00
required=True)
2020-04-07 15:34:03 +02:00
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=[
2021-05-31 19:40:08 +02:00
('type', '!=', None),
2020-04-07 15:34:03 +02:00
('code', '!=', None),
])
end_account = fields.Many2One('account.account', 'End Account',
domain=[
2021-05-31 19:40:08 +02:00
('type', '!=', None),
2020-04-07 15:34:03 +02:00
('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')
reference = fields.Char('Reference')
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_col.print_auxiliary_book'
start = StateView('account_col.print_auxiliary_book.start',
'account_col.print_auxiliary_book_start_view_form', [
Button('Cancel', 'end', 'tryton-cancel'),
Button('Print', 'print_', 'tryton-print', default=True),
2021-09-09 06:33:19 +02:00
]
)
2020-04-07 15:34:03 +02:00
print_ = StateReport('account_col.auxiliary_book')
2021-05-31 19:40:08 +02:00
def _search_records(self):
pass
2020-04-07 15:34:03 +02:00
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 = {
2021-05-31 19:40:08 +02:00
'ids': [],
2020-04-07 15:34:03 +02:00
'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,
'reference': self.start.reference,
2021-03-12 22:18:18 +01:00
'fiscalyearname': self.start.fiscalyear.name
2021-05-31 19:40:08 +02:00
}
2020-04-07 15:34:03 +02:00
return action, data
def transition_print_(self):
return 'end'
class AuxiliaryBook(Report):
__name__ = 'account_col.auxiliary_book'
@classmethod
2021-05-31 19:40:08 +02:00
def get_context(cls, records, header, data):
2021-09-09 06:33:19 +02:00
start = timer()
2021-05-31 19:40:08 +02:00
report_context = super().get_context(records, header, data)
2021-09-09 06:33:19 +02:00
2020-04-07 15:34:03 +02:00
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 = [
2021-05-31 19:40:08 +02:00
('company', '=', data['company']),
('type', '!=', None),
2020-04-07 15:34:03 +02:00
]
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']:
2021-09-09 06:33:19 +02:00
party, = Party.search([('id', '=', data['party'])])
2020-04-07 15:34:03 +02:00
# --------------------------------------------------------------
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)
2021-09-09 06:33:19 +02:00
end1 = timer()
delta1 = (end1 - start)
print('Delta 1.... ', delta1)
2020-04-07 15:34:03 +02:00
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)
2021-09-09 06:33:19 +02:00
end2 = timer()
delta2 = (end2 - end1)
print('Delta 2.... ', delta2)
2020-04-07 15:34:03 +02:00
id2end_account = {}
for account in end_accounts:
id2end_account[account.id] = account
if not data['empty_account']:
2021-09-09 06:33:19 +02:00
accounts_ids = [a.id for a in accounts]
2020-04-07 15:34:03 +02:00
account2lines = dict(cls.get_lines(accounts,
end_periods, data['posted'], data['party'],
data['reference']))
2021-09-09 06:33:19 +02:00
accounts_ = account2lines.keys()
2020-04-07 15:34:03 +02:00
accounts = Account.browse(
2021-09-09 06:33:19 +02:00
[a for a in accounts_ids if a in accounts_]
2020-04-07 15:34:03 +02:00
)
2021-09-09 06:33:19 +02:00
end3 = timer()
delta3 = (end3 - end2)
print('Delta 3.... ', delta3)
2020-04-07 15:34:03 +02:00
account_id2lines = cls.lines(accounts,
list(set(end_periods).difference(set(start_periods))),
data['posted'], data['party'], data['reference'])
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
2021-09-09 06:33:19 +02:00
end4 = timer()
delta4 = (end4 - end3)
print('Delta 4.... ', delta4)
end = timer()
delta_total = (end - start)
print('tiempo total --- :', delta_total)
2020-04-07 15:34:03 +02:00
return report_context
@classmethod
2020-12-02 00:26:07 +01:00
def get_lines(cls, accounts, periods, posted, party=None, reference=None):
2020-04-07 15:34:03 +02:00
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'))
if reference:
clause.append(('reference', 'like', '%' + reference + '%'))
2021-09-09 06:33:19 +02:00
lines = MoveLine.search_read(clause,
2020-04-07 15:34:03 +02:00
order=[
('account', 'ASC'),
('date', 'ASC'),
2021-09-09 06:33:19 +02:00
], fields_names=[
'description', 'move.number', 'account', 'debit',
2021-09-17 15:37:35 +02:00
'credit', 'reference', 'date', 'party.name', 'party.id_number',
'move_origin.rec_name',
2020-04-07 15:34:03 +02:00
])
2021-09-09 06:33:19 +02:00
key = operator.itemgetter('account')
2020-04-07 15:34:03 +02:00
lines.sort(key=key)
2021-09-09 06:33:19 +02:00
val = groupby(lines, key)
return val
2020-04-07 15:34:03 +02:00
@classmethod
def lines(cls, accounts, periods, posted, party=None, reference=None):
res = dict((a.id, []) for a in accounts)
account2lines = cls.get_lines(accounts, periods, posted, party, reference)
2021-09-09 06:33:19 +02:00
for account_id, lines in account2lines:
balance = _ZERO
rec_append = res[account_id].append
2020-04-07 15:34:03 +02:00
for line in lines:
2021-09-09 06:33:19 +02:00
line['move'] = line['move.']['number']
balance += line['debit'] - line['credit']
if line['party.']:
line['party'] = line['party.']['name']
2021-09-17 15:37:35 +02:00
line['party_id'] = line['party.']['id_number']
if line['move_origin.']:
line['origin'] = line['move_origin.']['rec_name']
2021-09-09 06:33:19 +02:00
line['balance'] = balance
rec_append(line)
2020-04-07 15:34:03 +02:00
return res
class PrintTrialBalanceDetailedStart(ModelView):
'Print Trial Balance Detailed'
__name__ = 'account_col.print_trial_balance_detailed.start'
fiscalyear = fields.Many2One('account.fiscalyear', 'Fiscal Year',
2020-12-02 00:26:07 +01:00
required=True, depends=['start_period', 'end_period'])
2020-04-07 15:34:03 +02:00
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=[
2021-05-31 19:40:08 +02:00
('type', '!=', None),
2020-04-07 15:34:03 +02:00
])
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_col.print_trial_balance_detailed'
start = StateView('account_col.print_trial_balance_detailed.start',
'account_col.print_trial_balance_detailed_start_view_form', [
Button('Cancel', 'end', 'tryton-cancel'),
Button('Print', 'print_', 'tryton-print', default=True),
])
print_ = StateReport('account_col.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_col.trial_balance_detailed'
@classmethod
2021-05-31 19:40:08 +02:00
def get_context(cls, records, header, data):
report_context = super().get_context(records, header, data)
2020-04-07 15:34:03 +02:00
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']))
2020-09-17 15:59:33 +02:00
if data['posted']:
select1.where = select1.where & (move.state == 'posted')
2020-04-07 15:34:03 +02:00
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,
{},
{
2021-09-09 06:33:19 +02:00
'debits': [],
'credits': [],
'start_balance': [],
'end_balance': [],
2020-04-07 15:34:03 +02:00
}
]
if not data['by_reference']:
parties_obj = Party.search_read([
('id', 'in', parties_ids),
('active', 'in', [False, True]),
], fields_names=['id_number', 'name'])
parties = {p['id'] : p for p in parties_obj}
else:
2020-12-02 00:26:07 +01:00
parties = {p: p for p in parties_ids}
2020-04-07 15:34:03 +02:00
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]
id_number = parties[party_id]['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
class BalanceSheetContextCol(BalanceSheetContext):
'Balance Sheet Context'
__name__ = 'account.balance_sheet.col.context'
2020-12-02 00:26:07 +01:00
utility_temp = fields.Boolean('Utility Temp',
help='Permited see the utility without have any account move')
2020-04-07 15:34:03 +02:00
class BalanceSheet(Report):
'Balance Sheet Report'
__name__ = 'account.balance_sheet'
@classmethod
2021-05-31 19:40:08 +02:00
def get_context(cls, records, header, data):
report_context = super().get_context(records, header, data)
2020-04-07 15:34:03 +02:00
Company = Pool().get('company.company')
report_context['company'] = Company(Transaction().context.get('company'))
report_context['date'] = Transaction().context.get('date')
report_context['comparison'] = Transaction().context.get('comparison')
report_context['date_cmp'] = Transaction().context.get('date_cmp')
value_accounts = report_context['records']
account_child_list = []
utility = {}
value_comp = 0
for account in value_accounts:
if account.amount != 0:
for child in account.childs:
if child.name == 'PATRIMONIO NETO Y PASIVOS':
child.amount = child.amount + account.amount
if child.amount_cmp and account.amount_cmp:
child.amount_cmp = child.amount_cmp + account.amount_cmp
for child1 in child.childs:
if child1.name == 'PATRIMONIO NETO':
child1.amount = child1.amount + account.amount
if child1.amount_cmp and account.amount_cmp:
child1.amount_cmp = child1.amount_cmp + account.amount_cmp
child1.childs[0].amount = child1.childs[0].amount + account.amount
if child1.childs[0].amount_cmp and account.amount_cmp:
child1.childs[0].amount_cmp = child1.childs[0].amount_cmp + account.amount_cmp
account_child_list = [child for child in child1.childs[0].childs]
if account.amount_cmp:
value_comp = account.amount_cmp
utility = {
'amount': account.amount,
'amount_cmp': value_comp,
'name': 'UTILIDAD / PERDIDA ESTIMADA DEL PERIODO',
'childs': None,
}
account_child_list.append(utility)
child1.childs[0].childs = account_child_list
return report_context
class IncomeStatement(Report):
'Income Statement'
__name__ = 'account.income_statement'
@classmethod
2021-05-31 19:40:08 +02:00
def get_context(cls, records, header, data):
2020-04-07 15:34:03 +02:00
pool = Pool()
Type = pool.get('account.account.type')
Account = pool.get('account.account')
Period = pool.get('account.period')
Fiscalyear = pool.get('account.fiscalyear')
Company = pool.get('company.company')
Context = pool.get('account.income_statement.context')
context = Transaction().context
2021-05-31 19:40:08 +02:00
report_context = super().get_context(records, header, data)
2020-04-07 15:34:03 +02:00
context_fields = Context.fields_get(['start_period', 'fiscalyear'])
types = Type.search([
('income_statement', '=', True)
])
accounts_types = []
company_id = Transaction().context.get('company')
records = Type(report_context['data']['id'])
fiscalyear_id = Transaction().context.get('fiscalyear')
fiscalyear_cmp = Transaction().context.get('fiscalyear_cmp')
start_period = Transaction().context.get('start_period')
start_period_cmp = Transaction().context.get('start_period_cmp')
end_period = Transaction().context.get('end_period')
end_period_cmp = Transaction().context.get('end_period_cmp')
comparison = Transaction().context.get('comparison')
if start_period:
start_period = Period(start_period)
if end_period:
end_period = Period(end_period)
2020-12-02 00:26:07 +01:00
dom_periods = [
2020-04-07 15:34:03 +02:00
('type', '=', 'standard'),
('fiscalyear', '=', fiscalyear_id),
]
if start_period:
dom_periods.append(('start_date', '>=', start_period.start_date))
if end_period:
dom_periods.append(('start_date', '<=', end_period.start_date))
range_periods = Period.search(dom_periods)
periods_ids = [p.id for p in range_periods]
od = {}
with Transaction().set_context(periods=periods_ids):
while types:
type_ = types.pop()
2020-12-02 00:26:07 +01:00
if type_.income_statement is False:
2020-04-07 15:34:03 +02:00
accounts = Account.search([
2021-05-31 19:40:08 +02:00
('type', '=', type_.id),
2020-04-07 15:34:03 +02:00
])
if accounts:
setattr(type_, 'accounts', accounts)
accounts_types.append((type_.sequence, type_))
if type_.childs:
types.extend(list(type_.childs))
if accounts_types:
od = OrderedDict(sorted(dict(accounts_types).items()))
types_added = []
filtered_records = []
for k, v in od.items():
childs = []
for c in v.childs:
if c.id not in types_added:
childs.append(c)
types_added.extend([v.id, c.id])
setattr(v, 'childs', childs)
filtered_records.append(v)
report_context['start_period'] = start_period
report_context['start_period_cmp'] = Period(start_period_cmp)
report_context['end_period'] = end_period
report_context['end_period_cmp'] = Period(end_period_cmp)
report_context['fiscalyear'] = Fiscalyear(fiscalyear_id).name
report_context['fiscalyear_cmp'] = Fiscalyear(fiscalyear_cmp).name if fiscalyear_cmp else ''
report_context['records'] = filtered_records
report_context['comparison'] = comparison
report_context['company'] = Company(Transaction().context.get('company'))
report_context['date'] = Transaction().context.get('date')
return report_context
class CashflowTemplate(ModelSQL, ModelView):
'Account Cashflow Template'
__name__ = 'account.account.cashflow.template'
name = fields.Char('Name', required=True, translate=True)
parent = fields.Many2One('account.account.cashflow.template', 'Parent',
2020-12-02 00:26:07 +01:00
ondelete="RESTRICT")
2020-04-07 15:34:03 +02:00
childs = fields.One2Many('account.account.cashflow.template', 'parent',
'Children')
sequence = fields.Integer('Sequence')
display_balance = fields.Selection([
('debit-credit', 'Debit - Credit'),
('credit-debit', 'Credit - Debit'),
], 'Display Balance', required=True)
@classmethod
def __setup__(cls):
super(CashflowTemplate, cls).__setup__()
cls._order.insert(0, ('sequence', 'ASC'))
@classmethod
def validate(cls, records):
super(CashflowTemplate, cls).validate(records)
cls.check_recursion(records, rec_name='name')
@staticmethod
def order_sequence(tables):
table, _ = tables[None]
2020-12-02 00:26:07 +01:00
return [table.sequence is None, table.sequence]
2020-04-07 15:34:03 +02:00
@staticmethod
def default_display_balance():
return 'debit-credit'
def get_rec_name(self, name):
if self.parent:
return self.parent.get_rec_name(name) + '\\' + self.name
else:
return self.name
def _get_cashflow_value(self, cashflow=None):
'''
Set the values for account creation.
'''
res = {}
if not cashflow or cashflow.name != self.name:
res['name'] = self.name
if not cashflow or cashflow.sequence != self.sequence:
res['sequence'] = self.sequence
if not cashflow or cashflow.display_balance != self.display_balance:
res['display_balance'] = self.display_balance
if not cashflow or cashflow.template != self:
res['template'] = self.id
return res
def create_cashflow(self, company_id, template2cashflow=None, parent_id=None):
'''
Create recursively cashflows based on template.
template2cashflow is a dictionary with template id as key and cashflow id as
value, used to convert template id into cashflow. The dictionary is filled
with new cashflows.
Return the id of the cashflow created
'''
pool = Pool()
Cashflow = pool.get('account.account.cashflow')
Lang = pool.get('ir.lang')
Config = pool.get('ir.configuration')
if template2cashflow is None:
template2cashflow = {}
if self.id not in template2cashflow:
vals = self._get_cashflow_value()
vals['company'] = company_id
vals['parent'] = parent_id
new_cashflow, = Cashflow.create([vals])
prev_lang = self._context.get('language') or Config.get_language()
prev_data = {}
for field_name, field in self._fields.items():
if getattr(field, 'translate', False):
prev_data[field_name] = getattr(self, field_name)
for lang in Lang.get_translatable_languages():
if lang == prev_lang:
continue
with Transaction().set_context(language=lang):
template = self.__class__(self.id)
data = {}
for field_name, field in template._fields.items():
if (getattr(field, 'translate', False)
and (getattr(template, field_name) !=
prev_data[field_name])):
data[field_name] = getattr(template, field_name)
if data:
Cashflow.write([new_cashflow], data)
template2cashflow[self.id] = new_cashflow.id
new_id = template2cashflow[self.id]
new_childs = []
for child in self.childs:
new_childs.append(child.create_cashflow(company_id,
template2cashflow=template2cashflow, parent_id=new_id))
return new_id
class Cashflow(ModelSQL, ModelView):
'Account Cashflow'
__name__ = 'account.account.cashflow'
name = fields.Char('Name', size=None, required=True, translate=True)
parent = fields.Many2One('account.account.cashflow', 'Parent',
ondelete="RESTRICT", domain=[
('company', '=', Eval('company')),
], depends=['company'])
childs = fields.One2Many('account.account.cashflow', 'parent', 'Children',
domain=[
('company', '=', Eval('company')),
], depends=['company'])
sequence = fields.Integer('Sequence',
help='Use to order the account cashflow')
currency_digits = fields.Function(fields.Integer('Currency Digits'),
'get_currency_digits')
amount = fields.Function(fields.Numeric('Amount',
digits=(16, Eval('currency_digits', 2)), depends=['currency_digits']),
'get_amount')
display_balance = fields.Selection([
('debit-credit', 'Debit - Credit'),
('credit-debit', 'Credit - Debit'),
], 'Display Balance', required=True)
company = fields.Many2One('company.company', 'Company', required=True,
ondelete="RESTRICT")
template = fields.Many2One('account.account.cashflow.template', 'Template')
accounts = fields.One2Many('account.account', 'cashflow', 'Accounts',
2021-05-31 19:40:08 +02:00
add_remove=[], domain=[('type', '!=', None)])
2020-04-07 15:34:03 +02:00
@classmethod
def __setup__(cls):
super(Cashflow, cls).__setup__()
cls._order.insert(0, ('sequence', 'ASC'))
@classmethod
def validate(cls, cashflows):
super(Cashflow, cls).validate(cashflows)
cls.check_recursion(cashflows, rec_name='name')
@staticmethod
def order_sequence(tables):
table, _ = tables[None]
2020-12-02 00:26:07 +01:00
return [table.sequence is None, table.sequence]
2020-04-07 15:34:03 +02:00
@staticmethod
def default_balance_sheet():
return False
@staticmethod
def default_income_statement():
return False
@staticmethod
def default_display_balance():
return 'debit-credit'
def get_currency_digits(self, name):
return self.company.currency.digits
@classmethod
def get_ctx(cls, fiscalyear=False):
Period = Pool().get('account.period')
end_period = Transaction().context.get('period')
period = Period(end_period)
dom = [('start_date', '<', period.start_date)]
fiscalyear_id = Transaction().context.get('fiscalyear')
if fiscalyear:
dom.append(('fiscalyear', '=', fiscalyear_id))
periods = Period.search(dom)
all_periods = [p.id for p in periods]
all_periods.append(end_period)
ctx = {
'posted': True,
'periods': all_periods,
}
return ctx
@classmethod
def get_amount(cls, cashflows, name):
pool = Pool()
Account = pool.get('account.account')
res = {}
for cashflow_ in cashflows:
res[cashflow_.id] = Decimal('0.0')
childs = cls.search([
('parent', 'child_of', [t.id for t in cashflows]),
])
cashflow_sum = {}
for cashflow_ in childs:
cashflow_sum[cashflow_.id] = Decimal('0.0')
with Transaction().set_context(cls.get_ctx(fiscalyear=False)):
accounts = Account.search([
('cashflow', 'in', [t.id for t in childs]),
2021-05-31 19:40:08 +02:00
('type', '!=', None),
2020-04-07 15:34:03 +02:00
])
for account in accounts:
cashflow_sum[account.cashflow.id] += (account.debit - account.credit)
for cashflow_ in cashflows:
childs = cls.search([
('parent', 'child_of', [cashflow_.id]),
])
for child in childs:
res[cashflow_.id] += cashflow_sum[child.id]
res[cashflow_.id] = cashflow_.company.currency.round(res[cashflow_.id])
if cashflow_.display_balance == 'credit-debit':
res[cashflow_.id] = - res[cashflow_.id]
return res
def get_rec_name(self, name):
if self.parent:
return self.parent.get_rec_name(name) + '\\' + self.name
else:
return self.name
@classmethod
def delete(cls, cashflows):
cashflows = cls.search([
('parent', 'child_of', [t.id for t in cashflows]),
])
super(Cashflow, cls).delete(cashflows)
def update_cashflow(self, template2cashflow=None):
'''
Update recursively cashflows based on template.
template2cashflow is a dictionary with template id as key and cashflow id as
value, used to convert template id into cashflow. The dictionary is filled
with new cashflows
'''
pool = Pool()
Lang = pool.get('ir.lang')
Config = pool.get('ir.configuration')
if template2cashflow is None:
template2cashflow = {}
if self.template:
vals = self.template._get_cashflow_value(cashflow=self)
if vals:
self.write([self], vals)
prev_lang = self._context.get('language') or Config.get_language()
prev_data = {}
for field_name, field in self.template._fields.items():
if getattr(field, 'translate', False):
prev_data[field_name] = getattr(self.template, field_name)
for lang in Lang.get_translatable_languages():
if lang == prev_lang:
continue
with Transaction().set_context(language=lang):
cashflow_ = self.__class__(self.id)
data = {}
for field_name, field in (
cashflow_.template._fields.items()):
if (getattr(field, 'translate', False)
and (getattr(cashflow_.template, field_name) !=
prev_data[field_name])):
data[field_name] = getattr(cashflow_.template,
field_name)
if data:
self.write([cashflow_], data)
template2cashflow[self.template.id] = self.id
for child in self.childs:
child.update_cashflow(template2cashflow=template2cashflow)
class CashflowStatementContext(ModelView):
'Cashflow Statement Context'
__name__ = 'account.cashflow_statement.context'
fiscalyear = fields.Many2One('account.fiscalyear', 'Fiscal Year',
required=True)
period = fields.Many2One('account.period', 'Period',
depends=['fiscalyear'], required=True, domain=[
('fiscalyear', '=', Eval('fiscalyear')),
])
company = fields.Many2One('company.company', 'Company', required=True)
posted = fields.Boolean('Posted Move', help='Show only posted 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_period():
Period = Pool().get('account.period')
company_id = Transaction().context.get('company')
period_id = Period.find(company_id, date=date.today())
return period_id
@fields.depends('fiscalyear')
def on_change_fiscalyear(self):
self.period = None
class CashflowStatement(Report):
__name__ = 'account.cashflow_statement'
@classmethod
2021-05-31 19:40:08 +02:00
def get_context(cls, records, header, data):
report_context = super().get_context(records, header, data)
2020-04-07 15:34:03 +02:00
pool = Pool()
Company = pool.get('company.company')
Period = pool.get('account.period')
CashFlow = pool.get('account.account.cashflow')
company_id = Transaction().context.get('company')
period_id = Transaction().context.get('period')
period = Period(period_id)
company = Company(company_id)
ctx = CashFlow.get_ctx(fiscalyear=True)
new_records = []
with Transaction().set_context(ctx):
for record in records:
target_accounts = []
for account in record.accounts:
if account.balance != 0:
target_accounts.append(account)
record.accounts = target_accounts
new_records.append(record)
report_context['records'] = new_records
report_context['company'] = company
report_context['period'] = period.name
return report_context
class PartyWithholdingStart(ModelView):
'Party Withholding Start'
__name__ = 'account.party_withholding.start'
fiscalyear = fields.Many2One('account.fiscalyear', 'Fiscalyear',
required=True)
company = fields.Many2One('company.company', 'Company', required=True)
party = fields.Many2One('party.party', 'Party')
2021-11-26 05:48:42 +01:00
clasification = fields.Selection('selection_certificate_type',
2020-04-07 15:34:03 +02:00
'Certificate Report')
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'])
@staticmethod
def default_company():
return Transaction().context.get('company')
@classmethod
def selection_certificate_type(cls):
Tax = Pool().get('account.tax')
2021-12-03 21:47:39 +01:00
sel = Tax.classification.selection
2020-04-07 15:34:03 +02:00
return sel
class PrintPartyWithholding(Wizard):
'Print Withholding'
__name__ = 'account.print_party_withholding'
start = StateView('account.party_withholding.start',
'account_col.print_party_withholding_start_view_form', [
Button('Cancel', 'end', 'tryton-cancel'),
Button('Ok', 'print_', 'tryton-ok', default=True),
])
print_ = StateReport('account_col.party_withholding')
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
party_id = None
if self.start.party:
party_id = self.start.party.id
data = {
'company': self.start.company.id,
'fiscalyear': self.start.fiscalyear.id,
'party': party_id,
2021-11-26 05:48:42 +01:00
'clasification': self.start.clasification,
2020-04-07 15:34:03 +02:00
'start_period': start_period,
'end_period': end_period,
}
return action, data
class PartyWithholding(Report):
__name__ = 'account_col.party_withholding'
@classmethod
2021-05-31 19:40:08 +02:00
def get_context(cls, records, header, data):
report_context = super().get_context(records, header, data)
2020-04-07 15:34:03 +02:00
pool = Pool()
InvoiceTax = pool.get('account.invoice.tax')
Tax = pool.get('account.tax')
Company = pool.get('company.company')
Period = pool.get('account.period')
Fiscalyear = pool.get('account.fiscalyear')
Party = pool.get('party.party')
company = Company(data['company'])
if data['party']:
party_dom = [
('id', '=', data['party']),
]
else:
party_dom = []
parties = Party.search(party_dom)
dom_periods = [
('fiscalyear', '=', data['fiscalyear']),
]
if data['start_period']:
start_period = Period(data['start_period'])
dom_periods.append(('start_date', '>=', start_period.start_date))
if data['end_period']:
end_period = Period(data['end_period'])
dom_periods.append(('start_date', '<=', end_period.start_date))
periods = Period.search(dom_periods, order=[('start_date', 'ASC')])
period_ids = [p.id for p in periods]
2021-11-26 05:48:42 +01:00
if data['clasification'] is None:
2020-04-07 15:34:03 +02:00
dom_taxes = []
else:
2022-01-06 23:42:57 +01:00
dom_taxes = [('classification', '=', data['clasification'])]
2020-04-07 15:34:03 +02:00
taxes = Tax.search(dom_taxes)
tax_ids = [t.id for t in taxes]
records = []
for party in parties:
invoice_taxes = InvoiceTax.search([
('invoice.move.period', 'in', period_ids),
('invoice.party', '=', party.id),
('invoice.state', 'in', ['posted', 'paid']),
('tax', 'in', tax_ids),
], order=[('create_date', 'ASC')])
if not invoice_taxes:
continue
group_taxes = {}
for it in invoice_taxes:
2022-01-06 23:42:57 +01:00
if not it.tax.classification:
2020-04-07 15:34:03 +02:00
continue
2022-01-06 23:42:57 +01:00
key_id = it.tax.classification + str(party.id)
2021-08-06 00:19:29 +02:00
if key_id not in group_taxes.keys():
group_taxes[key_id] = {
'party': party,
2022-01-06 23:42:57 +01:00
'tax_type': it.tax.classification,
2020-04-07 15:34:03 +02:00
'taxes_with': [],
'total_amount': _ZERO,
'total_untaxed': _ZERO,
}
2021-08-06 00:19:29 +02:00
group_taxes[key_id]['taxes_with'].append(it)
group_taxes[key_id]['total_amount'] += (it.amount) * (-1)
group_taxes[key_id]['total_untaxed'] += it.base
records.extend(group_taxes.values())
if not records:
raise UserError(gettext('account_col.msg_report_missing_information'))
2020-04-07 15:34:03 +02:00
report_context['records'] = records
report_context['fiscalyear'] = Fiscalyear(data['fiscalyear'])
report_context['start_date'] = periods[0].start_date
report_context['end_date'] = periods[-1].end_date
report_context['today'] = date.today()
report_context['company'] = company
return report_context
2021-05-31 19:40:08 +02:00
class AccountConfiguration(ModelSQL, ModelView):
2020-04-07 15:34:03 +02:00
__name__ = 'account.configuration'
2020-04-07 15:34:03 +02:00
equivalent_invoice_sec = fields.Many2One('ir.sequence',
2020-12-02 00:26:07 +01:00
'Equivalent Invoice', domain=[
2020-04-07 15:34:03 +02:00
('code', '=', 'account.invoice')
])
2021-05-31 19:40:08 +02:00
template_email_confirm = fields.Many2One(
'email.template', 'Template Email of Notification'
)
remove_tax = fields.Boolean('Remove Tax', help="Remove taxes on invoice if not exceeding the base")
2021-05-31 19:40:08 +02:00
2020-04-07 15:34:03 +02:00
class AuxiliaryPartyStart(ModelView):
'Auxiliary Party Start'
__name__ = 'account_col.print_auxiliary_party.start'
start_period = fields.Many2One('account.period', 'Start Period',
domain=[
('start_date', '<=', (Eval('end_period'), 'start_date')),
], depends=['fiscalyear', 'end_period'])
end_period = fields.Many2One('account.period', 'End Period',
domain=[
('start_date', '>=', (Eval('start_period'), 'start_date'))
],
depends=['start_period'])
party = fields.Many2One('party.party', 'Party')
accounts = fields.Many2Many('account.account', None, None, 'Accounts',
domain=[
2021-05-31 19:40:08 +02:00
('type', '!=', None),
2020-04-07 15:34:03 +02:00
])
company = fields.Many2One('company.company', 'Company', required=True)
posted = fields.Boolean('Posted Move', help='Show only posted move')
reference = fields.Char('Reference')
grouped_by_account = fields.Boolean('Grouped by Account')
grouped_by_location = fields.Boolean('Grouped by Location')
only_reference = fields.Boolean('Only By Reference')
empty_account = fields.Boolean('Empty Account',
help='With account without move')
@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 PrintAuxiliaryParty(Wizard):
'Print Auxiliary Party'
__name__ = 'account_col.print_auxiliary_party'
start = StateView('account_col.print_auxiliary_party.start',
'account_col.print_auxiliary_party_start_view_form', [
Button('Cancel', 'end', 'tryton-cancel'),
Button('Print', 'print_', 'tryton-print', default=True),
])
print_ = StateReport('account_col.auxiliary_party')
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
if self.start.accounts:
accounts_ids = [acc.id for acc in self.start.accounts]
else:
accounts_ids = []
grouped_by_oc = False
if hasattr(self.start, 'grouped_by_oc') and self.start.grouped_by_oc:
grouped_by_oc = self.start.grouped_by_oc
2020-04-07 15:34:03 +02:00
data = {
'company': self.start.company.id,
'start_period': start_period,
'end_period': end_period,
'posted': self.start.posted,
'party': party,
'empty_account': self.start.empty_account,
'accounts': accounts_ids,
'reference': self.start.reference,
'grouped_by_account': self.start.grouped_by_account,
'grouped_by_location': self.start.grouped_by_location,
'only_reference': self.start.only_reference,
'grouped_by_oc': grouped_by_oc,
2020-04-07 15:34:03 +02:00
}
return action, data
def transition_print_(self):
return 'end'
class AuxiliaryParty(Report):
__name__ = 'account_col.auxiliary_party'
@classmethod
2021-05-31 19:40:08 +02:00
def get_context(cls, records, header, data):
report_context = super().get_context(records, header, data)
2020-04-07 15:34:03 +02:00
pool = Pool()
Period = pool.get('account.period')
Company = pool.get('company.company')
Move = pool.get('account.move')
MoveLine = pool.get('account.move.line')
company = Company(data['company'])
dom_move = []
#Add context Transaction for company and fiscalyear
# dom_move = [('company', '=', company)]
if data.get('posted'):
dom_move.append(('state', '=', 'posted'))
start_period = None
end_period = None
if data.get('start_period'):
start_period = Period(data['start_period'])
dom_move.append(('period.start_date', '>=', start_period.start_date))
if data.get('end_period'):
end_period = Period(data['end_period'])
dom_move.append(('period.start_date', '<=', end_period.start_date))
moves = Move.search_read(dom_move,
order=[
('date', 'ASC'), ('id', 'ASC')
2020-12-02 00:26:27 +01:00
], fields_names=['id'],
2020-04-07 15:34:03 +02:00
)
moves_ids = [move['id'] for move in moves]
dom_lines = [
('move', 'in', moves_ids)
]
if data.get('reference'):
reference_dom = ('reference', 'ilike', data.get('reference'))
dom_lines.append(reference_dom)
if data.get('accounts'):
accounts_dom = ('account', 'in', data['accounts'])
dom_lines.append(accounts_dom)
if data.get('party'):
parties_dom = ('party', '=', data['party'])
dom_lines.append(parties_dom)
lines = MoveLine.search(dom_lines, order=[('move.date', 'ASC')])
res = {}
2021-08-10 23:34:05 +02:00
accounts_id = {}
grouped_by_loc = False
2021-09-09 06:33:19 +02:00
2020-04-07 15:34:03 +02:00
if lines:
for line in lines:
if not line.party:
continue
2021-09-09 06:33:19 +02:00
2020-04-07 15:34:03 +02:00
if data['only_reference']:
id_ = line.reference
name = line.reference
id_number = ''
else:
id_ = line.party.id
name = line.party.rec_name
id_number = line.party.id_number
2021-08-10 23:34:05 +02:00
account_id = line.account.id
if data['grouped_by_location'] or data['grouped_by_oc']:
grouped_by_loc = True
if data['grouped_by_location']:
city_name = ' '
if line.party.city_name:
city_name = line.party.city_name
id_loc = city_name
elif data['grouped_by_oc']:
id_loc = 'CO.'
if line.operation_center:
id_loc = 'CO. [' + line.operation_center.code + '] ' + line.operation_center.name
if id_loc not in res.keys():
res[id_loc] = {}
accounts_id[id_loc] = {
'name': id_loc,
2021-08-10 23:34:05 +02:00
'sum_debit': [],
'sum_credit': [],
'balance': []
}
2020-04-07 15:34:03 +02:00
if id_ not in res[id_loc].keys():
res[id_loc][id_] = {
2021-08-10 23:34:05 +02:00
'name': name,
'id_number': id_number,
'accounts': [],
}
accounts_id[id_loc][id_] = {}
2021-08-10 23:34:05 +02:00
if account_id not in accounts_id[id_loc][id_].keys():
accounts_id[id_loc][id_][account_id] = {
2021-08-10 23:34:05 +02:00
'account': line.account,
'lines': [],
'sum_debit': [],
'sum_credit': [],
'balance': []
}
res[id_loc][id_]['accounts'].append(account_id)
accounts_id[id_loc][id_][account_id]['lines'].append(line)
accounts_id[id_loc][id_][account_id]['sum_debit'].append(line.debit)
accounts_id[id_loc][id_][account_id]['sum_credit'].append(line.credit)
accounts_id[id_loc][id_][account_id]['balance'].append(line.debit - line.credit)
accounts_id[id_loc]['sum_debit'].append(line.debit)
accounts_id[id_loc]['sum_credit'].append(line.credit)
accounts_id[id_loc]['balance'].append(line.debit - line.credit)
2021-08-10 23:34:05 +02:00
else:
if id_ not in res.keys():
res[id_] = {
'name': name,
'id_number': id_number,
'accounts': [],
}
accounts_id[id_] = {}
2021-08-12 16:06:52 +02:00
# if id_ not in accounts_id.keys():
if account_id not in accounts_id[id_].keys():
2021-08-10 23:34:05 +02:00
accounts_id[id_][account_id] = {
'account': line.account,
'lines': [],
'sum_debit': [],
'sum_credit': [],
'balance': []
}
2021-08-12 16:06:52 +02:00
res[id_]['accounts'].append(account_id)
2020-04-07 15:34:03 +02:00
2021-08-10 23:34:05 +02:00
accounts_id[id_][account_id]['lines'].append(line)
accounts_id[id_][account_id]['sum_debit'].append(line.debit)
accounts_id[id_][account_id]['sum_credit'].append(line.credit)
accounts_id[id_][account_id]['balance'].append(line.debit - line.credit)
report_context['_records'] = res
report_context['_accounts'] = accounts_id
2020-04-07 15:34:03 +02:00
report_context['grouped_by_account'] = data['grouped_by_account']
report_context['grouped_by_location'] = grouped_by_loc
2020-04-07 15:34:03 +02:00
report_context['start_period'] = start_period.name if start_period else '*'
report_context['end_period'] = end_period.name if end_period else '*'
report_context['company'] = company
return report_context
class PrintBalanceSheetCOLGAAPStart(ModelView):
'Print Balance Sheet COLGAAP Start'
__name__ = 'account_col.print_balance_sheet_colgaap.start'
fiscalyear = fields.Many2One('account.fiscalyear', 'Fiscal Year',
help='Leave empty for all open fiscal year', required=True)
posted = fields.Boolean('Posted Moves', help='Show posted moves only')
period = fields.Many2One('account.period', 'Period', domain=[
('fiscalyear', '=', Eval('fiscalyear')),
2021-03-12 22:18:18 +01:00
], depends=['fiscalyear'], required=True)
2020-04-07 15:34:03 +02:00
company = fields.Many2One('company.company', 'Company', required=True)
detailed = fields.Boolean('Detailed')
account_profit = fields.Many2One('account.account',
'Account Profit', domain=[
2021-05-31 19:40:08 +02:00
('type', '!=', None),
2020-04-07 15:34:03 +02:00
('code', 'like', '36%'),
])
@staticmethod
def default_posted():
return False
@staticmethod
def default_company():
return Transaction().context.get('company')
class PrintBalanceSheetCOLGAAP(Wizard):
'Print Balance Sheet COLGAAP'
__name__ = 'account_col.print_balance_sheet_colgaap'
start = StateView('account_col.print_balance_sheet_colgaap.start',
'account_col.print_balance_sheet_colgaap_start_view_form', [
Button('Cancel', 'end', 'tryton-cancel'),
Button('Print', 'print_', 'tryton-print', default=True),
])
print_ = StateReport('account_col.balance_sheet_colgaap')
def do_print_(self, action):
Period = Pool().get('account.period')
account_profit_id = None
ctx = {
'fiscalyear': (self.start.fiscalyear.id
if self.start.fiscalyear else None),
'posted': self.start.posted,
'cumulate': True,
}
if self.start.account_profit:
account_profit_id = self.start.account_profit.id
if self.start.period:
periods = Period.search([
('end_date', '<', self.start.period.start_date),
])
periods_ids = [self.start.period.id]
periods_ids.extend([p.id for p in periods])
ctx['periods'] = periods_ids
action['pyson_context'] = PYSONEncoder().encode(ctx)
period_id = None
if self.start.period:
period_id = self.start.period.id
data = {
'fiscalyear': self.start.fiscalyear.id,
'period': period_id,
'company': self.start.company.id,
'detailed': self.start.detailed,
'posted': self.start.posted,
'account_profit': account_profit_id,
}
return action, data
def transition_print_(self):
return 'end'
class BalanceSheetCOLGAAP(Report):
__name__ = 'account_col.balance_sheet_colgaap'
@classmethod
2021-05-31 19:40:08 +02:00
def get_context(cls, records, header, data):
report_context = super().get_context(records, header, data)
2020-04-07 15:34:03 +02:00
pool = Pool()
Company = pool.get('company.company')
company = Company(data['company'])
codes = ['2', '3']
domain = [
('code', '<', '4'),
]
res = compute_report(data, domain, codes, kind='balance')
report_context.update(res)
report_context['detailed'] = data['detailed']
report_context['company'] = company
report_context['fiscalyear2'] = None
return report_context
class OpenChartAccountStart(metaclass=PoolMeta):
__name__ = 'account.open_chart.start'
period = fields.Many2One('account.period', 'Period',
domain=[
('fiscalyear', '=', Eval('fiscalyear')),
], depends=['fiscalyear'])
@classmethod
def __setup__(cls):
super(OpenChartAccountStart, cls).__setup__()
class OpenChartAccount(metaclass=PoolMeta):
__name__ = 'account.open_chart'
def do_open_(self, action):
Period = Pool().get('account.period')
ctx = {
'posted': self.start.posted,
}
if self.start.period:
periods = Period.search([
('end_date', '<', self.start.period.start_date),
])
periods_ids = [self.start.period.id]
periods_ids.extend([p.id for p in periods])
ctx['periods'] = periods_ids
else:
ctx['fiscalyear'] = self.start.fiscalyear.id
action['pyson_context'] = PYSONEncoder().encode(ctx)
if self.start.fiscalyear:
action['name'] += ' - %s' % self.start.fiscalyear.rec_name
if self.start.posted:
action['name'] += '*'
if self.start.period:
action['name'] += ' - [ %s ]' % self.start.period.name
return action, {}
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_col.print_trial_balance_start_view_form', [
Button('Cancel', 'end', 'tryton-cancel'),
Button('Print', 'print_', 'tryton-print', default=True),
])
print_ = StateReport('account_col.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_col.trial_balance_classic'
@classmethod
2021-05-31 19:40:08 +02:00
def get_context(cls, records, header, data):
report_context = super().get_context(records, header, data)
2020-04-07 15:34:03 +02:00
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']:
2021-05-31 19:40:08 +02:00
dom_accounts.append(('type', '!=', None))
2020-04-07 15:34:03 +02:00
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)
report_context['type_balance'] = data['detailed']
print('----', data['detailed'])
2020-04-07 15:34:03 +02:00
return report_context
@classmethod
def _accounts_view(cls, data, to_remove,
start_accounts, in_accounts, end_accounts):
dict_accounts = OrderedDict()
for start_account, in_account, end_account in izip(
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
])
2021-05-31 19:40:08 +02:00
if start_account.type and empty_account:
2020-04-07 15:34:03 +02:00
continue
2021-05-31 19:40:08 +02:00
if start_account.type is None:
2020-04-07 15:34:03 +02:00
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
2021-05-31 19:40:08 +02:00
if start_account.type and start_account.parent \
2020-04-07 15:34:03 +02:00
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 izip(
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:
2021-02-19 05:44:38 +01:00
amount += Decimal(sum(account[field]))
2020-04-07 15:34:03 +02:00
return amount
class PrintIncomeStatementCOLGAAPStart(ModelView):
'Print Balance Sheet COLGAAP Start'
__name__ = 'account_col.print_income_statement_colgaap.start'
fiscalyear = fields.Many2One('account.fiscalyear', 'Fiscal Year',
help='Leave empty for all open fiscal year', required=True)
posted = fields.Boolean('Posted Moves', help='Show posted moves only')
start_period = fields.Many2One('account.period', 'Start Period',
domain=[
('fiscalyear', '=', Eval('fiscalyear')),
('type', '=', 'standard'),
], depends=['fiscalyear'], required=True)
end_period = fields.Many2One('account.period', 'End Period',
domain=[
('fiscalyear', '=', Eval('fiscalyear')),
('type', '=', 'standard'),
], depends=['fiscalyear'], required=True)
company = fields.Many2One('company.company', 'Company', required=True)
detailed = fields.Boolean('Detailed')
@staticmethod
def default_posted():
return False
@staticmethod
def default_company():
return Transaction().context.get('company')
@fields.depends('fiscalyear')
def on_change_fiscalyear(self):
self.start_period = None
self.end_period = None
@fields.depends('start_period')
def on_change_start_period(self):
self.end_period = self.start_period.id
class PrintIncomeStatementCOLGAAP(Wizard):
'Print Balance Sheet COLGAAP'
__name__ = 'account_col.print_income_statement_colgaap'
start = StateView('account_col.print_income_statement_colgaap.start',
'account_col.print_income_statement_colgaap_start_view_form', [
Button('Cancel', 'end', 'tryton-cancel'),
Button('Print', 'print_', 'tryton-print', default=True),
])
print_ = StateReport('account_col.income_statement_colgaap')
def do_print_(self, action):
Period = Pool().get('account.period')
ctx = {
'fiscalyear': self.start.fiscalyear.id,
'posted': self.start.posted,
'cumulate': True,
}
periods = Period.search([
('start_date', '>=', self.start.start_period.start_date),
('end_date', '<=', self.start.end_period.end_date),
('type', '=', 'standard'),
])
periods_ids = [p.id for p in periods]
ctx['periods'] = periods_ids
action['pyson_context'] = PYSONEncoder().encode(ctx)
data = {
'fiscalyear': self.start.fiscalyear.id,
'periods': periods_ids,
'start_period': self.start.start_period.id,
'end_period': self.start.end_period.id,
'company': self.start.company.id,
'detailed': self.start.detailed,
'posted': self.start.posted,
}
return action, data
def transition_print_(self):
return 'end'
class IncomeStatementCOLGAAP(Report):
__name__ = 'account_col.income_statement_colgaap'
@classmethod
2021-05-31 19:40:08 +02:00
def get_context(cls, records, header, data):
2022-01-20 14:34:46 +01:00
report_context = super().get_context(records, header, data)
2020-04-07 15:34:03 +02:00
pool = Pool()
Company = pool.get('company.company')
Period = pool.get('account.period')
company = Company(data['company'])
codes = ['4', '5', '6', '7']
domain = [
('code', '>=', '4'),
]
res = compute_report(data, domain, codes, kind='income')
report_context.update(res)
report_context['start_period'] = Period(data['start_period'])
report_context['end_period'] = Period(data['end_period'])
report_context['detailed'] = data['detailed']
report_context['company'] = company
report_context['fiscalyear2'] = None
return report_context