Commit 4ae9d7cc authored by Sylvie Ye's avatar Sylvie Ye Committed by Romain Bignon

[cmb] add new feature iter recipient

parent b9a04b5e
......@@ -19,7 +19,7 @@
from __future__ import unicode_literals
from weboob.capabilities.bank import CapBankWealth, AccountNotFound
from weboob.capabilities.bank import CapBankTransfer, CapBankWealth, Account, AccountNotFound
from weboob.capabilities.contact import CapContact
from weboob.capabilities.base import find_object
from weboob.capabilities.profile import CapProfile
......@@ -33,7 +33,7 @@ from .pro.browser import CmsoProBrowser
__all__ = ['CmsoModule']
class CmsoModule(Module, CapBankWealth, CapContact, CapProfile):
class CmsoModule(Module, CapBankTransfer, CapBankWealth, CapContact, CapProfile):
NAME = 'cmso'
MAINTAINER = 'Romain Bignon'
EMAIL = 'romain@weboob.org'
......@@ -69,6 +69,14 @@ class CmsoModule(Module, CapBankWealth, CapContact, CapProfile):
def iter_investment(self, account):
return self.browser.iter_investment(account)
def iter_transfer_recipients(self, origin_account):
if self.config['website'].get() != "par":
raise NotImplementedError()
if not isinstance(origin_account, Account):
origin_account = self.get_account(origin_account)
return self.browser.iter_recipients(origin_account)
def iter_contacts(self):
if self.config['website'].get() != "par":
raise NotImplementedError()
......
......@@ -33,8 +33,9 @@ from weboob.tools.capabilities.bank.transactions import sorted_transactions
from .pages import (
LogoutPage, InfosPage, AccountsPage, HistoryPage, LifeinsurancePage, MarketPage,
AdvisorPage, LoginPage, RecipientsPage, ProfilePage,
AdvisorPage, LoginPage, ProfilePage,
)
from .transfer_pages import TransferInfoPage
def retry(exc_check, tries=4):
......@@ -92,7 +93,8 @@ class CmsoParBrowser(LoginBrowser, StatesMixin):
'https://www.*/domiweb/prive/particulier', MarketPage)
advisor = URL('/edrapi/v(?P<version>\w+)/oauth/(?P<page>\w+)', AdvisorPage)
recipients = URL(r'/domiapi/oauth/json/transfer/transferinfos', RecipientsPage)
# transfer
transfer_info = URL(r'/domiapi/oauth/json/transfer/transferinfos', TransferInfoPage)
profile = URL(r'/domiapi/oauth/json/edr/infosPerson', ProfilePage)
......@@ -158,7 +160,7 @@ class CmsoParBrowser(LoginBrowser, StatesMixin):
seen = {}
self.recipients.go(data='{"beneficiaryType":"INTERNATIONAL"}', headers=self.json_headers)
self.transfer_info.go(data='{"beneficiaryType":"INTERNATIONAL"}', headers=self.json_headers)
numbers = self.page.get_numbers()
# First get all checking accounts...
......@@ -305,6 +307,33 @@ class CmsoParBrowser(LoginBrowser, StatesMixin):
return []
raise NotImplementedError()
@retry((ClientError, ServerError))
@need_login
def iter_recipients(self, account):
self.transfer_info.go(
data='{"beneficiaryType":"INTERNATIONAL"}',
headers=self.json_headers
)
if account.type in (Account.TYPE_LOAN, ):
return
if not account._eligible_debit:
return
# internal recipient
for rcpt in self.page.iter_titu_accounts():
if rcpt.id != account.id:
yield rcpt
for rcpt in self.page.iter_manda_accounts():
if rcpt.id != account.id:
yield rcpt
for rcpt in self.page.iter_legal_rep_accounts():
if rcpt.id != account.id:
yield rcpt
# external recipient
for rcpt in self.page.iter_external_recipients():
yield rcpt
@retry((ClientError, ServerError))
@need_login
def get_advisor(self):
......
......@@ -135,6 +135,8 @@ class AccountsPage(LoggedPage, JsonPage):
# Iban is available without last 5 numbers, or by sms
obj_iban = NotAvailable
obj__index = Dict('index')
# to know if we can do transfer on account
obj__eligible_debit = Dict('eligibiliteDebit', default=False)
def obj_balance(self):
balance = CleanDecimal(Dict('soldeEuro', default="0"))(self)
......@@ -194,6 +196,8 @@ class AccountsPage(LoggedPage, JsonPage):
obj_coming = CleanDecimal(Dict('AVenir', default=None), default=NotAvailable)
obj__index = Dict('index')
obj__owner = Dict('nomTitulaire')
# to know if we can do transfer on account
obj__eligible_debit = Dict('eligibiliteDebit', default=False)
def obj_id(self):
type = Field('type')(self)
......@@ -549,35 +553,6 @@ class AdvisorPage(LoggedPage, JsonPage):
obj_address = Format('%s %s', Dict('adresse1'), Dict('adresse3'))
class RecipientsPage(LoggedPage, JsonPage):
def get_numbers(self):
# If account information is not available when asking for the
# recipients (server error for ex.), return an empty dictionary
# that will be filled later after being returned the json of the
# account page (containing the accounts IDs too).
if 'listCompteTitulaireCotitulaire' not in self.doc and 'exception' in self.doc:
return {}
ret = {}
ret.update({
d['index']: d['numeroContratSouscrit']
for d in self.doc['listCompteTitulaireCotitulaire']
})
ret.update({
d['index']: d['numeroContratSouscrit']
for p in self.doc['listCompteMandataire'].values()
for d in p
})
ret.update({
d['index']: d['numeroContratSouscrit']
for p in self.doc['listCompteLegalRep'].values()
for d in p
})
return ret
class ProfilePage(LoggedPage, JsonPage):
# be careful, this page is used in CmsoProBrowser too!
......
# -*- coding: utf-8 -*-
# Copyright(C) 2019 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 <http://www.gnu.org/licenses/>.
from __future__ import unicode_literals
import datetime as dt
from weboob.browser.pages import JsonPage, LoggedPage
from weboob.browser.elements import DictElement, ItemElement, method
from weboob.browser.filters.json import Dict
from weboob.capabilities.bank import Recipient
from weboob.capabilities.base import NotAvailable
class MyRecipientItemElement(ItemElement):
def condition(self):
return Dict('eligibiliteCredit', default=False)
klass = Recipient
obj_id = Dict('numeroContratSouscrit')
obj_label = Dict('lib')
obj_iban = NotAvailable
obj_enabled_at = dt.date.today()
obj_category = 'Interne'
obj__index = Dict('index')
class TransferInfoPage(LoggedPage, JsonPage):
def get_numbers(self):
# If account information is not available when asking for the
# recipients (server error for ex.), return an empty dictionary
# that will be filled later after being returned the json of the
# account page (containing the accounts IDs too).
if 'listCompteTitulaireCotitulaire' not in self.doc and 'exception' in self.doc:
return {}
ret = {}
ret.update({
d['index']: d['numeroContratSouscrit']
for d in self.doc['listCompteTitulaireCotitulaire']
})
ret.update({
d['index']: d['numeroContratSouscrit']
for p in self.doc['listCompteMandataire'].values()
for d in p
})
ret.update({
d['index']: d['numeroContratSouscrit']
for p in self.doc['listCompteLegalRep'].values()
for d in p
})
return ret
@method
class iter_titu_accounts(DictElement):
item_xpath = 'listCompteTitulaireCotitulaire'
class item(MyRecipientItemElement):
pass
@method
class iter_manda_accounts(DictElement):
item_xpath = 'listCompteMandataire/*'
class item(MyRecipientItemElement):
pass
@method
class iter_legal_rep_accounts(DictElement):
item_xpath = 'listCompteLegalRep/*'
class item(MyRecipientItemElement):
pass
@method
class iter_external_recipients(DictElement):
item_xpath = 'listBeneficiaries'
class item(ItemElement):
klass = Recipient
obj_id = obj_iban = Dict('iban')
obj_label = Dict('nom')
obj_category = 'Externe'
obj_enabled_at = dt.date.today()
obj__index = Dict('index')
def condition(self):
return Dict('actif', default=False)(self)
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