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.

398 lines
18 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. # This program is free software: you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation, either version 3 of the License, or
  10. # (at your option) any later version.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License
  18. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. ##############################################################################
  20. import xml
  21. import copy
  22. from operator import itemgetter
  23. import time
  24. import datetime
  25. from report import report_sxw
  26. from tools import config
  27. class account_mayor_analitico(report_sxw.rml_parse):
  28. def __init__(self, cr, uid, name, context):
  29. super(account_mayor_analitico, self).__init__(cr, uid, name, context)
  30. self.sum_debit = 0.00
  31. self.sum_credit = 0.00
  32. self.sum_balance = 0.00
  33. self.sum_debit_fy = 0.00
  34. self.sum_credit_fy = 0.00
  35. self.sum_balance_fy = 0.00
  36. self.date_lst = []
  37. self.date_lst_string = ''
  38. self.localcontext.update({
  39. 'time': time,
  40. 'lines': self.lines,
  41. 'get_fiscalyear_text': self.get_fiscalyear_text,
  42. 'get_periods_and_date_text': self.get_periods_and_date_text,
  43. 'get_inf_text': self.get_informe_text,
  44. 'set_fecha': self.set_fecha,
  45. })
  46. self.context = context
  47. def set_fecha(self, fecha):
  48. f = fecha.split('-')
  49. date = datetime.date(int(f[0]),int(f[1]),int(f[2]))
  50. return str(date.strftime("%d/%m/%Y"))
  51. def _get_mayor_detalle(self, account, form):
  52. res = []
  53. if account['type'] != 'view':
  54. if form['filter'] in ('bydate','none'):
  55. #Para filtrar por 'fechas' o 'sin filtro', este porque se envia el año fiscal por fecha.
  56. where = """where aml.date between '%s' and '%s' and aa.id = %s and aml.state <> 'draft'"""%(form['date_from'],form['date_to'],account['id'])
  57. elif form['filter'] == 'byperiod':
  58. #Para filtrar por periodos
  59. periodos = str(form['periods']).replace("[","(").replace("]",")")
  60. where = """where aml.period_id in %s and aa.id = %s and aml.state <> 'draft'"""%(periodos,account['id'])
  61. else:
  62. #Para filtrar por periodos y fechas
  63. periodos = str(form['periods']).replace("[","(").replace("]",")")
  64. where = """where aml.period_id in %s and aml.date between '%s' and '%s' and aa.id = %s and aml.state <> 'draft'"""%(periodos,form['date_from'],form['date_to'],account['id'])
  65. if form.get('state'):
  66. estado = " and am.state = '%s'"%form['state']
  67. where = where + estado
  68. sql_detalle = """select aml.id as id, aj.name as diario, aa.name as descripcion,
  69. (select name from res_partner where aml.partner_id = id) as partner,
  70. aa.code as cuenta, aml.name as name,
  71. aml.ref as ref,
  72. case when aml.debit is null then 0.00 else aml.debit end as debit,
  73. case when aml.credit is null then 0.00 else aml.credit end as credit,
  74. (select code from account_analytic_account where aml.analytic_account_id = id) as analitica,
  75. aml.date as fecha, ap.name as periodo,
  76. am.name as asiento
  77. from account_move_line aml
  78. inner join account_journal aj on aj.id = aml.journal_id
  79. inner join account_account aa on aa.id = aml.account_id
  80. inner join account_period ap on ap.id = aml.period_id
  81. inner join account_move am on am.id = aml.move_id """ + where +\
  82. """ order by fecha"""
  83. self.cr.execute(sql_detalle)
  84. resultat = self.cr.dictfetchall()
  85. balance = account['balanceinit']
  86. #~ print balance
  87. for det in resultat:
  88. print "det", det
  89. balance += det['debit'] - det['credit']
  90. res.append({
  91. 'id': det['id'],
  92. 'date': det['fecha'],
  93. 'journal':det['diario'],
  94. 'partner':det['partner'],
  95. 'name':det['name'],
  96. 'entry':det['asiento'],
  97. 'ref': det['ref'],
  98. 'debit': det['debit'],
  99. 'credit': det['credit'],
  100. 'analytic': det['analitica'],
  101. 'period': det['periodo'],
  102. 'balance': balance,
  103. })
  104. return res
  105. def get_fiscalyear_text(self, form):
  106. """
  107. Returns the fiscal year text used on the report.
  108. """
  109. fiscalyear_obj = self.pool.get('account.fiscalyear')
  110. fiscalyear = None
  111. if form.get('fiscalyear'):
  112. fiscalyear = fiscalyear_obj.browse(self.cr, self.uid, form['fiscalyear'])
  113. return fiscalyear.name or fiscalyear.code
  114. else:
  115. fiscalyear = fiscalyear_obj.browse(self.cr, self.uid, fiscalyear_obj.find(self.cr, self.uid))
  116. return "%s*" % (fiscalyear.name or fiscalyear.code)
  117. def get_informe_text(self, form):
  118. """
  119. Returns the header text used on the report.
  120. """
  121. inf_type = {
  122. 'bgen' : ' Balance General',
  123. 'bcom' : ' Balance de Comprobacion',
  124. 'edogp': 'Estado de Ganancias y Perdidas',
  125. 'bml': ' Mayor Analitico'
  126. }
  127. return inf_type[form['inf_type']]
  128. def get_periods_and_date_text(self, form):
  129. """
  130. Returns the text with the periods/dates used on the report.
  131. """
  132. period_obj = self.pool.get('account.period')
  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, [('fiscalyear_id','=',fiscalyear_id),('special','=',False)])
  136. if form['filter'] in ['byperiod', 'all']:
  137. period_ids = form['periods']
  138. periods_str = ', '.join([period.name or period.code for period in period_obj.browse(self.cr, self.uid, period_ids)])
  139. dates_str = None
  140. if form['filter'] in ['bydate', 'all']:
  141. dates_str = self.formatLang(form['date_from'], date=True) + ' - ' + self.formatLang(form['date_to'], date=True) + ' '
  142. return {'periods':periods_str, 'date':dates_str}
  143. def es_especial(self, periods):
  144. period_obj = self.pool.get('account.period')
  145. period_brws = period_obj.browse(self.cr, self.uid, periods)
  146. tod=0
  147. for p_b in period_brws:
  148. if p_b.special:
  149. tod = tod + 1
  150. if tod == len(periods):
  151. return True
  152. else:
  153. return False
  154. def lines(self, form, ids={}, done=None, level=0):
  155. """
  156. Returns all the data needed for the report lines
  157. (account info plus debit/credit/balance in the selected period
  158. and the full year)
  159. """
  160. tot_bin = 0.0
  161. tot_deb = 0.0
  162. tot_crd = 0.0
  163. tot_eje = 0.0
  164. if not ids:
  165. ids = self.ids
  166. if not ids:
  167. return []
  168. if not done:
  169. done = {}
  170. if form.has_key('account_list') and form['account_list']:
  171. account_ids = form['account_list']
  172. del form['account_list']
  173. res = {}
  174. result_acc = []
  175. accounts_levels = {}
  176. account_obj = self.pool.get('account.account')
  177. period_obj = self.pool.get('account.period')
  178. fiscalyear_obj = self.pool.get('account.fiscalyear')
  179. # Get the fiscal year
  180. fiscalyear = None
  181. if form.get('fiscalyear'):
  182. fiscalyear = fiscalyear_obj.browse(self.cr, self.uid, form['fiscalyear'])
  183. else:
  184. fiscalyear = fiscalyear_obj.browse(self.cr, self.uid, fiscalyear_obj.find(self.cr, self.uid))
  185. #
  186. # Get the accounts
  187. #
  188. def _get_children_and_consol(cr, uid, ids, level, context={}):
  189. aa_obj = self.pool.get('account.account')
  190. ids2=[]
  191. temp=[]
  192. read_data= aa_obj.read(cr, uid, ids,['id','child_id','level','type'], context)
  193. for data in read_data:
  194. if data['child_id'] and data['level'] < level and data['type']!='consolidation':
  195. #ids2.append([data['id'],'Label', 'Total'])
  196. ids2.append([data['id'],True, False])
  197. temp=[]
  198. for x in data['child_id']:
  199. temp.append(x)
  200. ids2 += _get_children_and_consol(cr, uid, temp, level, context)
  201. ids2.append([data['id'],False,True])
  202. else:
  203. ids2.append([data['id'],True,True])
  204. return ids2
  205. child_ids = _get_children_and_consol(self.cr, self.uid, account_ids, form['display_account_level'] and form['display_account_level'] or 100,self.context)
  206. if child_ids:
  207. account_ids = child_ids
  208. account_obj = self.pool.get('account.account')
  209. period_obj = self.pool.get('account.period')
  210. fiscalyear_obj = self.pool.get('account.fiscalyear')
  211. #############################################################################
  212. # Calculate the period Debit/Credit #
  213. # (from the selected period or all the non special periods in the fy) #
  214. #############################################################################
  215. ctx = self.context.copy()
  216. ctx['filter'] = form.get('filter','all')
  217. ctx['fiscalyear'] = fiscalyear.id
  218. #~ ctx['periods'] = period_obj.search(self.cr, self.uid, [('fiscalyear_id','=',fiscalyear.id),('special','=',False)])
  219. if ctx['filter'] not in ['bydate','none']:
  220. especial = self.es_especial(form['periods'])
  221. else:
  222. especial = False
  223. if form['filter'] in ['byperiod', 'all']:
  224. if especial:
  225. ctx['periods'] = period_obj.search(self.cr, self.uid, [('id','in',form['periods'] or ctx['periods'])])
  226. else:
  227. ctx['periods'] = period_obj.search(self.cr, self.uid, [('id','in',form['periods'] or ctx['periods']),('special','=',False)])
  228. if form['filter'] in ['bydate','all','none']:
  229. ctx['date_from'] = form['date_from']
  230. ctx['date_to'] = form['date_to']
  231. if form.get('state'):
  232. ctx['state'] = form['state']
  233. accounts=[]
  234. val = account_obj.browse(self.cr, self.uid, [aa_id[0] for aa_id in account_ids], ctx)
  235. c = 0
  236. for aa_id in account_ids:
  237. new_acc = {
  238. 'id' :val[c].id,
  239. 'type' :val[c].type,
  240. 'code' :val[c].code,
  241. 'name' :val[c].name,
  242. 'debit' :val[c].debit,
  243. 'credit' :val[c].credit,
  244. 'parent_id' :val[c].parent_id and val[c].parent_id.id,
  245. 'level' :val[c].level,
  246. 'label' :aa_id[1],
  247. 'total' :aa_id[2],
  248. }
  249. c += 1
  250. accounts.append(new_acc)
  251. def missing_period():
  252. ctx['fiscalyear'] = fiscalyear_obj.search(self.cr, self.uid, [('date_stop','<',fiscalyear.date_start)],order='date_stop') and \
  253. fiscalyear_obj.search(self.cr, self.uid, [('date_stop','<',fiscalyear.date_start)],order='date_stop')[-1] or []
  254. ctx['periods'] = period_obj.search(self.cr, self.uid, [('fiscalyear_id','=',ctx['fiscalyear']),('date_stop','<',fiscalyear.date_start)])
  255. #############################################################################
  256. # Calculate the period initial Balance #
  257. # (fy balance minus the balance from the start of the selected period #
  258. # to the end of the year) #
  259. #############################################################################
  260. ctx = self.context.copy()
  261. ctx['filter'] = form.get('filter','all')
  262. ctx['fiscalyear'] = fiscalyear.id
  263. if form['filter'] in ['byperiod', 'all']:
  264. ctx['periods'] = form['periods']
  265. date_start = min([period.date_start for period in period_obj.browse(self.cr, self.uid, ctx['periods'])])
  266. ctx['periods'] = period_obj.search(self.cr, self.uid, [('fiscalyear_id','=',fiscalyear.id),('date_stop','<=',date_start)])
  267. if not ctx['periods']:
  268. missing_period()
  269. elif form['filter'] in ['bydate']:
  270. ctx['date_from'] = fiscalyear.date_start
  271. ctx['date_to'] = form['date_from']
  272. ctx['periods'] = period_obj.search(self.cr, self.uid, [('fiscalyear_id','=',fiscalyear.id),('date_stop','<=',ctx['date_to'])])
  273. elif form['filter'] == 'none':
  274. ctx['periods'] = period_obj.search(self.cr, self.uid, [('fiscalyear_id','=',fiscalyear.id),('special','=',True)])
  275. date_start = min([period.date_start for period in period_obj.browse(self.cr, self.uid, ctx['periods'])])
  276. ctx['periods'] = period_obj.search(self.cr, self.uid, [('fiscalyear_id','=',fiscalyear.id),('date_start','<=',date_start),('special','=',True)])
  277. period_balanceinit = {}
  278. for acc in account_obj.browse(self.cr, self.uid, [x[0] for x in account_ids], ctx):
  279. if especial:
  280. period_balanceinit[acc['id']] = 0.0
  281. else:
  282. period_balanceinit[acc['id']] = acc.balance
  283. #
  284. # Generate the report lines (checking each account)
  285. #
  286. tot = {}
  287. for account in accounts:
  288. account_id = account['id']
  289. if account_id in done:
  290. pass
  291. done[account_id] = 1
  292. accounts_levels[account_id] = account['level']
  293. #
  294. # Check if we need to include this level
  295. #
  296. if not form['display_account_level'] or account['level'] <= form['display_account_level']:
  297. #
  298. # Copy the account values
  299. #
  300. res = {
  301. 'id' : account_id,
  302. 'type' : account['type'],
  303. 'code': account['code'],
  304. 'name': (account['total'] and not account['label']) and 'TOTAL %s'%(account['name'].upper()) or account['name'],
  305. 'level': account['level'],
  306. 'balanceinit': period_balanceinit[account_id],
  307. 'debit': account['debit'],
  308. 'credit': account['credit'],
  309. 'balance': period_balanceinit[account_id]+account['debit']-account['credit'],
  310. 'parent_id': account['parent_id'],
  311. 'bal_type': '',
  312. 'label': account['label'],
  313. 'total': account['total'],
  314. }
  315. #
  316. # Round the values to zero if needed (-0.000001 ~= 0)
  317. #
  318. if abs(res['balance']) < 0.5 * 10**-4:
  319. res['balance'] = 0.0
  320. #
  321. # Check whether we must include this line in the report or not
  322. #
  323. if form['display_account'] == 'con_movimiento' and account['parent_id']:
  324. # Include accounts with movements
  325. if abs(res['debit']) >= 0.5 * 10**-int(2) or abs(res['credit']) >= 0.5 * 10**-int(2):
  326. if res['type'] != 'view' and res['code']!='0':
  327. res['mayor'] = self._get_mayor_detalle(res,form)
  328. result_acc.append(res)
  329. elif form['display_account'] == 'con_balance' and account['parent_id']:
  330. # Include accounts with balance
  331. if abs(res['balance']) >= 0.5 * 10**-4:
  332. if res['type'] != 'view' and res['code']!='0':
  333. res['mayor'] = self._get_mayor_detalle(res,form)
  334. result_acc.append(res)
  335. else:
  336. # Include all accounts
  337. if res['type'] != 'view' and res['code']!='0':
  338. res['mayor'] = self._get_mayor_detalle(res,form)
  339. result_acc.append(res)
  340. if form['tot_check'] and res['type'] == 'view' and res['level'] == 1 and (res['id'] not in tot):
  341. tot[res['id']] = True
  342. tot_bin += res['balanceinit']
  343. tot_deb += res['debit']
  344. tot_crd += res['credit']
  345. tot_eje += res['balance']
  346. if form['tot_check']:
  347. str_label = form['lab_str']
  348. res2 = {
  349. 'type' : 'view',
  350. 'name': 'TOTAL %s'%(str_label),
  351. 'balanceinit': tot_bin,
  352. 'debit': tot_deb,
  353. 'credit': tot_crd,
  354. 'balance': tot_eje,
  355. 'label': False,
  356. 'total': True,
  357. }
  358. result_acc.append(res2)
  359. return result_acc
  360. report_sxw.report_sxw('report.wizard.reporte.comprobacion.mayor.analitico', 'wizard.reporte.comprobacion', 'l10n_ve_account_financial_report/report/mayor_analitico.rml', parser=account_mayor_analitico, header=False)