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

« back to all changes in this revision

Viewing changes to account_voucher/voucher.py

  • Committer: Mantavya Gajjar
  • Date: 2009-04-16 13:01:59 UTC
  • mto: (3589.23.3 addons-extra)
  • mto: This revision was merged to the branch mainline in revision 3608.
  • Revision ID: mga@tinyerp.com-20090416130159-z5ec22atycrwcl1v
uploda the new reviewd clean code for the indian accounting

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-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 ir_sequence_type(osv.osv):
 
33
    _inherit = "ir.sequence.type"
 
34
    _columns = {
 
35
        'name': fields.char('Sequence Name',size=128, required=True),
 
36
        'code': fields.char('Sequence Code',size=128, required=True),
 
37
    }
 
38
ir_sequence_type()
 
39
 
 
40
class account_voucher(osv.osv):
 
41
    def _get_period(self, cr, uid, context):
 
42
        periods = self.pool.get('account.period').find(cr, uid)
 
43
        if periods:
 
44
            return periods[0]
 
45
        else:
 
46
            return False
 
47
        
 
48
    def _get_type(self, cr, uid, context={}):
 
49
        type = context.get('type', 'rec_voucher')
 
50
        return type
 
51
    
 
52
    def _get_reference_type(self, cursor, user, context=None):
 
53
        return [('none', 'Free Reference')]
 
54
    
 
55
    def _get_journal(self, cr, uid, context):
 
56
        type_inv = 'rec_voucher'
 
57
        
 
58
        if type(context) == type(''):
 
59
            type_inv = context
 
60
        elif type(context) == type({}):
 
61
            type_inv = context.get('type', 'rec_voucher')
 
62
 
 
63
        type2journal = {
 
64
            'rec_voucher': 'cash', 
 
65
            'bank_rec_voucher': 'cash',
 
66
            'pay_voucher': 'cash',
 
67
            'bank_pay_voucher': 'cash', 
 
68
            'cont_voucher': 'cash',
 
69
            'journal_sale_vou': 'sale',
 
70
            'journal_pur_voucher': 'purchase',
 
71
            'journal_voucher':'expanse'
 
72
        }
 
73
        
 
74
        journal_obj = self.pool.get('account.journal')
 
75
        ttype = type2journal.get(type_inv, 'cash')
 
76
        res = journal_obj.search(cr, uid, [('type', '=', ttype)], limit=1)
 
77
        
 
78
        if res:
 
79
            return res[0]
 
80
        else:
 
81
            return False
 
82
        
 
83
    def _get_currency(self, cr, uid, context):
 
84
        user = pooler.get_pool(cr.dbname).get('res.users').browse(cr, uid, [uid])[0]
 
85
        if user.company_id:
 
86
            return user.company_id.currency_id.id
 
87
        else:
 
88
            return pooler.get_pool(cr.dbname).get('res.currency').search(cr, uid, [('rate','=',1.0)])[0]
 
89
        
 
90
    _name = 'account.voucher'
 
91
    _description = 'Accounting Voucher'
 
92
    _order = "number"
 
93
    _columns = {
 
94
        'name':fields.char('Name', size=256, required=True, readonly=True, states={'draft':[('readonly',False)]}),
 
95
        'type': fields.selection([
 
96
            ('pay_voucher','Cash Payment Voucher'),
 
97
            ('bank_pay_voucher','Bank Payment Voucher'),
 
98
            ('rec_voucher','Cash Receipt Voucher'),
 
99
            ('bank_rec_voucher','Bank Receipt Voucher'),
 
100
            ('cont_voucher','Contra Voucher'),
 
101
            ('journal_sale_vou','Journal Sale Voucher'),
 
102
            ('journal_pur_voucher','Journal Purchase Voucher'),
 
103
            ('journal_voucher','Journal Voucher'),
 
104
            ],'Type', readonly=True, select=True , size=128),
 
105
        'date':fields.date('Date', readonly=True, states={'draft':[('readonly',False)]}),
 
106
        'journal_id':fields.many2one('account.journal', 'Journal', required=True, readonly=True, states={'draft':[('readonly',False)]}),
 
107
        'account_id':fields.many2one('account.account', 'Account', required=True, readonly=True, states={'draft':[('readonly',False)]}),
 
108
        'payment_ids':fields.one2many('account.voucher.line','voucher_id','Voucher Lines', readonly=False, states={'proforma':[('readonly',True)]}),
 
109
        'period_id': fields.many2one('account.period', 'Period', required=True, states={'posted':[('readonly',True)]}),
 
110
        'narration':fields.text('Narration', readonly=True, states={'draft':[('readonly',False)]}, required=True),
 
111
        'currency_id': fields.many2one('res.currency', 'Currency', required=True, readonly=True, states={'draft':[('readonly',False)]}),
 
112
        'company_id': fields.many2one('res.company', 'Company', required=True),
 
113
        'state':fields.selection(
 
114
                    [('draft','Draft'),
 
115
                     ('proforma','Pro-forma'),
 
116
                     ('posted','Posted'),
 
117
                     ('cancel','Cancel')
 
118
                    ], 'State', 
 
119
                    readonly=True),
 
120
        'amount':fields.float('Amount', readonly=True),
 
121
#        , states={'draft':[('readonly',False)]}
 
122
        'number':fields.char('Number', size=32, readonly=True),
 
123
        'reference': fields.char('Voucher Reference', size=64),
 
124
        'reference_type': fields.selection(_get_reference_type, 'Reference Type',
 
125
            required=True),
 
126
        'move_id':fields.many2one('account.move', 'Account Entry'),
 
127
        'move_ids':fields.many2many('account.move.line', 'voucher_id', 'account_id', 'rel_account_move', 'Real Entry'),
 
128
        'partner_id':fields.many2one('res.partner', 'Partner', readonly=True, states={'draft':[('readonly',False)]})
 
129
    }
 
