← Back to team overview

banking-addons-team team mailing list archive

[Merge] lp:~therp-nl/banking-addons/7.0-link_partner_wizard into lp:banking-addons/banking-addons-70

 

Stefan Rijnhart (Therp) has proposed merging lp:~therp-nl/banking-addons/7.0-link_partner_wizard into lp:banking-addons/banking-addons-70 with lp:~therp-nl/banking-addons/ba7.0-manual_multi_match as a prerequisite.

Commit message:
[MIG] Forward port of lp:~therp-nl/banking-addons/6.1-link_partner_wizard

Requested reviews:
  Banking Addons Team (banking-addons-team)

For more details, see:
https://code.launchpad.net/~therp-nl/banking-addons/7.0-link_partner_wizard/+merge/161828
-- 
https://code.launchpad.net/~therp-nl/banking-addons/7.0-link_partner_wizard/+merge/161828
Your team Banking Addons Team is requested to review the proposed merge of lp:~therp-nl/banking-addons/7.0-link_partner_wizard into lp:banking-addons/banking-addons-70.
=== modified file 'account_banking/__openerp__.py'
--- account_banking/__openerp__.py	2013-05-01 14:29:27 +0000
+++ account_banking/__openerp__.py	2013-05-01 14:29:27 +0000
@@ -41,6 +41,7 @@
         'wizard/bank_import_view.xml',
         'account_banking_view.xml',
         'wizard/banking_transaction_wizard.xml',
