You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1075 lines
49 KiB

  1. # -*- encoding: utf-8 -*-
  2. ###########################################################################
  3. # Module Writen to OpenERP, Open Source Management Solution
  4. # Copyright (C) OpenERP Venezuela (<http://openerp.com.ve>).
  5. # All Rights Reserved
  6. # Credits######################################################
  7. # Coded by: Humberto Arocha humberto@openerp.com.ve
  8. # Angelica Barrios angelicaisabelb@gmail.com
  9. # Jordi Esteve <jesteve@zikzakmedia.com>
  10. # Javier Duran <javieredm@gmail.com>
  11. # Planified by: Humberto Arocha
  12. # Finance by: LUBCAN COL S.A.S http://www.lubcancol.com
  13. # Audited by: Humberto Arocha humberto@openerp.com.ve
  14. #############################################################################
  15. # This program is free software: you can redistribute it and/or modify
  16. # it under the terms of the GNU General Public License as published by
  17. # the Free Software Foundation, either version 3 of the License, or
  18. # (at your option) any later version.
  19. #
  20. # This program is distributed in the hope that it will be useful,
  21. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23. # GNU General Public License for more details.
  24. #
  25. # You should have received a copy of the GNU General Public License
  26. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  27. ##############################################################################
  28. #~ import xml
  29. #~ import copy
  30. #~ from operator import itemgetter
  31. import time
  32. #~ import datetime
  33. from report import report_sxw
  34. #~ from tools import config
  35. from tools.translate import _
  36. from osv import osv
  37. #~ from openerp.tools.safe_eval import safe_eval as eval
  38. class account_balance(report_sxw.rml_parse):
  39. def __init__(self, cr, uid, name, context):
  40. super(account_balance, self).__init__(cr, uid, name, context)
  41. self.sum_debit = 0.00
  42. self.sum_credit = 0.00
  43. self.sum_balance = 0.00
  44. self.sum_debit_fy = 0.00
  45. self.sum_credit_fy = 0.00
  46. self.sum_balance_fy = 0.00
  47. self.date_lst = []
  48. self.date_lst_string = ''
  49. self.localcontext.update({
  50. 'time': time,
  51. 'lines': self.lines,
  52. 'get_fiscalyear_text': self.get_fiscalyear_text,
  53. 'get_periods_and_date_text': self.get_periods_and_date_text,
  54. 'get_informe_text': self.get_informe_text,
  55. 'get_month': self.get_month,
  56. 'exchange_name': self.exchange_name,
  57. 'get_vat_by_country': self.get_vat_by_country,
  58. })
  59. self.context = context
  60. def get_vat_by_country(self, form):
  61. """
  62. Return the vat of the partner by country
  63. """
  64. rc_obj = self.pool.get('res.company')
  65. country_code = rc_obj.browse(self.cr, self.uid,
  66. form['company_id'][0]).partner_id.country_id.code or ''
  67. string_vat = rc_obj.browse(self.cr, self.uid,
  68. form['company_id'][0]).partner_id.vat or ''
  69. if string_vat:
  70. if country_code == 'MX':
  71. return '%s' % (string_vat[2:])
  72. elif country_code == 'VE':
  73. return '- %s-%s-%s' % (string_vat[2:3], string_vat[3:11], string_vat[11:12])
  74. else:
  75. return string_vat
  76. else:
  77. return _('\nVAT OF COMPANY NOT AVAILABLE')
  78. def get_fiscalyear_text(self, form):
  79. """
  80. Returns the fiscal year text used on the report.
  81. """
  82. fiscalyear_obj = self.pool.get('account.fiscalyear')
  83. fiscalyear = None
  84. if form.get('fiscalyear'):
  85. fiscalyear = fiscalyear_obj.browse(
  86. self.cr, self.uid, form['fiscalyear'])
  87. return fiscalyear.name or fiscalyear.code
  88. else:
  89. fiscalyear = fiscalyear_obj.browse(
  90. self.cr, self.uid, fiscalyear_obj.find(self.cr, self.uid))
  91. return "%s*" % (fiscalyear.name or fiscalyear.code)
  92. def get_informe_text(self, form):
  93. """
  94. Returns the header text used on the report.
  95. """
  96. afr_id = form['afr_id'] and type(form['afr_id']) in (
  97. list, tuple) and form['afr_id'][0] or form['afr_id']
  98. if afr_id:
  99. name = self.pool.get('afr').browse(self.cr, self.uid, afr_id).name
  100. elif form['analytic_ledger'] and form['columns'] == 'four' and form['inf_type'] == 'BS':
  101. name = _('Analytic Ledger')
  102. elif form['inf_type'] == 'BS':
  103. name = _('Balance Sheet')
  104. elif form['inf_type'] == 'IS':
  105. name = _('Income Statement')
  106. return name
  107. def get_month(self, form):
  108. '''
  109. return day, year and month
  110. '''
  111. if form['filter'] in ['bydate', 'all']:
  112. #~ months = ["Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio",
  113. #~ "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"]
  114. #~ mes = months[time.strptime(form['date_to'], "%Y-%m-%d")[1] - 1]
  115. #~ ano = time.strptime(form['date_to'], "%Y-%m-%d")[0]
  116. #~ dia = time.strptime(form['date_to'], "%Y-%m-%d")[2]
  117. return _('From ') + self.formatLang(form['date_from'], date=True) + _(' to ') + self.formatLang(form['date_to'], date=True)
  118. elif form['filter'] in ['byperiod', 'all']:
  119. aux = []
  120. period_obj = self.pool.get('account.period')
  121. for period in period_obj.browse(self.cr, self.uid, form['periods']):
  122. aux.append(period.date_start)
  123. aux.append(period.date_stop)
  124. sorted(aux)
  125. return _('From ') + self.formatLang(aux[0], date=True) + _(' to ') + self.formatLang(aux[-1], date=True)
  126. def get_periods_and_date_text(self, form):
  127. """
  128. Returns the text with the periods/dates used on the report.
  129. """
  130. form = form or {}
  131. period_obj = self.pool.get('account.period')
  132. fiscalyear_obj = self.pool.get('account.fiscalyear')
  133. periods_str = None
  134. fiscalyear_id = form['fiscalyear'] or fiscalyear_obj.find(self.cr, self.uid)
  135. period_ids = period_obj.search(self.cr, self.uid, [(
  136. 'fiscalyear_id', '=', fiscalyear_id), ('special', '=', False)])
  137. if form['filter'] in ['byperiod', 'all']:
  138. period_ids = form['periods']
  139. periods_str = ', '.join([period.name or period.code for period in period_obj.browse(
  140. self.cr, self.uid, period_ids)])
  141. dates_str = None
  142. if form['filter'] in ['bydate', 'all']:
  143. dates_str = self.formatLang(form[
  144. 'date_from'], date=True) + ' - ' + self.formatLang(form['date_to'], date=True) + ' '
  145. return {'periods': periods_str, 'date': dates_str}
  146. def special_period(self, periods):
  147. period_obj = self.pool.get('account.period')
  148. period_brw = period_obj.browse(self.cr, self.uid, periods)
  149. period_counter = [True for i in period_brw if not i.special]
  150. if not period_counter:
  151. return True
  152. return False
  153. def exchange_name(self, form):
  154. self.from_currency_id = self.get_company_currency(form['company_id'] and type(form[
  155. 'company_id']) in (list, tuple) and form['company_id'][0] or form['company_id'])
  156. if not form['currency_id']:
  157. self.to_currency_id = self.from_currency_id
  158. else:
  159. self.to_currency_id = form['currency_id'] and type(form['currency_id']) in (
  160. list, tuple) and form['currency_id'][0] or form['currency_id']
  161. return self.pool.get('res.currency').browse(self.cr, self.uid, self.to_currency_id).name
  162. def exchange(self, from_amount):
  163. if self.from_currency_id == self.to_currency_id:
  164. return from_amount
  165. curr_obj = self.pool.get('res.currency')
  166. return curr_obj.compute(self.cr, self.uid, self.from_currency_id, self.to_currency_id, from_amount)
  167. def get_company_currency(self, company_id):
  168. rc_obj = self.pool.get('res.company')
  169. return rc_obj.browse(self.cr, self.uid, company_id).currency_id.id
  170. def get_company_accounts(self, company_id, acc='credit'):
  171. rc_obj = self.pool.get('res.company')
  172. if acc == 'credit':
  173. return [brw.id for brw in rc_obj.browse(self.cr, self.uid, company_id).credit_account_ids]
  174. else:
  175. return [brw.id for brw in rc_obj.browse(self.cr, self.uid, company_id).debit_account_ids]
  176. def _get_partner_balance(self, account, init_period, ctx=None):
  177. #~ rp_obj = self.pool.get('res.partner')
  178. res = []
  179. ctx = ctx or {}
  180. if account['type'] in ('other', 'liquidity', 'receivable', 'payable'):
  181. sql_query = """
  182. SELECT
  183. CASE
  184. WHEN aml.partner_id IS NOT NULL
  185. THEN (SELECT name FROM res_partner WHERE aml.partner_id = id)
  186. ELSE 'UNKNOWN'
  187. END AS partner_name,
  188. CASE
  189. WHEN aml.partner_id IS NOT NULL
  190. THEN aml.partner_id
  191. ELSE 0
  192. END AS p_idx,
  193. %s,
  194. %s,
  195. %s,
  196. %s
  197. FROM account_move_line AS aml
  198. INNER JOIN account_account aa ON aa.id = aml.account_id
  199. INNER JOIN account_move am ON am.id = aml.move_id
  200. %s
  201. GROUP BY p_idx, partner_name
  202. """
  203. WHERE_POSTED = ''
  204. if ctx.get('state', 'posted') == 'posted':
  205. WHERE_POSTED = "AND am.state = 'posted'"
  206. cur_periods = ', '.join([str(i) for i in ctx['periods']])
  207. init_periods = ', '.join([str(i) for i in init_period])
  208. WHERE = """
  209. WHERE aml.period_id IN (%s)
  210. AND aa.id = %s
  211. AND aml.state <> 'draft'
  212. """ % (init_periods, account['id'])
  213. query_init = sql_query % ('SUM(aml.debit) AS init_dr',
  214. 'SUM(aml.credit) AS init_cr',
  215. '0.0 AS bal_dr',
  216. '0.0 AS bal_cr',
  217. WHERE + WHERE_POSTED)
  218. WHERE = """
  219. WHERE aml.period_id IN (%s)
  220. AND aa.id = %s
  221. AND aml.state <> 'draft'
  222. """ % (cur_periods, account['id'])
  223. query_bal = sql_query % ('0.0 AS init_dr',
  224. '0.0 AS init_cr',
  225. 'SUM(aml.debit) AS bal_dr',
  226. 'SUM(aml.credit) AS bal_cr',
  227. WHERE + WHERE_POSTED)
  228. query = '''
  229. SELECT
  230. partner_name,
  231. p_idx,
  232. SUM(init_dr)-SUM(init_cr) AS balanceinit,
  233. SUM(bal_dr) AS debit,
  234. SUM(bal_cr) AS credit,
  235. SUM(init_dr) - SUM(init_cr) + SUM(bal_dr) - SUM(bal_cr) AS balance
  236. FROM (
  237. SELECT
  238. *
  239. FROM (%s) vinit
  240. UNION ALL (%s)
  241. ) v
  242. GROUP BY p_idx, partner_name
  243. ORDER BY partner_name
  244. ''' % (query_init, query_bal)
  245. self.cr.execute(query)
  246. res_dict = self.cr.dictfetchall()
  247. unknown = False
  248. for det in res_dict:
  249. i, d, c, b = det['balanceinit'], det[
  250. 'debit'], det['credit'], det['balance'],
  251. if not any([i, d, c, b]):
  252. continue
  253. data = {
  254. 'partner_name': det['partner_name'],
  255. 'balanceinit': i,
  256. 'debit': d,
  257. 'credit': c,
  258. 'balance': b,
  259. }
  260. if not det['p_idx']:
  261. unknown = data
  262. continue
  263. res.append(data)
  264. unknown and res.append(unknown)
  265. return res
  266. def _get_analytic_ledger(self, account, ctx={}):
  267. res = []
  268. if account['type'] in ('other', 'liquidity', 'receivable', 'payable'):
  269. #~ TODO: CUANDO EL PERIODO ESTE VACIO LLENARLO CON LOS PERIODOS DEL EJERCICIO
  270. #~ FISCAL, SIN LOS PERIODOS ESPECIALES
  271. periods = ', '.join([str(i) for i in ctx['periods']])
  272. #~ periods = str(tuple(ctx['periods']))
  273. where = """where aml.period_id in (%s) and aa.id = %s and aml.state <> 'draft'""" % (
  274. periods, account['id'])
  275. if ctx.get('state', 'posted') == 'posted':
  276. where += "AND am.state = 'posted'"
  277. sql_detalle = """select aml.id as id, aj.name as diario, aa.name as descripcion,
  278. (select name from res_partner where aml.partner_id = id) as partner,
  279. aa.code as cuenta, aml.name as name,
  280. aml.ref as ref,
  281. case when aml.debit is null then 0.00 else aml.debit end as debit,
  282. case when aml.credit is null then 0.00 else aml.credit end as credit,
  283. (select code from account_analytic_account where aml.analytic_account_id = id) as analitica,
  284. aml.date as date, ap.name as periodo,
  285. am.name as asiento
  286. from account_move_line aml
  287. inner join account_journal aj on aj.id = aml.journal_id
  288. inner join account_account aa on aa.id = aml.account_id
  289. inner join account_period ap on ap.id = aml.period_id
  290. inner join account_move am on am.id = aml.move_id """ + where +\
  291. """ order by date, am.name"""
  292. self.cr.execute(sql_detalle)
  293. resultat = self.cr.dictfetchall()
  294. balance = account['balanceinit']
  295. for det in resultat:
  296. balance += det['debit'] - det['credit']
  297. res.append({
  298. 'id': det['id'],
  299. 'date': det['date'],
  300. 'journal': det['diario'],
  301. 'partner': det['partner'],
  302. 'name': det['name'],
  303. 'entry': det['asiento'],
  304. 'ref': det['ref'],
  305. 'debit': det['debit'],
  306. 'credit': det['credit'],
  307. 'analytic': det['analitica'],
  308. 'period': det['periodo'],
  309. 'balance': balance,
  310. })
  311. return res
  312. def _get_journal_ledger(self, account, ctx={}):
  313. res = []
  314. am_obj = self.pool.get('account.move')
  315. print 'AM OBJ ', am_obj
  316. if account['type'] in ('other', 'liquidity', 'receivable', 'payable'):
  317. #~ TODO: CUANDO EL PERIODO ESTE VACIO LLENARLO CON LOS PERIODOS DEL EJERCICIO
  318. #~ FISCAL, SIN LOS PERIODOS ESPECIALES
  319. periods = ', '.join([str(i) for i in ctx['periods']])
  320. #~ periods = str(tuple(ctx['periods']))
  321. where = """where aml.period_id in (%s) and aa.id = %s and aml.state <> 'draft'""" % (
  322. periods, account['id'])
  323. if ctx.get('state', 'posted') == 'posted':
  324. where += "AND am.state = 'posted'"
  325. sql_detalle = """SELECT
  326. DISTINCT am.id as am_id,
  327. aj.name as diario,
  328. am.name as name,
  329. am.date as date,
  330. ap.name as periodo
  331. from account_move_line aml
  332. inner join account_journal aj on aj.id = aml.journal_id
  333. inner join account_account aa on aa.id = aml.account_id
  334. inner join account_period ap on ap.id = aml.period_id
  335. inner join account_move am on am.id = aml.move_id """ + where +\
  336. """ order by date, am.name"""
  337. self.cr.execute(sql_detalle)
  338. resultat = self.cr.dictfetchall()
  339. for det in resultat:
  340. res.append({
  341. 'am_id': det['am_id'],
  342. 'journal': det['diario'],
  343. 'name': det['name'],
  344. 'date': det['date'],
  345. 'period': det['periodo'],
  346. 'obj': am_obj.browse(self.cr, self.uid, det['am_id'])
  347. })
  348. print 'ACCOUNT NAME', am_obj.browse(self.cr, self.uid, det['am_id']).name
  349. return res
  350. def lines(self, form, level=0):
  351. """
  352. Returns all the data needed for the report lines
  353. (account info plus debit/credit/balance in the selected period
  354. and the full year)
  355. """
  356. account_obj = self.pool.get('account.account')
  357. period_obj = self.pool.get('account.period')
  358. fiscalyear_obj = self.pool.get('account.fiscalyear')
  359. def _get_children_and_consol(cr, uid, ids, level, context={}, change_sign=False):
  360. aa_obj = self.pool.get('account.account')
  361. ids2 = []
  362. for aa_brw in aa_obj.browse(cr, uid, ids, context):
  363. if aa_brw.child_id and aa_brw.level < level and aa_brw.type != 'consolidation':
  364. if not change_sign:
  365. ids2.append([aa_brw.id, True, False, aa_brw])
  366. ids2 += _get_children_and_consol(cr, uid, [
  367. x.id for x in aa_brw.child_id], level, context, change_sign=change_sign)
  368. if change_sign:
  369. ids2.append(aa_brw.id)
  370. else:
  371. ids2.append([aa_brw.id, False, True, aa_brw])
  372. else:
  373. if change_sign:
  374. ids2.append(aa_brw.id)
  375. else:
  376. ids2.append([aa_brw.id, True, True, aa_brw])
  377. return ids2
  378. #######################################################################
  379. # CONTEXT FOR ENDIND BALANCE #
  380. #######################################################################
  381. def _ctx_end(ctx):
  382. ctx_end = ctx
  383. ctx_end['filter'] = form.get('filter', 'all')
  384. ctx_end['fiscalyear'] = fiscalyear.id
  385. #~ ctx_end['periods'] = period_obj.search(self.cr, self.uid, [('fiscalyear_id','=',fiscalyear.id),('special','=',False)])
  386. if ctx_end['filter'] not in ['bydate', 'none']:
  387. special = self.special_period(form['periods'])
  388. else:
  389. special = False
  390. if form['filter'] in ['byperiod', 'all']:
  391. if special:
  392. ctx_end['periods'] = period_obj.search(self.cr, self.uid, [(
  393. 'id', 'in', form['periods'] or ctx_end.get('periods', False))])
  394. else:
  395. ctx_end['periods'] = period_obj.search(self.cr, self.uid, [('id', 'in', form[
  396. 'periods'] or ctx_end.get('periods', False)), ('special', '=', False)])
  397. if form['filter'] in ['bydate', 'all', 'none']:
  398. ctx_end['date_from'] = form['date_from']
  399. ctx_end['date_to'] = form['date_to']
  400. return ctx_end.copy()
  401. def missing_period(ctx_init):
  402. ctx_init['fiscalyear'] = fiscalyear_obj.search(self.cr, self.uid, [('date_stop', '<', fiscalyear.date_start)], order='date_stop') and \
  403. fiscalyear_obj.search(self.cr, self.uid, [(
  404. 'date_stop', '<', fiscalyear.date_start)], order='date_stop')[-1] or []
  405. ctx_init['periods'] = period_obj.search(self.cr, self.uid, [(
  406. 'fiscalyear_id', '=', ctx_init['fiscalyear']), ('date_stop', '<', fiscalyear.date_start)])
  407. return ctx_init
  408. #######################################################################
  409. # CONTEXT FOR INITIAL BALANCE #
  410. #######################################################################
  411. def _ctx_init(ctx):
  412. ctx_init = self.context.copy()
  413. ctx_init['filter'] = form.get('filter', 'all')
  414. ctx_init['fiscalyear'] = fiscalyear.id
  415. if form['filter'] in ['byperiod', 'all']:
  416. ctx_init['periods'] = form['periods']
  417. if not ctx_init['periods']:
  418. ctx_init = missing_period(ctx_init.copy())
  419. date_start = min([period.date_start for period in period_obj.browse(
  420. self.cr, self.uid, ctx_init['periods'])])
  421. ctx_init['periods'] = period_obj.search(self.cr, self.uid, [(
  422. 'fiscalyear_id', '=', fiscalyear.id), ('date_stop', '<=', date_start)])
  423. elif form['filter'] in ['bydate']:
  424. ctx_init['date_from'] = fiscalyear.date_start
  425. ctx_init['date_to'] = form['date_from']
  426. ctx_init['periods'] = period_obj.search(self.cr, self.uid, [(
  427. 'fiscalyear_id', '=', fiscalyear.id), ('date_stop', '<=', ctx_init['date_to'])])
  428. elif form['filter'] == 'none':
  429. ctx_init['periods'] = period_obj.search(self.cr, self.uid, [(
  430. 'fiscalyear_id', '=', fiscalyear.id), ('special', '=', True)])
  431. date_start = min([period.date_start for period in period_obj.browse(
  432. self.cr, self.uid, ctx_init['periods'])])
  433. ctx_init['periods'] = period_obj.search(self.cr, self.uid, [(
  434. 'fiscalyear_id', '=', fiscalyear.id), ('date_start', '<=', date_start), ('special', '=', True)])
  435. return ctx_init.copy()
  436. def z(n):
  437. return abs(n) < 0.005 and 0.0 or n
  438. self.context['state'] = form['target_move'] or 'posted'
  439. self.from_currency_id = self.get_company_currency(form['company_id'] and type(form[
  440. 'company_id']) in (list, tuple) and form['company_id'][0] or form['company_id'])
  441. if not form['currency_id']:
  442. self.to_currency_id = self.from_currency_id
  443. else:
  444. self.to_currency_id = form['currency_id'] and type(form['currency_id']) in (
  445. list, tuple) and form['currency_id'][0] or form['currency_id']
  446. if 'account_list' in form and form['account_list']:
  447. account_ids = form['account_list']
  448. account_list = form['account_list']
  449. del form['account_list']
  450. credit_account_ids = self.get_company_accounts(form['company_id'] and type(form[
  451. 'company_id']) in (list, tuple) and form['company_id'][0] or form['company_id'], 'credit')
  452. debit_account_ids = self.get_company_accounts(form['company_id'] and type(form[
  453. 'company_id']) in (list, tuple) and form['company_id'][0] or form['company_id'], 'debit')
  454. if form.get('fiscalyear'):
  455. if type(form.get('fiscalyear')) in (list, tuple):
  456. fiscalyear = form['fiscalyear'] and form['fiscalyear'][0]
  457. elif type(form.get('fiscalyear')) in (int,):
  458. fiscalyear = form['fiscalyear']
  459. fiscalyear = fiscalyear_obj.browse(self.cr, self.uid, fiscalyear)
  460. ################################################################
  461. # Get the accounts #
  462. ################################################################
  463. all_account_ids = _get_children_and_consol(
  464. self.cr, self.uid, account_ids, 100, self.context)
  465. account_ids = _get_children_and_consol(self.cr, self.uid, account_ids, form[
  466. 'display_account_level'] and form['display_account_level'] or 100, self.context)
  467. credit_account_ids = _get_children_and_consol(
  468. self.cr, self.uid, credit_account_ids, 100, self.context, change_sign=True)
  469. debit_account_ids = _get_children_and_consol(
  470. self.cr, self.uid, debit_account_ids, 100, self.context, change_sign=True)
  471. credit_account_ids = list(set(
  472. credit_account_ids) - set(debit_account_ids))
  473. #
  474. # Generate the report lines (checking each account)
  475. #
  476. tot_check = False
  477. if not form['periods']:
  478. form['periods'] = period_obj.search(self.cr, self.uid, [(
  479. 'fiscalyear_id', '=', fiscalyear.id), ('special', '=', False)], order='date_start asc')
  480. if not form['periods']:
  481. raise osv.except_osv(_('UserError'), _(
  482. 'The Selected Fiscal Year Does not have Regular Periods'))
  483. if form['columns'] == 'qtr':
  484. period_ids = period_obj.search(self.cr, self.uid, [(
  485. 'fiscalyear_id', '=', fiscalyear.id), ('special', '=', False)], order='date_start asc')
  486. a = 0
  487. l = []
  488. p = []
  489. for x in period_ids:
  490. a += 1
  491. if a < 3:
  492. l.append(x)
  493. else:
  494. l.append(x)
  495. p.append(l)
  496. l = []
  497. a = 0
  498. tot_bal1 = 0.0
  499. tot_bal2 = 0.0
  500. tot_bal3 = 0.0
  501. tot_bal4 = 0.0
  502. tot_bal5 = 0.0
  503. elif form['columns'] == 'thirteen':
  504. period_ids = period_obj.search(self.cr, self.uid, [(
  505. 'fiscalyear_id', '=', fiscalyear.id), ('special', '=', False)], order='date_start asc')
  506. tot_bal1 = 0.0
  507. tot_bal1 = 0.0
  508. tot_bal2 = 0.0
  509. tot_bal3 = 0.0
  510. tot_bal4 = 0.0
  511. tot_bal5 = 0.0
  512. tot_bal6 = 0.0
  513. tot_bal7 = 0.0
  514. tot_bal8 = 0.0
  515. tot_bal9 = 0.0
  516. tot_bal10 = 0.0
  517. tot_bal11 = 0.0
  518. tot_bal12 = 0.0
  519. tot_bal13 = 0.0
  520. else:
  521. ctx_end = _ctx_end(self.context.copy())
  522. tot_bin = 0.0
  523. tot_deb = 0.0
  524. tot_crd = 0.0
  525. tot_ytd = 0.0
  526. tot_eje = 0.0
  527. res = {}
  528. result_acc = []
  529. tot = {}
  530. ###############################################################
  531. # Calculations of credit, debit and balance,
  532. # without repeating operations.
  533. ###############################################################
  534. account_black_ids = account_obj.search(self.cr, self.uid, (
  535. [('id', 'in', [i[0] for i in all_account_ids]),
  536. ('type', 'not in',
  537. ('view', 'consolidation'))]))
  538. account_not_black_ids = account_obj.search(self.cr, self.uid, ([('id', 'in', [
  539. i[0] for i in all_account_ids]), ('type', '=', 'view')]))
  540. acc_cons_ids = account_obj.search(self.cr, self.uid, ([('id', 'in', [
  541. i[0] for i in all_account_ids]), ('type', 'in', ('consolidation',))]))
  542. account_consol_ids = acc_cons_ids and account_obj._get_children_and_consol(
  543. self.cr, self.uid, acc_cons_ids) or []
  544. account_black_ids += account_obj.search(self.cr, self.uid, (
  545. [('id', 'in', account_consol_ids),
  546. ('type', 'not in',
  547. ('view', 'consolidation'))]))
  548. account_black_ids = list(set(account_black_ids))
  549. c_account_not_black_ids = account_obj.search(self.cr, self.uid, ([
  550. ('id', 'in',
  551. account_consol_ids),
  552. ('type', '=', 'view')]))
  553. delete_cons = False
  554. if c_account_not_black_ids:
  555. delete_cons = set(account_not_black_ids) & set(
  556. c_account_not_black_ids) and True or False
  557. account_not_black_ids = list(
  558. set(account_not_black_ids) - set(c_account_not_black_ids))
  559. # This could be done quickly with a sql sentence
  560. account_not_black = account_obj.browse(
  561. self.cr, self.uid, account_not_black_ids)
  562. account_not_black.sort(key=lambda x: x.level)
  563. account_not_black.reverse()
  564. account_not_black_ids = [i.id for i in account_not_black]
  565. c_account_not_black = account_obj.browse(
  566. self.cr, self.uid, c_account_not_black_ids)
  567. c_account_not_black.sort(key=lambda x: x.level)
  568. c_account_not_black.reverse()
  569. c_account_not_black_ids = [i.id for i in c_account_not_black]
  570. if delete_cons:
  571. account_not_black_ids = c_account_not_black_ids + \
  572. account_not_black_ids
  573. account_not_black = c_account_not_black + account_not_black
  574. else:
  575. acc_cons_brw = account_obj.browse(
  576. self.cr, self.uid, acc_cons_ids)
  577. acc_cons_brw.sort(key=lambda x: x.level)
  578. acc_cons_brw.reverse()
  579. acc_cons_ids = [i.id for i in acc_cons_brw]
  580. account_not_black_ids = c_account_not_black_ids + \
  581. acc_cons_ids + account_not_black_ids
  582. account_not_black = c_account_not_black + \
  583. acc_cons_brw + account_not_black
  584. all_account_period = {} # All accounts per period
  585. # Iteration limit depending on the number of columns
  586. if form['columns'] == 'thirteen':
  587. limit = 13
  588. elif form['columns'] == 'qtr':
  589. limit = 5
  590. else:
  591. limit = 1
  592. for p_act in range(limit):
  593. if limit != 1:
  594. if p_act == limit - 1:
  595. form['periods'] = period_ids
  596. else:
  597. if form['columns'] == 'thirteen':
  598. form['periods'] = [period_ids[p_act]]
  599. elif form['columns'] == 'qtr':
  600. form['periods'] = p[p_act]
  601. if form['inf_type'] == 'IS':
  602. ctx_to_use = _ctx_end(self.context.copy())
  603. else:
  604. ctx_i = _ctx_init(self.context.copy())
  605. ctx_to_use = _ctx_end(self.context.copy())
  606. account_black = account_obj.browse(
  607. self.cr, self.uid, account_black_ids, ctx_to_use)
  608. if form['inf_type'] == 'BS':
  609. account_black_init = account_obj.browse(
  610. self.cr, self.uid, account_black_ids, ctx_i)
  611. #~ Black
  612. dict_black = {}
  613. for i in account_black:
  614. d = i.debit
  615. c = i.credit
  616. dict_black[i.id] = {
  617. 'obj': i,
  618. 'debit': d,
  619. 'credit': c,
  620. 'balance': d - c
  621. }
  622. if form['inf_type'] == 'BS':
  623. dict_black.get(i.id)['balanceinit'] = 0.0
  624. # If the report is a balance sheet
  625. # Balanceinit values are added to the dictionary
  626. if form['inf_type'] == 'BS':
  627. for i in account_black_init:
  628. dict_black.get(i.id)['balanceinit'] = i.balance
  629. #~ Not black
  630. dict_not_black = {}
  631. for i in account_not_black:
  632. dict_not_black[i.id] = {
  633. 'obj': i, 'debit': 0.0, 'credit': 0.0, 'balance': 0.0}
  634. if form['inf_type'] == 'BS':
  635. dict_not_black.get(i.id)['balanceinit'] = 0.0
  636. all_account = dict_black.copy(
  637. ) # It makes a copy because they modify
  638. for acc_id in account_not_black_ids:
  639. acc_childs = dict_not_black.get(acc_id).get('obj').type == 'view' \
  640. and dict_not_black.get(acc_id).get('obj').child_id \
  641. or dict_not_black.get(acc_id).get('obj').child_consol_ids
  642. for child_id in acc_childs:
  643. if child_id.type == 'consolidation' and delete_cons:
  644. continue
  645. dict_not_black.get(acc_id)['debit'] += all_account.get(
  646. child_id.id).get('debit')
  647. dict_not_black.get(acc_id)['credit'] += all_account.get(
  648. child_id.id).get('credit')
  649. dict_not_black.get(acc_id)['balance'] += all_account.get(
  650. child_id.id).get('balance')
  651. if form['inf_type'] == 'BS':
  652. dict_not_black.get(acc_id)['balanceinit'] += all_account.get(
  653. child_id.id).get('balanceinit')
  654. all_account[acc_id] = dict_not_black[acc_id]
  655. if p_act == limit - 1:
  656. all_account_period['all'] = all_account
  657. else:
  658. if form['columns'] == 'thirteen':
  659. all_account_period[p_act] = all_account
  660. elif form['columns'] == 'qtr':
  661. all_account_period[p_act] = all_account
  662. ###############################################################
  663. # End of the calculations of credit, debit and balance
  664. #
  665. ###############################################################
  666. for aa_id in account_ids:
  667. id = aa_id[0]
  668. if aa_id[3].type == 'consolidation' and delete_cons:
  669. continue
  670. #
  671. # Check if we need to include this level
  672. #
  673. if not form['display_account_level'] or aa_id[3].level <= form['display_account_level']:
  674. res = {
  675. 'id': id,
  676. 'type': aa_id[3].type,
  677. 'code': aa_id[3].code,
  678. 'name': (aa_id[2] and not aa_id[1]) and 'TOTAL %s' % (aa_id[3].name.upper()) or aa_id[3].name,
  679. 'parent_id': aa_id[3].parent_id and aa_id[3].parent_id.id,
  680. 'level': aa_id[3].level,
  681. 'label': aa_id[1],
  682. 'total': aa_id[2],
  683. 'change_sign': credit_account_ids and (id in credit_account_ids and -1 or 1) or 1
  684. }
  685. if form['columns'] == 'qtr':
  686. for pn in range(1, 5):
  687. if form['inf_type'] == 'IS':
  688. d, c, b = map(z, [
  689. all_account_period.get(pn - 1).get(id).get('debit', 0.0), all_account_period.get(pn - 1).get(id).get('credit', 0.0), all_account_period.get(pn - 1).get(id).get('balance', 0.0)])
  690. res.update({
  691. 'dbr%s' % pn: self.exchange(d),
  692. 'cdr%s' % pn: self.exchange(c),
  693. 'bal%s' % pn: self.exchange(b),
  694. })
  695. else:
  696. i, d, c = map(z, [
  697. all_account_period.get(pn - 1).get(id).get('balanceinit', 0.0), all_account_period.get(pn - 1).get(id).get('debit', 0.0), all_account_period.get(pn - 1).get(id).get('credit', 0.0)])
  698. b = z(i + d - c)
  699. res.update({
  700. 'dbr%s' % pn: self.exchange(d),
  701. 'cdr%s' % pn: self.exchange(c),
  702. 'bal%s' % pn: self.exchange(b),
  703. })
  704. if form['inf_type'] == 'IS':
  705. d, c, b = map(z, [
  706. all_account_period.get('all').get(id).get('debit', 0.0), all_account_period.get('all').get(id).get('credit', 0.0), all_account_period.get('all').get(id).get('balance')])
  707. res.update({
  708. 'dbr5': self.exchange(d),
  709. 'cdr5': self.exchange(c),
  710. 'bal5': self.exchange(b),
  711. })
  712. else:
  713. i, d, c = map(z, [
  714. all_account_period.get('all').get(id).get('balanceinit', 0.0), all_account_period.get('all').get(id).get('debit', 0.0), all_account_period.get('all').get(id).get('credit', 0.0)])
  715. b = z(i + d - c)
  716. res.update({
  717. 'dbr5': self.exchange(d),
  718. 'cdr5': self.exchange(c),
  719. 'bal5': self.exchange(b),
  720. })
  721. elif form['columns'] == 'thirteen':
  722. pn = 1
  723. for p_num in range(12):
  724. if form['inf_type'] == 'IS':
  725. d, c, b = map(z, [
  726. all_account_period.get(p_num).get(id).get('debit', 0.0), all_account_period.get(p_num).get(id).get('credit', 0.0), all_account_period.get(p_num).get(id).get('balance', 0.0)])
  727. res.update({
  728. 'dbr%s' % pn: self.exchange(d),
  729. 'cdr%s' % pn: self.exchange(c),
  730. 'bal%s' % pn: self.exchange(b),
  731. })
  732. else:
  733. i, d, c = map(z, [
  734. all_account_period.get(p_num).get(id).get('balanceinit', 0.0), all_account_period.get(p_num).get(id).get('debit', 0.0), all_account_period.get(p_num).get(id).get('credit', 0.0)])
  735. b = z(i + d - c)
  736. res.update({
  737. 'dbr%s' % pn: self.exchange(d),
  738. 'cdr%s' % pn: self.exchange(c),
  739. 'bal%s' % pn: self.exchange(b),
  740. })
  741. pn += 1
  742. if form['inf_type'] == 'IS':
  743. d, c, b = map(z, [
  744. all_account_period.get('all').get(id).get('debit', 0.0), all_account_period.get('all').get(id).get('credit', 0.0), all_account_period.get('all').get(id).get('balance', 0.0)])
  745. res.update({
  746. 'dbr13': self.exchange(d),
  747. 'cdr13': self.exchange(c),
  748. 'bal13': self.exchange(b),
  749. })
  750. else:
  751. i, d, c = map(z, [
  752. all_account_period.get('all').get(id).get('balanceinit', 0.0), all_account_period.get('all').get(id).get('debit', 0.0), all_account_period.get('all').get(id).get('credit', 0.0)])
  753. b = z(i + d - c)
  754. res.update({
  755. 'dbr13': self.exchange(d),
  756. 'cdr13': self.exchange(c),
  757. 'bal13': self.exchange(b),
  758. })
  759. else:
  760. i, d, c = map(z, [
  761. all_account_period.get('all').get(id).get('balanceinit', 0.0), all_account_period.get('all').get(id).get('debit', 0.0), all_account_period.get('all').get(id).get('credit', 0.0)])
  762. b = z(i + d - c)
  763. res.update({
  764. 'balanceinit': self.exchange(i),
  765. 'debit': self.exchange(d),
  766. 'credit': self.exchange(c),
  767. 'ytd': self.exchange(d - c),
  768. })
  769. if form['inf_type'] == 'IS' and form['columns'] == 'one':
  770. res.update({
  771. 'balance': self.exchange(d - c),
  772. })
  773. else:
  774. res.update({
  775. 'balance': self.exchange(b),
  776. })
  777. #
  778. # Check whether we must include this line in the report or not
  779. #
  780. to_include = False
  781. if form['columns'] in ('thirteen', 'qtr'):
  782. to_test = [False]
  783. if form['display_account'] == 'mov' and aa_id[3].parent_id:
  784. # Include accounts with movements
  785. for x in range(pn - 1):
  786. to_test.append(res.get(
  787. 'dbr%s' % x, 0.0) >= 0.005 and True or False)
  788. to_test.append(res.get(
  789. 'cdr%s' % x, 0.0) >= 0.005 and True or False)
  790. if any(to_test):
  791. to_include = True
  792. elif form['display_account'] == 'bal' and aa_id[3].parent_id:
  793. # Include accounts with balance
  794. for x in range(pn - 1):
  795. to_test.append(res.get(
  796. 'bal%s' % x, 0.0) >= 0.005 and True or False)
  797. if any(to_test):
  798. to_include = True
  799. elif form['display_account'] == 'bal_mov' and aa_id[3].parent_id:
  800. # Include accounts with balance or movements
  801. for x in range(pn - 1):
  802. to_test.append(res.get(
  803. 'bal%s' % x, 0.0) >= 0.005 and True or False)
  804. to_test.append(res.get(
  805. 'dbr%s' % x, 0.0) >= 0.005 and True or False)
  806. to_test.append(res.get(
  807. 'cdr%s' % x, 0.0) >= 0.005 and True or False)
  808. if any(to_test):
  809. to_include = True
  810. else:
  811. # Include all accounts
  812. to_include = True
  813. else:
  814. if form['display_account'] == 'mov' and aa_id[3].parent_id:
  815. # Include accounts with movements
  816. if abs(d) >= 0.005 or abs(c) >= 0.005:
  817. to_include = True
  818. elif form['display_account'] == 'bal' and aa_id[3].parent_id:
  819. # Include accounts with balance
  820. if abs(b) >= 0.005:
  821. to_include = True
  822. elif form['display_account'] == 'bal_mov' and aa_id[3].parent_id:
  823. # Include accounts with balance or movements
  824. if abs(b) >= 0.005 or abs(d) >= 0.005 or abs(c) >= 0.005:
  825. to_include = True
  826. else:
  827. # Include all accounts
  828. to_include = True
  829. #~ ANALYTIC LEDGER
  830. if to_include and form['analytic_ledger'] and form['columns'] == 'four' and form['inf_type'] == 'BS' and res['type'] in ('other', 'liquidity', 'receivable', 'payable'):
  831. res['mayor'] = self._get_analytic_ledger(res, ctx=ctx_end)
  832. elif to_include and form['journal_ledger'] and form['columns'] == 'four' and form['inf_type'] == 'BS' and res['type'] in ('other', 'liquidity', 'receivable', 'payable'):
  833. res['journal'] = self._get_journal_ledger(res, ctx=ctx_end)
  834. elif to_include and form['partner_balance'] and form['columns'] == 'four' and form['inf_type'] == 'BS' and res['type'] in ('other', 'liquidity', 'receivable', 'payable'):
  835. res['partner'] = self._get_partner_balance(
  836. res, ctx_i['periods'], ctx=ctx_end)
  837. else:
  838. res['mayor'] = []
  839. if to_include:
  840. result_acc.append(res)
  841. #
  842. # Check whether we must sumarize this line in the report or not
  843. #
  844. if form['tot_check'] and (res['id'] in account_list) and (res['id'] not in tot):
  845. if form['columns'] == 'qtr':
  846. tot_check = True
  847. tot[res['id']] = True
  848. tot_bal1 += res.get('bal1', 0.0)
  849. tot_bal2 += res.get('bal2', 0.0)
  850. tot_bal3 += res.get('bal3', 0.0)
  851. tot_bal4 += res.get('bal4', 0.0)
  852. tot_bal5 += res.get('bal5', 0.0)
  853. elif form['columns'] == 'thirteen':
  854. tot_check = True
  855. tot[res['id']] = True
  856. tot_bal1 += res.get('bal1', 0.0)
  857. tot_bal2 += res.get('bal2', 0.0)
  858. tot_bal3 += res.get('bal3', 0.0)
  859. tot_bal4 += res.get('bal4', 0.0)
  860. tot_bal5 += res.get('bal5', 0.0)
  861. tot_bal6 += res.get('bal6', 0.0)
  862. tot_bal7 += res.get('bal7', 0.0)
  863. tot_bal8 += res.get('bal8', 0.0)
  864. tot_bal9 += res.get('bal9', 0.0)
  865. tot_bal10 += res.get('bal10', 0.0)
  866. tot_bal11 += res.get('bal11', 0.0)
  867. tot_bal12 += res.get('bal12', 0.0)
  868. tot_bal13 += res.get('bal13', 0.0)
  869. else:
  870. tot_check = True
  871. tot[res['id']] = True
  872. tot_bin += res['balanceinit']
  873. tot_deb += res['debit']
  874. tot_crd += res['credit']
  875. tot_ytd += res['ytd']
  876. tot_eje += res['balance']
  877. if tot_check:
  878. str_label = form['lab_str']
  879. res2 = {
  880. 'type': 'view',
  881. 'name': 'TOTAL %s' % (str_label),
  882. 'label': False,
  883. 'total': True,
  884. }
  885. if form['columns'] == 'qtr':
  886. res2.update(dict(
  887. bal1=z(tot_bal1),
  888. bal2=z(tot_bal2),
  889. bal3=z(tot_bal3),
  890. bal4=z(tot_bal4),
  891. bal5=z(tot_bal5),))
  892. elif form['columns'] == 'thirteen':
  893. res2.update(dict(
  894. bal1=z(tot_bal1),
  895. bal2=z(tot_bal2),
  896. bal3=z(tot_bal3),
  897. bal4=z(tot_bal4),
  898. bal5=z(tot_bal5),
  899. bal6=z(tot_bal6),
  900. bal7=z(tot_bal7),
  901. bal8=z(tot_bal8),
  902. bal9=z(tot_bal9),
  903. bal10=z(tot_bal10),
  904. bal11=z(tot_bal11),
  905. bal12=z(tot_bal12),
  906. bal13=z(tot_bal13),))
  907. else:
  908. res2.update({
  909. 'balanceinit': tot_bin,
  910. 'debit': tot_deb,
  911. 'credit': tot_crd,
  912. 'ytd': tot_ytd,
  913. 'balance': tot_eje,
  914. })
  915. result_acc.append(res2)
  916. return result_acc
  917. report_sxw.report_sxw('report.afr.1cols',
  918. 'wizard.report',
  919. 'account_financial_report/report/balance_full.rml',
  920. parser=account_balance,
  921. header=False)
  922. report_sxw.report_sxw('report.afr.2cols',
  923. 'wizard.report',
  924. 'account_financial_report/report/balance_full_2_cols.rml',
  925. parser=account_balance,
  926. header=False)
  927. report_sxw.report_sxw('report.afr.4cols',
  928. 'wizard.report',
  929. 'account_financial_report/report/balance_full_4_cols.rml',
  930. parser=account_balance,
  931. header=False)
  932. report_sxw.report_sxw('report.afr.analytic.ledger',
  933. 'wizard.report',
  934. 'account_financial_report/report/balance_full_4_cols_analytic_ledger.rml',
  935. parser=account_balance,
  936. header=False)
  937. report_sxw.report_sxw('report.afr.partner.balance',
  938. 'wizard.report',
  939. 'account_financial_report/report/balance_full_4_cols_partner_balance.rml',
  940. parser=account_balance,
  941. header=False)
  942. report_sxw.report_sxw('report.afr.journal.ledger',
  943. 'wizard.report',
  944. 'account_financial_report/report/balance_full_4_cols_journal_ledger.rml',
  945. parser=account_balance,
  946. header=False)
  947. report_sxw.report_sxw('report.afr.5cols',
  948. 'wizard.report',
  949. 'account_financial_report/report/balance_full_5_cols.rml',
  950. parser=account_balance,
  951. header=False)
  952. report_sxw.report_sxw('report.afr.qtrcols',
  953. 'wizard.report',
  954. 'account_financial_report/report/balance_full_qtr_cols.rml',
  955. parser=account_balance,
  956. header=False)
  957. report_sxw.report_sxw('report.afr.13cols',
  958. 'wizard.report',
  959. 'account_financial_report/report/balance_full_13_cols.rml',
  960. parser=account_balance,
  961. header=False)