Commit 76c42587 authored by Sylvie Ye's avatar Sylvie Ye Committed by Romain Bignon

[societegenerale pro] new feature: transfer

parent b1b1682f
......@@ -111,7 +111,7 @@ class SocieteGeneraleModule(Module, CapBankWealth, CapBankTransferAddRecipient,
return self.browser.new_recipient(recipient, **params)
def init_transfer(self, transfer, **params):
if self.config['website'].get() != 'par':
if self.config['website'].get() not in ('par', 'pro'):
raise NotImplementedError()
transfer.label = ' '.join(w for w in re.sub('[^0-9a-zA-Z ]+', '', transfer.label).split())
self.logger.info('Going to do a new transfer')
......@@ -130,7 +130,7 @@ class SocieteGeneraleModule(Module, CapBankWealth, CapBankTransferAddRecipient,
return self.browser.init_transfer(account, recipient, transfer)
def execute_transfer(self, transfer, **params):
if self.config['website'].get() != 'par':
if self.config['website'].get() not in ('par', 'pro'):
raise NotImplementedError()
return self.browser.execute_transfer(transfer)
......
......@@ -26,7 +26,9 @@ from weboob.browser.url import URL
from weboob.browser.exceptions import ClientError
from weboob.exceptions import BrowserIncorrectPassword
from weboob.capabilities.base import find_object
from weboob.capabilities.bank import AccountNotFound
from weboob.capabilities.bank import (
AccountNotFound, RecipientNotFound,
)
from .pages import (
LoginPage, CardsPage, CardHistoryPage, IncorrectLoginPage,
......@@ -34,7 +36,7 @@ from .pages import (
)
from .json_pages import AccountsJsonPage, BalancesJsonPage, HistoryJsonPage, BankStatementPage
from .transfer_pages import (
EasyTransferPage, RecipientsJsonPage,
EasyTransferPage, RecipientsJsonPage, TransferPage, SignTransferPage,
)
......@@ -178,6 +180,10 @@ class SGProfessionalBrowser(SGEnterpriseBrowser):
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)
init_transfer_page = URL('/ord-web/ord//ord-enregistrer-ordre-simplifie.json', TransferPage)
sign_transfer_page = URL('/ord-web/ord//ord-verifier-habilitation-signature-ordre.json', SignTransferPage)
confirm_transfer = URL('/ord-web/ord//ord-valider-signature-ordre.json', TransferPage)
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)
......@@ -249,6 +255,59 @@ class SGProfessionalBrowser(SGEnterpriseBrowser):
for external_rcpt in self.page.iter_external_recipients():
yield external_rcpt
@need_login
def init_transfer(self, account, recipient, transfer):
# update account and recipient info
recipient = find_object(self.iter_recipients(account), iban=recipient.iban, error=RecipientNotFound)
data = [
('an_codeAction', 'C'),
('an_referenceSiOrdre', ''),
('cl_compteEmetteur_intitule', account._account_title),
('cl_compteEmetteur_libelle', account.label),
('an_compteEmetteur_iban', account.iban),
('cl_compteEmetteur_ibanFormate', account._formatted_iban),
('an_compteEmetteur_bic', account._bic),
('b64_compteEmetteur_idPrestation', account._id_service),
('an_guichetGestionnaire', account._manage_counter),
('an_codeProduit', account._product_code),
('an_codeSousProduit', account._underproduct_code),
('n_ordreMontantValeur', int(transfer.amount * (10 ** account._decimal_code))),
('n_ordreMontantCodeDecimalisation', account._decimal_code),
('an_ordreMontantCodeDevise', account._currency_code),
('cl_dateExecution', transfer.exec_date.strftime('%d/%m/%Y')),
('cl_ordreLibelle', transfer.label),
('an_beneficiaireCodeAction', 'C'),
('cl_beneficiaireRefSiCoordonnee', recipient._ref),
('cl_beneficiaireCompteLibelle', recipient.label),
('cl_beneficiaireCompteIntitule', recipient._account_title),
('cl_beneficiaireCompteIbanFormate', recipient._formatted_iban),
('an_beneficiaireCompteIban', recipient.iban),
('cl_beneficiaireCompteBic', recipient._bic),
('cl_beneficiaireAdressePays', recipient.iban[:2]),
('an_indicateurIntraAbonnement', 'false'),
('cl_reference', ' '),
('cl_motif', transfer.label),
]
# WARNING: this save transfer information on user account
self.init_transfer_page.go(data=data)
return self.page.handle_response(account, recipient, transfer.amount, transfer.label, transfer.exec_date)
@need_login
def execute_transfer(self, transfer, **params):
assert transfer._b64_id_transfer, 'Transfer token is missing'
# get virtual keyboard
data = {
'b64_idOrdre': transfer._b64_id_transfer
}
self.sign_transfer_page.go(data=data)
data.update(self.page.get_confirm_transfer_data(self.password))
self.confirm_transfer.go(data=data)
self.page.is_transfer_validated()
return transfer
@need_login
def iter_documents(self, subscribtion):
# This quality website can only fetch documents through a form, looking for dates
......
......@@ -95,7 +95,7 @@ class ChangePassPage(SGPEPage):
class LoginPage(SGPEPage):
def login(self, login, password):
def get_authentication_data(self):
infos_data = self.browser.open('/sec/vk/gen_crypto?estSession=0').text
infos_data = re.match('^_vkCallback\((.*)\);$', infos_data).group(1)
infos = json.loads(infos_data.replace("'", '"'))
......@@ -110,10 +110,18 @@ class LoginPage(SGPEPage):
if err.tile:
err.tile.display()
return {
'infos': infos,
'img': img,
}
def login(self, login, password):
authentication_data = self.get_authentication_data()
form = self.get_form(name=self.browser.LOGIN_FORM)
form['user_id'] = login
form['codsec'] = img.get_codes(password[:6])
form['cryptocvcs'] = infos['crypto']
form['codsec'] = authentication_data['img'].get_codes(password[:6])
form['cryptocvcs'] = authentication_data['infos']['crypto']
form['vk_op'] = 'auth'
form.url = '/authent.html'
try:
......
......@@ -26,8 +26,11 @@ 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
from weboob.browser.filters.standard import Date, Eval
from weboob.capabilities.bank import Recipient, Transfer
from .pages import LoginPage
class RecipientsJsonPage(LoggedPage, JsonPage):
......@@ -53,6 +56,10 @@ class RecipientsJsonPage(LoggedPage, JsonPage):
obj_label = obj__account_title = Dict('nomRaisonSociale')
obj_enabled_at = date.today()
obj__formatted_iban = Dict('coordonnee/0/numeroCompteFormate')
obj__bic = Dict('coordonnee/0/BIC')
obj__ref = Dict('coordonnee/0/refSICoordonnee')
class EasyTransferPage(LoggedPage, HTMLPage):
def update_origin_account(self, origin_account):
......@@ -65,6 +72,15 @@ class EasyTransferPage(LoggedPage, HTMLPage):
origin_account.label == json_data['libelleCompte']
and origin_account.iban == json_data['ibanCompte']
):
origin_account._currency_code = json_data['codeDevise']
origin_account._formatted_iban = json_data['ibanFormateCompte']
origin_account._min_amount = json_data['montantMin']
origin_account._max_amount = json_data['montantMax']
origin_account._decimal_code = json_data['codeDecimal']
origin_account._manage_counter = json_data['guichetGestionnaire']
origin_account._account_title = json_data['intituleCompte']
origin_account._bic = json_data['bicCompte']
origin_account._id_service = json_data['idPrestation']
origin_account._product_code = json_data['codeProduit']
origin_account._underproduct_code = json_data['codeSousProduit']
break
......@@ -83,4 +99,63 @@ class EasyTransferPage(LoggedPage, HTMLPage):
rcpt.label = json_data['libelleCompte']
rcpt.enabled_at = date.today()
rcpt._formatted_iban = json_data['ibanFormateCompte']
rcpt._account_title = json_data['intituleCompte']
rcpt._bic = json_data['bicCompte']
rcpt._ref = ''
yield rcpt
class TransferPage(LoggedPage, JsonPage):
def on_load(self):
assert Dict('commun/statut')(self.doc) == 'ok', 'Something went wrong: %s' % Dict('commun/raison')(self.doc)
def handle_response(self, origin, recipient, amount, reason, exec_date):
account_data = Dict('donnees/detailOrdre/compteEmetteur')(self.doc)
recipient_data = Dict('donnees/listOperations/0/compteBeneficiaire')(self.doc)
transfer_data = Dict('donnees/detailOrdre')(self.doc)
transfer = Transfer()
transfer._b64_id_transfer = Dict('idOrdre')(transfer_data)
transfer.account_id = origin.id
transfer.account_label = Dict('libelleCompte')(account_data)
transfer.account_iban = Dict('ibanCompte')(account_data)
transfer.account_balance = origin.balance
transfer.recipient_id = recipient.id
transfer.recipient_label = Dict('libelleCompte')(recipient_data)
transfer.recipient_iban = Dict('ibanCompte')(recipient_data)
transfer.currency = Dict('montantTotalOrdre/codeDevise')(transfer_data)
transfer.amount = Eval(
lambda x, y: x * (10 ** -y),
Dict('montantTotalOrdre/valeurMontant'),
Dict('montantTotalOrdre/codeDecimalisation')
)(transfer_data)
transfer.exec_date = Date(Dict('dateExecution'), dayfirst=True)(transfer_data)
transfer.label = Dict('libelleClientOrdre')(transfer_data)
return transfer
def is_transfer_validated(self):
return Dict('donnees/statutOrdre')(self.doc) not in ('rejete', 'a_signer', )
class SignTransferPage(LoggedPage, LoginPage):
def get_token(self):
result_page = json.loads(self.content)
assert result_page['commun']['statut'] == 'ok', 'Something went wrong: %s' % result_page['commun']['raison']
return result_page['donnees']['jeton']
def get_confirm_transfer_data(self, password):
token = self.get_token()
authentication_data = self.get_authentication_data()
return {
'codsec': authentication_data['img'].get_codes(password[:6]),
'cryptocvcs': authentication_data['infos']['crypto'],
'vk_op': 'sign',
'context': token,
}
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