130
    
 
131
    _defaults = {
 
132
        'state': lambda *a: 'draft',
 
133
        'date' : lambda *a: time.strftime('%Y-%m-%d'),
 
134
        'period_id': _get_period,
 
135
        'type': _get_type,
 
136
        'reference_type': lambda *a: 'none',
 
137
        'journal_id':_get_journal,
 
138
        'company_id': lambda self, cr, uid, context: \
 
139
                self.pool.get('res.users').browse(cr, uid, uid,
 
140
                    context=context).company_id.id,
 
141
        'currency_id': _get_currency,
 
142
    }
 
143
    
 
144
    def _get_analityc_lines(self, cr, uid, id):
 
145
        inv = self.browse(cr, uid, [id])[0]
 
146
        cur_obj = self.pool.get('res.currency')
 
147
        
 
148
    def onchange_account(self, cr, uid, ids, account_id):
 
149
        if not account_id:
 
150
            return {'value':{'amount':False}}
 
151
        account = self.pool.get('account.account').browse(cr,uid,account_id)
 
152
        balance=account.balance
 
153
        return {'value':{'amount':balance}}
 
154
 
 
155
    def onchange_journal(self, cr, uid, ids, journal_id,type):
 
156
        if not journal_id:
 
157
            return {'value':{'account_id':False}}
 
158
        journal = self.pool.get('account.journal')
 
159
        if journal_id and (type in ('rec_voucher','bank_rec_voucher','journal_pur_voucher','journal_voucher')):
 
160
            account_id = journal.browse(cr, uid, journal_id).default_debit_account_id
 
161
            return {'value':{'account_id':account_id.id}}
 
162
        elif journal_id and (type in ('pay_voucher','bank_pay_voucher','journal_sale_vou')) :
 
163
                account_id = journal.browse(cr, uid, journal_id).default_credit_account_id
 
164
                return {'value':{'account_id':account_id.id}}
 
165
        else:
 
166
            account_id = journal.browse(cr, uid, journal_id).default_credit_account_id
 
167
            return {'value':{'account_id':account_id.id}}
 
168
        
 
169
    def open_voucher(self, cr, uid, ids, context={}):
 
170
        obj=self.pool.get('account.voucher').browse(cr,uid,ids)
 
171
        total=0
 
172
        for i in obj[0].payment_ids:
 
173
            total+=i.amount
 
174
        self.write(cr,uid,ids,{'amount':total})
 
175
        self.write(cr, uid, ids, {'state':'proforma'})
 
176
        return True
 
177
    
 
178
    def proforma_voucher(self, cr, uid, ids, context={}):
 
179
        self.action_move_line_create(cr, uid, ids)
 
180
        self.action_number(cr, uid, ids)
 
181
        self.write(cr, uid, ids, {'state':'posted'})
 
182
        return True
 
183
    
 
184
    def cancel_voucher(self,cr,uid,ids,context={}):
 
185
        self.action_cancel(cr, uid, ids)
 
186
        self.write(cr, uid, ids, {'state':'cancel'})
 
187
        return True
 
188
        
 
189
    def action_cancel_draft(self, cr, uid, ids, *args):
 
190
        self.write(cr, uid, ids, {'state':'draft'})
 
191
        return True
 
192
 
 
193
    def unlink(self, cr, uid, ids, context={}):
 
194
        vouchers = self.read(cr, uid, ids, ['state'])
 
195
        unlink_ids = []
 
196
        for t in vouchers:
 
197
            if t['state'] in ('draft', 'cancel'):
 
198
                unlink_ids.append(t['id'])
 
199
            else:
 
200
                raise osv.except_osv('Invalid action !', 'Cannot delete invoice(s) which are already opened or paid !')
 
201
        osv.osv.unlink(self, cr, uid, unlink_ids)
 
202
        return True
 
203
    
 
204
#    def _get_analityc_lines(self, cr, uid, id):
 
205
#        inv = self.browse(cr, uid, [id])[0]
 
206
#        cur_obj = self.pool.get('res.currency')
 
207
#
 
208
#        company_currency = inv.company_id.currency_id.id
 
209
#        
 
210
#        if inv.type in ('rec_voucher,bank_rec_voucher,cont_voucher,journal_pur_voucher'):
 
