Merge lp:~jamesj/account-banking/us-canada-payments into lp:~credativ/account-banking/upgrade-6.0

Proposed by James Jesudason
Status: Needs review
Proposed branch: lp:~jamesj/account-banking/us-canada-payments
Merge into: lp:~credativ/account-banking/upgrade-6.0
Diff against target: 576 lines (+282/-60)
5 files modified
account_banking/account_banking_view.xml (+1/-1)
account_banking_uk_hsbc/data/banking_export_hsbc.xml (+8/-0)
account_banking_uk_hsbc/hsbc_mt940.py (+1/-1)
account_banking_uk_hsbc/wizard/export_hsbc.py (+68/-9)
account_banking_uk_hsbc/wizard/paymul.py (+204/-49)
To merge this branch: bzr merge lp:~jamesj/account-banking/us-canada-payments
Reviewer Review Type Date Requested Status
Dimitri John Ledkov (ex-credativ) (community) Approve
Review via email: mp+88822@code.launchpad.net

Commit message

Handle Priority Payments and allow payments to non-UK bank accounts.

Description of the change

Allows Priority Payments to non-UK bank accounts and includes validation of US and Canada accounts.
Catches more exceptions to display a user-friendly error message instead of the default exception screen.
Files generated by the module have been validated by HSBCNet and are currently undergoing final approval by HSBC.

To post a comment you must log in.
Revision history for this message
Stefan Rijnhart (Opener) (stefan-opener) wrote :

Hi James,

please excuse me for commenting on your own branches, but I think you are interested in merging with banking-addons or account-banking eventually. Therefore I have a comment on your change to account_banking/account_banking_view.xml:8

You signaled the issue of the 404 on the SWIFT online lookup in lp:914922. Your solution here is to disable the on_change method. I would prefer to keep the on-change method, but disable the online function until we have found a viable alternative and parametrized the online lookup like you suggested in the bug report. See the following branch:

https://code.launchpad.net/~banking-addons-team/banking-addons/lp914922

If you feel that you must disable the on-change method, you can simply replace the field again in the HSBC module.

Cheers,
Stefan.

Revision history for this message
James Jesudason (jamesj) wrote :

Hi Stefan,

I understand the approach that your suggesting, and that sounds
reasonable. I debated taking that approach and decided to opt for the
one that included the smallest code change for now, allowing
alternatives to be investigated.

If the SWIFT online lookup is to be replaced by another online lookup, I
think that should be optional (triggered by a parameter). The reason is
that some deployments of OpenERP will be on servers that do not allow
external server access. Also, the user experience is poor when the
online lookup is slow - the UI just locks, without informing the user.

I think it would be better to place call the lookup code when the user
saves the record (the SWIFT code will only be in the vals dictionary
when the code is entered or changed).

Thanks

James

On 17/01/12 09:12, Stefan Rijnhart (Therp) wrote:
> Hi James,
>
> please excuse me for commenting on your own branches, but I think you are interested in merging with banking-addons or account-banking eventually. Therefore I have a comment on your change to account_banking/account_banking_view.xml:8
>
> You signaled the issue of the 404 on the SWIFT online lookup in lp:914922. Your solution here is to disable the on_change method. I would prefer to keep the on-change method, but disable the online function until we have found a viable alternative and parametrized the online lookup like you suggested in the bug report. See the following branch:
>
> https://code.launchpad.net/~banking-addons-team/banking-addons/lp914922
>
> If you feel that you must disable the on-change method, you can simply replace the field again in the HSBC module.
>
> Cheers,
> Stefan.
>
>
>
>
>
>
>

94. By James Jesudason

Use the 'valuedate' for the transaction 'effective_date' instead of the 'bookingdate' as that is the date the money left/arrived.

Revision history for this message
Dimitri John Ledkov (ex-credativ) (dle-credativ) wrote :

Fully merged into lp:~credativ/banking-addons/trunk-wip

After stephan reviews that it will land in lp:banking-addons.

