Commit 10956b61 authored by Quentin Defenouillere's avatar Quentin Defenouillere Committed by Vincent A

[bnporc] Implemented Market Orders for PP connections

parent 0b1be452
......@@ -96,6 +96,10 @@ class BNPCompany(LoginBrowser):
def iter_investment(self, account):
raise NotImplementedError()
@need_login
def iter_market_orders(self, account):
raise NotImplementedError()
@need_login
def get_transfer_accounts(self):
raise NotImplementedError()
......
......@@ -208,6 +208,11 @@ class BNPEnterprise(LoginBrowser):
for inv in self.page.iter_investment():
yield inv
@need_login
def iter_market_orders(self, account):
self.logger.warning('This is an "enterprise" connection, market orders are not implemented.')
raise NotImplementedError()
@need_login
def get_profile(self):
self.auth.go()
......
......@@ -124,6 +124,9 @@ class BNPorcModule(
def iter_investment(self, account):
return self.browser.iter_investment(account)
def iter_market_orders(self, account):
return self.browser.iter_market_orders(account)
def iter_transfer_recipients(self, origin_account):
if self.config['website'].get() != 'pp':
raise NotImplementedError()
......
......@@ -49,7 +49,7 @@ from weboob.tools.capabilities.bank.investments import create_french_liquidity
from .pages import (
LoginPage, AccountsPage, AccountsIBANPage, HistoryPage, TransferInitPage,
ConnectionThresholdPage, LifeInsurancesPage, LifeInsurancesHistoryPage,
LifeInsurancesDetailPage, NatioVieProPage, CapitalisationPage,
LifeInsurancesDetailPage, NatioVieProPage, CapitalisationPage, MarketOrdersPage,
MarketListPage, MarketPage, MarketHistoryPage, MarketSynPage, BNPKeyboard,
RecipientsPage, ValidateTransferPage, RegisterTransferPage, AdvisorPage,
AddRecipPage, ActivateRecipPage, ProfilePage, ListDetailCardPage, ListErrorPage,
......@@ -112,6 +112,7 @@ class BNPParibasBrowser(LoginBrowser, StatesMixin):
market_syn = URL(r'pe-war/rpc/synthesis/get', MarketSynPage)
market = URL(r'pe-war/rpc/portfolioDetails/get', MarketPage)
market_history = URL(r'/pe-war/rpc/turnOverHistory/get', MarketHistoryPage)
market_orders = URL(r'/pe-war/rpc/orderDetailList/get', MarketOrdersPage)
recipients = URL(r'/virement-wspl/rest/listerBeneficiaire', RecipientsPage)
add_recip = URL(r'/virement-wspl/rest/ajouterBeneficiaire', AddRecipPage)
......@@ -374,11 +375,11 @@ class BNPParibasBrowser(LoginBrowser, StatesMixin):
self.market_list.go(json={}, method='POST')
except ServerError:
self.logger.warning("An Internal Server Error occurred")
return iter([])
return []
for market_acc in self.page.get_list():
if account.number[-4:] == market_acc['securityAccountNumber'][-4:] and not account.iban:
# Sometimes generate an Internal Server Error ...
try:
# Sometimes generates an Internal Server Error ...
self.market.go(json={
"securityAccountNumber": market_acc['securityAccountNumber'],
})
......@@ -387,7 +388,40 @@ class BNPParibasBrowser(LoginBrowser, StatesMixin):
break
return self.page.iter_investments()
return iter([])
return []
@need_login
def iter_market_orders(self, account):
if (
account.type not in (Account.TYPE_MARKET, account.TYPE_PEA)
or 'espèces' in account.label.lower()
):
return []
try:
self.market_list.go(json={}, method='POST')
except ServerError:
self.logger.warning('An Internal Server Error occurred')
return []
for market_acc in self.page.get_list():
if account.number[-4:] == market_acc['securityAccountNumber'][-4:] and not account.iban:
json = {
'securityAccountNumber': market_acc['securityAccountNumber'],
'filterCriteria': [],
'sortColumn': 'orderDateTransmission',
'sortType': 'desc',
}
try:
# Sometimes generates an Internal Server Error ...
self.market_orders.go(json=json)
except ServerError:
self.logger.warning('An Internal Server Error occurred')
break
return self.page.iter_market_orders()
# In case we haven't found the account with get_list
return []
@need_login
def iter_recipients(self, origin_account_id):
......
......@@ -45,7 +45,9 @@ from weboob.capabilities.bank import (
Emitter, EmitterNumberType, TransferStatus,
TransferDateType,
)
from weboob.capabilities.wealth import Investment
from weboob.capabilities.wealth import (
Investment, MarketOrder, MarketOrderDirection,
)
from weboob.capabilities.base import empty
from weboob.capabilities.contact import Advisor
from weboob.capabilities.profile import Person, ProfileMissing
......@@ -58,7 +60,7 @@ from weboob.tools.capabilities.bank.iban import rib2iban, rebuild_rib, is_iban_v
from weboob.tools.capabilities.bank.transactions import FrenchTransaction, parse_with_patterns
from weboob.tools.captcha.virtkeyboard import GridVirtKeyboard
from weboob.tools.date import parse_french_date
from weboob.tools.capabilities.bank.investments import is_isin_valid
from weboob.tools.capabilities.bank.investments import is_isin_valid, IsinCode
from weboob.tools.compat import unquote_plus
from weboob.tools.html import html2text
......@@ -366,8 +368,10 @@ class AccountsPage(BNPPage):
LABEL_TO_TYPE = {
'PEA Espèces': Account.TYPE_PEA,
'PEA PME Espèces': Account.TYPE_PEA,
'PEA Titres': Account.TYPE_PEA,
'PEL': Account.TYPE_SAVINGS,
'BNPP MP PERP': Account.TYPE_PERP,
'Plan Epargne Retraite Particulier': Account.TYPE_PERP,
'Crédit immobilier': Account.TYPE_MORTGAGE,
'Réserve Provisio': Account.TYPE_REVOLVING_CREDIT,
......@@ -996,6 +1000,57 @@ class MarketHistoryPage(BNPPage):
yield tr
MARKET_ORDER_DIRECTIONS = {
'Achat': MarketOrderDirection.BUY,
'Vente': MarketOrderDirection.SALE,
}
class MarketOrdersPage(BNPPage):
@method
class iter_market_orders(DictElement):
item_xpath = 'contentList'
class item(ItemElement):
klass = MarketOrder
# Note: there is no information on the order type
obj_id = CleanText(Dict('orderReference'))
obj_label = CleanText(Dict('securityName'))
obj_state = CleanText(Dict('orderStatusLabel'))
obj_code = IsinCode(CleanText(Dict('securityCode')), default=NotAvailable)
obj_stock_market = CleanText(Dict('stockExchangeName'))
obj_date = FromTimestamp(
Eval(lambda t: t / 1000, Dict('orderDateTransmission'))
)
obj_direction = Map(
CleanText(Dict('orderNatureLabel')),
MARKET_ORDER_DIRECTIONS,
MarketOrderDirection.UNKNOWN
)
def obj_quantity(self):
if empty(Dict('quantity')(self)):
return NotAvailable
return Decimal(str(Dict('quantity')(self)))
def obj_unitprice(self):
if empty(Dict('executionPrice')(self)):
return NotAvailable
return Decimal(str(Dict('executionPrice')(self)))
def obj_ordervalue(self):
if empty(Dict('limitPrice')(self)):
return NotAvailable
return Decimal(str(Dict('limitPrice')(self)))
def obj_currency(self):
# Most of the times the currency is set to null
if empty(Dict('orderCurrency')(self)):
return NotAvailable
return Currency(Dict('orderCurrency'), default=NotAvailable)(self)
class AdvisorPage(BNPPage):
def has_error(self):
return (self.doc.get('message') == 'Erreur technique')
......
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