211
#            sign = 1
 
212
#        else:
 
213
#            sign = -1
 
214
#
 
215
#        iml = self.pool.get('account.voucher.line').move_line_get(cr, uid, inv.id)
 
216
#        
 
217
#        for il in iml:
 
218
#            if il['account_analytic_id']:
 
219
#                if inv.type in ('pay_voucher','journal_voucher', 'rec_voucher','cont_voucher','bank_pay_voucher','bank_rec_voucher','journal_sale_vou','journal_pur_voucher'):
 
220
#                    ref = inv.reference
 
221
#                else:
 
222
#                    ref = self._convert_ref(cr, uid, inv.number)
 
223
#
 
224
#                il['analytic_lines'] = [(0,0, {
 
225
#                    'name': il['name'],
 
226
#                    'date': inv['date'],
 
227
#                    'account_id': il['account_analytic_id'] or False,
 
228
#                    'amount': inv['amount'] * sign,
 
229
#                    'general_account_id': il['account_id'] or False,
 
230
#                    'journal_id': inv.journal_id.analytic_journal_id.id,
 
231
#                    'ref': ref,
 
232
#                })]
 
233
#
 
234
#        return iml
 
235
#    
 
236
#    def action_move_line_create(self, cr, uid, ids, *args):
 
237
#        for inv in self.browse(cr, uid, ids):
 
238
#            if inv.move_id:
 
239
#                continue
 
240
#            company_currency = inv.company_id.currency_id.id
 
241
#            # create the analytical lines
 
242
#            line_ids = self.read(cr, uid, [inv.id], ['payment_ids'])[0]['payment_ids']
 
243
#            ils = self.pool.get('account.voucher.line').read(cr, uid, line_ids)
 
244
#            # one move line per invoice line
 
245
#            iml = self._get_analityc_lines(cr, uid, inv.id)
 
246
#            # check if taxes are all computed
 
247
#            diff_currency_p = inv.currency_id.id <> company_currency
 
248
#            # create one move line for the total and possibly adjust the other lines amount
 
249
#            total = 0
 
250
#            if inv.type in ('pay_voucher', 'journal_voucher', 'rec_voucher','cont_voucher','bank_pay_voucher','bank_rec_voucher','journal_sale_vou','journal_pur_voucher'):
 
251
#                ref = inv.reference
 
252
#                
 
253
#            else:
 
254
#                ref = self._convert_ref(cr, uid, inv.number)
 
255
#                
 
256
#            date = inv.date
 
257
#            total_currency = 0
 
258
#            for i in iml:
 
259
#                    
 
260
#                if inv.currency_id.id != company_currency:
 
261
#                    i['currency_id'] = inv.currency_id.id
 
262
#                    i['amount_currency'] = i['amount']
 
263
#                    
 
264
#                else:
 
265
#                    i['amount_currency'] = False
 
266
#                    i['currency_id'] = False
 
267
#                ref = i['ref']
 
268
#                if inv.type in ('rec_voucher','bank_rec_voucher','journal_pur_voucher','journal_voucher'):
 
269
#                    total += i['amount']
 
270
#                    total_currency += i['amount_currency'] or i['amount']
 
271
#                    i['amount'] = - i['amount']
 
272
#                else:
 
273
#                    total -= i['amount']
 
274
#                    total_currency -= i['amount_currency'] or i['amount']
 
275
#            acc_id = inv.account_id.id
 
276
#
 
277
#            name = inv['name'] or '/'
 
278
#            totlines = False
 
279
#
 
280
#            iml.append({
 
281
#                'type': 'dest',
 
282
#                'name': name,
 
283
#                'amount': total,
 
284
#                'account_id': acc_id,
 
285
#                'amount_currency': diff_currency_p \
 
286
#                        and total_currency or False,
 
287
#                'currency_id': diff_currency_p \
 
288
#                        and inv.currency_id.id or False,
 
289
#                'ref': ref,
 
290
#                'partner_id':inv.partner_id.id or False,
 
291
#            })
 
292
#
 
293
#            date = inv.date
 
294
#            inv.amount=total
 
295
#
 
296
#            line = map(lambda x:(0,0,self.line_get_convert(cr, uid, x,date, context={})) ,iml)
 
297
#
 
298
#            journal_id = inv.journal_id.id #self._get_journal(cr, uid, {'type': inv['type']})
 
299
#            journal = self.pool.get('account.journal').browse(cr, uid, journal_id)
 
300
#            if journal.sequence_id:
 
301
#                name = self.pool.get('ir.sequence').get_id(cr, uid, journal.sequence_id.id)
 
302
#
 
303
#            move = {'name': name, 'line_id': line, 'journal_id': journal_id, 'type':inv.type}
 
304
#            if inv.period_id:
 
305
#                move['period_id'] = inv.period_id.id
 
306
#                for i in line:
 
307
#                    i[2]['period_id'] = inv.period_id.id
 
308
#            move_id = self.pool.get('account.move').create(cr, uid, move)
 
309
#            # make the invoice point to that move
 
