1 # -*- encoding: utf-8 -*-
2 ##############################################################################
4 # OpenERP, Open Source Management Solution
5 # Copyright (C) 2004-2008 Tiny SPRL (<http://tiny.be>). All Rights Reserved
8 # This program is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation, either version 3 of the License, or
11 # (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with this program. If not, see <http://www.gnu.org/licenses/>.
21 ##############################################################################
24 from osv import fields, osv
26 from tools.misc import currency
29 from mx.DateTime import RelativeDateTime, now, DateTime, localtime
32 class account_report(osv.osv):
33 _name = "account.report.report"
34 _description = "Account reporting"
41 # ('yellow','Yellow'),
43 # ('lightblue','Light Blue'),
44 # ('orange','Orange'),
55 def _amount_get(self, cr, uid, ids, field_name, arg, context={}):
56 obj_fy=self.pool.get('account.fiscalyear')
57 obj_period=self.pool.get('account.period')
59 def _calc_context(key,obj):
61 return obj.find(cr,uid)
63 obj_key=obj.browse(cr,uid,obj.find(cr,uid))
64 if isinstance(obj_key,list):
66 key_ids=obj.search(cr,uid,[('date_stop','<',obj_key.date_start)])
67 if len(key_ids)<abs(key):
71 def _calc_credit(code,year=0):
72 context['fiscalyear']=_calc_context(year,obj_fy)
73 if not context['fiscalyear']:
74 del context['fiscalyear']
75 acc = self.pool.get('account.account')
76 acc_id = acc.search(cr, uid, [('code','in',code)])
77 return reduce(lambda y,x=0: x.credit+y, acc.browse(cr, uid, acc_id, context),0.0)
79 def _calc_debit(code,year=0):
80 context['fiscalyear']=_calc_context(year,obj_fy)
81 if not context['fiscalyear']:
82 del context['fiscalyear']
83 acc = self.pool.get('account.account')
84 acc_id = acc.search(cr, uid, [('code','in',code)])
85 return reduce(lambda y,x=0: x.debit+y, acc.browse(cr, uid, acc_id, context),0.0)
87 def _calc_balance(code,year=0):
88 context['fiscalyear']=_calc_context(year,obj_fy)
89 if not context['fiscalyear']:
90 del context['fiscalyear']
91 acc = self.pool.get('account.account')
92 acc_id = acc.search(cr, uid, [('code','in',code)])
93 return reduce(lambda y,x=0: x.balance+y, acc.browse(cr, uid, acc_id, context),0.0)
95 def _calc_report(*code):
96 acc = self.pool.get('account.report.report')
97 acc_id = acc.search(cr, uid, [('code','in',code)])
98 return reduce(lambda y,x=0: x.amount+y, acc.browse(cr, uid, acc_id, context),0.0)
100 def _calc_tax_code(code,period=0):
101 context['period_id']=_calc_context(period,obj_period)
102 if not context['period_id']:
104 context['period_id']=context['period_id'][0]
105 acc = self.pool.get('account.tax.code')
106 acc_id = acc.search(cr, uid, [('code','in',code)])
107 return reduce(lambda y,x=0: x.sum_period+y, acc.browse(cr, uid, acc_id, context),0.0)
109 for rep in self.browse(cr, uid, ids, context):
111 'debit': _calc_debit,
112 'credit': _calc_credit,
113 'balance': _calc_balance,
114 'report': _calc_report,
115 'tax_code': _calc_tax_code,
117 # if field_name=='status':
118 # fld_name = 'expression_status'
120 # fld_name = 'expression'
122 val = eval(getattr(rep,'expression'), objdict)
126 if field_name=='status':
127 if val<rep.badness_limit:
128 result[rep.id] = 'very bad'
129 elif val==rep.badness_limit:
130 result[rep.id] = 'bad'
131 elif val<rep.goodness_limit:
132 result[rep.id] = 'normal'
133 elif val==rep.goodness_limit:
134 result[rep.id] = 'good'
136 result[rep.id] = 'very good'
141 def onchange_parent_id(self, cr, uid, ids, parent_id):
144 acc=self.pool.get('account.report.report').browse(cr,uid,parent_id)
146 # if int(acc.style) < 6:
147 # v['style'] = str(int(acc.style)+1)
151 'name': fields.char('Name', size=64, required=True),
152 'active': fields.boolean('Active'),
153 'sequence': fields.integer('Sequence'),
154 'code': fields.char('Code', size=64, required=True),
155 'type': fields.selection([
156 ('fiscal', 'Fiscal statement'),
157 ('indicator','Indicator'),
160 'Type', required=True),
161 'expression': fields.char('Expression', size=240, required=True),
162 # 'expression_status': fields.char('Status expression', size=240, required=True),
163 'badness_limit' :fields.float('Badness Indicator Limit', digits=(16,2),help='This Value depicts the limit of badness.'),
164 'goodness_limit' :fields.float('Goodness Indicator Limit', digits=(16,2),help='This Value depicts the limit of goodness.'),
165 'parent_id': fields.many2one('account.report.report', 'Parent'),
166 'child_ids': fields.one2many('account.report.report', 'parent_id', 'Childs'),
167 'note': fields.text('Note'),
168 'amount': fields.function(_amount_get, method=True, string='Value'),
169 'status': fields.function(_amount_get,
173 ('very bad', 'Very Bad'),
175 ('normal', 'Normal'),
177 ('very good', 'Very Good')
180 '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'),
181 '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.'),
182 # 'style': fields.selection(_style, 'Style', required=True),
183 # 'color_font' : fields.selection(_color, 'Font Color', help="Font Color for the report"),
184 # 'color_back' : fields.selection(_color, 'Back Color')
187 # 'style': lambda *args: '5',
188 'active': lambda *args: True,
189 'type': lambda *args: 'indicator',
192 def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=80):
199 ids = self.search(cr, user, [('code','=',name)]+ args, limit=limit, context=context)
201 ids = self.search(cr, user, [('name',operator,name)]+ args, limit=limit, context=context)
203 ids = self.search(cr, user, args, limit=limit, context=context)
204 return self.name_get(cr, user, ids, context=context)
207 #TODO Put an expression to valid expression and expression_status
210 ('code_uniq', 'unique (code)', 'The code of the report entry must be unique !')
215 class account_report_history(osv.osv):
217 def _calc_value(self, cr, uid, ids, name, args, context):
218 acc_report_id=self.read(cr,uid,ids,['tmp','period_id'])
220 for a in acc_report_id:
221 period_val=pooler.get_pool(cr.dbname).get('account.period').read(cr,uid,[a['period_id'][0]])[0]
222 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])])
223 tmp_ids[a['id']] = pooler.get_pool(cr.dbname).get('account.report.report').read(cr,uid,[a['tmp']],context={'periods':period_id})[0]['amount']
226 _name = "account.report.history"
227 _description = "Indicator"
228 _table = "account_report"
232 'period_id': fields.many2one('account.period','Period', readonly=True, select=True),
233 'fiscalyear_id': fields.many2one('account.fiscalyear','Fiscal Year', readonly=True, select=True),
234 'name': fields.many2one('account.report.report','Indicator', readonly=True, select=True),
235 'val': fields.function(_calc_value, method=True, string='Value', readonly=True),
236 'tmp' : fields.integer(string='temp',readonly=True)
240 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)''')
242 def unlink(self, cr, uid, ids, context={}):
243 raise osv.except_osv(_('Error !'), _('You can not delete an indicator history record. You may have to delete the concerned Indicator!'))
245 account_report_history()
247 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: