trytonpsk-account_col/account.py

2736 lines
100 KiB
Python

# 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, timedelta
from timeit import default_timer as timer
import operator
from sql import Null
from sql.aggregate import Sum
from sql.conditionals import Coalesce
from collections import OrderedDict
from itertools import groupby
try:
from itertools import izip
except ImportError:
izip = zip
from trytond.i18n import gettext
from trytond.model import ModelView, ModelSQL, fields
from trytond.wizard import Wizard, StateView, Button, StateReport
from trytond.report import Report
from trytond.pyson import Eval, Bool, PYSONEncoder, If
from trytond.transaction import Transaction
from trytond.pool import Pool, PoolMeta
from trytond.exceptions import UserError
from .exceptions import (BadOperationError, DontWriteAccountError)
_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'],
'colgaap': data['colgaap'],
}
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(
('type', '=', None),
)
view_accounts = Account.search(domain)
reduce_ids = [a.id for a in view_accounts if len(a.code) <= len_code]
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
class Account(ModelSQL, ModelView):
__name__ = 'account.account'
cashflow = fields.Many2One('account.account.cashflow', 'Cashflow',
ondelete="RESTRICT", states={
'invisible': ~Bool(Eval('type')),
},
domain=[
('company', '=', Eval('company')),
], depends=['type', 'company'])
classification = fields.Selection([
('', ''),
('ifrs', 'Ifrs'),
('colgaap', 'Colgaap'),
], 'Classification')
@classmethod
def __setup__(cls):
super(Account, cls).__setup__()
fields_names = [
'name', 'template_override', 'party_required', 'type',
]
cls._check_modify_exclude = fields_names
@classmethod
def copy(cls, records, default=None):
raise BadOperationError(gettext('account_col.msg_bad_operation'))
return super(Account, cls).copy(records, default=default)
@fields.depends('type')
def on_change_with_deferral(self, name=None):
return (self.type
and self.type.statement in {'balance', 'off-balance', 'income'})
@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):
if vlist.get('type') and vlist.get('code') and vlist['code'][0] in ['4', '5', '6', '7']:
vlist['party_required'] = True
# fields_modify = list(set(vlist.keys()) - set(cls._check_modify_exclude))
# if len(fields_modify) > 0:
# cls.check_account_to_write(records)
return super(Account, cls).write(records, vlist)
@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)])
if account.type and lines:
raise DontWriteAccountError(
gettext('account_col.msg_dont_write_account',
account=account.rec_name))
class Type(metaclass=PoolMeta):
'Account Type'
__name__ = 'account.account.type'
debit = fields.Function(fields.Numeric('Amount',
digits=(16, Eval('currency_digits', 2)), depends=['currency_digits']),
'get_debit_credit', 'search_debit_credit')
credit = fields.Function(fields.Numeric('Amount',
digits=(16, Eval('currency_digits', 2)), depends=['currency_digits']),
'get_debit_credit', 'search_debit_credit')
@classmethod
def get_debit_credit(cls, types, name):
pool = Pool()
Account = pool.get('account.account')
# GeneralLedger = pool.get('account.general_ledger.account')
context = Transaction().context
res = {}
for type_ in types:
res[type_.id] = Decimal('0.0')
childs = cls.search([
('parent', 'child_of', [t.id for t in types]),
])
type_sum = {}
for type_ in childs:
type_sum[type_.id] = Decimal('0.0')
with Transaction().set_context(context):
accounts = Account.search([
('type', 'in', [t.id for t in childs]),
])
if name == 'debit':
for account in accounts:
balance = account.debit
type_sum[account.type.id] += balance
else:
for account in accounts:
balance = account.credit
type_sum[account.type.id] += balance
for type_ in types:
childs = cls.search([
('parent', 'child_of', [type_.id]),
])
for child in childs:
res[type_.id] += type_sum[child.id]
exp = Decimal(str(10.0 ** -type_.currency_digits))
res[type_.id] = res[type_.id].quantize(exp)
# if type_.statement == 'balance' and type_.assets:
# res[type_.id] = - res[type_.id]
return res
@classmethod
def search_debit_credit(cls, name, domain):
pool = Pool()
Account = pool.get('account.account')
context = Transaction().context
with Transaction().set_context(context):
accounts = Account.search([], order=[])
_, operator_, operand = domain
operator_ = {
'=': operator.eq,
'>=': operator.ge,
'>': operator.gt,
'<=': operator.le,
'<': operator.lt,
'!=': operator.ne,
'in': lambda v, l: v in l,
'not in': lambda v, l: v not in l,
}.get(operator_, lambda v, l: False)
ids = [a.id for a in accounts
if operator_(getattr(a, name), operand)]
return [('id', 'in', ids)]
# @classmethod
# def get_amount_cmp(cls, types, name):
# transaction = Transaction()
# current = transaction.context
# if not current.get('comparison'):
# return dict.fromkeys([t.id for t in types], None)
# new = {}
# for key, value in current.items():
# if key.endswith('_cmp'):
# new[key[:-4]] = value
# with transaction.set_context(new):
# return cls.get_amount(types, name)
class AuxiliaryBookStart(ModelView):
'Auxiliary Book Start'
__name__ = 'account_col.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')
colgaap = fields.Boolean('Colgaap')
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),
]
)
print_ = StateReport('account_col.auxiliary_book')
def _search_records(self):
pass
def do_print_(self, action):
try:
start_period = self.start.start_period.id
except:
start_period = None
try:
end_period = self.start.end_period.id
except:
end_period = None
try:
party = self.start.party.id
except:
party = None
try:
start_account_id = self.start.start_account.id
except:
start_account_id = None
try:
end_account_id = self.start.end_account.id
except:
end_account_id = None
data = {
'ids': [],
'company': self.start.company.id,
'fiscalyear': self.start.fiscalyear.id,
'start_period': start_period,
'end_period': end_period,
'posted': self.start.posted,
'colgaap': self.start.colgaap,
'start_account': start_account_id,
'end_account': end_account_id,
'party': party,
'empty_account': self.start.empty_account,
'reference': self.start.reference,
'fiscalyearname': self.start.fiscalyear.name
}
return action, data
def transition_print_(self):
return 'end'
class AuxiliaryBook(Report):
__name__ = 'account_col.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'],
colgaap=data['colgaap']):
start_accounts = Account.browse(accounts)
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'],
colgaap=['colgaap']):
end_accounts = Account.browse(accounts)
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'],
data['reference'], data['colgaap']))
accounts_ = account2lines.keys()
with Transaction().set_context(
party=data['party'],
posted=data['posted'],
colgaap=['colgaap']):
accounts = Account.browse([a for a in accounts_ids if a in accounts_])
account_id2lines = cls.lines(accounts,
list(set(end_periods).difference(set(start_periods))),
data['posted'], data['party'], data['reference'], data['colgaap'])
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
return report_context
@classmethod
def get_lines(cls, accounts, periods, posted, party=None, reference=None, colgaap=False):
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 + '%'))
if colgaap:
clause.append(['OR', ('move.method', '=', 'colgaap'), ('move.method', 'in', [None, ''])])
else:
clause.append(['OR', ('move.method', '=', 'ifrs'), ('move.method', 'in', [None, ''])])
lines = MoveLine.search_read(clause,
order=[
('account', 'ASC'),
('date', 'ASC'),
], fields_names=[
'description', 'move.number', 'account', 'debit',
'credit', 'reference', 'date', 'party.name', 'party.id_number',
'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, reference=None, colgaap=False):
res = dict((a.id, []) for a in accounts)
account2lines = cls.get_lines(accounts, periods, posted, party, reference, colgaap)
for account_id, lines in account2lines:
balance = _ZERO
rec_append = res[account_id].append
for line in lines:
line['move'] = line['move.']['number']
balance += line['debit'] - line['credit']
if line['party.']:
line['party'] = line['party.']['name']
line['party_id'] = line['party.']['id_number']
if line['move_origin.']:
line['origin'] = line['move_origin.']['rec_name']
line['balance'] = balance
rec_append(line)
return res
class PrintTrialBalanceDetailedStart(ModelView):
'Print Trial Balance Detailed'
__name__ = 'account_col.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'))
],
states={'invisible': Eval('by_dates', False)},
depends=['end_period', 'fiscalyear'])
end_period = fields.Many2One('account.period', 'End Period',
domain=[
('fiscalyear', '=', Eval('fiscalyear')),
('start_date', '>=', (Eval('start_period'), 'start_date'))
],
states={'invisible': Eval('by_dates', False)},
depends=['start_period', 'fiscalyear'])
party = fields.Many2One('party.party', 'Party')
accounts = fields.Many2Many('account.account', None, None, 'Accounts',
domain=[
('type', '!=', None),
])
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')
colgaap = fields.Boolean('Colgaap')
by_dates = fields.Boolean('By Dates',
help='Filter accounts by dates')
from_date = fields.Date("From Date",
domain=[
If(Eval('to_date') & Eval('from_date'),
('from_date', '<=', Eval('to_date')),
()),
],
states={
'invisible': ~Eval('by_dates', False),
'required': Eval('by_dates', False)
},
depends=['to_date', 'start_period', 'end_period'])
to_date = fields.Date("To Date",
domain=[
If(Eval('from_date') & Eval('to_date'),
('to_date', '>=', Eval('from_date')),
()),
],
states={
'invisible': ~Eval('by_dates', False),
'required': Eval('by_dates', False)
},
depends=['from_date', 'start_period', 'end_period'])
@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
@fields.depends('by_dates')
def on_change_by_dates(self):
if self.by_dates:
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,
'colgaap': self.start.colgaap,
'from_date': self.start.from_date,
'to_date': self.start.to_date,
'by_dates': self.start.by_dates,
}
return action, data
def transition_print_(self):
return 'end'
class TrialBalanceDetailed(Report):
__name__ = 'account_col.trial_balance_detailed'
@classmethod
def get_context(cls, records, header, data):
report_context = super().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
start_period_ids, in_period_ids = None, None
if not data['by_dates']:
# ----- Set 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)))
start_period_ids = [p.id for p in start_periods]
in_period_ids = [p.id for p in end_periods]
# Select Query for In
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,
)
if data['by_dates']:
select1.where = (move.date <= data['to_date']) & (move.date >= data['from_date'])
else:
select1.where = (join1.right.period.in_(in_period_ids))
if data['party']:
select1.where = select1.where & (line.party == data['party'])
if data['accounts']:
select1.where = select1.where & (line.account.in_(data['accounts']))
if data['posted']:
select1.where = select1.where & (move.state == 'posted')
if data['colgaap']:
select1.where = select1.where & ((move.method == 'colgaap') | (move.method == Null))
else:
select1.where = select1.where & ((move.method == 'ifrs') | (move.method == Null))
cursor.execute(*select1)
result_in = cursor.fetchall()
# Select Query for Start
result_start = []
if start_period_ids or data['from_date']:
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,
)
if data['from_date']:
select2.where = (move.date >= data['from_date'])
else:
select2.where = (join1.right.period.in_(start_period_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=['id_number', '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]
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 BalanceSheetComparisionContext(metaclass=PoolMeta):
'Balance Sheet Context'
__name__ = 'account.balance_sheet.comparision.context'
colgaap = fields.Boolean('Colgaap')
class BalanceSheetContext(metaclass=PoolMeta):
'Balance Sheet Context'
__name__ = 'account.balance_sheet.context'
colgaap = fields.Boolean('Colgaap')
# class BalanceSheetContextCol(BalanceSheetContext):
# 'Balance Sheet Context'
# __name__ = 'account.balance_sheet.col.context'
# utility_temp = fields.Boolean('Utility Temp',
# help='Permited see the utility without have any account move')
class BalanceSheet(Report):
'Balance Sheet Report'
__name__ = 'account.balance_sheet'
@classmethod
def get_context(cls, records, header, data):
report_context = super().get_context(records, header, data)
Company = Pool().get('company.company')
context = Transaction().context
if not context.get('context_model') == 'account.balance_sheet.comparision.context':
raise UserError(
gettext('''Error: debe imprimir el reporte desde
Contabilidad/Informes/Balance de Situacion'''))
report_context['company'] = Company(context.get('company'))
report_context['date'] = context.get('date')
report_context['comparison'] = context.get('comparison')
report_context['date_cmp'] = context.get('date_cmp')
report_context['colgaap'] = context.get('colgaap')
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 BalanceSheetDetail(Report):
# 'Balance Sheet Detail Report'
# __name__ = 'account.balance_sheet_report'
# @classmethod
# def get_context(cls, records, header, data):
# report_context = super().get_context(records, header, data)
# context = Transaction().context
# pool = Pool()
# Company = pool.get('company.company')
# Account = pool.get('account.account')
# Period = pool.get('account.period')
# Type = pool.get('account.account.type')
# GeneralLedger = pool.get('account.general_ledger.account')
# context_model = context.get('context_model')
# if context_model == 'account.income_statement.context':
# statement = 'income'
# else:
# statement = 'balance'
# from_date = None
# to_date = None
# period_ids = None
# if context.get('start_period') or context.get('end_period'):
# start_period_ids = GeneralLedger.get_period_ids('start_%s' % statement)
# end_period_ids = GeneralLedger.get_period_ids('end_%s' % statement)
# period_ids = list(
# set(end_period_ids).difference(set(start_period_ids)))
# else:
# to_date = date(context.get('date').year - 1, 12, 31)
# from_date = to_date
# context['periods'] = period_ids
# context['from_date'] = from_date
# context['to_date'] = to_date
# with Transaction().set_context(context):
# types_final = Type.search(
# [('statement', '=', statement)],
# order=[('sequence', 'ASC')])
# new_context = {
# 'date': to_date,
# 'colgaap': context.get('colgaap'),
# 'posted': context.get('posted'),
# }
# with Transaction().set_context(new_context):
# types_initial = Type.search(
# [('statement', '=', statement)],
# order=[('sequence', 'ASC')])
# types = OrderedDict()
# type_ids = []
# type_ids_append = type_ids.append
# for t1, t2 in izip(types_initial, types_final):
# if not t1.childs:
# type_ids_append(t1.id)
# types[t1] = {
# 'name': t1.name,
# 'start_balance': t1.amount,
# 'end_balance': t2.amount,
# 'debit': t2.debit,
# 'credit': t2.credit,
# 'accounts': []
# }
# domain = [
# ('type', 'in', type_ids),
# ('closed', '!=', True)
# ]
# with Transaction().set_context(context):
# accounts_initial = Account.search(domain,
# order=[('code', 'ASC'), ('name', 'ASC')])
# with Transaction().set_context(new_context):
# accounts_final = Account.search(domain,
# order=[('code', 'ASC'), ('name', 'ASC')])
# for ac_in, ac_fin in izip(accounts_initial, accounts_final):
# types[ac_in.type]['accounts'].extend([{
# 'code': ac_in.code,
# 'name': ac_in.name,
# 'start_balance': ac_in.balance,
# 'debit': ac_fin.debit,
# 'credit': ac_fin.credit,
# 'end_balance': ac_fin.balance,
# }])
# report_context['company'] = Company(context.get('company'))
# report_context['date'] = context.get('date')
# report_context['types'] = types.values()
# return report_context
class IncomeStatement(Report):
'Income Statement'
__name__ = 'account.income_statement'
@classmethod
def get_context(cls, records, header, data):
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
report_context = super().get_context(records, header, data)
if not context.get('context_model') == 'account.income_statement.context':
raise UserError(
gettext('''Error: debe imprimir el reporte desde
Contabilidad/Informes/Estado de Resultado Integral'''))
# context_fields = Context.fields_get(['start_period', 'fiscalyear'])
types = Type.search([
('statement', '=', 'income')
])
accounts_types = []
company_id = context.get('company')
records = Type(report_context['data']['id'])
fiscalyear_id = context.get('fiscalyear')
fiscalyear_cmp = context.get('fiscalyear_cmp')
start_period = context.get('start_period')
start_period_cmp = context.get('start_period_cmp')
end_period = context.get('end_period')
end_period_cmp = context.get('end_period_cmp')
comparison = context.get('comparison')
colgaap = context.get('colgaap')
if start_period:
start_period = Period(start_period)
if end_period:
end_period = Period(end_period)
dom_periods = [
('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, colgaap=colgaap):
while types:
type_ = types.pop()
type_dict = {'type': type_, 'accounts': []}
if type_.statement == 'income':
accounts = Account.search([
('type', '=', type_.id),
])
if accounts:
# setattr(type_, 'accounts', accounts)
type_dict = {'type': type_, 'accounts': accounts}
accounts_types.append((type_.sequence, type_dict))
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['type'].childs:
if c.id not in types_added:
childs.append(od[c.sequence])
types_added.extend([v['type'].id, c.id])
# setattr(v, 'childs', childs)
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 if fiscalyear_id else ''
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',
ondelete="RESTRICT")
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)
@staticmethod
def order_sequence(tables):
table, _ = tables[None]
return [table.sequence is None, table.sequence]
@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',
add_remove=[], domain=[('type', '!=', None)])
@classmethod
def __setup__(cls):
super(Cashflow, cls).__setup__()
cls._order.insert(0, ('sequence', 'ASC'))
@classmethod
def validate(cls, cashflows):
super(Cashflow, cls).validate(cashflows)
@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):
if self.company and self.company.currency:
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]),
('type', '!=', None),
])
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
def get_context(cls, records, header, data):
report_context = super().get_context(records, header, data)
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')
classification = fields.Selection('selection_certificate_type',
'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'])
detailed = fields.Boolean('Detailed', help='Detailed the registers when applied tax')
@staticmethod
def default_company():
return Transaction().context.get('company')
@classmethod
def selection_certificate_type(cls):
Tax = Pool().get('account.tax')
sel = Tax.classification.selection
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,
'classification': self.start.classification,
'start_period': start_period,
'end_period': end_period,
'detailed': self.start.detailed,
}
return action, data
class PartyWithholding(Report):
__name__ = 'account_col.party_withholding'
@classmethod
def get_context(cls, records, header, data):
report_context = super().get_context(records, header, data)
cursor = Transaction().connection.cursor()
pool = Pool()
# InvoiceTax = pool.get('account.invoice.tax')
Tax = pool.get('account.tax')
MoveLine = pool.get('account.move.line')
Move = pool.get('account.move')
Account = pool.get('account.account')
Company = pool.get('company.company')
Period = pool.get('account.period')
Fiscalyear = pool.get('account.fiscalyear')
Party = pool.get('party.party')
company = Company(data['company'])
move = Move.__table__()
line = MoveLine.__table__()
tax = Tax.__table__()
account = Account.__table__()
where = tax.classification != Null
if data['party']:
where &= line.party == data['party']
else:
where &= line.party != Null
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]
where &= move.period.in_(period_ids)
if data['classification']:
where &= tax.classification == data['classification']
if data['detailed']:
columns= [
line.party,
tax.classification,
tax.id.as_('tax_id'),
tax.rate,
account.name.as_('account'),
tax.description,
move.date,
line.id.as_('line_id'),
(line.debit-line.credit).as_('amount'),
line.move
]
query = tax.join(line, condition=((tax.credit_note_account==line.account) or (tax.invoice_account==line.account))
).join(move, condition=line.move == move.id
).join(account, condition=line.account == account.id
).select(*columns,
where=where,
order_by=[line.party, tax.classification, line.create_date.asc])
records, move_ids = cls.query_to_dict_detailed(query)
moves = Move.search_read([('id', 'in', move_ids)], fields_names=['origin.rec_name'])
moves_ = {}
for v in moves:
try:
moves_[v['id']]= v['origin.']['rec_name']
except:
moves_[v['id']]=None
report_context['moves'] = moves_
else:
columns= [
line.party,
tax.classification,
tax.id.as_('tax_id'),
tax.rate,
account.name.as_('account'),
tax.description,
Sum(line.debit-line.credit).as_('amount'),
]
query = tax.join(line, condition=((tax.credit_note_account==line.account) or (tax.invoice_account==line.account))
).join(move, condition=line.move == move.id
).join(account, condition=line.account == account.id
).select(*columns,
where=where,
group_by=[line.party, tax.classification, tax.id, tax.rate, account.name, tax.description],
order_by=[line.party, tax.classification])
records = cls.query_to_dict(query)
# move.origin.name,
report_context['records'] = records.values()
report_context['detailed'] = data['detailed']
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
@classmethod
def query_to_dict_detailed(cls, query):
cursor = Transaction().connection.cursor()
Party = Pool().get('party.party')
cursor.execute(*query)
columns = list(cursor.description)
result = cursor.fetchall()
res_dict = {}
moves_ids = set()
for row in result:
row_dict = {}
key_id = str(row[0])+row[1]
for i, col in enumerate(columns):
row_dict[col.name] = row[i]
row_dict['base'] = row[8] / row[3] * (-1)
try:
res_dict[key_id]['taxes_with'].append(row_dict)
res_dict[key_id]['total_amount'] += row_dict['amount']
res_dict[key_id]['total_untaxed'] += row_dict['base']
moves_ids.add(row_dict['move'])
except:
res_dict[key_id] = {
'party': Party(row[0]),
'tax_type': row_dict['classification'],
'taxes_with': [row_dict],
'total_amount': row_dict['amount'],
'total_untaxed': row_dict['base']
}
moves_ids.add(row_dict['move'])
return res_dict, moves_ids
@classmethod
def query_to_dict(cls, query):
cursor = Transaction().connection.cursor()
Party = Pool().get('party.party')
cursor.execute(*query)
columns = list(cursor.description)
result = cursor.fetchall()
res_dict = {}
for row in result:
row_dict = {}
key_id = str(row[0])+row[1]+str(row[3])
for i, col in enumerate(columns):
row_dict[col.name] = row[i]
row_dict['base'] = row[6] / row[3] * (-1)
try:
res_dict[key_id]['amount'] += row_dict['amount']
res_dict[key_id]['base'] += row_dict['base']
except:
res_dict[key_id] = {
'party': Party(row[0]),
'tax_type': row_dict['classification'],
'account': row_dict['account'],
'description': row_dict['description'],
'amount': row_dict['amount'],
'base': row_dict['base']
}
return res_dict
class AccountConfiguration(ModelSQL, ModelView):
__name__ = 'account.configuration'
equivalent_invoice_sec = fields.Many2One('ir.sequence',
'Equivalent Invoice', domain=[
('code', '=', 'account.invoice')
])
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")
difference_in_exchange = fields.Many2One("account.move.reconcile.write_off", 'Difference in Exchange')
@classmethod
def __register__(cls, module_name):
super().__register__(module_name)
table_h = cls.__table_handler__(module_name)
# version 6.0: remove account_debit_writeoff, account_credit_writeoff
table_h.drop_column('account_debit_writeoff')
table_h.drop_column('account_credit_writeoff')
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=[
('type', '!=', None),
])
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
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,
}
return action, data
def transition_print_(self):
return 'end'
class AuxiliaryParty(Report):
__name__ = 'account_col.auxiliary_party'
@classmethod
def get_context(cls, records, header, data):
report_context = super().get_context(records, header, data)
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')
], fields_names=['id'],
)
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 = {}
accounts_id = {}
grouped_by_loc = False
if lines:
for line in lines:
if not line.party:
continue
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
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,
'sum_debit': [],
'sum_credit': [],
'balance': []
}
if id_ not in res[id_loc].keys():
res[id_loc][id_] = {
'name': name,
'id_number': id_number,
'accounts': [],
}
accounts_id[id_loc][id_] = {}
if account_id not in accounts_id[id_loc][id_].keys():
accounts_id[id_loc][id_][account_id] = {
'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)
else:
if id_ not in res.keys():
res[id_] = {
'name': name,
'id_number': id_number,
'accounts': [],
}
accounts_id[id_] = {}
# if id_ not in accounts_id.keys():
if account_id not in accounts_id[id_].keys():
accounts_id[id_][account_id] = {
'account': line.account,
'lines': [],
'sum_debit': [],
'sum_credit': [],
'balance': []
}
res[id_]['accounts'].append(account_id)
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
report_context['grouped_by_account'] = data['grouped_by_account']
report_context['grouped_by_location'] = grouped_by_loc
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')),
], depends=['fiscalyear'], required=True)
company = fields.Many2One('company.company', 'Company', required=True)
detailed = fields.Boolean('Detailed')
colgaap = fields.Boolean('Colgaap')
account_profit = fields.Many2One('account.account',
'Account Profit', domain=[
('type', '!=', None),
('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,
'colgaap': self.start.colgaap,
'account_profit': account_profit_id,
}
return action, data
def transition_print_(self):
return 'end'
class BalanceSheetCOLGAAP(Report):
__name__ = 'account_col.balance_sheet_colgaap'
@classmethod
def get_context(cls, records, header, data):
report_context = super().get_context(records, header, data)
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'))
],
states={'invisible': Eval('by_dates', False)},
depends=['end_period', 'fiscalyear'])
end_period = fields.Many2One('account.period', 'End Period',
domain=[
('fiscalyear', '=', Eval('fiscalyear')),
('start_date', '>=', (Eval('start_period'), 'start_date'))
],
states={'invisible': Eval('by_dates', False)},
depends=['start_period', 'fiscalyear'])
company = fields.Many2One('company.company', 'Company', required=True)
posted = fields.Boolean('Posted Move', help='Show only posted move')
colgaap = fields.Boolean('Colgaap')
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')
by_dates = fields.Boolean('By Dates',
help='Filter accounts by dates')
from_date = fields.Date("From Date",
domain=[
If(Eval('to_date') & Eval('from_date'),
('from_date', '<=', Eval('to_date')),
()),
],
states={
'invisible': ~Eval('by_dates', False),
'required': Eval('by_dates', False)
},
depends=['to_date', 'start_period', 'end_period'])
to_date = fields.Date("To Date",
domain=[
If(Eval('from_date') & Eval('to_date'),
('to_date', '>=', Eval('from_date')),
()),
],
states={
'invisible': ~Eval('by_dates', False),
'required': Eval('by_dates', False)
},
depends=['from_date', 'start_period', 'end_period'])
@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
@staticmethod
def default_by_dates():
return False
@fields.depends('fiscalyear')
def on_change_fiscalyear(self):
self.start_period = None
self.end_period = None
@fields.depends('by_dates')
def on_change_by_dates(self):
if self.by_dates:
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,
'colgaap': self.start.colgaap,
'empty_account': self.start.empty_account,
'accounts_with_balance': self.start.accounts_with_balance,
'detailed': self.start.detailed,
'from_date': self.start.from_date,
'to_date': self.start.to_date,
'by_dates': self.start.by_dates
}
return action, data
def transition_print_(self):
return 'end'
class TrialBalanceClassic(Report):
__name__ = 'account_col.trial_balance_classic'
@classmethod
def get_context(cls, records, header, data):
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')
Fiscalyear = pool.get('account.fiscalyear')
Type = pool.get('account.account.type')
company = Company(data['company'])
dom_accounts = [
('company', '=', data['company']),
('code', '!=', None),
]
if not data['detailed'] or not data['colgaap']:
dom_accounts.append(('type', '!=', None))
types = None
if data['detailed'] and not data['colgaap']:
types_, = Type.search([('parent', '=', None)])
types = []
types_append = types.append
def get_types(type_, exclude=False):
if not exclude:
types_append(type_)
for t in type_.childs:
get_types(t)
for t in types_.childs:
get_types(t, exclude=True)
accounts = Account.search(dom_accounts)
start_period_ids, end_period_ids = None, None
from_date, to_date = None, None
if not data['by_dates']:
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]
from_date_ = start_period.start_date
else:
from_date = data['from_date']
to_date = data['to_date']
to_date_ = (from_date or from_date_) - timedelta(days=1)
print(to_date_, 'fhfjd')
with Transaction().set_context(
fiscalyear=data['fiscalyear'],
periods=start_period_ids,
date=to_date_,
posted=data['posted'],
colgaap=data['colgaap']
):
start_accounts = Account.browse(accounts)
if types:
with Transaction().set_context(to_date=to_date_):
start_types = Type.browse(types)
with Transaction().set_context(
fiscalyear=None,
periods=end_period_ids,
from_date=from_date,
to_date=to_date,
posted=data['posted'],
colgaap=data['colgaap']):
in_accounts = Account.browse(accounts)
if types:
in_types = Type.browse(types)
all_periods = None
if not data['by_dates']:
all_periods = start_period_ids + end_period_ids
with Transaction().set_context(
fiscalyear=data['fiscalyear'],
periods=all_periods,
to_date=to_date,
posted=data['posted'],
colgaap=data['colgaap']):
end_accounts = Account.browse(accounts)
if types:
to_date = to_date or end_period.end_date
with Transaction().set_context(to_date=to_date):
end_types = Type.browse(types)
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:
if data['colgaap']:
accounts = cls._accounts_view(data, to_remove,
start_accounts, in_accounts, end_accounts)
else:
accounts = cls._accounts_view_niif(data, to_remove,
start_accounts, in_accounts, end_accounts,
start_types, in_types, end_types)
if not data['by_dates']:
periods = end_periods
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['accounts'] = accounts
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']
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
])
if start_account.type and empty_account:
continue
if start_account.type is None:
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 Exception:
pass
if start_account.type 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_view_niif(cls, data, to_remove, start_accounts, in_accounts,
end_accounts, start_types, in_types, end_types):
accounts = []
accounts_append = accounts.append
types = OrderedDict()
for start_type, in_type, end_type in izip(start_types, in_types, end_types):
if start_type.statement == 'balance' and start_type.assets:
start_balance = start_type.amount
end_balance = end_type.amount
else:
start_balance = start_type.amount * -1
end_balance = end_type.amount * -1
types[start_type] = {
'code': '',
'name': start_type.name,
'start_balance': [start_balance],
'end_balance': [end_balance],
'debit': [in_type.debit],
'credit': [in_type.credit],
'accounts': []
}
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
])
if not data['empty_account'] and empty_account:
continue
types[start_account.type]['accounts'].extend([{
'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],
}])
for type_ in list(types.values()):
accounts_ = type_.pop('accounts')
accounts_append(type_)
for ac in accounts_:
accounts_append(ac)
return accounts
@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:
if account['code'] != '':
amount += Decimal(sum(account[field]))
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')
colgaap = fields.Boolean('Colgaap')
@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,
'colgaap': self.start.colgaap,
'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,
'colgaap': self.start.colgaap,
}
return action, data
def transition_print_(self):
return 'end'
class IncomeStatementCOLGAAP(Report):
__name__ = 'account_col.income_statement_colgaap'
@classmethod
def get_context(cls, records, header, data):
report_context = super().get_context(records, header, data)
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
class GeneralLedgerAccountContext(metaclass=PoolMeta):
'General Ledger Account Context'
__name__ = 'account.general_ledger.account.context'
colgaap = fields.Boolean('Colgaap')
class IncomeStatementContext(metaclass=PoolMeta):
'Income Statement Context'
__name__ = 'account.income_statement.context'
colgaap = fields.Boolean('Colgaap')