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.

1241 lines
53 KiB

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