From 8b1ea6d21b5f4c15bca79d8492159d2c7bea3aa1 Mon Sep 17 00:00:00 2001 From: Florian Duguet Date: Wed, 17 Jul 2019 14:22:51 +0200 Subject: [PATCH] [societegenerale] get Rib document for all subscription change the way we get subscription to get one subscription for each account not only for those which have bank statement, because it is still possible to get rib document even for those which don't have it --- modules/societegenerale/browser.py | 60 +++++++++++++++---- modules/societegenerale/module.py | 5 +- .../societegenerale/pages/accounts_list.py | 14 +++++ modules/societegenerale/pages/subscription.py | 28 +++------ 4 files changed, 72 insertions(+), 35 deletions(-) diff --git a/modules/societegenerale/browser.py b/modules/societegenerale/browser.py index d6003b9d52..7d225ba560 100644 --- a/modules/societegenerale/browser.py +++ b/modules/societegenerale/browser.py @@ -24,6 +24,7 @@ from dateutil.relativedelta import relativedelta from weboob.browser import LoginBrowser, URL, need_login, StatesMixin +from weboob.capabilities.bill import Document, DocumentTypes from weboob.exceptions import BrowserIncorrectPassword, ActionNeeded, BrowserUnavailable from weboob.capabilities.bank import Account, TransferBankError, AddRecipientStep, TransactionType, AccountOwnerType from weboob.capabilities.base import find_object, NotAvailable @@ -40,7 +41,7 @@ ) from .pages.transfer import AddRecipientPage, SignRecipientPage, TransferJson, SignTransferPage from .pages.login import MainPage, LoginPage, BadLoginPage, ReinitPasswordPage, ActionNeededPage, ErrorPage -from .pages.subscription import BankStatementPage +from .pages.subscription import BankStatementPage, RibPdfPage __all__ = ['SocieteGenerale'] @@ -100,6 +101,7 @@ class SocieteGenerale(LoginBrowser, StatesMixin): bank_statement = URL(r'/restitution/rce_derniers_releves.html', BankStatementPage) bank_statement_search = URL(r'/restitution/rce_recherche.html\?noRedirect=1', r'/restitution/rce_recherche_resultat.html', BankStatementPage) + rib_pdf_page = URL(r'/com/icd-web/cbo/pdf/rib-authsec.pdf', RibPdfPage) bad_login = URL(r'/acces/authlgn.html', r'/error403.html', BadLoginPage) reinit = URL(r'/acces/changecodeobligatoire.html', @@ -475,24 +477,39 @@ def iter_subscription(self): except (ProfileMissing, BrowserUnavailable): subscriber = NotAvailable - # subscriptions which have statements are present on the last statement page - self.bank_statement.go() - subscriptions_list = list(self.page.iter_subscription()) + self.accounts.go() + subscriptions_list = list(self.page.iter_subscription(subscriber=subscriber)) - # this way the no statement accounts are excluded - # and the one keeped have all the data and parameters needed self.bank_statement_search.go() - for sub in self.page.iter_searchable_subscription(subscriber=subscriber): - found_sub = find_object(subscriptions_list, id=sub.id) + searchable_subscription_list = list(self.page.iter_searchable_subscription()) + for sub in subscriptions_list: + found_sub = find_object(searchable_subscription_list, id=sub.id) if found_sub: - yield sub - - @need_login - def iter_documents(self, subscription): - end_date = datetime.today() + # we need it to get bank statement, but not all subscription have it + sub._rad_button_id = found_sub._rad_button_id + else: + # even without bank statement we still can get RIB document, so we yield subscription anyway + sub._rad_button_id = NotAvailable + yield sub + + def _fetch_rib_document(self, subscription): + d = Document() + d.id = subscription.id + '_RIB' + d.url = self.rib_pdf_page.build(params={'b64e200_prestationIdTechnique': subscription._internal_id}) + d.type = DocumentTypes.RIB + d.format = 'pdf' + d.label = 'RIB' + return d + + def _iter_statements(self, subscription): + # we need _rad_button_id for post_form function + # if not present it means this subscription doesn't have any bank statement + if subscription._rad_button_id is NotAvailable: + return # 5 years since it goes with a 2 months step security_limit = 30 + end_date = datetime.today() i = 0 while i < security_limit: self.bank_statement_search.go() @@ -509,3 +526,20 @@ def iter_documents(self, subscription): # from the 08 to the 06, the 06 statement is included end_date = end_date - relativedelta(months=+3) i += 1 + + @need_login + def iter_documents(self, subscription): + yield self._fetch_rib_document(subscription) + for doc in self._iter_statements(subscription): + yield doc + + @need_login + def iter_documents_by_types(self, subscription, accepted_types): + if DocumentTypes.RIB in accepted_types: + yield self._fetch_rib_document(subscription) + + if DocumentTypes.STATEMENT not in accepted_types: + return + + for doc in self._iter_statements(subscription): + yield doc diff --git a/modules/societegenerale/module.py b/modules/societegenerale/module.py index e5b26165b0..7e5c46380f 100644 --- a/modules/societegenerale/module.py +++ b/modules/societegenerale/module.py @@ -57,7 +57,7 @@ class SocieteGeneraleModule(Module, CapBankWealth, CapBankTransferAddRecipient, Value('website', label='Type de compte', default='par', choices={'par': 'Particuliers', 'pro': 'Professionnels', 'ent': 'Entreprises'})) - accepted_document_types = (DocumentTypes.STATEMENT,) + accepted_document_types = (DocumentTypes.STATEMENT, DocumentTypes.RIB) def create_default_browser(self): b = {'par': SocieteGenerale, 'pro': SGProfessionalBrowser, 'ent': SGEnterpriseBrowser} @@ -157,6 +157,9 @@ def iter_documents(self, subscription): return self.browser.iter_documents(subscription) + def iter_documents_by_types(self, subscription, accepted_types): + return self.browser.iter_documents_by_types(subscription, accepted_types) + def download_document(self, document): if not isinstance(document, Document): document = self.get_document(document) diff --git a/modules/societegenerale/pages/accounts_list.py b/modules/societegenerale/pages/accounts_list.py index 7b7639af34..bdb83d8d2b 100644 --- a/modules/societegenerale/pages/accounts_list.py +++ b/modules/societegenerale/pages/accounts_list.py @@ -26,6 +26,7 @@ from dateutil.relativedelta import relativedelta from weboob.capabilities.base import NotAvailable from weboob.capabilities.bank import Account, Investment, Loan, AccountOwnership +from weboob.capabilities.bill import Subscription from weboob.capabilities.contact import Advisor from weboob.capabilities.profile import Person, ProfileMissing from weboob.tools.capabilities.bank.transactions import FrenchTransaction @@ -215,6 +216,19 @@ def obj__is_json_histo(self): not Dict('produit')(self) in ('PLAN_EPARGNE_POPULAIRE', ): return True + @method + class iter_subscription(DictElement): + item_xpath = 'donnees' + + class item(ItemElement): + klass = Subscription + + obj_id = CleanText(Dict('numeroCompteFormate'), replace=[(' ', '')]) + obj_subscriber = Env('subscriber') + obj_label = Format('%s %s', Dict('labelToDisplay'), Field('id')) + obj__internal_id = Dict('idTechnique') + + class AccountsSynthesesPage(JsonBasePage): def is_new_website_available(self): if not Dict('commun/raison')(self.doc): diff --git a/modules/societegenerale/pages/subscription.py b/modules/societegenerale/pages/subscription.py index 292eb75d6a..69dbd5f3c8 100644 --- a/modules/societegenerale/pages/subscription.py +++ b/modules/societegenerale/pages/subscription.py @@ -24,31 +24,14 @@ from weboob.capabilities.bill import Document, Subscription, DocumentTypes from weboob.browser.elements import TableElement, ItemElement, method -from weboob.browser.filters.standard import CleanText, Regexp, Env, Date, Format, Field +from weboob.browser.filters.standard import CleanText, Regexp, Date, Format, Field from weboob.browser.filters.html import Link, TableCell, Attr -from weboob.browser.pages import LoggedPage +from weboob.browser.pages import LoggedPage, RawPage from .base import BasePage -class BankStatementPage(LoggedPage, BasePage): - @method - class iter_subscription(TableElement): - item_xpath = '//table[.//th]//tr[td and @class="LGNTableRow"]' - head_xpath = '//table//th' - - col_id = 'Numéro de Compte' - col_label = 'Type de Compte' - col__last_document_label = 'Derniers relevés' - - class item(ItemElement): - def condition(self): - return 'Récapitulatif annuel' not in CleanText(TableCell('_last_document_label'))(self) - - klass = Subscription - - obj_id = CleanText(TableCell('id'), replace=[(' ', '')]) - obj_label = CleanText(TableCell('label')) +class BankStatementPage(LoggedPage, BasePage): @method class iter_searchable_subscription(TableElement): item_xpath = '//table//tr[@class="fond_ligne"]' @@ -63,7 +46,6 @@ class item(ItemElement): klass = Subscription obj_id = CleanText(TableCell('id'), replace=[(' ', '')]) - obj_subscriber = Env('subscriber') def obj_label(self): label = CleanText(TableCell('label'))(self) @@ -119,3 +101,7 @@ def has_error_msg(self): return any((CleanText('//div[@class="MessageErreur"]')(self.doc), CleanText('//span[@class="error_msg"]')(self.doc), self.doc.xpath('//div[contains(@class, "error_page")]'), )) + + +class RibPdfPage(LoggedPage, RawPage): + pass -- GitLab