+        'wizard/link_partner.xml',
         'workflow/account_invoice.xml',
     ],
     'js': [

=== modified file 'account_banking/account_banking_view.xml'
--- account_banking/account_banking_view.xml	2013-05-01 14:29:27 +0000
+++ account_banking/account_banking_view.xml	2013-05-01 14:29:27 +0000
@@ -236,6 +236,13 @@
                     -->
                     <xpath expr="//field[@name='line_ids']/tree/field[@name='partner_id']"
                            position="after">
+                        <field name="link_partner_ok" invisible="1" />
+                        <button name="link_partner"
+                                string="Link partner"
+                                icon="terp-partner"
+                                type="object"
+                                attrs="{'invisible': [('link_partner_ok', '=', False)]}"
+                                />
                         <!-- TODO set partner_id when partner_bank_id changes -->
                         <field name="partner_bank_id"/>
                     </xpath>
@@ -323,6 +330,13 @@
                     <field name="name"/>
                     <field name="ref"/>
                     <field name="partner_id" on_change="onchange_partner_id(partner_id)"/>
+                    <field name="link_partner_ok" invisible="1" />
+                    <button name="link_partner"
+                            string="Link partner"
+                            icon="terp-partner"
+                            type="object"
+                            attrs="{'invisible': [('link_partner_ok', '=', False)]}"
+                            />
                     <!-- TODO set partner_id when partner_bank_id changes -->
                     <field name="partner_bank_id"/>
                     <field name="type" on_change="onchange_type(partner_id, type)"/>

=== modified file 'account_banking/banking_import_transaction.py'
--- account_banking/banking_import_transaction.py	2013-05-01 14:29:27 +0000
+++ account_banking/banking_import_transaction.py	2013-05-01 14:29:27 +0000
@@ -885,6 +885,9 @@
                     i += 1
                 continue
             
+            partner_banks = []
+            partner_ids = []
+
             # TODO: optimize by ordering transactions per company, 
             # and perform the stanza below only once per company.
             # In that case, take newest transaction date into account
@@ -1027,6 +1030,7 @@
             if transaction.type == bt.STORNO and has_payment:
                 move_info = self._match_storno(
                     cr, uid, transaction, results['log'], context)
+
             # Allow inclusion of generated bank invoices
             if transaction.type == bt.BANK_COSTS:
                 lines = self._match_costs(
@@ -1038,7 +1042,6 @@
                     if not [x for x in move_lines if x.id == line.id]:
                         move_lines.append(line)
                 partner_ids = [account_info.bank_partner_id.id]
-                partner_banks = []
             else:
                 # Link remote partner, import account when needed
                 partner_banks = banktools.get_bank_accounts(
@@ -1048,47 +1051,28 @@
                 if partner_banks:
                     partner_ids = [x.partner_id.id for x in partner_banks]
                 elif transaction.remote_owner:
-                    iban = sepa.IBAN(transaction.remote_account)
-                    if iban.valid:
-                        country_code = iban.countrycode
-                    elif transaction.remote_owner_country_code:
-                        country_code = transaction.remote_owner_country_code
-                    # fallback on the import parsers country code
-                    elif transaction.bank_country_code:
-                        country_code = transaction.bank_country_code
-                    elif company.partner_id and company.partner_id.country:
-                        country_code = company.partner_id.country.code
-                    else:
-                        country_code = None
-                    partner_id = banktools.get_or_create_partner(
+                    country_id = banktools.get_country_id(
+                        self.pool, cr, uid, transaction, context=context)
+                    partner_id = banktools.get_partner(
                         self.pool, cr, uid, transaction.remote_owner,
                         transaction.remote_owner_address,
                         transaction.remote_owner_postalcode,
                         transaction.remote_owner_city,
-                        country_code, results['log'],
-                        customer=transaction.transferred_amount > 0,
-                        supplier=transaction.transferred_amount < 0,
+                        country_id, results['log'],
                         context=context)
-                    if transaction.remote_account:
-                        partner_bank_id = banktools.create_bank_account(
-                            self.pool, cr, uid, partner_id,
-                            transaction.remote_account,
-                            transaction.remote_owner, 
-                            transaction.remote_owner_address,
-                            transaction.remote_owner_city,
-                            country_code, results['log'],
-                            bic=transaction.remote_bank_bic
-                            )
-                        partner_banks = partner_bank_obj.browse(
-                            cr, uid, [partner_bank_id]
-                            )
-                    else:
-                        partner_bank_id = None
-                        partner_banks = []
-                    partner_ids = [partner_id]
-                else:
-                    partner_ids = []
-                    partner_banks = []
+                    if partner_id:
+                        partner_ids = [partner_id]
+                        if transaction.remote_account:
+                            partner_bank_id = banktools.create_bank_account(
+                                self.pool, cr, uid, partner_id,
+                                transaction.remote_account,
+                                transaction.remote_owner, 
+                                transaction.remote_owner_address,
+                                transaction.remote_owner_city,
+                                country_id, bic=transaction.remote_bank_bic,
+                                context=context)
+                            partner_banks = partner_bank_obj.browse(
+                                cr, uid, [partner_bank_id], context=context)
 
             # Credit means payment... isn't it?
             if (not move_info
@@ -1422,6 +1406,24 @@
 
 class account_bank_statement_line(orm.Model):
     _inherit = 'account.bank.statement.line'
+
+    def _get_link_partner_ok(
+            self, cr, uid, ids, name, args, context=None):
+        """
+        Deliver the values of the function field that
+        determines if the 'link partner' wizard is show on the 
+        bank statement line
+        """
+        res = {}
+        for line in self.browse(cr, uid, ids, context):
+            res[line.id] = bool(
+                line.state == 'draft'
+                and not line.partner_id
+                and line.import_transaction_id
+                and line.import_transaction_id.remote_owner
+                and line.import_transaction_id.remote_account)
+        return res
+
     _columns = {
         'import_transaction_id': fields.many2one(
             'banking.import.transaction', 
@@ -1447,6 +1449,9 @@
             readonly=True, required=True),
         'parent_id': fields.many2one('account.bank.statement.line',
             'Parent'),
+        'link_partner_ok': fields.function(
+            _get_link_partner_ok, type='boolean',
+            string='Can link partner'),
         }
 
     _defaults = {
@@ -1467,6 +1472,66 @@
             res = wizard_obj.create_act_window(cr, uid, res_id, context=context)
         return res
 
+    def link_partner(self, cr, uid, ids, context=None):
+        """
+        Get the appropriate partner or fire a wizard to create
+        or link one
+        """
+        if not ids:
+            return False
+
+        if isinstance(ids, (int, long)):
+            ids = [ids]
+                
+        # Check if the partner is already known but not shown
+        # because the screen was not refreshed yet
+        statement_line = self.browse(
+            cr, uid, ids[0], context=context)
+        if statement_line.partner_id:
+            return True
+
+        # Reuse the bank's partner if any
+        if (statement_line.partner_bank_id and
+                statement_line.partner_bank_id.partner_id):
+            statement_line.write(
+                {'partner_id': statement_line.partner_bank_id.partner_id.id})
+            return True
+
+        if (not statement_line.import_transaction_id or
+            not statement_line.import_transaction_id.remote_account):
+            raise osv.except_osv(
+                _("Error"),
+                _("No bank account available to link partner to"))
+            
+        # Check if the bank account was already been linked
+        # manually to another transaction
+        remote_account = statement_line.import_transaction_id.remote_account
+        source_line_ids = self.search(
+            cr, uid,
+            [('import_transaction_id.remote_account', '=', remote_account),
+             ('partner_bank_id.partner_id', '!=', False),
+             ], limit=1, context=context)
+        if source_line_ids:
+            source_line = self.browse(
+                cr, uid, source_line_ids[0], context=context)
+            target_line_ids = self.search(
+                cr, uid,
+                [('import_transaction_id.remote_account', '=', remote_account),
+                 ('partner_bank_id', '=', False),
+                 ('state', '=', 'draft')], context=context)
+            self.write(
+                cr, uid, target_line_ids,
+                {'partner_bank_id': source_line.partner_bank_id.id,
+                 'partner_id': source_line.partner_bank_id.partner_id.id,
+                 }, context=context)
+            return True
+                
+        # Or fire the wizard to link partner and account
+        wizard_obj = self.pool.get('banking.link_partner')
+        res_id = wizard_obj.create(
+            cr, uid, {'statement_line_id': ids[0]}, context=context)
+        return wizard_obj.create_act_window(cr, uid, res_id, context=context)
+
     def _convert_currency(
         self, cr, uid, from_curr_id, to_curr_id, from_amount,
         round=False, date=None, context=None):

=== modified file 'account_banking/wizard/__init__.py'
--- account_banking/wizard/__init__.py	2013-05-01 14:29:27 +0000
+++ account_banking/wizard/__init__.py	2013-05-01 14:29:27 +0000
@@ -20,5 +20,6 @@
 ##############################################################################
 import bank_import
 import banking_transaction_wizard
+import link_partner
 
 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

=== modified file 'account_banking/wizard/banking_transaction_wizard.py'
--- account_banking/wizard/banking_transaction_wizard.py	2013-05-01 14:29:27 +0000
+++ account_banking/wizard/banking_transaction_wizard.py	2013-05-01 14:29:27 +0000
@@ -73,7 +73,7 @@
         Call the automatic matching routine for one or
         more bank transactions
         """
-        if isinstance(ids, (int, float)):
+        if isinstance(ids, (int, long)):
             ids = [ids]
         import_transaction_obj = self.pool.get('banking.import.transaction')
         trans_id = self.read(
@@ -276,7 +276,7 @@
         settings_pool = self.pool.get('account.banking.account.settings')
         statement_pool = self.pool.get('account.bank.statement.line')
 
-        if isinstance(ids, (int, float)):
+        if isinstance(ids, (int, long)):
             ids = [ids]
 
         for wiz in self.browse(cr, uid, ids, context=context):
@@ -309,7 +309,7 @@
         return self.create_act_window(cr, uid, ids, context=None)
 
     def reverse_duplicate(self, cr, uid, ids, context=None):
-        if isinstance(ids, (int, float)):
+        if isinstance(ids, (int, long)):
             ids = [ids]
         transaction_obj = self.pool.get('banking.import.transaction')
         for wiz in self.read(

=== modified file 'account_banking/wizard/banktools.py'
--- account_banking/wizard/banktools.py	2013-05-01 14:29:27 +0000
+++ account_banking/wizard/banktools.py	2013-05-01 14:29:27 +0000
@@ -26,7 +26,8 @@
 __all__ = [
     'get_period', 
     'get_bank_accounts',
-    'get_or_create_partner',
+    'get_partner',
+    'get_country_id',
     'get_company_bank_account',
     'create_bank_account',
 ]
@@ -56,7 +57,7 @@
     '''
     # No need to search for nothing
     if not account_number:
-        return False
+        return []
 
     partner_bank_obj = pool.get('res.partner.bank')
     bank_account_ids = partner_bank_obj.search(cursor, uid, [
@@ -74,7 +75,7 @@
                 _('Bank account %(account_no)s was not found in the database')
                 % dict(account_no=account_number)
             )
-        return False
+        return []
     return partner_bank_obj.browse(cursor, uid, bank_account_ids)
 
 def _has_attr(obj, attr):
@@ -85,11 +86,10 @@
     except KeyError:
         return False
 
-def get_or_create_partner(pool, cr, uid, name, address, postal_code, city,
-                          country_code, log, supplier=False, customer=False,
-                          context=None):
+def get_partner(pool, cr, uid, name, address, postal_code, city,
+                country_id, log, context=None):
     '''
-    Get or create the partner belonging to the account holders name <name>
+    Get the partner belonging to the account holders name <name>
 
     If multiple partners are found with the same name, select the first and
     add a warning to the import log.
@@ -99,16 +99,10 @@
     partner_obj = pool.get('res.partner')
     partner_ids = partner_obj.search(cr, uid, [('name', 'ilike', name)],
                                      context=context)
-    country_id = False
     if not partner_ids:
         # Try brute search on address and then match reverse
         criteria = []
-        if country_code:
-            country_obj = pool.get('res.country')
-            country_ids = country_obj.search(
-                cr, uid, [('code', '=', country_code.upper())],
-                context=context)
-            country_id = country_ids and country_ids[0] or False
+        if country_id:
             criteria.append(('country_id', '=', country_id))
         if city:
             criteria.append(('city', 'ilike', city))
@@ -116,6 +110,11 @@
             criteria.append(('zip', 'ilike', postal_code))
         partner_search_ids = partner_obj.search(
             cr, uid, criteria, context=context)
+        if (not partner_search_ids and country_id):
+            # Try again with country_id = False
+            criteria[0] = ('country_id', '=', False)
+            partner_search_ids = partner_obj.search(
+                cr, uid, criteria, context=context)
         key = name.lower()
         partners = []
         for partner in partner_obj.read(
@@ -124,35 +123,11 @@
                 partners.append(partner)
         partners.sort(key=lambda x: len(x['name']), reverse=True)
         partner_ids = [x['id'] for x in partners]
-    if not partner_ids:
-        if not country_id:
-            user = pool.get('res.user').browse(cr, uid, uid, context=context)
-            country_id = (
-                user.company_id.partner_id.country and 
-                user.company_id.partner_id.country.id or
-                False
-            )
-        partner_id = partner_obj.create(
-            cr, uid, {
-                'name': name,
-                'active': True,
-                'comment': 'Generated from Bank Statements Import',
-                'street': address and address[0] or '',
-                'street2': len(address) > 1 and address[1] or '',
-                'city': city,
-                'zip': postal_code or '',
-                'country_id': country_id,
-                'is_company': True,
-                'supplier': supplier,
-                'customer': customer,
-                }, context=context)
-    else:
-        if len(partner_ids) > 1:
-            log.append(
-                _('More than one possible match found for partner with '
-                  'name %(name)s') % {'name': name})
-        partner_id = partner_ids[0]
-    return partner_id
+    if len(partner_ids) > 1:
+        log.append(
+            _('More than one possible match found for partner with '
+              'name %(name)s') % {'name': name})
+    return partner_ids and partner_ids[0] or False
 
 def get_company_bank_account(pool, cursor, uid, account_number, currency,
                              company, log):
@@ -283,19 +258,47 @@
         ))
     return bank_id, country_id
 
-def create_bank_account(pool, cursor, uid, partner_id,
+def get_country_id(pool, cr, uid, transaction, context=None):
+    """
+    Derive a country id from the info on the transaction.
+    
+    :param transaction: browse record of a transaction
+    :returns: res.country id or False 
+    """
+    
+    country_code = False
+    iban = sepa.IBAN(transaction.remote_account)
+    if iban.valid:
+        country_code = iban.countrycode
+    elif transaction.remote_owner_country_code:
+        country_code = transaction.remote_owner_country_code
+    # fallback on the import parsers country code
+    elif transaction.bank_country_code:
+        country_code = transaction.bank_country_code
+    if country_code:
+        country_ids = pool.get('res.country').search(
+            cr, uid, [('code', '=', country_code.upper())],
+            context=context)
+        country_id = country_ids and country_ids[0] or False
+    if not country_id:
+        company = transaction.statement_line_id.company_id
+        if company.partner_id.country:
+            country_id = company.partner_id.country.id
+    return country_id
+
+def create_bank_account(pool, cr, uid, partner_id,
                         account_number, holder_name, address, city,
-                        country_code, log, bic=False,
-                        ):
+                        country_id, bic=False,
+                        context=None):
     '''
     Create a matching bank account with this holder for this partner.
     '''
     values = struct(
         partner_id = partner_id,
         owner_name = holder_name,
+        country_id = country_id,
     )
     bankcode = None
-    country_obj = pool.get('res.country')
 
     # Are we dealing with IBAN?
     iban = sepa.IBAN(account_number)
@@ -305,44 +308,29 @@
         values.acc_number = str(iban)
         values.acc_number_domestic = iban.BBAN
         bankcode = iban.bankcode + iban.countrycode
-        country_code = iban.countrycode
-
-    if not country_code:
-        country = pool.get('res.partner').browse(
-            cursor, uid, partner_id).country
-        country_code = country.code
-        country_id = country.id
     else:
-        if iban.valid:
-            country_ids = country_obj.search(cursor, uid,
-                                             [('code', '=', iban.countrycode)]
-                                             )
-        else:
-            country_ids = country_obj.search(cursor, uid,
-                                             [('code', '=', country_code)]
-                                             )
-        country_id = country_ids[0]
-    
-    account_info = False
-    if not iban.valid:
         # No, try to convert to IBAN
         values.state = 'bank'
         values.acc_number = values.acc_number_domestic = account_number
-        if country_code in sepa.IBAN.countries:
-            account_info = sepa.online.account_info(country_code,
-                                                    values.acc_number
-                                                   )
-            if account_info:
-                values.acc_number = iban = account_info.iban
-                values.state = 'iban'
-                bankcode = account_info.code
-                bic = account_info.bic
+
+        if country_id:
+            country_code = pool.get('res.country').read(
+                cr, uid, country_id, ['code'], context=context)['code']
+            if country_code in sepa.IBAN.countries:
+                account_info = sepa.online.account_info(
+                    country_code, values.acc_number)
+                if account_info:
+                    values.acc_number = iban = account_info.iban
+                    values.state = 'iban'
+                    bankcode = account_info.code
+                    bic = account_info.bic
 
     if bic:
-        values.bank = get_or_create_bank(pool, cursor, uid, bic)[0]
+        values.bank = get_or_create_bank(pool, cr, uid, bic)[0]
         values.bank_bic = bic
 
     # Create bank account and return
-    return pool.get('res.partner.bank').create(cursor, uid, values)
+    return pool.get('res.partner.bank').create(
+        cr, uid, values, context=context)
 
 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

=== added file 'account_banking/wizard/link_partner.py'
--- account_banking/wizard/link_partner.py	1970-01-01 00:00:00 +0000
+++ account_banking/wizard/link_partner.py	2013-05-01 14:29:27 +0000
@@ -0,0 +1,179 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    Copyright (C) 2013 Therp BV (<http://therp.nl>).
+#    All Rights Reserved
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+from openerp.osv import orm, fields
+from openerp.tools.translate import _
+from openerp.addons.account_banking.wizard import banktools
+
+class link_partner(orm.TransientModel):
+    _name = 'banking.link_partner'
+    _description = 'Link partner'
+
+    _columns = {
+        'name': fields.char(
+            'Create partner with name', size=128, required=True),
+        'supplier': fields.boolean('Supplier'),
+        'customer': fields.boolean('Customer'),
+        'partner_id': fields.many2one(
+            'res.partner', 'or link existing partner'),
+        'statement_line_id': fields.many2one(
+            'account.bank.statement.line',
+            'Statement line', required=True),
+        'remote_account': fields.char(
+            'Account number', size=24, readonly=True),
+        # Partner values
+        'street': fields.char('Street', size=128),
+        'street2': fields.char('Street2', size=128),
+        'zip': fields.char('Zip', change_default=True, size=24),
+        'city': fields.char('City', size=128),
+        'state_id': fields.many2one("res.country.state", 'State'),
+        'country_id': fields.many2one('res.country', 'Country'),
+        'email': fields.char('Email', size=240),
+        'phone': fields.char('Phone', size=64),
+        'fax': fields.char('Fax', size=64),
+        'mobile': fields.char('Mobile', size=64),
+        }
+    
+    def create(self, cr, uid, vals, context=None):
+        """
+        Get default values from the transaction data 
+        on the statement line
+        """
+        if vals and vals.get('statement_line_id'):
+            statement_line_obj = self.pool.get('account.bank.statement.line')
+            statement_line = statement_line_obj.browse(
+                cr, uid, vals['statement_line_id'], context=context)
+            transaction = statement_line.import_transaction_id
+
+            if statement_line.partner_bank_id:
+                raise orm.except_orm(
+                    _('Error'),
+                    _('Statement line is already linked to a bank account '))
+            
+            if not(transaction and transaction.remote_owner
+                   and transaction.remote_account):
+                raise orm.except_orm(
+                    _('Error'),
+                    _('No transaction data on statement line'))
+
+            if 'supplier' not in vals and statement_line.amount < 0:
+                vals['supplier'] = True
+            if 'customer' not in vals and statement_line.amount > 0:
+                vals['customer'] = True
+
+            if not vals.get('street'):
+                vals['street'] = transaction.remote_owner_address
+            if not vals.get('street'):
+                vals['city'] = transaction.remote_owner_city
+            if not vals.get('country_id'):
+                vals['country_id'] = banktools.get_country_id(
+                    self.pool, cr, uid, transaction, context=context)
+            if not vals.get('name'):
+                vals['name'] = transaction.remote_owner
+            if not vals.get('remote_account'):
+                vals['remote_account'] = transaction.remote_account
+
+        return super(link_partner, self).create(
+            cr, uid, vals, context=context)
+            
+    def update_partner_values(self, cr, uid, wizard, values, context=None):
+        """
+        Updates the new partner values with the values from the wizard
+        
+        :param wizard: read record of wizard (with load='_classic_write')
+        :param values: the dictionary of partner values that will be updated
+        """
+        for field in ['name',
+                      'street', 
+                      'street2',
+                      'zip',
+                      'country_id',
+                      'state_id',
+                      'phone',
+                      'fax',
+                      'mobile',
+                      'email'
+                      ]:
+            if wizard[field]:
+                values[field] = wizard[field]
+        return True
+    
+    def link_partner(self, cr, uid, ids, context=None):
+        statement_line_obj = self.pool.get(
+            'account.bank.statement.line')
+        wiz = self.browse(cr, uid, ids[0], context=context)
+
+        if wiz.partner_id:
+            partner_id = wiz.partner_id.id
+        else:
+            wiz_read = self.read(
+                cr, uid, ids[0], context=context, load='_classic_write')
+            partner_fields = self.pool.get(
+                'res.partner')._columns.keys()
+            partner_vals = {
+                    'is_company': True,
+                    'type': 'default',
+                    }
+            self.update_partner_values(
+                cr, uid, wiz_read, partner_vals, context=context)
+            partner_id = self.pool.get('res.partner').create(
+                cr, uid, partner_vals, context=context)
+            
+        partner_bank_id = banktools.create_bank_account(
+            self.pool, cr, uid, partner_id,
+            wiz.remote_account, wiz.name,
+            wiz.street, wiz.city,
+            wiz.country_id and wiz.country_id.id or False,
+            bic=wiz.statement_line_id.import_transaction_id.remote_bank_bic,
+            context=context)
+
+        statement_line_ids = statement_line_obj.search(
+            cr, uid,
+            [('import_transaction_id.remote_account', '=', wiz.remote_account),
+             ('partner_bank_id', '=', False),
+             ('state', '=', 'draft')], context=context)
+        statement_line_obj.write(
+            cr, uid, statement_line_ids,
+            {'partner_bank_id': partner_bank_id,
+             'partner_id': partner_id}, context=context)
+
+        return {'type': 'ir.actions.act_window_close'}        
+
+    def create_act_window(self, cr, uid, ids, nodestroy=True, context=None):
+        """ 
+        Return a popup window for this model
+        """
+        if isinstance(ids, (int, long)):
+            ids = [ids]
+        return {
+            'name': self._description,
+            'view_type': 'form',
+            'view_mode': 'form',
+            'res_model': self._name,
+            'domain': [],
+            'context': context,
+            'type': 'ir.actions.act_window',
+            'target': 'new',
+            'res_id': ids[0],
+            'nodestroy': nodestroy,
+            }
+
+

=== added file 'account_banking/wizard/link_partner.xml'
--- account_banking/wizard/link_partner.xml	1970-01-01 00:00:00 +0000
+++ account_banking/wizard/link_partner.xml	2013-05-01 14:29:27 +0000
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+    <data>
+        <record model="ir.ui.view" id="link_partner_view">
+            <field name="name">Link partner wizard view</field>
+            <field name="type">form</field>
+            <field name="model">banking.link_partner</field>
+            <field name="arch" type="xml">
+                <form string="Link partner">
+                    <group colspan="4" col="6">
+                        <field name="name"
+                               attrs="{'readonly': [('partner_id', '!=', False)]}" />
+                        <field name="partner_id"/>
+                        <field name="remote_account" />
+                    </group>
+                    <group colspan="4"
+                           string="Address"
+                           attrs="{'invisible': [('partner_id', '!=', False)]}">
+                        <group colspan="2" col="2">
+                            <field name="street"/>
+                            <field name="street2"/>
+                            <field name="zip"/>
+                            <field name="city"/>
+                            <field name="country_id"/>
+                            <field name="state_id"/>
+                        </group>
+                        <group colspan="2" col="2">
+                            <field name="phone"/>
+                            <field name="fax"/>
+                            <field name="mobile"/>
+                            <field name="email" widget="email"/>
+                        </group>
+                    </group>
+                    <button icon="gtk-cancel" string="Cancel" special="cancel" />
+                    <button icon="gtk-ok" string="Create partner"
+                            name="link_partner" type="object"
+                            attrs="{'invisible': [('partner_id', '!=', False)]}"
+                            />
+                    <button icon="gtk-ok" string="Link existing partner"
+                            name="link_partner" type="object"
+                            attrs="{'invisible': [('partner_id', '==', False)]}"
+                            />
+                </form>
+            </field>
+        </record>
+    </data>
+</openerp>


Follow ups