support currencies

This commit is contained in:
Romain Bignon 2012-12-06 12:18:26 +01:00
commit d91dad2b2b
17 changed files with 95 additions and 30 deletions

View file

@ -72,15 +72,24 @@ class AccountsPage(BasePage):
account_type = self.ACCOUNT_TYPES.get(div.text.strip(), Account.TYPE_UNKNOWN)
for tr in div.getnext().xpath('.//tbody/tr'):
if not 'id' in tr.attrib:
continue
args = dict(parse_qsl(tr.attrib['id']))
tds = tr.findall('td')
if len(tds) < 4 or not 'identifiant' in args:
self.logger.warning('Unable to parse an account')
continue
account = Account()
account.id = args['identifiant']
account.label = u' '.join([u''.join([txt.strip() for txt in tds[1].itertext()]),
u''.join([txt.strip() for txt in tds[2].itertext()])]).strip()
account.type = account_type
account.balance = Decimal(FrenchTransaction.clean_amount(u''.join([txt.strip() for txt in tds[3].itertext()])))
balance = u''.join([txt.strip() for txt in tds[3].itertext()])
account.balance = Decimal(FrenchTransaction.clean_amount(balance))
account.currency = account.get_currency(balance)
account._params = params.copy()
account._params['dialogActionPerformed'] = 'SOLDE'
account._params['attribute($SEL_$%s)' % tr.attrib['id'].split('_')[0]] = tr.attrib['id'].split('_', 1)[1]

View file

@ -21,6 +21,7 @@
import re
from decimal import Decimal
from weboob.tools.capabilities.bank.transactions import FrenchTransaction
from weboob.capabilities.bank import Account
from weboob.capabilities.base import NotAvailable
from weboob.tools.browser import BasePage, BrokenPageError, BrowserPasswordExpired
@ -69,6 +70,7 @@ class AccountsList(BasePage):
account.label = u''+a.text.strip()
tds = tr.findall('td')
account.currency = account.get_currency(tds[3].find('a').text)
account.balance = self._parse_amount(tds[3].find('a'))
if tds[4].find('a') is not None:
account.coming = self._parse_amount(tds[4].find('a'))
@ -78,7 +80,7 @@ class AccountsList(BasePage):
return account
def _parse_amount(self, elem):
return Decimal(elem.text.replace('.', '').replace(',', '.').strip(u' \t\u20ac\xa0\n\r'))
return Decimal(FrenchTransaction.clean_amount(elem.text))
def get_list(self):
l = []

View file

@ -24,6 +24,7 @@ from decimal import Decimal
from weboob.capabilities.bank import Account
from weboob.tools.browser import BasePage
from weboob.tools.misc import to_unicode
from weboob.tools.capabilities.bank.transactions import FrenchTransaction
class AccountsList(BasePage):
@ -31,7 +32,6 @@ class AccountsList(BasePage):
pass
def get_list(self):
l = []
for div in self.document.getiterator('div'):
if div.attrib.get('id', '') == 'synthese-list':
for tr in div.getiterator('tr'):
@ -57,7 +57,8 @@ class AccountsList(BasePage):
balance = td.text
else:
balance = span.text
balance = balance.strip(u' \n\t€+').replace(',', '.').replace(' ', '')
account.currency = account.get_currency(balance)
balance = FrenchTransaction.clean_amount(balance)
if balance != "":
account.balance = Decimal(balance)
else:
@ -66,6 +67,4 @@ class AccountsList(BasePage):
else:
# because of some weird useless <tr>
if account.id is not None:
l.append(account)
return l
yield account

View file

@ -23,6 +23,7 @@ from decimal import Decimal
from weboob.capabilities.bank import Account, AccountNotFound
from weboob.tools.browser import BasePage
from weboob.tools.misc import to_unicode
from weboob.tools.capabilities.bank.transactions import FrenchTransaction
__all__ = ['AccountList']
@ -63,7 +64,8 @@ class AccountList(BasePage):
tmp_balance = tmp[0].text
account.id = tmp_id
account.balance = Decimal(''.join(tmp_balance.replace('.','').replace(',','.').split()))
account.currency = account.get_currency(tmp_balance)
account.balance = Decimal(FrenchTransaction.clean_amount(tmp_balance))
self.account_list.append(account)
def get_account(self, id):

View file

