~koi-accounting-modules-maintainer/koi-accounting-modules/7.0-fixed-asset

« back to all changes in this revision

Viewing changes to ar_account/object_module/import_bank_statement.py

  • Committer: Andhitia Rama
  • Date: 2014-10-07 22:28:21 UTC
  • mfrom: (71.1.9 koi_account_bs)
  • Revision ID: andhitia.r@gmail.com-20141007222821-ir0ft7j9zlchsvoj
MergeĀ denganĀ 7.0-klik-bca-statement

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-2009 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
 
 
24
from osv import fields, osv
 
25
 
 
26
import base64
 
27
from tempfile import TemporaryFile
 
28
import csv
 
29
 
 
30
from tools.translate import _
 
31
 
 
32
class import_bank_statement(osv.osv):
 
33
    _name = 'account.import_bank_statement'
 
34
    _description = 'Import Bank Statement'
 
35
    _inherit = ['mail.thread']
 
36
 
 
37
    def default_state(self, cr, uid, context={}):
 
38
        return 'draft'
 
39
 
 
40
    def default_company_id(self, cr, uid, context={}):
 
41
        obj_user = self.pool.get('res.users')
 
42
 
 
43
        user = obj_user.browse(cr, uid, [uid])[0]
 
44
 
 
45
        return user.company_id.id
 
46
 
 
47
    _columns =  {
 
48
                'name' : fields.char(string='Description', size=100, required=True, readonly=True, states={'draft':[('readonly',False)]}),
 
49
                'company_id' : fields.many2one(string='Company', obj='res.company', required=True, readonly=True, states={'draft':[('readonly',False)]}),
 
50
                'fiscalyear_id' : fields.many2one(string='Fiscal Year', obj='account.fiscalyear', required=True, readonly=True, states={'draft':[('readonly',False)]}),
 
51
                'period_id' : fields.many2one(string='Period', obj='account.period', required=True, readonly=True, states={'draft':[('readonly',False)]}),
 
52
                'file_name' : fields.binary(string='Bank Statement File', required=True, readonly=True, states={'draft':[('readonly',False)]}),
 
53
                'journal_id' : fields.many2one(string='Journal', obj='account.journal', required=True, readonly=True, states={'draft':[('readonly',False)]}),
 
54
                'temporary_account_id' : fields.many2one(string='Temporary Account', obj='account.account', required=True, readonly=True, states={'draft':[('readonly',False)]}),
 
55
                'bank_statement_type_id' : fields.many2one(string='Statement Type', obj='account.bank_statement_type', required=True, readonly=True, states={'draft':[('readonly',False)]}),
 
56
                'bank_statement_type' : fields.related('bank_statement_type_id','name', string='Statement Type', type='char', relation='account.bank_statement_type', store=True, readonly=True),
 
57
                'import_bank_statement_ids' : fields.one2many(string='Detail', obj='account.import_bank_statement_detail', fields_id='import_bank_statement_id'),
 
58
                'state' : fields.selection(string='State', selection=[('draft','Draft'),('imported','Imported'),('open','On Progress'),('done','Done'),('cancel','Cancelled')], readonly=True, required=True),
 
59
                }
 
60
 
 
61
 
 
62
    _defaults = {
 
63
                'state' : default_state,
 
64
                'company_id' : default_company_id,
 
65
                }
 
66
 
 
67
    def unlink(self, cr, uid, ids, context=None):
 
68
        raise osv.except_osv(_('Warning!'),_('You can not delete data, please cancel instead'))
 
69
        return False
 
70
 
 
71
    def copy(self, cr, uid, id, defaults, context=None):
 
72
        raise osv.except_osv(_('Warning!'),_('You can not copy data'))
 
73
        return False
 
74
 
 
75
 
 
76
    def button_import(self, cr, uid, ids, context={}):
 
77
        for id in ids:
 
78
            csv_file = False
 
79
 
 
80
            csv_file = self._open_file(cr, uid, id)
 
81
            if not csv_file:
 
82
                return False
 
83
 
 
84
            csv_file = self._cleanup_csv(cr, uid, id, csv_file)
 
