~openerp-commiter/openobject-addons/extra-6.0

« back to all changes in this revision

Viewing changes to account_financial_report/report/account_balance.py

  • Committer: Borja L.S.
  • Date: 2010-04-07 17:17:06 UTC
  • mto: This revision was merged to the branch mainline in revision 4498.
  • Revision ID: borjals@pexego.es-20100407171706-bdyhd0essc5237g2
[ADD] account_financial_report: Added the module from the 5.0 extra-addons.

  This module from the 5.0 extra-addons was missing on the 
  trunk extra-addons branch.
 
  We have just tested that it works with the 5.2 version.

  The module adds some extra financial/accounting reports:
  * Account chart list
  * Invoice list
  * Account move (journal ledger)
  * Account move line
  * Account balance compared period-fiscal year
  * Cumulative general ledger

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- encoding: utf-8 -*-
 
2
##############################################################################
 
3
#
 
4
#    OpenERP, Open Source Management Solution
 
5
#    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
 
6
#    Copyright (c) 2009 Zikzakmedia S.L. (http://zikzakmedia.com) All Rights Reserved.
 
7
#                       Jordi Esteve <jesteve@zikzakmedia.com>
 
8
#    $Id$
 
9
#
 
10
#    This program is free software: you can redistribute it and/or modify
 
11
#    it under the terms of the GNU General Public License as published by
 
12
#    the Free Software Foundation, either version 3 of the License, or
 
13
#    (at your option) any later version.
 
14
#
 
15
#    This program is distributed in the hope that it will be useful,
 
16
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
17
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
18
#    GNU General Public License for more details.
 
19
#
 
20
#    You should have received a copy of the GNU General Public License
 
21
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
22
#
 
23
##############################################################################
 
24
 
 
25
import xml
 
26
import copy
 
27
from operator import itemgetter
 
28
import time
 
29
import datetime
 
30
from report import report_sxw
 
31
from tools import config
 
32
 
 
33
 
 
34
class account_balance(report_sxw.rml_parse):
 
35
    _name = 'report.account.account.balance'
 
36
 
 
37
    def set_context(self, objects, data, ids, report_type = None):
 
38
        self.get_context_date_period(data['form'])
 
39
        super(account_balance, self).set_context(objects, data, ids, report_type)
 
40
 
 
41
 
 
42
    def __init__(self, cr, uid, name, context):
 
43
        super(account_balance, self).__init__(cr, uid, name, context)
 
44
        self.sum_debit = 0.00
 
45
        self.sum_credit = 0.00
 
46
        self.sum_balance = 0.00
 
47
        self.sum_debit_fy = 0.00
 
48
        self.sum_credit_fy = 0.00
 
49
        self.sum_balance_fy = 0.00
 
50
        self.date_lst = []
 
51
        self.date_lst_string = ''
 
52
        self.ctx = {}      # Context for given date or period
 
53
        self.ctxfy = {}    # Context from the date start or first period of the fiscal year
 
54
        self.localcontext.update({
 
55
            'time': time,
 
56
            'lines': self.lines,
 
57
            'sum_debit': self._sum_debit,
 
58
            'sum_credit': self._sum_credit,
 
59
            'sum_balance': self._sum_balance,
 
60
            'sum_balanceinit': self._sum_balanceinit,
 
61
            'sum_debit_fy': self._sum_debit_fy,
 
62
            'sum_credit_fy': self._sum_credit_fy,
 
63
            'sum_balance_fy': self._sum_balance_fy,
 
64
            'sum_balanceinit_fy': self._sum_balanceinit_fy,
 
65
            'get_fiscalyear':self.get_fiscalyear,
 
66
            'get_periods':self.get_periods,
 
67
        })
 
68
        self.context = context
 
69
 
 
70
 
 
71
    def get_fiscalyear(self, form):
 
72
        res=[]
 
73
        if form.has_key('fiscalyear'):
 
74
            fisc_id = form['fiscalyear']
 
75
            if not (fisc_id):
 
76
                return ''
 
77
            self.cr.execute("SELECT name FROM account_fiscalyear WHERE id = %s" , (int(fisc_id),))
 
78
            res=self.cr.fetchone()
 
