Commit b006d47b authored by Romain Bignon's avatar Romain Bignon

Update of modules

parent 6fdd8b37
......@@ -30,7 +30,7 @@ from weboob.capabilities.bank import (
from weboob.capabilities.messages import CapMessages, Thread
from weboob.capabilities.contact import CapContact
from weboob.capabilities.profile import CapProfile
from weboob.capabilities.base import find_object
from weboob.capabilities.base import find_object, strict_find_object
from weboob.tools.backend import Module, BackendConfig
from weboob.tools.value import ValueBackendPassword, Value, ValueBool
......@@ -119,7 +119,9 @@ class BNPorcModule(Module, CapBankWealth, CapBankTransferAddRecipient, CapMessag
else:
account = find_object(self.iter_accounts(), id=transfer.account_id, error=AccountNotFound)
recipient = find_object(self.iter_transfer_recipients(account.id), id=transfer.recipient_id, error=RecipientNotFound)
recipient = strict_find_object(self.iter_transfer_recipients(account.id), iban=transfer.recipient_iban)
if not recipient:
recipient = strict_find_object(self.iter_transfer_recipients(account.id), id=transfer.recipient_id, error=RecipientNotFound)
assert account.id.isdigit()
# quantize to show 2 decimals.
......@@ -130,6 +132,17 @@ class BNPorcModule(Module, CapBankWealth, CapBankTransferAddRecipient, CapMessag
def execute_transfer(self, transfer, **params):
return self.browser.execute_transfer(transfer)
def transfer_check_recipient_id(self, old, new):
# external recipient id can change, check the iban in recipient id
iban = re.search(r'([A-Z]{2}[A-Z\d]+)', old)
if iban:
# external recipients id
iban = iban.group(1)
return iban in new
else:
# iternal recipients id
return old == new
def iter_contacts(self):
if not hasattr(self.browser, 'get_advisor'):
raise NotImplementedError()
......
......@@ -327,11 +327,18 @@ class BNPParibasBrowser(JsonBrowserMixin, LoginBrowser):
except TransferError:
return
# avoid recipient with same iban
seen = set()
for recipient in self.page.transferable_on(origin_account_ibancrypte=origin_account_id):
yield recipient
if recipient.iban not in seen:
seen.add(recipient.iban)
yield recipient
if self.page.can_transfer_to_recipients(origin_account_id):
for recipient in self.recipients.go(data=JSON({'type': 'TOUS'})).iter_recipients():
yield recipient
if recipient.iban not in seen:
seen.add(recipient.iban)
yield recipient
@need_login
def new_recipient(self, recipient, **params):
......
......@@ -389,7 +389,7 @@ class RecipientsPage(BNPPage):
class item(MyRecipient):
# For the moment, only yield ready to transfer on recipients.
condition = lambda self: Dict('libelleStatut')(self.el) in [u'Activé', u'Temporisé']
condition = lambda self: Dict('libelleStatut')(self.el) in [u'Activé', u'Temporisé', u'En attente']
obj_id = Dict('idBeneficiaire')
obj_label = Dict('nomBeneficiaire')
......
......@@ -29,7 +29,7 @@ from weboob.capabilities.contact import Advisor
from weboob.capabilities.profile import Person
from weboob.browser.elements import ListElement, ItemElement, method, TableElement
from weboob.browser.pages import LoggedPage, RawPage, PartialHTMLPage, HTMLPage
from weboob.browser.filters.html import Link, TableCell
from weboob.browser.filters.html import Link, TableCell, Attr
from weboob.browser.filters.standard import CleanText, CleanDecimal, Regexp, Env, Field, Currency, Async, Date, Format
from weboob.exceptions import BrowserUnavailable
from weboob.tools.compat import urljoin, unicode
......@@ -57,6 +57,8 @@ class item_account_generic(ItemElement):
def obj_url(self):
url = Link(u'./a', default=NotAvailable)(self)
if not url:
url = Regexp(Attr(u'.//span', 'onclick', default=''), r'\'(https.*)\'', default=NotAvailable)(self)
if url:
if 'CreditRenouvelable' in url:
url = Link(u'.//a[contains(text(), "espace de gestion crédit renouvelable")]')(self.el)
......
......@@ -563,6 +563,10 @@ class CragrAPI(LoginBrowser):
@need_login
def iter_transfer_recipients(self, account, transfer_space_info=None):
if account.type in (account.TYPE_CARD, account.TYPE_LOAN, account.TYPE_LIFE_INSURANCE,
account.TYPE_PEA, account.TYPE_CONSUMER_CREDIT, account.TYPE_REVOLVING_CREDIT, ):
return
# avoid to call `get_account_transfer_space_info()` several time
if transfer_space_info:
space, operation, referer = transfer_space_info
......@@ -574,12 +578,16 @@ class CragrAPI(LoginBrowser):
if not self.page.is_sender_account(account.id):
return
for index, internal_rcpt in enumerate(self.page.iter_internal_recipient(account_id=account.id)):
internal_rcpt._index = index
yield internal_rcpt
# can't use 'ignore_duplicate' in DictElement because we need the 'index' to do transfer
seen = set()
seen.add(account.iban)
for index, internal_rcpt in enumerate(self.page.iter_internal_recipient()):
internal_rcpt._index = index
if internal_rcpt._is_recipient and (internal_rcpt.iban not in seen):
seen.add(internal_rcpt.iban)
yield internal_rcpt
for index, external_rcpt in enumerate(self.page.iter_external_recipient()):
external_rcpt._index = index
if external_rcpt.iban not in seen:
......
......@@ -27,7 +27,7 @@ from weboob.capabilities.bank import (
Account, Recipient, Transfer, TransferBankError,
)
from weboob.browser.filters.standard import (
CleanDecimal, Env, Date, CleanText,
CleanDecimal, Date, CleanText,
)
from weboob.browser.filters.json import Dict
......@@ -59,10 +59,12 @@ class RecipientsPage(LoggedPage, JsonPage):
@method
class iter_internal_recipient(DictElement):
def store(self, obj):
return obj
class item(ItemElement):
def condition(self):
return Dict('recipientOfTransfert', default=None)(self) and \
Env('account_id')(self) != Dict('accountNumber', default=None)(self)
return Dict('accountNumber', default=None)(self)
klass = Recipient
......@@ -71,6 +73,7 @@ class RecipientsPage(LoggedPage, JsonPage):
obj_iban = Dict('ibanCode')
obj_category = 'Interne'
obj_enabled_at = date.today()
obj__is_recipient = Dict('recipientOfTransfert', default=False)
@method
class iter_external_recipient(DictElement):
......
......@@ -460,6 +460,9 @@ class Cragr(LoginBrowser, StatesMixin):
date_guesser = LinearDateGuesser(date_max_bump=timedelta(2))
else:
date_guesser = LinearDateGuesser()
if self.predica_redirect.is_here():
self.logger.warning('Predica transactions are not handled.')
return
self.page.order_transactions()
while True:
assert self.transactions.is_here()
......
......@@ -165,11 +165,12 @@ class CreditDuNordBrowser(LoginBrowser):
self.location(account._link, data=account._args)
if self.page.can_iter_investments() and self.page.not_restrained():
return self.page.get_market_investment()
elif account.type in (Account.TYPE_LIFE_INSURANCE, Account.TYPE_CAPITALISATION):
self.location(account._link, data=account._args)
self.location(account._link.replace("_attente", "_detail_contrat_rep"), data=account._args)
if self.page.can_iter_investments():
return self.page.get_deposit_investment()
return self.page.get_li_investments()
return []
@need_login
......
......@@ -179,8 +179,8 @@ class LabelsPage(LoggedPage, JsonPage):
for element in Dict('submenu')(key):
if Lower(CleanText(Dict('label')))(element) in synthesis_labels:
synthesis_label = CleanText(Dict('link'))(element).split("/")[-1]
if CleanText(Dict('label'))(element).lower() in loan_labels:
loan_label = Lower(CleanText(Dict('link')))(element).split("/")[-1]
if Lower(CleanText(Dict('label')))(element) in loan_labels:
loan_label = CleanText(Dict('link'))(element).split("/")[-1]
return (synthesis_label, loan_label)
......@@ -687,9 +687,9 @@ class TransactionsPage(LoggedPage, CDNBasePage):
return "Sous-total" not in Field('label')(self)
@method
class get_deposit_investment(TableElement):
class get_li_investments(TableElement):
item_xpath = '//table[@class="datas"]//tr[position()>1]'
head_xpath = '//table[@class="datas"]//tr[@class="entete"]/td/b'
head_xpath = '//table[@class="datas"]//tr[@class="entete"]/td/*'
col_label = u'Libellé'
col_quantity = u'Quantité'
......@@ -726,7 +726,7 @@ class TransactionsPage(LoggedPage, CDNBasePage):
def fill_diff_currency(self, account):
valuation_diff = CleanText(u'//td[span[contains(text(), "dont +/- value : ")]]//b', default=None)(self.doc)
account.balance = CleanDecimal.French(Regexp(CleanText('//table[@class="v1-formbloc"]//td[@class="v1-labels"]/b[contains(text(), "Estimation du contrat")]/ancestor::td/following-sibling::td[1]'), r'^(.+) EUR'))(self.doc)
account.balance = CleanDecimal.French(Regexp(CleanText('//table[@class="v1-formbloc"]//td[@class="v1-labels"]//b[contains(text(), "Estimation du contrat")]/ancestor::td/following-sibling::td[1]'), r'^(.+) EUR'))(self.doc)
# NC == Non communiqué
if valuation_diff and "NC" not in valuation_diff:
account.valuation_diff = MyDecimal().filter(valuation_diff)
......
......@@ -177,8 +177,16 @@ class SocieteGenerale(LoginBrowser, StatesMixin):
else:
account_ibans = self.page.get_account_ibans_dict()
# get accounts coming
self.accounts_syntheses.go()
if not self.page.is_new_website_available():
# return in old pages to get accounts
self.accounts_main_page.go(params={'NoRedirect': True})
for acc in self.page.iter_accounts():
yield acc
return
# get accounts coming
account_comings = self.page.get_account_comings()
self.accounts.go()
......@@ -211,6 +219,9 @@ class SocieteGenerale(LoginBrowser, StatesMixin):
if account.type == Account.TYPE_PEA and not ('Espèces' in account.label or 'ESPECE' in account.label):
return
if not account._internal_id:
raise BrowserUnavailable()
if account.type in (account.TYPE_LIFE_INSURANCE, account.TYPE_PERP, ):
# request to get json is not available yet, old request to get html response
self.account_details_page.go(params={'idprest': account._prestation_id})
......@@ -254,6 +265,9 @@ class SocieteGenerale(LoginBrowser, StatesMixin):
account.TYPE_CONSUMER_CREDIT, Account.TYPE_PERP, ):
return
if not account._internal_id:
raise BrowserUnavailable()
internal_id = account._internal_id
if account.type == account.TYPE_CARD:
internal_id = account.parent._internal_id
......
......@@ -59,13 +59,15 @@ class JsonBasePage(LoggedPage, JsonPage):
if action and 'BLOCAGE' in action:
raise ActionNeeded()
if 'le service est momentanement indisponible' in reason:
# TODO: iter account on old website
# can't access new website
if ('le service est momentanement indisponible' in reason and
Dict('commun/origine')(self.doc) != 'cbo'):
raise BrowserUnavailable()
assert 'pas encore géré' in reason, 'Error %s is not handled yet' % reason
self.browser.logger.warning('This page is not handled yet by SG')
conditions = (
'pas encore géré' in reason, # this page is not handled by SG api website
'le service est momentanement indisponible' in reason, # can't access new website
)
assert any(conditions), 'Error %s is not handled yet' % reason
class AccountsMainPage(LoggedPage, HTMLPage):
......@@ -77,6 +79,36 @@ class AccountsMainPage(LoggedPage, HTMLPage):
if 'Vous ne disposez pas de compte consultable' in error_msg:
raise NoAccountsException(error_msg)
@method
class iter_accounts(TableElement):
"""iter account on old website"""
head_xpath = '//table[@class="LGNTableA ListePrestation"]//tr[@class="LGNTableHead"]/th'
item_xpath = '//table[@class="LGNTableA ListePrestation"]//tr[has-class("LGNTableRow")]'
col_id = 'Numéro de Compte'
col_type = 'Type de Compte'
col_label = 'Libellé'
col_balance = 'Solde'
class item(ItemElement):
klass = Account
TYPES = {
'LIVRET': Account.TYPE_SAVINGS,
}
obj_id = obj_number = CleanText(TableCell('id'), replace=[(' ', '')])
obj_label = CleanText('.//span[@class="TypeCompte"]')
obj_balance = MyDecimal(TableCell('balance'))
obj_currency = Currency(CleanText(TableCell('balance')))
obj__internal_id = None
def obj_type(self):
for acc_type in self.TYPES:
if acc_type in Field('label')(self).upper():
return self.TYPES[acc_type]
return Account.TYPE_UNKNOWN
class AccountDetailsPage(LoggedPage, HTMLPage):
pass
......@@ -155,6 +187,14 @@ class AccountsPage(JsonBasePage):
return True
class AccountsSynthesesPage(JsonBasePage):
def is_new_website_available(self):
if not Dict('commun/raison')(self.doc):
return True
elif not 'le service est momentanement indisponible' in Dict('commun/raison')(self.doc):
return True
self.logger.warning("SG new website is not available yet for this user")
return False
def get_account_comings(self):
account_comings = {}
......
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