class get_transfer(ItemElement): klass = Transfer obj_label = CleanText( '//div[@id="transfer-label"]/span[@class="transfer__account-value"]' ) obj_amount = CleanDecimal( '//div[@id="transfer-amount"]/span[@class="transfer__account-value"]', replace_dots=True) obj_currency = CleanCurrency( '//div[@id="transfer-amount"]/span[@class="transfer__account-value"]' ) obj_account_label = CleanText('//span[@id="transfer-origin-account"]') obj_recipient_label = CleanText( '//span[@id="transfer-destination-account"]') def obj_exec_date(self): type_ = CleanText( '//div[@id="transfer-type"]/span[@class="transfer__account-value"]' )(self) if type_ == 'Ponctuel': return datetime.date.today() elif type_ == 'Différé': return Date(CleanText( '//div[@id="transfer-date"]/span[@class="transfer__account-value"]' ), dayfirst=True)(self)
class item(ItemElement): klass = Account def condition(self): if 'Votre carte est annulée' in CleanText( './/span[@id="cardSORStatus"]')(self): self.logger.warning('skipping cancelled card %r', self.obj_id(self)) return False return True obj_id = CleanText( './/td[@class="cardArtColWidth"]/div[@class="summaryTitles"]') obj_label = CleanText('.//span[@class="cardTitle"]') obj_type = Account.TYPE_CARD obj_currency = CleanCurrency( './/td[@id="colOSBalance"]/div[@class="summaryValues makeBold"]' ) def obj_balance(self): return -abs( parse_decimal( CleanText( './/td[@id="colOSBalance"]/div[@class="summaryValues makeBold"]' )(self))) obj_url = AbsoluteLink( './/a[text()="View Latest Transactions"]', default=AbsoluteLink( './/a[span[text()="Online Statement"] or text()="Détail de vos opérations"]' ))
class get_main_account(ItemElement): klass = Account obj_id = CleanText(Dict('comptePrincipal/numeroCompte')) obj_number = CleanText(Dict('comptePrincipal/numeroCompte')) obj_label = CleanText(Dict('comptePrincipal/libelleProduit')) def obj_balance(self): balance = Dict('comptePrincipal/solde', default=NotAvailable)(self) if not empty(balance): return Eval(float_to_decimal, balance)(self) return NotAvailable obj_currency = CleanCurrency(Dict('comptePrincipal/idDevise')) obj__index = Dict('comptePrincipal/index') obj__category = Dict('comptePrincipal/grandeFamilleProduitCode', default=None) obj__id_element_contrat = CleanText( Dict('comptePrincipal/idElementContrat')) obj__fam_product_code = CleanText( Dict('comptePrincipal/codeFamilleProduitBam')) obj__fam_contract_code = CleanText( Dict('comptePrincipal/codeFamilleContratBam')) def obj_type(self): _type = Map(CleanText(Dict('comptePrincipal/libelleUsuelProduit')), ACCOUNT_TYPES, Account.TYPE_UNKNOWN)(self) if _type == Account.TYPE_UNKNOWN: self.logger.warning( 'We got an untyped account: please add "%s" to ACCOUNT_TYPES.' % CleanText( Dict('comptePrincipal/libelleUsuelProduit'))(self)) return _type
def get_transfer(self): transfer = Transfer() # FIXME all will probably fail if an account has a user-chosen label with "IBAN :" or "n°" amount_xpath = '//fieldset//p[has-class("montant")]' transfer.amount = CleanDecimal.French(amount_xpath)(self.doc) transfer.currency = CleanCurrency(amount_xpath)(self.doc) if self.is_sent(): transfer.account_id = Regexp( CleanText('//p[@class="nomarge"][span[contains(text(),' '"Compte émetteur")]]/text()'), r'n°(\d+)')(self.doc) base = CleanText( '//fieldset//table[.//span[contains(text(), "Compte bénéficiaire")]]' + '//td[contains(text(),"n°") or contains(text(),"IBAN :")]//text()', newlines=False)(self.doc) transfer.recipient_id = Regexp( None, r'IBAN : ([^\n]+)|n°(\d+)').filter(base) transfer.recipient_id = transfer.recipient_id.replace(' ', '') if 'IBAN' in base: transfer.recipient_iban = transfer.recipient_id transfer.exec_date = MyDate( CleanText( '//p[@class="nomarge"][span[contains(text(), "Date de l\'ordre")]]/text()' ))(self.doc) else: transfer.account_id = Regexp( CleanText( '//fieldset[.//h3[contains(text(), "Compte émetteur")]]//p' ), r'n°(\d+)')(self.doc) base = CleanText( '//fieldset[.//h3[contains(text(), "Compte bénéficiaire")]]//text()', newlines=False)(self.doc) transfer.recipient_id = Regexp( None, r'IBAN : ([^\n]+)|n°(\d+)').filter(base) transfer.recipient_id = transfer.recipient_id.replace(' ', '') if 'IBAN' in base: transfer.recipient_iban = transfer.recipient_id transfer.exec_date = MyDate( CleanText( '//fieldset//p[span[contains(text(), "Virement unique le :")]]/text()' ))(self.doc) transfer.label = CleanText( '//fieldset//p[span[contains(text(), "Référence opération")]]')( self.doc) transfer.label = re.sub(r'^Référence opération(?:\s*):', '', transfer.label).strip() return transfer
class item(ItemElement): IGNORED_ACCOUNT_FAMILIES = ( 'MES ASSURANCES', 'VOS ASSURANCES', ) klass = Account def obj_id(self): # Loan/credit ids may be duplicated so we use the contract number for now: if Field('type')(self) in (Account.TYPE_LOAN, Account.TYPE_CONSUMER_CREDIT, Account.TYPE_REVOLVING_CREDIT): return CleanText(Dict('idElementContrat'))(self) return CleanText(Dict('numeroCompte'))(self) obj_number = CleanText(Dict('numeroCompte')) obj_label = CleanText(Dict('libelleProduit')) obj_currency = CleanCurrency(Dict('idDevise')) obj__index = Dict('index') obj__category = Coalesce(Dict('grandeFamilleProduitCode', default=None), Dict('sousFamilleProduit/niveau', default=None), default=None) obj__id_element_contrat = CleanText(Dict('idElementContrat')) obj__fam_product_code = CleanText(Dict('codeFamilleProduitBam')) obj__fam_contract_code = CleanText(Dict('codeFamilleContratBam')) def obj_type(self): if CleanText( Dict('libelleUsuelProduit'))(self) in ('HABITATION', ): # No need to log warning for "assurance" accounts return NotAvailable _type = Map(CleanText(Dict('libelleUsuelProduit')), ACCOUNT_TYPES, Account.TYPE_UNKNOWN)(self) if _type == Account.TYPE_UNKNOWN: self.logger.warning( 'There is an untyped account: please add "%s" to ACCOUNT_TYPES.' % CleanText(Dict('libelleUsuelProduit'))(self)) return _type def obj_balance(self): balance = Dict('solde', default=None)(self) if balance: return Eval(float_to_decimal, balance)(self) # We will fetch the balance with account_details return NotAvailable def condition(self): # Ignore insurances (plus they all have identical IDs) # Ignore some credits not displayed on the website return CleanText(Dict('familleProduit/libelle', default=''))(self) not in self.IGNORED_ACCOUNT_FAMILIES \ and 'non affiche' not in CleanText(Dict('sousFamilleProduit/libelle', default=''))(self) \ and 'Inactif' not in CleanText(Dict('libelleSituationContrat', default=''))(self)
class get_main_account(ItemElement): klass = Account obj_id = CleanText(Dict('comptePrincipal/numeroCompte')) obj_number = CleanText(Dict('comptePrincipal/numeroCompte')) def obj_owner_type(self): return self.page.get_owner_type() def obj_label(self): if Field('owner_type')(self) == AccountOwnerType.PRIVATE: # All the accounts have the same owner if it is private, # so adding the owner in the libelle is useless. return CleanText(Dict('comptePrincipal/libelleProduit'))(self) return Format( '%s %s', CleanText(Dict('comptePrincipal/libelleProduit')), CleanText(Dict('comptePrincipal/libellePartenaireBam')), )(self) def obj_balance(self): balance = Dict('comptePrincipal/solde', default=NotAvailable)(self) if not empty(balance): return Eval(float_to_decimal, balance)(self) return NotAvailable obj_currency = CleanCurrency(Dict('comptePrincipal/idDevise')) obj__index = Dict('comptePrincipal/index') obj__category = Dict('comptePrincipal/grandeFamilleProduitCode', default=None) obj__id_element_contrat = CleanText( Dict('comptePrincipal/idElementContrat')) obj__fam_product_code = CleanText( Dict('comptePrincipal/codeFamilleProduitBam')) obj__fam_contract_code = CleanText( Dict('comptePrincipal/codeFamilleContratBam')) def obj_type(self): _type = Map(CleanText(Dict('comptePrincipal/libelleUsuelProduit')), ACCOUNT_TYPES, Account.TYPE_UNKNOWN)(self) if _type == Account.TYPE_UNKNOWN: self.logger.warning( 'We got an untyped account: please add "%s" to ACCOUNT_TYPES.', CleanText( Dict('comptePrincipal/libelleUsuelProduit'))(self)) return _type