79
        return res and res[0] or ''
 
80
 
 
81
 
 
82
    def get_periods(self, form):
 
83
        result=''
 
84
        if form.has_key('periods') and form['periods'][0][2]:
 
85
            period_ids = ",".join([str(x) for x in form['periods'][0][2] if x])
 
86
            self.cr.execute("SELECT name FROM account_period WHERE id in (%s)" % (period_ids))
 
87
            res = self.cr.fetchall()
 
88
            len_res = len(res) 
 
89
            for r in res:
 
90
                if (r == res[len_res-1]):
 
91
                    result+=r[0]+". "
 
92
                else:
 
93
                    result+=r[0]+", "
 
94
        elif form.has_key('date_from') and form.has_key('date_to'):
 
95
            result = self.formatLang(form['date_from'], date=True) + ' - ' + self.formatLang(form['date_to'], date=True) + ' '
 
96
        else:
 
97
            fy_obj = self.pool.get('account.fiscalyear').browse(self.cr,self.uid,form['fiscalyear'])
 
98
            res = fy_obj.period_ids
 
99
            len_res = len(res)
 
100
            for r in res:
 
101
                if r == res[len_res-1]:
 
102
                    result+=r.name+". "
 
103
                else:
 
104
                    result+=r.name+", "
 
105
            
 
106
        return str(result and result[:-1]) or ''
 
107
 
 
108
 
 
109
    def get_context_date_period(self, form):
 
110
        # ctx: Context for the given date or period
 
111
        ctx = self.context.copy()
 
112
        ctx['state'] = form['context'].get('state','all')
 
113
        if 'fiscalyear' in form and form['fiscalyear']:
 
114
            ctx['fiscalyear'] = form['fiscalyear']
 
115
        if form['state'] in ['byperiod', 'all']:
 
116
            ctx['periods'] = form['periods'][0][2]
 
117
        if form['state'] in ['bydate', 'all']:
 
118
            ctx['date_from'] = form['date_from']
 
119
            ctx['date_to'] = form['date_to']
 
120
        if 'periods' not in ctx:
 
121
            ctx['periods'] = []
 
122
        self.ctx = ctx
 
123
 
 
124
        # ctxfy: Context from the date start / first period of the fiscal year
 
125
        ctxfy = ctx.copy()
 
126
        ctxfy['periods'] = ctx['periods'][:]
 
127
 
 
128
        if form['state'] in ['byperiod', 'all'] and len(ctx['periods']):
 
129
            self.cr.execute("""SELECT id, date_start, fiscalyear_id
 
130
                FROM account_period
 
131
                WHERE date_start = (SELECT min(date_start) FROM account_period WHERE id in (%s))"""
 
132
                % (','.join([str(x) for x in ctx['periods']])))
 
133
            res = self.cr.dictfetchone()
 
134
            self.cr.execute("""SELECT id
 
135
                FROM account_period
 
136
                WHERE fiscalyear_id in (%s) AND special=FALSE AND date_start < '%s'"""
 
137
                % (res['fiscalyear_id'], res['date_start']))
 
138
            ids = filter(None, map(lambda x:x[0], self.cr.fetchall()))
 
139
            ctxfy['periods'].extend(ids)
 
140
 
 
141
        if form['state'] in ['bydate', 'all']:
 
142
            self.cr.execute("""SELECT date_start
 
143
                FROM account_fiscalyear
 
144
                WHERE '%s' BETWEEN date_start AND date_stop""" % (ctx['date_from']))
 
145
            res = self.cr.dictfetchone()
 
146
            ctxfy['date_from'] = res['date_start']
 
147
 
 
148
        if form['state'] == 'none' or (form['state'] == 'byperiod' and not len(ctx['periods'])):
 
149
            if 'fiscalyear' in form and form['fiscalyear']:
 
150
                sql = """SELECT id, date_start
 
151
                    FROM account_period
 
152
                    WHERE fiscalyear_id in (%s) AND special=FALSE
 
153
                    ORDER BY date_start""" % (ctx['fiscalyear'])
 
154
            else:
 
155
                sql = """SELECT id, date_start
 
156
                    FROM account_period
 
157
                    WHERE fiscalyear_id in (SELECT id FROM account_fiscalyear WHERE state='draft') AND special=FALSE
 
158
                    ORDER BY date_start"""
 
159
            self.cr.execute(sql)
 
160
            res = self.cr.dictfetchall()
 
161
            ids = filter(None, map(lambda x:x['id'], res))
 
162
            ctxfy['periods'] = ids
 
163
        self.ctxfy = ctxfy
 
164
#        print "ctx=", self.ctx
 
165
#        print "ctxfy=", self.ctxfy
 
166
 
 
167
 
 
168
 
 
169
    def lines(self, form, ids={}, done=None, level=1):
 
170
        if not ids:
 
171
            ids = self.ids
 
172
        if not ids:
 
173
            return []
 
174
        if not done:
 
175
            done={}
 
176
        if form.has_key('Account_list') and form['Account_list']:
 
177
            ids = form['Account_list'][0][2]
 
178
            del form['Account_list']
 
179
        res={}
 
180
        result_acc=[]
 
181
        account_obj = self.pool.get('account.account')
 
182
        period_obj = self.pool.get('account.period')
 
183
 
 
184
        ctx_allfy = self.context.copy()
 
185
        ctx_allfy['fiscalyear'] = form['fiscalyear']
 
186
        ctx_allfy['periods'] = period_obj.search(self.cr, self.uid, [('fiscalyear_id','=',form['fiscalyear'])])
 
187
 
 
188
        ctx_allfy_nospecial = self.context.copy()
 
189
        ctx_allfy_nospecial['fiscalyear'] = form['fiscalyear']
 
190
        ctx_allfy_nospecial['periods'] = period_obj.search(self.cr, self.uid, [('fiscalyear_id','=',form['fiscalyear']),('special','=',False)])
 
191
 
 
192
#            accounts = account_obj.browse(self.cr, self.uid, ids, self.ctx)
 
193
#            def cmp_code(x, y):
 
194
#                return cmp(x.code, y.code)
 
195
#            accounts.sort(cmp_code)
 
196
        child_ids = account_obj._get_children_and_consol(self.cr, self.uid, ids, self.ctx)
 
197
        if child_ids:
 
198
            ids = child_ids
 
199
        # Amounts in period or date
 
200
        accounts = account_obj.read(self.cr, self.uid, ids, ['type','code','name','debit','credit','balance','parent_id'], self.ctx)
 
201
        # Amounts from the date start / first period of the fiscal year
 
202
        balance_fy = {}
 
203
        for acc in account_obj.read(self.cr, self.uid, ids, ['balance'], self.ctxfy):
 
204
            balance_fy[acc['id']] = acc['balance']
 
205
        # Amounts in all fiscal year
 
206
        balance_allfy = {}
 
207
        for acc in account_obj.read(self.cr, self.uid, ids, ['balance'], ctx_allfy):
 
208
            balance_allfy[acc['id']] = acc['balance']
 
209
        # Amounts in all fiscal year without special periods
 
210
        debit_allfy_nos = {}
 
211
        credit_allfy_nos = {}
 
212
        for acc in account_obj.read(self.cr, self.uid, ids, ['debit','credit'], ctx_allfy_nospecial):
 
213
            debit_allfy_nos[acc['id']] = acc['debit']
 
214
            credit_allfy_nos[acc['id']] = acc['credit']
 
215
 
 
216
        for account in accounts:
 
217
            account_id = account['id']
 
218
            if account_id in done:
 
219
                continue
 
220
            done[account_id] = 1
 
221
            res = {
 
222
                    'id' : account_id,
 
223
                    'type' : account['type'],
 
224
                    'code': account['code'],
 
225
                    'name': account['name'],
 
226
                    'level': level,
 
227
                    'debit': account['debit'],
 
228
                    'credit': account['credit'],
 
229
                    'balance': balance_fy[account_id],
 
230
                    'balanceinit': round(balance_fy[account_id]-account['debit']+account['credit'], int(config['price_accuracy'])),
 
231
                    'debit_fy': debit_allfy_nos[account_id],
 
232
                    'credit_fy': credit_allfy_nos[account_id],
 
233
                    'balance_fy': balance_allfy[account_id],
 
234
                    'balanceinit_fy': round(balance_allfy[account_id]-debit_allfy_nos[account_id]+credit_allfy_nos[account_id], int(config['price_accuracy'])),
 
235
                   # 'leef': not bool(account['child_id']),
 
236
                    'parent_id':account['parent_id'],
 
237
                    'bal_type':'',
 
238
                }
 