310
#            self.write(cr, uid, [inv.id], {'move_id': move_id})
 
311
#            obj=self.pool.get('account.move').browse(cr,uid,move_id)
 
312
#            for line in obj.line_id :
 
313
#                cr.execute('insert into voucher_id (account_id,rel_account_move) values (%d, %d)',(int(ids[0]),int(line.id)))
 
314
##            self.pool.get('account.move').post(cr, uid, [move_id])
 
315
##        self._log_event(cr, uid, ids)
 
316
#        return True
 
317
         
 
318
    def _get_analytic_lines(self, cr, uid, id):
 
319
        inv = self.browse(cr, uid, [id])[0]
 
320
        cur_obj = self.pool.get('res.currency')
 
321
 
 
322
        company_currency = inv.company_id.currency_id.id
 
323
        if inv.type in ('rec_voucher'):
 
324
            sign = 1
 
325
        else:
 
326
            sign = -1
 
327
 
 
328
        iml = self.pool.get('account.voucher.line').move_line_get(cr, uid, inv.id)
 
329
        
 
330
        for il in iml:
 
331
            if il['account_analytic_id']:
 
332
                if inv.type in ('pay_voucher', 'rec_voucher','cont_voucher','bank_pay_voucher','bank_rec_voucher','journal_sale_voucher','journal_pur_voucher'):
 
333
                    ref = inv.reference
 
334
                else:
 
335
                    ref = self._convert_ref(cr, uid, inv.number)
 
336
                    
 
337
                il['analytic_lines'] = [(0, 0, {
 
338
                    'name': il['name'],
 
339
                    'date': inv['date'],
 
340
                    'account_id': il['account_analytic_id'],
 
341
                    'amount': inv['amount'] * sign,
 
342
                    'general_account_id': il['account_id'] or False,
 
343
                    'journal_id': self.pool.get('account.voucher').browse(cr, uid, id).journal_id.analytic_journal_id.id or False,
 
344
                    'ref': ref,
 
345
                })]
 
346
        return iml
 
347
    
 
348
    def action_move_line_create(self, cr, uid, ids, *args):
 
349
        
 
350
        for inv in self.browse(cr, uid, ids):
 
351
            if inv.move_id:
 
352
                continue
 
353
            company_currency = inv.company_id.currency_id.id
 
354
 
 
355
            line_ids = self.read(cr, uid, [inv.id], ['payment_ids'])[0]['payment_ids']
 
356
            ils = self.pool.get('account.voucher.line').read(cr, uid, line_ids)
 
357
 
 
358
            iml = self._get_analytic_lines(cr, uid, inv.id)
 
359
 
 
360
            diff_currency_p = inv.currency_id.id <> company_currency
 
361
 
 
362
            total = 0
 
363
            if inv.type in ('pay_voucher', 'journal_voucher', 'rec_voucher','cont_voucher','bank_pay_voucher','bank_rec_voucher','journal_sale_voucher','journal_pur_voucher'):
 
364
                ref = inv.reference
 
365
            else:
 
366
                ref = self._convert_ref(cr, uid, inv.number)
 
367
                
 
368
            date = inv.date
 
369
            total_currency = 0
 
370
            for i in iml:
 
371
                partner_id=i['partner_id']
 
372
                acc_id = i['account_id']    
 
373
                if inv.currency_id.id != company_currency:
 
374
                    i['currency_id'] = inv.currency_id.id
 
375
                    i['amount_currency'] = i['amount']
 
376
                else:
 
377
                    i['amount_currency'] = False
 
378
                    i['currency_id'] = False
 
379
                if inv.type in ('rec_voucher','bank_rec_voucher','journal_pur_voucher','journal_voucher'):
 
380
                    total += i['amount']
 
381
                    total_currency += i['amount_currency'] or i['amount']
 
382
                    i['amount'] = - i['amount']
 
383
                else:
 
384
                    total -= i['amount']
 
385
                    total_currency -= i['amount_currency'] or i['amount']
 
386
 
 
387
            name = inv['name'] or '/'
 
388
            totlines = False
 
389
 
 
390
            iml.append({
 
391
                'type': 'dest',
 
392
                'name': name,
 
393
                'amount': total or False,
 
394
                'account_id': acc_id,
 
395
                'amount_currency': diff_currency_p \
 
396
                        and total_currency or False,
 
397
                'currency_id': diff_currency_p \
 
398
                        and inv.currency_id.id or False,
 
399
                'ref': ref,
 
400
                'partner_id':partner_id or False,
 
401
            })
 
402
 
 
403
            date = inv.date
 
404
            inv.amount=total
 
405
 
 
406
            line = map(lambda x:(0,0,self.line_get_convert(cr, uid, x,date, context={})) ,iml)
 
407
            an_journal_id=inv.journal_id.analytic_journal_id.id
 
408
            journal_id = inv.journal_id.id
 
409
            
 
410
            journal = self.pool.get('account.journal').browse(cr, uid, journal_id)
 
411
            if journal.sequence_id:
 
