Skip to content
Commits on Source (35)
......@@ -55,6 +55,10 @@ def on_load(self):
if "prendre connaissance des nouvelles conditions" in msg:
raise ActionNeeded(msg)
msg = CleanText('//span[@id="txtErrorAccesBase"]')(self.doc)
if 'Merci de nous envoyer' in msg:
raise ActionNeeded(msg)
# website sometime crash
if self.doc.xpath(u'//div[@id="divError"]/span[contains(text(),"Une erreur est survenue")]'):
raise BrowserUnavailable()
......
......@@ -71,7 +71,7 @@ def __init__(self, config, *args, **kwargs):
super(AmazonBrowser, self).__init__(*args, **kwargs)
def locate_browser(self, state):
pass
self.location(state['url'])
def push_security_otp(self, pin_code):
res_form = self.otp_form
......@@ -181,11 +181,12 @@ def iter_subscription(self):
@need_login
def iter_documents(self, subscription):
documents = []
for y in range(date.today().year - 2, date.today().year + 1):
self.documents.go(year=y)
year = date.today().year
old_year = year - 2
while year >= old_year:
self.documents.go(year=year)
request_id = self.page.response.headers['x-amz-rid']
for doc in self.page.iter_documents(subid=subscription.id, currency=self.CURRENCY, request_id=request_id):
documents.append(doc)
return documents
yield doc
year -= 1
......@@ -20,11 +20,10 @@
from __future__ import unicode_literals
from collections import OrderedDict
from weboob.capabilities.bill import CapDocument, Subscription, Document, SubscriptionNotFound, DocumentNotFound
from weboob.capabilities.bill import DocumentTypes, CapDocument, Subscription, Document, SubscriptionNotFound, DocumentNotFound
from weboob.capabilities.base import find_object, NotAvailable
from weboob.tools.backend import Module, BackendConfig
from weboob.tools.value import ValueBackendPassword, Value
from weboob.tools.pdf import html_to_pdf
from .browser import AmazonBrowser
from .en.browser import AmazonEnBrowser
......@@ -64,6 +63,8 @@ class AmazonModule(Module, CapDocument):
Value('pin_code', label='OTP response', required=False, default='')
)
accepted_document_types = (DocumentTypes.BILL,)
def create_default_browser(self):
self.BROWSER = self.BROWSERS[self.config['website'].get()]
return self.create_browser(self.config)
......@@ -92,11 +93,3 @@ def download_document(self, document):
return
return self.browser.open(document.url).content
def download_document_pdf(self, document):
if not isinstance(document, Document):
document = self.get_document(document)
if document.url is NotAvailable:
return
return html_to_pdf(self.browser, url=self.browser.BASEURL + document.url)
......@@ -26,7 +26,7 @@
CleanText, CleanDecimal, Env, Regexp, Format,
Field, Currency, RegexpError, Date, Async, AsyncLoad
)
from weboob.capabilities.bill import Bill, Subscription
from weboob.capabilities.bill import DocumentTypes, Bill, Subscription
from weboob.capabilities.base import NotAvailable
from weboob.tools.date import parse_french_date
......@@ -131,7 +131,7 @@ class item(ItemElement):
obj_url = Async('details') & Link('//a[contains(@href, "download")]|//a[contains(@href, "generated_invoices")]')
obj_format = 'pdf'
obj_label = Format('Facture %s', Field('_simple_id'))
obj_type = 'bill'
obj_type = DocumentTypes.BILL
def obj_date(self):
date = Date(CleanText('.//div[has-class("a-span4") and not(has-class("recipient"))]/div[2]'),
......
......@@ -19,7 +19,7 @@
from __future__ import unicode_literals
from weboob.capabilities.bill import CapDocument, SubscriptionNotFound, DocumentNotFound, Subscription, Bill
from weboob.capabilities.bill import DocumentTypes, CapDocument, SubscriptionNotFound, DocumentNotFound, Subscription, Bill
from weboob.tools.backend import Module, BackendConfig
from weboob.tools.value import ValueBackendPassword
from .browser import AmeliBrowser
......@@ -38,6 +38,8 @@ class AmeliModule(Module, CapDocument):
CONFIG = BackendConfig(ValueBackendPassword('login', label='Numero de SS', regexp=r'^\d{13}$', masked=False),
ValueBackendPassword('password', label='Password', masked=True))
accepted_document_types = (DocumentTypes.BILL,)
def create_default_browser(self):
return self.create_browser(self.config['login'].get(),
self.config['password'].get())
......
......@@ -25,7 +25,7 @@
from weboob.browser.filters.html import Attr, XPathNotFound
from weboob.browser.pages import HTMLPage, RawPage, LoggedPage
from weboob.capabilities.bill import Subscription, Detail, Bill
from weboob.capabilities.bill import DocumentTypes, Subscription, Detail, Bill
from weboob.browser.filters.standard import CleanText, Regexp
from weboob.exceptions import BrowserUnavailable
......@@ -132,7 +132,7 @@ def iter_documents(self, sub):
bil.id = sub._id + "." + date.strftime("%Y%m")
bil.date = date
bil.format = 'pdf'
bil.type = 'bill'
bil.type = DocumentTypes.BILL
bil.label = date.strftime("%Y%m%d")
bil.url = '/PortailAS/PDFServletReleveMensuel.dopdf?PDF.moisRecherche=' + date.strftime("%m%Y")
yield bil
......
......@@ -17,7 +17,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
from weboob.capabilities.bill import CapDocument, SubscriptionNotFound, DocumentNotFound, Subscription, Bill
from weboob.capabilities.bill import DocumentTypes, CapDocument, SubscriptionNotFound, DocumentNotFound, Subscription, Bill
from weboob.tools.backend import Module, BackendConfig
from weboob.tools.value import ValueBackendPassword
from .browser import AmeliProBrowser
......@@ -40,6 +40,8 @@ class AmeliProModule(Module, CapDocument):
masked=True)
)
accepted_document_types = (DocumentTypes.BILL,)
def create_default_browser(self):
self.logger.settings['save_responses'] = False # Set to True to help debugging
return self.create_browser(self.config['login'].get(),
......
......@@ -22,7 +22,7 @@
import re
from decimal import Decimal
from weboob.browser.pages import HTMLPage
from weboob.capabilities.bill import Subscription, Detail, Bill
from weboob.capabilities.bill import DocumentTypes, Subscription, Detail, Bill
# Ugly array to avoid the use of french locale
......@@ -111,7 +111,7 @@ def iter_documents(self):
bil.price = 0
bil.label = u''+date.strftime("%Y%m%d")
bil.format = u''+format
bil.type = u'bill'
bil.type = DocumentTypes.BILL
filedate = date.strftime("%m%Y")
bil.url = u'/PortailPS/fichier.do'
bil._data = {'FICHIER.type': format.lower()+'.releveCompteMensuel',
......
......@@ -111,6 +111,7 @@ def iter_accounts(self):
acc._idforJSON = account_data[10][-1]
else:
acc._idforJSON = account_data[-5][-1]
acc._idforJSON = re.sub('\s+', ' ', acc._idforJSON)
acc.number = '-%s' % account_data[2][2]
acc.label = '%s %s' % (account_data[6][4], account_data[10][-1])
acc._balances_token = acc.id = balances_token
......
......@@ -29,7 +29,8 @@
from .pages import (
LoginPage, AccountsPage, AccountPage, MarketAccountPage,
LifeInsuranceAccountPage, CardPage, IbanPDFPage,
LifeInsuranceAccountPage, CardPage, IbanPDFPage, ActionNeededPage,
RevolvingAccountPage, LoanAccountPage,
)
......@@ -41,10 +42,13 @@ class Barclays(LoginBrowser):
login = URL('/BconnectDesk/servletcontroller', LoginPage)
accounts = URL('/BconnectDesk/servletcontroller', AccountsPage)
loan_account = URL('/BconnectDesk/servletcontroller', LoanAccountPage)
account = URL('/BconnectDesk/servletcontroller', AccountPage)
card_account = URL('/BconnectDesk/servletcontroller', CardPage)
market_account = URL('/BconnectDesk/servletcontroller', MarketAccountPage)
life_insurance_account = URL('/BconnectDesk/servletcontroller', LifeInsuranceAccountPage)
revolving_account = URL('/BconnectDesk/servletcontroller', RevolvingAccountPage)
actionNeededPage = URL('/BconnectDesk/servletcontroller', ActionNeededPage)
iban = URL('/BconnectDesk/editique', IbanPDFPage)
def __init__(self, secret, *args, **kwargs):
......@@ -127,8 +131,9 @@ def iter_accounts(self):
traccounts = []
for account in accounts:
if account.type != Account.TYPE_LOAN:
self._go_to_account(account)
self._go_to_account(account)
if account.type == Account.TYPE_LOAN:
account = self.page.get_loan_attributes(account)
if account.type == Account.TYPE_CARD:
if self.page.is_immediate_card():
......@@ -138,6 +143,8 @@ def iter_accounts(self):
continue
account._attached_account = self.page.do_account_attachment([a for a in accounts if a.type == Account.TYPE_CHECKING])
if account.type == Account.TYPE_REVOLVING_CREDIT:
account = self.page.get_revolving_attributes(account)
account.iban = self.iban.open().get_iban() if self.page.has_iban() else NotAvailable
......@@ -151,7 +158,7 @@ def iter_accounts(self):
def iter_history(self, account):
if account._multiple_type and not self._multiple_account_choice(account):
return []
elif account.type == Account.TYPE_LOAN:
elif account.type in (Account.TYPE_LOAN, Account.TYPE_REVOLVING_CREDIT):
return []
self._go_to_account(account)
......
......@@ -21,16 +21,14 @@
import re
from six.moves.html_parser import HTMLParser
from weboob.browser.pages import HTMLPage, PDFPage, LoggedPage
from weboob.browser.elements import TableElement, ListElement, ItemElement, method
from weboob.browser.filters.standard import CleanText, CleanDecimal, Regexp, Field, Date, Eval
from weboob.browser.filters.html import Attr, TableCell
from weboob.capabilities.bank import Account, Investment, NotAvailable
from weboob.browser.filters.html import Attr, TableCell, ReplaceEntities
from weboob.capabilities.bank import Account, Investment, Loan, NotAvailable
from weboob.tools.capabilities.bank.transactions import FrenchTransaction
from weboob.tools.capabilities.bank.iban import is_iban_valid
from weboob.exceptions import ActionNeeded
def MyDecimal(*args, **kwargs):
kwargs.update(replace_dots=True, default=NotAvailable)
......@@ -109,6 +107,8 @@ class AccountsPage(StatefulPage):
ACCOUNT_EXTRA_TYPES = {'BMOOVIE': Account.TYPE_LIFE_INSURANCE,
'B. GESTION VIE': Account.TYPE_LIFE_INSURANCE,
'E VIE MILLEIS': Account.TYPE_LIFE_INSURANCE,
'BANQUE PRIVILEGE': Account.TYPE_REVOLVING_CREDIT,
'PRET PERSONNEL': Account.TYPE_LOAN,
}
ACCOUNT_TYPE_TO_STR = {Account.TYPE_MARKET: 'TTR',
Account.TYPE_CARD: 'CRT'
......@@ -205,16 +205,6 @@ class Transaction(FrenchTransaction):
]
class Entities(CleanText):
"""
Filter to replace HTML entities like "&eacute;" or "&#x42;" with their unicode counterpart.
"""
def filter(self, data):
h = HTMLParser()
txt = super(Entities, self).filter(data)
return h.unescape(txt)
class AbstractAccountPage(StatefulPage):
def has_iban(self):
return len(self.doc.xpath('//a[contains(., "Edition RIB")]/ancestor::node()[2][not(contains(@style, "display: none;"))]')) > 1
......@@ -255,7 +245,7 @@ class item(ItemElement):
obj_date = Date(CleanText(TableCell('date')), dayfirst=True)
obj_vdate = Date(CleanText(TableCell('vdate')), dayfirst=True)
obj_amount = MyDecimal(TableCell('credit'), default=TableCell('debit'))
obj_raw = Transaction.Raw(Entities(Regexp(CleanText('.//script[1]'), r"toggleDetails\([^,]+,[^,]+, '(.*?)', '(.*?)', '(.*?)',", r'\1 \2 \3')))
obj_raw = Transaction.Raw(ReplaceEntities(Regexp(CleanText('.//script[1]'), r"toggleDetails\([^,]+,[^,]+, '(.*?)', '(.*?)', '(.*?)',", r'\1 \2 \3')))
class AccountPage(AbstractAccountPage):
......@@ -449,6 +439,64 @@ def get_space_attrs(self, space):
return (a[1], 'C4__WORKING[1].LISTCONTRATS', form['C4__WORKING[1].LISTCONTRATS'], a[2])
class RevolvingAccountPage(AbstractAccountPage):
def is_here(self):
return bool(CleanText('//span[contains(., "Crédit renouvelable")]')(self.doc))
def has_iban(self):
return False
def get_revolving_attributes(self, account):
loan = Loan()
loan.available_amount = CleanDecimal('//div/span[contains(text(), "Montant disponible")]/following-sibling::*[1]', replace_dots=True)(self.doc)
loan.used_amount = CleanDecimal('//div/span[contains(text(), "Montant Utilisé")]/following-sibling::*[1]', replace_dots=True)(self.doc)
loan.total_amount = CleanDecimal('//div/span[contains(text(), "Réserve accordée")]/following-sibling::*[1]', replace_dots=True)(self.doc)
loan.last_payment_amount = CleanDecimal('//div/span[contains(text(), "Echéance Précédente")]/following-sibling::*[1]', replace_dots=True)(self.doc)
loan.last_payment_date = Date(Regexp(CleanText('//div/span[contains(text(), "Echéance Précédente")]/following-sibling::*[2]'), r'(\d{2}\/\d{2}\/\d{4})'), dayfirst=True)(self.doc)
owner_name = CleanText('//a[@class="lien-entete login"]/span')(self.doc)
loan.name = ' '.join(owner_name.split()[1:])
loan.id = account.id
loan.currency = account.currency
loan.label = account.label
loan.balance = account.balance
loan.coming = account.coming
loan.type = account.type
loan._uncleaned_id = account._uncleaned_id
loan._multiple_type = account._multiple_type
return loan
class LoanAccountPage(AbstractAccountPage):
def is_here(self):
return bool(CleanText('//span[contains(., "Détail compte")]')(self.doc))
def has_iban(self):
return False
def get_loan_attributes(self, account):
loan = Loan()
loan.total_amount = CleanDecimal('//div/span[contains(text(), "Capital initial")]/following-sibling::*[1]', replace_dots=True)(self.doc)
owner_name = CleanText('//a[@class="lien-entete login"]/span')(self.doc)
loan.name = ' '.join(owner_name.split()[1:])
loan.subscription_date = Date(Regexp(CleanText('//h4[span[contains(text(), "Date de départ du prêt")]]'), r'(\d{2}\/\d{2}\/\d{4})'), dayfirst=True)(self.doc)
loan.maturity_date = Date(Regexp(CleanText('//h4[span[contains(text(), "Date de fin du prêt")]]'), r'(\d{2}\/\d{2}\/\d{4})'), dayfirst=True)(self.doc)
loan.rate = Eval(lambda x: x / 100, CleanDecimal('//div/span[contains(text(), "Taux fixe")]/following-sibling::*[1]', replace_dots=True))(self.doc)
loan.last_payment_amount = CleanDecimal('//div[@class="txt-detail " and not (@style)]//span[contains(text(), "Echéance du")]/following-sibling::span[1]')(self.doc)
loan.last_payment_date = Date(Regexp(CleanText('//div[@class="txt-detail " and not (@style)]//span[contains(text(), "Echéance du")]'), r'(\d{2}\/\d{2}\/\d{4})'), dayfirst=True)(self.doc)
loan.id = account.id
loan.currency = account.currency
loan.label = account.label
loan.balance = account.balance
loan.coming = account.coming
loan.type = account.type
loan._uncleaned_id = account._uncleaned_id
loan._multiple_type = account._multiple_type
return loan
class IbanPDFPage(LoggedPage, PDFPage):
def get_iban(self):
match = re.search(r'Tm \[\((FR[0-9]{2} [A-Z0-9 ]+)\)\]', self.doc.decode('ISO8859-1'))
......@@ -461,3 +509,15 @@ def get_iban(self):
assert is_iban_valid(iban)
return iban
class ActionNeededPage(LoggedPage, HTMLPage):
def on_load(self):
# We only need 2 sentences because the thirds is too specific
message = CleanText("//h2[contains(@class, 'ecDIB')]")(self.doc).split('.')
raise ActionNeeded('%s.' % '.'.join(message[:-2]))
def is_here(self):
message = CleanText("//h2[contains(@class, 'ecDIB')]")(self.doc)
text = "Afin de respecter nos obligations réglementaires, nous devons disposer d’une connaissance récente des données de nos clients."
return message and text in message
......@@ -343,7 +343,8 @@ class MarketPage(LoggedPage, HTMLPage):
@method
class iter_market_accounts(TableElement):
def condition(self):
return not self.el.xpath('//table[@id="table-portefeuille"]//tr/td[contains(text(), "Aucun portefeuille à afficher")]')
return not self.el.xpath('//table[@id="table-portefeuille"]//tr/td[contains(text(), "Aucun portefeuille à afficher") \
or contains(text(), "No portfolio to display")]')
item_xpath = '//table[@id="table-portefeuille"]/tbody[@class="main-content"]/tr'
head_xpath = '//table[@id="table-portefeuille"]/thead/tr/th/label'
......
......@@ -22,7 +22,7 @@
from datetime import timedelta, datetime
from weboob.browser import LoginBrowser, need_login, URL
from weboob.capabilities.bill import Document
from weboob.capabilities.bill import DocumentTypes, Document
from weboob.tools.capabilities.bank.investments import create_french_liquidity
from .pages import (
......@@ -97,6 +97,6 @@ def iter_documents(self):
doc.id = inv.id
doc.url = inv._docurl
doc.label = 'Contrat %s' % inv.label
doc.type = 'other'
doc.type = DocumentTypes.OTHER
doc.format = 'pdf'
yield doc
......@@ -26,6 +26,7 @@
from weboob.capabilities.base import find_object
from weboob.capabilities.bill import (
CapDocument, Subscription, SubscriptionNotFound, DocumentNotFound, Document,
DocumentTypes,
)
from weboob.capabilities.profile import CapProfile
......@@ -50,6 +51,8 @@ class BoldenModule(Module, CapBankWealth, CapDocument, CapProfile):
ValueBackendPassword('password', label='Mot de passe'),
)
accepted_document_types = (DocumentTypes.OTHER,)
def create_default_browser(self):
return self.create_browser(self.config['login'].get(), self.config['password'].get())
......
......@@ -36,7 +36,7 @@
from weboob.capabilities.contact import Advisor
from weboob.tools.captcha.virtkeyboard import VirtKeyboardError
from weboob.tools.value import Value
from weboob.tools.compat import basestring, urlsplit, urlunsplit
from weboob.tools.compat import basestring, urlsplit
from weboob.tools.capabilities.bank.transactions import sorted_transactions
from .pages import (
......@@ -45,7 +45,7 @@
CardsNumberPage, CalendarPage, HomePage, PEPPage,
TransferAccounts, TransferRecipients, TransferCharac, TransferConfirm, TransferSent,
AddRecipientPage, StatusPage, CardHistoryPage, CardCalendarPage, CurrencyListPage, CurrencyConvertPage,
AccountsErrorPage, NoAccountPage,
AccountsErrorPage, NoAccountPage, TransferMainPage,
)
......@@ -85,10 +85,11 @@ class BoursoramaBrowser(RetryLoginBrowser, StatesMixin):
saving_pep = URL('/compte/epargne/pep', PEPPage)
incident = URL('/compte/cav/(?P<webid>.*)/mes-incidents.*', IncidentPage)
transfer_accounts = URL(r'/compte/(?P<type>[^/]+)/(?P<webid>\w+)/virements/nouveau/(?P<id>\w+)/1',
r'/compte/(?P<type>[^/]+)/(?P<webid>\w+)/virements/nouveau$',
TransferAccounts)
recipients_page = URL(r'/compte/(?P<type>[^/]+)/(?P<webid>\w+)/virements/$',
# transfer
transfer_main_page = URL(r'/compte/(?P<acc_type>[^/]+)/(?P<webid>\w+)/virements$', TransferMainPage)
transfer_accounts = URL(r'/compte/(?P<acc_type>[^/]+)/(?P<webid>\w+)/virements/nouveau$',
r'/compte/(?P<type>[^/]+)/(?P<webid>\w+)/virements/nouveau/(?P<id>\w+)/1', TransferAccounts)
recipients_page = URL(r'/compte/(?P<type>[^/]+)/(?P<webid>\w+)/virements$',
r'/compte/(?P<type>[^/]+)/(?P<webid>\w+)/virements/nouveau/(?P<id>\w+)/2',
TransferRecipients)
transfer_charac = URL(r'/compte/(?P<type>[^/]+)/(?P<webid>\w+)/virements/nouveau/(?P<id>\w+)/3',
......@@ -376,24 +377,25 @@ def get_advisor(self):
def iter_transfer_recipients(self, account):
if account.type in (Account.TYPE_LOAN, Account.TYPE_LIFE_INSURANCE):
return []
assert account.url
# url transfer preparation
url = urlsplit(account.url)
parts = [part for part in url.path.split('/') if part]
if account.type == Account.TYPE_SAVINGS:
self.logger.debug('Deleting account name %s to get recipients', parts[-2])
del parts[-2]
parts.append('virements')
url = url._replace(path='/'.join(parts))
target = urlunsplit(url)
assert len(parts) > 2, 'Account url missing some important part to iter recipient'
account_type = parts[1] # cav, ord, epargne ...
account_webid = parts[-1]
try:
self.location(target)
self.transfer_main_page.go(acc_type=account_type, webid=account_webid)
except BrowserHTTPNotFound:
return []
# can check all account available transfer option
if self.transfer_main_page.is_here():
self.transfer_accounts.go(acc_type=account_type, webid=account_webid)
if self.transfer_accounts.is_here():
try:
self.page.submit_account(account.id)
......
......@@ -804,6 +804,10 @@ class NoTransferPage(LoggedPage, HTMLPage):
pass
class TransferMainPage(LoggedPage, HTMLPage):
pass
class TransferAccounts(LoggedPage, HTMLPage):
@method
class iter_accounts(ListElement):
......
......@@ -612,7 +612,7 @@ def get_accounts_list(self):
self.location('%s/voscomptes/rib/init-rib.ea' % self.base_url)
value = self.page.get_rib_value(acc.id)
if value:
self.location('%s/voscomptes/rib/preparerRIB-rib.ea?%s' % (self.base_url, value))
self.location('%s/voscomptes/rib/preparerRIB-rib.ea?idxSelection=%s' % (self.base_url, value))
if self.rib.is_here():
acc.iban = self.page.get_iban()
......@@ -626,7 +626,7 @@ def get_profile(self):
self.location('%s/voscomptes/rib/init-rib.ea' % self.base_url)
value = self.page.get_rib_value(acc.id)
if value:
self.location('%s/voscomptes/rib/preparerRIB-rib.ea?%s' % (self.base_url, value))
self.location('%s/voscomptes/rib/preparerRIB-rib.ea?idxSelection=%s' % (self.base_url, value))
if self.rib.is_here():
return self.page.get_profile()
......
......@@ -21,7 +21,7 @@
import re
from weboob.capabilities.bill import Subscription, Document
from weboob.capabilities.bill import DocumentTypes, Subscription, Document
from weboob.browser.pages import LoggedPage, HTMLPage
from weboob.browser.filters.standard import CleanText, Regexp, Env, Date, Format, Field
from weboob.browser.filters.html import Link, Attr, TableCell
......@@ -62,7 +62,7 @@ class item(ItemElement):
obj_label = Format('%s - %s', CleanText('.//span[contains(@class, "lib")]'), CleanText('.//span[contains(@class, "date")]'))
obj_url = Format('/voscomptes/canalXHTML/relevePdf/relevePdf_historique/%s', Link('./a'))
obj_format = 'pdf'
obj_type = 'other'
obj_type = DocumentTypes.OTHER
def obj_date(self):
date = CleanText('.//span[contains(@class, "date")]')(self)
......@@ -141,7 +141,7 @@ class item(ItemElement):
# on the page of the year XXX for the subscription YYYY
obj_url = Link('.//a')
obj_format = 'pdf'
obj_type = 'other'
obj_type = DocumentTypes.OTHER
def submit_form(self, sub_number, year):
form = self.get_form(name='formRechHisto')
......
......@@ -411,6 +411,10 @@ def get_accounts_list(self):
self.page.submit()
if 'offrebourse.com' in self.url:
# Some users may not have access to this.
if self.page.is_error():
continue
self.update_linebourse_token()
page = self.linebourse.go_portfolio(account.id)
assert self.linebourse.portfolio.is_here()
......
......@@ -29,7 +29,7 @@
from weboob.capabilities.bank import Account, Transaction
from weboob.capabilities.contact import Advisor
from weboob.capabilities.profile import Profile
from weboob.capabilities.bill import Subscription, Document
from weboob.capabilities.bill import DocumentTypes, Subscription, Document
from weboob.tools.capabilities.bank.transactions import FrenchTransaction
from weboob.exceptions import BrowserUnavailable
......@@ -278,7 +278,7 @@ class item(ItemElement):
obj_id = Format('%s_%s_%s', Env('sub_id'), Dict('Numero'), CleanText(Env('french_date'), symbols='/'))
obj_format = 'pdf'
obj_type = 'other'
obj_type = DocumentTypes.OTHER
obj__numero = CleanText(Dict('Numero'))
obj__sub_id = Env('sub_id')
obj__sub_label = Env('sub_label')
......