239
            if abs(res['balanceinit']) < 10**-int(config['price_accuracy']):
 
240
                res['balanceinit'] = 0
 
241
            if abs(res['balanceinit_fy']) < 10**-int(config['price_accuracy']):
 
242
                res['balanceinit_fy'] = 0
 
243
            self.sum_debit += account['debit']
 
244
            self.sum_credit += account['credit']
 
245
            self.sum_balance += balance_fy[account_id]
 
246
            self.sum_debit_fy += debit_allfy_nos[account_id]
 
247
            self.sum_credit_fy += credit_allfy_nos[account_id]
 
248
            self.sum_balance_fy += balance_allfy[account_id]
 
249
#                if account.child_id:
 
250
#                    def _check_rec(account):
 
251
#                        if not account.child_id:
 
252
#                            return bool(account.credit or account.debit)
 
253
#                        for c in account.child_id:
 
254
#                            if not _check_rec(c) or _check_rec(c):
 
255
#                                return True
 
256
#                        return False
 
257
#                    if not _check_rec(account) :
 
258
#                        continue
 
259
            if account['parent_id']:
 
260
#                    acc = account_obj.read(self.cr, self.uid, [ account['parent_id'][0] ] ,['name'], self.ctx)
 
261
                for r in result_acc:
 
262
                    if r['id'] == account['parent_id'][0]:
 
263
                        res['level'] = r['level'] + 1
 
264
                        break
 
265
            if form['display_account'] == 'bal_mouvement':
 
266
                if res['credit'] > 0 or res['debit'] > 0 or res['balance'] > 0 :
 
267
                    result_acc.append(res)
 
268
            elif form['display_account'] == 'bal_solde':
 
269
                if  res['balance'] != 0:
 
270
                    result_acc.append(res)
 
271
            else:
 
272
                result_acc.append(res)
 
273
#                if account.child_id:
 
274
#                    acc_id = [acc.id for acc in account.child_id]
 
275
#                    lst_string = ''
 
276
#                    lst_string = '\'' + '\',\''.join(map(str,acc_id)) + '\''
 
277
#                    self.cr.execute("select code,id from account_account where id IN (%s)"%(lst_string))
 
278
#                    a_id = self.cr.fetchall()
 
279
#                    a_id.sort()
 
280
#                    ids2 = [x[1] for x in a_id]
 
281
#
 
282
#                    result_acc += self.lines(form, ids2, done, level+1)
 
283
        self.sum_balanceinit = round(self.sum_balance - self.sum_debit + self.sum_credit, int(config['price_accuracy']))
 
284
        self.sum_balanceinit_fy = round(self.sum_balance_fy - self.sum_debit_fy + self.sum_credit_fy, int(config['price_accuracy']))
 
285
        return result_acc
 
286
    
 
287
    def _sum_credit(self):
 
288
        return self.sum_credit
 
289
 
 
290
    def _sum_debit(self):
 
291
        return self.sum_debit
 
292
 
 
293
    def _sum_balance(self):
 
294
        return self.sum_balance
 
295
 
 
296
    def _sum_balanceinit(self):
 
297
        return self.sum_balanceinit
 
298
    
 
299
    def _sum_credit_fy(self):
 
300
        return self.sum_credit_fy
 
301
 
 
302
    def _sum_debit_fy(self):
 
303
        return self.sum_debit_fy
 
304
 
 
305
    def _sum_balance_fy(self):
 
306
        return self.sum_balance_fy
 
307
 
 
308
    def _sum_balanceinit_fy(self):
 
309
        return self.sum_balanceinit_fy
 
310
 
 
311
report_sxw.report_sxw('report.account.balance.full', 'account.account', 'addons/account_financial_report/report/account_balance_full.rml', parser=account_balance, header=False)
 
312
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: