diff --git a/modules/creditmutuel/browser.py b/modules/creditmutuel/browser.py index 67edadb0a901d7eac3beed0c0f3ead1116cd4884..7a7cc777f173fe8a7696d74d82eb024be310f1fd 100644 --- a/modules/creditmutuel/browser.py +++ b/modules/creditmutuel/browser.py @@ -53,7 +53,8 @@ ExternalTransferPage, RevolvingLoanDetails, RevolvingLoansList, ErrorPage, SubscriptionPage, NewCardsListPage, CardPage2, FiscalityConfirmationPage, ConditionsPage, MobileConfirmationPage, UselessPage, DecoupledStatePage, CancelDecoupled, - OtpValidationPage, OtpBlockedErrorPage, TwoFAUnabledPage + OtpValidationPage, OtpBlockedErrorPage, TwoFAUnabledPage, + LoansOperationsPage, ) @@ -108,6 +109,8 @@ class CreditMutuelBrowser(TwoFactorBrowser): r'/(?P.*)fr/banque/nr/nr_devbooster.aspx.*', r'(?P.*)fr/banque/CRP8_GESTPMONT.aspx\?webid=.*&trnref=.*&contract=\d+&cardid=.*&cardmonth=\d+', OperationsPage) + # This loans_operations contains operation for some loans, but not all of them. + loans_operations = URL(r'/(?P.*)fr/banque/gec9.aspx.*', LoansOperationsPage) coming = URL(r'/(?P.*)fr/banque/mvts_instance.cgi.*', ComingPage) info = URL(r'/(?P.*)fr/banque/BAD.*', EmptyPage) change_pass = URL(r'/(?P.*)fr/validation/change_password.cgi', diff --git a/modules/creditmutuel/pages.py b/modules/creditmutuel/pages.py index 6377d2c406058c783ddf851aee6224334dd6eabe..f9d298d858e083d0d3dd9ea8438a610247f5cec8 100644 --- a/modules/creditmutuel/pages.py +++ b/modules/creditmutuel/pages.py @@ -30,7 +30,8 @@ from weboob.browser.pages import HTMLPage, FormNotFound, LoggedPage, pagination, XMLPage, PartialHTMLPage from weboob.browser.elements import ListElement, ItemElement, SkipItem, method, TableElement from weboob.browser.filters.standard import ( - Filter, Env, CleanText, CleanDecimal, Field, Regexp, Async, AsyncLoad, Date, Format, Type, Currency, + Filter, Env, CleanText, CleanDecimal, Field, Regexp, Async, + AsyncLoad, Date, Format, Type, Currency, ) from weboob.browser.filters.html import Link, Attr, TableCell, ColumnNotFound from weboob.exceptions import ( @@ -207,6 +208,7 @@ def get_error_message(self): return CleanText('//div[contains(@class, "bloctxt err")]')(self.doc) + class EmptyPage(LoggedPage, HTMLPage): REFRESH_MAX = 10.0 @@ -804,6 +806,7 @@ class Transaction(FrenchTransaction): (re.compile(r'^CHEQUE( (?P.*))?$'), FrenchTransaction.TYPE_CHECK), (re.compile(r'^(F )?COTIS\.? (?P.*)'), FrenchTransaction.TYPE_BANK), (re.compile(r'^(REMISE|REM CHQ) (?P.*)'), FrenchTransaction.TYPE_DEPOSIT), + (re.compile(r'^(?P(ÉCHÉANCE|Echéance)).*'), FrenchTransaction.TYPE_LOAN_PAYMENT), ] _is_coming = False @@ -825,7 +828,11 @@ class get_history(Pagination, Transaction.TransactionsElement): item_xpath = '//table[has-class("liste")]//tbody/tr' class item(Transaction.TransactionElement): - condition = lambda self: len(self.el.xpath('./td')) >= 3 and len(self.el.xpath('./td[@class="i g" or @class="p g" or contains(@class, "_c1")]')) > 0 + def condition(self): + return ( + len(self.el.xpath('./td')) >= 3 + and len(self.el.xpath('./td[@class="i g" or @class="p g" or contains(@class, "_c1")]')) > 0 + ) class OwnRaw(Filter): def __call__(self, item): @@ -890,6 +897,42 @@ def get_balance(self): return CleanDecimal.French('//span[contains(text(), "Dont opérations enregistrées")]', default=NotAvailable)(self.doc) +class LoansOperationsPage(OperationsPage): + @method + class get_history(Pagination, Transaction.TransactionsElement): + head_xpath = '//table[has-class("liste")]/thead/tr/th' + item_xpath = '//table[has-class("liste")]/tr' + + class item(Transaction.TransactionElement): + def condition(self): + return ( + len(self.el.xpath('./td')) >= 3 + and len(self.el.xpath('./td[@class="i g" or @class="p g" or contains(@class, "_c1")]')) > 0 + and 'Echéance' in CleanText(TableCell('raw'))(self) + and 'Intérêts' in CleanText(TableCell('raw'))(self) + ) + + # Crédit = Echéance / Débit = Intérêts (and Assurance sometimes) + # 'Intérêts' do not affect the loans value. + obj_gross_amount = CleanDecimal.French(TableCell('credit')) + + # Need to set it manually to NotAvailable otherwise Transaction.TransactionElement + # set its value to TableCell('credit') + obj_amount = NotAvailable + + def obj_commission(self): + raw = Field('raw')(self) + if 'Assurance' in raw and 'Intérêts' in raw: + # There is 2 values in the 'debit' TableCell if we have + # Assurance and Intérêts... + interets, assurance = Regexp(CleanText(TableCell('debit')), r'([\d, ]+)', r'\1', nth='*')(self) + return ( + CleanDecimal.French(sign=lambda x: -1).filter(interets) + - CleanDecimal.French().filter(assurance) + ) + return CleanDecimal.French(TableCell('debit'), sign=lambda x: -1)(self) + + class CardsOpePage(OperationsPage): def select_card(self, card_number): if CleanText('//select[@id="iso"]', default=None)(self.doc):