~camptocamp/account-financial-report/7.0-fix-1253659

« back to all changes in this revision

Viewing changes to account_financial_report/wizard/wizard.py

[IMP] Linearization of computation for account_financial_report, necesary with big quantity of data from 90 minutes to 90 secs .... good Job team

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
#    Module Writen to OpenERP, Open Source Management Solution
4
4
#    Copyright (C) OpenERP Venezuela (<http://openerp.com.ve>).
5
5
#    All Rights Reserved
6
 
###############Credits######################################################
 
6
# Credits######################################################
7
7
#    Coded by:   Humberto Arocha humberto@openerp.com.ve
8
8
#                Angelica Barrios angelicaisabelb@gmail.com
9
9
#               Jordi Esteve <jesteve@zikzakmedia.com>
26
26
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
27
27
##############################################################################
28
28
 
29
 
from osv import osv,fields
 
29
from osv import osv, fields
30
30
import pooler
31
31
import time
32
32
from tools.translate import _
33
33
 
 
34
 
34
35
class wizard_report(osv.osv_memory):
35
36
    _name = "wizard.report"
36
37
 
37
38
    _columns = {
38
 
        'afr_id': fields.many2one('afr','Custom Report', help='If you have already set a Custom Report, Select it Here.'),
39
 
        'company_id': fields.many2one('res.company','Company',required=True),
 
39
        'afr_id': fields.many2one('afr', 'Custom Report', help='If you have already set a Custom Report, Select it Here.'),
 
40
        'company_id': fields.many2one('res.company', 'Company', required=True),
40
41
        'currency_id': fields.many2one('res.currency', 'Currency', help="Currency at which this report will be expressed. If not selected will be used the one set in the company"),
41
 
        'inf_type': fields.selection([('BS','Balance Sheet'),('IS','Income Statement')],'Type',required=True),
42
 
        'columns': fields.selection([('one','End. Balance'),('two','Debit | Credit'), ('four','Initial | Debit | Credit | YTD'), ('five','Initial | Debit | Credit | Period | YTD'),('qtr',"4 QTR's | YTD"),('thirteen','12 Months | YTD')],'Columns',required=True),
43
 
        'display_account': fields.selection([('all','All Accounts'),('bal', 'With Balance'),('mov','With movements'),('bal_mov','With Balance / Movements')],'Display accounts'),
44
 
        'display_account_level': fields.integer('Up to level',help='Display accounts up to this level (0 to show all)'),
45
 
        
46
 
        'account_list': fields.many2many ('account.account','rel_wizard_account','account_list','account_id','Root accounts',required=True),
47
 
        
48
 
        'fiscalyear': fields.many2one('account.fiscalyear','Fiscal year',help='Fiscal Year for this report',required=True),
49
 
        'periods': fields.many2many('account.period','rel_wizard_period','wizard_id','period_id','Periods',help='All periods in the fiscal year if empty'),
50
 
        
 
42
        'inf_type': fields.selection([('BS', 'Balance Sheet'), ('IS', 'Income Statement')], 'Type', required=True),
 
43
        'columns': fields.selection([('one', 'End. Balance'), ('two', 'Debit | Credit'), ('four', 'Initial | Debit | Credit | YTD'), ('five', 'Initial | Debit | Credit | Period | YTD'), ('qtr', "4 QTR's | YTD"), ('thirteen', '12 Months | YTD')], 'Columns', required=True),
 
44
        'display_account': fields.selection([('all', 'All Accounts'), ('bal', 'With Balance'), ('mov', 'With movements'), ('bal_mov', 'With Balance / Movements')], 'Display accounts'),
 
45
        'display_account_level': fields.integer('Up to level', help='Display accounts up to this level (0 to show all)'),
 
46
 
 
47
        'account_list': fields.many2many('account.account', 'rel_wizard_account', 'account_list', 'account_id', 'Root accounts', required=True),
 
48
 
 
49
        'fiscalyear': fields.many2one('account.fiscalyear', 'Fiscal year', help='Fiscal Year for this report', required=True),
 
50
        'periods': fields.many2many('account.period', 'rel_wizard_period', 'wizard_id', 'period_id', 'Periods', help='All periods in the fiscal year if empty'),
 
51
 
51
52
        'analytic_ledger': fields.boolean('Analytic Ledger', help="Allows to Generate an Analytic Ledger for accounts with moves. Available when Balance Sheet and 'Initial | Debit | Credit | YTD' are selected"),
52
 
        
 
53
 
53
54
        'tot_check': fields.boolean('Summarize?', help='Checking will add a new line at the end of the Report which will Summarize Columns in Report'),
54
 
        'lab_str': fields.char('Description', help='Description for the Summary', size= 128),
55
 
        
 
55
        'lab_str': fields.char('Description', help='Description for the Summary', size=128),
 
56
 
56
57
        #~ Deprecated fields
57
 
        'filter': fields.selection([('bydate','By Date'),('byperiod','By Period'),('all','By Date and Period'),('none','No Filter')],'Date/Period Filter'),
 
58
        'filter': fields.selection([('bydate', 'By Date'), ('byperiod', 'By Period'), ('all', 'By Date and Period'), ('none', 'No Filter')], 'Date/Period Filter'),
58
59
        'date_to': fields.date('End date'),
59
60
        'date_from': fields.date('Start date'),
60
61
    }
