RenderPM will only work on updated Reportlab,commented
[odoo/odoo.git] / addons / account_report / account.py
1 # -*- encoding: utf-8 -*-
2 ##############################################################################
3 #
4 # Copyright (c) 2004-2008 TINY SPRL. (http://tiny.be) All Rights Reserved.
5 #
6 # $Id$
7 #
8 # WARNING: This program as such is intended to be used by professional
9 # programmers who take the whole responsability of assessing all potential
10 # consequences resulting from its eventual inadequacies and bugs
11 # End users who are looking for a ready-to-use solution with commercial
12 # garantees and support are strongly adviced to contract a Free Software
13 # Service Company
14 #
15 # This program is Free Software; you can redistribute it and/or
16 # modify it under the terms of the GNU General Public License
17 # as published by the Free Software Foundation; either version 2
18 # of the License, or (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, write to the Free Software
27 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
28 #
29 ##############################################################################
30 import time
31 import netsvc
32 from osv import fields, osv
33 import pooler
34 from tools.misc import currency
35
36 import mx.DateTime
37 from mx.DateTime import RelativeDateTime, now, DateTime, localtime
38
39
40 class account_report(osv.osv):
41     _name = "account.report.report"
42     _description = "Account reporting"
43 #    _color = [
44 #            ('', ''),
45 #            ('green','Green'),
46 #            ('red','Red'),
47 #            ('pink','Pink'),
48 #            ('blue','Blue'),
49 #            ('yellow','Yellow'),
50 #            ('cyan','Cyan'),
51 #            ('lightblue','Light Blue'),
52 #            ('orange','Orange'),
53 #            ]
54 #    _style = [
55 #            ('1','Header 1'),
56 #            ('2','Header 2'),
57 #            ('3','Header 3'),
58 #            ('4','Header 4'),
59 #            ('5','Normal'),
60 #            ('6', 'Small'),
61 #            ]
62
63     def _amount_get(self, cr, uid, ids, field_name, arg, context={}):
64         def _calc_credit(*code):
65             acc = self.pool.get('account.account')
66             acc_id = acc.search(cr, uid, [('code','in',code)])
67             return reduce(lambda y,x=0: x.credit+y, acc.browse(cr, uid, acc_id, context),0)
68         def _calc_debit(*code):
69             acc = self.pool.get('account.account')
70             acc_id = acc.search(cr, uid, [('code','in',code)])
71             return reduce(lambda y,x=0: x.debit+y, acc.browse(cr, uid, acc_id, context),0)
72         def _calc_balance(*code):
73             acc = self.pool.get('account.account')
74             acc_id = acc.search(cr, uid, [('code','in',code)])
75             return reduce(lambda y,x=0: x.balance+y, acc.browse(cr, uid, acc_id, context),0)
76         def _calc_report(*code):
77             acc = self.pool.get('account.report.report')
78             acc_id = acc.search(cr, uid, [('code','in',code)])
79             return reduce(lambda y,x=0: x.amount+y, acc.browse(cr, uid, acc_id, context),0)
80         result = {}
81         for rep in self.browse(cr, uid, ids, context):
82             objdict = {
83                 'debit': _calc_debit,
84                 'credit': _calc_credit,
85                 'balance': _calc_balance,
86                 'report': _calc_report,
87             }
88 #            if field_name=='status':
89 #                fld_name = 'expression_status'
90 #            else:
91 #                fld_name = 'expression'
92             try:
93                 val = eval(getattr(rep,'expression'), objdict)
94             except:
95                 val = 0.0
96
97             if field_name=='status':
98                 if val<rep.badness_limit:
99                     result[rep.id] = 'very bad'
100                 elif val==rep.badness_limit:
101                     result[rep.id] = 'bad'
102                 elif val<rep.goodness_limit:
103                     result[rep.id] = 'normal'
104                 elif val==rep.goodness_limit:
105                     result[rep.id] = 'good'
106                 else:
107                     result[rep.id] = 'very good'
108             else:
109                 result[rep.id] =  val
110         return result
111
112     def onchange_parent_id(self, cr, uid, ids, parent_id):
113         v={}
114         if parent_id:
115             acc=self.pool.get('account.report.report').browse(cr,uid,parent_id)
116             v['type']=acc.type
117 #            if int(acc.style) < 6:
118 #                v['style'] = str(int(acc.style)+1)
119         return {'value': v}
120
121     _columns = {
122         'name': fields.char('Name', size=64, required=True),
123         'active': fields.boolean('Active'),
124         'sequence': fields.integer('Sequence'),
125         'code': fields.char('Code', size=64, required=True),
126         'type': fields.selection([
127             ('fiscal', 'Fiscal statement'),
128             ('indicator','Indicator'),
129             ('view','View'),
130             ('other','Others')],
131             'Type', required=True),
132         'expression': fields.char('Expression', size=240, required=True),
133 #        'expression_status': fields.char('Status expression', size=240, required=True),
134         'badness_limit' :fields.float('Badness Indicator Limit', digits=(16,2),help='This Value depicts the limit of badness.'),
135         'goodness_limit' :fields.float('Goodness Indicator Limit', digits=(16,2),help='This Value depicts the limit of goodness.'),
136         'parent_id': fields.many2one('account.report.report', 'Parent'),
137         'child_ids': fields.one2many('account.report.report', 'parent_id', 'Childs'),
138         'note': fields.text('Note'),
139         'amount': fields.function(_amount_get, method=True, string='Value'),
140         'status': fields.function(_amount_get,
141             method=True,
142             type="selection",
143             selection=[
144                 ('very bad', 'Very Bad'),
145                 ('bad', 'Bad'),
146                 ('normal', 'Normal'),
147                 ('good', 'Good'),
148                 ('very good', 'Very Good')
149             ],
150             string='Status'),
151          'disp_tree':fields.boolean('Display Tree',help='When the indicators will be printed, if one indicator is set with this field to True, then it will display one more graph with all its children in tree'),
152          'disp_graph':fields.boolean('Display as a Graph',help='If the field is set to True,information will be printed as a Graph; as an array otherwise.'),
153 #        'style': fields.selection(_style, 'Style', required=True),
154 #        'color_font' : fields.selection(_color, 'Font Color', help="Font Color for the report"),
155 #        'color_back' : fields.selection(_color, 'Back Color')
156     }
157     _defaults = {
158 #        'style': lambda *args: '5',
159         'active': lambda *args: True,
160         'type': lambda *args: 'indicator',
161     }
162
163     def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=80):
164         if not args:
165             args=[]
166         if not context:
167             context={}
168         ids = []
169         if name:
170             ids = self.search(cr, user, [('code','=',name)]+ args, limit=limit, context=context)
171             if not ids:
172                 ids = self.search(cr, user, [('name',operator,name)]+ args, limit=limit, context=context)
173         else:
174             ids = self.search(cr, user, args, limit=limit, context=context)
175         return self.name_get(cr, user, ids, context=context)
176
177     _constraints = [
178     #TODO Put an expression to valid expression and expression_status
179     ]
180     _sql_constraints = [
181         ('code_uniq', 'unique (code)', 'The code of the report entry must be unique !')
182     ]
183
184 account_report()
185
186 class account_report_history(osv.osv):
187
188     def _calc_value(self, cr, uid, ids, name, args, context):
189         acc_report_id=self.read(cr,uid,ids,['tmp','period_id'])
190         tmp_ids={}
191         for a in acc_report_id:
192             period_val=pooler.get_pool(cr.dbname).get('account.period').read(cr,uid,[a['period_id'][0]])[0]
193             period_id=pooler.get_pool(cr.dbname).get('account.period').search(cr,uid,[('date_start','<=',period_val['date_start']),('fiscalyear_id','=',period_val['fiscalyear_id'][0])])
194             tmp_ids[a['id']] = pooler.get_pool(cr.dbname).get('account.report.report').read(cr,uid,[a['tmp']],context={'periods':period_id})[0]['amount']
195         return tmp_ids
196
197     _name = "account.report.history"
198     _description = "Indicator"
199     _table = "account_report"
200     _auto = False
201     _order='name'
202     _columns = {
203         'period_id': fields.many2one('account.period','Period', readonly=True, select=True),
204         'fiscalyear_id': fields.many2one('account.fiscalyear','Fiscal Year', readonly=True, select=True),
205         'name': fields.many2one('account.report.report','Indicator', readonly=True, select=True),
206         'val': fields.function(_calc_value, method=True, string='Value', readonly=True),
207         'tmp' : fields.integer(string='temp',readonly=True)
208     }
209
210     def init(self, cr):
211         cr.execute('''create or replace view account_report as (select ar.id as tmp,((pr.id*100000)+ar.id) as id,ar.id as name,pr.id as period_id,pr.fiscalyear_id as fiscalyear_id from account_report_report as ar cross join account_period as pr group by ar.id,pr.id,pr.fiscalyear_id)''')
212
213     def unlink(self, cr, uid, ids, context={}):
214         raise osv.except_osv(_('Error !'), _('You can not delete an indicator history record. You may have to delete the concerned Indicator!'))
215
216 account_report_history()
217
218 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
219