Commit c93255ef authored by Vincent Ardisson's avatar Vincent Ardisson Committed by Romain Bignon

[bforbank] use spirica for life insurance

TODO: use PARENT
parent 1121988f
......@@ -22,7 +22,11 @@ from weboob.exceptions import BrowserIncorrectPassword
from weboob.browser import LoginBrowser, URL, need_login
from weboob.capabilities.bank import Account
from .pages import LoginPage, ErrorPage, AccountsPage, HistoryPage, LoanHistoryPage, RibPage
from .pages import (
LoginPage, ErrorPage, AccountsPage, HistoryPage, LoanHistoryPage, RibPage,
LifeInsuranceIframe, LifeInsuranceRedir
)
from .spirica.browser import SpiricaBrowser
class BforbankBrowser(LoginBrowser):
......@@ -35,12 +39,16 @@ class BforbankBrowser(LoginBrowser):
'/espace-client/rib/(?P<id>\d+)', RibPage)
loan_history = URL('/espace-client/livret/consultation.*', LoanHistoryPage)
history = URL('/espace-client/consultation/operations/.*', HistoryPage)
lifeinsurance_iframe = URL(r'/client/accounts/lifeInsurance/consultationDetailSpirica.action', LifeInsuranceIframe)
lifeinsurance_redir = URL(r'https://assurance-vie.bforbank.com:443/sylvea/welcomeSSO.xhtml', LifeInsuranceRedir)
def __init__(self, birthdate, *args, **kwargs):
super(BforbankBrowser, self).__init__(*args, **kwargs)
self.birthdate = birthdate
self.accounts = None
self.spirica = SpiricaBrowser('https://assurance-vie.bforbank.com:443/', None, None)
def do_login(self):
assert isinstance(self.username, basestring)
assert isinstance(self.password, basestring)
......@@ -62,7 +70,33 @@ class BforbankBrowser(LoginBrowser):
@need_login
def get_history(self, account):
if account.type == Account.TYPE_MARKET or account.type == Account.TYPE_LIFE_INSURANCE:
if account.type == Account.TYPE_MARKET:
raise NotImplementedError()
elif account.type == Account.TYPE_LIFE_INSURANCE:
self.goto_spirica(account)
return self.spirica.iter_history(account)
self.location(account._link.replace('tableauDeBord', 'operations'))
return self.page.get_operations()
def goto_spirica(self, account):
assert account.type == Account.TYPE_LIFE_INSURANCE
self.home.stay_or_go() # make sure we are on the right domain
self.location('/client/accounts/lifeInsurance/lifeInsuranceSummary.action')
assert self.lifeinsurance_iframe.is_here()
self.location(self.page.get_iframe())
assert self.lifeinsurance_redir.is_here()
redir = self.page.get_redir()
assert redir
account._link = self.absurl(redir)
self.spirica.session.cookies.update(self.session.cookies)
self.spirica.logged = True
@need_login
def iter_investment(self, account):
if account.type == Account.TYPE_LIFE_INSURANCE:
self.goto_spirica(account)
return self.spirica.iter_investment(account)
raise NotImplementedError()
......@@ -60,4 +60,4 @@ class BforbankModule(Module, CapBank):
return self.browser.get_history(account)
def iter_investment(self, account):
raise NotImplementedError()
return self.browser.iter_investment(account)
......@@ -192,3 +192,17 @@ class HistoryPage(LoggedPage, HTMLPage):
obj_raw = Transaction.Raw('./td[1]')
obj_amount = MyDecimal('./td[2]', replace_dots=True)
class LifeInsuranceIframe(LoggedPage, HTMLPage):
def get_iframe(self):
return Attr(None, 'src').filter(self.doc.xpath('//iframe[@id="iframePartenaire"]'))
class LifeInsuranceRedir(LoggedPage, HTMLPage):
def get_redir(self):
# meta http-equiv redirection...
for meta in self.doc.xpath('//meta[@http-equiv="Refresh"]/@content'):
match = re.search(r'URL=([^\s"\']+)', meta)
if match:
return match.group(1)
../../spirica/browser.py
\ No newline at end of file
../../spirica/pages.py
\ No newline at end of file
......@@ -118,6 +118,11 @@ class TableTransactionsInvestment(TableInvestment):
obj_code = Regexp(CleanText(TableCell('code')), pattern='([A-Z]{2}\d{10})', default=NotAvailable)
class ProfileTableInvestment(TableInvestment):
# used only when portfolio is divided in multiple "profiles"
head_xpath = '//thead[ends-with(@id, ":contratProfilTable_head")]/tr/th'
class DetailsPage(LoggedPage, HTMLPage):
DEBIT_WORDS = [u'arrêté', 'rachat', 'frais', u'désinvestir']
......@@ -131,8 +136,8 @@ class DetailsPage(LoggedPage, HTMLPage):
@method
class iter_investment(TableInvestment):
item_xpath = '//div[contains(@id, "INVESTISSEMENT")]//table/tbody/tr[@data-ri]'
head_xpath = '//div[contains(@id, "INVESTISSEMENT")]//table/thead/tr/th'
item_xpath = '//div[contains(@id,"INVESTISSEMENT")]//div[ends-with(@id, ":tableDetailSituationCompte")]//table/tbody/tr[@data-ri]'
head_xpath = '//div[contains(@id,"INVESTISSEMENT")]//div[ends-with(@id, ":tableDetailSituationCompte")]//table/thead/tr/th'
col_valuation = re.compile('Contre')
......@@ -147,6 +152,27 @@ class DetailsPage(LoggedPage, HTMLPage):
return MyDecimal('//div[contains(@id, "PRIX_REVIENT")]//a[contains(text(), \
"%s")]/ancestor::tr/td[6]' % Field('label')(self))(self)
def obj_portfolio_share(self):
inv_share = ItemInvestment.obj_portfolio_share(self)
if self.xpath('ancestor::tbody[ends-with(@id, "contratProfilTable_data")]'):
# investments are nested in profiles, row share is relative to profile share
profile_table_el = self.xpath('ancestor::tr/ancestor::table[position() = 1]')[0]
profile_table = ProfileTableInvestment(self.page, self, profile_table_el)
share_idx = profile_table.get_colnum('portfolio_share')
assert share_idx
curr_profile_el = self.xpath('ancestor::tr/preceding-sibling::tr[@data-ri][position() = 1]')[0]
share_el = curr_profile_el.xpath('./td[%d]' % (share_idx + 1))
path = 'ancestor::tr/preceding-sibling::tr[@data-ri][position() = 1][1]/td[%d]' % (share_idx + 1)
profile_share = MyDecimal(path)(self)
assert profile_share
#raise Exception('dtc')
profile_share = Eval(lambda x: x / 100, profile_share)(self)
return inv_share * profile_share
else:
return inv_share
def get_historytab_form(self):
form = self.get_form('//form[contains(@id, "j_idt")]')
idt = Attr(None, 'name').filter(self.doc.xpath('//input[contains(@name, "j_idt") \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment