diff --git a/modules/bnporc/pp/browser.py b/modules/bnporc/pp/browser.py index b6e94aa3687ab471aeed420accbea562d20687f6..6f6eaab5e7b631ce727d68990780e5bd9a1a4a08 100644 --- a/modules/bnporc/pp/browser.py +++ b/modules/bnporc/pp/browser.py @@ -51,7 +51,7 @@ UselessPage, TransferAssertionError, LoanDetailsPage, ) -from .document_pages import DocumentsPage, TitulairePage +from .document_pages import DocumentsPage, DocumentsResearchPage, TitulairePage __all__ = ['BNPPartPro', 'HelloBank'] @@ -126,7 +126,8 @@ class BNPParibasBrowser(JsonBrowserMixin, LoginBrowser, StatesMixin): advisor = URL(r'/conseiller-wspl/rest/monConseiller', AdvisorPage) titulaire = URL(r'/demat-wspl/rest/listerTitulairesDemat', TitulairePage) - document = URL(r'/demat-wspl/rest/rechercheCriteresDemat', DocumentsPage) + document = URL(r'/demat-wspl/rest/listerDocuments', DocumentsPage) + document_research = URL(r'/demat-wspl/rest/rechercheCriteresDemat', DocumentsResearchPage) profile = URL(r'/kyc-wspl/rest/informationsClient', ProfilePage) list_detail_card = URL(r'/udcarte-wspl/rest/listeDetailCartes', ListDetailCardPage) @@ -546,18 +547,37 @@ def iter_documents(self, subscription): titulaires = self.titulaire.go().get_titulaires() # Calling '/demat-wspl/rest/listerDocuments' before the request on 'document' # is necessary when you specify an ikpi, otherwise no documents are returned - self.location('/demat-wspl/rest/listerDocuments') + self.document.go() + docs = [] + id_docs = [] + iter_documents_functions = [self.page.iter_documents, self.page.iter_documents_pro] + for iter_documents in iter_documents_functions: + for doc in iter_documents(sub_id=subscription.id, sub_number=subscription._number, baseurl=self.BASEURL): + docs.append(doc) + id_docs.append(doc.id) + + # documents are sorted by type then date, sort them directly by date + docs = sorted(docs, key=lambda doc: doc.date, reverse=True) + for doc in docs: + yield doc + # When we only have one titulaire, no need to use the ikpi parameter in the request, # all document are provided with this simple request data = { 'dateDebut': (datetime.now() - relativedelta(years=3)).strftime('%d/%m/%Y'), 'dateFin': datetime.now().strftime('%d/%m/%Y'), } + + len_titulaires = len(titulaires) + self.logger.info('The total number of titulaires on this connection is %s.', len_titulaires) # Ikpi is necessary for multi titulaires accounts to get each document of each titulaires - if len(titulaires) > 1: + if len_titulaires > 1: data['ikpiPersonne'] = subscription._iduser - self.document.go(json=data) - return self.page.iter_documents(sub_id=subscription.id, sub_number=subscription._number, baseurl=self.BASEURL) + + self.document_research.go(json=data) + for doc in self.page.iter_documents(sub_id=subscription.id, sub_number=subscription._number, baseurl=self.BASEURL): + if doc.id not in id_docs: + yield doc @need_login def iter_subscription(self): @@ -576,6 +596,7 @@ def iter_subscription(self): sub._iduser = acc._iduser yield sub + class BNPPartPro(BNPParibasBrowser): BASEURL_TEMPLATE = r'https://%s.bnpparibas/' BASEURL = BASEURL_TEMPLATE % 'mabanque' diff --git a/modules/bnporc/pp/document_pages.py b/modules/bnporc/pp/document_pages.py index 6db2080e93201aabcaac47a3ca01ede2591e9570..e4a02e7ff11c4002db83c9d0d910ceb8db394ecf 100644 --- a/modules/bnporc/pp/document_pages.py +++ b/modules/bnporc/pp/document_pages.py @@ -42,6 +42,7 @@ r'Factures': DocumentTypes.BILL, } + def get_document_type(family): for patt, type in patterns.items(): if re.search(re.escape(patt), family): @@ -54,67 +55,92 @@ def get_titulaires(self): return set([t['idKpiTitulaire'] for t in self.doc['data']['listeTitulairesDemat']['listeTitulaires']]) +class ItemDocument(ItemElement): + klass = Document + + def condition(self): + # There is two type of json, the one with the ibancrypte in it + # and the one with the idcontrat in it, here we check if + # the document belong to the subscription. + if 'ibanCrypte' in self.el: + return Env('sub_id')(self) in Dict('ibanCrypte')(self) + else: + return Env('sub_number')(self) in Dict('idContrat')(self) + + obj_date = Date(Dict('dateDoc'), dayfirst=True) + obj_format = 'pdf' + obj_id = Format('%s_%s', Env('sub_id'), Dict('idDoc')) + + def obj_label(self): + if 'ibanCrypte' in self.el: + return '%s %s N° %s' % (Dict('dateDoc')(self), Dict('libelleSousFamille')(self), Dict('numeroCompteAnonymise')(self)) + else: + return '%s %s N° %s' % (Dict('dateDoc')(self), Dict('libelleSousFamille')(self), Dict('idContrat')(self)) + + def obj_url(self): + keys_to_copy = { + 'idDocument' :'idDoc', + 'dateDocument': 'dateDoc', + 'idLocalisation': 'idLocalisation', + 'viDocDocument': 'viDocDocument', + } + # Here we parse the json with ibancrypte in it, for most cases + if 'ibanCrypte' in self.el: + url = 'demat-wspl/rest/consultationDocumentDemat?' + keys_to_copy.update({ + 'typeCpt': 'typeCompte', + 'familleDoc': 'famDoc', + 'ibanCrypte': 'ibanCrypte', + 'typeDoc': 'typeDoc', + 'consulted': 'consulted', + }) + request_params = {'typeFamille': 'R001', 'ikpiPersonne': ''} + # Here we parse the json with idcontrat in it. For the cases present + # on privee.mabanque where sometimes the doc url is different + else: + url = 'demat-wspl/rest/consultationDocumentSpecialBpfDemat?' + keys_to_copy.update({ + 'heureDocument': 'heureDoc', + 'numClient': 'numClient', + 'typeReport': 'typeReport', + }) + request_params = {'ibanCrypte': ''} + + for k, v in keys_to_copy.items(): + request_params[k] = Dict(v)(self) + + return Env('baseurl')(self) + url + urlencode(request_params) + + def obj_type(self): + return get_document_type(Dict('libelleSousFamille')(self)) + + class DocumentsPage(LoggedPage, JsonPage): @method class iter_documents(DictElement): + # * refer to the account, it can be 'Comptes chèques', 'Comptes d'épargne', etc... + item_xpath = 'data/listerDocumentDemat/mapReleves/*/listeDocument' + ignore_duplicate = True + + class item(ItemDocument): + pass + + @method + class iter_documents_pro(DictElement): + # * refer to the account, it can be 'Comptes chèques', 'Comptes d'épargne', etc... + item_xpath = 'data/listerDocumentDemat/mapRelevesPro/*/listeDocument' + ignore_duplicate = True + + class item(ItemDocument): + pass + + +class DocumentsResearchPage(LoggedPage, JsonPage): + @method + class iter_documents(DictElement): + # * refer to the account, it can be 'Comptes chèques', 'Comptes d'épargne', etc... item_xpath = 'data/rechercheCriteresDemat/*/*/listeDocument' ignore_duplicate = True - class item(ItemElement): - klass = Document - - def condition(self): - # There is two type of json, the one with the ibancrypte in it - # and the one with the idcontrat in it, here we check if - # the document belong to the subscritpion. - if 'ibanCrypte' in self.el: - return Env('sub_id')(self) in Dict('ibanCrypte')(self) - else: - return Env('sub_number')(self) in Dict('idContrat')(self) - - obj_date = Date(Dict('dateDoc'), dayfirst=True) - obj_format = 'pdf' - obj_id = Format('%s_%s', Env('sub_id'), Dict('idDoc')) - - def obj_label(self): - if 'ibanCrypte' in self.el: - return '%s %s N° %s' % (Dict('dateDoc')(self), Dict('libelleSousFamille')(self), Dict('numeroCompteAnonymise')(self)) - else: - return '%s %s N° %s' % (Dict('dateDoc')(self), Dict('libelleSousFamille')(self), Dict('idContrat')(self)) - - def obj_url(self): - keys_to_copy = { - 'idDocument' :'idDoc', - 'dateDocument': 'dateDoc', - 'idLocalisation': 'idLocalisation', - 'viDocDocument': 'viDocDocument', - } - # Here we parse the json with ibancrypte in it, for most cases - if 'ibanCrypte' in self.el: - url = 'demat-wspl/rest/consultationDocumentDemat?' - keys_to_copy.update({ - 'typeCpt': 'typeCompte', - 'familleDoc': 'famDoc', - 'ibanCrypte': 'ibanCrypte', - 'typeDoc': 'typeDoc', - 'consulted': 'consulted', - }) - request_params = {'typeFamille': 'R001', 'ikpiPersonne': ''} - # Here we parse the json with idcontrat in it. For the cases present - # on privee.mabanque where sometimes the doc url is different - else: - url = 'demat-wspl/rest/consultationDocumentSpecialBpfDemat?' - keys_to_copy.update({ - 'heureDocument': 'heureDoc', - 'numClient': 'numClient', - 'typeReport': 'typeReport', - }) - request_params = {'ibanCrypte': ''} - - for k, v in keys_to_copy.items(): - request_params[k] = Dict(v)(self) - - return Env('baseurl')(self) + url + urlencode(request_params) - - def obj_type(self): - return get_document_type(Dict('libelleSousFamille')(self)) + class item(ItemDocument): + pass