diff --git a/modules/cmes/browser.py b/modules/cmes/browser.py index b5e3df0ec996e772d0dce11519d35b5b1d23fcac..52cd4084fc1940098514b092b5b0e27e2dbc481c 100644 --- a/modules/cmes/browser.py +++ b/modules/cmes/browser.py @@ -182,6 +182,14 @@ def iter_pocket(self, account): for pocket in self.page.iter_ccb_pockets(account=account): yield pocket else: - for inv in self.iter_investment(account=account): - for pocket in self.page.iter_pocket(inv=inv): - yield pocket + form = self.page.get_investment_form() + for inv in self.page.iter_investments(account=account): + # Go to the investment details to get employee savings attributes + self.go_investment(form, inv._form_param) + if self.investments.is_here(): + try: + self.page.go_investment_details() + for pocket in self.page.iter_pockets(inv=inv): + yield pocket + finally: + self.page.go_back() diff --git a/modules/cmes/pages.py b/modules/cmes/pages.py index 1cae1df2be22140136a6a63da24ecab9ec18cb07..39365fb35923379a353e520936f58e276f13d641 100644 --- a/modules/cmes/pages.py +++ b/modules/cmes/pages.py @@ -22,12 +22,12 @@ import re from weboob.browser.pages import HTMLPage, LoggedPage -from weboob.browser.elements import ListElement, ItemElement, method +from weboob.browser.elements import ListElement, ItemElement, method, TableElement from weboob.browser.filters.standard import ( CleanText, CleanDecimal, Date, Regexp, Field, Currency, - Upper, MapIn, Eval, Title, + MapIn, Eval, Title, Env, ) -from weboob.browser.filters.html import Link +from weboob.browser.filters.html import Link, TableCell from weboob.capabilities.base import NotAvailable from weboob.capabilities.bank import Account from weboob.capabilities.wealth import Investment, Pocket @@ -123,7 +123,6 @@ def iter_investments(self, account): for row, elem_repartition, elem_pocket, elem_diff in self.iter_invest_rows(account=account): inv = Investment() inv._account = account - inv._el_pocket = elem_pocket inv.label = CleanText('.//td[1]')(row) inv._form_param = CleanText('.//td[1]/input/@name')(row) inv.valuation = CleanDecimal.French('.//td[2]')(row) @@ -148,23 +147,6 @@ def iter_investments(self, account): )(row) yield inv - def iter_pocket(self, inv): - if inv._el_pocket is not None: - for i, row in enumerate(inv._el_pocket.xpath('.//tr[position()>1]')): - pocket = Pocket() - pocket.id = "%s%s%s" % (inv._account.label, inv.label, i) - pocket.label = inv.label - pocket.investment = inv - pocket.amount = CleanDecimal.French('./td[2]')(row) - - if 'DISPONIBLE' in Upper(CleanText('./td[1]'))(row): - pocket.condition = Pocket.CONDITION_AVAILABLE - else: - pocket.condition = Pocket.CONDITION_DATE - pocket.availability_date = Date(Regexp(Upper(CleanText('./td[1]')), r'AU[\s]+(.*)'), dayfirst=True)(row) - - yield pocket - def iter_ccb_pockets(self, account): # CCB accounts have a specific table with more columns and specific attributes for row in self.doc.xpath('//th/div[contains(., "%s")]/ancestor::table//table/tbody/tr' % account.label): @@ -252,6 +234,13 @@ def obj_performance_history(self): return perfs +POCKET_CONDITIONS = { + 'retraite': Pocket.CONDITION_RETIREMENT, + 'disponibilites': Pocket.CONDITION_DATE, + 'immediate': Pocket.CONDITION_AVAILABLE, +} + + class InvestmentDetailsPage(LoggedPage, HTMLPage): def get_quantity(self): return CleanDecimal.French('//tr[th[text()="Nombre de parts"]]//em', default=NotAvailable)(self.doc) @@ -260,6 +249,39 @@ def go_back(self): go_back_url = Link('//a[@id="C:A"]')(self.doc) self.browser.location(go_back_url) + @method + class iter_pockets(TableElement): + item_xpath = '//table[contains(caption/span/text(), "Détail par échéance")]/tbody/tr' + head_xpath = '//table[contains(caption/span/text(), "Détail par échéance")]/thead//th' + + col_condition = 'Echéance' + col_amount = 'Montant investi' + col_quantity = 'Nombre de parts' + + class item(ItemElement): + klass = Pocket + + obj_investment = Env('inv') + obj_amount = CleanDecimal.French(TableCell('amount')) + obj_quantity = CleanDecimal.French(TableCell('quantity'), default=NotAvailable) + + def obj_label(self): + return Env('inv')(self).label + + def obj_condition(self): + condition_text = CleanText(TableCell('condition'), transliterate=True)(self) + condition = MapIn(self, POCKET_CONDITIONS, Pocket.CONDITION_UNKNOWN).filter(condition_text.lower()) + if condition == Pocket.CONDITION_UNKNOWN: + self.page.logger.warning('Unhandled availability condition for pockets: %s', condition_text) + return condition + + def obj_availability_date(self): + if Field('condition')(self) == Pocket.CONDITION_DATE: + return Date( + Regexp(CleanText(TableCell('condition')), r'Disponibilités (.*)'), + dayfirst=True, + )(self) + class OperationPage(LoggedPage, HTMLPage): # Most '_account_label' correspond 'account.label', but there are exceptions