Merge lp:~therp-nl/banking-addons/ba70-deprecate_iban_lookup into lp:banking-addons

Proposed by Stefan Rijnhart (Opener)
Status: Merged
Approved by: Yannick Vaucher @ Camptocamp
Approved revision: 234
Merged at revision: 234
Proposed branch: lp:~therp-nl/banking-addons/ba70-deprecate_iban_lookup
Merge into: lp:banking-addons
Diff against target: 1285 lines (+593/-470)
20 files modified
account_banking/__init__.py (+2/-0)
account_banking/__openerp__.py (+0/-6)
account_banking/account_banking.py (+1/-409)
account_banking/account_banking_view.xml (+0/-29)
account_banking/res_bank.py (+31/-0)
account_banking/res_partner_bank.py (+101/-0)
account_banking/sepa/__init__.py (+0/-1)
account_banking/wizard/banktools.py (+4/-14)
account_banking_iban_lookup/__init__.py (+3/-0)
account_banking_iban_lookup/__openerp__.py (+52/-0)
account_banking_iban_lookup/model/__init__.py (+2/-0)
account_banking_iban_lookup/model/res_bank.py (+63/-0)
account_banking_iban_lookup/model/res_partner_bank.py (+271/-0)
account_banking_iban_lookup/online.py (+2/-2)
account_banking_iban_lookup/urlagent.py (+0/-1)
account_banking_iban_lookup/view/res_bank.xml (+15/-0)
account_banking_iban_lookup/view/res_partner_bank.xml (+23/-0)
account_banking_nl_clieop/__openerp__.py (+4/-1)
account_banking_nl_multibank/__openerp__.py (+1/-1)
account_banking_payment/model/banking_import_transaction.py (+18/-6)
To merge this branch: bzr merge lp:~therp-nl/banking-addons/ba70-deprecate_iban_lookup
Reviewer Review Type Date Requested Status
Yannick Vaucher @ Camptocamp Approve
Raphaël Valyi - http://www.akretion.com Approve
Guewen Baconnier @ Camptocamp Approve
Holger Brunn (Therp) code review Approve
Review via email: mp+202520@code.launchpad.net

Description of the change

Splitting off the online account number (i.e. IBAN) lookup functionality into a separate module, and labelling this as deprecated. This was only ever functional for NL and maybe BE. The long diff mainly represents moving a single block of code around. Notable exception is a modification to the existing search extension on res.partner.bank which makes sure that spaces in IBANs are now ignored when searching for equivalence.

To post a comment you must log in.
Revision history for this message
Holger Brunn (Therp) (hbrunn) :
review: Approve (code review)
Revision history for this message
Guewen Baconnier @ Camptocamp (gbaconnier-c2c) :
review: Approve
Revision history for this message
Raphaël Valyi - http://www.akretion.com (rvalyi) wrote :

Thanks! this is terrific and will make account_banking easier to use here in Brazil!

review: Approve
Revision history for this message
Yannick Vaucher @ Camptocamp (yvaucher-c2c) wrote :

You should remove unused import from account_banking.

account_banking/account_banking.py|68 col 1| F401 'SUPERUSER_ID' imported but unused
account_banking/account_banking.py|70 col 1| F401 'sepa' imported but unused
account_banking/account_banking.py|71 col 1| F401 'get_or_create_bank' imported but unused

Plus I had a conflict on account_banking.py on removals of res_partner_bank and res_bank classes. Can you check that and if needed merge main branch in here to solve it.

review: Needs Fixing (code review)
228. By Stefan Rijnhart (Opener)

[FIX] Remove unused imports

229. By Stefan Rijnhart (Opener)

[MRG] lp:banking-addons/7.0, revno 225

230. By Stefan Rijnhart (Opener)

[MRG] Conflicting revision 226 of lp:banking-addons/7.0

231. By Stefan Rijnhart (Opener)

[RFR] Flake8

232. By Stefan Rijnhart (Opener)

[FIX] Flake8

233. By Stefan Rijnhart (Opener)

[RFR] Flake8

234. By Stefan Rijnhart (Opener)

[MRG] lp:banking-addons, revno 233

Revision history for this message
Stefan Rijnhart (Opener) (stefan-opener) wrote :

Hi Yannick, thanks for the review! I removed the unused imports and carefully resolved the conflicts in revno. 226 by manually adapting the changes in code that was moved to other files.

Revision history for this message
Yannick Vaucher @ Camptocamp (yvaucher-c2c) wrote :

Thanks for your changes