Regards,

Dmitrijs.

review: Approve
Revision history for this message
Dimitri John Ledkov (ex-credativ) (dle-credativ) wrote :

Fully merged into lp:banking-addons now.

Regards,

Dmitrijs.

Unmerged revisions

94. By James Jesudason

Use the 'valuedate' for the transaction 'effective_date' instead of the 'bookingdate' as that is the date the money left/arrived.

93. By James Jesudason

Use the SWIFT code as the default account code format

92. By James Jesudason

Remove online verification of the BIC/SWIFT code as the web page is no longer available

91. By James Jesudason

Ensure that the address is supplied for transactions. Strip invalid accented characters.

90. By James Jesudason

Remove spaces from the account numbers

89. By James Jesudason

Handle Priority Payments

88. By James Jesudason

Improve the error messages and raise a user-friendly error message

87. By James Jesudason

Check for an entered US/Canada account number, not for a specific number od digits (that can vary)

86. By James Jesudason

Allow multi-currency payments in a single payment file and include logging

85. By James Jesudason

Handle payments from and to US/Canada bank accounts

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'account_banking/account_banking_view.xml'
2--- account_banking/account_banking_view.xml 2011-07-21 11:30:59 +0000
3+++ account_banking/account_banking_view.xml 2012-01-31 17:53:28 +0000
4@@ -384,7 +384,7 @@
5 <field name="type">form</field>
6 <field name="arch" type="xml">
7 <field name="bic" position="replace">
8- <field name="bic" on_change="onchange_bic(bic, name)"/>
9+ <field name="bic" />
10 </field>
11 </field>
12 </record>
13
14=== modified file 'account_banking_uk_hsbc/data/banking_export_hsbc.xml'
15--- account_banking_uk_hsbc/data/banking_export_hsbc.xml 2011-10-25 11:51:12 +0000
16+++ account_banking_uk_hsbc/data/banking_export_hsbc.xml 2012-01-31 17:53:28 +0000
17@@ -17,5 +17,13 @@
18 <field name="ir_model_id"
19 ref="account_banking_uk_hsbc.model_banking_export_hsbc_wizard"/>
20 </record>
21+ <record model="payment.mode.type" id="export_priority_payment">
22+ <field name="name">Priority Payment</field>
23+ <field name="code">not used</field>
24+ <field name="suitable_bank_types"
25+ eval="[(6,0,[ref('base_iban.bank_iban'),ref('base.bank_normal'),])]" />
26+ <field name="ir_model_id"
27+ ref="account_banking_uk_hsbc.model_banking_export_hsbc_wizard"/>
28+ </record>
29 </data>
30 </openerp>
31
32=== modified file 'account_banking_uk_hsbc/hsbc_mt940.py'
33--- account_banking_uk_hsbc/hsbc_mt940.py 2011-11-10 14:19:20 +0000
34+++ account_banking_uk_hsbc/hsbc_mt940.py 2012-01-31 17:53:28 +0000
35@@ -38,7 +38,7 @@
36
37 mapping = {
38 'execution_date' : 'valuedate',
39- 'effective_date' : 'bookingdate',
40+ 'effective_date' : 'valuedate',
41 'local_currency' : 'currency',
42 'transfer_type' : 'bookingcode',
43 'reference' : 'custrefno',
44
45=== modified file 'account_banking_uk_hsbc/wizard/export_hsbc.py'
46--- account_banking_uk_hsbc/wizard/export_hsbc.py 2011-10-25 11:51:12 +0000
47+++ account_banking_uk_hsbc/wizard/export_hsbc.py 2012-01-31 17:53:28 +0000
48@@ -28,6 +28,7 @@
49 import paymul
50 import string
51 import random
52+import netsvc
53
54 def strpdate(arg, format='%Y-%m-%d'):
55 '''shortcut'''
56@@ -98,6 +99,8 @@
57 ),
58 }
59
60+ logger = netsvc.Logger()
61+
62 def create(self, cursor, uid, wizard_data, context=None):
63 '''
64 Retrieve a sane set of default values based on the payment orders
65@@ -139,8 +142,14 @@
66 def _create_account(self, oe_account):
67 currency = None # let the receiving bank select the currency from the batch
68 holder = oe_account.owner_name or oe_account.partner_id.name
69+ self.logger.notifyChannel('paymul', netsvc.LOG_INFO,'Create account %s' % (holder))
70+ self.logger.notifyChannel('paymul', netsvc.LOG_INFO,'-- %s' % (oe_account.country_id.code))
71+ self.logger.notifyChannel('paymul', netsvc.LOG_INFO,'-- %s' % (oe_account.acc_number))
72+ self.logger.notifyChannel('paymul', netsvc.LOG_INFO,'-- %s' % (oe_account.iban))
73+
74
75 if oe_account.iban:
76+ self.logger.notifyChannel('paymul', netsvc.LOG_INFO,'IBAN: %s' % (oe_account.iban))
77 paymul_account = paymul.IBANAccount(
78 iban=oe_account.iban,
79 bic=oe_account.bank.bic,
80@@ -151,6 +160,7 @@
81 'charges': paymul.CHARGES_EACH_OWN,
82 }
83 elif oe_account.country_id.code == 'GB':
84+ self.logger.notifyChannel('paymul', netsvc.LOG_INFO,'GB: %s %s' % (oe_account.country_id.code,oe_account.acc_number))
85 split = oe_account.acc_number.split(" ", 2)
86 if len(split) == 2:
87 sortcode, accountno = split
88@@ -167,11 +177,53 @@
89 transaction_kwargs = {
90 'charges': paymul.CHARGES_PAYEE,
91 }
92+ elif oe_account.country_id.code in ('US','CA'):
93+ self.logger.notifyChannel('paymul', netsvc.LOG_INFO,'US/CA: %s %s' % (oe_account.country_id.code,oe_account.acc_number))
94+ split = oe_account.acc_number.split(' ', 2)
95+ if len(split) == 2:
96+ sortcode, accountno = split
97+ else:
98+ raise osv.except_osv(
99+ _('Error'),
100+ "Invalid %s account number '%s'" % (oe_account.country_id.code,oe_account.acc_number))
101+ paymul_account = paymul.NorthAmericanAccount(
102+ number=accountno,
103+ sortcode=sortcode,
104+ holder=holder,
105+ currency=currency,
106+ swiftcode=oe_account.bank.bic,
107+ country=oe_account.country_id.code,
108+ #origin_country=origin_country
109+ )
110+ transaction_kwargs = {
111+ 'charges': paymul.CHARGES_PAYEE,
112+ }
113+ transaction_kwargs = {
114+ 'charges': paymul.CHARGES_PAYEE,
115+ }
116 else:
117- raise osv.except_osv(
118- _('Error'),
119- _('%s: only UK accounts and IBAN are supported') % (holder)
120+ self.logger.notifyChannel('paymul', netsvc.LOG_INFO,'SWIFT Account: %s' % (oe_account.country_id.code))
121+ split = oe_account.acc_number.split(' ', 2)
122+ if len(split) == 2:
123+ sortcode, accountno = split
124+ else:
125+ raise osv.except_osv(
126+ _('Error'),
127+ "Invalid %s account number '%s'" % (oe_account.country_id.code,oe_account.acc_number))
128+ paymul_account = paymul.SWIFTAccount(
129+ number=accountno,
130+ sortcode=sortcode,
131+ holder=holder,
132+ currency=currency,
133+ swiftcode=oe_account.bank.bic,
134+ country=oe_account.country_id.code,
135 )
136+ transaction_kwargs = {
137+ 'charges': paymul.CHARGES_PAYEE,
138+ }
139+ transaction_kwargs = {
140+ 'charges': paymul.CHARGES_PAYEE,
141+ }
142
143 return paymul_account, transaction_kwargs
144
145@@ -185,14 +237,19 @@
146 'number must be provided'
147 )
148 )
149-
150+
151+ self.logger.notifyChannel('paymul', netsvc.LOG_INFO, '====')
152 dest_account, transaction_kwargs = self._create_account(line.bank_id)
153
154 means = {'ACH or EZONE': paymul.MEANS_ACH_OR_EZONE,
155- 'Faster Payment': paymul.MEANS_FASTER_PAYMENT}.get(line.order_id.mode.type.name)
156+ 'Faster Payment': paymul.MEANS_FASTER_PAYMENT,
157+ 'Priority Payment': paymul.MEANS_PRIORITY_PAYMENT}.get(line.order_id.mode.type.name)
158 if means is None:
159 raise osv.except_osv('Error', "Invalid payment type mode for HSBC '%s'" % line.order_id.mode.type.name)
160
161+ if not line.info_partner:
162+ raise osv.except_osv('Error', "No default address for transaction '%s'" % line.name)
163+
164 try:
165 return paymul.Transaction(
166 amount=Decimal(str(line.amount_currency)),
167@@ -221,6 +278,7 @@
168
169
170 try:
171+ self.logger.notifyChannel('paymul', netsvc.LOG_INFO,'Source - %s (%s) %s' % (payment_orders[0].mode.bank_id.partner_id.name, payment_orders[0].mode.bank_id.acc_number, payment_orders[0].mode.bank_id.country_id.code))
172 src_account = self._create_account(
173 payment_orders[0].mode.bank_id,
174 )[0]
175@@ -237,11 +295,12 @@
176 "account number (not IBAN)" + str(type(src_account)))
177 )
178
179- transactions = []
180- for po in payment_orders:
181- transactions += [self._create_transaction(l) for l in po.line_ids]
182-
183 try:
184+ self.logger.notifyChannel('paymul', netsvc.LOG_INFO, 'Create transactions...')
185+ transactions = []
186+ for po in payment_orders:
187+ transactions += [self._create_transaction(l) for l in po.line_ids]
188+
189 batch = paymul.Batch(
190 exec_date=strpdate(wizard_data.execution_date_create),
191 reference=wizard_data.reference,
192
193=== modified file 'account_banking_uk_hsbc/wizard/paymul.py'
194--- account_banking_uk_hsbc/wizard/paymul.py 2011-10-25 11:51:12 +0000
195+++ account_banking_uk_hsbc/wizard/paymul.py 2012-01-31 17:53:28 +0000
196@@ -23,6 +23,10 @@
197 from decimal import Decimal
198 import datetime
199 import re
200+import unicodedata
201+
202+def strip_accents(string):
203+ return unicodedata.normalize('NFKD', unicode(string)).encode('ASCII', 'ignore')
204
205 def split_account_holder(holder):
206 holder_parts = holder.split("\n")
207@@ -40,13 +44,19 @@
208 def edifact_isalnum(s):
209 return bool(re.match(r'^[A-Za-z0-9 ]*$', s))
210
211-def edifact_digits(val, digits, mindigits=None):
212+def edifact_digits(val, digits=None, mindigits=None):
213+ if digits is None:
214+ digits = ''
215 if mindigits is None:
216 mindigits = digits
217
218 pattern = r'^[0-9]{' + str(mindigits) + ',' + str(digits) + r'}$'
219 return bool(re.match(pattern, str(val)))
220
221+def edifact_isalnum_size(val, digits):
222+ pattern = r'^[A-Za-z0-9 ]{' + str(digits) + ',' + str(digits) + r'}$'
223+ return bool(re.match(pattern, str(val)))
224+
225 class HasCurrency(object):
226 def _get_currency(self):
227 return self._currency
228@@ -73,14 +83,14 @@
229 segments = self.segments()
230
231 def format_segment(segment):
232- return '+'.join([':'.join([str(y) for y in x]) for x in segment]) + "'"
233+ return '+'.join([':'.join([str(strip_accents(y)) for y in x]) for x in segment]) + "'"
234
235 return "\n".join([format_segment(s) for s in segments])
236
237
238 def _fii_segment(self, party_qualifier):
239 holder = split_account_holder(self.holder)
240- account_identification = [self.number, holder[0]]
241+ account_identification = [self.number.replace(' ',''), holder[0]]
242 if holder[1] or self.currency:
243 account_identification.append(holder[1])
244 if self.currency:
245@@ -126,16 +136,16 @@
246 holder_parts = split_account_holder(holder)
247
248 if not len(holder_parts[0]) <= 35:
249- raise ValueError("Account holder must be <= 35 characters long")
250+ raise ValueError("Account holder must be <= 35 characters long: " + str(holder_parts[0]))
251
252 if not len(holder_parts[1]) <= 35:
253- raise ValueError("Second line of account holder must be <= 35 characters long")
254+ raise ValueError("Second line of account holder must be <= 35 characters long: " + str(holder_parts[1]))
255
256 if not edifact_isalnum(holder_parts[0]):
257- raise ValueError("Account holder must be alphanumeric")
258+ raise ValueError("Account holder must be alphanumeric: " + str(holder_parts[0]))
259
260 if not edifact_isalnum(holder_parts[1]):
261- raise ValueError("Second line of account holder must be alphanumeric")
262+ raise ValueError("Second line of account holder must be alphanumeric: " + str(holder_parts[1]))
263
264 self._holder = holder.upper()
265
266@@ -155,6 +165,113 @@
267 def fii_or_segment(self):
268 return _fii_segment(self, 'OR')
269
270+
271+class NorthAmericanAccount(UKAccount):
272+
273+ def _set_account_ident(self):
274+ if self.origin_country in ('US','CA'):
275+ # Use the routing number
276+ account_ident = ['', '', '', self.sortcode, 155, 114]
277+ else:
278+ # Using the BIC/Swift Code
279+ account_ident = [self.bic, 25, 5, '', '', '']
280+ return account_ident
281+
282+ def _set_sortcode(self, sortcode):
283+ if not edifact_digits(sortcode, 9):
284+ raise ValueError("Account routing number must be 9 digits long: " +
285+ str(sortcode))
286+
287+
288+ self._sortcode = sortcode
289+
290+ def _get_sortcode(self):
291+ return self._sortcode
292+
293+ sortcode = property(_get_sortcode, _set_sortcode)
294+
295+ def _set_bic(self, bic):
296+ if not edifact_isalnum_size(bic, 8) and not edifact_isalnum_size(bic, 11):
297+ raise ValueError("Account BIC/Swift code must be 8 or 11 characters long: " +
298+ str(bic))
299+ self._bic = bic
300+
301+ def _get_bic(self):
302+ return self._bic
303+
304+ bic = property(_get_bic, _set_bic)
305+
306+ def _set_number(self, number):
307+ if not edifact_digits(number, mindigits=1):
308+ raise ValueError("Account number is invalid: " +
309+ str(number))
310+
311+ self._number = number
312+
313+ def _get_number(self):
314+ return self._number
315+
316+ number = property(_get_number, _set_number)
317+
318+ def __init__(self, number, holder, currency, sortcode, swiftcode, country, origin_country=None):
319+ self.number = number
320+ self.holder = holder
321+ self.currency = currency
322+ self.sortcode = sortcode
323+ self.country = country
324+ self.bic = swiftcode
325+ self.origin_country = origin_country
326+ self.institution_identification = self._set_account_ident()
327+
328+
329+class SWIFTAccount(UKAccount):
330+
331+ def _set_account_ident(self):
332+ # Using the BIC/Swift Code
333+ return [self.bic, 25, 5, '', '', '']
334+
335+ def _set_sortcode(self, sortcode):
336+ self._sortcode = sortcode
337+
338+ def _get_sortcode(self):
339+ return self._sortcode
340+
341+ sortcode = property(_get_sortcode, _set_sortcode)
342+
343+ def _set_bic(self, bic):
344+ if not edifact_isalnum_size(bic, 8) and not edifact_isalnum_size(bic, 11):
345+ raise ValueError("Account BIC/Swift code must be 8 or 11 characters long: " +
346+ str(bic))
347+ self._bic = bic
348+
349+ def _get_bic(self):
350+ return self._bic
351+
352+ bic = property(_get_bic, _set_bic)
353+
354+ def _set_number(self, number):
355+ if not edifact_digits(number, mindigits=1):
356+ raise ValueError("Account number is invalid: " +
357+ str(number))
358+
359+ self._number = number
360+
361+ def _get_number(self):
362+ return self._number
363+
364+ number = property(_get_number, _set_number)
365+
366+ def __init__(self, number, holder, currency, sortcode, swiftcode, country, origin_country=None):
367+ self.number = number
368+ self.holder = holder
369+ self.currency = currency
370+ self.sortcode = sortcode
371+ self.country = country
372+ self.bic = swiftcode
373+ self.origin_country = origin_country
374+ self.institution_identification = self._set_account_ident()
375+
376+
377 class IBANAccount(HasCurrency):
378 def _get_iban(self):
379 return self._iban
380@@ -162,7 +279,7 @@
381 def _set_iban(self, iban):
382 iban_obj = sepa.IBAN(iban)
383 if not iban_obj.valid:
384- raise ValueError("IBAN is invalid")
385+ raise ValueError("IBAN is invalid: " + str(iban))
386
387 self._iban = iban
388 self.country = iban_obj.countrycode
389@@ -186,10 +303,10 @@
390
391 def _set_reference(self, reference):
392 if not len(reference) <= 15:
393- raise ValueError("Reference must be <= 15 characters long")
394+ raise ValueError("Reference must be <= 15 characters long: " + str(reference))
395
396 if not edifact_isalnum(reference):
397- raise ValueError("Reference must be alphanumeric")
398+ raise ValueError("Reference must be alphanumeric: " + str(reference))
399
400 self._reference = reference.upper()
401
402@@ -226,10 +343,10 @@
403
404 def _set_reference(self, reference):
405 if not len(reference) <= 35:
406- raise ValueError("Reference must be <= 35 characters long")
407+ raise ValueError("Reference must be <= 35 characters long: " + str(reference))
408
409 if not edifact_isalnum(reference):
410- raise ValueError("Reference must be alphanumeric")
411+ raise ValueError("Reference must be alphanumeric: " + str(reference))
412
413 self._reference = reference.upper()
414
415@@ -285,10 +402,10 @@
416
417 def _set_reference(self, reference):
418 if not len(reference) <= 18:
419- raise ValueError("Reference must be <= 18 characters long")
420+ raise ValueError("Reference must be <= 18 characters long: " + str(reference))
421
422 if not edifact_isalnum(reference):
423- raise ValueError("Reference must be alphanumeric")
424+ raise ValueError("Reference must be alphanumeric: " + str(reference))
425
426 self._reference = reference.upper()
427
428@@ -306,41 +423,78 @@
429
430 def segments(self, index):
431 if not edifact_digits(index, 6, 1):
432- raise ValueError("Index must be 6 digits or less")
433+ raise ValueError("Index must be 6 digits or less: " + str(index))
434+
435+ # Store the payment means
436+ means = None
437+ if len(self.transactions)>0:
438+ means = self.transactions[0].means
439
440 segments = []
441
442- segments.append([
443- ['LIN'],
444- [index],
445- ])
446- segments.append([
447- ['DTM'],
448- [203, self.exec_date.strftime('%Y%m%d'), 102],
449- ])
450- segments.append([
451- ['RFF'],
452- ['AEK', self.reference],
453- ])
454-
455- currencies = set([x.currency for x in self.transactions])
456- if len(currencies) > 1:
457- raise ValueError("All transactions in a batch must have the same currency")
458-
459- segments.append([
460- ['MOA'],
461- [9, self.amount().quantize(Decimal('0.00')), currencies.pop()],
462- ])
463- segments.append(self.debit_account.fii_or_segment())
464- segments.append([
465- ['NAD'],
466- ['OY'],
467- [''],
468- self.name_address.upper().split("\n")[0:5],
469- ])
470+ if means != MEANS_PRIORITY_PAYMENT:
471+ segments.append([
472+ ['LIN'],
473+ [index],
474+ ])
475+ segments.append([
476+ ['DTM'],
477+ [203, self.exec_date.strftime('%Y%m%d'), 102],
478+ ])
479+ segments.append([
480+ ['RFF'],
481+ ['AEK', self.reference],
482+ ])
483+
484+ currencies = set([x.currency for x in self.transactions])
485+ if len(currencies) > 1:
486+ raise ValueError("All transactions in a batch must have the same currency")
487+
488+ segments.append([
489+ ['MOA'],
490+ [9, self.amount().quantize(Decimal('0.00')), currencies.pop()],
491+ ])
492+ segments.append(self.debit_account.fii_or_segment())
493+ segments.append([
494+ ['NAD'],
495+ ['OY'],
496+ [''],
497+ self.name_address.upper().split("\n")[0:5],
498+ ])
499
500 for index, transaction in enumerate(self.transactions):
501- segments += transaction.segments(index + 1)
502+ if transaction.means == MEANS_PRIORITY_PAYMENT:
503+ # Need a debit-credit format for Priority Payments
504+ segments.append([
505+ ['LIN'],
506+ [index+1],
507+ ])
508+ segments.append([
509+ ['DTM'],
510+ [203, self.exec_date.strftime('%Y%m%d'), 102],
511+ ])
512+ segments.append([
513+ ['RFF'],
514+ ['AEK', self.reference],
515+ ])
516+
517+ # Use the transaction amount and currency for the debit line
518+ segments.append([
519+ ['MOA'],
520+ [9, transaction.amount.quantize(Decimal('0.00')), transaction.currency],
521+ ])
522+ segments.append(self.debit_account.fii_or_segment())
523+ segments.append([
524+ ['NAD'],
525+ ['OY'],
526+ [''],
527+ self.name_address.upper().split("\n")[0:5],
528+ ])
529+ use_index = 1
530+ else:
531+ use_index = index + 1
532+
533+ segments += transaction.segments(use_index)
534
535 return segments
536
537@@ -367,7 +521,7 @@
538
539 def _set_amount(self, amount):
540 if len(str(amount)) > 18:
541- raise ValueError("Amount must be shorter than 18 bytes")
542+ raise ValueError("Amount must be shorter than 18 bytes: " + str(amount))
543
544 self._amount = amount
545
546@@ -378,10 +532,10 @@
547
548 def _set_payment_reference(self, payment_reference):
549 if not len(payment_reference) <= 18:
550- raise ValueError("Payment reference must be <= 18 characters long")
551+ raise ValueError("Payment reference must be <= 18 characters long: " + str(payment_reference))
552
553 if not edifact_isalnum(payment_reference):
554- raise ValueError("Payment reference must be alphanumeric")
555+ raise ValueError("Payment reference must be alphanumeric: " + str(payment_reference))
556
557 self._payment_reference = payment_reference.upper()
558
559@@ -392,10 +546,10 @@
560
561 def _set_customer_reference(self, customer_reference):
562 if not len(customer_reference) <= 18:
563- raise ValueError("Customer reference must be <= 18 characters long")
564+ raise ValueError("Customer reference must be <= 18 characters long: " + str(customer_reference))
565
566 if not edifact_isalnum(customer_reference):
567- raise ValueError("Customer reference must be alphanumeric")
568+ raise ValueError("Customer reference must be alphanumeric: " + str(customer_reference))
569
570 self._customer_reference = customer_reference.upper()
571
572@@ -472,3 +626,4 @@
573 segments.append(nad_segment)
574
575 return segments
576+

Subscribers

People subscribed via source and target branches