Merge lp:~camptocamp/openobject-addons/5.0_l10n_ch_maintenance into lp:openobject-addons/5.0

Proposed by Nicolas Bessi - Camptocamp
Status: Merged
Merged at revision: not available
Proposed branch: lp:~camptocamp/openobject-addons/5.0_l10n_ch_maintenance
Merge into: lp:openobject-addons/5.0
Diff against target: 3141 lines
15 files modified
l10n_ch/__terp__.py (+38/-44)
l10n_ch/account_move_line.py (+33/-33)
l10n_ch/bank.py (+17/-8)
l10n_ch/bank_view.xml (+26/-0)
l10n_ch/company.py (+11/-11)
l10n_ch/dta.py (+53/-53)
l10n_ch/invoice.py (+166/-166)
l10n_ch/partner.py (+51/-53)
l10n_ch/payment.py (+5/-5)
l10n_ch/report/bvr.py (+84/-62)
l10n_ch/report/bvr.rml (+29/-26)
l10n_ch/report/invoice.rml (+37/-32)
l10n_ch/report/tiny_sxw2rml.py (+0/-342)
l10n_ch/wizard/bvr_import.py (+198/-198)
l10n_ch/wizard/dta_wizard.py (+529/-519)
To merge this branch: bzr merge lp:~camptocamp/openobject-addons/5.0_l10n_ch_maintenance
Reviewer Review Type Date Requested Status
OpenERP Core Team Pending
Review via email: mp+13464@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Nicolas Bessi - Camptocamp (nbessi-c2c-deactivatedaccount) wrote :

Hello,

Camptocamp has made a branch that fix the l10n_ch following problems (lp:~c2c/openobject-addons/5.0_l10n_ch_maintenance) :
 Wizard DTA generation encoding error (thanks for the contributions)
 Old BVR references are now supported
 Temporary solution for the non functional expr tag in the RML
 Temporary solution for the missing ocrb file (I know its is dirty but it copy the file in tmp if it does not exist)
 (we are waiting on Tiny for these two bugs)

Improvements:
 Adding fields on the res.partner.bank view that will allows you to choose what to print on BVR
 We also integrated all the changes made by Tiny for the translation of error messages, we take our time when merging in order to have the optimum solution

Known bug still pending :
 DTA in foreign currencies

Nicolas

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'l10n_ch/__terp__.py'
2--- l10n_ch/__terp__.py 2009-04-09 10:02:19 +0000
3+++ l10n_ch/__terp__.py 2009-10-16 12:20:30 +0000
4@@ -31,8 +31,8 @@
5 #
6 ##############################################################################
7 {
8- "name" : "Switzerland localisation corrected by Camptocamp",
9- "description" : """
10+ "name" : "Switzerland localisation corrected by Camptocamp",
11+ "description" : """
12 Swiss localisation :
13 - DTA generation for a lot of paiment types
14 - BVR management (number generation, report, etc..)
15@@ -43,9 +43,9 @@
16 - l10n_ch_c2c_pcg
17
18
19-
20+
21 ------------------------------------------------------------------------
22-
23+
24 Module incluant la localisation Suisse de TinyERP revu et corrigé par Camptocamp. Cette nouvelle version
25 comprend la gestion et l'émissionde BVR, le paiement électronique via DTA (pour les banques, le système postal est en développement)
26 et l'import du relevé de compte depuis la banque de manière automatisée.
27@@ -66,45 +66,39 @@
28
29
30 """,
31- "version" : "5.0",
32- "author" : "Camptocamp SA",
33- "category" : "Localisation/Europe",
34- "website": "http://www.camptocamp.com",
35-
36- "depends" : [
37- "base",
38- "account",
39- "base_vat",
40- "base_iban",
41- "account_payment",
42- "account_tax_include",
43- ],
44- "init_xml" : [
45- "dta_data.xml",
46- "vaudtax_data.xml",
47- #these data will soon be part of an other modules but if you want
48- #them now uncomment the two lines
49- #"zip_code_default.xml",
50- #"bank_ch.xml",
51- ],
52- "demo_xml" : [
53- "demo/vaudtax_data_demo.xml",
54- ],
55- "update_xml" : [
56- "dta_view.xml",
57- "dta_wizard.xml",
58- #this file as been move to the account chart
59- # "account_vat.xml",
60- "bvr_report.xml",
61- "bvr_wizard.xml",
62- "bvr_view.xml",
63- "company_view.xml",
64- "account_invoice.xml",
65- "bank_view.xml",
66- "account_journal_view.xml",
67- "security/ir.model.access.csv",
68- ],
69- "active": False,
70- "installable": True,
71+ "version" : "5.0",
72+ "author" : "Camptocamp SA",
73+ "category" : "Localisation/Europe",
74+ "website": "http://www.camptocamp.com",
75+
76+ "depends" : [
77+ "base",
78+ "account",
79+ "base_vat",
80+ "base_iban",
81+ "account_payment",
82+ "account_tax_include",
83+ ],
84+ "init_xml" : [
85+ "dta_data.xml",
86+ "vaudtax_data.xml",
87+ ],
88+ "demo_xml" : [
89+ "demo/vaudtax_data_demo.xml",
90+ ],
91+ "update_xml" : [
92+ "dta_view.xml",
93+ "dta_wizard.xml",
94+ "bvr_report.xml",
95+ "bvr_wizard.xml",
96+ "bvr_view.xml",
97+ "company_view.xml",
98+ "account_invoice.xml",
99+ "bank_view.xml",
100+ "account_journal_view.xml",
101+ "security/ir.model.access.csv",
102+ ],
103+ "active": False,
104+ "installable": True,
105 }
106 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
107
108=== modified file 'l10n_ch/account_move_line.py'
109--- l10n_ch/account_move_line.py 2009-04-09 10:02:19 +0000
110+++ l10n_ch/account_move_line.py 2009-10-16 12:20:30 +0000
111@@ -33,39 +33,39 @@
112 from osv import fields, osv
113
114 class AccountMoveLine(osv.osv):
115- """ Inherit account.move.line in order to add a custom link
116- between supplier invoice line and bank. The original link
117- was defined in account_payment between line """
118-
119- _inherit = 'account.move.line'
120-
121- ## @param self The object pointer.
122- ## @param cr a psycopg cursor
123- ## @param uid res.user.id that is currently loged
124- ## @param payment_type manual
125- ## @parma context a standard dict
126- ## @return a dict who has the account move line id as key and the bank id as value
127- def line2bank(self, cr, uid, ids, payment_type='manual', context=None):
128- """add a link to account.move.line in order to link
129- supplier invoice line and bank. The original link
130- was defined in account_payment"""
131- payment_mode_obj = self.pool.get('payment.mode')
132- line2bank = {}
133- if not ids:
134- return {}
135- bank_type = payment_mode_obj.suitable_bank_types(cr, uid, payment_type,
136- context=context)
137- for line in self.browse(cr, uid, ids, context=context):
138- if line.invoice and line.invoice.partner_bank:
139- line2bank[line.id] = line.invoice.partner_bank.id
140- elif line.partner:
141- for bank in line.partner.bank_ids:
142- if bank.state in bank_type:
143- line2bank[line.id] = bank.id
144- break
145- if line.id not in line2bank and line.partner.bank_ids:
146- line2bank[line.id] = line.partner.bank_ids[0].id
147- return line2bank
148+ """ Inherit account.move.line in order to add a custom link
149+ between supplier invoice line and bank. The original link
150+ was defined in account_payment between line """
151+
152+ _inherit = 'account.move.line'
153+
154+ ## @param self The object pointer.
155+ ## @param cr a psycopg cursor
156+ ## @param uid res.user.id that is currently loged
157+ ## @param payment_type manual
158+ ## @parma context a standard dict
159+ ## @return a dict who has the account move line id as key and the bank id as value
160+ def line2bank(self, cr, uid, ids, payment_type='manual', context=None):
161+ """add a link to account.move.line in order to link
162+ supplier invoice line and bank. The original link
163+ was defined in account_payment"""
164+ payment_mode_obj = self.pool.get('payment.mode')
165+ line2bank = {}
166+ if not ids:
167+ return {}
168+ bank_type = payment_mode_obj.suitable_bank_types(cr, uid, payment_type,
169+ context=context)
170+ for line in self.browse(cr, uid, ids, context=context):
171+ if line.invoice and line.invoice.partner_bank:
172+ line2bank[line.id] = line.invoice.partner_bank.id
173+ elif line.partner_id:
174+ for bank in line.partner_id.bank_ids:
175+ if bank.state in bank_type:
176+ line2bank[line.id] = bank.id
177+ break
178+ if line.id not in line2bank and line.partner_id.bank_ids:
179+ line2bank[line.id] = line.partner_id.bank_ids[0].id
180+ return line2bank
181
182 AccountMoveLine()
183 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
184
185=== modified file 'l10n_ch/bank.py'
186--- l10n_ch/bank.py 2009-04-09 10:02:19 +0000
187+++ l10n_ch/bank.py 2009-10-16 12:20:30 +0000
188@@ -33,14 +33,23 @@
189
190
191 class Bank(osv.osv):
192- """Inherit res.bank class in order to add swiss specific field"""
193- _inherit = 'res.bank'
194- _columns = {
195- ###Swiss unik bank identifier also use in IBAN number
196- 'clearing': fields.char('Clearing number', size=64),
197- ### city of the bank
198- 'city': fields.char('City', size=128, select=1),
199- }
200+ """Inherit res.bank class in order to add swiss specific field"""
201+ _inherit = 'res.bank'
202+ _columns = {
203+ ###Swiss unik bank identifier also use in IBAN number
204+ 'clearing': fields.char('Clearing number', size=64),
205+ ### city of the bank
206+ 'city': fields.char('City', size=128, select=1),
207+ }
208
209 Bank()
210+
211+class bvr_checkbox(osv.osv):
212+ """ Add function to generate function """
213+ _inherit = "res.partner.bank"
214+ _columns = {
215+ 'printBank' : fields.boolean('Print Bank on BVR'),
216+ 'printAccount' : fields.boolean('Print Account Number on BVR'),
217+ }
218+bvr_checkbox()
219 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
220
221=== modified file 'l10n_ch/bank_view.xml'
222--- l10n_ch/bank_view.xml 2009-02-13 15:53:46 +0000
223+++ l10n_ch/bank_view.xml 2009-10-16 12:20:30 +0000
224@@ -24,5 +24,31 @@
225 </field>
226 </field>
227 </record>
228+
229+ <record model="ir.ui.view" id="l10nch_view_res_partner_bank">
230+ <field name="name">res.partner_bank.form</field>
231+ <field name="model">res.partner.bank</field>
232+ <field name="type">form</field>
233+ <field name="inherit_id" ref="base.view_partner_bank_form"/>
234+ <field name="arch" type="xml">
235+ <field name="country_id" position="after">
236+ <field name="printBank" select="2"/>
237+ <field name="printAccount" select="2"/>
238+ </field>
239+ </field>
240+ </record>
241+ <record model="ir.ui.view" id="l10nch_view_res_partner_bank">
242+ <field name="name">res.partner_partner_bank.form</field>
243+ <field name="model">res.partner</field>
244+ <field name="type">form</field>
245+ <field name="inherit_id" ref="account.view_partner_property_form"/>
246+ <field name="arch" type="xml">
247+ <field name="bank" position="after">
248+ <newline />
249+ <field name="printBank" select="2"/>
250+ <field name="printAccount" select="2"/>
251+ </field>
252+ </field>
253+ </record>
254 </data>
255 </openerp>
256
257=== modified file 'l10n_ch/company.py'
258--- l10n_ch/company.py 2009-04-09 10:02:19 +0000
259+++ l10n_ch/company.py 2009-10-16 12:20:30 +0000
260@@ -34,17 +34,17 @@
261 import netsvc
262 from osv import fields, osv
263 class res_company(osv.osv):
264- """override company in order to add bvr vertical and
265- Horizontal print delta"""
266- _inherit = "res.company"
267- _columns = {
268- ### horiz. delta in mm 1.2 will print the bvz 1.2mm lefter
269- 'bvr_delta_horz': fields.float('BVR Horz. Delta (mm)',
270- help='horiz. delta in mm 1.2 will print the bvz 1.2mm lefter'),
271- ### vert. delta in mm 1.2 will print the bvz 1.2mm lefter
272- 'bvr_delta_vert': fields.float('BVR Vert. Delta (mm)',
273- help='vert. delta in mm 1.2 will print the bvz 1.2mm lefter'),
274- }
275+ """override company in order to add bvr vertical and
276+ Horizontal print delta"""
277+ _inherit = "res.company"
278+ _columns = {
279+ ### horiz. delta in mm 1.2 will print the bvz 1.2mm lefter
280+ 'bvr_delta_horz': fields.float('BVR Horz. Delta (mm)',
281+ help='horiz. delta in mm 1.2 will print the bvz 1.2mm lefter'),
282+ ### vert. delta in mm 1.2 will print the bvz 1.2mm lefter
283+ 'bvr_delta_vert': fields.float('BVR Vert. Delta (mm)',
284+ help='vert. delta in mm 1.2 will print the bvz 1.2mm lefter'),
285+ }
286 res_company()
287
288 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
289
290=== modified file 'l10n_ch/dta.py'
291--- l10n_ch/dta.py 2009-04-09 10:02:19 +0000
292+++ l10n_ch/dta.py 2009-10-16 12:20:30 +0000
293@@ -34,62 +34,62 @@
294 from osv import osv,fields
295
296 class account_dta(osv.osv):
297- """class that implements bank DTA File format,
298- used to transfert bulk batch payment instruction to a bank"""
299- _name = "account.dta"
300- _description = "DTA History"
301- _columns = {
302- ### name of the file
303- 'name': fields.binary('DTA file', readonly=True),
304- ### list of dta line linked to the dta order
305- 'dta_line_ids': fields.one2many('account.dta.line','dta_id','DTA lines', readonly=True),
306- ## textual notes
307- 'note': fields.text('Creation log', readonly=True,
308- help="display the problem during dta generation"),
309- ### bank how will execute DTA order
310- 'bank': fields.many2one('res.partner.bank','Bank', readonly=True,select=True,
311- help="bank how will execute DTA order"),
312- ### date of DTA order generation
313- 'date': fields.date('Creation Date', readonly=True,select=True,
314- help="date of DTA order generation"),
315- ### user how generate the DTA order
316- 'user_id': fields.many2one('res.users','User', readonly=True, select=True),
317- }
318+ """class that implements bank DTA File format,
319+ used to transfert bulk batch payment instruction to a bank"""
320+ _name = "account.dta"
321+ _description = "DTA History"
322+ _columns = {
323+ ### name of the file
324+ 'name': fields.binary('DTA file', readonly=True),
325+ ### list of dta line linked to the dta order
326+ 'dta_line_ids': fields.one2many('account.dta.line','dta_id','DTA lines', readonly=True),
327+ ## textual notes
328+ 'note': fields.text('Creation log', readonly=True,
329+ help="display the problem during dta generation"),
330+ ### bank how will execute DTA order
331+ 'bank': fields.many2one('res.partner.bank','Bank', readonly=True,select=True,
332+ help="bank how will execute DTA order"),
333+ ### date of DTA order generation
334+ 'date': fields.date('Creation Date', readonly=True,select=True,
335+ help="date of DTA order generation"),
336+ ### user how generate the DTA order
337+ 'user_id': fields.many2one('res.users','User', readonly=True, select=True),
338+ }
339 account_dta()
340
341 class account_dta_line(osv.osv):
342- """Class that represent a DTA order line,
343- each lin corressponds to a payment instruction"""
344- _name = "account.dta.line"
345- _description = "DTA line"
346- _columns = {
347- ### name of the line
348- 'name' : fields.many2one('account.invoice','Invoice', required=True, size=256),
349- ### partner how will receive payments
350- 'partner_id' : fields.many2one('res.partner','Partner',
351- help="Partenr to pay"),
352- ### due date of the payment
353- 'due_date' : fields.date('Due date'),
354- ### date of the supplier invoice to pay
355- 'invoice_date' : fields.date('Invoice date'),
356- ### cash discount date
357- 'cashdisc_date' : fields.date('Cash Discount date'),
358- ### amount effectively paied on this line
359- 'amount_to_pay' : fields.float('Amount to pay',
360- help="amount effectively paid"),
361- ### amount that was on the supplier invoice
362- 'amount_invoice': fields.float('Invoiced Amount',
363- help="amount to pay base on the supplier invoice"),
364- ### Cash discount amount
365- 'amount_cashdisc': fields.float('Cash Discount Amount'),
366- ### Linke to the main dta order
367- 'dta_id': fields.many2one('account.dta','Associated DTA', required=True, ondelete='cascade'),
368- ### state of the invoice Drat, Cancel, Done
369- 'state' : fields.selection([('draft','Draft'),('cancel','Error'),('done','Paid')],'State')
370- }
371- _defaults = {
372- 'state' : lambda *a :'draft',
373- }
374+ """Class that represent a DTA order line,
375+ each lin corressponds to a payment instruction"""
376+ _name = "account.dta.line"
377+ _description = "DTA line"
378+ _columns = {
379+ ### name of the line
380+ 'name' : fields.many2one('account.invoice','Invoice', required=True, size=256),
381+ ### partner how will receive payments
382+ 'partner_id' : fields.many2one('res.partner','Partner',
383+ help="Partenr to pay"),
384+ ### due date of the payment
385+ 'due_date' : fields.date('Due date'),
386+ ### date of the supplier invoice to pay
387+ 'invoice_date' : fields.date('Invoice date'),
388+ ### cash discount date
389+ 'cashdisc_date' : fields.date('Cash Discount date'),
390+ ### amount effectively paied on this line
391+ 'amount_to_pay' : fields.float('Amount to pay',
392+ help="amount effectively paid"),
393+ ### amount that was on the supplier invoice
394+ 'amount_invoice': fields.float('Invoiced Amount',
395+ help="amount to pay base on the supplier invoice"),
396+ ### Cash discount amount
397+ 'amount_cashdisc': fields.float('Cash Discount Amount'),
398+ ### Linke to the main dta order
399+ 'dta_id': fields.many2one('account.dta','Associated DTA', required=True, ondelete='cascade'),
400+ ### state of the invoice Drat, Cancel, Done
401+ 'state' : fields.selection([('draft','Draft'),('cancel','Error'),('done','Paid')],'State')
402+ }
403+ _defaults = {
404+ 'state' : lambda *a :'draft',
405+ }
406 account_dta_line()
407
408
409
410=== modified file 'l10n_ch/invoice.py'
411--- l10n_ch/invoice.py 2009-04-09 10:02:19 +0000
412+++ l10n_ch/invoice.py 2009-10-16 12:20:30 +0000
413@@ -37,176 +37,176 @@
414
415
416 class account_invoice(osv.osv):
417- """Inherit account.invoice in order to add bvr
418- printing functionnalites. BVR is a Swiss payment vector"""
419- _inherit = "account.invoice"
420-
421- ## @param self The object pointer.
422- ## @param cursor a psycopg cursor
423- ## @param user res.user.id that is currently loged
424- ## @parma context a standard dict
425- ## @return a list of tuple (name,value)
426- def _get_reference_type(self, cursor, user, context=None):
427- """Function use by the function field reference_type in order to initalise available
428- BVR Reference Types"""
429- res = super(account_invoice, self)._get_reference_type(cursor, user,
430- context=context)
431- res.append(('bvr', 'BVR'))
432- return res
433-
434- ## @param self The object pointer.
435- ## @param cursor a psycopg cursor
436- ## @param user res.user.id that is currently loged
437- ## @parma context a standard dict
438- ## @param name of the files
439- ## @param args a list of diverse argument
440- ## @parma context a standard dict
441- ## @return a dict (invoice id,amount to pay)
442- def _amount_to_pay(self, cursor, user, ids, name, args, context=None):
443- '''Return the amount still to pay regarding all the payment orders'''
444- if not ids:
445- return {}
446- res = {}
447- for invoice in self.browse(cursor, user, ids, context=context):
448- res[invoice.id] = 0.0
449- if invoice.move_id:
450- for line in invoice.move_id.line_id:
451- if not line.date_maturity or \
452- DateTime.strptime(line.date_maturity, '%Y-%m-%d') \
453- < DateTime.now():
454- res[invoice.id] += line.amount_to_pay
455- return res
456-
457- _columns = {
458- ### BVR reference type BVR or FREE
459- 'reference_type': fields.selection(_get_reference_type,
460- 'Reference Type', required=True),
461- ### Partner bank link between bank and partner id
462- 'partner_bank': fields.many2one('res.partner.bank', 'Bank Account',
463- help='The partner bank account to pay\nKeep empty to use the default'
464- ),
465- ### Amount to pay
466- 'amount_to_pay': fields.function(_amount_to_pay, method=True,
467- type='float', string='Amount to be paid',
468- help='The amount which should be paid at the current date\n' \
469- 'minus the amount which is already in payment order'),
470- }
471-
472- ## @param self The object pointer.
473- ## @param cursor a psycopg cursor
474- ## @param user res.user.id that is currently loged
475- ## @parma ids invoices id
476- ## @return a boolean True if valid False if invalid
477- def _check_bvr(self, cr, uid, ids):
478- """
479- Function to validate a bvr reference like :
480- 0100054150009>132000000000000000000000014+ 1300132412>
481- The validation is based on l10n_ch
482- """
483- invoices = self.browse(cr,uid,ids)
484- for invoice in invoices:
485- if invoice.reference_type == 'bvr':
486- if not invoice.reference:
487- return False
488- ## I need help for this bug because in this case
489- # <010001000060190> 052550152684006+ 43435>
490- # the reference 052550152684006 do not match modulo 10
491- #
492- if mod10r(invoice.reference[:-1]) != invoice.reference and \
493- len(invoice.reference) == 15:
494- return True
495- #
496- if mod10r(invoice.reference[:-1]) != invoice.reference:
497- return False
498- return True
499- ## @param self The object pointer.
500- ## @param cursor a psycopg cursor
501- ## @param user res.user.id that is currently loged
502- ## @parma ids invoices id
503- ## @return a boolean True if valid False if invalid
504- def _check_reference_type(self, cursor, user, ids):
505- """Check the customer invoice reference type depending
506- on the BVR reference type and the invoice partner bank type"""
507- for invoice in self.browse(cursor, user, ids):
508- if invoice.type in 'in_invoice':
509- if invoice.partner_bank and \
510- invoice.partner_bank.state in \
511- ('bvrbank', 'bvrpost') and \
512- invoice.reference_type != 'bvr':
513- return False
514- return True
515-
516- _constraints = [
517- (_check_bvr, 'Error: Invalid Bvr Number (wrong checksum).',
518- ['reference']),
519- (_check_reference_type, 'Error: BVR reference is required.',
520- ['reference_type']),
521- ]
522-
523- ## @param self The object pointer.
524- ## @param cr a psycopg cursor
525- ## @param uid res.user.id that is currently loged
526- ## @parma ids invoices id
527- ## @parma type the invoice type
528- ## @param partner_id the partner linked to the invoice
529- ## @parma date_invoice date of the invoice
530- ## @parma payment_term inoice payment term
531- ## @param partner_bank_id the partner linked invoice bank
532- ## @return the dict of values with the partner_bank value updated
533- def onchange_partner_id(self, cr, uid, ids, type, partner_id,
534- date_invoice=False, payment_term=False, partner_bank_id=False):
535- """ Function that is call when the partner of the invoice is changed
536- it will retriev and set the good bank partner bank"""
537- res = super(account_invoice, self).onchange_partner_id(
538- cr,
539- uid,
540- ids,
541- type,
542- partner_id,
543- date_invoice,
544- payment_term
545- )
546- bank_id = False
547- if partner_id:
548- p = self.pool.get('res.partner').browse(cr, uid, partner_id)
549- if p.bank_ids:
550- bank_id = p.bank_ids[0].id
551-
552- if type in ('in_invoice', 'in_refund'):
553- res['value']['partner_bank'] = bank_id
554-
555- if partner_bank_id != bank_id:
556- to_update = self.onchange_partner_bank(cr, uid, ids, bank_id)
557- res['value'].update(to_update['value'])
558- return res
559-
560- ## @param self The object pointer.
561- ## @param cursor a psycopg cursor
562- ## @param user res.user.id that is currently loged
563- ## @parma ids invoices id
564- ## @param partner_bank_id the partner linked invoice bank
565- ## @return the dict of values with the reference type value updated
566- def onchange_partner_bank(self, cursor, user, ids, partner_bank_id):
567- """update the reference type depending of the partner bank"""
568- res = {'value': {}}
569- partner_bank_obj = self.pool.get('res.partner.bank')
570- if partner_bank_id:
571- partner_bank = partner_bank_obj.browse(cursor, user, partner_bank_id)
572- if partner_bank.state in ('bvrbank', 'bvrpost'):
573- res['value']['reference_type'] = 'bvr'
574- return res
575+ """Inherit account.invoice in order to add bvr
576+ printing functionnalites. BVR is a Swiss payment vector"""
577+ _inherit = "account.invoice"
578+
579+ ## @param self The object pointer.
580+ ## @param cursor a psycopg cursor
581+ ## @param user res.user.id that is currently loged
582+ ## @parma context a standard dict
583+ ## @return a list of tuple (name,value)
584+ def _get_reference_type(self, cursor, user, context=None):
585+ """Function use by the function field reference_type in order to initalise available
586+ BVR Reference Types"""
587+ res = super(account_invoice, self)._get_reference_type(cursor, user,
588+ context=context)
589+ res.append(('bvr', 'BVR'))
590+ return res
591+
592+ ## @param self The object pointer.
593+ ## @param cursor a psycopg cursor
594+ ## @param user res.user.id that is currently loged
595+ ## @parma context a standard dict
596+ ## @param name of the files
597+ ## @param args a list of diverse argument
598+ ## @parma context a standard dict
599+ ## @return a dict (invoice id,amount to pay)
600+ def _amount_to_pay(self, cursor, user, ids, name, args, context=None):
601+ '''Return the amount still to pay regarding all the payment orders'''
602+ if not ids:
603+ return {}
604+ res = {}
605+ for invoice in self.browse(cursor, user, ids, context=context):
606+ res[invoice.id] = 0.0
607+ if invoice.move_id:
608+ for line in invoice.move_id.line_id:
609+ if not line.date_maturity or \
610+ DateTime.strptime(line.date_maturity, '%Y-%m-%d') \
611+ < DateTime.now():
612+ res[invoice.id] += line.amount_to_pay
613+ return res
614+
615+ _columns = {
616+ ### BVR reference type BVR or FREE
617+ 'reference_type': fields.selection(_get_reference_type,
618+ 'Reference Type', required=True),
619+ ### Partner bank link between bank and partner id
620+ 'partner_bank': fields.many2one('res.partner.bank', 'Bank Account',
621+ help='The partner bank account to pay\nKeep empty to use the default'
622+ ),
623+ ### Amount to pay
624+ 'amount_to_pay': fields.function(_amount_to_pay, method=True,
625+ type='float', string='Amount to be paid',
626+ help='The amount which should be paid at the current date\n' \
627+ 'minus the amount which is already in payment order'),
628+ }
629+
630+ ## @param self The object pointer.
631+ ## @param cursor a psycopg cursor
632+ ## @param user res.user.id that is currently loged
633+ ## @parma ids invoices id
634+ ## @return a boolean True if valid False if invalid
635+ def _check_bvr(self, cr, uid, ids):
636+ """
637+ Function to validate a bvr reference like :
638+ 0100054150009>132000000000000000000000014+ 1300132412>
639+ The validation is based on l10n_ch
640+ """
641+ invoices = self.browse(cr,uid,ids)
642+ for invoice in invoices:
643+ if invoice.reference_type == 'bvr':
644+ if not invoice.reference:
645+ return False
646+ ## I need help for this bug because in this case
647+ # <010001000060190> 052550152684006+ 43435>
648+ # the reference 052550152684006 do not match modulo 10
649+ #
650+ if mod10r(invoice.reference[:-1]) != invoice.reference and \
651+ len(invoice.reference) == 15:
652+ return True
653+ #
654+ if mod10r(invoice.reference[:-1]) != invoice.reference:
655+ return False
656+ return True
657+ ## @param self The object pointer.
658+ ## @param cursor a psycopg cursor
659+ ## @param user res.user.id that is currently loged
660+ ## @parma ids invoices id
661+ ## @return a boolean True if valid False if invalid
662+ def _check_reference_type(self, cursor, user, ids):
663+ """Check the customer invoice reference type depending
664+ on the BVR reference type and the invoice partner bank type"""
665+ for invoice in self.browse(cursor, user, ids):
666+ if invoice.type in 'in_invoice':
667+ if invoice.partner_bank and \
668+ invoice.partner_bank.state in \
669+ ('bvrbank', 'bvrpost') and \
670+ invoice.reference_type != 'bvr':
671+ return False
672+ return True
673+
674+ _constraints = [
675+ (_check_bvr, 'Error: Invalid Bvr Number (wrong checksum).',
676+ ['reference']),
677+ (_check_reference_type, 'Error: BVR reference is required.',
678+ ['reference_type']),
679+ ]
680+
681+ ## @param self The object pointer.
682+ ## @param cr a psycopg cursor
683+ ## @param uid res.user.id that is currently loged
684+ ## @parma ids invoices id
685+ ## @parma type the invoice type
686+ ## @param partner_id the partner linked to the invoice
687+ ## @parma date_invoice date of the invoice
688+ ## @parma payment_term inoice payment term
689+ ## @param partner_bank_id the partner linked invoice bank
690+ ## @return the dict of values with the partner_bank value updated
691+ def onchange_partner_id(self, cr, uid, ids, type, partner_id,
692+ date_invoice=False, payment_term=False, partner_bank_id=False):
693+ """ Function that is call when the partner of the invoice is changed
694+ it will retriev and set the good bank partner bank"""
695+ res = super(account_invoice, self).onchange_partner_id(
696+ cr,
697+ uid,
698+ ids,
699+ type,
700+ partner_id,
701+ date_invoice,
702+ payment_term
703+ )
704+ bank_id = False
705+ if partner_id:
706+ p = self.pool.get('res.partner').browse(cr, uid, partner_id)
707+ if p.bank_ids:
708+ bank_id = p.bank_ids[0].id
709+
710+ if type in ('in_invoice', 'in_refund'):
711+ res['value']['partner_bank'] = bank_id
712+
713+ if partner_bank_id != bank_id:
714+ to_update = self.onchange_partner_bank(cr, uid, ids, bank_id)
715+ res['value'].update(to_update['value'])
716+ return res
717+
718+ ## @param self The object pointer.
719+ ## @param cursor a psycopg cursor
720+ ## @param user res.user.id that is currently loged
721+ ## @parma ids invoices id
722+ ## @param partner_bank_id the partner linked invoice bank
723+ ## @return the dict of values with the reference type value updated
724+ def onchange_partner_bank(self, cursor, user, ids, partner_bank_id):
725+ """update the reference type depending of the partner bank"""
726+ res = {'value': {}}
727+ partner_bank_obj = self.pool.get('res.partner.bank')
728+ if partner_bank_id:
729+ partner_bank = partner_bank_obj.browse(cursor, user, partner_bank_id)
730+ if partner_bank.state in ('bvrbank', 'bvrpost'):
731+ res['value']['reference_type'] = 'bvr'
732+ return res
733
734 account_invoice()
735
736 class account_tax_code(osv.osv):
737- """Inherit account tax code in order
738- to add a Case code"""
739- _name = 'account.tax.code'
740- _inherit = "account.tax.code"
741- _columns = {
742- ### The case code of the taxt code
743- 'code': fields.char('Case Code', size=512),
744- }
745+ """Inherit account tax code in order
746+ to add a Case code"""
747+ _name = 'account.tax.code'
748+ _inherit = "account.tax.code"
749+ _columns = {
750+ ### The case code of the taxt code
751+ 'code': fields.char('Case Code', size=512),
752+ }
753 account_tax_code()
754
755 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
756
757=== modified file 'l10n_ch/partner.py'
758--- l10n_ch/partner.py 2009-09-10 12:48:05 +0000
759+++ l10n_ch/partner.py 2009-10-16 12:20:30 +0000
760@@ -34,13 +34,13 @@
761 from osv import fields, osv
762
763 class res_partner(osv.osv):
764- _inherit = 'res.partner'
765+ _inherit = 'res.partner'
766
767- _columns = {
768- 'ref_companies': fields.one2many('res.company', 'partner_id',
769- 'Companies that refers to partner'),
770- }
771-
772+ _columns = {
773+ 'ref_companies': fields.one2many('res.company', 'partner_id',
774+ 'Companies that refers to partner'),
775+ }
776+
777
778
779 res_partner()
780@@ -48,52 +48,50 @@
781
782
783 class res_partner_bank(osv.osv):
784- _inherit = "res.partner.bank"
785- _columns = {
786- 'name': fields.char('Description', size=128, required=True),
787- 'post_number': fields.char('Post number', size=64),
788- 'bvr_number': fields.char('BVR account number', size=11),
789- 'bvr_adherent_num': fields.char('BVR adherent number', size=11),
790- 'dta_code': fields.char('DTA code', size=5),
791- }
792-
793- def _default_value(self, cursor, user, field, context=None):
794- if field in ('country_id', 'state_id'):
795- value = False
796- else:
797- value = ''
798- if not context.get('address', False):
799- return value
800- for ham, spam, address in context['address']:
801- if 'type' in address.keys() :
802- if address['type'] == 'default':
803- return address.get(field,False)
804- elif not address['type']:
805- value = address.get(field,False)
806- else :
807- value = False
808- return value
809-
810-
811- def name_get(self, cr, uid, ids, context=None):
812- if not len(ids):
813- return []
814- bank_type_obj = self.pool.get('res.partner.bank.type')
815-
816- type_ids = bank_type_obj.search(cr, uid, [])
817- bank_type_names = {}
818- for bank_type in bank_type_obj.browse(cr, uid, type_ids,
819- context=context):
820- bank_type_names[bank_type.code] = bank_type.name
821- res = []
822- for r in self.read(cr, uid, ids, ['name','state'], context):
823- res.append((r['id'], r['name']+' : '+bank_type_names[r['state']]))
824- return res
825-
826- _sql_constraints = [
827- ('bvr_adherent_uniq', 'unique (bvr_adherent_num)', 'The BVR adherent number must be unique !')
828- ]
829-
830-
831+ _inherit = "res.partner.bank"
832+ _columns = {
833+ 'name': fields.char('Description', size=128, required=True),
834+ 'post_number': fields.char('Post number', size=64),
835+ 'bvr_number': fields.char('BVR account number', size=11),
836+ 'bvr_adherent_num': fields.char('BVR adherent number', size=11),
837+ 'dta_code': fields.char('DTA code', size=5),
838+ }
839+
840+# def _default_value(self, cursor, user, field, context=None):
841+# if field in ('country_id', 'state_id'):
842+# value = False
843+# else:
844+# value = ''
845+# if not context.get('address', False):
846+# return value
847+# for ham, spam, address in context['address']:
848+# if 'type' in address.keys() :
849+# if address['type'] == 'default':
850+# return address[field]
851+# elif not address['type']:
852+# value = address[field]
853+# else :
854+# value = False
855+# return value
856+
857+
858+ def name_get(self, cr, uid, ids, context=None):
859+ if not len(ids):
860+ return []
861+ bank_type_obj = self.pool.get('res.partner.bank.type')
862+
863+ type_ids = bank_type_obj.search(cr, uid, [])
864+ bank_type_names = {}
865+ for bank_type in bank_type_obj.browse(cr, uid, type_ids,
866+ context=context):
867+ bank_type_names[bank_type.code] = bank_type.name
868+ res = []
869+ for r in self.read(cr, uid, ids, ['name','state'], context):
870+ res.append((r['id'], r['name']+' : '+bank_type_names[r['state']]))
871+ return res
872+
873+ _sql_constraints = [
874+ ('bvr_adherent_uniq', 'unique (bvr_adherent_num)', 'The BVR adherent number must be unique !')
875+ ]
876 res_partner_bank()
877 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
878
879=== modified file 'l10n_ch/payment.py'
880--- l10n_ch/payment.py 2009-04-09 10:02:19 +0000
881+++ l10n_ch/payment.py 2009-10-16 12:20:31 +0000
882@@ -34,11 +34,11 @@
883 from osv import osv
884
885 class payment_order(osv.osv):
886- _inherit = 'payment.order'
887+ _inherit = 'payment.order'
888
889- def get_wizard(self,mode):
890- if mode == 'dta':
891- return 'l10n_ch','wizard_account_dta_create'
892- return super(payment_order,self).get_wizard(mode)
893+ def get_wizard(self,mode):
894+ if mode == 'dta':
895+ return 'l10n_ch','wizard_account_dta_create'
896+ return super(payment_order,self).get_wizard(mode)
897 payment_order()
898 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
899
900=== modified file 'l10n_ch/report/bvr.py'
901--- l10n_ch/report/bvr.py 2009-10-09 11:49:00 +0000
902+++ l10n_ch/report/bvr.py 2009-10-16 12:20:31 +0000
903@@ -34,70 +34,92 @@
904 from report import report_sxw
905 from tools import mod10r
906 import re
907+import os
908+import sys
909+import shutil
910 from mx.DateTime import *
911
912 class account_invoice_bvr(report_sxw.rml_parse):
913- """Report class that Allows to print BVR payement vector"""
914- def __init__(self, cr, uid, name, context):
915- super(account_invoice_bvr, self).__init__(cr, uid, name, context=context)
916- self.localcontext.update({
917- 'time': time,
918- 'user':self.pool.get("res.users").browse(cr,uid,uid),
919- 'mod10r': mod10r,
920- '_space': self._space,
921- '_get_ref': self._get_ref,
922- 'comma_me': self.comma_me,
923- 'format_date': self._get_and_change_date_format_for_swiss,
924- #'date_invoice':
925- })
926- def _get_and_change_date_format_for_swiss (self,date_to_format):
927- date_formatted=''
928- print date_to_format
929- if date_to_format:
930- date_formatted = strptime(date_to_format,'%Y-%m-%d').strftime('%d.%m.%Y')
931- return date_formatted
932-
933- def comma_me(self,amount):
934- if type(amount) is float :
935- amount = str('%.2f'%amount)
936- else :
937- amount = str(amount)
938- orig = amount
939- new = re.sub("^(-?\d+)(\d{3})", "\g<1>'\g<2>", amount)
940- if orig == new:
941- return new
942- else:
943- return self.comma_me(new)
944-
945- def _space(self,nbr, nbrspc=5):
946- res = ''
947- for i in range(len(nbr)):
948- res = res + nbr[i]
949- if not (i-1) % nbrspc:
950- res = res + ' '
951- return res
952-
953- def _get_ref(self, o):
954- res = ''
955- if o.partner_bank.bvr_adherent_num:
956- res = o.partner_bank.bvr_adherent_num
957- invoice_number = ''
958- if o.number:
959- invoice_number = re.sub('[^0-9]', '0', o.number)
960- return mod10r(res + invoice_number.rjust(26-len(res), '0'))
961-
962-report_sxw.report_sxw(
963- 'report.l10n_ch.bvr',
964- 'account.invoice',
965- 'addons/l10n_ch/report/bvr.rml',
966- parser=account_invoice_bvr,
967- header=False)
968-
969-report_sxw.report_sxw(
970- 'report.l10n_ch.invoice.bvr',
971- 'account.invoice',
972- 'addons/l10n_ch/report/invoice.rml',
973- parser=account_invoice_bvr,
974- header=False)
975+ """Report class that Allows to print BVR payement vector"""
976+ def __init__(self, cr, uid, name, context):
977+ super(account_invoice_bvr, self).__init__(cr, uid, name, context)
978+ self.copyocrbfile('addons/l10n_ch/report/ocrbb.ttf')
979+ self.localcontext.update({
980+ 'time': time,
981+ 'user':self.pool.get("res.users").browse(cr,uid,uid),
982+ 'mod10r': mod10r,
983+ '_space': self._space,
984+ '_get_ref': self._get_ref,
985+ 'comma_me': self.comma_me,
986+ 'format_date': self._get_and_change_date_format_for_swiss,
987+ 'police_absolute_path' : self.police_absolute_path,
988+ 'copyocrbfile': self.copyocrbfile
989+ })
990+ def _get_and_change_date_format_for_swiss (self,date_to_format):
991+ date_formatted=''
992+ print date_to_format
993+ if date_to_format:
994+ date_formatted = strptime(date_to_format,'%Y-%m-%d').strftime('%d.%m.%Y')
995+ return date_formatted
996+
997+ def police_absolute_path(self, inner_path) :
998+ path = os.path.join(os.path.dirname(sys.argv[0]), inner_path)
999+ return path
1000+
1001+ def copyocrbfile(self,file):
1002+ src = self.police_absolute_path(file)
1003+ file = os.path.basename(src)
1004+ dest = os.path.join('/tmp/',file)
1005+ if not os.path.isfile(dest):
1006+ try:
1007+ shutil.copyfile(src,dest)
1008+ except:
1009+ """print ocrbfile was not copy in /tmp/ please
1010+ copy it manually from l10_ch/report"""
1011+
1012+
1013+
1014+ def comma_me(self,amount):
1015+ if type(amount) is float :
1016+ amount = str('%.2f'%amount)
1017+ else :
1018+ amount = str(amount)
1019+ orig = amount
1020+ new = re.sub("^(-?\d+)(\d{3})", "\g<1>'\g<2>", amount)
1021+ if orig == new:
1022+ return new
1023+ else:
1024+ return self.comma_me(new)
1025+
1026+ def _space(self,nbr, nbrspc=5):
1027+ res = ''
1028+ for i in range(len(nbr)):
1029+ res = res + nbr[i]
1030+ if not (i-1) % nbrspc:
1031+ res = res + ' '
1032+ return res
1033+
1034+ def _get_ref(self, o):
1035+ res = ''
1036+ if o.partner_bank.bvr_adherent_num:
1037+ res = o.partner_bank.bvr_adherent_num
1038+ invoice_number = ''
1039+ if o.number:
1040+ invoice_number = re.sub('[^0-9]', '0', o.number)
1041+ return mod10r(res + invoice_number.rjust(26-len(res), '0'))
1042+
1043+report_sxw.report_sxw(
1044+ 'report.l10n_ch.bvr',
1045+ 'account.invoice',
1046+ 'addons/l10n_ch/report/bvr.rml',
1047+ parser=account_invoice_bvr,
1048+ header=False)
1049+
1050+report_sxw.report_sxw(
1051+ 'report.l10n_ch.invoice.bvr',
1052+ 'account.invoice',
1053+ 'addons/l10n_ch/report/invoice.rml',
1054+ parser=account_invoice_bvr,
1055+ header=False)
1056
1057 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
1058
1059=== modified file 'l10n_ch/report/bvr.rml'
1060--- l10n_ch/report/bvr.rml 2009-02-13 15:53:46 +0000
1061+++ l10n_ch/report/bvr.rml 2009-10-16 12:20:31 +0000
1062@@ -1,40 +1,36 @@
1063 <?xml version="1.0"?>
1064 <document filename="test.pdf">
1065 <docinit>
1066- <registerFont fontName="ocrb" fontFile="addons/l10n_ch/report/ocrbb.ttf"/>
1067+ <registerFont fontFile="/tmp/ocrbb.ttf" expr="{'fontFile':str(police_absolute_path('addons/l10n_ch/report/ocrbb.ttf'))}" fontName="ocrb" />
1068 </docinit>
1069 <template pageSize="(210.0mm,297.0mm)" title="Test" author="Martin Simon" allowSplitting="20">
1070 <pageTemplate id="first">
1071 <pageGraphics>
1072- <setFont name="Helvetica" size="30"/>
1073- <fill color="darkblue"/>
1074- <stroke color="darkblue"/>
1075- <drawString x="1cm" y="27.8cm">[[ company.partner_id.name ]]</drawString>
1076- <lines>1cm 27.7cm 20cm 27.7cm</lines>
1077-
1078- <setFont name="Helvetica" size="10"/>
1079- <drawRightString x="20cm" y="27.8cm">[[ company.rml_header1 ]]</drawRightString>
1080-
1081- <drawString x="1cm" y="27.1cm">[[ company.partner_id.address[0].street ]]</drawString>
1082- <drawString x="1cm" y="26.7cm">[[ company.partner_id.address[0].zip ]] [[ company.partner_id.address[0].city ]]</drawString>
1083- <drawString x="17cm" y="27.1cm">TVA:</drawString>
1084- <drawString x="18cm" y="27.1cm">[[ company.partner_id.vat ]]</drawString>
1085- <drawString x="1cm" y="26.2cm">Phone:</drawString>
1086- <drawRightString x="7cm" y="26.2cm">[[ company.partner_id.address[0].phone ]]</drawRightString>
1087-
1088- <drawString x="1cm" y="25.8cm">Mail:</drawString>
1089- <drawRightString x="7cm" y="25.8cm">[[ company.partner_id.address[0].email ]]</drawRightString>
1090- <lines>1cm 25.7cm 7cm 25.7cm</lines>
1091-
1092- </pageGraphics>
1093+ <!-- You Logo - Change X,Y,Width and Height -->
1094+ <image x="1.3cm" y="27.6cm" height="40.0" >[[company.logo or removeParentNode('image')]]</image>
1095+ <setFont name="Helvetica" size="8"/>
1096+ <fill color="black"/>
1097+ <stroke color="black"/>
1098+ <lines>1.3cm 27.7cm 20cm 27.7cm</lines>
1099+
1100+ <drawRightString x="20cm" y="27.8cm">[[ company.rml_header1 ]] </drawRightString>
1101+ <drawString x="1.3cm" y="27.2cm">[[ company.partner_id.name ]]</drawString>
1102+ <drawString x="1.3cm" y="26.8cm">[[ company.partner_id.address and company.partner_id.address[0].street or '' ]]</drawString>
1103+ <drawString x="1.3cm" y="26.4cm">[[ company.partner_id.address and company.partner_id.address[0].zip or '' ]] [[ company.partner_id.address and company.partner_id.address[0].city or '' ]] - [[ company.partner_id.address and company.partner_id.address[0].country_id and company.partner_id.address[0].country_id.name or '']]</drawString>
1104+ <drawString x="1.3cm" y="26.0cm">Phone:</drawString>
1105+ <drawRightString x="7cm" y="26.0cm">[[ company.partner_id.address and company.partner_id.address[0].phone or '' ]]</drawRightString>
1106+ <drawString x="1.3cm" y="25.6cm">Mail:</drawString>
1107+ <drawRightString x="7cm" y="25.6cm">[[ company.partner_id.address and company.partner_id.address[0].email or '' ]]</drawRightString>
1108+ <lines>1.3cm 25.5cm 7cm 25.5cm</lines>
1109+ </pageGraphics>
1110
1111 <frame id="first" x1="24.0" y1="111.5mm" width="190mm" height="142mm" last="1"/>
1112 <frame id="Frame1"
1113 expr="{'height':str(111+(company.bvr_delta_vert or 0.0))+'mm', 'x1': str((company.bvr_delta_horz or 0.0))+'mm'}"
1114 x1="0mm"
1115- y1="0mm"
1116+ y1="-5"
1117 width="210mm"
1118- height="106mm"/>
1119+ height="111mm"/>
1120 </pageTemplate>
1121 </template>
1122
1123@@ -116,6 +112,12 @@
1124 -->
1125 <illustration width="210mm" height="106mm">
1126 <setFont name="Helvetica" size="11"/>
1127+ <drawString x="2mm" y="93mm">[[ o.partner_bank and o.partner_bank.printBank and o.partner_bank.bank and o.partner_bank.bank.name or '' ]]</drawString>
1128+ <drawString x="2mm" y="88mm">[[ o.partner_bank and o.partner_bank.printBank and o.partner_bank.bank and o.partner_bank.bank.zip or '']] [[ o.partner_bank and o.partner_bank.printBank and o.partner_bank.bank and o.partner_bank.bank.city or '']]</drawString>
1129+
1130+ <drawString x="62mm" y="93mm">[[ o.partner_bank and o.partner_bank.printBank and o.partner_bank.bank and o.partner_bank.bank.name or '' ]]</drawString>
1131+ <drawString x="62mm" y="88mm">[[ o.partner_bank and o.partner_bank.printBank and o.partner_bank.bank and o.partner_bank.bank.zip or '']] [[ o.partner_bank and o.partner_bank.printBank and o.partner_bank.bank and o.partner_bank.bank.city or '']]</drawString>
1132+
1133 <drawString x="2mm" y="78mm"> [[ user.company_id.partner_id.name ]]</drawString>
1134 <drawString x="2mm" y="73mm"> [[ user.company_id.partner_id.address[0].street ]]</drawString>
1135 <drawString x="2mm" y="68mm"> [[ (user.company_id.partner_id.address[0].street2 or '')]]</drawString>
1136@@ -145,10 +147,11 @@
1137 <drawString x="124mm" y="67mm">[[ _space(_get_ref(o)) ]]</drawString>
1138
1139 <setFont name="ocrb" size="12"/>
1140-
1141+ <drawRightString x="52 mm" y="59.3mm">[[ o.partner_bank and o.partner_bank.printAccount and o.partner_bank.bvr_number or '' ]]</drawRightString>
1142+ <drawRightString x="112mm" y="59.3mm">[[ o.partner_bank and o.partner_bank.printAccount and o.partner_bank.bvr_number or '' ]]</drawRightString>
1143 <drawRightString x="42mm" y="50mm">[[ _space(('%.2f' % o.amount_total)[:-3], 1) + ' ' ]]</drawRightString>
1144 <drawRightString x="104mm" y="50mm">[[ _space(('%.2f' % o.amount_total)[:-3], 1) + ' ' ]]</drawRightString>
1145-
1146+ <drawRightString x="114 mm" y="59.3mm">[[ o.partner_bank and o.partner_bank.printAccount and o.partner_bank.bvr_number or '' ]]</drawRightString>
1147 <drawRightString x="58mm" y="50mm">[[ _space(('%.2f' % o.amount_total)[-2:], 1) + ' ' ]]</drawRightString>
1148 <drawRightString x="119mm" y="50mm">[[ _space(('%.2f' % o.amount_total)[-2:], 1) + ' ' ]]</drawRightString>
1149
1150
1151=== modified file 'l10n_ch/report/invoice.rml'
1152--- l10n_ch/report/invoice.rml 2009-02-13 15:53:46 +0000
1153+++ l10n_ch/report/invoice.rml 2009-10-16 12:20:31 +0000
1154@@ -1,41 +1,40 @@
1155 <?xml version="1.0"?>
1156 <document filename="test.pdf">
1157 <docinit>
1158- <registerFont fontName="ocrb" fontFile="addons/l10n_ch/report/ocrbb.ttf"/>
1159+ <registerFont fontFile="/tmp/ocrbb.ttf" expr="{'fontFile':str(police_absolute_path('addons/l10n_ch/report/ocrbb.ttf'))}" fontName="ocrb" />
1160+
1161 </docinit>
1162
1163 <template pageSize="(210.0mm,297.0mm)" title="Test" author="Martin Simon" allowSplitting="20">
1164 <pageTemplate id="first">
1165 <pageGraphics>
1166- <!--logo-->
1167- <setFont name="Helvetica" size="30"/>
1168- <fill color="darkblue"/>
1169- <stroke color="darkblue"/>
1170- <drawString x="1cm" y="27.8cm">[[ company.partner_id.name ]]</drawString>
1171- <lines>1cm 27.7cm 20cm 27.7cm</lines>
1172-
1173- <setFont name="Helvetica" size="10"/>
1174- <drawRightString x="20cm" y="27.8cm">[[ company.rml_header1 ]]</drawRightString>
1175-
1176-
1177- <drawString x="1cm" y="27.1cm">[[ company.partner_id.address and company.partner_id.address[0].street ]]</drawString>
1178- <drawString x="1cm" y="26.7cm">[[ company.partner_id.address and company.partner_id.address[0].zip ]] [[ company.partner_id.address and company.partner_id.address[0].city ]] - [[ company.partner_id.address and company.partner_id.address[0].country_id and company.partner_id.address[0].country_id.name ]]</drawString>
1179- <drawString x="17cm" y="27.1cm">TVA:</drawString>
1180- <drawString x="18cm" y="27.1cm">[[ company.partner_id.vat ]]</drawString>
1181- <drawString x="1cm" y="26.2cm">Phone:</drawString>
1182- <drawRightString x="7cm" y="26.2cm">[[ company.partner_id.address and company.partner_id.address[0].phone ]]</drawRightString>
1183- <drawString x="1cm" y="25.8cm">Mail:</drawString>
1184- <drawRightString x="7cm" y="25.8cm">[[ company.partner_id.address and company.partner_id.address[0].email ]]</drawRightString>
1185- <lines>1cm 25.7cm 7cm 25.7cm</lines>
1186- </pageGraphics>
1187- <!-- end of header -->
1188+ <!-- You Logo - Change X,Y,Width and Height -->
1189+ <image x="1.3cm" y="27.6cm" height="40.0" >[[company.logo or removeParentNode('image')]]</image>
1190+ <setFont name="Helvetica" size="8"/>
1191+ <fill color="black"/>
1192+ <stroke color="black"/>
1193+ <lines>1.3cm 27.7cm 20cm 27.7cm</lines>
1194+
1195+ <drawRightString x="20cm" y="27.8cm">[[ company.rml_header1 ]]</drawRightString>
1196+
1197+
1198+ <drawString x="1.3cm" y="27.2cm">[[ company.partner_id.name ]]</drawString>
1199+ <drawString x="1.3cm" y="26.8cm">[[ company.partner_id.address and company.partner_id.address[0].street or '' ]]</drawString>
1200+ <drawString x="1.3cm" y="26.4cm">[[ company.partner_id.address and company.partner_id.address[0].zip or '' ]] [[ company.partner_id.address and company.partner_id.address[0].city or '' ]] - [[ company.partner_id.address and company.partner_id.address[0].country_id and company.partner_id.address[0].country_id.name or '']]</drawString>
1201+ <drawString x="1.3cm" y="26.0cm">Phone:</drawString>
1202+ <drawRightString x="7cm" y="26.0cm">[[ company.partner_id.address and company.partner_id.address[0].phone or '' ]]</drawRightString>
1203+ <drawString x="1.3cm" y="25.6cm">Mail:</drawString>
1204+ <drawRightString x="7cm" y="25.6cm">[[ company.partner_id.address and company.partner_id.address[0].email or '' ]]</drawRightString>
1205+ <lines>1.3cm 25.5cm 7cm 25.5cm</lines>
1206+ <drawCentredString x="10.5cm" y="0.8cm">Contact : [[ user.name ]] - Page: <pageNumber/></drawCentredString>
1207+ </pageGraphics> <!-- end of header -->
1208 <frame id="first" x1="24.0" y1="111.5mm" width="190mm" height="142mm" last="1"/>
1209 <frame id="Frame1"
1210 expr="{'height':str(111+(company.bvr_delta_vert or 0.0))+'mm', 'x1': str((company.bvr_delta_horz or 0.0))+'mm'}"
1211 x1="0mm"
1212- y1="0mm"
1213+ y1="-5"
1214 width="210mm"
1215- height="106mm"/>
1216+ height="111mm"/>
1217 </pageTemplate>
1218 </template>
1219 <!-- begin of core -->
1220@@ -189,7 +188,7 @@
1221 </para>
1222 <para style="P21">
1223 <font face="Helvetica">Invoice Date: </font>
1224- <font face="Helvetica">[[format_date(o.date_invoice)]]</font>
1225+ <font face="Helvetica">[[ o.date_invoice and format_date(o.date_invoice) or '']]</font>
1226 </para>
1227 <para style="P21">
1228 <font face="Helvetica">Remarque:</font>
1229@@ -248,19 +247,18 @@
1230 </td>
1231 </tr>
1232 </blockTable>
1233- <blockTable colWidths="28.0,499.0" style="Table4">
1234+ <blockTable colWidths="28.0, 499.0" style="Table4">
1235 <tr>
1236 <td>
1237- <para style="P16">[[ repeatIn((l.note and l.note.splitlines()) or [], 'note') ]]</para>
1238+ <para style="P9">[[ note or removeParentNode('blockTable') ]]</para>
1239 </td>
1240 <td>
1241- <para style="P9">[[ note or removeParentNode('table') ]]</para>
1242+ <xpre style="P16">[[ l.note ]]</xpre>
1243 </td>
1244 </tr>
1245 </blockTable>
1246 </section>
1247 <para style="P18">
1248- <font color="white"> </font>
1249 </para>
1250 <blockTable colWidths="215.0,313.0" style="Table5">
1251 <tr>
1252@@ -328,6 +326,11 @@
1253 -->
1254 <illustration width="210mm" height="106mm">
1255 <setFont name="Helvetica" size="11"/>
1256+ <drawString x="2mm" y="93mm">[[ o.partner_bank and o.partner_bank.printBank and o.partner_bank.bank and o.partner_bank.bank.name or '' ]]</drawString>
1257+ <drawString x="2mm" y="88mm">[[ o.partner_bank and o.partner_bank.printBank and o.partner_bank.bank and o.partner_bank.bank.zip or '']] [[ o.partner_bank and o.partner_bank.printBank and o.partner_bank.bank and o.partner_bank.bank.city or '']]</drawString>
1258+
1259+ <drawString x="62mm" y="93mm">[[ o.partner_bank and o.partner_bank.printBank and o.partner_bank.bank and o.partner_bank.bank.name or '' ]]</drawString>
1260+ <drawString x="62mm" y="88mm">[[ o.partner_bank and o.partner_bank.printBank and o.partner_bank.bank and o.partner_bank.bank.zip or '']] [[ o.partner_bank and o.partner_bank.printBank and o.partner_bank.bank and o.partner_bank.bank.city or '']]</drawString>
1261 <drawString x="2mm" y="78mm"> [[user.company_id.name]]</drawString>
1262 <drawString x="2mm" y="73mm"> [[ user.company_id.partner_id.address[0].street ]]</drawString>
1263 <drawString x="2mm" y="68mm"> [[ (user.company_id.partner_id.address[0].street2 or '')]]</drawString>
1264@@ -354,10 +357,12 @@
1265
1266
1267 <setFont name="ocrb" size="11"/>
1268+
1269 <drawString x="124mm" y="67mm">[[ _space(_get_ref(o)) ]]</drawString>
1270
1271 <setFont name="ocrb" size="12"/>
1272-
1273+ <drawRightString x="52 mm" y="59.3mm">[[ o.partner_bank and o.partner_bank.printAccount and o.partner_bank.bvr_number or '' ]]</drawRightString>
1274+ <drawRightString x="112mm" y="59.3mm">[[ o.partner_bank and o.partner_bank.printAccount and o.partner_bank.bvr_number or '' ]]</drawRightString>
1275 <drawRightString x="42mm" y="50mm">[[ _space(('%.2f' % o.amount_total)[:-3], 1) + ' ' ]]</drawRightString>
1276 <drawRightString x="104mm" y="50mm">[[ _space(('%.2f' % o.amount_total)[:-3], 1) + ' ' ]]</drawRightString>
1277
1278@@ -375,4 +380,4 @@
1279 </illustration>
1280
1281 </story>
1282-</document>
1283+</document>
1284\ No newline at end of file
1285
1286=== removed file 'l10n_ch/report/tiny_sxw2rml.py'
1287--- l10n_ch/report/tiny_sxw2rml.py 2009-04-09 10:02:19 +0000
1288+++ l10n_ch/report/tiny_sxw2rml.py 1970-01-01 00:00:00 +0000
1289@@ -1,342 +0,0 @@
1290-
1291-
1292-#!/usr/bin/python
1293-#coding: latin-1
1294-
1295-##############################################################################
1296-#
1297-# Copyright (c):
1298-#
1299-# 2005 pyopenoffice.py Martin Simon (http://www.bezirksreiter.de)
1300-# 2005 Fabien Pinckaers, TINY SPRL. (http://tiny.be)
1301-#
1302-# WARNING: This program as such is intended to be used by professional
1303-# programmers who take the whole responsability of assessing all potential
1304-# consequences resulting from its eventual inadequacies and bugs
1305-# End users who are looking for a ready-to-use solution with commercial
1306-# garantees and support are strongly adviced to contact a Free Software
1307-# Service Company
1308-#
1309-# This program is Free Software; you can redistribute it and/or
1310-# modify it under the terms of the GNU General Public License
1311-# as published by the Free Software Foundation; either version 2
1312-# of the License, or (at your option) any later version.
1313-#
1314-# This program is distributed in the hope that it will be useful,
1315-# but WITHOUT ANY WARRANTY; without even the implied warranty of
1316-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1317-# GNU General Public License for more details.
1318-#
1319-# You should have received a copy of the GNU General Public License
1320-# along with this program; if not, write to the Free Software
1321-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1322-#
1323-##############################################################################
1324-
1325-"""
1326-Tiny SXW2RML - The Tiny ERP's report engine
1327-
1328-Tiny SXW2RMLis part of the Tiny report project.
1329-Tiny Report is a module that allows you to render high quality PDF document
1330-from an OpenOffice template (.sxw) and any relationnal database.
1331-
1332-The whole source code is distributed under the terms of the
1333-GNU Public Licence.
1334-
1335-(c) 2005 pyopenoffice.py Martin Simon (http://www.bezirksreiter.de)
1336-(c) 2005-TODAY, Fabien Pinckaers - Tiny sprl
1337-"""
1338-__version__ = '0.9'
1339-
1340-
1341-import re
1342-import string
1343-import os
1344-import time
1345-import zipfile
1346-import xml.dom.minidom
1347-from reportlab.lib.units import toLength
1348-import optparse
1349-
1350-parser = optparse.OptionParser(
1351- version="Tiny Report v%s" % __version__,
1352- usage = 'tiny_sxw2rml.py [options] file.sxw')
1353-parser.add_option("-v", "--verbose", default=False, dest="verbose", help="enable basic debugging")
1354-parser.add_option("-o", "--output", dest="output", default='.', help="directory of image output")
1355-(opt, args) = parser.parse_args()
1356-if len(args) != 1:
1357- parser.error("incorrect number of arguments")
1358-
1359-class DomApiGeneral:
1360- """General DOM API utilities."""
1361- def __init__(self,content_string="",file=""):
1362- self.content_string = content_string
1363- self.re_digits = re.compile(r"(.*?\d)(pt|cm|mm|inch|in)")
1364-
1365- def _unitTuple(self,string):
1366- """Split values and units to a tuple."""
1367- temp = self.re_digits.findall(string)
1368- if not temp:
1369- return (string,"")
1370- else:
1371- return (temp[0])
1372-
1373- def stringPercentToFloat(self,string):
1374- temp = string.replace("""%""","")
1375- return float(temp)/100
1376-
1377- def findChildrenByName(self,parent,name,attr_dict={}):
1378- """Helper functions. Does not work recursively.
1379- Optional: also test for certain attribute/value pairs."""
1380- children = []
1381- for c in parent.childNodes:
1382- if c.nodeType == c.ELEMENT_NODE and c.nodeName == name:
1383- children.append(c)
1384- if attr_dict == {}:
1385- return children
1386- else:
1387- return self._selectForAttributes(nodelist=children,attr_dict=attr_dict)
1388-
1389- def _selectForAttributes(self,nodelist,attr_dict):
1390- "Helper function."""
1391- selected_nodes = []
1392- for n in nodelist:
1393- check = 1
1394- for a in attr_dict.keys():
1395- if n.getAttribute(a) != attr_dict[a]:
1396- # at least one incorrect attribute value?
1397- check = 0
1398- if check:
1399- selected_nodes.append(n)
1400- return selected_nodes
1401-
1402- def _stringToTuple(self,s):
1403- """Helper function."""
1404- try:
1405- temp = string.split(s,",")
1406- return int(temp[0]),int(temp[1])
1407- except:
1408- return None
1409-
1410- def _tupleToString(self,t):
1411- try:
1412- return self.openOfficeStringUtf8("%s,%s" % (t[0],t[1]))
1413- except:
1414- return None
1415-
1416- def _lengthToFloat(self,value):
1417- v = value
1418- if not self.re_digits.search(v):
1419- return v
1420- try:
1421- if v[-4:] == "inch":
1422- # OO files use "inch" instead of "in" in Reportlab units
1423- v = v[:-2]
1424- except:
1425- pass
1426- try:
1427- c = round(toLength(v))
1428- return c
1429- except:
1430- return v
1431-
1432- def openOfficeStringUtf8(self,string):
1433- if type(string) == unicode:
1434- return string.encode("utf-8")
1435- tempstring = unicode(string,"cp1252").encode("utf-8")
1436- return tempstring
1437-
1438-class DomApi(DomApiGeneral):
1439- """This class provides a DOM-API for XML-Files from an SXW-Archive."""
1440- def __init__(self,xml_content,xml_styles):
1441- DomApiGeneral.__init__(self)
1442- self.content_dom = xml.dom.minidom.parseString(xml_content)
1443- self.styles_dom = xml.dom.minidom.parseString(xml_styles)
1444- body = self.content_dom.getElementsByTagName("office:body")
1445- self.body = body and body[0]
1446-
1447- # TODO:
1448- self.style_dict = {}
1449- self.style_properties_dict = {}
1450-
1451- # ******** always use the following order:
1452- self.buildStyleDict()
1453- self.buildStylePropertiesDict()
1454-
1455- self.page_master = self.styles_dom.getElementsByTagName("style:page-master")[0]
1456- self.document = self.content_dom.getElementsByTagName("office:document-content")[0]
1457-
1458- def buildStylePropertiesDict(self):
1459- for s in self.style_dict.keys():
1460- self.style_properties_dict[s] = self.getStylePropertiesDict(s)
1461-
1462- def updateWithPercents(self,dict,updatedict):
1463- """Sometimes you find values like "115%" in the style hierarchy."""
1464- if not updatedict:
1465- # no style hierarchies for this style? =>
1466- return
1467- new_updatedict = copy.copy(updatedict)
1468- for u in new_updatedict.keys():
1469- try:
1470- if new_updatedict[u].find("""%""") != -1 and dict.has_key(u):
1471- number = float(self.re_digits.search(dict[u]).group(1))
1472- unit = self.re_digits.search(dict[u]).group(2)
1473- new_number = self.stringPercentToFloat(new_updatedict[u]) * number
1474- if unit == "pt":
1475- new_number = int(new_number)
1476- # no floats allowed for "pt"
1477- # OOo just takes the int, does not round (try it out!)
1478- new_updatedict[u] = "%s%s" % (new_number,unit)
1479- else:
1480- dict[u] = new_updatedict[u]
1481- except:
1482- dict[u] = new_updatedict[u]
1483- dict.update(new_updatedict)
1484-
1485- def normalizeStyleProperties(self):
1486- """Transfer all style:style-properties attributes from the
1487- self.style_properties_hierarchical dict to the automatic-styles
1488- from content.xml. Use this function to preprocess content.xml for
1489- XSLT transformations etc.Do not try to implement this function
1490- with XSlT - believe me, it's a terrible task..."""
1491- styles_styles = self.styles_dom.getElementsByTagName("style:style")
1492- automatic_styles = self.content_dom.getElementsByTagName("office:automatic-styles")[0]
1493- for s in styles_styles:
1494- automatic_styles.appendChild(s.cloneNode(deep=1))
1495- content_styles = self.content_dom.getElementsByTagName("style:style")
1496- # these are the content_styles with styles_styles added!!!
1497- for s in content_styles:
1498- c = self.findChildrenByName(s,"style:properties")
1499- if c == []:
1500- # some derived automatic styles do not have "style:properties":
1501- temp = self.content_dom.createElement("style:properties")
1502- s.appendChild(temp)
1503- c = self.findChildrenByName(s,"style:properties")
1504- c = c[0]
1505- dict = self.style_properties_dict[(s.getAttribute("style:name")).encode("latin-1")] or {}
1506- for attribute in dict.keys():
1507- c.setAttribute(self.openOfficeStringUtf8(attribute),self.openOfficeStringUtf8(dict[attribute]))
1508-
1509- def transferStylesXml(self):
1510- """Transfer certain sub-trees from styles.xml to the normalized content.xml
1511- (see above). It is not necessary to do this - for example - with paragraph styles.
1512- the "normalized" style properties contain all information needed for
1513- further processing."""
1514- # TODO: What about table styles etc.?
1515- page_master = self.page_master
1516- outline_styles = self.styles_dom.getElementsByTagName("text:outline-style")
1517- t = self.content_dom.createElement("transferredfromstylesxml")
1518- self.document.insertBefore(t,self.body)
1519- t_new = self.body.previousSibling
1520- try:
1521- t_new.appendChild(page_master.cloneNode(deep=1))
1522- t_new.appendChild(outline_styles[0].cloneNode(deep=1))
1523- except:
1524- pass
1525-
1526- def normalizeLength(self):
1527- """Normalize all lengthes to floats (i.e: 1 inch = 72).
1528- Always use this after "normalizeContent" and "transferStyles"!"""
1529- # TODO: The complex attributes of table cell styles are not transferred yet.
1530- #all_styles = self.content_dom.getElementsByTagName("style:properties")
1531- #all_styles += self.content_dom.getElementsByTagName("draw:image")
1532- all_styles = self.content_dom.getElementsByTagName("*")
1533- for s in all_styles:
1534- for x in s._attrs.keys():
1535- v = s.getAttribute(x)
1536- s.setAttribute(x,"%s" % self._lengthToFloat(v))
1537- # convert float to string first!
1538-
1539- def normalizeTableColumns(self):
1540- """Handle this strange table:number-columns-repeated attribute."""
1541- columns = self.content_dom.getElementsByTagName("table:table-column")
1542- for c in columns:
1543- if c.hasAttribute("table:number-columns-repeated"):
1544- number = int(c.getAttribute("table:number-columns-repeated"))
1545- c.removeAttribute("table:number-columns-repeated")
1546- for i in range(number-1):
1547- (c.parentNode).insertBefore(c.cloneNode(deep=1),c)
1548-
1549- def buildStyleDict(self):
1550- """Store all style:style-nodes from content.xml and styles.xml in self.style_dict.
1551- Caution: in this dict the nodes from two dom apis are merged!"""
1552- for st in (self.styles_dom,self.content_dom):
1553- for s in st.getElementsByTagName("style:style"):
1554- name = s.getAttribute("style:name").encode("latin-1")
1555- self.style_dict[name] = s
1556- return True
1557-
1558- def toxml(self):
1559- return self.content_dom.toxml(encoding="utf-8")
1560-
1561- def getStylePropertiesDict(self,style_name):
1562- res = {}
1563-
1564- if self.style_dict[style_name].hasAttribute("style:parent-style-name"):
1565- parent = self.style_dict[style_name].getAttribute("style:parent-style-name").encode("latin-1")
1566- res = self.getStylePropertiesDict(parent)
1567-
1568- childs = self.style_dict[style_name].childNodes
1569- for c in childs:
1570- if c.nodeType == c.ELEMENT_NODE and c.nodeName == "style:properties":
1571- for attr in c._attrs.keys():
1572- res[attr] = c.getAttribute(attr).encode("latin-1")
1573- return res
1574-
1575-class PyOpenOffice(object):
1576- """This is the main class which provides all functionality."""
1577- def __init__(self, path='.'):
1578- self.path = path
1579-
1580- def oo_read(self,fname):
1581- z = zipfile.ZipFile(fname,"r")
1582- content = z.read('content.xml')
1583- style = z.read('styles.xml')
1584- all = z.namelist()
1585- for a in all:
1586- if a[:9]=='Pictures/' and len(a)>10:
1587- pic_content = z.read(a)
1588- f=open(os.path.join(self.path, os.path.basename(a)),"wb")
1589- f.write(pic_content)
1590- f.close()
1591- z.close()
1592- return content,style
1593-
1594- def oo_replace(self,content):
1595- regex = [
1596- (r"<para[^>]*/>", ""),
1597- #(r"<text:ordered-list.*?>(.*?)</text:ordered-list>", "$1"),
1598- #(r"<text:unordered-list.*?>(.*?)</text:unordered-list>", "$1"),
1599- (r"<para(.*)>(.*?)<text:line-break[^>]*/>", "<para$1>$2</para><para$1>"),
1600- ]
1601- for key,val in regex:
1602- content = re.sub(key, val, content)
1603- return content
1604-
1605- def unpackNormalize(self,sourcefile):
1606- c,s = self.oo_read(sourcefile)
1607- c = self.oo_replace(c)
1608- dom = DomApi(c,s)
1609- dom.normalizeStyleProperties()
1610- dom.transferStylesXml()
1611- dom.normalizeLength()
1612- dom.normalizeTableColumns()
1613- new_c = dom.toxml()
1614- return new_c
1615-
1616-
1617-if __name__ == "__main__":
1618- import sys
1619- import libxslt
1620- import libxml2
1621-
1622- f = sys.argv[1]
1623- tool = PyOpenOffice(opt.output)
1624- res = tool.unpackNormalize(f)
1625- styledoc = libxml2.parseFile('normalized_oo2rml.xsl')
1626- style = libxslt.parseStylesheetDoc(styledoc)
1627- doc = libxml2.parseMemory(res,len(res))
1628- result = style.applyStylesheet(doc, None)
1629- xml = style.saveResultToString(result)
1630- print xml
1631-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
1632
1633=== modified file 'l10n_ch/wizard/bvr_import.py'
1634--- l10n_ch/wizard/bvr_import.py 2009-04-09 10:02:19 +0000
1635+++ l10n_ch/wizard/bvr_import.py 2009-10-16 12:20:31 +0000
1636@@ -39,215 +39,215 @@
1637
1638 ASK_FORM = """<?xml version="1.0"?>
1639 <form string="BVR Import">
1640- <field name="file"/>
1641+ <field name="file"/>
1642 </form>"""
1643
1644 ASK_FIELDS = {
1645- 'file': {
1646- 'string': 'BVR file',
1647- 'type': 'binary',
1648- 'required': True,
1649- },
1650+ 'file': {
1651+ 'string': 'BVR file',
1652+ 'type': 'binary',
1653+ 'required': True,
1654+ },
1655 }
1656
1657 def _reconstruct_invoice_ref(cursor, user, reference, context):
1658- ###
1659- id_invoice = False
1660- # On fait d'abord une recherche sur toutes les factures
1661- # we now searhc for company
1662- user_obj=pooler.get_pool(cursor.dbname).get('res.users')
1663- user_current=user_obj.browse(cursor, user, user)
1664-
1665- ##
1666-
1667- cursor.execute("SELECT inv.id,inv.number from account_invoice AS inv where inv.company_id = " + str(user_current.company_id.id))
1668- result_invoice = cursor.fetchall()
1669-
1670- for inv_id,inv_name in result_invoice:
1671- inv_name = re.sub('[^0-9]', '0', str(inv_name))
1672- if inv_name == reference:
1673- id_invoice = inv_id
1674- break
1675- if id_invoice:
1676- cursor.execute('SELECT l.id ' \
1677- 'FROM account_move_line l, account_invoice i ' \
1678- 'WHERE l.move_id = i.move_id AND l.reconcile_id is NULL ' \
1679- 'AND i.id in (' + ','.join([str(x) for x in [id_invoice]]) + ')')
1680- inv_line = []
1681- for id_line in cursor.fetchall():
1682- inv_line.append(id_line[0])
1683- return inv_line
1684- else:
1685- return []
1686- return True
1687+ ###
1688+ id_invoice = False
1689+ # On fait d'abord une recherche sur toutes les factures
1690+ # we now searhc for company
1691+ user_obj=pooler.get_pool(cursor.dbname).get('res.users')
1692+ user_current=user_obj.browse(cursor, user, user)
1693+
1694+ ##
1695+
1696+ cursor.execute("SELECT inv.id,inv.number from account_invoice AS inv where inv.company_id = " + str(user_current.company_id.id))
1697+ result_invoice = cursor.fetchall()
1698+
1699+ for inv_id,inv_name in result_invoice:
1700+ inv_name = re.sub('[^0-9]', '0', str(inv_name))
1701+ if inv_name == reference:
1702+ id_invoice = inv_id
1703+ break
1704+ if id_invoice:
1705+ cursor.execute('SELECT l.id ' \
1706+ 'FROM account_move_line l, account_invoice i ' \
1707+ 'WHERE l.move_id = i.move_id AND l.reconcile_id is NULL ' \
1708+ 'AND i.id in (' + ','.join([str(x) for x in [id_invoice]]) + ')')
1709+ inv_line = []
1710+ for id_line in cursor.fetchall():
1711+ inv_line.append(id_line[0])
1712+ return inv_line
1713+ else:
1714+ return []
1715+ return True
1716 def _import(obj, cursor, user, data, context):
1717
1718- pool = pooler.get_pool(cursor.dbname)
1719- statement_line_obj = pool.get('account.bank.statement.line')
1720- statement_reconcile_obj = pool.get('account.bank.statement.reconcile')
1721- move_line_obj = pool.get('account.move.line')
1722- property_obj = pool.get('ir.property')
1723- model_fields_obj = pool.get('ir.model.fields')
1724- attachment_obj = pool.get('ir.attachment')
1725- file = data['form']['file']
1726- statement_id = data['id']
1727-
1728- records = []
1729- total_amount = 0
1730- total_cost = 0
1731- find_total = False
1732-
1733- for lines in base64.decodestring(file).split("\n"):
1734- # Manage files without carriage return
1735- while lines:
1736- (line, lines) = (lines[:128], lines[128:])
1737- record = {}
1738-
1739- if line[0:3] in ('999', '995'):
1740- if find_total:
1741- raise wizard.except_wizard(_('Error'),
1742- _('Too much total record found!'))
1743- find_total = True
1744- if lines:
1745- raise wizard.except_wizard(_('Error'),
1746- _('Record found after total record!'))
1747- amount = float(line[39:49]) + (float(line[49:51]) / 100)
1748- cost = float(line[69:76]) + (float(line[76:78]) / 100)
1749- if line[2] == '5':
1750- amount *= -1
1751- cost *= -1
1752-
1753- if round(amount - total_amount, 2) >= 0.01 \
1754- or round(cost - total_cost, 2) >= 0.01:
1755- raise wizard.except_wizard(_('Error'),
1756- _('Total record different from the computed!'))
1757- if int(line[51:63]) != len(records):
1758- raise wizard.except_wizard(_('Error'),
1759- _('Number record different from the computed!'))
1760- else:
1761- record = {
1762- 'reference': line[12:39],
1763- 'amount': float(line[39:47]) + (float(line[47:49]) / 100),
1764- 'date': time.strftime('%Y-%m-%d',
1765- time.strptime(line[65:71], '%y%m%d')),
1766- 'cost': float(line[96:98]) + (float(line[98:100]) / 100),
1767- }
1768-
1769- if record['reference'] != mod10r(record['reference'][:-1]):
1770- raise wizard.except_wizard(_('Error'),
1771- _('Recursive mod10 is invalid for reference: %s') % \
1772- record['reference'])
1773-
1774- if line[2] == '5':
1775- record['amount'] *= -1
1776- record['cost'] *= -1
1777- total_amount += record['amount']
1778- total_cost += record['cost']
1779- records.append(record)
1780-
1781- model_fields_ids = model_fields_obj.search(cursor, user, [
1782- ('name', 'in', ['property_account_receivable', 'property_account_payable']),
1783- ('model', '=', 'res.partner'),
1784- ], context=context)
1785- property_ids = property_obj.search(cursor, user, [
1786- ('fields_id', 'in', model_fields_ids),
1787- ('res_id', '=', False),
1788- ], context=context)
1789-
1790- account_receivable = False
1791- account_payable = False
1792- for property in property_obj.browse(cursor, user, property_ids, context=context):
1793- if property.fields_id.name == 'property_account_receivable':
1794- account_receivable = int(property.value.split(',')[1])
1795- elif property.fields_id.name == 'property_account_payable':
1796- account_payable = int(property.value.split(',')[1])
1797-
1798- for record in records:
1799- # Remove the 11 first char because it can be adherent number
1800- # TODO check if 11 is the right number
1801- reference = record['reference'][11:-1].lstrip('0')
1802- values = {
1803- 'name': 'IN '+ reference,
1804- 'date': record['date'],
1805- 'amount': record['amount'],
1806- 'ref': reference,
1807- 'type': (record['amount'] >= 0 and 'customer') or 'supplier',
1808- 'statement_id': statement_id,
1809- }
1810- line_ids = move_line_obj.search(cursor, user, [
1811- ('ref', 'like', reference),
1812- ('reconcile_id', '=', False),
1813- ('account_id.type', 'in', ['receivable', 'payable']),
1814- ], order='date desc', context=context)
1815- if not line_ids:
1816- line_ids = _reconstruct_invoice_ref(cursor,user,reference,None)
1817-
1818- line2reconcile = False
1819- partner_id = False
1820- account_id = False
1821- for line in move_line_obj.browse(cursor, user, line_ids, context=context):
1822- if line.partner_id.id:
1823- partner_id = line.partner_id.id
1824- if record['amount'] >= 0:
1825- if round(record['amount'] - line.debit, 2) < 0.01:
1826- line2reconcile = line.id
1827- account_id = line.account_id.id
1828- break
1829- else:
1830- if round(line.credit + record['amount'], 2) < 0.01:
1831- line2reconcile = line.id
1832- account_id = line.account_id.id
1833- break
1834- if not account_id:
1835- if record['amount'] >= 0:
1836- account_id = account_receivable
1837- else:
1838- account_id = account_payable
1839- if not account_id :
1840- raise wizard.except_wizard(_('Error'),
1841- _('The properties account payable account receivable'))
1842- values['account_id'] = account_id
1843- values['partner_id'] = partner_id
1844-
1845- if line2reconcile:
1846- values['reconcile_id'] = statement_reconcile_obj.create(cursor, user, {
1847- 'line_ids': [(6, 0, [line2reconcile])],
1848- }, context=context)
1849-
1850- statement_line_obj.create(cursor, user, values, context=context)
1851- attachment_obj.create(cursor, user, {
1852- 'name': 'BVR',
1853- 'datas': file,
1854- 'datas_fname': 'BVR.txt',
1855- 'res_model': 'account.bank.statement',
1856- 'res_id': statement_id,
1857- }, context=context)
1858- return {}
1859+ pool = pooler.get_pool(cursor.dbname)
1860+ statement_line_obj = pool.get('account.bank.statement.line')
1861+ statement_reconcile_obj = pool.get('account.bank.statement.reconcile')
1862+ move_line_obj = pool.get('account.move.line')
1863+ property_obj = pool.get('ir.property')
1864+ model_fields_obj = pool.get('ir.model.fields')
1865+ attachment_obj = pool.get('ir.attachment')
1866+ file = data['form']['file']
1867+ statement_id = data['id']
1868+
1869+ records = []
1870+ total_amount = 0
1871+ total_cost = 0
1872+ find_total = False
1873+
1874+ for lines in base64.decodestring(file).split("\n"):
1875+ # Manage files without carriage return
1876+ while lines:
1877+ (line, lines) = (lines[:128], lines[128:])
1878+ record = {}
1879+
1880+ if line[0:3] in ('999', '995'):
1881+ if find_total:
1882+ raise wizard.except_wizard(_('Error'),
1883+ _('Too much total record found!'))
1884+ find_total = True
1885+ if lines:
1886+ raise wizard.except_wizard(_('Error'),
1887+ _('Record found after total record!'))
1888+ amount = float(line[39:49]) + (float(line[49:51]) / 100)
1889+ cost = float(line[69:76]) + (float(line[76:78]) / 100)
1890+ if line[2] == '5':
1891+ amount *= -1
1892+ cost *= -1
1893+
1894+ if round(amount - total_amount, 2) >= 0.01 \
1895+ or round(cost - total_cost, 2) >= 0.01:
1896+ raise wizard.except_wizard(_('Error'),
1897+ _('Total record different from the computed!'))
1898+ if int(line[51:63]) != len(records):
1899+ raise wizard.except_wizard(_('Error'),
1900+ _('Number record different from the computed!'))
1901+ else:
1902+ record = {
1903+ 'reference': line[12:39],
1904+ 'amount': float(line[39:47]) + (float(line[47:49]) / 100),
1905+ 'date': time.strftime('%Y-%m-%d',
1906+ time.strptime(line[65:71], '%y%m%d')),
1907+ 'cost': float(line[96:98]) + (float(line[98:100]) / 100),
1908+ }
1909+
1910+ if record['reference'] != mod10r(record['reference'][:-1]):
1911+ raise wizard.except_wizard(_('Error'),
1912+ _('Recursive mod10 is invalid for reference: %s') % \
1913+ record['reference'])
1914+
1915+ if line[2] == '5':
1916+ record['amount'] *= -1
1917+ record['cost'] *= -1
1918+ total_amount += record['amount']
1919+ total_cost += record['cost']
1920+ records.append(record)
1921+
1922+ model_fields_ids = model_fields_obj.search(cursor, user, [
1923+ ('name', 'in', ['property_account_receivable', 'property_account_payable']),
1924+ ('model', '=', 'res.partner'),
1925+ ], context=context)
1926+ property_ids = property_obj.search(cursor, user, [
1927+ ('fields_id', 'in', model_fields_ids),
1928+ ('res_id', '=', False),
1929+ ], context=context)
1930+
1931+ account_receivable = False
1932+ account_payable = False
1933+ for property in property_obj.browse(cursor, user, property_ids, context=context):
1934+ if property.fields_id.name == 'property_account_receivable':
1935+ account_receivable = int(property.value.split(',')[1])
1936+ elif property.fields_id.name == 'property_account_payable':
1937+ account_payable = int(property.value.split(',')[1])
1938+
1939+ for record in records:
1940+ # Remove the 11 first char because it can be adherent number
1941+ # TODO check if 11 is the right number
1942+ reference = record['reference'][11:-1].lstrip('0')
1943+ values = {
1944+ 'name': 'IN '+ reference,
1945+ 'date': record['date'],
1946+ 'amount': record['amount'],
1947+ 'ref': reference,
1948+ 'type': (record['amount'] >= 0 and 'customer') or 'supplier',
1949+ 'statement_id': statement_id,
1950+ }
1951+ line_ids = move_line_obj.search(cursor, user, [
1952+ ('ref', 'like', reference),
1953+ ('reconcile_id', '=', False),
1954+ ('account_id.type', 'in', ['receivable', 'payable']),
1955+ ], order='date desc', context=context)
1956+ if not line_ids:
1957+ line_ids = _reconstruct_invoice_ref(cursor,user,reference,None)
1958+
1959+ line2reconcile = False
1960+ partner_id = False
1961+ account_id = False
1962+ for line in move_line_obj.browse(cursor, user, line_ids, context=context):
1963+ if line.partner_id.id:
1964+ partner_id = line.partner_id.id
1965+ if record['amount'] >= 0:
1966+ if round(record['amount'] - line.debit, 2) < 0.01:
1967+ line2reconcile = line.id
1968+ account_id = line.account_id.id
1969+ break
1970+ else:
1971+ if round(line.credit + record['amount'], 2) < 0.01:
1972+ line2reconcile = line.id
1973+ account_id = line.account_id.id
1974+ break
1975+ if not account_id:
1976+ if record['amount'] >= 0:
1977+ account_id = account_receivable
1978+ else:
1979+ account_id = account_payable
1980+ if not account_id :
1981+ raise wizard.except_wizard(_('Error'),
1982+ _('The properties account payable account receivable'))
1983+ values['account_id'] = account_id
1984+ values['partner_id'] = partner_id
1985+
1986+ if line2reconcile:
1987+ values['reconcile_id'] = statement_reconcile_obj.create(cursor, user, {
1988+ 'line_ids': [(6, 0, [line2reconcile])],
1989+ }, context=context)
1990+
1991+ statement_line_obj.create(cursor, user, values, context=context)
1992+ attachment_obj.create(cursor, user, {
1993+ 'name': 'BVR',
1994+ 'datas': file,
1995+ 'datas_fname': 'BVR.txt',
1996+ 'res_model': 'account.bank.statement',
1997+ 'res_id': statement_id,
1998+ }, context=context)
1999+ return {}
2000
2001
2002 class BVRImport(wizard.interface):
2003- states = {
2004- 'init': {
2005- 'actions': [],
2006- 'result': {
2007- 'type': 'form',
2008- 'arch': ASK_FORM,
2009- 'fields': ASK_FIELDS,
2010- 'state': [
2011- ('end', 'Cancel', 'gtk-cancel'),
2012- ('import', 'Import', 'gtk-ok', True),
2013- ],
2014- },
2015- },
2016- 'import': {
2017- 'actions': [],
2018- 'result': {
2019- 'type': 'action',
2020- 'action': _import,
2021- 'state': 'end',
2022- },
2023- },
2024- }
2025+ states = {
2026+ 'init': {
2027+ 'actions': [],
2028+ 'result': {
2029+ 'type': 'form',
2030+ 'arch': ASK_FORM,
2031+ 'fields': ASK_FIELDS,
2032+ 'state': [
2033+ ('end', 'Cancel', 'gtk-cancel'),
2034+ ('import', 'Import', 'gtk-ok', True),
2035+ ],
2036+ },
2037+ },
2038+ 'import': {
2039+ 'actions': [],
2040+ 'result': {
2041+ 'type': 'action',
2042+ 'action': _import,
2043+ 'state': 'end',
2044+ },
2045+ },
2046+ }
2047
2048 BVRImport('l10n_ch.bvr_import')
2049 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
2050
2051=== modified file 'l10n_ch/wizard/dta_wizard.py'
2052--- l10n_ch/wizard/dta_wizard.py 2009-04-13 12:43:13 +0000
2053+++ l10n_ch/wizard/dta_wizard.py 2009-10-16 12:20:31 +0000
2054@@ -41,558 +41,568 @@
2055 FORM = """<?xml version="1.0"?>
2056 <form string="DTA file creation - Results">
2057 <separator colspan="4" string="Clic on 'Save as' to save the DTA file :" />
2058- <field name="dta"/>
2059+ <field name="dta"/>
2060 </form>"""
2061
2062 FIELDS = {
2063- 'dta': {
2064- 'string': 'DTA File',
2065- 'type': 'binary',
2066- 'readonly': True,
2067- },
2068+ 'dta': {
2069+ 'string': 'DTA File',
2070+ 'type': 'binary',
2071+ 'readonly': True,
2072+ },
2073 }
2074
2075 TRANS=[
2076- (u'é','e'),
2077- (u'è','e'),
2078- (u'à','a'),
2079- (u'ê','e'),
2080- (u'î','i'),
2081- (u'ï','i'),
2082- (u'â','a'),
2083- (u'ä','a'),
2084+ (u'é','e'),
2085+ (u'è','e'),
2086+ (u'à','a'),
2087+ (u'ê','e'),
2088+ (u'î','i'),
2089+ (u'ï','i'),
2090+ (u'â','a'),
2091+ (u'ä','a'),
2092 ]
2093
2094-def tr(s):
2095- s= s.decode('utf-8')
2096- for k in TRANS:
2097- s = s.replace(k[0],k[1])
2098- try:
2099- res= s.encode('ascii','replace')
2100- except:
2101- res = s
2102- return res
2103+def tr(string_in):
2104+ try:
2105+ string_in= string_in.decode('utf-8')
2106+ except:
2107+ # If exception => then just take the string as is
2108+ pass
2109+ for k in TRANS:
2110+ string_in = string_in.replace(k[0],k[1])
2111+ try:
2112+ res= string_in.encode('ascii','replace')
2113+ except:
2114+ res = string_in
2115+ return res
2116
2117
2118 class record:
2119
2120- def __init__(self, global_context_dict):
2121- for i in global_context_dict:
2122- global_context_dict[i] = global_context_dict[i] \
2123- and tr(global_context_dict[i])
2124- self.fields = []
2125- self.global_values = global_context_dict
2126- self.pre = {
2127- 'padding': '',
2128- 'seg_num1': '01',
2129- 'seg_num2': '02',
2130- 'seg_num3': '03',
2131- 'seg_num4': '04',
2132- 'seg_num5': '05',
2133- 'flag': '0',
2134- 'zero5': '00000'
2135- }
2136- self.post={'date_value_hdr': '000000', 'type_paiement': '0'}
2137- self.init_local_context()
2138-
2139- def init_local_context(self):
2140- """
2141- Must instanciate a fields list, field = (name,size)
2142- and update a local_values dict.
2143- """
2144- raise _('not implemented')
2145-
2146- def generate(self):
2147- res=''
2148- for field in self.fields :
2149- if self.pre.has_key(field[0]):
2150- value = self.pre[field[0]]
2151- elif self.global_values.has_key(field[0]):
2152- value = self.global_values[field[0]]
2153- elif self.post.has_key(field[0]):
2154- value = self.post[field[0]]
2155- else :
2156- pass
2157- #raise Exception(field[0]+' not found !')
2158- try:
2159- res = res + c_ljust(value, field[1])
2160- except :
2161- pass
2162- return res
2163+ def __init__(self, global_context_dict):
2164+ for i in global_context_dict:
2165+ global_context_dict[i] = global_context_dict[i] \
2166+ and tr(global_context_dict[i])
2167+ self.fields = []
2168+ self.global_values = global_context_dict
2169+ self.pre = {
2170+ 'padding': '',
2171+ 'seg_num1': '01',
2172+ 'seg_num2': '02',
2173+ 'seg_num3': '03',
2174+ 'seg_num4': '04',
2175+ 'seg_num5': '05',
2176+ 'flag': '0',
2177+ 'zero5': '00000'
2178+ }
2179+ self.post={'date_value_hdr': '000000', 'type_paiement': '0'}
2180+ self.init_local_context()
2181+
2182+ def init_local_context(self):
2183+ """
2184+ Must instanciate a fields list, field = (name,size)
2185+ and update a local_values dict.
2186+ """
2187+ raise _('not implemented')
2188+
2189+ def generate(self):
2190+ res=''
2191+ for field in self.fields :
2192+ if self.pre.has_key(field[0]):
2193+ value = self.pre[field[0]]
2194+ elif self.global_values.has_key(field[0]):
2195+ value = self.global_values[field[0]]
2196+ elif self.post.has_key(field[0]):
2197+ value = self.post[field[0]]
2198+ else :
2199+ pass
2200+ #raise Exception(field[0]+' not found !')
2201+ try:
2202+ res = res + c_ljust(value, field[1])
2203+ except :
2204+ pass
2205+ return res
2206
2207
2208 class record_gt826(record):
2209- """
2210- bvr
2211- """
2212- def init_local_context(self):
2213- self.fields=[
2214- ('seg_num1', 2),
2215- #header
2216- ('date_value_hdr', 6),
2217- ('partner_bank_clearing', 12),
2218- ('zero5', 5),
2219- ('creation_date', 6),
2220- ('comp_bank_clearing', 7),
2221- ('uid', 5),
2222- ('sequence', 5),
2223- ('genre_trans', 3),
2224- ('type_paiement', 1),
2225- ('flag', 1),
2226- #seg1
2227- ('comp_dta', 5),
2228- ('number', 11),
2229- ('comp_bank_iban', 24),
2230- ('date_value', 6),
2231- ('currency', 3),
2232- ('amount_to_pay', 12),
2233- ('padding', 14),
2234- #seg2
2235- ('seg_num2', 2),
2236- ('comp_name', 20),
2237- ('comp_street', 20),
2238- ('comp_zip', 10),
2239- ('comp_city', 10),
2240- ('comp_country', 20),
2241- ('padding', 46),
2242- #seg3
2243- ('seg_num3', 2),
2244- ('partner_bvr', 12),#numero d'adherent bvr
2245- ('partner_name', 20),
2246- ('partner_street', 20),
2247- ('partner_zip', 10),
2248- ('partner_city', 10),
2249- ('partner_country', 20),
2250- ('reference', 27),#communication structuree
2251- ('padding', 2),#cle de controle
2252- ('padding', 5)
2253- ]
2254- self.pre.update({
2255- 'date_value_hdr': self.global_values['date_value'],
2256- 'date_value': '',
2257- 'partner_bank_clearing': '',
2258- 'partner_cpt_benef': '',
2259- 'genre_trans': '826',
2260- 'conv_cours': '',
2261- 'option_id_bank': 'D',
2262- 'partner_bvr': '/C/'+ self.global_values['partner_bvr'],
2263- 'ref2': '',
2264- 'ref3': '',
2265- 'format': '0',
2266- })
2267+ """
2268+ bvr
2269+ """
2270+ def init_local_context(self):
2271+ self.fields=[
2272+ ('seg_num1', 2),
2273+ #header
2274+ ('date_value_hdr', 6),
2275+ ('partner_bank_clearing', 12),
2276+ ('zero5', 5),
2277+ ('creation_date', 6),
2278+ ('comp_bank_clearing', 7),
2279+ ('uid', 5),
2280+ ('sequence', 5),
2281+ ('genre_trans', 3),
2282+ ('type_paiement', 1),
2283+ ('flag', 1),
2284+ #seg1
2285+ ('comp_dta', 5),
2286+ ('number', 11),
2287+ ('comp_bank_iban', 24),
2288+ ('date_value', 6),
2289+ ('currency', 3),
2290+ ('amount_to_pay', 12),
2291+ ('padding', 14),
2292+ #seg2
2293+ ('seg_num2', 2),
2294+ ('comp_name', 20),
2295+ ('comp_street', 20),
2296+ ('comp_zip', 10),
2297+ ('comp_city', 10),
2298+ ('comp_country', 20),
2299+ ('padding', 46),
2300+ #seg3
2301+ ('seg_num3', 2),
2302+ ('partner_bvr', 12),#numero d'adherent bvr
2303+ ('partner_name', 20),
2304+ ('partner_street', 20),
2305+ ('partner_zip', 10),
2306+ ('partner_city', 10),
2307+ ('partner_country', 20),
2308+ ('reference', 27),#communication structuree
2309+ ('padding', 2),#cle de controle
2310+ ('padding', 5)
2311+ ]
2312+ self.pre.update({
2313+ 'date_value_hdr': self.global_values['date_value'],
2314+ 'date_value': '',
2315+ 'partner_bank_clearing': '',
2316+ 'partner_cpt_benef': '',
2317+ 'genre_trans': '826',
2318+ 'conv_cours': '',
2319+ 'option_id_bank': 'D',
2320+ 'partner_bvr': '/C/'+ self.global_values['partner_bvr'],
2321+ 'ref2': '',
2322+ 'ref3': '',
2323+ 'format': '0',
2324+ })
2325
2326 class record_gt827(record):
2327- """
2328- interne suisse (bvpost et bvbank)
2329- """
2330- def init_local_context(self):
2331- self.fields = [
2332- ('seg_num1', 2),
2333- #header
2334- ('date_value_hdr', 6),
2335- ('partner_bank_clearing', 12),
2336- ('zero5', 5),
2337- ('creation_date', 6),
2338- ('comp_bank_clearing', 7),
2339- ('uid', 5),
2340- ('sequence', 5),
2341- ('genre_trans', 3),
2342- ('type_paiement', 1),
2343- ('flag', 1),
2344- #seg1
2345- ('comp_dta', 5),
2346- ('number', 11),
2347- ('comp_bank_iban', 24),
2348- ('date_value', 6),
2349- ('currency', 3),
2350- ('amount_to_pay', 12),
2351- ('padding', 14),
2352- #seg2
2353- ('seg_num2', 2),
2354- ('comp_name', 20),
2355- ('comp_street', 20),
2356- ('comp_zip', 10),
2357- ('comp_city', 10),
2358- ('comp_country', 20),
2359- ('padding', 46),
2360- #seg3
2361- ('seg_num3', 2),
2362- ('partner_bank_number', 30),
2363- ('partner_name', 24),
2364- ('partner_street', 24),
2365- ('partner_zip', 12),
2366- ('partner_city', 12),
2367- ('partner_country', 24),
2368- #seg4
2369- ('seg_num4', 2),
2370- ('reference', 112),
2371- ('padding', 14),
2372- #seg5
2373- #('padding',128)
2374- ]
2375+ """
2376+ interne suisse (bvpost et bvbank)
2377+ """
2378+ def init_local_context(self):
2379+ self.fields = [
2380+ ('seg_num1', 2),
2381+ #header
2382+ ('date_value_hdr', 6),
2383+ ('partner_bank_clearing', 12),
2384+ ('zero5', 5),
2385+ ('creation_date', 6),
2386+ ('comp_bank_clearing', 7),
2387+ ('uid', 5),
2388+ ('sequence', 5),
2389+ ('genre_trans', 3),
2390+ ('type_paiement', 1),
2391+ ('flag', 1),
2392+ #seg1
2393+ ('comp_dta', 5),
2394+ ('number', 11),
2395+ ('comp_bank_iban', 24),
2396+ ('date_value', 6),
2397+ ('currency', 3),
2398+ ('amount_to_pay', 12),
2399+ ('padding', 14),
2400+ #seg2
2401+ ('seg_num2', 2),
2402+ ('comp_name', 20),
2403+ ('comp_street', 20),
2404+ ('comp_zip', 10),
2405+ ('comp_city', 10),
2406+ ('comp_country', 20),
2407+ ('padding', 46),
2408+ #seg3
2409+ ('seg_num3', 2),
2410+ ('partner_bank_number', 30),
2411+ ('partner_name', 24),
2412+ ('partner_street', 24),
2413+ ('partner_zip', 12),
2414+ ('partner_city', 12),
2415+ ('partner_country', 24),
2416+ #seg4
2417+ ('seg_num4', 2),
2418+ ('reference', 112),
2419+ ('padding', 14),
2420+ #seg5
2421+ #('padding',128)
2422+ ]
2423
2424- self.pre.update({
2425- 'date_value_hdr': self.global_values['date_value'],
2426- 'date_value': '',
2427- 'partner_cpt_benef': '',
2428- 'type_paiement': '0',
2429- 'genre_trans': '827',
2430- 'conv_cours': '',
2431- 'option_id_bank': 'D',
2432- 'ref2': '',
2433- 'ref3': '',
2434- 'format': '0'
2435- })
2436+ self.pre.update({
2437+ 'date_value_hdr': self.global_values['date_value'],
2438+ 'date_value': '',
2439+ 'partner_cpt_benef': '',
2440+ 'type_paiement': '0',
2441+ 'genre_trans': '827',
2442+ 'conv_cours': '',
2443+ 'option_id_bank': 'D',
2444+ 'ref2': '',
2445+ 'ref3': '',
2446+ 'format': '0'
2447+ })
2448
2449
2450 class record_gt836(record):
2451- """
2452- iban
2453- """
2454- def init_local_context(self):
2455- self.fields = [
2456- ('seg_num1', 2),
2457- #header
2458- ('date_value_hdr', 6),
2459- ('partner_bank_clearing', 12),
2460- ('zero5', 5),
2461- ('creation_date', 6),
2462- ('comp_bank_clearing', 7),
2463- ('uid', 5),
2464- ('sequence', 5),
2465- ('genre_trans', 3),
2466- ('type_paiement', 1),
2467- ('flag', 1),
2468- #seg1
2469- ('comp_dta', 5),
2470- ('number', 11),
2471- ('comp_bank_iban', 24),
2472- ('date_value', 6),
2473- ('currency', 3),
2474- ('amount_to_pay', 15),
2475- ('padding', 11),
2476- #seg2
2477- ('seg_num2', 2),
2478- ('conv_cours', 12),
2479- ('comp_name', 35),
2480- ('comp_street', 35),
2481- ('comp_country', 3),
2482- ('comp_zip', 10),
2483- ('comp_city', 22),
2484- ('padding', 9),
2485- #seg3
2486- ('seg_num3', 2),
2487- ('option_id_bank', 1),
2488- ('partner_bank_ident', 70),
2489- ('partner_bank_iban', 34),
2490- ('padding', 21),
2491- #seg4
2492- ('seg_num4', 2),
2493- ('partner_name', 35),
2494- ('partner_street', 35),
2495- ('partner_country', 3),
2496- ('partner_zip', 10),
2497- ('partner_city', 22),
2498- ('padding', 21),
2499- #seg5
2500- ('seg_num5', 2),
2501- ('option_motif', 1),
2502- ('reference', 105),
2503- ('format', 1),
2504- ('padding', 19)
2505- ]
2506- self.pre.update( {
2507- 'partner_bank_clearing': '',
2508- 'partner_cpt_benef': '',
2509- 'type_paiement': '0',
2510- 'genre_trans': '836',
2511- 'conv_cours': '',
2512- 'reference': self.global_values['reference'],
2513- 'ref2': '',
2514- 'ref3': '',
2515- 'format': '2'
2516- })
2517- self.post.update({'option_motif': 'U'})
2518+ """
2519+ iban
2520+ """
2521+ def init_local_context(self):
2522+ self.fields = [
2523+ ('seg_num1', 2),
2524+ #header
2525+ ('date_value_hdr', 6),
2526+ ('partner_bank_clearing', 12),
2527+ ('zero5', 5),
2528+ ('creation_date', 6),
2529+ ('comp_bank_clearing', 7),
2530+ ('uid', 5),
2531+ ('sequence', 5),
2532+ ('genre_trans', 3),
2533+ ('type_paiement', 1),
2534+ ('flag', 1),
2535+ #seg1
2536+ ('comp_dta', 5),
2537+ ('number', 11),
2538+ ('comp_bank_iban', 24),
2539+ ('date_value', 6),
2540+ ('currency', 3),
2541+ ('amount_to_pay', 15),
2542+ ('padding', 11),
2543+ #seg2
2544+ ('seg_num2', 2),
2545+ ('conv_cours', 12),
2546+ ('comp_name', 35),
2547+ ('comp_street', 35),
2548+ ('comp_country', 3),
2549+ ('comp_zip', 10),
2550+ ('comp_city', 22),
2551+ ('padding', 9),
2552+ #seg3
2553+ ('seg_num3', 2),
2554+ ('option_id_bank', 1),
2555+ ('partner_bank_ident', 70),
2556+ ('partner_bank_iban', 34),
2557+ ('padding', 21),
2558+ #seg4
2559+ ('seg_num4', 2),
2560+ ('partner_name', 35),
2561+ ('partner_street', 35),
2562+ ('partner_country', 3),
2563+ ('partner_zip', 10),
2564+ ('partner_city', 22),
2565+ ('padding', 21),
2566+ #seg5
2567+ ('seg_num5', 2),
2568+ ('option_motif', 1),
2569+ ('reference', 105),
2570+ ('format', 1),
2571+ ('padding', 19)
2572+ ]
2573+ self.pre.update( {
2574+ 'partner_bank_clearing': '',
2575+ 'partner_cpt_benef': '',
2576+ 'type_paiement': '0',
2577+ 'genre_trans': '836',
2578+ 'conv_cours': '',
2579+ 'reference': self.global_values['reference'],
2580+ 'ref2': '',
2581+ 'ref3': '',
2582+ 'format': '2'
2583+ })
2584+ self.post.update({'option_motif': 'U'})
2585
2586
2587 class record_gt890(record):
2588- """
2589- Total
2590- """
2591- def init_local_context(self):
2592- self.fields = [
2593- ('seg_num1', 2),
2594- #header
2595- ('date_value_hdr', 6),
2596- ('partner_bank_clearing', 12),
2597- ('zero5', 5),
2598- ('creation_date', 6),
2599- ('comp_bank_clearing', 7),
2600- ('uid', 5),
2601- ('sequence', 5),
2602- ('genre_trans', 3),
2603- ('type_paiement', 1),
2604- ('flag', 1),
2605- #total
2606- ('amount_total', 16),
2607- ('padding', 59)
2608- ]
2609- self.pre.update({'partner_bank_clearing': '', 'partner_cpt_benef': '',
2610- 'company_bank_clearing': '', 'genre_trans': '890'})
2611+ """
2612+ Total
2613+ """
2614+ def init_local_context(self):
2615+ self.fields = [
2616+ ('seg_num1', 2),
2617+ #header
2618+ ('date_value_hdr', 6),
2619+ ('partner_bank_clearing', 12),
2620+ ('zero5', 5),
2621+ ('creation_date', 6),
2622+ ('comp_bank_clearing', 7),
2623+ ('uid', 5),
2624+ ('sequence', 5),
2625+ ('genre_trans', 3),
2626+ ('type_paiement', 1),
2627+ ('flag', 1),
2628+ #total
2629+ ('amount_total', 16),
2630+ ('padding', 59)
2631+ ]
2632+ self.pre.update({'partner_bank_clearing': '', 'partner_cpt_benef': '',
2633+ 'company_bank_clearing': '', 'genre_trans': '890'})
2634
2635 def c_ljust(s, size):
2636- """
2637- check before calling ljust
2638- """
2639- s= s or ''
2640- if len(s) > size:
2641- s= s[:size]
2642- s = s.decode('utf-8').encode('latin1','replace').ljust(size)
2643- return s
2644+ """
2645+ check before calling ljust
2646+ """
2647+ s= s or ''
2648+ if len(s) > size:
2649+ s= s[:size]
2650+ s = s.decode('utf-8').encode('latin1','replace').ljust(size)
2651+ return s
2652
2653 def _create_dta(obj, cr, uid, data, context):
2654- v={}
2655- v['uid'] = str(uid)
2656- v['creation_date']= time.strftime('%y%m%d')
2657- dta=''
2658-
2659- pool = pooler.get_pool(cr.dbname)
2660- payment_obj = pool.get('payment.order')
2661- attachment_obj = pool.get('ir.attachment')
2662-
2663- payment = payment_obj.browse(cr, uid, data['id'], context=context)
2664-
2665- if not payment.mode or payment.mode.type.code != 'dta':
2666- raise wizard.except_wizard(_('Error'),
2667- _('No payment mode or payment type code invalid.'))
2668- bank = payment.mode.bank_id
2669- if not bank:
2670- raise wizard.except_wizard(_('Error'), _('No bank account for the company.'))
2671-
2672- v['comp_bank_name']= bank.bank and bank.bank.name or False
2673- v['comp_bank_clearing'] = bank.bank.clearing
2674-
2675- if not v['comp_bank_clearing']:
2676- raise wizard.except_wizard(_('Error'),
2677- _('You must provide a Clearing Number for your bank account.'))
2678-
2679- user = pool.get('res.users').browse(cr,uid,[uid])[0]
2680- company= user.company_id
2681- #XXX dirty code use get_addr
2682- co_addr= company.partner_id.address[0]
2683- v['comp_country'] = co_addr.country_id and co_addr.country_id.name or ''
2684- v['comp_street'] = co_addr.street or ''
2685- v['comp_zip'] = co_addr.zip
2686- v['comp_city'] = co_addr.city
2687- v['comp_name'] = co_addr.name
2688- v['comp_dta'] = bank.dta_code or '' #XXX not mandatory in pratice
2689-
2690-
2691- v['comp_bank_number'] = bank.acc_number or ''
2692- if bank.iban:
2693- v['comp_bank_iban'] = bank.iban.replace(' ','') or ''
2694- else:
2695- v['comp_bank_iban'] = ''
2696- if not v['comp_bank_iban']:
2697- raise wizard.except_wizard(_('Error'),
2698- _('No IBAN for the company bank account.'))
2699-
2700- dta_line_obj = pool.get('account.dta.line')
2701- res_partner_bank_obj = pool.get('res.partner.bank')
2702-
2703- seq= 1
2704- amount_tot = 0
2705- amount_currency_tot = 0
2706-
2707- for pline in payment.line_ids:
2708- if not pline.bank_id:
2709- raise wizard.except_wizard(_('Error'), _('No bank account defined\n' \
2710- 'on line: %s') % pline.name)
2711- if not pline.bank_id.bank:
2712- raise wizard.except_wizard(_('Error'), _('No bank defined\n' \
2713- 'for the bank account: %s\n' \
2714- 'on the partner: %s\n' \
2715- 'on line: %s') + (pline.bank_id.state, pline.partner_id.name, pline.name))
2716-
2717- v['sequence'] = str(seq).rjust(5).replace(' ', '0')
2718- v['amount_to_pay']= str(pline.amount_currency).replace('.', ',')
2719- v['number'] = pline.name
2720- v['currency'] = pline.currency.code
2721-
2722- v['partner_bank_name'] = pline.bank_id.bank.name or False
2723- v['partner_bank_clearing'] = pline.bank_id.bank.clearing or False
2724- if not v['partner_bank_name'] :
2725- raise wizard.except_wizard(_('Error'), _('No bank name defined\n' \
2726- 'for the bank account: %s\n' \
2727- 'on the partner: %s\n' \
2728- 'on line: %s') % (pline.bank_id.state, pline.partner_id.name, pline.name))
2729-
2730- v['partner_bank_iban']= pline.bank_id.iban or False
2731- v['partner_bank_number']= pline.bank_id.acc_number \
2732- and pline.bank_id.acc_number.replace('.','').replace('-','') \
2733- or False
2734- v['partner_post_number']= pline.bank_id.post_number \
2735- and pline.bank_id.post_number.replace('.', '').replace('-', '') \
2736- or False
2737- v['partner_bvr'] = pline.bank_id.bvr_number or ''
2738- if v['partner_bvr']:
2739- v['partner_bvr'] = v['partner_bvr'].replace('-','')
2740- if len(v['partner_bvr']) < 9:
2741- v['partner_bvr'] = v['partner_bvr'][:2] + '0' * \
2742- (9 - len(v['partner_bvr'])) + v['partner_bvr'][2:]
2743-
2744- if pline.bank_id.bank:
2745- v['partner_bank_city'] = pline.bank_id.bank.city or False
2746- v['partner_bank_street'] = pline.bank_id.bank.street or ''
2747- v['partner_bank_zip'] = pline.bank_id.bank.zip or ''
2748- v['partner_bank_country'] = pline.bank_id.bank.country and \
2749- pline.bank_id.bank.country.name or ''
2750-
2751- v['partner_bank_code'] = pline.bank_id.bank.bic
2752- v['reference'] = pline.move_line_id.ref
2753- v['partner_name'] = pline.partner_id and pline.partner_id.name or ''
2754- if pline.partner_id and pline.partner_id.address \
2755- and pline.partner_id.address[0]:
2756- v['partner_street'] = pline.partner_id.address[0].street
2757- v['partner_city']= pline.partner_id.address[0].city
2758- v['partner_zip']= pline.partner_id.address[0].zip
2759- # If iban => country=country code for space reason
2760- elec_pay = pline.bank_id.state #Bank type
2761- if elec_pay == 'iban':
2762- v['partner_country']= pline.partner_id.address[0].country_id \
2763- and pline.partner_id.address[0].country_id.code+'-' \
2764- or ''
2765- else:
2766- v['partner_country']= pline.partner_id.address[0].country_id \
2767- and pline.partner_id.address[0].country_id.name \
2768- or ''
2769- else:
2770- v['partner_street'] =''
2771- v['partner_city']= ''
2772- v['partner_zip']= ''
2773- v['partner_country']= ''
2774- raise wizard.except_wizard(_('Error'), _('No address defined \n' \
2775- 'for the partner: %s\n' \
2776- 'on line: %s') % (pline.partner_id.name, pline.name))
2777-
2778- if pline.order_id.date_planned :
2779- date_value = mx.DateTime.strptime(pline.order_id.date_planned, '%Y-%m-%d')
2780- elif pline.date :
2781- date_value = mx.DateTime.strptime(pline.date, '%Y-%m-%d')
2782- else :
2783- date_value = mx.DateTime.now()
2784- v['date_value'] = date_value.strftime("%y%m%d")
2785-
2786- # si compte iban -> iban (836)
2787- # si payment structure -> bvr (826)
2788- # si non -> (827)
2789-
2790- if elec_pay == 'dta_iban':
2791- # If iban => country=country code for space reason
2792- v['comp_country'] = co_addr.country_id and co_addr.country_id.code+'-' or ''
2793- record_type = record_gt836
2794- if not v['partner_bank_iban']:
2795- raise wizard.except_wizard(_('Error'), _('No IBAN defined \n' \
2796- 'for the bank account: %s\n' + \
2797- 'on line: %s') % (res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id], context)[0][1] , pline.name))
2798-
2799- if v['partner_bank_code'] : # bank code is swift (BIC address)
2800- v['option_id_bank']= 'A'
2801- v['partner_bank_ident']= v['partner_bank_code']
2802- elif v['partner_bank_city']:
2803-
2804- v['option_id_bank']= 'D'
2805- v['partner_bank_ident']= v['partner_bank_name'] \
2806- + ' ' + v['partner_bank_street'] \
2807- + ' ' + v['partner_bank_zip'] \
2808- + ' ' + v['partner_bank_city'] \
2809- + ' ' + v['partner_bank_country']
2810- else:
2811- raise wizard.except_wizard(_('Error'), _('You must provide the bank city '
2812- 'or the bic code for the partner bank: \n %d\n' + \
2813- 'on line: %s') %(res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id], context)[0][1], pline.name))
2814-
2815- elif elec_pay == 'bvrbank' or elec_pay == 'bvrpost':
2816- from tools import mod10r
2817- if v['reference']:
2818- v['reference'] = v['reference'].replace(' ',
2819- '').rjust(27).replace(' ', '0')
2820- if not v['reference'] \
2821- or mod10r(v['reference'][:-1]) != v['reference']:
2822- raise wizard.except_wizard(_('Error'), _('You must provide ' \
2823- 'a valid BVR reference number \n' \
2824- 'for the line: %s') % pline.name)
2825- if not v['partner_bvr']:
2826- raise wizard.except_wizard(_('Error'), _('You must provide a BVR number\n'
2827- 'for the bank account: %s' \
2828- 'on line: %s') % (res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id],context)[0][1] ,pline.name))
2829- record_type = record_gt826
2830-
2831- elif elec_pay == 'bvbank':
2832- if not v['partner_bank_number'] :
2833- if v['partner_bank_iban'] :
2834- v['partner_bank_number']= v['partner_bank_iban']
2835- else:
2836- raise wizard.except_wizard(_('Error'), _('You must provide ' \
2837- 'a bank number \n' \
2838- 'for the partner bank: %s\n' \
2839- 'on line: %s') % (res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id], context)[0][1] , pline.name))
2840- if not v['partner_bank_clearing']:
2841- raise wizard.except_wizard(_('Error'), _('You must provide ' \
2842- 'a Clearing Number\n' \
2843- 'for the partner bank: %s\n' \
2844- 'on line %s') % (res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id], context)[0][1] , pline.name))
2845- v['partner_bank_number'] = '/C/'+v['partner_bank_number']
2846- record_type = record_gt827
2847- elif elec_pay == 'bvpost':
2848- if not v['partner_post_number']:
2849- raise wizard.except_wizard(_('Error'), _('You must provide ' \
2850- 'a post number \n' \
2851- 'for the partner bank: %s\n' \
2852- 'on line: %s') % (res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id], context)[0][1] ,pline.name))
2853- v['partner_bank_clearing']= ''
2854- v['partner_bank_number'] = '/C/'+v['partner_post_number']
2855- record_type = record_gt827
2856- else:
2857- raise wizard.except_wizard(_('Error'), _('The Bank type %s of the bank account: %s is not supported') \
2858+ v={}
2859+ v['uid'] = str(uid)
2860+ v['creation_date']= time.strftime('%y%m%d')
2861+ dta=''
2862+
2863+ pool = pooler.get_pool(cr.dbname)
2864+ payment_obj = pool.get('payment.order')
2865+ attachment_obj = pool.get('ir.attachment')
2866+
2867+ payment = payment_obj.browse(cr, uid, data['id'], context=context)
2868+
2869+ if not payment.mode or payment.mode.type.code != 'dta':
2870+ raise wizard.except_wizard(_('Error'),
2871+ _('No payment mode or payment type code invalid.'))
2872+ bank = payment.mode.bank_id
2873+ if not bank:
2874+ raise wizard.except_wizard(_('Error'), _('No bank account for the company.'))
2875+
2876+ v['comp_bank_name']= bank.bank and bank.bank.name or False
2877+ v['comp_bank_clearing'] = bank.bank.clearing
2878+
2879+ if not v['comp_bank_clearing']:
2880+ raise wizard.except_wizard(_('Error'),
2881+ _('You must provide a Clearing Number for your bank account.'))
2882+
2883+ user = pool.get('res.users').browse(cr,uid,[uid])[0]
2884+ company= user.company_id
2885+ #XXX dirty code use get_addr
2886+ co_addr= company.partner_id.address[0]
2887+ v['comp_country'] = co_addr.country_id and co_addr.country_id.name or ''
2888+ v['comp_street'] = co_addr.street or ''
2889+ v['comp_zip'] = co_addr.zip
2890+ v['comp_city'] = co_addr.city
2891+ v['comp_name'] = co_addr.name
2892+ v['comp_dta'] = bank.dta_code or '' #XXX not mandatory in pratice
2893+
2894+
2895+ v['comp_bank_number'] = bank.acc_number or ''
2896+ if bank.iban:
2897+ v['comp_bank_iban'] = bank.iban.replace(' ','') or ''
2898+ else:
2899+ v['comp_bank_iban'] = ''
2900+ if not v['comp_bank_iban']:
2901+ raise wizard.except_wizard(_('Error'),
2902+ _('No IBAN for the company bank account.'))
2903+
2904+ dta_line_obj = pool.get('account.dta.line')
2905+ res_partner_bank_obj = pool.get('res.partner.bank')
2906+
2907+ seq= 1
2908+ amount_tot = 0
2909+ amount_currency_tot = 0
2910+
2911+ for pline in payment.line_ids:
2912+ if not pline.bank_id:
2913+ raise wizard.except_wizard(_('Error'), _('No bank account defined\n' \
2914+ 'on line: %s') % pline.name)
2915+ if not pline.bank_id.bank:
2916+ raise wizard.except_wizard(_('Error'), _('No bank defined\n' \
2917+ 'for the bank account: %s\n' \
2918+ 'on the partner: %s\n' \
2919+ 'on line: %s') + (pline.bank_id.state, pline.partner_id.name, pline.name))
2920+
2921+ v['sequence'] = str(seq).rjust(5).replace(' ', '0')
2922+ v['amount_to_pay']= str(pline.amount_currency).replace('.', ',')
2923+ v['number'] = pline.name
2924+ v['currency'] = pline.currency.code
2925+
2926+ v['partner_bank_name'] = pline.bank_id.bank.name or False
2927+ v['partner_bank_clearing'] = pline.bank_id.bank.clearing or False
2928+ if not v['partner_bank_name'] :
2929+ raise wizard.except_wizard(_('Error'), _('No bank name defined\n' \
2930+ 'for the bank account: %s\n' \
2931+ 'on the partner: %s\n' \
2932+ 'on line: %s') % (pline.bank_id.state, pline.partner_id.name, pline.name))
2933+
2934+ v['partner_bank_iban']= pline.bank_id.iban or False
2935+ v['partner_bank_number']= pline.bank_id.acc_number \
2936+ and pline.bank_id.acc_number.replace('.','').replace('-','') \
2937+ or False
2938+ v['partner_post_number']= pline.bank_id.post_number \
2939+ and pline.bank_id.post_number.replace('.', '').replace('-', '') \
2940+ or False
2941+ v['partner_bvr'] = pline.bank_id.bvr_number or ''
2942+ if v['partner_bvr']:
2943+ v['partner_bvr'] = v['partner_bvr'].replace('-','')
2944+ if len(v['partner_bvr']) < 9:
2945+ v['partner_bvr'] = v['partner_bvr'][:2] + '0' * \
2946+ (9 - len(v['partner_bvr'])) + v['partner_bvr'][2:]
2947+
2948+ if pline.bank_id.bank:
2949+ v['partner_bank_city'] = pline.bank_id.bank.city or False
2950+ v['partner_bank_street'] = pline.bank_id.bank.street or ''
2951+ v['partner_bank_zip'] = pline.bank_id.bank.zip or ''
2952+ v['partner_bank_country'] = pline.bank_id.bank.country and \
2953+ pline.bank_id.bank.country.name or ''
2954+
2955+ v['partner_bank_code'] = pline.bank_id.bank.bic
2956+ v['reference'] = pline.move_line_id.ref
2957+ # Add support for owner of the account if exists..
2958+ if pline.bank_id.owner_name:
2959+ v['partner_name'] = pline.bank_id.owner_name
2960+ else:
2961+ v['partner_name'] = pline.partner_id and pline.partner_id.name or ''
2962+
2963+ if pline.partner_id and pline.partner_id.address \
2964+ and pline.partner_id.address[0]:
2965+ v['partner_street'] = pline.partner_id.address[0].street
2966+ v['partner_city']= pline.partner_id.address[0].city
2967+ v['partner_zip']= pline.partner_id.address[0].zip
2968+ # If iban => country=country code for space reason
2969+ elec_pay = pline.bank_id.state #Bank type
2970+ if elec_pay == 'iban':
2971+ v['partner_country']= pline.partner_id.address[0].country_id \
2972+ and pline.partner_id.address[0].country_id.code+'-' \
2973+ or ''
2974+ else:
2975+ v['partner_country']= pline.partner_id.address[0].country_id \
2976+ and pline.partner_id.address[0].country_id.name \
2977+ or ''
2978+ else:
2979+ v['partner_street'] =''
2980+ v['partner_city']= ''
2981+ v['partner_zip']= ''
2982+ v['partner_country']= ''
2983+ raise wizard.except_wizard('Error', 'No address defined \n' \
2984+ 'for the partner: ' + pline.partner_id.name + '\n' \
2985+ 'on line: ' + pline.name)
2986+
2987+ if pline.order_id.date_planned :
2988+ date_value = mx.DateTime.strptime(pline.order_id.date_planned, '%Y-%m-%d')
2989+ elif pline.date :
2990+ date_value = mx.DateTime.strptime(pline.date, '%Y-%m-%d')
2991+ else :
2992+ date_value = mx.DateTime.now()
2993+ v['date_value'] = date_value.strftime("%y%m%d")
2994+
2995+ # si compte iban -> iban (836)
2996+ # si payment structure -> bvr (826)
2997+ # si non -> (827)
2998+
2999+ if elec_pay == 'dta_iban':
3000+ # If iban => country=country code for space reason
3001+ v['comp_country'] = co_addr.country_id and co_addr.country_id.code+'-' or ''
3002+ record_type = record_gt836
3003+ if not v['partner_bank_iban']:
3004+ raise wizard.except_wizard(_('Error'), _('No IBAN defined \n' \
3005+ 'for the bank account: %s\n' + \
3006+ 'on line: %s') % (res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id], context)[0][1] , pline.name))
3007+
3008+ if v['partner_bank_code'] : # bank code is swift (BIC address)
3009+ v['option_id_bank']= 'A'
3010+ v['partner_bank_ident']= v['partner_bank_code']
3011+ elif v['partner_bank_city']:
3012+
3013+ v['option_id_bank']= 'D'
3014+ v['partner_bank_ident']= v['partner_bank_name'] \
3015+ + ' ' + v['partner_bank_street'] \
3016+ + ' ' + v['partner_bank_zip'] \
3017+ + ' ' + v['partner_bank_city'] \
3018+ + ' ' + v['partner_bank_country']
3019+ else:
3020+ raise wizard.except_wizard(_('Error'), _('You must provide the bank city '
3021+ 'or the bic code for the partner bank: \n %d\n' + \
3022+ 'on line: %s') %(res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id], context)[0][1], pline.name))
3023+
3024+ elif elec_pay == 'bvrbank' or elec_pay == 'bvrpost':
3025+ from tools import mod10r
3026+ if v['reference']:
3027+ v['reference'] = v['reference'].replace(' ',
3028+ '').rjust(27).replace(' ', '0')
3029+ if not v['reference'] \
3030+ or (mod10r(v['reference'][:-1]) != v['reference'] and \
3031+ not len(v['reference']) == 15):
3032+ raise wizard.except_wizard(_('Error'), _('You must provide ' \
3033+ 'a valid BVR reference number \n' \
3034+ 'for the line: %s') % pline.name)
3035+ if not v['partner_bvr']:
3036+ raise wizard.except_wizard(_('Error'), _('You must provide a BVR number\n'
3037+ 'for the bank account: %s' \
3038+ 'on line: %s') % (res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id],context)[0][1] ,pline.name))
3039+ record_type = record_gt826
3040+
3041+ elif elec_pay == 'bvbank':
3042+ if not v['partner_bank_number'] :
3043+ if v['partner_bank_iban'] :
3044+ v['partner_bank_number']= v['partner_bank_iban']
3045+ else:
3046+ raise wizard.except_wizard(_('Error'), _('You must provide ' \
3047+ 'a bank number \n' \
3048+ 'for the partner bank: %s\n' \
3049+ 'on line: %s') % (res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id], context)[0][1] , pline.name))
3050+ if not v['partner_bank_clearing']:
3051+ raise wizard.except_wizard(_('Error'), _('You must provide ' \
3052+ 'a Clearing Number\n' \
3053+ 'for the partner bank: %s\n' \
3054+ 'on line %s') % (res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id], context)[0][1] , pline.name))
3055+ v['partner_bank_number'] = '/C/'+v['partner_bank_number']
3056+ record_type = record_gt827
3057+ elif elec_pay == 'bvpost':
3058+ if not v['partner_post_number']:
3059+ raise wizard.except_wizard(_('Error'), _('You must provide ' \
3060+ 'a post number \n' \
3061+ 'for the partner bank: %s\n' \
3062+ 'on line: %s') % (res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id], context)[0][1] ,pline.name))
3063+ v['partner_bank_clearing']= ''
3064+ v['partner_bank_number'] = '/C/'+v['partner_post_number']
3065+ record_type = record_gt827
3066+ else:
3067+ raise wizard.except_wizard(_('Error'), _('The Bank type %s of the bank account: %s is not supported') \
3068 % (elec_pay, res_partner_bank_obj.name_get(cr, uid, [pline.bank_id.id], context)[0][1],))
3069
3070- dta_line = record_type(v).generate()
3071-
3072- dta = dta + dta_line
3073- amount_tot += pline.amount
3074- amount_currency_tot += pline.amount_currency
3075- seq += 1
3076-
3077- # segment total
3078- v['amount_total'] = str(amount_currency_tot).replace('.',',')
3079- v['sequence'] = str(seq).rjust(5).replace(' ','0')
3080- if dta :
3081- dta = dta + record_gt890(v).generate()
3082-
3083- dta_data= base64.encodestring(dta)
3084- payment_obj.set_done(cr, uid, data['id'], context)
3085- attachment_obj.create(cr, uid, {
3086- 'name': 'DTA',
3087- 'datas': dta_data,
3088- 'datas_fname': 'DTA.txt',
3089- 'res_model': 'payment.order',
3090- 'res_id': data['id'],
3091- }, context=context)
3092- return {'dta': dta_data}
3093+ dta_line = record_type(v).generate()
3094+
3095+ dta = dta + dta_line
3096+ amount_tot += pline.amount
3097+ amount_currency_tot += pline.amount_currency
3098+ seq += 1
3099+
3100+ # segment total
3101+ v['amount_total'] = str(amount_currency_tot).replace('.',',')
3102+ v['sequence'] = str(seq).rjust(5).replace(' ','0')
3103+ if dta :
3104+ dta = dta + record_gt890(v).generate()
3105+
3106+ dta_data= base64.encodestring(dta)
3107+ payment_obj.set_done(cr, uid, data['id'], context)
3108+ attachment_obj.create(cr, uid, {
3109+ 'name': 'DTA',
3110+ 'datas': dta_data,
3111+ 'datas_fname': 'DTA.txt',
3112+ 'res_model': 'payment.order',
3113+ 'res_id': data['id'],
3114+ }, context=context)
3115+ return {'dta': dta_data}
3116
3117
3118 class wizard_dta_create(wizard.interface):
3119- states = {
3120- 'init' : {
3121- 'actions' : [_create_dta],
3122- 'result' : {'type' : 'form',
3123- 'arch' : FORM,
3124- 'fields' : FIELDS,
3125- 'state' : [('end', 'OK', 'gtk-ok', True)]
3126- }
3127- },
3128- }
3129+ states = {
3130+ 'init' : {
3131+ 'actions' : [_create_dta],
3132+ 'result' : {'type' : 'form',
3133+ 'arch' : FORM,
3134+ 'fields' : FIELDS,
3135+ 'state' : [('end', 'OK', 'gtk-ok', True)]
3136+ }
3137+ },
3138+ }
3139
3140 wizard_dta_create('account.dta_create')
3141 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: