def parse_transaction(self, transaction, account): t = FrenchTransaction(transaction['id']) if not transaction['isPrimaryCurrency']: original_currency = unicode(transaction['amounts']['txnCurrency']) if original_currency in self.browser.account_currencies: return [] if 'conversionFrom' in transaction['amounts'] and account.currency == transaction['amounts']['conversionFrom']['currency']: cc = self.format_amount(transaction['amounts']['conversionFrom']['value'], transaction['isCredit']) else: try: cc = self.browser.convert_amount(account, transaction, transaction['detailsLink']) except ServerError: self.logger.warning('Unable to go on detail, transaction skipped.') return [] if not cc: return [] t.original_amount = self.format_amount(transaction['amounts']['net']['value'], transaction["isCredit"]) t.original_currency = original_currency t.amount = self.format_amount(cc, transaction['isCredit']) else: t.amount = self.format_amount(transaction['amounts']['net']['value'], transaction['isCredit']) date = parse_french_date(transaction['date']['formattedDate'] + ' ' + transaction['date']['year']) raw = transaction.get('counterparty', transaction['displayType']) t.parse(date=date, raw=raw) return [t]
def parse_transaction(self, transaction, account): trans = [] if transaction['transactionStatus'] in [u'Créé', u'Annulé', u'Suspendu', u'Mis à jour', u'Actif', u'Payé', u'En attente', u'Rejeté', u'Expiré', \ u'Created']: return [] if transaction['transactionDescription'].startswith(u'Offre de remboursement') or transaction['transactionDescription'].startswith(u'Commande à'): return [] t = FrenchTransaction(transaction['transactionId']) if not transaction['transactionAmount']['currencyCode'] == account.currency: cc = self.browser.convert_amount(account, transaction, 'https://www.paypal.com/cgi-bin/webscr?cmd=_history-details-from-hub&id=' + transaction['transactionId']) if not cc: return [] t.original_amount = Decimal('%.2f' % transaction['transactionAmount']['currencyDoubleValue']) t.original_currency = u'' + transaction['transactionAmount']['currencyCode'] t.amount = abs(cc) if not transaction['debit'] else -abs(cc) else: t.amount = Decimal('%.2f' % transaction['net']['currencyDoubleValue']) date = parse_french_date(transaction['transactionTime']) raw = transaction['transactionDescription'] if raw.startswith(u'Paiement \xe0') or raw.startswith('Achat de'): payback_id, payback_raw, payback_amount, payback_currency = self.browser.check_for_payback(transaction, 'https://www.paypal.com/cgi-bin/webscr?cmd=_history-details-from-hub&id=' + transaction['transactionId']) if payback_id and payback_raw and payback_amount and payback_currency: t_payback = FrenchTransaction(payback_id) t_payback.amount = payback_amount t_payback.original_currency = payback_currency t_payback.type = FrenchTransaction.TYPE_TRANSFER t_payback.parse(date=date, raw=u'Prélèvement pour %s' % raw) trans.append(t_payback) t.commission = Decimal('%.2f' % transaction['fee']['currencyDoubleValue']) t.parse(date=date, raw=raw) trans.append(t) return trans
def parse_transaction(self, transaction): t = FrenchTransaction(transaction['activityId']) date = parse_french_date(transaction['date']) raw = transaction['counterparty'] t.parse(date=date, raw=raw) amount = transaction['displayAmount'] t.set_amount(amount) t._currency = transaction['currencyCode'] return t
def parse(self): for i, tr in enumerate(self.document.xpath('//tr')): t = FrenchTransaction(tr.xpath('./td[@class="transactionId"]/span')[0].text.strip()) date = parse_french_date(tr.xpath('./td[@class="date"]')[0].text.strip()) status = tr.xpath('./td[@class="desc"]/ul/li[@class="first"]')[0].text.strip() #We pass this because it's not transaction if status == u'Créé' or status == u'Annulé': continue raw = tr.xpath('./td[@class="desc"]/strong')[0].text.strip() t.parse(date=date, raw=raw) amount = tr.xpath('./td[@class="price"]/span')[0].text.strip() t.set_amount(amount) t._currency = Account.get_currency(amount) yield t
def parse_transaction(self, transaction, account): page = None if 'id' not in transaction or not transaction['date']: return [] t = FrenchTransaction(transaction['id']) if not transaction['isPrimaryCurrency']: if not 'txnCurrency' in transaction['amounts']: return [] original_currency = unicode(transaction['amounts']['txnCurrency']) if original_currency in self.browser.account_currencies: return [] if 'conversionFrom' in transaction[ 'amounts'] and 'value' in transaction['amounts'][ 'conversionFrom'] and account.currency == transaction[ 'amounts']['conversionFrom']['currency']: cc = self.format_amount( transaction['amounts']['conversionFrom']['value'], transaction['isCredit']) else: try: page = self.return_detail_page(transaction['detailsLink']) cc = page.get_converted_amount() if isinstance( page, HistoryDetailsPage) else None except ServerError: self.logger.warning( 'Unable to go on detail, transaction skipped.') return [] if not cc: return [] t.original_amount = self.format_amount( transaction['amounts']['net']['value'], transaction["isCredit"]) t.original_currency = original_currency t.amount = self.format_amount(cc, transaction['isCredit']) else: t.amount = self.format_amount( transaction['amounts']['net']['value'], transaction['isCredit']) date = parse_french_date(transaction['date']['formattedDate'] + ' ' + transaction['date']['year']).date() raw = transaction.get('counterparty', transaction['displayType']) t.parse(date=date, raw=raw) if page is None and t.amount < 0: page = self.return_detail_page(transaction['detailsLink']) funding_src = page.get_funding_src(t) if isinstance( page, HistoryDetailsPage) else None return [t] if funding_src is None else ([t] + [funding_src])
def parse_transaction(self, transaction, account): trans = [] if 'transactionStatus' in transaction and transaction[ 'transactionStatus'] in [ u'Créé', u'Annulé', u'Suspendu', u'Mis à jour', u'Actif', u'Payé', u'En attente', u'Rejeté', u'Expiré', u'Created', u'Brouillon', u'Paid', u'Pending', u'Canceled' ]: return [] for pattern in [u'Commande à', u'Offre de remboursement', u'Bill to']: if 'description' not in transaction[ 'transactionDescription'] or transaction[ 'transactionDescription']['description'].startswith( pattern): return [] t = FrenchTransaction(transaction['transactionId']) # Those are not really transactions. if not 'currency' in transaction['grossAmount'] \ or transaction['transactionDescription']['description'].startswith("Conversion de devise"): return [] original_currency = unicode(transaction['grossAmount']['currency']) if not original_currency == account.currency: if original_currency in self.browser.account_currencies: return [] cc = [tr['grossAmount']['amountUnformatted'] for tr in transaction['secondaryTransactions'] \ if account.currency == tr['grossAmount']['currency'] \ and (tr['grossAmount']['amountUnformatted'] < 0) == (transaction['grossAmount']['amountUnformatted'] < 0) \ and tr['transactionDescription']['description'].startswith('Conversion de devise')] if not cc: return [] assert len(cc) == 1 t.original_amount = Decimal( str(transaction['grossAmount']['amountUnformatted'])) t.original_currency = original_currency t.amount = Decimal(str(cc[0])) else: t.amount = Decimal( str(transaction['netAmount']['amountUnformatted'])) date = parse_french_date(transaction['transactionTime']) raw = "%s %s" % (transaction['transactionDescription']['description'], transaction['transactionDescription']['name']) if raw == "Transfert de Compte bancaire": t.type = FrenchTransaction.TYPE_TRANSFER t.commission = Decimal( str(transaction['feeAmount']['amountUnformatted'])) t.parse(date=date, raw=raw) trans.append(t) return trans
def parse_transaction(self, transaction, account): trans = [] if transaction['transactionStatus'] in [u'Créé', u'Annulé', u'Suspendu', u'Mis à jour', u'Actif', u'Payé', u'En attente', u'Rejeté', u'Expiré', \ u'Created', u'Canceled']: return [] if transaction['transactionDescription'].startswith( u'Offre de remboursement' ) or transaction['transactionDescription'].startswith(u'Commande à'): return [] t = FrenchTransaction(transaction['transactionId']) original_currency = unicode( transaction['transactionAmount']['currencyCode']) if not original_currency == account.currency: if original_currency in self.browser.account_currencies: return [] cc = self.browser.convert_amount( account, transaction, 'https://www.paypal.com/cgi-bin/webscr?cmd=_history-details-from-hub&id=' + transaction['transactionId']) if not cc: return [] t.original_amount = Decimal( '%.2f' % transaction['transactionAmount']['currencyDoubleValue']) t.original_currency = original_currency t.amount = abs(cc) if not transaction['debit'] else -abs(cc) else: t.amount = Decimal('%.2f' % transaction['net']['currencyDoubleValue']) date = parse_french_date(transaction['transactionTime']) raw = transaction['transactionDescription'] if raw.startswith(u'Paiement \xe0') or raw.startswith('Achat de'): payback_id, payback_raw, payback_amount, payback_currency = self.browser.check_for_payback( transaction, 'https://www.paypal.com/cgi-bin/webscr?cmd=_history-details-from-hub&id=' + transaction['transactionId']) if payback_id and payback_raw and payback_amount and payback_currency: t_payback = FrenchTransaction(payback_id) t_payback.amount = payback_amount t_payback.original_currency = payback_currency t_payback.type = FrenchTransaction.TYPE_TRANSFER t_payback.parse(date=date, raw=u'Prélèvement pour %s' % raw) trans.append(t_payback) t.commission = Decimal('%.2f' % transaction['fee']['currencyDoubleValue']) t.parse(date=date, raw=raw) trans.append(t) return trans
def parse_transaction(self, transaction, account): t = FrenchTransaction(transaction['id']) if not transaction['isPrimaryCurrency']: cc = self.browser.convert_amount(account, transaction, transaction['detailsLink']) if not cc: return [] t.original_amount = self.format_amount(transaction['amounts']['net']['value'], transaction["isCredit"]) t.original_currency = u'' + transaction['amounts']['txnCurrency'] t.amount = self.format_amount(cc, transaction['isCredit']) else: t.amount = self.format_amount(transaction['amounts']['net']['value'], transaction['isCredit']) date = parse_french_date(transaction['date']['formattedDate'] + ' ' + transaction['date']['year']) raw = transaction.get('counterparty', transaction['displayType']) t.parse(date=date, raw=raw) return [t]
def get_operations(self): for tr in self.document.xpath('//div[@class="block no-hd"]//table[@class="list"]/tbody/tr'): tds = tr.xpath('./td') date = self.parser.tocleanstring(tds[0]) label = self.parser.tocleanstring(tds[1]) amount = self.parser.tocleanstring(tds[2]) operation = FrenchTransaction() operation.parse(date=date, raw=label) operation.set_amount(amount) if tds[0].xpath('./a'): operation.investments = self.get_investments(tds[0].xpath('./a')[0].attrib['href']) or NotAvailable yield operation
def parse(self): for i, tr in enumerate(self.document.xpath('//tr')): t = FrenchTransaction( tr.xpath('./td[@class="transactionId"]/span')[0].text.strip()) date = parse_french_date( tr.xpath('./td[@class="date"]')[0].text.strip()) status = tr.xpath( './td[@class="desc"]/ul/li[@class="first"]')[0].text.strip() #We pass this because it's not transaction if status == u'Créé' or status == u'Annulé': continue raw = tr.xpath('./td[@class="desc"]/strong')[0].text.strip() t.parse(date=date, raw=raw) amount = tr.xpath('./td[@class="price"]/span')[0].text.strip() t.set_amount(amount) t._currency = Account.get_currency(amount) yield t
def get_transactions(self, _type='consommable'): for tr in self.document.xpath('//table[@id="solde_%s_lignes"]/tbody/tr' % _type): cols = tr.findall('td') t = Transaction(0) day, month, year = self.parser.tocleanstring(cols[self.COL_DATE]).split(' ') day = int(day) year = int(year) month = self.MONTHS.index(month.rstrip('.')) + 1 date = datetime.date(year, month, day) label = self.parser.tocleanstring(cols[self.COL_LABEL]) t.parse(date, label) t.set_amount(self.parser.tocleanstring(cols[self.COL_AMOUNT])) yield t
def parse_transaction(self, transaction, account): if transaction['transactionStatus'] in [u'Créé', u'Annulé', u'Suspendu', u'Mis à jour', u'Actif']: return t = FrenchTransaction(transaction['transactionId']) if not transaction['transactionAmount']['currencyCode'] == account.currency: cc = self.browser.convert_amount(account, transaction, 'https://www.paypal.com/cgi-bin/webscr?cmd=_history-details-from-hub&id=' + transaction['transactionId']) if not cc: return t.original_amount = Decimal(transaction['transactionAmount']['currencyDoubleValue']) t.original_currency = u'' + transaction['transactionAmount']['currencyCode'] t.set_amount(cc) else: t.amount = Decimal(transaction['transactionAmount']['currencyDoubleValue']) date = parse_french_date(transaction['transactionTime']) raw = transaction['transactionDescription'] t.commission = Decimal(transaction['fee']['currencyDoubleValue']) t.parse(date=date, raw=raw) return t
def parse_transaction(self, transaction, account): t = FrenchTransaction(transaction['activityId']) date = parse_french_date(transaction['date']) raw = transaction.get('counterparty', transaction['displayType']) t.parse(date=date, raw=raw) try: if transaction['currencyCode'] != account.currency: transaction = self.browser.convert_amount(account, transaction) t.original_amount = self.format_amount(transaction['originalAmount'], transaction["isCredit"]) t.original_currency = u'' + transaction["currencyCode"] t.amount = self.format_amount(transaction['netAmount'], transaction["isCredit"]) except KeyError: return t._currency = transaction['currencyCode'] return t
def parse_transaction(self, transaction): t = FrenchTransaction(transaction['activityId']) date = parse_french_date(transaction['date']) try: raw = transaction['counterparty'] except KeyError: raw = transaction['displayType'] t.parse(date=date, raw=raw) try: amount = transaction['netAmount'] except KeyError: return if transaction['isCredit']: t.set_amount(credit=amount) else: t.set_amount(debit=amount) t._currency = transaction['currencyCode'] return t
def parse_transaction(self, transaction): t = FrenchTransaction(transaction['activityId']) date = parse_french_date(transaction['date']) try: raw = transaction['counterparty'] except KeyError: raw = transaction['displayType'] t.parse(date=date, raw=raw) try: amount = transaction['netAmount'] except KeyError: return if transaction['isCredit']: t.set_amount(credit=amount) else: t.set_amount(debit=amount) t._currency = transaction['currencyCode'] return t
def parse(self): for tr in self.document.xpath('//tbody/tr'): tlink = tr.xpath('./td[@class="desc"]/a[@class="rowClick"]')[0].attrib['href'].strip() t = FrenchTransaction(tlink[tlink.find('&id=')+4:]) date = parse_french_date(tr.xpath('./td[@class="date"]')[0].text.strip()) raw = tr.xpath('./td[@class="desc"]/a[@class="rowClick"]')[0].tail.strip() # Filter lines that do not actually modify the balance if raw.startswith('Autorisation ') or raw.endswith(' en attente par PayPal'): continue t.parse(date=date, raw=raw) amount = tr.xpath('./td[@class="price-value net"]')[0].text.strip() t.set_amount(amount) commission = tr.xpath('./td[@class="price-value fee"]')[0].text.strip() t.commission = Decimal(t.clean_amount(commission)) t.label = t.raw if t.commission: t.label += " (%s)" % tr.xpath('./td[@class="price-value gross"]')[0].text.strip() t._currency = Account.get_currency(amount) yield t
def parse_transaction(self, transaction, account): if self.browser.is_new_api: return self.parse_new_api_transaction(transaction, account) t = FrenchTransaction(transaction['transactionId']) date = parse_french_date(transaction['date']) if not transaction['txnIsInPrimaryCurrency']: cc = self.browser.convert_amount(account, transaction, transaction['actions']['details']['url']) if not cc: return t.original_amount = self.format_amount(transaction['netAmount'], transaction["isCredit"]) t.original_currency = u'' + transaction["currencyCode"] t.amount = self.format_amount(cc, transaction['isCredit']) elif 'netAmount' in transaction: t.amount = self.format_amount(transaction['netAmount'], transaction["isCredit"]) else: return raw = transaction.get('counterparty', transaction['displayType']) t.parse(date=date, raw=raw) return t
def parse_transaction(self, transaction, account): t = FrenchTransaction(transaction['id']) if not transaction['isPrimaryCurrency']: cc = self.browser.convert_amount(account, transaction, transaction['detailsLink']) if not cc: return [] t.original_amount = self.format_amount( transaction['amounts']['net']['value'], transaction["isCredit"]) t.original_currency = u'' + transaction['amounts']['txnCurrency'] t.amount = self.format_amount(cc, transaction['isCredit']) else: t.amount = self.format_amount( transaction['amounts']['net']['value'], transaction['isCredit']) date = parse_french_date(transaction['date']['formattedDate'] + ' ' + transaction['date']['year']) raw = transaction.get('counterparty', transaction['displayType']) t.parse(date=date, raw=raw) return [t]
def get_history(self): for tr in self.document.xpath('//div[contains(@class, "mod-listeoperations")]//table/tbody/tr'): cols = tr.findall('td') date = self.parser.tocleanstring(cols[0]) raw = self.parser.tocleanstring(cols[1]) label = re.sub(u' - traité le \d+/\d+', '', raw) debit = self.parser.tocleanstring(cols[3]) if len(debit) > 0: t = FrenchTransaction(0) t.parse(date, raw) t.label = label t.set_amount(debit) yield t amount = self.parser.tocleanstring(cols[2]) if len(amount) > 0: t = FrenchTransaction(0) t.parse(date, raw) t.label = label t.set_amount('-' + amount) yield t
def get_history(self, account): transactions = [] last_order = None for tr in self.document.split('\n')[1:]: cols = tr.split(';') if len(cols) < 4: continue t = FrenchTransaction(0) date = cols[self.COL_DATE] raw = cols[self.COL_TEXT] amount = cols[self.COL_AMOUNT] t.parse(date, re.sub(r'[ ]+', ' ', raw)) if t.raw.startswith('PRELEVEMENT ACHATS DIFFERES'): t._coming = False if last_order is None: last_order = t.date else: t._coming = True t.set_amount(amount) transactions.append(t) # go to the previous stop date before the last order while last_order is not None and last_order.day != account._outstanding_date.day: last_order = last_order - datetime.timedelta(days=1) for t in transactions: if t.date <= last_order: t._coming = False return iter(transactions)
def parse_transaction(self, transaction, account): page = None if 'id' not in transaction or not transaction['date']: return [] t = FrenchTransaction(transaction['id']) if not transaction['isPrimaryCurrency']: if not 'txnCurrency' in transaction['amounts']: return [] original_currency = unicode(transaction['amounts']['txnCurrency']) if original_currency in self.browser.account_currencies: return [] if 'conversionFrom' in transaction['amounts'] and 'value' in transaction['amounts']['conversionFrom'] and account.currency == transaction['amounts']['conversionFrom']['currency']: cc = self.format_amount(transaction['amounts']['conversionFrom']['value'], transaction['isCredit']) else: try: page = self.return_detail_page(transaction['detailsLink']) cc = page.get_converted_amount() if isinstance(page, HistoryDetailsPage) else None except ServerError: self.logger.warning('Unable to go on detail, transaction skipped.') return [] if not cc: return [] t.original_amount = self.format_amount(transaction['amounts']['net']['value'], transaction["isCredit"]) t.original_currency = original_currency t.amount = self.format_amount(cc, transaction['isCredit']) else: t.amount = self.format_amount(transaction['amounts']['net']['value'], transaction['isCredit']) date = parse_french_date(transaction['date']['formattedDate'] + ' ' + transaction['date']['year']).date() raw = transaction.get('counterparty', transaction['displayType']) t.parse(date=date, raw=raw) if page is None and t.amount < 0: page = self.return_detail_page(transaction['detailsLink']) funding_src = page.get_funding_src(t) if isinstance(page, HistoryDetailsPage) else None return [t] if funding_src is None else ([t] + [funding_src])
def get_history(self, account): transactions = [] last_order = None for tr in self.document.split('\n')[1:]: cols = tr.split(';') if len(cols) < 4: continue t = FrenchTransaction(0) date = cols[self.COL_DATE] raw = cols[self.COL_TEXT] amount = cols[self.COL_AMOUNT] t.parse(date, re.sub(r'[ ]+', ' ', raw)) if t.raw.startswith('PRELEVEMENT ACHATS DIFFERES'): t._coming = False if last_order is None: last_order = t.date else: t._coming = True t.set_amount(amount) transactions.append(t) # go to the previous stop date before the last order while last_order is not None and last_order.day != account._outstanding_date.day: last_order = last_order - datetime.timedelta(days=1) for t in transactions: if t.date <= last_order: t._coming = False return iter(transactions)
def parse_transaction(self, transaction, account): trans = [] # Add secondary transactions on label condition. for t in transaction['secondaryTransactions']: if t['transactionDescription'][ 'description'] == u'Virement à partir de': trans.extend(self.parse_transaction(t, account)) if 'transactionStatus' in transaction and transaction[ 'transactionStatus'] in [ u'Créé', u'Annulé', u'Suspendu', u'Mis à jour', u'Actif', u'Payé', u'En attente', u'Rejeté', u'Expiré', u'Created', u'Brouillon', u'Paid', u'Pending', u'Canceled', u'Suspended' ]: return [] for pattern in [u'Commande à', u'Offre de remboursement', u'Bill to']: if 'description' not in transaction[ 'transactionDescription'] or transaction[ 'transactionDescription']['description'].startswith( pattern): return [] t = FrenchTransaction(transaction['transactionId']) # Those are not really transactions. if 'grossAmount' not in transaction or not 'currency' in transaction['grossAmount'] \ or transaction['transactionDescription']['description'].startswith("Conversion de devise"): return [] original_currency = unicode(transaction['grossAmount']['currency']) if not original_currency == account.currency: if original_currency in self.browser.account_currencies: return [] cc = [tr['grossAmount']['amountUnformatted'] for tr in transaction['secondaryTransactions'] \ if account.currency == tr['grossAmount']['currency'] \ and (tr['grossAmount']['amountUnformatted'] < 0) == (transaction['grossAmount']['amountUnformatted'] < 0) \ and tr['transactionDescription']['description'].startswith('Conversion de devise')] if not cc: return [] assert len(cc) == 1 t.original_amount = Decimal( str(transaction['netAmount']['amountUnformatted'])) t.original_currency = original_currency t.amount = Decimal(str(cc[0])) else: t.amount = Decimal( str(transaction['netAmount']['amountUnformatted'])) date = parse_french_date(transaction['transactionTime']) raw = "%s %s" % (transaction['transactionDescription']['description'], transaction['transactionDescription']['name']) if raw == "Transfert de Compte bancaire": t.type = FrenchTransaction.TYPE_TRANSFER if raw == u'Annulation des frais de PayPal': return [] # Dougs told us that commission should always be netAmount minus grossAmount grossAmount = Decimal( str(transaction['grossAmount']['amountUnformatted'])) t.commission = Decimal( str(transaction['feeAmount']['amountUnformatted'])) if t.commission: if original_currency == account.currency: assert abs(t.amount - grossAmount) == abs(t.commission) t.commission = t.amount - grossAmount else: t.commission = (t.commission * t.amount / t.original_amount).quantize( Decimal('.01'), rounding=ROUND_DOWN) t.parse(date=date, raw=raw) trans.append(t) return trans
def parse_transaction(self, transaction, account): trans = [] # Add secondary transactions on label condition. for t in transaction['secondaryTransactions']: if t['transactionDescription']['description'] == u'Virement à partir de': trans.extend(self.parse_transaction(t, account)) if 'transactionStatus' in transaction and transaction['transactionStatus'] in [u'Créé', u'Annulé', u'Suspendu', u'Mis à jour', u'Actif', u'Payé', u'En attente', u'Rejeté', u'Expiré', u'Created', u'Brouillon', u'Paid', u'Pending', u'Canceled', u'Suspended']: return [] for pattern in [u'Commande à', u'Offre de remboursement', u'Bill to']: if 'description' not in transaction['transactionDescription'] or transaction['transactionDescription']['description'].startswith(pattern): return [] t = FrenchTransaction(transaction['transactionId']) # Those are not really transactions. if 'grossAmount' not in transaction or not 'currency' in transaction['grossAmount'] \ or transaction['transactionDescription']['description'].startswith("Conversion de devise"): return [] original_currency = unicode(transaction['grossAmount']['currency']) if not original_currency == account.currency: if original_currency in self.browser.account_currencies: return [] cc = [tr['grossAmount']['amountUnformatted'] for tr in transaction['secondaryTransactions'] \ if account.currency == tr['grossAmount']['currency'] \ and (tr['grossAmount']['amountUnformatted'] < 0) == (transaction['grossAmount']['amountUnformatted'] < 0) \ and tr['transactionDescription']['description'].startswith('Conversion de devise')] if not cc: return [] assert len(cc) == 1 t.original_amount = Decimal(str(transaction['netAmount']['amountUnformatted'])) t.original_currency = original_currency t.amount = Decimal(str(cc[0])) else: t.amount = Decimal(str(transaction['netAmount']['amountUnformatted'])) date = parse_french_date(transaction['transactionTime']) raw = "%s %s" % (transaction['transactionDescription']['description'], transaction['transactionDescription']['name']) if raw == "Transfert de Compte bancaire": t.type = FrenchTransaction.TYPE_TRANSFER if raw == u'Annulation des frais de PayPal': return [] # Dougs told us that commission should always be netAmount minus grossAmount grossAmount = Decimal(str(transaction['grossAmount']['amountUnformatted'])) t.commission = Decimal(str(transaction['feeAmount']['amountUnformatted'])) if t.commission: if original_currency == account.currency: assert abs(t.amount - grossAmount) == abs(t.commission) t.commission = t.amount - grossAmount else: t.commission = (t.commission * t.amount / t.original_amount).quantize(Decimal('.01'), rounding=ROUND_DOWN) t.parse(date=date, raw=raw) trans.append(t) return trans