# -*- coding: utf-8 -*-
# Copyright(C) 2016 Jean Walrave
#
# This file is part of a weboob module.
#
# This weboob module is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This weboob module 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 Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this weboob module. If not, see .
from __future__ import unicode_literals
from datetime import datetime
from dateutil.rrule import rrule, MONTHLY
from dateutil.relativedelta import relativedelta
from weboob.browser import LoginBrowser, need_login
from weboob.capabilities.base import find_object
from weboob.capabilities.bank import Account
from weboob.exceptions import BrowserIncorrectPassword, BrowserForbidden
from weboob.browser.url import URL
from weboob.tools.capabilities.bank.transactions import sorted_transactions
from .pages import (
LoginPage, AuthPage, AccountsPage, AccountHistoryViewPage, AccountHistoryPage,
ActionNeededPage, TransactionPage, MarketPage, InvestPage
)
__all__ = ['BNPEnterprise']
class BNPEnterprise(LoginBrowser):
BASEURL = 'https://secure1.entreprises.bnpparibas.net'
login = URL('/sommaire/jsp/identification.jsp',
'/sommaire/generateImg', LoginPage)
auth = URL('/sommaire/PseMenuServlet', AuthPage)
accounts = URL('/NCCPresentationWeb/e10_soldes/liste_soldes.do', AccountsPage)
account_history_view = URL('/NCCPresentationWeb/e10_soldes/init.do\?nccIdSelected=NCC_Soldes',
'/NCCPresentationWeb/e11_releve_op/init.do\?identifiant=(?P)'
'&typeSolde=(?P)&typeReleve=(?P)&typeDate=(?P)'
'&dateMin=(?P)&dateMax=(?P)&ajax=true',
'/NCCPresentationWeb/e11_releve_op/init.do', AccountHistoryViewPage)
account_coming_view = URL('/NCCPresentationWeb/m04_selectionCompteGroupe/init.do\?type=compte&identifiant=(?P)', AccountHistoryViewPage)
account_history = URL('/NCCPresentationWeb/e11_releve_op/listeOperations.do\?identifiant=(?P)&typeSolde=(?P)&typeReleve=(?P)&typeDate=(?P)&dateMin=(?P)&dateMax=(?P)&ajax=true',
'/NCCPresentationWeb/e11_releve_op/listeOperations.do', AccountHistoryPage)
account_coming = URL('/NCCPresentationWeb/e12_rep_cat_op/listOperations.do\?periode=date_valeur&identifiant=(?P)',
'/NCCPresentationWeb/e12_rep_cat_op/listOperations.do', AccountHistoryPage)
transaction_detail = URL(r'/NCCPresentationWeb/e21/getOptBDDF.do', TransactionPage)
invest = URL(r'/opcvm/lister-composition/afficher.do', InvestPage)
# The Market page is used only if there are several market accounts
market = URL(r'/opcvm/lister-portefeuilles/afficher.do', MarketPage)
renew_pass = URL('/sommaire/PseRedirectPasswordConnect', ActionNeededPage)
def __init__(self, config, *args, **kwargs):
super(BNPEnterprise, self).__init__(config['login'].get(), config['password'].get(), *args, **kwargs)
def do_login(self):
self.login.go()
if not self.login.is_here():
return
data = {}
data['txtAuthentMode'] = 'PASSWORD'
data['BEFORE_LOGIN_REQUEST'] = None
data['txtPwdUserId'] = self.username
data['gridpass_hidden_input'] = self.page.get_password(self.password)
self.auth.go(data=data)
if self.login.is_here():
raise BrowserIncorrectPassword
@need_login
def iter_accounts(self):
accounts = []
# Fetch checking accounts:
for account in self.accounts.stay_or_go().iter_accounts():
accounts.append(account)
# Fetch market accounts:
try:
self.market.go()
if self.market.is_here():
for market_account in self.page.iter_market_accounts():
market_account.parent = find_object(accounts, label=market_account._parent)
accounts.append(market_account)
elif self.invest.is_here():
# Redirected to invest page, meaning there is only 1 market account.
# We thus create an Account object for this unique market account.
account = self.page.get_unique_market_account()
account.parent = find_object(accounts, label=account._parent)
accounts.append(account)
except BrowserForbidden:
pass
return accounts
@need_login
def get_account(self, _id):
for account in self.iter_accounts():
if account.id == _id:
return account
@need_login
def iter_history(self, account):
# There is no available history for market accounts
if account.type == Account.TYPE_MARKET:
return []
return self._iter_history_base(account)
def _iter_history_base(self, account):
dformat = "%Y%m%d"
for date in rrule(MONTHLY, dtstart=(datetime.now() - relativedelta(months=12)), until=datetime.now())[::-1]:
history = []
self.account_history_view.go(
identifiant=account.iban, type_solde='C', type_releve='Previsionnel',
type_date='O', date_min=(date + relativedelta(days=1)).strftime(dformat),
date_max=(date + relativedelta(months=1)).strftime(dformat)
)
self.account_history.go(
identifiant=account.iban, type_solde='C', type_releve='Previsionnel',
type_date='O', date_min=(date + relativedelta(days=1)).strftime(dformat),
date_max=(date + relativedelta(months=1)).strftime(dformat)
)
for transaction in self.page.iter_history():
if transaction._coming:
self.logger.debug('skipping coming %r', transaction.to_dict())
continue
history.append(transaction)
for transaction in sorted_transactions(history):
yield transaction
@need_login
def iter_coming_operations(self, account):
# There is no available coming operation for market accounts
if account.type == Account.TYPE_MARKET:
return []
self.account_coming_view.go(identifiant=account.iban)
self.account_coming.go(identifiant=account.iban)
return self.page.iter_coming()
@need_login
def iter_investment(self, account):
if account.type != Account.TYPE_MARKET:
return
self.market.go()
# If there is more than one market account, we must fetch the account params:
if not account._unique:
if self.market.is_here():
token = self.page.get_token()
id_invest = self.page.get_id(label=account.label)
data = {"numeroCompte": id_invest, "_csrf": token}
self.location('/opcvm/lister-composition/redirect-afficher.do', data=data)
for inv in self.page.iter_investment():
yield inv
@need_login
def get_profile(self):
profile = self.account_history_view.go().get_profile()
return profile