85
            if not csv_file:
 
86
                return False
 
87
 
 
88
            csv_file = self._read_csv_row(cr, uid, id, csv_file)
 
89
            if not csv_file:
 
90
                return False
 
91
 
 
92
            if not self._import_result_list(cr, uid, id, csv_file):
 
93
                return False
 
94
 
 
95
        return True
 
96
 
 
97
    def button_posted(self, cr, uid, ids, context={}):
 
98
        for id in ids:
 
99
            if not self._create_bank_voucher(cr, uid, id):
 
100
                return False
 
101
 
 
102
        return True
 
103
 
 
104
    def button_confirm(self, cr, uid, ids, context={}):
 
105
        for id in ids:
 
106
            self.write(cr, uid, [id], {'state' : 'imported'})
 
107
 
 
108
        return True
 
109
 
 
110
    def button_finished_assign_voucher(self, cr, uid, ids, context={}):
 
111
        for id in ids:
 
112
            if not self._check_finished_assign(cr, uid, id):
 
113
                return False
 
114
 
 
115
            self.write(cr, uid, [id], {'state' : 'open'})
 
116
 
 
117
        return True
 
118
 
 
119
    def button_done(self, cr, uid, ids, context={}):
 
120
        for id in ids:
 
121
            if not self._check_voucher_posted(cr, uid, id):
 
122
                return False
 
123
 
 
124
            self.write(cr, uid, [id], {'state' : 'done'})
 
125
 
 
126
        return True
 
127
 
 
128
    def button_cancel(self, cr, uid, ids, context={}):
 
129
        for id in ids:
 
130
            if not self._check_voucher_cancel(cr, uid, id):
 
131
                return False
 
132
 
 
133
            self.write(cr, uid, [id], {'state' : 'cancel'})
 
134
 
 
135
        return True
 
136
 
 
137
    def button_set_to_draft(self, cr, uid, ids, context={}):
 
138
        for id in ids:
 
139
            self.write(cr, uid, [id], {'state' : 'draft'})
 
140
 
 
141
        return True
 
142
 
 
143
    def _import_csv(self, cr, uid, id):
 
144
        #TODO
 
145
        return True
 
146
 
 
147
    def _create_bank_voucher(self, cr, uid, id):
 
148
        obj_detail = self.pool.get('account.import_bank_statement_detail')
 
149
 
 
150
        import_bank_statement = self.browse(cr, uid, [id])[0]
 
151
 
 
152
        if import_bank_statement.import_bank_statement_ids:
 
153
            for detail in import_bank_statement.import_bank_statement_ids:
 
154
                if not obj_detail._create_account_voucher(cr, uid, detail.id):
 
155
                    return False
 
156
 
 
157
        return True
 
158
 
 
159
    def _open_file(self, cr, uid, id):
 
160
        obj_import_bank_statement = self.pool.get('account.import_bank_statement')
 
161
 
 
162
        import_bank_statement = obj_import_bank_statement.browse(cr, uid, [id])[0]
 
163
 
 
164
        try:
 
165
            fileobj = TemporaryFile('w+')
 
166
            fileobj.write(base64.decodestring(import_bank_statement.file_name))
 
167
        except Exception, e:
 
168
            raise osv.except_osv(_('Open file error'),_('%s') % e)
 
169
 
 
170
        return fileobj
 
171
 
 
172
    def _cleanup_csv(self, cr, uid, id, fileobj):
 
173
        obj_import_bank_statement = self.pool.get('account.import_bank_statement')
 
174
 
 
175
        import_bank_statement = obj_import_bank_statement.browse(cr, uid, [id])[0]
 
176
 
 
177
        try:
 
178
            f = getattr(obj_import_bank_statement, import_bank_statement.bank_statement_type_id.csv_cleanup_function, None)
 
179
        except Exception, e:
 
180
            raise osv.except_osv(_('CSV cleanup error'),_('%s') % e)
 
181
        else:
 
182
            result = f(cr, uid, id, fileobj)
 
183
 
 
184
            return result
 
