From 522ac040dc360041f214f94c06d3fc7c194d0dd0 Mon Sep 17 00:00:00 2001 From: Sylvie Ye Date: Thu, 8 Nov 2018 16:29:22 +0100 Subject: [PATCH] [sgpe] retrieve intraday accounts if there are no standard accounts --- modules/societegenerale/sgpe/browser.py | 38 ++++++++-- modules/societegenerale/sgpe/json_pages.py | 80 +++++++++++++++------- 2 files changed, 86 insertions(+), 32 deletions(-) diff --git a/modules/societegenerale/sgpe/browser.py b/modules/societegenerale/sgpe/browser.py index 573b295e1c..13f78ba3cb 100644 --- a/modules/societegenerale/sgpe/browser.py +++ b/modules/societegenerale/sgpe/browser.py @@ -25,7 +25,7 @@ from weboob.browser.browsers import LoginBrowser, need_login, StatesMixin from weboob.browser.url import URL from weboob.browser.exceptions import ClientError -from weboob.exceptions import BrowserIncorrectPassword, ActionNeeded +from weboob.exceptions import BrowserIncorrectPassword, ActionNeeded, NoAccountsException from weboob.capabilities.base import find_object from weboob.capabilities.bank import ( AccountNotFound, RecipientNotFound, AddRecipientStep, AddRecipientBankError, @@ -38,7 +38,9 @@ ProfileProPage, ProfileEntPage, ChangePassPage, SubscriptionPage, InscriptionPage, ErrorPage, ) -from .json_pages import AccountsJsonPage, BalancesJsonPage, HistoryJsonPage, BankStatementPage +from .json_pages import ( + AccountsJsonPage, BalancesJsonPage, HistoryJsonPage, BankStatementPage, +) from .transfer_pages import ( EasyTransferPage, RecipientsJsonPage, TransferPage, SignTransferPage, TransferDatesPage, AddRecipientPage, AddRecipientStepPage, ConfirmRecipientPage, @@ -127,23 +129,47 @@ class SGEnterpriseBrowser(SGPEBrowser): CERTHASH = '2231d5ddb97d2950d5e6fc4d986c23be4cd231c31ad530942343a8fdcc44bb99' accounts = URL('/icd/syd-front/data/syd-comptes-accederDepuisMenu.json', AccountsJsonPage) + intraday_accounts = URL('/icd/syd-front/data/syd-intraday-accederDepuisMenu.json', AccountsJsonPage) + balances = URL('/icd/syd-front/data/syd-comptes-chargerSoldes.json', BalancesJsonPage) + intraday_balances = URL('/icd/syd-front/data/syd-intraday-chargerSoldes.json', BalancesJsonPage) + history = URL('/icd/syd-front/data/syd-comptes-chargerReleve.json', '/icd/syd-front/data/syd-intraday-chargerDetail.json', HistoryJsonPage) history_next = URL('/icd/syd-front/data/syd-comptes-chargerProchainLotEcriture.json', HistoryJsonPage) + profile = URL('/gae/afficherModificationMesDonnees.html', ProfileEntPage) subscription = URL(r'/Pgn/NavigationServlet\?MenuID=BANRELRIE&PageID=ReleveRIE&NumeroPage=1&Origine=Menu', SubscriptionPage) subscription_form = URL(r'Pgn/NavigationServlet', SubscriptionPage) def go_accounts(self): - self.accounts.go() + try: + # get standard accounts + self.accounts.go() + except NoAccountsException: + # get intraday accounts + self.intraday_accounts.go() @need_login def get_accounts_list(self): - accounts = [] - accounts.extend(self.accounts.stay_or_go().iter_accounts()) - for acc in self.balances.go().populate_balances(accounts): + # 'Comptes' are standard accounts on sge website + # 'OpĂ©rations du jour' are intraday accounts on sge website + # Standard and Intraday accounts are same accounts with different detail + # User could have standard accounts with no intraday accounts or the contrary + # They also could have both, in that case, retrieve only standard accounts + try: + # get standard accounts + self.accounts.go() + accounts = list(self.page.iter_class_accounts()) + self.balances.go() + except NoAccountsException: + # get intraday accounts + self.intraday_accounts.go() + accounts = list(self.page.iter_class_accounts()) + self.intraday_balances.go() + + for acc in self.page.populate_balances(accounts): yield acc @need_login diff --git a/modules/societegenerale/sgpe/json_pages.py b/modules/societegenerale/sgpe/json_pages.py index 992e67110a..e8ee73e4ea 100644 --- a/modules/societegenerale/sgpe/json_pages.py +++ b/modules/societegenerale/sgpe/json_pages.py @@ -22,13 +22,16 @@ from weboob.browser.pages import LoggedPage, JsonPage, pagination from weboob.browser.elements import ItemElement, method, DictElement -from weboob.browser.filters.standard import CleanDecimal, CleanText, Date, Format, BrowserURL, Env +from weboob.browser.filters.standard import ( + CleanDecimal, CleanText, Date, Format, BrowserURL, Env, + Field, +) from weboob.browser.filters.json import Dict from weboob.capabilities.base import Currency from weboob.capabilities import NotAvailable from weboob.capabilities.bank import Account from weboob.capabilities.bill import Document, Subscription -from weboob.exceptions import BrowserUnavailable, BrowserIncorrectPassword +from weboob.exceptions import BrowserUnavailable, NoAccountsException from weboob.tools.capabilities.bank.iban import is_iban_valid from weboob.tools.capabilities.bank.transactions import FrenchTransaction from weboob.tools.compat import quote_plus @@ -52,27 +55,51 @@ class AccountsJsonPage(LoggedPage, JsonPage): u'PrĂȘt': Account.TYPE_LOAN, } - def iter_accounts(self): - for classeur in self.doc.get('donnees', {}).get('classeurs', {}): - title = classeur['title'] - for compte in classeur.get('comptes', []): - a = Account() - a.label = CleanText().filter(compte['libelle']) - a._id = compte['id'] - a.type = self.obj_type(a.label) - a.number = compte['iban'].replace(' ', '') - # for some account that don't have Iban the account number is store under this variable in the Json - if not is_iban_valid(a.number): - a.iban = NotAvailable - else: - a.iban = a.number - # id based on iban to match ids in database. - a.id = a.number[4:-2] if len(a.number) == 27 else a.number - a._agency = compte['agenceGestionnaire'] - a._title = title - yield a - - def obj_type(self, label): + def on_load(self): + if self.doc['commun']['statut'] == 'NOK': + reason = self.doc['commun']['raison'] + if reason == 'SYD-COMPTES-UNAUTHORIZED-ACCESS': + raise NoAccountsException("Vous n'avez pas l'autorisation de consulter : {}".format(reason)) + raise BrowserUnavailable(reason) + + @method + class iter_class_accounts(DictElement): + item_xpath = 'donnees/classeurs' + + class iter_accounts(DictElement): + @property + def item_xpath(self): + if 'intradayComptes' in self.el: + return 'intradayComptes' + return 'comptes' + + class item(ItemElement): + klass = Account + + obj__id = Dict('id') + obj_number = CleanText(Dict('iban'), replace=[(' ', '')]) + obj_iban = Field('number') + obj_label = CleanText(Dict('libelle')) + obj__agency = Dict('agenceGestionnaire') + + def obj_id(self): + number = Field('number')(self) + if len(number) == 27: + # id based on iban to match ids in database. + return number[4:-2] + return number + + def obj_iban(self): + # for some account that don't have Iban the account number is store under this variable in the Json + number = Field('number')(self) + if not is_iban_valid(number): + return NotAvailable + return number + + def obj_type(self): + return self.page.acc_type(Field('label')(self)) + + def acc_type(self, label): for wording, acc_type in self.TYPES.items(): if wording.lower() in label.lower(): return acc_type @@ -91,14 +118,15 @@ def on_load(self): if self.doc['commun']['statut'] == 'NOK': reason = self.doc['commun']['raison'] if reason == 'SYD-COMPTES-UNAUTHORIZED-ACCESS': - raise BrowserIncorrectPassword("Vous n'avez pas l'autorisation de consulter : {}".format(reason)) + raise NoAccountsException("Vous n'avez pas l'autorisation de consulter : {}".format(reason)) raise BrowserUnavailable(reason) def populate_balances(self, accounts): for account in accounts: acc_dict = self.doc['donnees']['compteSoldesMap'][account._id] - account.balance = CleanDecimal(replace_dots=True).filter(acc_dict['soldeComptable']) - account.currency = Currency.get_currency(acc_dict['deviseSoldeComptable']) + account.balance = CleanDecimal(replace_dots=True).filter(acc_dict.get('soldeComptable', acc_dict.get('soldeInstantane'))) + account.currency = Currency.get_currency(acc_dict.get('deviseSoldeComptable', acc_dict.get('deviseSoldeInstantane'))) + account.coming = CleanDecimal(replace_dots=True, default=NotAvailable).filter(acc_dict.get('montantOperationJour')) yield account -- GitLab