412
                name = self.pool.get('ir.sequence').get_id(cr, uid, journal.sequence_id.id)
 
413
 
 
414
            move = {'name': name, 'journal_id': journal_id}
 
415
            
 
416
            if inv.period_id:
 
417
                move['period_id'] = inv.period_id.id
 
418
                for i in line:
 
419
                    i[2]['period_id'] = inv.period_id.id
 
420
            move_id = self.pool.get('account.move').create(cr, uid, move)
 
421
            ref=move['name']
 
422
            amount=0.0
 
423
            
 
424
            #create the first line our self
 
425
            move_line = {
 
426
                'name': inv.name,
 
427
                'debit': False,
 
428
                'credit':False,
 
429
                'account_id': inv.account_id.id or False,
 
430
                'move_id':move_id ,
 
431
                'journal_id':journal_id ,
 
432
                'period_id':inv.period_id.id,
 
433
                'partner_id': False,
 
434
                'ref': ref, 
 
435
                'date': inv.date
 
436
            }
 
437
            if inv.type in ('rec_voucher', 'bank_rec_voucher', 'journal_pur_voucher', 'journal_voucher'):
 
438
                move_line['debit'] = inv.amount
 
439
            else:
 
440
                move_line['credit'] = inv.amount * (-1)
 
441
            self.pool.get('account.move.line').create(cr, uid, move_line)
 
442
            
 
443
            for line in inv.payment_ids:
 
444
                
 
445
                move_line = {
 
446
                    'name':line.name,
 
447
                     'debit':False,
 
448
                     'credit':False,
 
449
                     'account_id':line.account_id.id or False,
 
450
                     'move_id':move_id ,
 
451
                     'journal_id':journal_id ,
 
452
                     'period_id':inv.period_id.id,
 
453
                     'partner_id':line.partner_id.id or False,
 
454
                     'ref':ref, 
 
455
                     'date':inv.date
 
456
                 }
 
457
                
 
458
                if line.type == 'dr':
 
459
                    move_line['debit'] = line.amount or False
 
460
                    amount=line.amount
 
461
                elif line.type == 'cr':
 
462
                    move_line['credit'] = line.amount or False
 
463
                    amount=line.amount * (-1)
 
464
                
 
465
                ml_id=self.pool.get('account.move.line').create(cr, uid, move_line)
 
466
                
 
467
                if inv.narration:
 
468
                    line.name=inv.narration
 
469
                else:
 
470
                    line.name=line.name
 
471
                
 
472
                if line.account_analytic_id:
 
473
                    an_line = {
 
474
                         'name':line.name,
 
475
                         'date':inv.date,
 
476
                         'amount':amount,
 
477
                         'account_id':line.account_analytic_id.id or False,
 
478
                         'move_id':ml_id,
 
479
                         'journal_id':an_journal_id ,
 
480
                         'general_account_id':line.account_id.id,
 
481
                         'ref':ref
 
482
                     }
 
483
                    self.pool.get('account.analytic.line').create(cr,uid,an_line)
 
484
                
 
485
            self.write(cr, uid, [inv.id], {'move_id': move_id})
 
486
            obj=self.pool.get('account.move').browse(cr, uid, move_id)
 
487
            
 
488
            for line in obj.line_id :
 
489
                cr.execute('insert into voucher_id (account_id,rel_account_move) values (%d, %d)',(int(ids[0]),int(line.id)))
 
490
                
 
491
        return True
 
492
 
 
493
    
 
494
    def line_get_convert(self, cr, uid, x, date, context={}):
 
495
       
 
496
        return {
 
497
            'date':date,
 
498
            'date_maturity': x.get('date_maturity', False),
 
499
            'partner_id':x.get('partner_id',False),
 
500
            'name':x['name'][:64],
 
501
            'debit':x['amount']>0 and x['amount'],
 
502
            'credit':x['amount']<0 and -x['amount'],
 
503
            'account_id':x['account_id'],
 
504
            'analytic_lines':x.get('analytic_lines', []),
 
505
            'amount_currency':x.get('amount_currency', False),
 
506
            'currency_id':x.get('currency_id', False),
 
507
            'tax_code_id': x.get('tax_code_id', False),
 
508
            'tax_amount': x.get('tax_amount', False),
 
509
            'ref':x.get('ref',False)
 
510
        }
 
511
    def _convert_ref(self, cr, uid, ref):
 
512
        return (ref or '').replace('/','')
 
513
    
 
514
    
 
515
    def action_number(self, cr, uid, ids, *args):
 
516
        cr.execute('SELECT id, type, number, move_id, reference ' \
 
517
                'FROM account_voucher ' \
 
518
                'WHERE id IN ('+','.join(map(str,ids))+')')
 
519
        for (id, invtype, number, move_id, reference) in cr.fetchall():
 
520
            if not number:
 
521
                number = self.pool.get('ir.sequence').get(cr, uid,
 
522
                        'account.voucher.' + invtype)
 
523
 
 
524
                if type in ('pay_voucher', 'journal_voucher', 'rec_voucher','cont_voucher','bank_pay_voucher','bank_rec_voucher','journal_sale_vou','journal_pur_voucher'):
 