185
 
 
186
    def _read_csv_row(self, cr, uid, id, fileobj):
 
187
        obj_import_bank_statement = self.pool.get('account.import_bank_statement')
 
188
 
 
189
        import_bank_statement = obj_import_bank_statement.browse(cr, uid, [id])[0]
 
190
 
 
191
        try:
 
192
            f = getattr(obj_import_bank_statement, import_bank_statement.bank_statement_type_id.csv_read_row_function, None)
 
193
        except Exception, e:
 
194
            raise osv.except_osv(_('CSV row reading error'),_('%s') % e)
 
195
        else:
 
196
            result = f(cr, uid, id, fileobj)
 
197
 
 
198
            return result
 
199
 
 
200
    def _generic_cleanup_function(self, cr, uid, id, fileobj):
 
201
        result = fileobj
 
202
        return result
 
203
 
 
204
    def _generic_read_row_function(self, cr, uid, id, fileobj):
 
205
        list_result = []
 
206
        fileobj.seek(1)
 
207
        csvfile = csv.reader(fileobj,delimiter=';')
 
208
 
 
209
        for baris in csvfile:
 
210
            res =   {
 
211
                    'name' : baris[1],
 
212
                    'date' : baris[0],
 
213
                    'transaction_type' : baris[2],
 
214
                    'amount' : baris[3],
 
215
                    }
 
216
            list_result.append(res)
 
217
 
 
218
        list_result.pop(0)
 
219
        return list_result
 
220
 
 
221
    def _import_result_list(self, cr, uid, id, list_result):
 
222
        obj_detail = self.pool.get('account.import_bank_statement_detail')
 
223
 
 
224
        for import_row in list_result:
 
225
            import_row['import_bank_statement_id'] = id
 
226
            obj_detail.create(cr, uid, import_row)
 
227
 
 
228
        return True
 
229
 
 
230
    def _check_finished_assign(self, cr, uid, id):
 
231
        import_bank_statement = self.browse(cr, uid, [id])[0]
 
232
 
 
233
        for detail in import_bank_statement.import_bank_statement_ids:
 
234
            if not detail.account_voucher_id:
 
235
                raise osv.except_osv(_('Warning!'),_('Not all line have a voucher'))
 
236
                return False
 
237
 
 
238
        return True
 
239
 
 
240
    def _check_voucher_posted(self, cr, uid, id):
 
241
        import_bank_statement = self.browse(cr, uid, [id])[0]
 
242
 
 
243
        for detail in import_bank_statement.import_bank_statement_ids:
 
244
            if detail.account_voucher_id.state != 'posted':
 
245
                raise osv.except_osv(_('Warning!'),_('No all voucher is posted'))
 
246
                return False
 
247
 
 
248
        return True
 
249
 
 
250
    def _check_voucher_cancel(self, cr, uid, id):
 
251
        import_bank_statement = self.browse(cr, uid, [id])[0]
 
252
 
 
253
        for detail in import_bank_statement.import_bank_statement_ids:
 
254
            if detail.account_voucher_id and detail.account_voucher_id.state != 'cancel':
 
255
                raise osv.except_osv(_('Warning!'),_('Cancel or unassign voucher first'))
 
256
                return False
 
257
 
 
258
        return True
 
259
 
 
260
import_bank_statement()
 
261
 
 
262
class import_bank_statement_detail(osv.osv):
 
263
    _name = 'account.import_bank_statement_detail'
 
264
    _description = 'Import Bank Statement Detail'
 
265
 
 
266
    def function_state(self, cr, uid, ids, field_name, args, context=None):
 
267
        res = {}
 
268
        for detail in self.browse(cr, uid, ids):
 
269
            res[detail.id] = 'unassigned'
 
270
 
 
271
            if detail.account_voucher_id:
 
272
                res[detail.id] = detail.account_voucher_id.state
 
273
 
 
274
        return res
 
275
 
 
276
    def _get_import_bank_statement(self, cr, uid, ids, context=None):
 
277
        obj_import_bs = self.pool.get('account.import_bank_statement')
 
278
        result = []
 