@ -84,7 +84,7 @@ class AccountsPage(BredBasePage):
continue
try:
amount = sum([Decimal(txt.strip(' EUR').replace(' ', '').replace(',', '.')) for txt in cols[-1].itertext() if len(txt.strip()) > 0])
amount = sum([Decimal(FrenchTransaction.clean_amount(txt)) for txt in cols[-1].itertext() if len(txt.strip()) > 0])
except InvalidOperation:
continue
@ -117,6 +117,7 @@ class AccountsPage(BredBasePage):
account.id = u'%s.%s' % (args['numero_compte'], args['numero_poste'])
account.label = to_unicode(a.attrib.get('alt', a.text.strip()))
account.balance = amount
account.currency = [account.get_currency(txt) for txt in cols[-1].itertext() if len(txt.strip()) > 0][0]
account._card_links = []
accounts.append(account)

View file

@ -110,7 +110,8 @@ class IndexPage(BasePage):
account.label = unicode(a.text.strip())
account.type = account_type
amount = u''.join([txt.strip() for txt in tds[-1].itertext()])
account.balance = Decimal(FrenchTransaction.clean_amount(amount.rstrip(' EUR')))
account.balance = Decimal(FrenchTransaction.clean_amount(amount))
account.currency = account.get_currency(amount)
yield account
def go_history(self, id):

View file

@ -69,7 +69,8 @@ class AccountsPage(BasePage):
continue
for i in (2,1):
balance = FrenchTransaction.clean_amount(tr.getchildren()[i].text.strip(' EUR'))
balance = FrenchTransaction.clean_amount(tr.getchildren()[i].text)
currency = Account.get_currency(tr.getchildren()[i].text)
if len(balance) > 0:
break
balance = Decimal(balance)
@ -90,6 +91,7 @@ class AccountsPage(BasePage):
account._card_links = []
account.balance = balance
account.currency = currency
accounts[account.id] = account

View file

@ -114,6 +114,7 @@ class AccountsList(CragrBasePage):
account.label = required_tokens['account_name']
account.id = required_tokens['account_number']
account.balance = FrenchTransaction.clean_amount(required_tokens['account_amount'])
account.currency = account.get_currency(required_tokens['account_amount'])
# we found almost all required information to create an account object
self.logger.debug('Found account %s with number %s and balance = %.2f' % (account.label, account.id, account.balance))
# we may have found the owner name too

View file

@ -72,6 +72,7 @@ class AccountsPage(BasePage):
account.balance = Decimal(FrenchTransaction.clean_amount(tds[self.CPT_ROW_BALANCE].find("a").text))
account.coming = Decimal(FrenchTransaction.clean_amount( tds[self.CPT_ROW_ENCOURS].find("a").text))
account.currency = account.get_currency(tds[self.CPT_ROW_BALANCE].find("a").text)
yield account
return

View file

@ -69,7 +69,8 @@ class AccountsPage(BasePage):
continue
for i in (2,1):
balance = FrenchTransaction.clean_amount(tr.getchildren()[i].text.strip(' EUR'))
balance = FrenchTransaction.clean_amount(tr.getchildren()[i].text)
currency = Account.get_currency(tr.getchildren()[i].text)
if len(balance) > 0:
break
balance = Decimal(balance)
@ -90,6 +91,7 @@ class AccountsPage(BasePage):
account._card_links = []
account.balance = balance
account.currency = currency
accounts[account.id] = account

View file

