From 36a9bd4d9a02232b360925ab6d9d258e8ea1132d Mon Sep 17 00:00:00 2001 From: Quentin Defenouillere Date: Wed, 6 Jan 2021 17:03:41 +0100 Subject: [PATCH] [carrefourbanque] Fix card history and balance The card index was hardcoded to "0" so we were always fetching the same transactions for all cards. Also handled balance for cards that don't have an "en cours" balance. Also handled the "no transaction" case. --- modules/carrefourbanque/browser.py | 7 ++++-- modules/carrefourbanque/pages.py | 39 +++++++++++++++++++++++++++--- 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/modules/carrefourbanque/browser.py b/modules/carrefourbanque/browser.py index b5be98d7c8..9f684120be 100644 --- a/modules/carrefourbanque/browser.py +++ b/modules/carrefourbanque/browser.py @@ -19,6 +19,7 @@ from __future__ import absolute_import, unicode_literals +import re from time import sleep from weboob.browser import LoginBrowser, URL, need_login, StatesMixin @@ -163,6 +164,8 @@ def iter_history(self, account): elif account.type == Account.TYPE_CARD: assert self.card_history.is_here() + card_index = re.search(r'[?&]index=(\d+)', account.url).group(1) + previous_date = self.page.get_previous_date() # the website stores the transactions over more or less 1 year # the transactions are displayed 40 by 40 in a dynamic table @@ -176,7 +179,7 @@ def iter_history(self, account): # if we do the call without sending a dateRecup it will return the 40 first transactions twice # it will also do with a random timestamp # in this particular case dateRecup can be any value as long as it's not an empty string or a timestamp - self.card_history_json.go(data={'dateRecup': 'needToNotBeEmpty', 'index': 0}) + self.card_history_json.go(data={'dateRecup': 'needToNotBeEmpty', 'index': card_index}) previous_date = self.page.get_last_timestamp() if previous_date: @@ -184,7 +187,7 @@ def iter_history(self, account): total = 0 loop_limit = 500 for page in range(loop_limit): - self.card_history_json.go(data={'dateRecup': previous_date, 'index': 0}) + self.card_history_json.go(data={'dateRecup': previous_date, 'index': card_index}) previous_date = self.page.get_previous_date() it = iter(self.page.iter_history()) diff --git a/modules/carrefourbanque/pages.py b/modules/carrefourbanque/pages.py index f24374e788..6ae0bb3190 100644 --- a/modules/carrefourbanque/pages.py +++ b/modules/carrefourbanque/pages.py @@ -35,7 +35,7 @@ from weboob.browser.filters.json import Dict from weboob.capabilities.bank import Account from weboob.capabilities.wealth import Investment -from weboob.capabilities.base import NotAvailable +from weboob.capabilities.base import NotAvailable, empty from weboob.tools.capabilities.bank.transactions import FrenchTransaction from weboob.exceptions import ActionNeeded @@ -195,7 +195,9 @@ class item_account_generic(ItemElement): def obj_balance(self): balance = CleanDecimal('.//div[contains(@class, "right_col")]//h2[1]', replace_dots=True)(self) - return (-balance if Field('type')(self) in (Account.TYPE_LOAN,) else balance) + if Field('type')(self) in (Account.TYPE_LOAN, ): + return -balance + return balance obj_currency = Currency('.//div[contains(@class, "right_col")]//h2[1]') obj_label = CleanText('.//div[contains(@class, "leftcol")]//h2[1]') @@ -250,8 +252,32 @@ class item(item_account_generic): obj_type = Account.TYPE_CARD def obj_balance(self): - available = CleanDecimal('.//p[contains(., "encours depuis le")]//preceding-sibling::h2', default=None, replace_dots=True)(self) - return NotAvailable if not available else -available + available = CleanDecimal( + './/p[contains(., "encours depuis le")]//preceding-sibling::h2', + default=None, + replace_dots=True + )(self) + if available is not None: + return -available + + # No "en cours" available: return - (total_amount - available_amount) + total_amount = CleanDecimal.French( + Regexp( + CleanText('.//p[text()[contains(., "plafond de")]]'), + r'plafond de ([0-9, ]+)', + default=NotAvailable + ), + default=NotAvailable + )(self) + + available_amount = CleanDecimal.French( + './/p[contains(text(), "disponibles à crédit")]//preceding-sibling::h2', + default=NotAvailable + )(self) + + if empty(total_amount) or empty(available_amount): + return NotAvailable + return - (total_amount - available_amount) @method class iter_saving_accounts(ListElement): # livrets @@ -367,6 +393,11 @@ def on_load(self): if isinstance(self.doc['tab_historique'], dict): self.doc['tab_historique'] = sorted(self.doc['tab_historique'].values(), key=lambda x: x['timestampOperation'], reverse=True) + elif self.doc['tab_historique'] is None: + # No transaction available, set value to empty dict + # instead of null since we need an iterable + self.doc['tab_historique'] = {} + @method class iter_history(DictElement): item_xpath = 'tab_historique' -- GitLab