525
                    ref = reference
 
526
                else:
 
527
                    ref = self._convert_ref(cr, uid, number)
 
528
                    
 
529
                cr.execute('UPDATE account_voucher SET number=%s ' \
 
530
                        'WHERE id=%d', (number, id))
 
531
                cr.execute('UPDATE account_move_line SET ref=%s ' \
 
532
                        'WHERE move_id=%d AND (ref is null OR ref = \'\')',
 
533
                        (ref, move_id))
 
534
                cr.execute('UPDATE account_analytic_line SET ref=%s ' \
 
535
                        'FROM account_move_line ' \
 
536
                        'WHERE account_move_line.move_id = %d ' \
 
537
                            'AND account_analytic_line.move_id = account_move_line.id',
 
538
                            (ref, move_id))
 
539
        return True
 
540
 
 
541
 
 
542
    
 
543
    def name_get(self, cr, uid, ids, context={}):
 
544
        if not len(ids):
 
545
            return []
 
546
        types = {
 
547
                'pay_voucher': 'CPV: ',
 
548
                'rec_voucher': 'CRV: ',
 
549
                'cont_voucher': 'CV: ',
 
550
                'bank_pay_voucher': 'BPV: ',
 
551
                'bank_rec_voucher': 'BRV: ',
 
552
                'journal_sale_vou': 'JSV: ',
 
553
                'journal_pur_voucher': 'JPV: ',
 
554
                'journal_voucher':'JV'
 
555
        }
 
556
        return [(r['id'], types[r['type']]+(r['number'] or '')+' '+(r['name'] or '')) for r in self.read(cr, uid, ids, ['type', 'number', 'name'], context, load='_classic_write')]
 
557
 
 
558
    def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=80):
 
559
        if not args:
 
560
            args=[]
 
561
        if not context:
 
562
            context={}
 
563
        ids = []
 
564
        if name:
 
565
            ids = self.search(cr, user, [('number','=',name)]+ args, limit=limit, context=context)
 
566
        if not ids:
 
567
            ids = self.search(cr, user, [('name',operator,name)]+ args, limit=limit, context=context)
 
568
        return self.name_get(cr, user, ids, context)
 
569
    
 
570
    def copy(self, cr, uid, id, default=None, context=None):
 
571
        if default is None:
 
572
            default = {}
 
573
        default = default.copy()
 
574
        default.update({'state':'draft', 'number':False, 'move_id':False, 'move_ids':False})
 
575
        if 'date' not in default:
 
576
            default['date'] = time.strftime('%Y-%m-%d')
 
577
        return super(account_voucher, self).copy(cr, uid, id, default, context)
 
578
    
 
579
    def action_cancel(self, cr, uid, ids, *args):
 
580
        account_move_obj = self.pool.get('account.move')
 
581
        voucher = self.read(cr, uid, ids, ['move_id'])
 
582
        for i in voucher:
 
583
            if i['move_id']:
 
584
                account_move_obj.button_cancel(cr, uid, [i['move_id'][0]])
 
585
                # delete the move this invoice was pointing to
 
586
                # Note that the corresponding move_lines and move_reconciles
 
587
                # will be automatically deleted too
 
588
                account_move_obj.unlink(cr, uid, [i['move_id'][0]])
 
589
        self.write(cr, uid, ids, {'state':'cancel', 'move_id':False})
 
590
#        self._log_event(cr, uid, ids,-1.0, 'Cancel Invoice')
 
591
        return True
 
592
    
 
593
account_voucher()
 
594
 
 
595
class VoucherLine(osv.osv):
 
596
    _name = 'account.voucher.line'
 
597
    _description = 'Voucher Line'
 
598
    _columns = {
 
599
        'voucher_id':fields.many2one('account.voucher', 'Voucher'),
 
600
        'name':fields.char('Description', size=256, required=True),
 
601
        'account_id':fields.many2one('account.account','Account', required=True),
 
602
        'partner_id': fields.many2one('res.partner', 'Partner', change_default=True),
 
603
        'amount':fields.float('Amount'),
 
604
        'type':fields.selection([('dr','Debit'),('cr','Credit')], 'Type'),
 
605
        'ref':fields.char('Ref.', size=32),
 
606
        'account_analytic_id':  fields.many2one('account.analytic.account', 'Analytic Account')
 
607
    }
 
608
    _defaults = {
 
609
        'type': lambda *a: 'cr'
 
610
    }
 
611
    
 
612
#    def default_get(self, cr, uid, fields, context={}):
 
613
#        # Compute simple values
 
614
#        data = super(VoucherLine, self).default_get(cr, uid, fields, context)
 
615
#        # Starts: Manual entry from account.move form
 
616
#        if context.get('lines',[]):
 
617
#            type=""
 
618
#            total_new=0.00
 
619
#            sum ={
 
620
#                  'dr':0.0,
 
621
#                  'cr':0.0
 
622
#                  }
 
623
#            for i in context['lines']:
 
