add investments to bnporc module

This commit is contained in:
smurail 2015-04-29 18:00:40 +02:00 committed by Romain Bignon
commit 18c1df1502
4 changed files with 136 additions and 6 deletions

View file

@ -21,12 +21,14 @@
import urllib
from datetime import datetime
from logging import warning
from random import randint
from weboob.deprecated.browser import Browser, BrowserIncorrectPassword, BrowserPasswordExpired
from weboob.capabilities.bank import TransferError, Transfer
from weboob.capabilities.bank import TransferError, Transfer, Account
from .perso.accounts_list import AccountsList, AccountPrelevement
from .perso.transactions import AccountHistory, AccountComing
from .perso.investment import AccountMarketInvestment, AccountLifeInsuranceInvestment
from .perso.transfer import TransferPage, TransferConfirmPage, TransferCompletePage
from .perso.login import LoginPage, ConfirmPage, ChangePasswordPage, InfoMessagePage
from .perso.messages import MessagePage, MessagesPage
@ -44,6 +46,8 @@ class BNPorc(Browser):
PAGES = {'.*pageId=unedescomptes.*': AccountsList,
'.*pageId=releveoperations.*': AccountHistory,
'.*FicheA': AccountHistory,
'.*SAF_DPF.*': AccountMarketInvestment,
'.*identifiant=Assurance_Vie_Consultation.*': AccountLifeInsuranceInvestment,
'.*Action=SAF_CHM.*': ChangePasswordPage,
'.*pageId=mouvementsavenir.*': AccountComing,
'.*NS_AVEDP.*': AccountPrelevement,
@ -229,6 +233,35 @@ class BNPorc(Browser):
return self.page.iter_coming_operations()
def iter_investment(self, account):
if account.type == Account.TYPE_MARKET:
if not account.iban:
return iter([])
stp = datetime.strftime(datetime.now(), '%Y%m%d%H%M%S')
self.location('https://www.secure.bnpparibas.net/SAF_DPF?Origine=DSP_DPF&ch4=' + account.iban + 'stp=' + stp)
data = {'ch4': account.iban,
'Origine': 'DSP_DPF',
'chD': 'oui',
'chT': 'sans',
'chU': 'alpha',
'x': randint(0, 99),
'y': randint(0, 18)
}
self.location('https://www.secure.bnpparibas.net/SAF_DPF', urllib.urlencode(data))
elif account.type == Account.TYPE_LIFE_INSURANCE:
if not account._link_id:
return iter([])
self.location('https://www.secure.bnpparibas.net/banque/portail/particulier/Fiche?type=folder&identifiant=Assurance_Vie_Consultation_20071002051044&contrat=' + account._link_id)
else:
raise NotImplementedError()
return self.page.iter_investment()
@check_expired_password
def get_transfer_accounts(self):
if not self.is_on_page(TransferPage):

View file

@ -101,6 +101,10 @@ class BNPorcModule(Module, CapBank, CapMessages):
with self.browser:
return self.browser.iter_coming_operations(account)
def iter_investment(self, account):
with self.browser:
return self.browser.iter_investment(account)
def iter_transfer_recipients(self, ignored):
if self.config['website'].get() != 'pp':
raise NotImplementedError()

View file

@ -32,7 +32,7 @@ class AccountsList(Page):
u'Liquidités': Account.TYPE_CHECKING,
u'Epargne disponible': Account.TYPE_SAVINGS,
u'Titres': Account.TYPE_MARKET,
u'Assurance vie': Account.TYPE_DEPOSIT,
u'Assurance vie': Account.TYPE_LIFE_INSURANCE,
u'Crédit immobilier': Account.TYPE_LOAN,
}
@ -77,10 +77,15 @@ class AccountsList(Page):
if m:
account._link_id = m.group(1)
else:
# Can't get history for this account.
account._link_id = None
# To prevent multiple-IDs for CIF (for example), add an arbitrary char in ID.
account.id += 'C'
# Find _link_id of life insurances
m = re.match(r'javascript:overviewRedirectionOperation.*contrat=(\d+)', a.get('onclick', ''))
if m:
account._link_id = m.group(1)
else:
# Can't get history for this account.
account._link_id = None
# To prevent multiple-IDs for CIF (for example), add an arbitrary char in ID.
account.id += 'C'
account.label = u''+a.text.strip()

View file

@ -0,0 +1,88 @@
# -*- coding: utf-8 -*-
# Copyright(C) 2009-2012 Romain Bignon
#
# This file is part of weboob.
#
# weboob is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# weboob 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
import re
from decimal import Decimal
from xml.etree import ElementTree
from weboob.deprecated.browser import Page
from weboob.capabilities.bank import Investment
from weboob.tools.capabilities.bank.transactions import FrenchTransaction
from weboob.capabilities.base import NotAvailable
def clean_text(el):
text = ElementTree.tostring(el, 'utf-8', 'text').decode('utf-8')
return re.sub(ur'[\s\xa0]+', u' ', text).strip()
def clean_cells(cells):
return list(map(clean_text, cells))
def clean_amount(amount):
return Decimal(FrenchTransaction.clean_amount(amount)) if amount else NotAvailable
def clean_amounts(amounts):
return list(map(clean_amount, amounts))
class AccountMarketInvestment(Page):
def iter_investment(self):
table = self.document.xpath('//table[@align="center"]')[4]
rows = table.xpath('.//tr[@class="hdoc1"]')
for tr in rows:
cells = clean_cells(tr.findall('td'))
cells[2:] = clean_amounts(cells[2:])
inv = Investment()
inv.label, _, inv.quantity, inv.unitvalue, inv.valuation = cells
tr2 = tr.xpath('./following-sibling::tr')[0]
tr2td = tr2.findall('td')[1]
inv.id = inv.code = clean_text(tr2.xpath('.//a')[0])
inv.unitprice = clean_amount(tr2td.xpath('.//td[@class="hdotc1nb"]')[0].text)
inv.description = u''
inv.diff = inv.quantity * inv.unitprice - inv.valuation
yield inv
class AccountLifeInsuranceInvestment(Page):
def iter_investment(self):
rows = self.document.xpath('//table[@id="mefav_repartition_supports_BPF"]//tr')
for tr in rows:
cells = clean_cells(tr.findall('td'))
cells[3:] = clean_amounts(cells[3:])
inv = Investment()
inv.label, _, inv.code, inv.quantity, inv.unitvalue, inv.valuation, _ = cells
if inv.code:
inv.id = inv.code
if not inv.unitvalue:
# XXX Fonds eu Euros
inv.code = u'XX' + re.sub(ur'[^A-Za-z0-9]', u'', inv.label).upper()
inv.description = u''
yield inv