61
 
    
 
62
 
62
63
    _defaults = {
63
64
        'date_from': lambda *a: time.strftime('%Y-%m-%d'),
64
65
        'date_to': lambda *a: time.strftime('%Y-%m-%d'),
65
 
        'filter': lambda *a:'byperiod',
 
66
        'filter': lambda *a: 'byperiod',
66
67
        'display_account_level': lambda *a: 0,
67
 
        'inf_type': lambda *a:'BS',
68
 
        'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'account.invoice', context=c),
 
68
        'inf_type': lambda *a: 'BS',
 
69
        'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'account.invoice', context=c),
69
70
        'fiscalyear': lambda self, cr, uid, c: self.pool.get('account.fiscalyear').find(cr, uid),
70
 
        'display_account': lambda *a:'bal_mov',
71
 
        'columns': lambda *a:'five',
 
71
        'display_account': lambda *a: 'bal_mov',
 
72
        'columns': lambda *a: 'five',
72
73
    }
73
74
 
74
 
    def onchange_inf_type(self,cr,uid,ids,inf_type,context=None):
 
75
    def onchange_inf_type(self, cr, uid, ids, inf_type, context=None):
75
76
        if context is None:
76
77
            context = {}
77
 
        res = {'value':{}}
78
 
        
 
78
        res = {'value': {}}
 
79
 
79
80
        if inf_type != 'BS':
80
 
            res['value'].update({'analytic_ledger':False})
81
 
        
 
81
            res['value'].update({'analytic_ledger': False})
 
82
 
82
83
        return res
83
84
 
84
 
    def onchange_columns(self,cr,uid,ids,columns,fiscalyear,periods,context=None):
 
85
    def onchange_columns(self, cr, uid, ids, columns, fiscalyear, periods, context=None):
85
86
        if context is None:
86
87
            context = {}
87
 
        res = {'value':{}}
88
 
        
 
88
        res = {'value': {}}
 
89
 
89
90
        p_obj = self.pool.get("account.period")
90
 
        all_periods = p_obj.search(cr,uid,[('fiscalyear_id','=',fiscalyear),('special','=',False)],context=context)
 
91
        all_periods = p_obj.search(cr, uid, [('fiscalyear_id', '=', fiscalyear), (
 
92
            'special', '=', False)], context=context)
91
93
        s = set(periods[0][2])
92
94
        t = set(all_periods)
93
95
        go = periods[0][2] and s.issubset(t) or False
94
 
        
 
96
 
95
97
        if columns != 'four':
96
 
            res['value'].update({'analytic_ledger':False})
97
 
        
 
98
            res['value'].update({'analytic_ledger': False})
 
99
 
98
100
        if columns in ('qtr', 'thirteen'):
99
 
            res['value'].update({'periods':all_periods})
 
101
            res['value'].update({'periods': all_periods})
100
102
        else:
101
103
            if go:
102
 
                res['value'].update({'periods':periods})
 
104
                res['value'].update({'periods': periods})
103
105
            else:
104
 
                res['value'].update({'periods':[]})
105
 
        return res