I'll proceed with the merge

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'account_banking/__init__.py'
2--- account_banking/__init__.py 2013-11-17 19:45:48 +0000
3+++ account_banking/__init__.py 2014-03-15 16:07:41 +0000
4@@ -31,5 +31,7 @@
5 import parsers
6 import wizard
7 import res_partner
8+import res_bank
9+import res_partner_bank
10
11 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
12
13=== modified file 'account_banking/__openerp__.py'
14--- account_banking/__openerp__.py 2013-12-10 07:06:28 +0000
15+++ account_banking/__openerp__.py 2014-03-15 16:07:41 +0000
16@@ -33,7 +33,6 @@
17 'category': 'Banking addons',
18 'depends': [
19 'account_voucher',
20- 'account_iban_preserve_domestic',
21 ],
22 'data': [
23 'security/ir.model.access.csv',
24@@ -47,14 +46,9 @@
25 'js': [
26 'static/src/js/account_banking.js',
27 ],
28- 'external_dependencies': {
29- 'python' : ['BeautifulSoup'],
30- },
31 'description': '''
32 Module to do banking.
33
34- Note: This module is depending on BeautifulSoup.
35-
36 This modules tries to combine all current banking import and export
37 schemes. Rationale for this is that it is quite common to have foreign
38 bank account numbers next to national bank account numbers. The current
39
40=== modified file 'account_banking/account_banking.py'
41--- account_banking/account_banking.py 2014-02-10 20:21:08 +0000
42+++ account_banking/account_banking.py 2014-03-15 16:07:41 +0000
43@@ -65,14 +65,8 @@
44 from openerp.osv import orm, fields
45 from openerp.osv.osv import except_osv
46 from openerp.tools.translate import _
47-from openerp import netsvc, SUPERUSER_ID
48+from openerp import netsvc
49 from openerp.addons.decimal_precision import decimal_precision as dp
50-from openerp.addons.account_banking import sepa
51-from openerp.addons.account_banking.wizard.banktools import get_or_create_bank
52-
53-def warning(title, message):
54- '''Convenience routine'''
55- return {'warning': {'title': title, 'message': message}}
56
57
58 class account_banking_account_settings(orm.Model):
59@@ -559,408 +553,6 @@
60 'currency': _get_currency,
61 }
62
63-account_bank_statement_line()
64-
65-
66-class res_partner_bank(orm.Model):
67- '''
68- This is a hack to circumvent the very limited but widely used base_iban
69- dependency. The usage of __mro__ requires inside information of
70- inheritence. This code is tested and works - it bypasses base_iban
71- altogether. Be sure to use 'super' for inherited classes from here though.
72-
73- Extended functionality:
74- 1. BBAN and IBAN are considered equal
75- 2. Online databases are checked when available
76- 3. Banks are created on the fly when using IBAN
77- 4. Storage is uppercase, not lowercase
78- 5. Presentation is formal IBAN
79- 6. BBAN's are generated from IBAN when possible
80- 7. In the absence of online databanks, BBAN's are checked on format
81- using IBAN specs.
82- '''
83- _inherit = 'res.partner.bank'
84-
85- def __init__(self, *args, **kwargs):
86- '''
87- Locate founder (first non inherited class) in inheritance tree.
88- Defaults to super()
89- Algorithm should prevent moving unknown classes between
90- base.res_partner_bank and this module's res_partner_bank.
91- '''
92- self._founder = super(res_partner_bank, self)
93- self._founder.__init__(*args, **kwargs)
94- mro = self.__class__.__mro__
95- for i in range(len(mro)):
96- if mro[i].__module__.startswith('openerp.addons.base.'):
97- self._founder = mro[i]
98- break
99-
100- def init(self, cr):
101- '''
102- Update existing iban accounts to comply to new regime
103- '''
104-
105- partner_bank_obj = self.pool.get('res.partner.bank')
106- bank_ids = partner_bank_obj.search(
107- cr, SUPERUSER_ID, [('state', '=', 'iban')], limit=0)
108- for bank in partner_bank_obj.read(cr, SUPERUSER_ID, bank_ids):
109- write_vals = {}
110- if bank['state'] == 'iban':
111- iban_acc = sepa.IBAN(bank['acc_number'])
112- if iban_acc.valid:
113- write_vals['acc_number_domestic'] = iban_acc.localized_BBAN
114- write_vals['acc_number'] = str(iban_acc)
115- elif bank['acc_number'] != bank['acc_number'].upper():
116- write_vals['acc_number'] = bank['acc_number'].upper()
117- if write_vals:
118- partner_bank_obj.write(
119- cr, SUPERUSER_ID, bank['id'], write_vals)
120-
121- @staticmethod
122- def _correct_IBAN(acc_number):
123- '''
124- Routine to correct IBAN values and deduce localized values when valid.
125- Note: No check on validity IBAN/Country
126- '''
127- iban = sepa.IBAN(acc_number)
128- return (str(iban), iban.localized_BBAN)
129-
130- def create(self, cr, uid, vals, context=None):
131- '''
132- Create dual function IBAN account for SEPA countries
133- '''
134- if vals.get('state') == 'iban':
135- iban = (vals.get('acc_number')
136- or vals.get('acc_number_domestic', False))
137- vals['acc_number'], vals['acc_number_domestic'] = (
138- self._correct_IBAN(iban))
139- return self._founder.create(self, cr, uid, vals, context)
140-
141- def write(self, cr, uid, ids, vals, context=None):
142- '''
143- Create dual function IBAN account for SEPA countries
144-
145- Update the domestic account number when the IBAN is
146- written, or clear the domestic number on regular account numbers.
147- '''
148- if ids and isinstance(ids, (int, long)):
149- ids = [ids]
150- for account in self.read(
151- cr, uid, ids, ['state', 'acc_number']):
152- if 'state' in vals or 'acc_number' in vals:
153- account.update(vals)
154- if account['state'] == 'iban':
155- vals['acc_number'], vals['acc_number_domestic'] = (
156- self._correct_IBAN(account['acc_number']))
157- else:
158- vals['acc_number_domestic'] = False
159- self._founder.write(self, cr, uid, account['id'], vals, context)
160- return True
161-
162- def search(self, cr, uid, args, *rest, **kwargs):
163- '''
164- Overwrite search, as both acc_number and iban now can be filled, so
165- the original base_iban 'search and search again fuzzy' tactic now can
166- result in doubled findings. Also there is now enough info to search
167- for local accounts when a valid IBAN was supplied.
168-
169- Chosen strategy: create complex filter to find all results in just
170- one search
171- '''
172-
173- def is_term(arg):
174- '''Flag an arg as term or otherwise'''
175- return isinstance(arg, (list, tuple)) and len(arg) == 3
176-
177- def extended_filter_term(term):
178- '''
179- Extend the search criteria in term when appropriate.
180- '''
181- extra_term = None
182- if term[0].lower() == 'acc_number' and term[1] in ('=', '=='):
183- iban = sepa.IBAN(term[2])
184- if iban.valid:
185- bban = iban.localized_BBAN
186- # Prevent empty search filters
187- if bban:
188- extra_term = ('acc_number_domestic', term[1], bban)
189- if extra_term:
190- return ['|', term, extra_term]
191- return [term]
192-
193- def extended_search_expression(args):
194- '''
195- Extend the search expression in args when appropriate.
196- The expression itself is in reverse polish notation, so recursion
197- is not needed.
198- '''
199- if not args:
200- return []
201-
202- all = []
203- if is_term(args[0]) and len(args) > 1:
204- # Classic filter, implicit '&'
205- all += ['&']
206-
207- for arg in args:
208- if is_term(arg):
209- all += extended_filter_term(arg)
210- else:
211- all += arg
212- return all
213-
214- # Extend search filter
215- newargs = extended_search_expression(args)
216-
217- # Original search
218- results = super(res_partner_bank, self).search(
219- cr, uid, newargs, *rest, **kwargs)
220- return results
221-
222- def read(
223- self, cr, uid, ids, fields=None, context=None, load='_classic_read'):
224- '''
225- Convert IBAN electronic format to IBAN display format
226- SR 2012-02-19: do we really need this? Fields are converted upon write already.
227- '''
228- if fields and 'state' not in fields:
229- fields.append('state')
230- records = self._founder.read(self, cr, uid, ids, fields, context, load)
231- is_list = True
232- if not isinstance(records, list):
233- records = [records,]
234- is_list = False
235- for record in records:
236- if 'acc_number' in record and record['state'] == 'iban':
237- record['acc_number'] = unicode(sepa.IBAN(record['acc_number']))
238- if is_list:
239- return records
240- return records[0]
241-
242- def check_iban(self, cr, uid, ids, context=None):
243- '''
244- Check IBAN number
245- '''
246- for bank_acc in self.browse(cr, uid, ids, context=context):
247- if bank_acc.state == 'iban' and bank_acc.acc_number:
248- iban = sepa.IBAN(bank_acc.acc_number)
249- if not iban.valid:
250- return False
251- return True
252-
253- def get_bban_from_iban(self, cr, uid, ids, context=None):
254- '''
255- Return the local bank account number aka BBAN from the IBAN.
256- '''
257- res = {}
258- for record in self.browse(cr, uid, ids, context):
259- if not record.state == 'iban':
260- res[record.id] = False
261- else:
262- iban_acc = sepa.IBAN(record.acc_number)
263- res[record.id] = iban_acc.localized_BBAN
264- return res
265-
266- def onchange_acc_number(
267- self, cr, uid, ids, acc_number, acc_number_domestic,
268- state, partner_id, country_id, context=None):
269- if state == 'iban':
270- return self.onchange_iban(
271- cr, uid, ids, acc_number, acc_number_domestic,
272- state, partner_id, country_id, context=None
273- )
274- else:
275- return self.onchange_domestic(
276- cr, uid, ids, acc_number,
277- partner_id, country_id, context=None
278- )
279-
280- def onchange_domestic(
281- self, cr, uid, ids, acc_number,
282- partner_id, country_id, context=None):
283- '''
284- Trigger to find IBAN. When found:
285- 1. Reformat BBAN
286- 2. Autocomplete bank
287-
288- TODO: prevent unnecessary assignment of country_ids and
289- browsing of the country
290- '''
291- if not acc_number:
292- return {}
293-
294- values = {}
295- country_obj = self.pool.get('res.country')
296- country_ids = []
297- country = False
298-
299- # Pre fill country based on available data. This is just a default
300- # which can be overridden by the user.
301- # 1. Use provided country_id (manually filled)
302- if country_id:
303- country = country_obj.browse(cr, uid, country_id, context=context)
304- country_ids = [country_id]
305- # 2. Use country_id of found bank accounts
306- # This can be usefull when there is no country set in the partners
307- # addresses, but there was a country set in the address for the bank
308- # account itself before this method was triggered.
309- elif ids and len(ids) == 1:
310- partner_bank_obj = self.pool.get('res.partner.bank')
311- partner_bank_id = partner_bank_obj.browse(cr, uid, ids[0], context=context)
312- if partner_bank_id.country_id:
313- country = partner_bank_id.country_id
314- country_ids = [country.id]
315- # 3. Use country_id of default address of partner
316- # The country_id of a bank account is a one time default on creation.
317- # It originates in the same address we are about to check, but
318- # modifications on that address afterwards are not transfered to the
319- # bank account, hence the additional check.
320- elif partner_id:
321- partner_obj = self.pool.get('res.partner')
322- country = partner_obj.browse(cr, uid, partner_id, context=context).country
323- country_ids = country and [country.id] or []
324- # 4. Without any of the above, take the country from the company of
325- # the handling user
326- if not country_ids:
327- user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
328- # Try user companies partner (user no longer has address in 6.1)
329- if (user.company_id and
330- user.company_id.partner_id and
331- user.company_id.partner_id.country
332- ):
333- country_ids = [user.company_id.partner_id.country.id]
334- else:
335- if (user.company_id and user.company_id.partner_id and
336- user.company_id.partner_id.country):
337- country_ids = [user.company_id.partner_id.country.id]
338- else:
339- # Ok, tried everything, give up and leave it to the user
340- return warning(_('Insufficient data'),
341- _('Insufficient data to select online '
342- 'conversion database')
343- )
344- result = {'value': values}
345- # Complete data with online database when available
346- if country_ids:
347- country = country_obj.browse(
348- cr, uid, country_ids[0], context=context)
349- values['country_id'] = country_ids[0]
350- if country and country.code in sepa.IBAN.countries:
351- info = sepa.online.account_info(country.code, acc_number)
352- if info:
353- iban_acc = sepa.IBAN(info.iban)
354- if iban_acc.valid:
355- values['acc_number_domestic'] = iban_acc.localized_BBAN
356- values['acc_number'] = unicode(iban_acc)
357- values['state'] = 'iban'
358- bank_id, country_id = get_or_create_bank(
359- self.pool, cr, uid,
360- info.bic or iban_acc.BIC_searchkey,
361- name = info.bank
362- )
363- if country_id:
364- values['country_id'] = country_id
365- values['bank'] = bank_id or False
366- if info.bic:
367- values['bank_bic'] = info.bic
368- else:
369- info = None
370- if info is None:
371- result.update(warning(
372- _('Invalid data'),
373- _('The account number appears to be invalid for %s')
374- % country.name
375- ))
376- if info is False:
377- if country.code in sepa.IBAN.countries:
378- acc_number_fmt = sepa.BBAN(acc_number, country.code)
379- if acc_number_fmt.valid:
380- values['acc_number_domestic'] = str(acc_number_fmt)
381- else:
382- result.update(warning(
383- _('Invalid format'),
384- _('The account number has the wrong format '
385- 'for %(country)s')
386- % {'country': country.name}
387- ))
388- return result
389-
390- def onchange_iban(
391- self, cr, uid, ids, acc_number, acc_number_domestic,
392- state, partner_id, country_id, context=None):
393- '''
394- Trigger to verify IBAN. When valid:
395- 1. Extract BBAN as local account
396- 2. Auto complete bank
397- '''
398- if not acc_number:
399- return {}
400-
401- iban_acc = sepa.IBAN(acc_number)
402- if iban_acc.valid:
403- bank_id, country_id = get_or_create_bank(
404- self.pool, cr, uid, iban_acc.BIC_searchkey,
405- code=iban_acc.BIC_searchkey
406- )
407- return {
408- 'value': dict(
409- acc_number_domestic = iban_acc.localized_BBAN,
410- acc_number = unicode(iban_acc),
411- country = country_id or False,
412- bank = bank_id or False,
413- )
414- }
415- return warning(_('Invalid IBAN account number!'),
416- _("The IBAN number doesn't seem to be correct")
417- )
418-
419-res_partner_bank()
420-
421-
422-class res_bank(orm.Model):
423- '''
424- Add a on_change trigger to automagically fill bank details from the
425- online SWIFT database. Allow hand filled names to overrule SWIFT names.
426- '''
427- _inherit = 'res.bank'
428-
429- def onchange_bic(self, cr, uid, ids, bic, name, context=None):
430- '''
431- Trigger to auto complete other fields.
432- '''
433- if not bic:
434- return {}
435-
436- info, address = sepa.online.bank_info(bic)
437- if not info:
438- return {}
439-
440- if address and address.country_id:
441- country_id = self.pool.get('res.country').search(
442- cr, uid, [('code','=',address.country_id)]
443- )
444- country_id = country_id and country_id[0] or False
445- else:
446- country_id = False
447-
448- return {
449- 'value': dict(
450- # Only the first eight positions of BIC are used for bank
451- # transfers, so ditch the rest.
452- bic = info.bic[:8],
453- street = address.street,
454- street2 =
455- address.has_key('street2') and address.street2 or False,
456- zip = address.zip,
457- city = address.city,
458- country = country_id,
459- name = name and name or info.name,
460- )
461- }
462-
463-res_bank()
464-
465
466 class invoice(orm.Model):
467 '''
468
469=== modified file 'account_banking/account_banking_view.xml'
470--- account_banking/account_banking_view.xml 2014-03-03 11:21:17 +0000
471+++ account_banking/account_banking_view.xml 2014-03-15 16:07:41 +0000
472@@ -289,35 +289,6 @@
473 </field>
474 </record>
475
476- <record id="view_partner_bank_account_banking_form_2" model="ir.ui.view">
477- <field name="name">res.partner.bank.form.banking-2</field>
478- <field name="model">res.partner.bank</field>
479- <field name="inherit_id" ref="base.view_partner_bank_form"/>
480- <field name="priority" eval="24"/>
481- <field name="arch" type="xml">
482- <data>
483- <field name="acc_number" position="attributes">
484- <attribute name="on_change">onchange_acc_number(acc_number, acc_number_domestic, state, partner_id, country_id)</attribute>
485- </field>
486- <field name="acc_number_domestic" position="attributes">
487- <attribute name="on_change">onchange_domestic(acc_number_domestic, partner_id, country_id)</attribute>
488- </field>
489- </data>
490- </field>
491- </record>
492-
493- <!-- Set trigger on BIC in res_bank form -->
494- <record id="view_res_bank_account_banking_form_1" model="ir.ui.view">
495- <field name="name">res.bank.form.banking-1</field>
496- <field name="model">res.bank</field>
497- <field name="inherit_id" ref="base.view_res_bank_form"/>
498- <field name="arch" type="xml">
499- <field name="bic" position="replace">
500- <field name="bic" on_change="onchange_bic(bic, name)"/>
501- </field>
502- </field>
503- </record>
504-
505 <record model="ir.ui.view" id="view_bank_statement_line_tree">
506 <field name="name">Bank statement line tree view</field>
507 <field name="model">account.bank.statement.line</field>
508
509=== added file 'account_banking/res_bank.py'
510--- account_banking/res_bank.py 1970-01-01 00:00:00 +0000
511+++ account_banking/res_bank.py 2014-03-15 16:07:41 +0000
512@@ -0,0 +1,31 @@
513+# -*- coding: utf-8 -*-
514+##############################################################################
515+#
516+# Copyright 2011 - 2014 Therp BV (<http://therp.nl>).
517+#
518+# This program is free software: you can redistribute it and/or modify
519+# it under the terms of the GNU Affero General Public License as
520+# published by the Free Software Foundation, either version 3 of the
521+# License, or (at your option) any later version.
522+#
523+# This program is distributed in the hope that it will be useful,
524+# but WITHOUT ANY WARRANTY; without even the implied warranty of
525+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
526+# GNU Affero General Public License for more details.
527+#
528+# You should have received a copy of the GNU Affero General Public License
529+# along with this program. If not, see <http://www.gnu.org/licenses/>.
530+#
531+##############################################################################
532+from openerp.osv import orm
533+
534+
535+class ResBank(orm.Model):
536+ _inherit = 'res.bank'
537+
538+ def online_bank_info(self, cr, uid, bic, context=None):
539+ """
540+ API hook for legacy online lookup of BICs,
541+ to be removed in OpenERP 8.0.
542+ """
543+ return False, False
544
545=== added file 'account_banking/res_partner_bank.py'
546--- account_banking/res_partner_bank.py 1970-01-01 00:00:00 +0000
547+++ account_banking/res_partner_bank.py 2014-03-15 16:07:41 +0000
548@@ -0,0 +1,101 @@
549+# -*- coding: utf-8 -*-
550+##############################################################################
551+#
552+# Copyright (C) 2009 EduSense BV (<http://www.edusense.nl>).
553+# (C) 2011 - 2014 Therp BV (<http://therp.nl>).
554+#
555+# This program is free software: you can redistribute it and/or modify
556+# it under the terms of the GNU Affero General Public License as
557+# published by the Free Software Foundation, either version 3 of the
558+# License, or (at your option) any later version.
559+#
560+# This program is distributed in the hope that it will be useful,
561+# but WITHOUT ANY WARRANTY; without even the implied warranty of
562+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
563+# GNU Affero General Public License for more details.
564+#
565+# You should have received a copy of the GNU Affero General Public License
566+# along with this program. If not, see <http://www.gnu.org/licenses/>.
567+#
568+##############################################################################
569+from openerp.osv import orm
570+from openerp.addons.account_banking import sepa
571+
572+
573+class ResPartnerBank(orm.Model):
574+ _inherit = 'res.partner.bank'
575+
576+ def online_account_info(
577+ self, cr, uid, country_code, acc_number, context=None):
578+ """
579+ API hook for legacy online lookup of account info,
580+ to be removed in OpenERP 8.0.
581+ """
582+ return False
583+
584+ def search(self, cr, uid, args, *rest, **kwargs):
585+ """
586+ When a complete IBAN is searched, also search for its BBAN
587+ if we have the domestic column. Disregard spaces
588+ when comparing IBANs.
589+ """
590+
591+ def is_term(arg):
592+ '''Flag an arg as term or otherwise'''
593+ return isinstance(arg, (list, tuple)) and len(arg) == 3
594+
595+ def extended_filter_term(term):
596+ '''
597+ Extend the search criteria in term when appropriate.
598+ '''
599+ result = [term]
600+ extra_terms = []
601+ if term[0].lower() == 'acc_number' and term[1] in ('=', '=='):
602+ iban = sepa.IBAN(term[2])
603+ if iban.valid:
604+ # Disregard spaces when comparing IBANs
605+ cr.execute(
606+ """
607+ SELECT id FROM res_partner_bank
608+ WHERE replace(acc_number, ' ', '') = %s
609+ """, (term[2].replace(' ', ''),))
610+ ids = [row[0] for row in cr.fetchall()]
611+ result = [('id', 'in', ids)]
612+
613+ if 'acc_number_domestic' in self._columns:
614+ bban = iban.localized_BBAN
615+ # Prevent empty search filters
616+ if bban:
617+ extra_terms.append(
618+ ('acc_number_domestic', term[1], bban))
619+ for extra_term in extra_terms:
620+ result = ['|'] + result + [extra_term]
621+ return result
622+
623+ def extended_search_expression(args):
624+ '''
625+ Extend the search expression in args when appropriate.
626+ The expression itself is in reverse polish notation, so recursion
627+ is not needed.
628+ '''
629+ if not args:
630+ return []
631+
632+ result = []
633+ if is_term(args[0]) and len(args) > 1:
634+ # Classic filter, implicit '&'
635+ result += ['&']
636+
637+ for arg in args:
638+ if is_term(arg):
639+ result += extended_filter_term(arg)
640+ else:
641+ result += arg
642+ return result
643+
644+ # Extend search filter
645+ newargs = extended_search_expression(args)
646+
647+ # Original search
648+ return super(ResPartnerBank, self).search(
649+ cr, uid, newargs, *rest, **kwargs)
650
651=== modified file 'account_banking/sepa/__init__.py'
652--- account_banking/sepa/__init__.py 2013-04-15 13:59:50 +0000
653+++ account_banking/sepa/__init__.py 2014-03-15 16:07:41 +0000
654@@ -19,6 +19,5 @@
655 #
656 ##############################################################################
657 import iban
658-import online
659 IBAN = iban.IBAN
660 BBAN = iban.BBAN
661
662=== modified file 'account_banking/wizard/banktools.py'
663--- account_banking/wizard/banktools.py 2013-09-14 11:54:23 +0000
664+++ account_banking/wizard/banktools.py 2014-03-15 16:07:41 +0000
665@@ -64,12 +64,6 @@
666 ('acc_number', '=', account_number)
667 ])
668 if not bank_account_ids:
669- # SR 2012-02-19 does the search() override in res_partner_bank
670- # provides this result on the previous query?
671- bank_account_ids = partner_bank_obj.search(cr, uid, [
672- ('acc_number_domestic', '=', account_number)
673- ])
674- if not bank_account_ids:
675 if not fail:
676 log.append(
677 _('Bank account %(account_no)s was not found in the database')
678@@ -237,7 +231,7 @@
679 bank_id = False
680
681 if online:
682- info, address = sepa.online.bank_info(bic)
683+ info, address = bank_obj.online_bank_info(cr, uid, bic, context=context)
684 if info:
685 bank_id = bank_obj.create(cr, uid, dict(
686 code = info.code,
687@@ -301,7 +295,6 @@
688 owner_name = holder_name,
689 country_id = country_id,
690 )
691- bankcode = None
692
693 # Are we dealing with IBAN?
694 iban = sepa.IBAN(account_number)
695@@ -309,23 +302,20 @@
696 # Take as much info as possible from IBAN
697 values.state = 'iban'
698 values.acc_number = str(iban)
699- values.acc_number_domestic = iban.BBAN
700- bankcode = iban.bankcode + iban.countrycode
701 else:
702 # No, try to convert to IBAN
703 values.state = 'bank'
704- values.acc_number = values.acc_number_domestic = account_number
705+ values.acc_number = account_number
706
707 if country_id:
708 country_code = pool.get('res.country').read(
709 cr, uid, country_id, ['code'], context=context)['code']
710 if country_code in sepa.IBAN.countries:
711- account_info = sepa.online.account_info(
712- country_code, values.acc_number)
713+ account_info = pool['res.partner.bank'].online_account_info(
714+ cr, uid, country_code, values.acc_number, context=context)
715 if account_info:
716 values.acc_number = iban = account_info.iban
717 values.state = 'iban'
718- bankcode = account_info.code
719 bic = account_info.bic
720
721 if bic:
722
723=== added directory 'account_banking_iban_lookup'
724=== added file 'account_banking_iban_lookup/__init__.py'
725--- account_banking_iban_lookup/__init__.py 1970-01-01 00:00:00 +0000
726+++ account_banking_iban_lookup/__init__.py 2014-03-15 16:07:41 +0000
727@@ -0,0 +1,3 @@
728+from . import online
729+from . import urlagent
730+from . import model
731
732=== added file 'account_banking_iban_lookup/__openerp__.py'
733--- account_banking_iban_lookup/__openerp__.py 1970-01-01 00:00:00 +0000
734+++ account_banking_iban_lookup/__openerp__.py 2014-03-15 16:07:41 +0000
735@@ -0,0 +1,52 @@
736+# -*- coding: utf-8 -*-
737+##############################################################################
738+#
739+# Copyright (C) 2009 EduSense BV (<http://www.edusense.nl>).
740+# (C) 2011 - 2014 Therp BV (<http://therp.nl>).
741+#
742+# This program is free software: you can redistribute it and/or modify
743+# it under the terms of the GNU Affero General Public License as
744+# published by the Free Software Foundation, either version 3 of the
745+# License, or (at your option) any later version.
746+#
747+# This program is distributed in the hope that it will be useful,
748+# but WITHOUT ANY WARRANTY; without even the implied warranty of
749+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
750+# GNU Affero General Public License for more details.
751+#
752+# You should have received a copy of the GNU Affero General Public License
753+# along with this program. If not, see <http://www.gnu.org/licenses/>.
754+#
755+##############################################################################
756+
757+{
758+ 'name': 'Banking Addons - Iban lookup (legacy)',
759+ 'version': '0.1',
760+ 'license': 'AGPL-3',
761+ 'author': 'Banking addons community',
762+ 'website': 'https://launchpad.net/banking-addons',
763+ 'category': 'Banking addons',
764+ 'depends': [
765+ 'account_banking',
766+ 'account_iban_preserve_domestic',
767+ ],
768+ 'data': [
769+ 'view/res_bank.xml',
770+ 'view/res_partner_bank.xml',
771+ ],
772+ 'external_dependencies': {
773+ 'python': ['BeautifulSoup'],
774+ },
775+ 'description': '''
776+This addons contains the legacy infrastructure for autocompletion of IBANs
777+and BBANs.
778+
779+The autocompletion was implemented for Dutch IBANs, but as it turns out
780+the online database that it consults does not get updated. As a result,
781+the autocompletion will come up with outdated IBANs and BICs.
782+
783+This module is deprecated and will be dropped in OpenERP 8.0.
784+ ''',
785+ 'auto_install': False,
786+ 'installable': True,
787+}
788
789=== added directory 'account_banking_iban_lookup/model'
790=== added file 'account_banking_iban_lookup/model/__init__.py'
791--- account_banking_iban_lookup/model/__init__.py 1970-01-01 00:00:00 +0000
792+++ account_banking_iban_lookup/model/__init__.py 2014-03-15 16:07:41 +0000
793@@ -0,0 +1,2 @@
794+from . import res_bank
795+from . import res_partner_bank
796
797=== added file 'account_banking_iban_lookup/model/res_bank.py'
798--- account_banking_iban_lookup/model/res_bank.py 1970-01-01 00:00:00 +0000
799+++ account_banking_iban_lookup/model/res_bank.py 2014-03-15 16:07:41 +0000
800@@ -0,0 +1,63 @@
801+# -*- coding: utf-8 -*-
802+##############################################################################
803+#
804+# Copyright (C) 2009 EduSense BV (<http://www.edusense.nl>).
805+# (C) 2011 - 2014 Therp BV (<http://therp.nl>).
806+#
807+# This program is free software: you can redistribute it and/or modify
808+# it under the terms of the GNU Affero General Public License as
809+# published by the Free Software Foundation, either version 3 of the
810+# License, or (at your option) any later version.
811+#
812+# This program is distributed in the hope that it will be useful,
813+# but WITHOUT ANY WARRANTY; without even the implied warranty of
814+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
815+# GNU Affero General Public License for more details.
816+#
817+# You should have received a copy of the GNU Affero General Public License
818+# along with this program. If not, see <http://www.gnu.org/licenses/>.
819+#
820+##############################################################################
821+from openerp.osv import orm
822+from openerp.addons.account_banking_iban_lookup import online
823+
824+
825+class ResBank(orm.Model):
826+ _inherit = 'res.bank'
827+
828+ def online_bank_info(self, cr, uid, bic, context=None):
829+ """
830+ Overwrite existing API hook from account_banking
831+ """
832+ return online.bank_info(bic)
833+
834+ def onchange_bic(
835+ self, cr, uid, ids, bic, name, context=None):
836+
837+ if not bic:
838+ return {}
839+
840+ info, address = online.bank_info(bic)
841+ if not info:
842+ return {}
843+
844+ if address and address.country_id:
845+ country_ids = self.pool.get('res.country').search(
846+ cr, uid, [('code', '=', address.country_id)])
847+ country_id = country_ids[0] if country_ids else False
848+ else:
849+ country_id = False
850+
851+ return {
852+ 'value': dict(
853+ # Only the first eight positions of BIC are used for bank
854+ # transfers, so ditch the rest.
855+ bic=info.bic[:8],
856+ street=address.street,
857+ street2=address.get('street2', False),
858+ zip=address.zip,
859+ city=address.city,
860+ country=country_id,
861+ name=name or info.name,
862+ )
863+ }
864
865=== added file 'account_banking_iban_lookup/model/res_partner_bank.py'
866--- account_banking_iban_lookup/model/res_partner_bank.py 1970-01-01 00:00:00 +0000
867+++ account_banking_iban_lookup/model/res_partner_bank.py 2014-03-15 16:07:41 +0000
868@@ -0,0 +1,271 @@
869+# -*- coding: utf-8 -*-
870+##############################################################################
871+#
872+# Copyright (C) 2009 EduSense BV (<http://www.edusense.nl>).
873+# (C) 2011 - 2014 Therp BV (<http://therp.nl>).
874+#
875+# All other contributions are (C) by their respective contributors
876+#
877+# All Rights Reserved
878+#
879+# This program is free software: you can redistribute it and/or modify
880+# it under the terms of the GNU Affero General Public License as
881+# published by the Free Software Foundation, either version 3 of the
882+# License, or (at your option) any later version.
883+#
884+# This program is distributed in the hope that it will be useful,
885+# but WITHOUT ANY WARRANTY; without even the implied warranty of
886+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
887+# GNU Affero General Public License for more details.
888+#
889+# You should have received a copy of the GNU Affero General Public License
890+# along with this program. If not, see <http://www.gnu.org/licenses/>.
891+#
892+##############################################################################
893+from openerp import SUPERUSER_ID
894+from openerp.osv import orm
895+from openerp.tools.translate import _
896+from openerp.addons.account_banking_iban_lookup import online
897+from openerp.addons.account_banking import sepa
898+from openerp.addons.account_banking.wizard.banktools import get_or_create_bank
899+
900+
901+def warning(title, message):
902+ '''Convenience routine'''
903+ return {'warning': {'title': title, 'message': message}}
904+
905+
906+class res_partner_bank(orm.Model):
907+ '''
908+ Extended functionality:
909+ 1. BBAN and IBAN are considered equal
910+ 2. Online lookup when an API is available (providing NL in this module)
911+ 3. Banks are created on the fly when using IBAN + online
912+ 4. IBAN formatting
913+ 5. BBAN's are generated from IBAN when possible
914+ '''
915+ _inherit = 'res.partner.bank'
916+
917+ def init(self, cr):
918+ '''
919+ Update existing iban accounts to comply to new regime
920+ '''
921+
922+ partner_bank_obj = self.pool.get('res.partner.bank')
923+ bank_ids = partner_bank_obj.search(
924+ cr, SUPERUSER_ID, [('state', '=', 'iban')], limit=0)
925+ for bank in partner_bank_obj.read(cr, SUPERUSER_ID, bank_ids):
926+ write_vals = {}
927+ if bank['state'] == 'iban':
928+ iban_acc = sepa.IBAN(bank['acc_number'])
929+ if iban_acc.valid:
930+ write_vals['acc_number_domestic'] = iban_acc.localized_BBAN
931+ write_vals['acc_number'] = str(iban_acc)
932+ elif bank['acc_number'] != bank['acc_number'].upper():
933+ write_vals['acc_number'] = bank['acc_number'].upper()
934+ if write_vals:
935+ partner_bank_obj.write(
936+ cr, SUPERUSER_ID, bank['id'], write_vals)
937+
938+ @staticmethod
939+ def _correct_IBAN(acc_number):
940+ '''
941+ Routine to correct IBAN values and deduce localized values when valid.
942+ Note: No check on validity IBAN/Country
943+ '''
944+ iban = sepa.IBAN(acc_number)
945+ return (str(iban), iban.localized_BBAN)
946+
947+ def create(self, cr, uid, vals, context=None):
948+ '''
949+ Create dual function IBAN account for SEPA countries
950+ '''
951+ if vals.get('state') == 'iban':
952+ iban = (vals.get('acc_number')
953+ or vals.get('acc_number_domestic', False))
954+ vals['acc_number'], vals['acc_number_domestic'] = (
955+ self._correct_IBAN(iban))
956+ return super(res_partner_bank, self).create(
957+ cr, uid, vals, context)
958+
959+ def write(self, cr, uid, ids, vals, context=None):
960+ '''
961+ Create dual function IBAN account for SEPA countries
962+
963+ Update the domestic account number when the IBAN is
964+ written, or clear the domestic number on regular account numbers.
965+ '''
966+ if ids and isinstance(ids, (int, long)):
967+ ids = [ids]
968+ for account in self.read(
969+ cr, uid, ids, ['state', 'acc_number']):
970+ if 'state' in vals or 'acc_number' in vals:
971+ account.update(vals)
972+ if account['state'] == 'iban':
973+ vals['acc_number'], vals['acc_number_domestic'] = (
974+ self._correct_IBAN(account['acc_number']))
975+ else:
976+ vals['acc_number_domestic'] = False
977+ super(res_partner_bank, self).write(
978+ cr, uid, account['id'], vals, context)
979+ return True
980+
981+ def onchange_acc_number(
982+ self, cr, uid, ids, acc_number, acc_number_domestic,
983+ state, partner_id, country_id, context=None):
984+ if state == 'iban':
985+ return self.onchange_iban(
986+ cr, uid, ids, acc_number, acc_number_domestic,
987+ state, partner_id, country_id, context=None
988+ )
989+ else:
990+ return self.onchange_domestic(
991+ cr, uid, ids, acc_number,
992+ partner_id, country_id, context=None
993+ )
994+
995+ def onchange_domestic(
996+ self, cr, uid, ids, acc_number,
997+ partner_id, country_id, context=None):
998+ '''
999+ Trigger to find IBAN. When found:
1000+ 1. Reformat BBAN
1001+ 2. Autocomplete bank
1002+
1003+ TODO: prevent unnecessary assignment of country_ids and
1004+ browsing of the country
1005+ '''
1006+ if not acc_number:
1007+ return {}
1008+
1009+ values = {}
1010+ country_obj = self.pool.get('res.country')
1011+ country_ids = []
1012+ country = False
1013+
1014+ # Pre fill country based on available data. This is just a default
1015+ # which can be overridden by the user.
1016+ # 1. Use provided country_id (manually filled)
1017+ if country_id:
1018+ country = country_obj.browse(cr, uid, country_id, context=context)
1019+ country_ids = [country_id]
1020+ # 2. Use country_id of found bank accounts
1021+ # This can be usefull when there is no country set in the partners
1022+ # addresses, but there was a country set in the address for the bank
1023+ # account itself before this method was triggered.
1024+ elif ids and len(ids) == 1:
1025+ partner_bank_obj = self.pool.get('res.partner.bank')
1026+ partner_bank_id = partner_bank_obj.browse(
1027+ cr, uid, ids[0], context=context)
1028+ if partner_bank_id.country_id:
1029+ country = partner_bank_id.country_id
1030+ country_ids = [country.id]
1031+ # 3. Use country_id of default address of partner
1032+ # The country_id of a bank account is a one time default on creation.
1033+ # It originates in the same address we are about to check, but
1034+ # modifications on that address afterwards are not transfered to the
1035+ # bank account, hence the additional check.
1036+ elif partner_id:
1037+ partner_obj = self.pool.get('res.partner')
1038+ country = partner_obj.browse(
1039+ cr, uid, partner_id, context=context).country
1040+ country_ids = country and [country.id] or []
1041+ # 4. Without any of the above, take the country from the company of
1042+ # the handling user
1043+ if not country_ids:
1044+ user = self.pool.get('res.users').browse(
1045+ cr, uid, uid, context=context)
1046+ # Try user companies partner (user no longer has address in 6.1)
1047+ if (user.company_id and
1048+ user.company_id.partner_id and
1049+ user.company_id.partner_id.country):
1050+ country_ids = [user.company_id.partner_id.country.id]
1051+ else:
1052+ if (user.company_id and user.company_id.partner_id and
1053+ user.company_id.partner_id.country):
1054+ country_ids = [user.company_id.partner_id.country.id]
1055+ else:
1056+ # Ok, tried everything, give up and leave it to the user
1057+ return warning(_('Insufficient data'),
1058+ _('Insufficient data to select online '
1059+ 'conversion database')
1060+ )
1061+ result = {'value': values}
1062+ # Complete data with online database when available
1063+ if country_ids:
1064+ country = country_obj.browse(
1065+ cr, uid, country_ids[0], context=context)
1066+ values['country_id'] = country_ids[0]
1067+ if country and country.code in sepa.IBAN.countries:
1068+ info = online.account_info(country.code, acc_number)
1069+ if info:
1070+ iban_acc = sepa.IBAN(info.iban)
1071+ if iban_acc.valid:
1072+ values['acc_number_domestic'] = iban_acc.localized_BBAN
1073+ values['acc_number'] = unicode(iban_acc)
1074+ values['state'] = 'iban'
1075+ bank_id, country_id = get_or_create_bank(
1076+ self.pool, cr, uid,
1077+ info.bic or iban_acc.BIC_searchkey,
1078+ name=info.bank)
1079+ if country_id:
1080+ values['country_id'] = country_id
1081+ values['bank'] = bank_id or False
1082+ if info.bic:
1083+ values['bank_bic'] = info.bic
1084+ else:
1085+ info = None
1086+ if info is None:
1087+ result.update(warning(
1088+ _('Invalid data'),
1089+ _('The account number appears to be invalid for %s')
1090+ % country.name
1091+ ))
1092+ if info is False:
1093+ if country.code in sepa.IBAN.countries:
1094+ acc_number_fmt = sepa.BBAN(acc_number, country.code)
1095+ if acc_number_fmt.valid:
1096+ values['acc_number_domestic'] = str(acc_number_fmt)
1097+ else:
1098+ result.update(warning(
1099+ _('Invalid format'),
1100+ _('The account number has the wrong format for %s')
1101+ % country.name
1102+ ))
1103+ return result
1104+
1105+ def onchange_iban(
1106+ self, cr, uid, ids, acc_number, acc_number_domestic,
1107+ state, partner_id, country_id, context=None):
1108+ '''
1109+ Trigger to verify IBAN. When valid:
1110+ 1. Extract BBAN as local account
1111+ 2. Auto complete bank
1112+ '''
1113+ if not acc_number:
1114+ return {}
1115+
1116+ iban_acc = sepa.IBAN(acc_number)
1117+ if iban_acc.valid:
1118+ bank_id, country_id = get_or_create_bank(
1119+ self.pool, cr, uid, iban_acc.BIC_searchkey,
1120+ code=iban_acc.BIC_searchkey
1121+ )
1122+ return {
1123+ 'value': dict(
1124+ acc_number_domestic=iban_acc.localized_BBAN,
1125+ acc_number=unicode(iban_acc),
1126+ country=country_id or False,
1127+ bank=bank_id or False,
1128+ )
1129+ }
1130+ return warning(
1131+ _('Invalid IBAN account number!'),
1132+ _("The IBAN number doesn't seem to be correct"))
1133+
1134+ def online_account_info(
1135+ self, cr, uid, country_code, acc_number, context=None):
1136+ """
1137+ Overwrite API hook from account_banking
1138+ """
1139+ return online.account_info(country_code, acc_number)
1140
1141=== renamed file 'account_banking/sepa/online.py' => 'account_banking_iban_lookup/online.py'
1142--- account_banking/sepa/online.py 2014-02-10 20:21:08 +0000
1143+++ account_banking_iban_lookup/online.py 2014-03-15 16:07:41 +0000
1144@@ -1,4 +1,4 @@
1145-# -*- encoding: utf-8 -*-
1146+# -*- coding: utf-8 -*-
1147 ##############################################################################
1148 #
1149 # Copyright (C) 2009 EduSense BV (<http://www.edusense.nl>).
1150@@ -26,7 +26,7 @@
1151 import urllib, urllib2
1152 from BeautifulSoup import BeautifulSoup
1153 from openerp.addons.account_banking.sepa import postalcode
1154-from openerp.addons.account_banking.sepa.urlagent import URLAgent, SoupForm
1155+from openerp.addons.account_banking_iban_lookup.urlagent import URLAgent, SoupForm
1156 from openerp.addons.account_banking.sepa.iban import IBAN
1157 from openerp.addons.account_banking.struct import struct
1158
1159
1160=== renamed file 'account_banking/sepa/urlagent.py' => 'account_banking_iban_lookup/urlagent.py'
1161--- account_banking/sepa/urlagent.py 2013-04-15 13:59:50 +0000
1162+++ account_banking_iban_lookup/urlagent.py 2014-03-15 16:07:41 +0000
1163@@ -25,7 +25,6 @@
1164 '''
1165
1166 import urllib
1167-from BeautifulSoup import BeautifulSoup
1168
1169 __all__ = ['urlsplit', 'urljoin', 'pathbase', 'urlbase', 'SoupForm',
1170 'URLAgent'
1171
1172=== added directory 'account_banking_iban_lookup/view'
1173=== added file 'account_banking_iban_lookup/view/res_bank.xml'
1174--- account_banking_iban_lookup/view/res_bank.xml 1970-01-01 00:00:00 +0000
1175+++ account_banking_iban_lookup/view/res_bank.xml 2014-03-15 16:07:41 +0000
1176@@ -0,0 +1,15 @@
1177+<?xml version="1.0" encoding="utf-8"?>
1178+<openerp>
1179+ <data>
1180+ <record id="view_res_bank_account_banking_form_1" model="ir.ui.view">
1181+ <field name="name">Add BIC lookup to bank form</field>
1182+ <field name="model">res.bank</field>
1183+ <field name="inherit_id" ref="base.view_res_bank_form"/>
1184+ <field name="arch" type="xml">
1185+ <field name="bic" position="replace">
1186+ <field name="bic" on_change="onchange_bic(bic, name)"/>
1187+ </field>
1188+ </field>
1189+ </record>
1190+ </data>
1191+</openerp>
1192
1193=== added file 'account_banking_iban_lookup/view/res_partner_bank.xml'
1194--- account_banking_iban_lookup/view/res_partner_bank.xml 1970-01-01 00:00:00 +0000
1195+++ account_banking_iban_lookup/view/res_partner_bank.xml 2014-03-15 16:07:41 +0000
1196@@ -0,0 +1,23 @@
1197+<?xml version="1.0" encoding="utf-8"?>
1198+<openerp>
1199+ <data>
1200+ <record id="view_partner_bank_account_banking_form_2" model="ir.ui.view">
1201+ <field name="name">Add autocompletion methods to partner bank form</field>
1202+ <field name="model">res.partner.bank</field>
1203+ <field name="inherit_id" ref="base.view_partner_bank_form"/>
1204+ <field name="priority" eval="24"/>
1205+ <field name="arch" type="xml">
1206+ <data>
1207+ <field name="acc_number" position="attributes">
1208+ <attribute name="on_change">onchange_acc_number(acc_number, acc_number_domestic, state, partner_id, country_id)</attribute>
1209+ </field>
1210+ <field name="acc_number_domestic" position="attributes">
1211+ <attribute name="on_change">onchange_domestic(acc_number_domestic, partner_id, country_id)</attribute>
1212+ </field>
1213+ </data>
1214+ </field>
1215+ </record>
1216+ </data>
1217+</openerp>
1218+
1219+
1220
1221=== modified file 'account_banking_nl_clieop/__openerp__.py'
1222--- account_banking_nl_clieop/__openerp__.py 2013-05-28 15:18:26 +0000
1223+++ account_banking_nl_clieop/__openerp__.py 2014-03-15 16:07:41 +0000
1224@@ -24,7 +24,10 @@
1225 'author': 'EduSense BV',
1226 'website': 'http://www.edusense.nl',
1227 'category': 'Account Banking',
1228- 'depends': ['account_banking_payment'],
1229+ 'depends': [
1230+ 'account_banking_payment',
1231+ 'account_iban_preserve_domestic',
1232+ ],
1233 'data': [
1234 'account_banking_nl_clieop.xml',
1235 'wizard/export_clieop_view.xml',
1236
1237=== modified file 'account_banking_nl_multibank/__openerp__.py'
1238--- account_banking_nl_multibank/__openerp__.py 2013-04-15 13:56:18 +0000
1239+++ account_banking_nl_multibank/__openerp__.py 2014-03-15 16:07:41 +0000
1240@@ -20,7 +20,7 @@
1241 ##############################################################################
1242
1243 {
1244- 'name': 'Account Banking',
1245+ 'name': 'Account Banking - NL Multibank import',
1246 'version': '0.62',
1247 'license': 'AGPL-3',
1248 'author': 'EduSense BV',
1249
1250=== modified file 'account_banking_payment/model/banking_import_transaction.py'
1251--- account_banking_payment/model/banking_import_transaction.py 2013-06-04 13:44:24 +0000
1252+++ account_banking_payment/model/banking_import_transaction.py 2014-03-15 16:07:41 +0000
1253@@ -116,14 +116,26 @@
1254 '''
1255 # TODO: Not sure what side effects are created when payments are done
1256 # for credited customer invoices, which will be matched later on too.
1257+
1258+ def bank_match(account, partner_bank):
1259+ """
1260+ Returns whether a given account number is equivalent to a
1261+ partner bank in the database. We simply call the search method,
1262+ which checks IBAN, domestic and disregards from spaces in IBANs.
1263+
1264+ :param account: string representation of a bank account number
1265+ :param partner_bank: browse record of model res.partner.bank
1266+ """
1267+ return partner_bank.id in self.pool['res.partner.bank'].search(
1268+ cr, uid, [('acc_number', '=', account)])
1269+
1270 digits = dp.get_precision('Account')(cr)[1]
1271 candidates = [
1272- x for x in payment_lines
1273- if x.communication == trans.reference
1274- and round(x.amount, digits) == -round(
1275- trans.statement_line_id.amount, digits)
1276- and trans.remote_account in (x.bank_id.acc_number,
1277- x.bank_id.acc_number_domestic)
1278+ line for line in payment_lines
1279+ if (line.communication == trans.reference
1280+ and round(line.amount, digits) == -round(
1281+ trans.statement_line_id.amount, digits)
1282+ and bank_match(trans.remote_account, line.bank_id))
1283 ]
1284 if len(candidates) == 1:
1285 candidate = candidates[0]

Subscribers

People subscribed via source and target branches

to status/vote changes: