bnporc implements transfers (closes #416)

This commit is contained in:
Romain Bignon 2010-10-31 10:26:44 +01:00
commit e973525b50
4 changed files with 119 additions and 7 deletions

View file

@ -16,7 +16,7 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
from weboob.capabilities.bank import ICapBank, AccountNotFound from weboob.capabilities.bank import ICapBank, AccountNotFound, Account
from weboob.tools.backend import BaseBackend from weboob.tools.backend import BaseBackend
from weboob.tools.value import ValuesDict, Value from weboob.tools.value import ValuesDict, Value
@ -67,6 +67,7 @@ class BNPorcBackend(BaseBackend, ICapBank):
except ValueError: except ValueError:
raise AccountNotFound() raise AccountNotFound()
else: else:
with self.browser:
account = self.browser.get_account(_id) account = self.browser.get_account(_id)
if account: if account:
return account return account
@ -74,9 +75,25 @@ class BNPorcBackend(BaseBackend, ICapBank):
raise AccountNotFound() raise AccountNotFound()
def iter_history(self, account): def iter_history(self, account):
with self.browser:
for history in self.browser.get_history(account): for history in self.browser.get_history(account):
yield history yield history
def iter_operations(self, account): def iter_operations(self, account):
with self.browser:
for coming in self.browser.get_coming_operations(account): for coming in self.browser.get_coming_operations(account):
yield coming yield coming
def transfer(self, account, to, amount, reason=None):
if isinstance(account, Account):
account = account.id
try:
account = long(account)
to = long(to)
amount = float(amount)
except ValueError:
raise AccountNotFound()
with self.browser:
return self.browser.transfer(account, to, amount, reason)

View file

@ -16,9 +16,11 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
from datetime import datetime
from logging import warning from logging import warning
from weboob.tools.browser import BaseBrowser, BrowserIncorrectPassword from weboob.tools.browser import BaseBrowser, BrowserIncorrectPassword
from weboob.capabilities.bank import TransferError, Transfer
from weboob.backends.bnporc import pages from weboob.backends.bnporc import pages
from .errors import PasswordExpired from .errors import PasswordExpired
@ -35,6 +37,9 @@ class BNPorc(BaseBrowser):
'.*Action=SAF_CHM.*': pages.ChangePasswordPage, '.*Action=SAF_CHM.*': pages.ChangePasswordPage,
'.*NS_AVEET.*': pages.AccountComing, '.*NS_AVEET.*': pages.AccountComing,
'.*NS_AVEDP.*': pages.AccountPrelevement, '.*NS_AVEDP.*': pages.AccountPrelevement,
'.*NS_VIRDF.*': pages.TransferPage,
'.*NS_VIRDC.*': pages.TransferConfirmPage,
'.*/NS_VIRDA\?stp=(?P<id>\d+).*': pages.TransferCompletePage,
'.*Action=DSP_VGLOBALE.*': pages.LoginPage, '.*Action=DSP_VGLOBALE.*': pages.LoginPage,
'.*type=homeconnex.*': pages.LoginPage, '.*type=homeconnex.*': pages.LoginPage,
'.*layout=HomeConnexion.*': pages.ConfirmPage, '.*layout=HomeConnexion.*': pages.ConfirmPage,
@ -120,3 +125,19 @@ class BNPorc(BaseBrowser):
if not self.is_on_page(pages.AccountComing) or self.page.account.id != account.id: if not self.is_on_page(pages.AccountComing) or self.page.account.id != account.id:
self.location('/NS_AVEET?ch4=%s' % account.link_id) self.location('/NS_AVEET?ch4=%s' % account.link_id)
return self.page.get_operations() return self.page.get_operations()
def transfer(self, from_id, to_id, amount, reason=None):
if not self.is_on_page(pages.TransferPage):
self.location('/NS_VIRDF')
self.page.transfer(from_id, to_id, amount, reason)
if not self.is_on_page(pages.TransferCompletePage):
raise TransferError('An error occured during transfer')
transfer = Transfer(self.page.get_id())
transfer.amount = amount
transfer.origin = from_id
transfer.recipient = to_id
transfer.date = datetime.now()
return transfer

View file

@ -19,9 +19,11 @@
from .accounts_list import AccountsList from .accounts_list import AccountsList
from .account_coming import AccountComing from .account_coming import AccountComing
from .account_history import AccountHistory from .account_history import AccountHistory
from .transfer import TransferPage, TransferConfirmPage, TransferCompletePage
from .login import LoginPage, ConfirmPage, ChangePasswordPage from .login import LoginPage, ConfirmPage, ChangePasswordPage
class AccountPrelevement(AccountsList): pass class AccountPrelevement(AccountsList): pass
__all__ = ['AccountsList', 'AccountComing', 'AccountHistory', 'LoginPage', __all__ = ['AccountsList', 'AccountComing', 'AccountHistory', 'LoginPage',
'ConfirmPage', 'AccountPrelevement', 'ChangePasswordPage'] 'ConfirmPage', 'AccountPrelevement', 'ChangePasswordPage',
'TransferPage', 'TransferConfirmPage', 'TransferCompletePage']

View file

@ -0,0 +1,72 @@
# -*- coding: utf-8 -*-
# Copyright(C) 2010 Romain Bignon
#
# 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, version 3 of the License.
#
# 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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
import re
from weboob.tools.browser import BasePage
from weboob.capabilities.bank import TransferError
__all__ = ['TransferPage', 'TransferConfirmPage', 'TransferCompletePage']
class TransferPage(BasePage):
def transfer(self, from_id, to_id, amount, reason):
self.browser.select_form(nr=0)
from_found = False
to_found = False
for table in self.document.getiterator('table'):
if table.attrib.get('cellspacing') == '2':
for tr in table.cssselect('tr.hdoc1, tr.hdotc1'):
tds = tr.findall('td')
id = long(tds[1].text.replace(u'\xa0', u''))
if id == from_id:
if tds[4].find('input') is None:
raise TransferError("Unable to make a transfer from %s" % from_id)
self.browser['C1'] = [tds[4].find('input').attrib['value']]
from_found = True
elif id == to_id:
if tds[5].find('input') is None:
raise TransferError("Unable to make a transfer to %s" % from_id)
self.browser['C2'] = [tds[5].find('input').attrib['value']]
to_found = True
if not from_found:
raise TransferError('Account %s not found' % from_id)
if not to_found:
raise TransferError('Recipient %s not found' % to_id)
self.browser['T6'] = str(amount).replace('.', ',')
if reason:
self.browser['T5'] = reason
self.browser.submit()
class TransferConfirmPage(BasePage):
def on_loaded(self):
for td in self.document.getroot().cssselect('td#size2'):
raise TransferError(td.text.strip())
for a in self.document.getiterator('a'):
m = re.match('/NSFR\?Action=VIRDA&stp=(\d+)', a.attrib['href'])
if m:
self.browser.location('/NS_VIRDA?stp=%s' % m.group(1))
return
class TransferCompletePage(BasePage):
def get_id(self):
return self.group_dict['id']