2736 lines
100 KiB
Python
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')
|