279
 
 
280
        for import_bs in obj_import_bs.browse(cr, uid, ids):
 
281
            if import_bs.import_bank_statement_ids:
 
282
                for detail in import_bs.import_bank_statement_ids:
 
283
                    result.append(detail.import_bank_statement_id.id)
 
284
 
 
285
        return result
 
286
 
 
287
    def _get_account_voucher(self, cr, uid, ids, context=None):
 
288
        result = []
 
289
        obj_voucher = self.pool.get('account.voucher')
 
290
        obj_detail = self.pool.get('account.import_bank_statement_detail')
 
291
 
 
292
        for voucher in obj_voucher.browse(cr, uid, ids):
 
293
            criteria = [('account_voucher_id','=',voucher.id)]
 
294
            import_ids = obj_detail.search(cr, uid, criteria)
 
295
            result += import_ids
 
296
 
 
297
        raise osv.except_osv('a','b')
 
298
        return result
 
299
 
 
300
    def _get_bank_payment(self, cr, uid, ids, context=None):
 
301
        result = []
 
302
        obj_voucher = self.pool.get('account.bank_payment')
 
303
        obj_detail = self.pool.get('account.import_bank_statement_detail')
 
304
 
 
305
        for voucher in obj_voucher.browse(cr, uid, ids):
 
306
            criteria = [('account_voucher_id','=',voucher.id)]
 
307
            import_ids = obj_detail.search(cr, uid, criteria)
 
308
            result += import_ids
 
309
 
 
310
        raise osv.except_osv('a','c')
 
311
        return result
 
312
 
 
313
    def _get_bank_receipt(self, cr, uid, ids, context=None):
 
314
        result = []
 
315
        obj_voucher = self.pool.get('account.bank_receipt')
 
316
        obj_detail = self.pool.get('account.import_bank_statement_detail')
 
317
 
 
318
        for voucher in obj_voucher.browse(cr, uid, ids):
 
319
            criteria = [('account_voucher_id','=',voucher.id)]
 
320
            import_ids = obj_detail.search(cr, uid, criteria)
 
321
            result += import_ids
 
322
 
 
323
 
 
324
        raise osv.except_osv('a','d')
 
325
        return result
 
326
 
 
327
    _columns =  {
 
328
                'import_bank_statement_id' : fields.many2one(string='Import Bank Statement', obj='account.import_bank_statement', ondelete='cascade'),
 
329
                'name' : fields.char(string='Description', size=255, required=True),
 
330
                'date' : fields.date(string='Date', required=True), #TODO: Help tips
 
331
                'transaction_type' : fields.selection(string='Type', selection=[('dr','DR'),('cr','CR')], required=True), #TODO: Help tips
 
332
                'amount' : fields.float(string='Amount', required=True), #TODO: Help tips
 
333
                'account_voucher_id' : fields.many2one(string='Bank Receipt/Payment', obj='account.voucher'), #TODO: Help tips
 
334
 
 
335
                'state' : fields.function(string='Voucher State', fnct=function_state, type='selection', selection=[('unassigned','Unassigned'),('draft','Draft'),('confirm','Waiting For Approval'),('approve','Ready To Process'),('proforma','Pro-Forma'),('posted','Posted'),('cancel','Cancelled')], 
 
336
                    store={
 
337
                            'account.import_bank_statement_detail' : (lambda self, cr, uid, ids, c={}:ids, ['account_voucher_id'], 10),
 
338
                            'account.import_bank_statement' : (_get_import_bank_statement, None, 10),
 
339
                            'acount.voucher' : (_get_account_voucher, None, 10),
 
340
                            'account.bank_payment' : (_get_bank_payment, None, 10),
 
341
                            'account.bank_receipt' : (_get_bank_receipt, None, 10),
 
342
                            }
 
343
                        , method=True, readonly=True),
 
344
                }
 
345
 
 
346
    def button_unassign_voucher(self, cr, uid, ids, context={}):
 
347
        for id in ids:
 
348
            if not self._unassign_voucher(cr, uid, id):
 
349
                return False
 
350
 
 
351
        return True
 