624
#                if i[2]['type']=='dr':
 
625
#                    sum['dr'] += i[2]['amount']
 
626
#                else:
 
627
#                    sum['cr'] += i[2]['amount']
 
628
#                for item in i[2]:
 
629
#                    data[item]=i[2][item]
 
630
#                total_new=max(sum['cr'],sum['dr'])-min(sum['cr'],sum['dr'])
 
631
#                if sum['cr'] > sum['dr']:
 
632
#                    type = 'cr'
 
633
#                else:
 
634
#                    type= 'dr'
 
635
#                types = ['cr','dr']
 
636
#                data['type']= types[-1 - (types.index(type))]
 
637
#            data['amount']=total_new
 
638
#            if context['journal']:
 
639
#                journal_obj=self.pool.get('account.journal').browse(cr,uid,context['journal'])
 
640
#                if journal_obj.type == 'purchase':
 
641
#                    if total_new>0:
 
642
#                        account = journal_obj.default_credit_account_id
 
643
#                    else:
 
644
#                        account = journal_obj.default_debit_account_id
 
645
#                else:
 
646
#                    if total_new>0:
 
647
#                        account = journal_obj.default_credit_account_id
 
648
#                    else:
 
649
#                        account = journal_obj.default_debit_account_id
 
650
#                data['account_id'] =  account.id
 
651
#        return data
 
652
#        # Ends: Manual entry from account.move form
 
653
 
 
654
    def move_line_get(self, cr, uid, voucher_id, context={}):
 
655
        res = []
 
656
 
 
657
        cur_obj = self.pool.get('res.currency')
 
658
        inv = self.pool.get('account.voucher').browse(cr, uid, voucher_id)
 
659
        company_currency = inv.company_id.currency_id.id
 
660
        cur = inv.currency_id
 
661
 
 
662
        for line in inv.payment_ids:
 
663
            res.append(self.move_line_get_item(cr, uid, line, context))
 
664
        return res
 
665
    
 
666
    def onchange_partner(self, cr, uid, ids, partner_id, type,type1):
 
667
        if not partner_id:
 
668
            return {'value' : {'account_id' : False, 'type' : False ,'amount':False}}
 
669
        obj = self.pool.get('res.partner')
 
670
        account_id = False
 
671
        
 
672
        if type1 in ('rec_voucher','bank_rec_voucher', 'journal_voucher'):
 
673
            account_id = obj.browse(cr, uid, partner_id).property_account_receivable
 
674
            balance=obj.browse(cr,uid,partner_id).credit
 
675
            type = 'cr'
 
676
        elif type1 in ('pay_voucher','bank_pay_voucher','cont_voucher') : 
 
677
            account_id = obj.browse(cr, uid, partner_id).property_account_payable
 
678
            balance=obj.browse(cr,uid,partner_id).debit
 
679
            type = 'dr'
 
680
        elif type1 in ('journal_sale_vou') : 
 
681
            account_id = obj.browse(cr, uid, partner_id).property_account_receivable
 
682
            balance=obj.browse(cr,uid,partner_id).credit
 
683
            type = 'dr'
 
684
        elif type1 in ('journal_pur_voucher') : 
 
685
            account_id = obj.browse(cr, uid, partner_id).property_account_payable
 
686
            balance=obj.browse(cr,uid,partner_id).debit
 
687
            type = 'cr'
 
688
 
 
689
        return {
 
690
            'value' : {'account_id' : account_id.id, 'type' : type, 'amount':balance}
 
691
        }
 
692
        
 
693
    def onchange_amount(self, cr, uid, ids,partner_id,amount, type,type1):
 
694
        if not amount:
 
695
            return {'value' : {}}
 
696
        if partner_id:
 
697
            
 
698
            obj = self.pool.get('res.partner')
 
699
            if type1 in ('rec_voucher', 'bank_rec_voucher', 'journal_voucher'):
 
700
                if amount < 0 :
 
701
                    account_id = obj.browse(cr, uid, partner_id).property_account_payable 
 
702
                    type = 'dr'
 
703
                else:
 
704
                    account_id = obj.browse(cr, uid, partner_id).property_account_receivable 
 
705
                    type = 'cr'
 
706
               
 
707
            elif type1 in ('pay_voucher','bank_pay_voucher','cont_voucher') : 
 
708
                if amount < 0 :
 
709
                    account_id = obj.browse(cr, uid, partner_id).property_account_receivable 
 
710
                    type = 'cr'
 
711
                else:
 
712
                    account_id = obj.browse(cr, uid, partner_id).property_account_payable
 
713
                    type = 'dr'
 
714
                    
 
715
            elif type1 in ('journal_sale_vou') : 
 
716
                if amount < 0 :
 
717
                    account_id = obj.browse(cr, uid, partner_id).property_account_payable
 
718
                    type = 'cr'
 
719
                else:
 
720
                    account_id = obj.browse(cr, uid, partner_id).property_account_receivable
 
721
                    type = 'dr'
 
722
                
 
723
            elif type1 in ('journal_pur_voucher') : 
 
724
                if amount< 0 :
 