106
 
        
107
 
    def onchange_analytic_ledger(self,cr,uid,ids,company_id,analytic_ledger,context=None):
108
 
        if context is None:
109
 
            context = {}
110
 
        context['company_id']=company_id
111
 
        res = {'value':{}}
112
 
        cur_id = self.pool.get('res.company').browse(cr,uid,company_id,context=context).currency_id.id
113
 
        res['value'].update({'currency_id':cur_id})
114
 
        return res
115
 
        
116
 
    def onchange_company_id(self,cr,uid,ids,company_id,context=None):
117
 
        if context is None:
118
 
            context = {}
119
 
        context['company_id']=company_id
120
 
        res = {'value':{}}
121
 
        
 
106
                res['value'].update({'periods': []})
 
107
        return res
 
108
 
 
109
    def onchange_analytic_ledger(self, cr, uid, ids, company_id, analytic_ledger, context=None):
 
110
        if context is None:
 
111
            context = {}
 
112
        context['company_id'] = company_id
 
113
        res = {'value': {}}
 
114
        cur_id = self.pool.get('res.company').browse(
 
115
            cr, uid, company_id, context=context).currency_id.id
 
116
        res['value'].update({'currency_id': cur_id})
 
117
        return res
 
118
 
 
119
    def onchange_company_id(self, cr, uid, ids, company_id, context=None):
 
120
        if context is None:
 
121
            context = {}
 
122
        context['company_id'] = company_id
 
123
        res = {'value': {}}
 
124
 
122
125
        if not company_id:
123
126
            return res
124
 
            
125
 
        cur_id = self.pool.get('res.company').browse(cr,uid,company_id,context=context).currency_id.id
126
 
        fy_id = self.pool.get('account.fiscalyear').find(cr, uid,context=context)
127
 
        res['value'].update({'fiscalyear':fy_id})
128
 
        res['value'].update({'currency_id':cur_id})
129
 
        res['value'].update({'account_list':[]})
130
 
        res['value'].update({'periods':[]})
131
 
        res['value'].update({'afr_id':None})
 
127
 
 
128
        cur_id = self.pool.get('res.company').browse(
 
129
            cr, uid, company_id, context=context).currency_id.id
 
130
        fy_id = self.pool.get('account.fiscalyear').find(
 
131
            cr, uid, context=context)
 
132
        res['value'].update({'fiscalyear': fy_id})
 
133
        res['value'].update({'currency_id': cur_id})
 
134
        res['value'].update({'account_list': []})
 
135
        res['value'].update({'periods': []})
 
136
        res['value'].update({'afr_id': None})
132
137
        return res
133
138
 
134
 
    def onchange_afr_id(self,cr,uid,ids,afr_id,context=None):
 
139
    def onchange_afr_id(self, cr, uid, ids, afr_id, context=None):
135
140
        if context is None:
136
141
            context = {}
137
 
        res = {'value':{}}
138
 
        if not afr_id: return res
139
 
        afr_brw = self.pool.get('afr').browse(cr,uid,afr_id,context=context)
140
 
        res['value'].update({'currency_id':afr_brw.currency_id and afr_brw.currency_id.id or afr_brw.company_id.currency_id.id})
141
 
        res['value'].update({'inf_type':afr_brw.inf_type or 'BS'})
142
 
        res['value'].update({'columns':afr_brw.columns or 'five'})
143
 
        res['value'].update({'display_account':afr_brw.display_account or 'bal_mov'})
144
 
        res['value'].update({'display_account_level':afr_brw.display_account_level or 0})
145
 
        res['value'].update({'fiscalyear':afr_brw.fiscalyear_id and afr_brw.fiscalyear_id.id})
146
 
        res['value'].update({'account_list':[acc.id for acc in afr_brw.account_ids]})
147
 
        res['value'].update({'periods':[p.id for p in afr_brw.period_ids]})
148
 
        res['value'].update({'analytic_ledger':afr_brw.analytic_ledger or False})
149
 
        res['value'].update({'tot_check':afr_brw.tot_check or False})
150
 
        res['value'].update({'lab_str':afr_brw.lab_str or _('Write a Description for your Summary Total')})
 
142
        res = {'value': {}}
 
