1
# -*- encoding: utf-8 -*-
2
##############################################################################
4
# Copyright (c) 2005-2007 TINY SPRL. (http://tiny.be) All Rights Reserved.
6
# WARNING: This program as such is intended to be used by professional
7
# programmers who take the whole responsability of assessing all potential
8
# consequences resulting from its eventual inadequacies and bugs
9
# End users who are looking for a ready-to-use solution with commercial
10
# garantees and support are strongly adviced to contract a Free Software
13
# This program is Free Software; you can redistribute it and/or
14
# modify it under the terms of the GNU General Public License
15
# as published by the Free Software Foundation; either version 2
16
# of the License, or (at your option) any later version.
18
# This program is distributed in the hope that it will be useful,
19
# but WITHOUT ANY WARRANTY; without even the implied warranty of
20
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
# GNU General Public License for more details.
23
# You should have received a copy of the GNU General Public License
24
# along with this program; if not, write to the Free Software
25
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27
##############################################################################
36
FORM = """<?xml version="1.0"?>
37
<form string="DTA file creation - Results">
38
<separator colspan="4" string="Clic on 'Save as' to save the DTA file :" />
64
s = s.replace(k[0],k[1])
66
res= s.encode('ascii','replace')
74
def __init__(self, global_context_dict):
75
for i in global_context_dict:
76
global_context_dict[i] = global_context_dict[i] \
77
and tr(global_context_dict[i])
79
self.global_values = global_context_dict
90
self.post={'date_value_hdr': '000000', 'type_paiement': '0'}
91
self.init_local_context()
93
def init_local_context(self):
95
Must instanciate a fields list, field = (name,size)
96
and update a local_values dict.
98
raise "not implemented"
102
for field in self.fields :
103
if self.pre.has_key(field[0]):
104
value = self.pre[field[0]]
105
elif self.global_values.has_key(field[0]):
106
value = self.global_values[field[0]]
107
elif self.post.has_key(field[0]):
108
value = self.post[field[0]]
111
#raise Exception(field[0]+' not found !')
113
res = res + c_ljust(value, field[1])
119
class record_gt826(record):
123
def init_local_context(self):
127
('date_value_hdr', 6),
128
('partner_bank_clearing', 12),
130
('creation_date', 6),
131
('comp_bank_clearing', 7),
135
('type_paiement', 1),
140
('comp_bank_iban', 24),
143
('amount_to_pay', 12),
151
('comp_country', 20),
155
('partner_bvr', 12),#numero d'adherent bvr
156
('partner_name', 20),
157
('partner_street', 20),
159
('partner_city', 10),
160
('partner_country', 20),
161
('reference', 27),#communication structuree
162
('padding', 2),#cle de controle
166
'date_value_hdr': self.global_values['date_value'],
168
'partner_bank_clearing': '',
169
'partner_cpt_benef': '',
170
'genre_trans': '826',
172
'option_id_bank': 'D',
173
'partner_bvr': '/C/'+ self.global_values['partner_bvr'],
179
class record_gt827(record):
181
interne suisse (bvpost et bvbank)
183
def init_local_context(self):
187
('date_value_hdr', 6),
188
('partner_bank_clearing', 12),
190
('creation_date', 6),
191
('comp_bank_clearing', 7),
195
('type_paiement', 1),
200
('comp_bank_iban', 24),
203
('amount_to_pay', 12),
211
('comp_country', 20),
215
('partner_bank_number', 30),
216
('partner_name', 24),
217
('partner_street', 24),
219
('partner_city', 12),
220
('partner_country', 24),
230
'date_value_hdr': self.global_values['date_value'],
232
'partner_cpt_benef': '',
233
'type_paiement': '0',
234
'genre_trans': '827',
236
'option_id_bank': 'D',
243
class record_gt836(record):
247
def init_local_context(self):
251
('date_value_hdr', 6),
252
('partner_bank_clearing', 12),
254
('creation_date', 6),
255
('comp_bank_clearing', 7),
259
('type_paiement', 1),
264
('comp_bank_iban', 24),
267
('amount_to_pay', 15),
280
('option_id_bank', 1),
281
('partner_bank_ident', 70),
282
('partner_bank_iban', 34),
286
('partner_name', 35),
287
('partner_street', 35),
288
('partner_country', 3),
290
('partner_city', 22),
300
'partner_bank_clearing': '',
301
'partner_cpt_benef': '',
302
'type_paiement': '0',
303
'genre_trans': '836',
305
'reference': self.global_values['reference'],
310
self.post.update({'comp_dta': '', 'option_motif': 'U'})
313
class record_gt890(record):
317
def init_local_context(self):
321
('date_value_hdr', 6),
322
('partner_bank_clearing', 12),
324
('creation_date', 6),
325
('comp_bank_clearing', 7),
329
('type_paiement', 1),
332
('amount_total', 16),
335
self.pre.update({'partner_bank_clearing': '', 'partner_cpt_benef': '',
336
'company_bank_clearing': '', 'genre_trans': '890'})
338
def c_ljust(s, size):
340
check before calling ljust
345
s = s.decode('utf-8').encode('latin1','replace').ljust(size)
348
def _create_dta(obj, cr, uid, data, context):
351
v['creation_date']= time.strftime('%y%m%d')
354
pool = pooler.get_pool(cr.dbname)
355
payment_obj = pool.get('payment.order')
356
attachment_obj = pool.get('ir.attachment')
358
payment = payment_obj.browse(cr, uid, data['id'], context=context)
360
if not payment.mode or payment.mode.type.code != 'dta':
361
raise wizard.except_wizard('Error',
362
'No payment mode or payment type code invalid.')
363
bank = payment.mode.bank_id
365
raise wizard.except_wizard('Error', 'No bank account for the company.')
367
v['comp_bank_name']= bank.bank and bank.bank.name or False
368
v['comp_bank_clearing'] = bank.bank.clearing
370
if not v['comp_bank_clearing']:
371
raise wizard.except_wizard('Error',
372
'You must provide a Clearing Number for your bank account.')
374
user = pool.get('res.users').browse(cr,uid,[uid])[0]
375
company= user.company_id
376
#XXX dirty code use get_addr
377
co_addr= company.partner_id.address[0]
378
v['comp_country'] = co_addr.country_id and co_addr.country_id.name or ''
379
v['comp_street'] = co_addr.street or ''
380
v['comp_zip'] = co_addr.zip
381
v['comp_city'] = co_addr.city
382
v['comp_name'] = co_addr.name
383
v['comp_dta'] = '' #XXX not mandatory in pratice
386
v['comp_bank_number'] = bank.acc_number or ''
388
v['comp_bank_iban'] = bank.iban or ''
389
if not v['comp_bank_iban']:
390
raise wizard.except_wizard('Error',
391
'No IBAN for the company bank account.')
393
dta_line_obj = pool.get('account.dta.line')
394
res_partner_bank_obj = pool.get('res.partner.bank')
398
amount_currency_tot = 0
400
for pline in payment.line_ids:
401
if not pline.bank_id:
402
raise wizard.except_wizard('Error', 'No bank account defined\n' \
403
'on line: ' + pline.name)
404
if not pline.bank_id.bank:
405
raise wizard.except_wizard('Error', 'No bank defined\n' \
406
'for the bank account: ' + pline.bank_id.state + '\n' \
407
'on the partner: ' + pline.partner_id.name + '\n' \
408
'on line: ' + pline.name)
410
v['sequence'] = str(seq).rjust(5).replace(' ', '0')
411
v['amount_to_pay']= str(pline.amount_currency).replace('.', ',')
412
v['number'] = pline.name
413
v['currency'] = pline.currency.code
415
v['partner_bank_name'] = pline.bank_id.bank.name or False
416
v['partner_bank_clearing'] = pline.bank_id.bank.clearing or False
417
if not v['partner_bank_name'] :
418
raise wizard.except_wizard('Error', 'No bank name defined\n' \
419
'for the bank account: ' + pline.bank_id.state + '\n' \
420
'on the partner: ' + pline.partner_id.name + '\n' \
421
'on line: ' + pline.name)
423
v['partner_bank_iban']= pline.bank_id.iban or False
424
v['partner_bank_number']= pline.bank_id.acc_number \
425
and pline.bank_id.acc_number.replace('.','').replace('-','') \
427
v['partner_post_number']= pline.bank_id.post_number \
428
and pline.bank_id.post_number.replace('.', '').replace('-', '') \
430
v['partner_bvr'] = pline.bank_id.bvr_number or ''
432
v['partner_bvr'] = v['partner_bvr'].replace('-','')
433
if len(v['partner_bvr']) < 9:
434
v['partner_bvr'] = v['partner_bvr'][:2] + '0' * \
435
(9 - len(v['partner_bvr'])) + v['partner_bvr'][2:]
437
if pline.bank_id.bank:
438
v['partner_bank_city'] = pline.bank_id.bank.city or False
439
v['partner_bank_street'] = pline.bank_id.bank.street or ''
440
v['partner_bank_zip'] = pline.bank_id.bank.zip or ''
441
v['partner_bank_country'] = pline.bank_id.bank.country and \
442
pline.bank_id.bank.country.name or ''
444
v['partner_bank_code'] = pline.bank_id.bank.bic
445
v['reference'] = pline.move_line_id.ref
446
v['partner_name'] = pline.partner_id and pline.partner_id.name or ''
447
if pline.partner_id and pline.partner_id.address \
448
and pline.partner_id.address[0]:
449
v['partner_street'] = pline.partner_id.address[0].street
450
v['partner_city']= pline.partner_id.address[0].city
451
v['partner_zip']= pline.partner_id.address[0].zip
452
# If iban => country=country code for space reason
453
elec_pay = pline.bank_id.state #Bank type
454
if elec_pay == 'iban':
455
v['partner_country']= pline.partner_id.address[0].country_id \
456
and pline.partner_id.address[0].country_id.code+'-' \
459
v['partner_country']= pline.partner_id.address[0].country_id \
460
and pline.partner_id.address[0].country_id.name \
463
v['partner_street'] =''
464
v['partner_city']= ''
466
v['partner_country']= ''
467
raise wizard.except_wizard('Error', 'No address defined \n' \
468
'for the partner: ' + pline.partner_id.name + '\n' \
469
'on line: ' + pline.name)
471
date_value = mx.DateTime.strptime(pline.value_date, '%Y-%m-%d') \
473
v['date_value'] = date_value.strftime("%y%m%d")
475
# si compte iban -> iban (836)
476
# si payment structure -> bvr (826)
479
if elec_pay == 'dta_iban':
480
# If iban => country=country code for space reason
481
v['comp_country'] = co_addr.country_id and co_addr.country_id.code+'-' or ''
482
record_type = record_gt836
483
if not v['partner_bank_iban']:
484
raise wizard.except_wizard('Error', 'No IBAN defined \n' \
485
'for the bank account: ' + \
486
res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id],
487
context)[0][1] + '\n' \
488
'on line: ' + pline.name)
490
if v['partner_bank_code'] : # bank code is swift (BIC address)
491
v['option_id_bank']= 'A'
492
v['partner_bank_ident']= v['partner_bank_code']
493
elif v['partner_bank_city']:
495
v['option_id_bank']= 'D'
496
v['partner_bank_ident']= v['partner_bank_name'] \
497
+ ' ' + v['partner_bank_street'] \
498
+ ' ' + v['partner_bank_zip'] \
499
+ ' ' + v['partner_bank_city'] \
500
+ ' ' + v['partner_bank_country']
502
raise wizard.except_wizard('Error', 'You must provide the bank city '
503
'or the bic code for the partner bank: \n' + \
504
res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id],
505
context)[0][1] + '\n' \
506
'on line: ' + pline.name)
508
elif elec_pay == 'bvrbank' or elec_pay == 'bvrpost':
509
from tools import mod10r
511
v['reference'] = v['reference'].replace(' ',
512
'').rjust(27).replace(' ', '0')
513
if not v['reference'] \
514
or mod10r(v['reference'][:-1]) != v['reference']:
515
raise wizard.except_wizard('Error', 'You must provide ' \
516
'a valid BVR reference number \n' +
517
'for the line: ' + pline.name)
518
if not v['partner_bvr']:
519
raise wizard.except_wizard('Error', 'You must provide a BVR number\n'
520
'for the bank account: ' + \
521
res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id],
522
context)[0][1] + '\n' \
523
'on line: ' + pline.name)
524
record_type = record_gt826
526
elif elec_pay == 'bvbank':
527
if not v['partner_bank_number'] :
528
if v['partner_bank_iban'] :
529
v['partner_bank_number']= v['partner_bank_iban']
531
raise wizard.except_wizard('Error', 'You must provide ' \
533
'for the partner bank: ' + \
534
res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id],
535
context)[0][1] + '\n' \
536
'on line: ' + pline.name)
537
if not v['partner_bank_clearing']:
538
raise wizard.except_wizard('Error', 'You must provide ' \
539
'a Clearing Number\n' \
540
'for the partner bank: ' + \
541
res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id],
542
context)[0][1] + '\n' \
543
'on line '+ pline.name)
544
v['partner_bank_number'] = '/C/'+v['partner_bank_number']
545
record_type = record_gt827
546
elif elec_pay == 'bvpost':
547
if not v['partner_post_number']:
548
raise wizard.except_wizard('Error', 'You must provide ' \
550
'for the partner bank: ' + \
551
res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id],
552
context)[0][1] + '\n' \
553
'on line: ' + pline.name)
554
v['partner_bank_clearing']= ''
555
v['partner_bank_number'] = '/C/'+v['partner_post_number']
556
record_type = record_gt827
558
raise wizard.except_wizard('Error', 'The Bank type ' + elec_pay + \
559
'of the bank account: ' + \
560
res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id],
561
context)[0][1] + ' '\
564
dta_line = record_type(v).generate()
567
amount_tot += pline.amount
568
amount_currency_tot += pline.amount_currency
572
v['amount_total'] = str(amount_currency_tot).replace('.',',')
573
v['sequence'] = str(seq).rjust(5).replace(' ','0')
575
dta = dta + record_gt890(v).generate()
577
dta_data= base64.encodestring(dta)
578
payment_obj.set_done(cr, uid, data['id'], context)
579
attachment_obj.create(cr, uid, {
582
'datas_fname': 'DTA.txt',
583
'res_model': 'payment.order',
584
'res_id': data['id'],
586
return {'dta': dta_data}
589
class wizard_dta_create(wizard.interface):
592
'actions' : [_create_dta],
593
'result' : {'type' : 'form',
596
'state' : [('end', 'OK', 'gtk-ok', True)]
601
wizard_dta_create('account.dta_create')