725
                    account_id = obj.browse(cr, uid, partner_id).property_account_receivable
 
726
                    type = 'dr'
 
727
                else:
 
728
                    account_id = obj.browse(cr, uid, partner_id).property_account_payable
 
729
                    type = 'cr'
 
730
        else:
 
731
            if type1 in ('rec_voucher', 'bank_rec_voucher', 'journal_voucher'):
 
732
                if amount < 0 :
 
733
                     
 
734
                    type = 'dr'
 
735
                else:
 
736
                   
 
737
                    type = 'cr'
 
738
               
 
739
            elif type1 in ('pay_voucher','bank_pay_voucher','cont_voucher') : 
 
740
                if amount < 0 :
 
741
                    
 
742
                    type = 'cr'
 
743
                else:
 
744
                   
 
745
                    type = 'dr'
 
746
                    
 
747
            elif type1 in ('journal_sale_vou') : 
 
748
                if amount < 0 :
 
749
                   
 
750
                    type = 'cr'
 
751
                else:
 
752
                   
 
753
                    type = 'dr'
 
754
                
 
755
            elif type1 in ('journal_pur_voucher') : 
 
756
                if amount< 0 :
 
757
                    
 
758
                    type = 'dr'
 
759
                else:
 
760
                   
 
761
                    type = 'cr'
 
762
                
 
763
        return {
 
764
            'value' : { 'type' : type , 'amount':amount}
 
765
        }
 
766
        
 
767
    def onchange_type(self, cr, uid, ids,partner_id,amount,type,type1):
 
768
        if partner_id:
 
769
           
 
770
            obj = self.pool.get('res.partner')
 
771
        
 
772
            if type1 in ('rec_voucher','bank_rec_voucher', 'journal_voucher'):
 
773
                if type == 'dr' :
 
774
                    account_id = obj.browse(cr, uid, partner_id).property_account_payable 
 
775
                    total=amount*(-1)
 
776
                else:
 
777
                    account_id = obj.browse(cr, uid, partner_id).property_account_receivable 
 
778
                    total=amount*(-1)
 
779
               
 
780
            elif type1 in ('pay_voucher','bank_pay_voucher','cont_voucher') : 
 
781
                if type == 'cr' :
 
782
                    account_id = obj.browse(cr, uid, partner_id).property_account_receivable 
 
783
                    total=amount*(-1)
 
784
                else:
 
785
                    account_id = obj.browse(cr, uid, partner_id).property_account_payable
 
786
                    total=amount*(-1)
 
787
                    
 
788
            elif type1 in ('journal_sale_vou') : 
 
789
                if type == 'cr' :
 
790
                    account_id = obj.browse(cr, uid, partner_id).property_account_payable
 
791
                    total=amount*(-1)
 
792
                else:
 
793
                    account_id = obj.browse(cr, uid, partner_id).property_account_receivable
 
794
                    total=amount*(-1)
 
795
                
 
796
            elif type1 in ('journal_pur_voucher') : 
 
797
                if type == 'dr' :
 
798
                    account_id = obj.browse(cr, uid, partner_id).property_account_receivable
 
799
                    total=amount*(-1)
 
800
                else:
 
801
                    account_id = obj.browse(cr, uid, partner_id).property_account_payable
 
802
                    total=amount*(-1)
 
803
        else:
 
804
            if type1 in ('rec_voucher','bank_rec_voucher', 'journal_voucher'):
 
805
                if type == 'dr' :
 
806
    
 
807
                    total=amount*(-1)
 
808
                else:
 
809
    
 
810
                    total=amount*(-1)
 
811
               
 
812
            elif type1 in ('pay_voucher','bank_pay_voucher','cont_voucher') : 
 
813
                if type == 'cr' :
 
814
    
 
815
                    total=amount*(-1)
 
816
                else:
 
817
    
 
818
                    total=amount*(-1)
 
819
                    
 
820
            elif type1 in ('journal_sale_vou') : 
 
821
                if type == 'cr' :
 
822
    
 
823
                    total=amount*(-1)
 
824
                else:
 
825
    
 
826
                    total=amount*(-1)
 
827
                
 
828
            elif type1 in ('journal_pur_voucher') : 
 
829
                if type == 'dr' :
 
830
    
 
831
                    total=amount*(-1)
 
832
                else:
 
833
    
 
834
                    total=amount*(-1)
 
835
                    
 
836
        return {
 
837
            'value' : {'type' : type , 'amount':total}
 
838
        }
 
839
        
 
840
    def move_line_get_item(self, cr, uid, line, context={}):
 
841
        return {
 
842
            'type':'src',
 
843
            'name': line.name[:64],
 
844
            'amount':line.amount,
 
845
            'account_id':line.account_id.id,
 
846
            'partner_id':line.partner_id.id or False ,
 
847
            'account_analytic_id':line.account_analytic_id.id or False,
 
848
            'ref' : line.ref
 
849
        }
 
850
        
 
851
VoucherLine()
 
852
 
 
853
 
 
854
 
 
855
 
 
856
 
 
857