[IMP] removal of usages of the deprecated node.getchildren call, better usage of...
[odoo/odoo.git] / addons / account_voucher / account.py
1 # -*- encoding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution   
5 #    Copyright (C) 2004-2008 Tiny SPRL (<http://tiny.be>). All Rights Reserved
6 #    $Id$
7 #
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.
12 #
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.
17 #
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/>.
20 #
21 ##############################################################################
22
23 import time
24 import netsvc
25 from osv import fields, osv
26 import ir
27 import pooler
28 import mx.DateTime
29 from mx.DateTime import RelativeDateTime
30 from tools import config
31
32 class Account(osv.osv):
33     _inherit = "account.account"
34     
35     def _get_level(self, cr, uid, ids, field_name, arg, context={}):
36         res={}
37         acc_obj=self.browse(cr,uid,ids)
38         for aobj in acc_obj:
39             level = 0
40             if aobj.parent_id :
41                 obj=self.browse(cr,uid,aobj.parent_id.id)
42                 level= obj.level + 1
43             res[aobj.id] = level
44         return res
45     
46     def _get_children_and_consol(self, cr, uid, ids, context={}):
47         ids2=[]
48         temp=[]
49         read_data= self.read(cr, uid, ids,['id','child_id'], context)
50         for data in read_data:
51             ids2.append(data['id'])
52             if data['child_id']:
53                 temp=[]
54                 for x in data['child_id']:
55                     temp.append(x)
56                 ids2 += self._get_children_and_consol(cr, uid, temp, context)
57         return ids2
58
59     _columns = {
60
61         'journal_id':fields.many2one('account.journal', 'Journal',domain=[('type','=','situation')]),
62         'open_bal' : fields.float('Opening Balance',digits=(16,2)),
63         'level': fields.function(_get_level, string='Level', method=True, store=True, type='integer'),
64         'type1':fields.selection([('dr','Debit'),('cr','Credit'),('none','None')], 'Dr/Cr',store=True),
65     }
66     
67     def compute_total(self, cr, uid, ids, yr_st_date, yr_end_date, st_date, end_date, field_names, context={}, query=''):
68         #compute the balance/debit/credit accordingly to the value of field_name for the given account ids
69         mapping = {
70             'credit': "COALESCE(SUM(l.credit), 0) as credit ",
71             'balance': "COALESCE(SUM(l.debit),0) - COALESCE(SUM(l.credit), 0) as balance ",
72             'debit': "COALESCE(SUM(l.debit), 0) as debit ",
73         }
74         #get all the necessary accounts
75         ids2 = self._get_children_and_consol(cr, uid, ids, context)
76         acc_set = ",".join(map(str, ids2))
77         #compute for each account the balance/debit/credit from the move lines
78         if not (st_date >= yr_st_date and end_date <= yr_end_date):
79             return {}
80         accounts = {}
81         if ids2:
82             query = self.pool.get('account.move.line')._query_get(cr, uid,
83                     context=context)
84             cr.execute("SELECT l.account_id as id, "  \
85                     +  ' , '.join(map(lambda x: mapping[x], field_names.keys() ))  + \
86                     "FROM account_move_line l " \
87                     "WHERE l.account_id IN ("+ acc_set +") " \
88                         "AND " + query + " " \
89                         " AND l.date >= "+"'"+ st_date +"'"+" AND l.date <= "+"'"+ end_date +""+"'"" " \
90                     "GROUP BY l.account_id ")
91             for res in cr.dictfetchall():
92                 accounts[res['id']] = res
93         #for the asked accounts, get from the dictionnary 'accounts' the value of it
94         res = {}
95         for id in ids:
96             res[id] = self._get_account_values(cr, uid, id, accounts, field_names, context)
97         return res
98
99     def create(self, cr, uid, vals, context={}):
100         name=self.search(cr,uid,[('name','ilike',vals['name']),('company_id','=',vals['name'])])
101         if name:
102             raise osv.except_osv('Error', 'Account is Already Created !')
103         obj=self.pool.get('account.account.type').browse(cr,uid,vals['user_type'])
104         if obj.code in ('cash','asset','expense'):
105             vals['type1'] = 'dr'
106         elif obj.code in ('equity','income','liability') : 
107              vals['type1'] = 'cr'
108         else:
109              vals['type1'] = 'none'
110         journal_ids=self.pool.get('account.journal').search(cr,uid,[('name','=','Opening Journal')])
111         vals['journal_id'] = journal_ids and journal_ids[0] or False
112         account_id = super(Account, self).create(cr, uid, vals, context)
113         if vals.get('type1', False) != False:
114             journal_id = vals.get('journal_id',False)
115             if journal_id and vals.has_key('open_bal'):
116                 if vals['open_bal'] != 0.0:
117                     journal = self.pool.get('account.journal').browse(cr, uid, [journal_id])
118                     if journal and journal[0].sequence_id:
119                         name = self.pool.get('ir.sequence').get_id(cr, uid, journal[0].sequence_id.id)
120                     move=self.pool.get('account.move').search(cr,uid,[('journal_id','=',journal_id)])
121                     if not move:
122                         move = False
123                         move_data = {'name': name, 'journal_id': journal_id}
124                         move_id=self.pool.get('account.move').create(cr,uid,move_data)
125                         move_obj=self.pool.get('account.move').browse(cr,uid,move_id)
126                     else:
127                         move_obj=self.pool.get('account.move').browse(cr,uid,move[0])
128                     self_obj=self.browse(cr,uid,account_id)
129                     move_line = {
130                          'name':journal[0].name,
131                          'debit':self_obj.debit or False,
132                          'credit':self_obj.credit or False,
133                          'account_id':account_id or False,
134                          'move_id':move and move[0] or move_id,
135                          'journal_id':journal_id ,
136                          'period_id':move_obj.period_id.id,
137                  }
138                     if vals['type1'] == 'dr':
139                         move_line['debit'] = vals['open_bal'] or False
140                     elif vals['type1'] == 'cr':
141                         move_line['credit'] = vals['open_bal'] or False
142                     self.pool.get('account.move.line').create(cr,uid,move_line)
143         return account_id
144
145     def write(self, cr, uid, ids, vals, context=None, check=True, update_check=True):
146         res_temp={}
147         if vals.has_key('name'):
148             if not vals.has_key('company_id'):
149                 vals['company_id']=self.browse(cr,uid,ids)[0].company_id.id
150             name=self.search(cr,uid,[('name','ilike',vals['name']),('company_id','=',vals['company_id'])])
151             if name:
152                 raise osv.except_osv('Error', 'Same Account Name is Already present !')
153         if vals.has_key('user_type'):
154             obj=self.pool.get('account.account.type').browse(cr,uid,vals['user_type'])
155             if obj.code in ('asset','expense'):
156                 vals['type1'] = 'dr'
157             elif obj.code in ('income','liability') : 
158                  vals['type1'] = 'cr'
159             else:
160                  vals['type1'] = 'none'
161         super(Account, self).write(cr, uid,ids, vals, context)
162         if vals.has_key('open_bal'):
163             self_obj= self.browse(cr,uid,ids)
164             move_pool=self.pool.get('account.move')
165             if vals:
166                 for obj in self_obj:
167                     flg=0
168                     if obj.journal_id and obj.journal_id.type == 'situation':
169                         move=move_pool.search(cr,uid,[('journal_id','=',obj.journal_id.id)])
170                         if move:
171                             move_obj=move_pool.browse(cr,uid,move[0])
172                             move=move[0]
173                         else:
174                             name = self.pool.get('ir.sequence').get_id(cr, uid, obj.journal_id.sequence_id.id)
175                             move_data = {'name': name, 'journal_id': obj.journal_id.id}
176                             move=self.pool.get('account.move').create(cr,uid,move_data)
177                             move_obj=move_pool.browse(cr,uid,move)
178                         move_line_data={'name':obj.journal_id.name,
179                                                'debit':obj.debit or 0.0,
180                                                'credit':obj.credit or 0.0,
181                                                'account_id':obj.id,
182                                                'move_id':move,
183                                                'journal_id':obj.journal_id.id,
184                                                'period_id':move_obj.period_id.id,
185                                                }
186                         if obj.type1:
187                             if obj.type1 == 'dr':
188                                 move_line_data['debit'] = obj.open_bal
189                             elif obj.type1 == 'cr':
190                                 move_line_data['credit'] = obj.open_bal
191                         if move_obj and move:
192                             for move_line in move_obj.line_id:
193                                 if move_line.account_id.id == obj.id:
194                                     if move_line_data['debit'] == 0.0 and move_line_data['credit']== 0.0:
195                                         self.pool.get('account.move.line').unlink(cr,uid,[move_line.id])
196                                     else:
197                                         self.pool.get('account.move.line').write(cr,uid,[move_line.id],move_line_data)
198                                     flg=1
199                             if not flg:
200                                 self.pool.get('account.move.line').create(cr,uid,move_line_data)
201         return True
202
203     def onchange_type(self, cr, uid, ids,user_type,type1):
204         if not user_type:
205             return {'value' : {}}
206         type_obj=self.pool.get('account.account.type').browse(cr,uid,user_type)
207         if type_obj.code in ('asset','expense'):
208             type1 = 'dr'
209         elif type_obj.code in ('income','liability') :
210             type1 = 'cr'
211         else:
212             type1 = 'none'
213
214         return {
215             'value' : {'type1' : type1}
216     }
217 Account()
218
219 class AccountMove(osv.osv):
220     _inherit = "account.move"
221     _columns = {
222         'name':fields.char('Name', size=256, required=True, readonly=True, states={'draft':[('readonly',False)]}),
223         'narration':fields.text('Narration', readonly=True, select=True, states={'draft':[('readonly',False)]}),
224     }
225
226 AccountMove()
227
228 class res_currency(osv.osv):
229     _inherit = "res.currency"
230
231     _columns = {
232                 'sub_name': fields.char('Sub Currency', size=32, required=True)
233             }
234     _defaults = {
235         'sub_name': lambda *a: 'cents',
236
237     }
238 res_currency()
239
240 class account_account_template(osv.osv):
241         _inherit = "account.account.template"
242         
243         _columns = {
244         'type1':fields.selection([('dr','Debit'),('cr','Credit'),('none','None')], 'Dr/Cr',store=True),
245     }
246
247 account_account_template()
248
249