@ -22,13 +22,31 @@ import re
import datetime
from weboob.capabilities.bank import Account
from weboob.tools.capabilities.bank.transactions import Transaction
from weboob.tools.browser import BasePage#, BrokenPageError
from weboob.capabilities import NotAvailable
from weboob.tools.capabilities.bank.transactions import FrenchTransaction
__all__ = ['AccountsList', 'AccountHistoryPage']
class Transaction(FrenchTransaction):
PATTERNS = [(re.compile(u'^(?P<category>CHEQUE)(?P<text>.*)'), FrenchTransaction.TYPE_CHECK),
(re.compile('^(?P<category>FACTURE CARTE) DU (?P<dd>\d{2})(?P<mm>\d{2})(?P<yy>\d{2}) (?P<text>.*?)( CA?R?T?E? ?\d*X*\d*)?$'),
FrenchTransaction.TYPE_CARD),
(re.compile('^(?P<category>(PRELEVEMENT|TELEREGLEMENT|TIP)) (?P<text>.*)'),
FrenchTransaction.TYPE_ORDER),
(re.compile('^(?P<category>ECHEANCEPRET)(?P<text>.*)'), FrenchTransaction.TYPE_LOAN_PAYMENT),
(re.compile('^(?P<category>RETRAIT DAB) (?P<dd>\d{2})/(?P<mm>\d{2})/(?P<yy>\d{2})( (?P<HH>\d+)H(?P<MM>\d+))? (?P<text>.*)'),
FrenchTransaction.TYPE_WITHDRAWAL),
(re.compile('^(?P<category>VIR(EMEN)?T? ((RECU|FAVEUR) TIERS|SEPA RECU)?)( /FRM)?(?P<text>.*)'),
FrenchTransaction.TYPE_TRANSFER),
(re.compile('^(?P<category>REMBOURST)(?P<text>.*)'), FrenchTransaction.TYPE_PAYBACK),
(re.compile('^(?P<category>COMMISSIONS)(?P<text>.*)'), FrenchTransaction.TYPE_BANK),
(re.compile('^(?P<text>(?P<category>REMUNERATION).*)'), FrenchTransaction.TYPE_BANK),
(re.compile('^(?P<category>REMISE CHEQUES)(?P<text>.*)'), FrenchTransaction.TYPE_DEPOSIT),
]
class AccountHistoryPage(BasePage):
def get_operations(self, _id):
"""history, see http://docs.weboob.org/api/capabilities/bank.html?highlight=transaction#weboob.capabilities.bank.Transaction"""
@ -42,23 +60,23 @@ class AccountHistoryPage(BasePage):
for i in range(len(tables)):
operation = Transaction(len(operations))
operation.type = 0
operation.category = NotAvailable
date_oper = tables[i].xpath("./td[2]/text()")[0]
date_val = tables[i].xpath("./td[3]/text()")[0]
label = tables[i].xpath("./td[4]/text()")[0]
operation.label = operation.raw = unicode(label.strip())
amount = tables[i].xpath("./td[5]/text() | ./td[6]/text()")
operation.date = datetime.datetime.strptime(date_val, "%d/%m/%Y")
operation.parse(date=date_val, raw=label)
operation.rdate = datetime.datetime.strptime(date_oper,"%d/%m/%Y")
operation.type = 0
if amount[1] == u'\xa0':
amount = amount[0].replace(u"\xa0", "").replace(",", ".").strip()
amount = amount[0]
else:
amount = amount[1].replace(u"\xa0", "").replace(",", ".").strip()
operation.amount = Decimal(amount)
amount = amount[1]
operation.category = NotAvailable
operation.set_amount(amount)
operations.append(operation)
@ -75,7 +93,8 @@ class AccountsList(BasePage):
account.id = cpt.xpath("./span[1]/text()")[0].replace(u"\xa0", "").replace(',', '.').replace("EUR", "").replace("\n", "").replace("\t", "").replace(u"\xb0", '').replace(" ", "").replace('N', '')
# account balance
account.balance = Decimal(cpt.xpath("./span[2]/text()")[0].replace("+", "").replace(u"\xa0", "").replace(',', '.').replace("EUR", "").replace("\n", "").replace("\t", "").replace(" ", ""))
account.balance = Decimal(Transaction.clean_amount(cpt.xpath("./span[2]/text()")[0]))
account.currency = account.get_currency(cpt.xpath("./span[2]/text()")[0])
# account coming TODO
#mycomingval = cpt.xpath("../../following-sibling::*[1]/td[2]/a[@class='lien_synthese_encours']/span/text()")[0].replace(',', '.').replace("EUR", "").replace("\n", "").replace("\t", "").replace(u"\xa0", "")

View file

@ -53,7 +53,8 @@ class AccountsListPage(BasePage):
tag = tds[2].find('font')
if tag is None:
tag = tds[2]
account.balance = Decimal(tag.text.replace('.','').replace(',','.').replace(' ', '').strip(u' \t\u20ac\xa0\n\r'))
account.balance = Decimal(FrenchTransaction.clean_amount(tag.text))
account.currency = account.get_currency(tag.text)
account.coming = NotAvailable
yield account

View file

@ -24,6 +24,7 @@ import re
from weboob.capabilities.bank import Account
from weboob.capabilities.base import NotAvailable
from weboob.tools.browser import BasePage
from weboob.tools.capabilities.bank.transactions import FrenchTransaction
__all__ = ['AccountsList']
@ -47,7 +48,7 @@ class AccountsList(BasePage):
linkbis = self.document.xpath(urltofind).pop()
if linkbis.text == link.text:
linkbis = self.document.xpath(urltofind)[1]
account.balance = Decimal(linkbis.text.replace('.', '').\
replace(' ', '').replace(',', '.'))
account.balance = Decimal(FrenchTransaction.clean_amount(linkbis.text))
account.currency = account.get_currency(linkbis.text)
account.coming = NotAvailable
yield account

View file

@ -168,10 +168,11 @@ class AccountsPage(BasePage):
if not div.text.strip():
div = div.find('div')
account.label=u''+div.text.strip()
balance=a.text.replace(u"\u00A0",'').replace(' ','').replace('.','').replace('+','').replace(',','.').strip()
balance = FrenchTransaction.clean_amount(a.text)
if '-' in balance:
balance='-'+balance.replace('-', '')
account.balance=Decimal(balance)
account.currency = account.get_currency(a.text)
self.logger.debug('%s Type: %s' % (account.label, account._type))
l.append(account)
if link.startswith('/outil/UWCB/UWCBEncours'):
@ -181,7 +182,7 @@ class AccountsPage(BasePage):
account = l[-1]
coming = a.text.replace(u"\u00A0",'').replace(' ','').replace('.','').replace('+','').replace(',','.').strip()
coming = FrenchTransaction.clean_amount(a.text)
if '-' in coming:
coming = '-'+coming.replace('-', '')
if not account.coming:

View file

@ -64,7 +64,8 @@ class AccountsList(BasePage):
elif td.attrib.get('headers', '') == 'Solde':
balance = td.find('div').text
if balance != None:
balance = balance.replace(u'\xa0','').replace(',','.')
account.currency = account.get_currency(balance)
balance = FrenchTransaction.clean_amount(balance)
account.balance = Decimal(balance)
else:
account.balance = Decimal(0)

View file

@ -18,6 +18,7 @@
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
import re
from datetime import date, datetime
from .base import CapBaseObject, Field, StringField, DateField, DecimalField, IntField, UserError
@ -40,6 +41,25 @@ class TransferError(UserError):
A transfer has failed.
"""
class Currency:
CUR_UNKNOWN = 0
CUR_EUR = 1
CUR_CHF = 2
CUR_USD = 3
TXT2CUR = {u'': CUR_EUR,
u'EUR': CUR_EUR,
u'CHF': CUR_CHF,
u'$': CUR_USD,
u'USD': CUR_USD,
}
@classmethod
def get_currency(klass, text):
text = re.sub(u'[^A-Za-z€]', '', text)
return klass.TXT2CUR.get(text, klass.CUR_UNKNOWN)
class Recipient(CapBaseObject):
"""
Recipient of a transfer.
@ -50,7 +70,7 @@ class Recipient(CapBaseObject):
def __init__(self):
CapBaseObject.__init__(self, 0)
class Account(Recipient):
class Account(Recipient, Currency):
"""
Bank account.
@ -68,6 +88,7 @@ class Account(Recipient):
type = IntField('Type of account', default=TYPE_UNKNOWN)
balance = DecimalField('Balance on this bank account')
coming = DecimalField('Coming balance')
currency = IntField('Currency', default=Currency.CUR_UNKNOWN)
def __repr__(self):
return u"<Account id=%r label=%r>" % (self.id, self.label)

View file

@ -20,6 +20,7 @@
from decimal import Decimal
import datetime
import re
from weboob.capabilities.bank import Transaction
from weboob.capabilities import NotAvailable
@ -40,8 +41,8 @@ class FrenchTransaction(Transaction):
"""
Clean a string containing an amount.
"""
return text.replace(' ', '').replace('.','').replace(u'\xa0', '') \
.replace(',','.').strip(u' \t\u20ac\xa0\x80\n\rEUR')
text = text.replace('.','').replace(',','.')
return re.sub(u'[^\d\-\.]', '', text)
def set_amount(self, credit='', debit=''):
"""