143
        if not afr_id:
 
144
            return res
 
145
        afr_brw = self.pool.get('afr').browse(cr, uid, afr_id, context=context)
 
146
        res['value'].update({
 
147
                            'currency_id': afr_brw.currency_id and afr_brw.currency_id.id or afr_brw.company_id.currency_id.id})
 
148
        res['value'].update({'inf_type': afr_brw.inf_type or 'BS'})
 
149
        res['value'].update({'columns': afr_brw.columns or 'five'})
 
150
        res['value'].update({
 
151
                            'display_account': afr_brw.display_account or 'bal_mov'})
 
152
        res['value'].update({
 
153
                            'display_account_level': afr_brw.display_account_level or 0})
 
154
        res['value'].update({
 
155
                            'fiscalyear': afr_brw.fiscalyear_id and afr_brw.fiscalyear_id.id})
 
156
        res['value'].update({'account_list': [
 
157
                            acc.id for acc in afr_brw.account_ids]})
 
158
        res['value'].update({'periods': [p.id for p in afr_brw.period_ids]})
 
159
        res['value'].update({
 
160
                            'analytic_ledger': afr_brw.analytic_ledger or False})
 
161
        res['value'].update({'tot_check': afr_brw.tot_check or False})
 
162
        res['value'].update({'lab_str': afr_brw.lab_str or _(
 
163
            'Write a Description for your Summary Total')})
151
164
        return res
152
 
    
 
165
 
153
166
    def _get_defaults(self, cr, uid, data, context=None):
154
167
        if context is None:
155
168
            context = {}
156
 
        user = pooler.get_pool(cr.dbname).get('res.users').browse(cr, uid, uid, context=context)
 
169
        user = pooler.get_pool(cr.dbname).get(
 
170
            'res.users').browse(cr, uid, uid, context=context)
157
171
        if user.company_id:
158
 
           company_id = user.company_id.id
 
172
            company_id = user.company_id.id
159
173
        else:
160
 
           company_id = pooler.get_pool(cr.dbname).get('res.company').search(cr, uid, [('parent_id', '=', False)])[0]
 
174
            company_id = pooler.get_pool(cr.dbname).get(
 
175
                'res.company').search(cr, uid, [('parent_id', '=', False)])[0]
161
176
        data['form']['company_id'] = company_id
162
177
        fiscalyear_obj = pooler.get_pool(cr.dbname).get('account.fiscalyear')
163
178
        data['form']['fiscalyear'] = fiscalyear_obj.find(cr, uid)
168
183
        if context is None:
169
184
            context = {}
170
185
        if data['form']['filter'] == 'bydate':
171
 
           self._check_date(cr, uid, data, context)
 
186
            self._check_date(cr, uid, data, context)
172
187
        return data['form']
173
 
    
 
188
 
174
189
    def _check_date(self, cr, uid, data, context=None):
175
190
        if context is None:
176
191
            context = {}
177
 
            
 
192
 
178
193
        if data['form']['date_from'] > data['form']['date_to']:
179
 
            raise osv.except_osv(_('Error !'),('La fecha final debe ser mayor a la inicial'))
180
 
        
 
194
            raise osv.except_osv(_('Error !'), (
 
195
                'La fecha final debe ser mayor a la inicial'))
 
196
 
181
197
        sql = """SELECT f.id, f.date_start, f.date_stop
182
198
            FROM account_fiscalyear f
183
 
            WHERE '%s' = f.id """%(data['form']['fiscalyear'])
 
