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.

404 lines
19 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. class account_balance(report_sxw.rml_parse):
  37. def __init__(self, cr, uid, name, context):
  38. super(account_balance, self).__init__(cr, uid, name, context)
  39. self.sum_debit = 0.00
  40. self.sum_credit = 0.00
  41. self.sum_balance = 0.00
  42. self.sum_debit_fy = 0.00
  43. self.sum_credit_fy = 0.00
  44. self.sum_balance_fy = 0.00
  45. self.date_lst = []
  46. self.date_lst_string = ''
  47. self.localcontext.update({
  48. 'time': time,
  49. 'lines': self.lines,
  50. 'get_fiscalyear_text': self.get_fiscalyear_text,
  51. 'get_periods_and_date_text': self.get_periods_and_date_text,
  52. 'get_informe_text': self.get_informe_text,
  53. 'get_month':self.get_month,
  54. 'exchange_name':self.exchange_name,
  55. })
  56. self.context = context
  57. def get_fiscalyear_text(self, form):
  58. """
  59. Returns the fiscal year text used on the report.
  60. """
  61. fiscalyear_obj = self.pool.get('account.fiscalyear')
  62. fiscalyear = None
  63. if form.get('fiscalyear'):
  64. fiscalyear = fiscalyear_obj.browse(self.cr, self.uid, form['fiscalyear'])
  65. return fiscalyear.name or fiscalyear.code
  66. else:
  67. fiscalyear = fiscalyear_obj.browse(self.cr, self.uid, fiscalyear_obj.find(self.cr, self.uid))
  68. return "%s*" % (fiscalyear.name or fiscalyear.code)
  69. def get_informe_text(self, form):
  70. """
  71. Returns the header text used on the report.
  72. """
  73. inf_type = {
  74. 'bgen' : ' Balance General',
  75. 'bcom' : ' Balance de Comprobacion',
  76. 'edogp': 'Estado de Ganancias y Perdidas',
  77. 'bml': 'Libro Mayor Legal',
  78. 'bdl' : 'Diario Legal'
  79. }
  80. return inf_type[form['inf_type']]
  81. def get_month(self, form):
  82. '''
  83. return day, year and month
  84. '''
  85. if form['filter'] in ['bydate', 'all']:
  86. months=["Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre"]
  87. mes = months[time.strptime(form['date_to'],"%Y-%m-%d")[1]-1]
  88. ano = time.strptime(form['date_to'],"%Y-%m-%d")[0]
  89. dia = time.strptime(form['date_to'],"%Y-%m-%d")[2]
  90. return 'Período del '+self.formatLang(form['date_from'], date=True)+' al '+self.formatLang(form['date_to'], date=True)
  91. elif form['filter'] in ['byperiod', 'all']:
  92. aux=[]
  93. period_obj = self.pool.get('account.period')
  94. for period in period_obj.browse(self.cr, self.uid, form['periods']):
  95. aux.append(period.date_start)
  96. aux.append(period.date_stop)
  97. sorted(aux)
  98. return _('Período del ')+self.formatLang(aux[0], date=True)+_(' al ')+self.formatLang(aux[-1], date=True)
  99. def get_periods_and_date_text(self, form):
  100. """
  101. Returns the text with the periods/dates used on the report.
  102. """
  103. period_obj = self.pool.get('account.period')
  104. periods_str = None
  105. fiscalyear_id = form['fiscalyear'] or fiscalyear_obj.find(self.cr, self.uid)
  106. period_ids = period_obj.search(self.cr, self.uid, [('fiscalyear_id','=',fiscalyear_id),('special','=',False)])
  107. if form['filter'] in ['byperiod', 'all']:
  108. period_ids = form['periods']
  109. periods_str = ', '.join([period.name or period.code for period in period_obj.browse(self.cr, self.uid, period_ids)])
  110. dates_str = None
  111. if form['filter'] in ['bydate', 'all']:
  112. dates_str = self.formatLang(form['date_from'], date=True) + ' - ' + self.formatLang(form['date_to'], date=True) + ' '
  113. return {'periods':periods_str, 'date':dates_str}
  114. def special_period(self, periods):
  115. period_obj = self.pool.get('account.period')
  116. period_brw = period_obj.browse(self.cr, self.uid, periods)
  117. period_counter = [True for i in period_brw if not i.special]
  118. if not period_counter:
  119. return True
  120. return False
  121. def exchange_name(self, form):
  122. self.from_currency_id = self.get_company_currency(form['company_id'] and type(form['company_id']) in (list,tuple) and form['company_id'][0] or form['company_id'])
  123. if not form['currency_id']:
  124. self.to_currency_id = self.from_currency_id
  125. else:
  126. self.to_currency_id = form['currency_id'] and type(form['currency_id']) in (list, tuple) and form['currency_id'][0] or form['currency_id']
  127. return self.pool.get('res.currency').browse(self.cr, self.uid, self.to_currency_id).name
  128. def exchange(self, from_amount):
  129. if self.from_currency_id == self.to_currency_id:
  130. return from_amount
  131. curr_obj = self.pool.get('res.currency')
  132. return curr_obj.compute(self.cr, self.uid, self.from_currency_id, self.to_currency_id, from_amount)
  133. def get_company_currency(self, company_id):
  134. rc_obj = self.pool.get('res.company')
  135. return rc_obj.browse(self.cr, self.uid, company_id).currency_id.id
  136. def get_company_credit_accounts(self, company_id):
  137. rc_obj = self.pool.get('res.company')
  138. return [brw.id for brw in rc_obj.browse(self.cr, self.uid, company_id).credit_account_ids]
  139. def lines(self, form, level=0):
  140. """
  141. Returns all the data needed for the report lines
  142. (account info plus debit/credit/balance in the selected period
  143. and the full year)
  144. """
  145. self.from_currency_id = self.get_company_currency(form['company_id'] and type(form['company_id']) in (list,tuple) and form['company_id'][0] or form['company_id'])
  146. if not form['currency_id']:
  147. self.to_currency_id = self.from_currency_id
  148. else:
  149. self.to_currency_id = form['currency_id'] and type(form['currency_id']) in (list, tuple) and form['currency_id'][0] or form['currency_id']
  150. tot_check = False
  151. tot_bin = 0.0
  152. tot_deb = 0.0
  153. tot_crd = 0.0
  154. tot_eje = 0.0
  155. if form.has_key('account_list') and form['account_list']:
  156. account_ids = form['account_list']
  157. del form['account_list']
  158. credit_account_ids = self.get_company_credit_accounts(form['company_id'] and type(form['company_id']) in (list,tuple) and form['company_id'][0] or form['company_id'])
  159. print 'Primer print de credit_account_ids ', credit_account_ids
  160. res = {}
  161. result_acc = []
  162. accounts_levels = {}
  163. account_obj = self.pool.get('account.account')
  164. period_obj = self.pool.get('account.period')
  165. fiscalyear_obj = self.pool.get('account.fiscalyear')
  166. if form.get('fiscalyear'):
  167. if type(form.get('fiscalyear')) in (list,tuple):
  168. fiscalyear = form['fiscalyear'] and form['fiscalyear'][0]
  169. elif type(form.get('fiscalyear')) in (int,):
  170. fiscalyear = form['fiscalyear']
  171. fiscalyear = fiscalyear_obj.browse(self.cr, self.uid, fiscalyear)
  172. #
  173. # Get the accounts
  174. #
  175. def _get_children_and_consol(cr, uid, ids, level, context={},change_sign=False):
  176. aa_obj = self.pool.get('account.account')
  177. ids2=[]
  178. for aa_brw in aa_obj.browse(cr, uid, ids, context):
  179. if aa_brw.child_id and aa_brw.level < level and aa_brw.type !='consolidation':
  180. if not change_sign:
  181. ids2.append([aa_brw.id,True, False])
  182. ids2 += _get_children_and_consol(cr, uid, [x.id for x in aa_brw.child_id], level, context,change_sign=change_sign)
  183. if change_sign:
  184. ids2.append(aa_brw.id)
  185. else:
  186. ids2.append([aa_brw.id,False,True])
  187. else:
  188. if change_sign:
  189. ids2.append(aa_brw.id)
  190. else:
  191. ids2.append([aa_brw.id,True,True])
  192. return ids2
  193. account_ids = _get_children_and_consol(self.cr, self.uid, account_ids, form['display_account_level'] and form['display_account_level'] or 100,self.context)
  194. credit_account_ids = _get_children_and_consol(self.cr, self.uid, credit_account_ids, 100,self.context,change_sign=True)
  195. print 'credit_account_ids ', credit_account_ids
  196. account_obj = self.pool.get('account.account')
  197. period_obj = self.pool.get('account.period')
  198. fiscalyear_obj = self.pool.get('account.fiscalyear')
  199. #############################################################################
  200. # Calculate the period Debit/Credit #
  201. # (from the selected period or all the non special periods in the fy) #
  202. #############################################################################
  203. ctx = self.context.copy()
  204. ctx['filter'] = form.get('filter','all')
  205. ctx['fiscalyear'] = fiscalyear.id
  206. #~ ctx['periods'] = period_obj.search(self.cr, self.uid, [('fiscalyear_id','=',fiscalyear.id),('special','=',False)])
  207. if ctx['filter'] not in ['bydate','none']:
  208. special = self.special_period(form['periods'])
  209. else:
  210. special = False
  211. if form['filter'] in ['byperiod', 'all']:
  212. if special:
  213. ctx['periods'] = period_obj.search(self.cr, self.uid, [('id','in',form['periods'] or ctx.get('periods',False))])
  214. else:
  215. ctx['periods'] = period_obj.search(self.cr, self.uid, [('id','in',form['periods'] or ctx.get('periods',False)),('special','=',False)])
  216. if form['filter'] in ['bydate','all','none']:
  217. ctx['date_from'] = form['date_from']
  218. ctx['date_to'] = form['date_to']
  219. accounts=[]
  220. val = account_obj.browse(self.cr, self.uid, [aa_id[0] for aa_id in account_ids], ctx)
  221. c = 0
  222. for aa_id in account_ids:
  223. new_acc = {
  224. 'id' :val[c].id,
  225. 'type' :val[c].type,
  226. 'code' :val[c].code,
  227. 'name' :val[c].name,
  228. 'debit' :val[c].debit,
  229. 'credit' :val[c].credit,
  230. 'parent_id' :val[c].parent_id and val[c].parent_id.id,
  231. 'level' :val[c].level,
  232. 'label' :aa_id[1],
  233. 'total' :aa_id[2],
  234. }
  235. c += 1
  236. accounts.append(new_acc)
  237. def missing_period():
  238. ctx['fiscalyear'] = fiscalyear_obj.search(self.cr, self.uid, [('date_stop','<',fiscalyear.date_start)],order='date_stop') and \
  239. fiscalyear_obj.search(self.cr, self.uid, [('date_stop','<',fiscalyear.date_start)],order='date_stop')[-1] or []
  240. ctx['periods'] = period_obj.search(self.cr, self.uid, [('fiscalyear_id','=',ctx['fiscalyear']),('date_stop','<',fiscalyear.date_start)])
  241. #############################################################################
  242. # Calculate the period initial Balance #
  243. # (fy balance minus the balance from the start of the selected period #
  244. # to the end of the year) #
  245. #############################################################################
  246. ctx = self.context.copy()
  247. ctx['filter'] = form.get('filter','all')
  248. ctx['fiscalyear'] = fiscalyear.id
  249. if form['filter'] in ['byperiod', 'all']:
  250. ctx['periods'] = form['periods']
  251. date_start = min([period.date_start for period in period_obj.browse(self.cr, self.uid, ctx['periods'])])
  252. ctx['periods'] = period_obj.search(self.cr, self.uid, [('fiscalyear_id','=',fiscalyear.id),('date_stop','<=',date_start)])
  253. if not ctx['periods']:
  254. missing_period()
  255. elif form['filter'] in ['bydate']:
  256. ctx['date_from'] = fiscalyear.date_start
  257. ctx['date_to'] = form['date_from']
  258. ctx['periods'] = period_obj.search(self.cr, self.uid, [('fiscalyear_id','=',fiscalyear.id),('date_stop','<=',ctx['date_to'])])
  259. elif form['filter'] == 'none':
  260. ctx['periods'] = period_obj.search(self.cr, self.uid, [('fiscalyear_id','=',fiscalyear.id),('special','=',True)])
  261. date_start = min([period.date_start for period in period_obj.browse(self.cr, self.uid, ctx['periods'])])
  262. ctx['periods'] = period_obj.search(self.cr, self.uid, [('fiscalyear_id','=',fiscalyear.id),('date_start','<=',date_start),('special','=',True)])
  263. period_balanceinit = {}
  264. for acc in account_obj.browse(self.cr, self.uid, [x[0] for x in account_ids], ctx):
  265. if special:
  266. period_balanceinit[acc['id']] = 0.0
  267. else:
  268. period_balanceinit[acc['id']] = acc.balance
  269. #
  270. # Generate the report lines (checking each account)
  271. #
  272. tot = {}
  273. for account in accounts:
  274. account_id = account['id']
  275. accounts_levels[account_id] = account['level']
  276. #
  277. # Check if we need to include this level
  278. #
  279. if not form['display_account_level'] or account['level'] <= form['display_account_level']:
  280. #
  281. # Copy the account values
  282. #
  283. res = {
  284. 'id' : account_id,
  285. 'type' : account['type'],
  286. 'code': account['code'],
  287. 'name': (account['total'] and not account['label']) and 'TOTAL %s'%(account['name'].upper()) or account['name'],
  288. 'level': account['level'],
  289. 'balanceinit': self.exchange(period_balanceinit[account_id]),
  290. 'debit': self.exchange(account['debit']),
  291. 'credit': self.exchange(account['credit']),
  292. 'balance': self.exchange(period_balanceinit[account_id]+account['debit']-account['credit']),
  293. 'parent_id': account['parent_id'],
  294. 'bal_type': '',
  295. 'label': account['label'],
  296. 'total': account['total'],
  297. 'change_sign' : credit_account_ids and (account_id in credit_account_ids and -1 or 1) or 1
  298. }
  299. #
  300. # Round the values to zero if needed (-0.000001 ~= 0)
  301. #
  302. if abs(res['balance']) < 0.5 * 10**-4:
  303. res['balance'] = 0.0
  304. #
  305. # Check whether we must include this line in the report or not
  306. #
  307. if form['display_account'] == 'con_movimiento' and account['parent_id']:
  308. # Include accounts with movements
  309. if abs(res['debit']) >= 0.5 * 10**-int(2) or abs(res['credit']) >= 0.5 * 10**-int(2):
  310. result_acc.append(res)
  311. elif form['display_account'] == 'con_balance' and account['parent_id']:
  312. # Include accounts with balance
  313. if abs(res['balance']) >= 0.5 * 10**-4:
  314. result_acc.append(res)
  315. else:
  316. # Include all accounts
  317. result_acc.append(res)
  318. if form['tot_check'] and res['type'] == 'view' and res['level'] == 1 and (res['id'] not in tot):
  319. tot_check = True
  320. tot[res['id']] = True
  321. tot_bin += res['balanceinit']
  322. tot_deb += res['debit']
  323. tot_crd += res['credit']
  324. tot_eje += res['balance']
  325. #if (form['tot_check'] and res['type']=='view' and res['level']==1 and (res['id'] not in tot)):
  326. if tot_check:
  327. str_label = form['lab_str']
  328. res2 = {
  329. 'type' : 'view',
  330. 'name': 'TOTAL %s'%(str_label),
  331. 'balanceinit': tot_bin,
  332. 'debit': tot_deb,
  333. 'credit': tot_crd,
  334. 'balance': tot_eje,
  335. 'label': False,
  336. 'total': True,
  337. }
  338. result_acc.append(res2)
  339. return result_acc
  340. report_sxw.report_sxw('report.wizard.report.reporte',
  341. 'wizard.report',
  342. 'account_financial_report/report/balance_full_4_cols.rml',
  343. parser=account_balance,
  344. header=False)
  345. report_sxw.report_sxw('report.account.account.balance.gene.2',
  346. 'wizard.report.account.balance.gene.2',
  347. 'account_financial_report/report/balance_full_2_cols.rml',
  348. parser=account_balance,
  349. header=False)
  350. report_sxw.report_sxw('report.account.account.balance.gene',
  351. 'wizard.report.account.balance.gene',
  352. 'account_financial_report/report/balance_full.rml',
  353. parser=account_balance,
  354. header=False)