352
 
 
353
    def _create_account_voucher(self, cr, uid, id):
 
354
        obj_account_voucher = self.pool.get('account.voucher')
 
355
        obj_detail_voucher = self.pool.get('account.voucher.line')
 
356
 
 
357
        detail = self.browse(cr, uid, [id])[0]
 
358
 
 
359
        if detail.account_voucher_id:
 
360
            return True
 
361
 
 
362
        dict_voucher = self._prepare_voucher_header(cr, uid, id)
 
363
 
 
364
        account_voucher_id = obj_account_voucher.create(cr, uid, dict_voucher)
 
365
 
 
366
        dict_detail = self._prepare_voucher_detail(cr, uid, id, account_voucher_id)
 
367
 
 
368
        detail_id = obj_detail_voucher.create(cr, uid, dict_detail)
 
369
 
 
370
        self.write(cr, uid, [id], {'account_voucher_id' : account_voucher_id})
 
371
 
 
372
        return True
 
373
 
 
374
 
 
375
    def _prepare_voucher_header(self, cr, uid, id):
 
376
        obj_data = self.pool.get('ir.model.data')
 
377
 
 
378
        detail = self.browse(cr, uid, [id])[0]
 
379
        header = detail.import_bank_statement_id
 
380
 
 
381
        if detail.transaction_type == 'dr':
 
382
            account_id = header.journal_id.default_debit_account_id.id
 
383
            voucher_type = 'receipt'
 
384
            voucher_type_id = obj_data.get_object_reference(cr, uid, 'ar_account', 'data_voucherType_bankReceive')[1]
 
385
        else:
 
386
            account_id = header.journal_id.default_credit_account_id.id
 
387
            voucher_type = 'payment'
 
388
            voucher_type_id = obj_data.get_object_reference(cr, uid, 'ar_account', 'data_voucherType_bankPayment')[1]
 
389
 
 
390
        
 
391
        
 
392
        dict_result =   {
 
393
                        'name' : detail.name,
 
394
                        'date' : detail.date,
 
395
                        'period_id' : header.period_id.id, #TODO
 
396
                        'journal_id' : header.journal_id.id,
 
397
                        'company_id' : header.company_id.id, #TODO,
 
398
                        'account_id' : account_id, #TODO,
 
399
                        'type' : voucher_type, #TODO,
 
400
                        'voucher_type_id' : voucher_type_id, #TODO
 
401
                        'partner_id' : False,
 
402
                        'payment_method' : 'bank_transfer',
 
403
                        'amount' : abs(detail.amount), #TODO
 
404
                        }
 
405
 
 
406
        return dict_result
 
407
 
 
408
    def _prepare_voucher_detail(self, cr, uid, id, voucher_id):
 
409
        detail = self.browse(cr, uid, [id])[0]
 
410
 
 
411
        if detail.transaction_type == 'dr':
 
412
            transaction_type = 'cr'
 
413
        else:
 
414
            transaction_type = 'dr'
 
415
 
 
416
        dict_result =   {
 
417
                        'voucher_id' : voucher_id,
 
418
                        'name' : detail.name,
 
419
                        'type' : transaction_type,
 
420
                        'partner_id' : False,
 
421
                        'account_id' : detail.import_bank_statement_id.temporary_account_id.id,
 
422
                        'amount' : abs(detail.amount), #TODO
 
423
                        }
 
424
 
 
425
        return dict_result
 
426
 
 
427
    def _unassign_voucher(self, cr, uid, id):
 
428
        detail = self.browse(cr, uid, [id])[0]
 
429
 
 
430
        if not detail.account_voucher_id:
 
431
            raise osv.except_osv(_('Warning!'),_('No voucher assigned'))
 
432
            return False
 
433
 
 
434
        if detail.account_voucher_id.state != 'cancel':
 
435
            raise osv.except_osv(_('Warning!'),_('Please cancel the voucher first'))
 
436
            return False
 
437
 
 
438
        self.write(cr, uid, [id], {'account_voucher_id' : False})
 
439
 
 
440
        return True
 
441
 
 
442
import_bank_statement_detail()
 
443
 
 
444