199
            WHERE '%s' = f.id """ % (data['form']['fiscalyear'])
184
200
        cr.execute(sql)
185
201
        res = cr.dictfetchall()
186
202
 
187
203
        if res:
188
204
            if (data['form']['date_to'] > res[0]['date_stop'] or data['form']['date_from'] < res[0]['date_start']):
189
 
                raise osv.except_osv(_('UserError'),'Las fechas deben estar entre %s y %s' % (res[0]['date_start'], res[0]['date_stop']))
 
205
                raise osv.except_osv(_('UserError'), 'Las fechas deben estar entre %s y %s' % (
 
206
                    res[0]['date_start'], res[0]['date_stop']))
190
207
            else:
191
208
                return 'report'
192
209
        else:
193
 
            raise osv.except_osv(_('UserError'),'No existe periodo fiscal')
 
210
            raise osv.except_osv(_('UserError'), 'No existe periodo fiscal')
194
211
 
195
212
    def period_span(self, cr, uid, ids, fy_id, context=None):
196
213
        if context is None:
197
214
            context = {}
198
215
        ap_obj = self.pool.get('account.period')
199
 
        fy_id = fy_id and type(fy_id) in (list,tuple) and fy_id[0] or fy_id
 
216
        fy_id = fy_id and type(fy_id) in (list, tuple) and fy_id[0] or fy_id
200
217
        if not ids:
201
218
            #~ No hay periodos
202
 
            return ap_obj.search(cr, uid, [('fiscalyear_id','=',fy_id),('special','=',False)],order='date_start asc')
203
 
        
 
219
            return ap_obj.search(cr, uid, [('fiscalyear_id', '=', fy_id), ('special', '=', False)], order='date_start asc')
 
220
 
204
221
        ap_brws = ap_obj.browse(cr, uid, ids, context=context)
205
222
        date_start = min([period.date_start for period in ap_brws])
206
223
        date_stop = max([period.date_stop for period in ap_brws])
207
 
        
208
 
        return ap_obj.search(cr, uid, [('fiscalyear_id','=',fy_id),('special','=',False),('date_start','>=',date_start),('date_stop','<=',date_stop)],order='date_start asc')
209
 
        
 
224
 
 
225
        return ap_obj.search(cr, uid, [('fiscalyear_id', '=', fy_id), ('special', '=', False), ('date_start', '>=', date_start), ('date_stop', '<=', date_stop)], order='date_start asc')
 
226
 
210
227
    def print_report(self, cr, uid, ids, data, context=None):
211
228
        if context is None:
212
229
            context = {}
213
 
            
 
230
 
214
231
        data = {}
215
232
        data['ids'] = context.get('active_ids', [])
216
233
        data['model'] = context.get('active_model', 'ir.ui.menu')
220
237
            del data['form']['date_from']
221
238
            del data['form']['date_to']
222
239
 
223
 
            data['form']['periods'] = self.period_span(cr, uid, data['form']['periods'], data['form']['fiscalyear'])
 
240
            data['form']['periods'] = self.period_span(cr, uid, data[
 
241
                                                       'form']['periods'], data['form']['fiscalyear'])
224
242
 
225
243
        elif data['form']['filter'] == 'bydate':
226
244
            self._check_date(cr, uid, data)
231
249
            del data['form']['periods']
232
250
        else:
233
251
            self._check_date(cr, uid, data)
234
 
            lis2 = str(data['form']['periods']).replace("[","(").replace("]",")")
235
 
            sqlmm = """select min(p.date_start) as inicio, max(p.date_stop) as fin 
236
 
            from account_period p 
237
 
            where p.id in %s"""%lis2
 
252
            lis2 = str(data['form']['periods']).replace(
 
253
                "[", "(").replace("]", ")")
 
254
            sqlmm = """select min(p.date_start) as inicio, max(p.date_stop) as fin
 
255
            from account_period p
 
256
            where p.id in %s""" % lis2
238
257
            cr.execute(sqlmm)
239
258
            minmax = cr.dictfetchall()
240
259
            if minmax:
241
260
                if (data['form']['date_to'] < minmax[0]['inicio']) or (data['form']['date_from'] > minmax[0]['fin']):
242
 
                    raise osv.except_osv(_('Error !'),_('La interseccion entre el periodo y fecha es vacio'))
243
 
        
 
261
                    raise osv.except_osv(_('Error !'), _(
 
262
                        'La interseccion entre el periodo y fecha es vacio'))
 
263
 
244
264
        if data['form']['columns'] == 'one':
245
265
            name = 'afr.1cols'
246
266
        if data['form']['columns'] == 'two':
256
276
            name = 'afr.qtrcols'
257
277
        if data['form']['columns'] == 'thirteen':
258
278
            name = 'afr.13cols'
259
 
        
 
279
 
260
280
        return {'type': 'ir.actions.report.xml', 'report_name': name, 'datas': data}
261
 
            
 
281
 
262
282
wizard_report()