From b1b1682f80c8f50b44c05e593c08ded70957f031 Mon Sep 17 00:00:00 2001 From: Sylvie Ye Date: Thu, 2 Aug 2018 10:57:48 +0200 Subject: [PATCH] [societegenerale pro] new feature: iter recipients --- modules/societegenerale/module.py | 2 +- modules/societegenerale/sgpe/browser.py | 39 +++++++++ .../societegenerale/sgpe/transfer_pages.py | 86 +++++++++++++++++++ 3 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 modules/societegenerale/sgpe/transfer_pages.py diff --git a/modules/societegenerale/module.py b/modules/societegenerale/module.py index 46ba4e8932..af39b56fed 100644 --- a/modules/societegenerale/module.py +++ b/modules/societegenerale/module.py @@ -100,7 +100,7 @@ def get_profile(self): return self.browser.get_profile() def iter_transfer_recipients(self, origin_account): - if self.config['website'].get() != 'par': + if self.config['website'].get() not in ('par', 'pro'): raise NotImplementedError() if not isinstance(origin_account, Account): origin_account = find_object(self.iter_accounts(), id=origin_account, error=AccountNotFound) diff --git a/modules/societegenerale/sgpe/browser.py b/modules/societegenerale/sgpe/browser.py index 30424f6f5d..641d5f72e7 100644 --- a/modules/societegenerale/sgpe/browser.py +++ b/modules/societegenerale/sgpe/browser.py @@ -17,6 +17,8 @@ # You should have received a copy of the GNU Affero General Public License # along with weboob. If not, see . +from __future__ import unicode_literals + import re from weboob.browser.browsers import LoginBrowser, need_login @@ -31,6 +33,9 @@ ProfileProPage, ProfileEntPage, ChangePassPage, SubscriptionPage, ) from .json_pages import AccountsJsonPage, BalancesJsonPage, HistoryJsonPage, BankStatementPage +from .transfer_pages import ( + EasyTransferPage, RecipientsJsonPage, +) __all__ = ['SGProfessionalBrowser', 'SGEnterpriseBrowser'] @@ -169,6 +174,10 @@ class SGProfessionalBrowser(SGEnterpriseBrowser): incorrect_login = URL('/authent.html', IncorrectLoginPage) profile = URL('/gao/modifier-donnees-perso-saisie.html', ProfileProPage) + easy_transfer = URL('/ord-web/ord//ord-virement-simplifie-emetteur.html', EasyTransferPage) + internal_recipients = URL('/ord-web/ord//ord-virement-simplifie-beneficiaire.html', EasyTransferPage) + external_recipients = URL('/ord-web/ord//ord-liste-compte-beneficiaire-externes.json', RecipientsJsonPage) + bank_statement_menu = URL('/icd/syd-front/data/syd-rce-accederDepuisMenu.json', BankStatementPage) bank_statement_search = URL('/icd/syd-front/data/syd-rce-lancerRecherche.json', BankStatementPage) @@ -210,6 +219,36 @@ def advance_month(self, end_month, end_year, month_range=3): return new_end_month, end_year, begin_month, begin_year + @need_login + def iter_recipients(self, origin_account): + self.easy_transfer.go() + self.page.update_origin_account(origin_account) + + params = { + 'cl_ibanEmetteur': origin_account.iban, + 'cl_codeProduit': origin_account._product_code, + 'cl_codeSousProduit': origin_account._underproduct_code, + } + self.internal_recipients.go(method='POST', params=params, headers={'Content-Type': 'application/json;charset=UTF-8'}) + for internal_rcpt in self.page.iter_internal_recipients(): + yield internal_rcpt + + data = { + 'an_filtreIban': 'true', + 'an_filtreIbanSEPA': 'true', + 'an_isCredit': 'true', + 'an_isDebit': 'false', + 'an_rang': 0, + 'an_restrictFRMC': 'false', + 'cl_codeProduit': origin_account._product_code, + 'cl_codeSousProduit': origin_account._underproduct_code, + 'n_nbOccurences': '10000', + } + self.external_recipients.go(data=data) + assert self.page.is_all_external_recipient(), "Some recipients are missing" + for external_rcpt in self.page.iter_external_recipients(): + yield external_rcpt + @need_login def iter_documents(self, subscribtion): # This quality website can only fetch documents through a form, looking for dates diff --git a/modules/societegenerale/sgpe/transfer_pages.py b/modules/societegenerale/sgpe/transfer_pages.py new file mode 100644 index 0000000000..bafe80de29 --- /dev/null +++ b/modules/societegenerale/sgpe/transfer_pages.py @@ -0,0 +1,86 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) 2018 Sylvie Ye +# +# This file is part of weboob. +# +# weboob is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# weboob is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with weboob. If not, see . + +from __future__ import unicode_literals + + +import json +from datetime import date + +from weboob.browser.pages import LoggedPage, HTMLPage, JsonPage +from weboob.browser.elements import method, DictElement, ItemElement +from weboob.browser.filters.html import Attr +from weboob.capabilities.bank import Recipient +from weboob.browser.filters.json import Dict + + +class RecipientsJsonPage(LoggedPage, JsonPage): + def is_all_external_recipient(self): + return ( + Dict('donnees/nbTotalDestinataires')(self.doc) == len(self.doc['donnees']['items']) + and not Dict('donnees/moreItems')(self.doc) + ) + + @method + class iter_external_recipients(DictElement): + item_xpath = 'donnees/items' + + class item(ItemElement): + klass = Recipient + + def condition(self): + return Dict('coordonnee/0/natureTypee')(self) == 'CREDIT' + + obj_category = 'Externe' + obj_id = Dict('coordonnee/0/refSICoordonnee') + obj_iban = Dict('coordonnee/0/numeroCompte') + obj_label = obj__account_title = Dict('nomRaisonSociale') + obj_enabled_at = date.today() + + +class EasyTransferPage(LoggedPage, HTMLPage): + def update_origin_account(self, origin_account): + for account in self.doc.xpath('//ul[@id="idCptFrom"]//li'): + # get all account data + data = Attr('.', 'data-comptecomplet')(account) + json_data = json.loads(data.replace('"', '"')) + + if ( + origin_account.label == json_data['libelleCompte'] + and origin_account.iban == json_data['ibanCompte'] + ): + origin_account._product_code = json_data['codeProduit'] + origin_account._underproduct_code = json_data['codeSousProduit'] + break + else: + assert False, 'Account % not found on transfer page' % (origin_account.label) + + def iter_internal_recipients(self): + if self.doc.xpath('//ul[@id="idCmptToInterne"]'): + for account in self.doc.xpath('//ul[@id="idCmptToInterne"]/li'): + data = Attr('.', 'data-comptecomplet')(account) + json_data = json.loads(data.replace('"', '"')) + + rcpt = Recipient() + rcpt.category = 'Interne' + rcpt.id = rcpt.iban = json_data['ibanCompte'] + rcpt.label = json_data['libelleCompte'] + rcpt.enabled_at = date.today() + + yield rcpt -- GitLab