support of ASV accounts
This commit is contained in:
parent
130cec8c5a
commit
d26bbc50a8
3 changed files with 77 additions and 14 deletions
|
|
@ -18,13 +18,14 @@
|
|||
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
|
||||
import re
|
||||
import hashlib
|
||||
import time
|
||||
|
||||
from weboob.browser import LoginBrowser, URL, need_login
|
||||
from weboob.exceptions import BrowserIncorrectPassword, ParseError
|
||||
from weboob.capabilities.bank import Account, TransferError
|
||||
|
||||
from .pages import AccountsList, LoginPage, TitrePage, TitreHistory,\
|
||||
TransferPage, TransferConfirmPage, BillsPage, StopPage
|
||||
TransferPage, TransferConfirmPage, BillsPage, StopPage, TitreDetails
|
||||
|
||||
|
||||
__all__ = ['IngBrowser']
|
||||
|
|
@ -52,6 +53,7 @@ class IngBrowser(LoginBrowser):
|
|||
transferpage = URL('/protected/pages/cc/transfer/transferManagement.jsf', TransferPage)
|
||||
dotransferpage = URL('/general\?command=DisplayDoTransferCommand', TransferPage)
|
||||
valtransferpage = URL('/protected/pages/cc/transfer/create/transferCreateValidation.jsf', TransferConfirmPage)
|
||||
titredetails = URL('/general\?command=display.*', TitreDetails)
|
||||
# CapBank-Market
|
||||
starttitre = URL('/general\?command=goToAccount&zone=COMPTE', TitrePage)
|
||||
titrepage = URL('https://bourse.ingdirect.fr/priv/portefeuille-TR.php', TitrePage)
|
||||
|
|
@ -226,7 +228,17 @@ class IngBrowser(LoginBrowser):
|
|||
"javax.faces.ViewState": account._jid,
|
||||
"cptnbr": account._id
|
||||
}
|
||||
self.accountspage.go(data=data)
|
||||
|
||||
# On ASV pages, data maybe not available.
|
||||
for i in range(4):
|
||||
time.sleep(2**i)
|
||||
self.accountspage.go(data=data)
|
||||
|
||||
if not self.page.has_error():
|
||||
break
|
||||
|
||||
if self.page.is_asv:
|
||||
return
|
||||
|
||||
self.starttitre.go()
|
||||
self.where = u"titre"
|
||||
|
|
@ -237,12 +249,15 @@ class IngBrowser(LoginBrowser):
|
|||
raise NotImplementedError()
|
||||
self.go_investments(account)
|
||||
|
||||
self.titrerealtime.go()
|
||||
if self.where == u'titre':
|
||||
self.titrerealtime.go()
|
||||
return self.page.iter_investments()
|
||||
|
||||
def get_history_titre(self, account):
|
||||
self.go_investments(account)
|
||||
self.titrehistory.go()
|
||||
|
||||
if self.where == u'titre':
|
||||
self.titrehistory.go()
|
||||
return self.page.iter_history()
|
||||
|
||||
############# CapBill #############
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
from .accounts_list import AccountsList
|
||||
from .accounts_list import AccountsList, TitreDetails
|
||||
from .login import LoginPage, StopPage
|
||||
from .transfer import TransferPage, TransferConfirmPage
|
||||
from .bills import BillsPage
|
||||
|
|
@ -28,6 +28,6 @@ from .titre import TitrePage, TitreHistory
|
|||
class AccountPrelevement(AccountsList):
|
||||
pass
|
||||
|
||||
__all__ = ['AccountsList', 'LoginPage',
|
||||
__all__ = ['AccountsList', 'LoginPage', 'TitreDetails',
|
||||
'AccountPrelevement', 'TransferPage', 'TransferConfirmPage',
|
||||
'BillsPage', 'StopPage', 'TitrePage', 'TitreHistory']
|
||||
|
|
|
|||
|
|
@ -20,13 +20,15 @@
|
|||
|
||||
from datetime import date, timedelta
|
||||
import datetime
|
||||
from decimal import Decimal
|
||||
import re
|
||||
|
||||
from weboob.capabilities.bank import Account
|
||||
from weboob.capabilities.bank import Account, Investment
|
||||
from weboob.capabilities.base import NotAvailable
|
||||
from weboob.browser.pages import HTMLPage, LoggedPage
|
||||
from weboob.browser.elements import ListElement, ItemElement, method
|
||||
from weboob.browser.filters.standard import CleanText, CleanDecimal, Filter, Field, MultiFilter, Date, Lower
|
||||
from weboob.browser.filters.standard import CleanText, CleanDecimal, Filter, Field, MultiFilter, \
|
||||
Date, Lower, Regexp, Async, AsyncLoad, Slugify
|
||||
from weboob.browser.filters.html import Attr
|
||||
from weboob.tools.capabilities.bank.transactions import FrenchTransaction
|
||||
|
||||
|
|
@ -57,7 +59,8 @@ class AddPref(MultiFilter):
|
|||
class AddType(Filter):
|
||||
types = {u'Courant': Account.TYPE_CHECKING, u'Livret A': Account.TYPE_SAVINGS,
|
||||
u'Orange': Account.TYPE_SAVINGS, u'Durable': Account.TYPE_SAVINGS,
|
||||
u'Titres': Account.TYPE_MARKET, u'PEA': Account.TYPE_MARKET}
|
||||
u'Titres': Account.TYPE_MARKET, u'PEA': Account.TYPE_MARKET,
|
||||
u'Direct Vie': Account.TYPE_MARKET}
|
||||
|
||||
def filter(self, label):
|
||||
for key, acc_type in self.types.items():
|
||||
|
|
@ -112,9 +115,10 @@ class INGCategory(Filter):
|
|||
|
||||
|
||||
class AccountsList(LoggedPage, HTMLPage):
|
||||
def __init__(self, browser, response, *args, **kwargs):
|
||||
super(AccountsList, self).__init__(browser, response, *args, **kwargs)
|
||||
self.i = 0
|
||||
i = 0
|
||||
|
||||
def has_error(self):
|
||||
return self.doc.xpath('//div[has-class("alert-warning")]') > 0
|
||||
|
||||
@method
|
||||
class get_list(ListElement):
|
||||
|
|
@ -166,8 +170,7 @@ class AccountsList(LoggedPage, HTMLPage):
|
|||
item_xpath = '//table'
|
||||
|
||||
def get_history_jid(self):
|
||||
span = self.doc.xpath('//span[@id="index:panelASV"]')
|
||||
if len(span) > 1:
|
||||
if self.is_asv:
|
||||
# Assurance Vie, we do not support this kind of account.
|
||||
return None
|
||||
|
||||
|
|
@ -182,3 +185,48 @@ class AccountsList(LoggedPage, HTMLPage):
|
|||
|
||||
nomore = self.doc.getroot().cssselect('.no-more-transactions')
|
||||
return (len(nomore) > 0)
|
||||
|
||||
@property
|
||||
def is_asv(self):
|
||||
span = self.doc.xpath('//span[@id="index:panelASV"]')
|
||||
return len(span) > 0
|
||||
|
||||
@method
|
||||
class iter_investments(ListElement):
|
||||
item_xpath = '//div[has-class("asv_fond")]'
|
||||
|
||||
class item(ItemElement):
|
||||
klass = Investment
|
||||
|
||||
# ASV.popup('/general?command=displayAVEuroEpargne')
|
||||
load_details = Attr('.//div[has-class("asv_fond_view")]//a', 'onclick') & Regexp(pattern="'(.*)'") & AsyncLoad
|
||||
|
||||
obj_label = CleanText('.//span[has-class("asv_cat_lbl")]')
|
||||
# XXX I would like to do that... but 1. CleanText doesn't deal with default 2. default values can't be filters yet
|
||||
#obj_code = Async('details') & CleanText('//li[contains(text(), "Code ISIN")]/span') | (Field('label') & Format('XX%s', Slugify))
|
||||
obj_code = Async('details') & CleanText('//li[contains(text(), "Code ISIN")]/span')
|
||||
obj_id = obj_code
|
||||
obj_description = Async('details') & CleanText('//h5')
|
||||
obj_quantity = CleanDecimal('.//dl[contains(dt/text(), "Nombre de parts")]/dd', replace_dots=True)
|
||||
obj_unitvalue = CleanDecimal('.//dl[contains(dt/text(), "Valeur de part")]/dd', replace_dots=True)
|
||||
obj_valuation = CleanDecimal('.//dl[has-class("ligne-montant")]/dd', replace_dots=True)
|
||||
|
||||
def obj_unitprice(self):
|
||||
if 'eurossima' in self.el.get('class'):
|
||||
return self.obj.unitvalue
|
||||
|
||||
percent = CleanDecimal('.//dl[has-class("ligne-pmvalue")]/dd', replace_dots=True)(self)
|
||||
return (self.obj.unitvalue / (1 + percent/Decimal('100.0'))).quantize(Decimal('1.00'))
|
||||
|
||||
def obj_diff(self):
|
||||
return (self.obj.valuation - (self.obj.quantity * self.obj.unitprice)).quantize(Decimal('1.00'))
|
||||
|
||||
def validate(self, obj):
|
||||
if not obj.id:
|
||||
obj.id = obj.code = 'XX' + Slugify(self.obj_label)(self)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
class TitreDetails(LoggedPage, HTMLPage):
|
||||
pass
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue