def _check_ofx(self, data_file, raise_error=False): try: OfxParser.parse(io.BytesIO(data_file)) return True except Exception as e: if raise_error: raise UserError(_("Arquivo formato inválido:\n%s") % str(e)) return False
def _check_ofx(self, data_file, raise_error=False): try: data_file = data_file.replace('\r\n', '\n').replace('\r', '\n') OfxParser.parse(StringIO.StringIO(data_file)) return True except Exception as e: if raise_error: raise UserError(u"Arquivo formato inválido:\n%s" % str(e)) return False
def testDecimalParsingWithCommas(self): # open files ofx_standard = OfxParser.parse(open_file('bank_medium.ofx')) ofx_w_commas = OfxParser.parse(open_file('bank_medium_with_commas.ofx')) # extract transactions t1 = list(t.amount for t in ofx_standard.account.statement.transactions) t2 = list(t.amount for t in ofx_w_commas.account.statement.transactions) # compare self.assertEquals(t1, t2)
def download_parsed(self, days=60): """Downloaded OFX response parsed by :py:meth:`OfxParser.parse` :param days: Number of days to look back at :type days: integer :rtype: :py:class:`ofxparser.Ofx` """ if IS_PYTHON_2: return OfxParser.parse(self.download(days=days)) else: return OfxParser.parse(BytesIO((((self.download(days=days)).read()).encode())))
def testSuccess(self): ofx = OfxParser.parse(open_file("signon_success.ofx"), True) self.assertTrue(ofx.signon.success) self.assertEquals(ofx.signon.code, 0) self.assertEquals(ofx.signon.severity, "INFO") self.assertEquals(ofx.signon.message, "Login successful") ofx = OfxParser.parse(open_file("signon_success_no_message.ofx"), True) self.assertTrue(ofx.signon.success) self.assertEquals(ofx.signon.code, 0) self.assertEquals(ofx.signon.severity, "INFO") self.assertEquals(ofx.signon.message, "")
def testSuccess(self): ofx = OfxParser.parse(open_file('signon_success.ofx'), True) self.assertTrue(ofx.signon.success) self.assertEquals(ofx.signon.code, 0) self.assertEquals(ofx.signon.severity, 'INFO') self.assertEquals(ofx.signon.message, 'Login successful') ofx = OfxParser.parse(open_file('signon_success_no_message.ofx'), True) self.assertTrue(ofx.signon.success) self.assertEquals(ofx.signon.code, 0) self.assertEquals(ofx.signon.severity, 'INFO') self.assertEquals(ofx.signon.message, '')
def parse(self, file_): # ofxparse workaround # ofxparse doesn't parse the transaction amount correctly. It assumes # that the decimal point separator is always a full-stop; however, it # depends on the locale of the statement. # # This workaround finds the transaction amount in the file and replaces # comma with a full-stop. A temporary file is used to make the change # so the original file data stays intact. with open(file_) as f: data = f.read() data = re.sub(r'<TRNAMT>([-\d]+),([\d]+)', r'<TRNAMT>\1.\2', data) ofx_file = tempfile.NamedTemporaryFile(delete=False) try: with ofx_file as f: f.write(data) # Actual parsing ofx = OfxLibParser.parse(file(ofx_file.name)) i_txs = [] for f_acc in ofx.accounts: for f_tx in f_acc.statement.transactions: p_tx = ParsedTx(f_tx.date.date(), f_tx.amount, unicode(f_acc.number), unicode(f_tx.memo)) i_tx = ImportTx(p_tx) i_txs.append(i_tx) return i_txs finally: os.remove(ofx_file.name)
def test_using_ofx_printer_with_stringio(self): with open_file('checking.ofx') as f: ofx = OfxParser.parse(f) output_buffer = StringIO() printer = OfxPrinter(ofx=ofx, filename=None) printer.writeToFile(output_buffer, tabs=1) assert output_buffer.getvalue().startswith("OFXHEADER")
def testErrorInTransactionList(self): """There is an error in the transaction list.""" with open_file('error_message.ofx') as f: ofx = OfxParser.parse(f, False) self.assertEqual(ofx.status['code'], 2000) self.assertEqual(ofx.status['severity'], 'ERROR') self.assertEqual(ofx.status['message'], 'General Server Error')
def test_checking_custom_payee(self): ofx = OfxParser.parse(open(os.path.join('fixtures', 'checking.ofx'))) converter = OfxConverter( account=ofx.account, name="Foo", payee_format="{memo}") self.assertEqual( converter.format_payee( ofx.account.statement.transactions[0]), 'DIVIDEND EARNED FOR PERIOD OF 03/01/2011 THROUGH 03/31/2011 ANNUAL PERCENTAGE YIELD EARNED IS 0.05%') converter = OfxConverter( account=ofx.account, name="Foo", payee_format="{payee}") self.assertEqual( converter.format_payee(ofx.account.statement.transactions[0]), 'DIVIDEND EARNED FOR PERIOD OF 03') converter = OfxConverter( account=ofx.account, name="Foo", payee_format="{account}") self.assertEqual( converter.format_payee(ofx.account.statement.transactions[0]), 'Foo') converter = OfxConverter( account=ofx.account, name="Foo", payee_format=" {account} ") self.assertEqual( converter.format_payee(ofx.account.statement.transactions[0]), 'Foo')
def __init__(self, file, user, conta_user): self.user = user try: datas = file.read() fileobj = open(user.email + ".ofx", "wb") fileobj.write(datas) fileobj.close() fileobj = open(user.email + ".ofx", "rb") ofx = OfxParser.parse(fileobj) conta = ofx.account self.conta_extrato = conta.account_id if conta_user == self.conta_extrato: self.error_control = True self.agencia = conta.branch_id self.banco = conta.institution.organization relatorio = conta.statement self.balanco = relatorio.balance self.relatorio.update(inicio=relatorio.start_date, fim=relatorio.end_date), for extrato in relatorio.transactions: self.operacao.append(extrato.id) self.valor.append(extrato.amount) self.history.append(extrato.memo) self.date.append(extrato.date) self.type.append(extrato.type) self.documento.append(extrato.checknum) else: self.error_control = False fileobj.close() except: self.error_control = False
def parseofx(ofxfile): newaccounts = [] newtransactions = [] skippedtransactions = [] ofx = OfxParser.parse(ofxfile) for account in ofx.accounts: # Check that all account exist, if not create them. if account.account_type == 'SAVINGS': accounttype = 'SAV' elif account.account_type == 'CHECKING': accounttype = 'CUR' else: accounttype = 'CUR' results = Account.objects.filter(account=account.number,sortcode=account.routing_number) if len(results) == 0: # No existing account exists, lets create one accountmodel = Account(account=account.number,sortcode=account.routing_number,accounttype=accounttype) accountmodel.save() newaccounts.append(accountmodel) else: accountmodel = results[0] #Load transactions. for transaction in account.statement.transactions: results = Transaction.objects.filter(account=accountmodel,transid=transaction.id) if len(results) == 0: # No existing transaction exists, lets create one transactionmodel = Transaction(account=accountmodel,memo=transaction.memo,payee=transaction.payee,amount=transaction.amount,transtype=transaction.type,transid=transaction.id) transactionmodel.save() newtransactions.append(transactionmodel) else: transactionmodel = results[0] skippedtransactions.append(transactionmodel) return [newaccounts,newtransactions,skippedtransactions]
def post(self): try: bank_statement = self.get_uploads()[0] from ofxparse import OfxParser ofx = OfxParser.parse(bank_statement.open()) user = users.get_current_user() logging.info(ofx.account.number) # The account number logging.info(ofx.account.routing_number) # The transit id (sometimes called branch number) #logging.info(ofx.account.statement # Account information for a period of time logging.info(ofx.account.statement.start_date) # The start date of the transactions logging.info(ofx.account.statement.end_date) # The end date of the transactions #ofx.account.statement.transactions # A list of account activities logging.info(ofx.account.statement.balance) # The money in the account as of the statement for tx in ofx.account.statement.transactions: logging.info(vars(tx)) if tx.type == 'debit': # new expense: new_expense = Expenses(parent=expenses_key(tx.date.month, tx.date.year)) new_expense.user = user new_expense.date = tx.date new_expense.amount = -float(str(tx.amount)) new_expense.category = tx.payee new_expense.exptype = 3 new_expense.put() finally: self.redirect('comptes')
def testFailure(self): with open_file('signon_fail.ofx') as f: ofx = OfxParser.parse(f, True) self.assertFalse(ofx.signon.success) self.assertEqual(ofx.signon.code, 15500) self.assertEqual(ofx.signon.severity, 'ERROR') self.assertEqual(ofx.signon.message, 'Your request could not be processed because you supplied an invalid identification code or your password was incorrect')
def main(): balances = {} for request in config.requests: data = open(request["file"]).read() % request response_data = post(request["url"], data, { "Content-type": "application/x-ofx", "Accept": "*/*, application/x-ofx" }) response = OfxParser.parse(response_data) groups = dict([(request[k], v) for k, v in request.get("groups", {}).items()]) for account in response.accounts: group = groups.get(account.number, "") balances[group] = balances.get(group, 0) + account.statement.balance #balances.append(sum([float(x.statement.balance) for x in response.accounts])) #for label, k in request.get("special", {}).items(): # balance = [a.statement.balance for a in response.accounts if a.number == request[k]] # if balance: # specials.append("%s: %d" % (label, balance[0])) # positive_accounts = set([request[x.strip()] for x in request.get("positive", "").split(", ") if x.strip()]) # positive = sum([float(x.statement.balance) for x in response.accounts if x.number in positive_accounts]) # negative = sum([float(x.statement.balance) for x in response.accounts if x.number not in positive_accounts]) # print positive, negative #print [x.statement for x in response.accounts] #ch, zch, s, c = [a.statement.balance for a in response.accounts] #balance = ch + c #print "%d %d %dk" % (balance, zch, s / 1000) #print "%d %d" % (balance, zch) print "%d %s" % (balances[""] - 10000, ", ".join(["%s: %d" % (k, v) for k, v in balances.items() if k]))
def importOFX(fileName): '''importOFX brings in the OFX transaction objects to be analyzed''' if not (os.path.exists("data")): os.makedirs("data") currentData = fe.unPickleData() transList = [] ofx = ofp.parse(fileName) for t in ofx.account.statement.transactions: transList.append({ 'id': t.id, 'amount': t.amount, 'checknum': t.checknum, 'date': t.date, 'mcc': t.mcc, 'memo': t.memo, 'payee': t.payee, 'sic': t.sic, 'type': t.type, 'cat': '' }) df = pandas.DataFrame.from_records(transList, columns=[ 'id', 'date', 'payee', 'cat', 'amount', 'type', 'memo', 'checknum', 'sic' ]) df.amount = df.amount.astype(float) df = pandas.concat([df, currentData]).drop_duplicates(subset='id', keep='last') return df
def testForFourAccounts(self): ofx = OfxParser.parse(open_file("account_listing_aggregation.ofx")) self.assertTrue(hasattr(ofx, "accounts")) self.assertEquals(len(ofx.accounts), 4) # first account account = ofx.accounts[0] self.assertEquals(account.account_type, "SAVINGS") self.assertEquals(account.desc, "USAA SAVINGS") self.assertEquals(account.institution.organization, "USAA") self.assertEquals(account.number, "0000000001") self.assertEquals(account.routing_number, "314074269") # second account = ofx.accounts[1] self.assertEquals(account.account_type, "CHECKING") self.assertEquals(account.desc, "FOUR STAR CHECKING") self.assertEquals(account.institution.organization, "USAA") self.assertEquals(account.number, "0000000002") self.assertEquals(account.routing_number, "314074269") # third account = ofx.accounts[2] self.assertEquals(account.account_type, "CREDITLINE") self.assertEquals(account.desc, "LINE OF CREDIT") self.assertEquals(account.institution.organization, "USAA") self.assertEquals(account.number, "00000000000003") self.assertEquals(account.routing_number, "314074269") # fourth account = ofx.accounts[3] self.assertEquals(account.account_type, "") self.assertEquals(account.desc, "MY CREDIT CARD") self.assertEquals(account.institution.organization, "USAA") self.assertEquals(account.number, "4111111111111111")
def test_checking(self): ofx = OfxParser.parse(open(os.path.join('fixtures', 'checking.ofx'))) converter = OfxConverter(account=ofx.account, name="Foo") self.assertEqualLedgerPosting( converter.convert( ofx.account.statement.transactions[0]).format(), """2011/03/31 DIVIDEND EARNED FOR PERIOD OF 03/01/2011 THROUGH 03/31/2011 ANNUAL PERCENTAGE YIELD EARNED IS 0.05% Foo $0.01 ; ofxid: 1101.1452687~7.0000486 Expenses:Misc -$0.01 """) self.assertEqualLedgerPosting( converter.convert( ofx.account.statement.transactions[1]).format(), """2011/04/05 AUTOMATIC WITHDRAWAL, ELECTRIC BILL WEB(S ) Foo -$34.51 ; ofxid: 1101.1452687~7.0000487 Expenses:Misc $34.51 """) self.assertEqualLedgerPosting( converter.convert( ofx.account.statement.transactions[2]).format(), """2011/04/07 RETURNED CHECK FEE, CHECK # 319 FOR $45.33 ON 04/07/11 Foo -$25.00 ; ofxid: 1101.1452687~7.0000488 Expenses:Misc $25.00 """)
def parse_file(file, transactions_data, words_df): print(file) total_file = 0.0 competency = None with open(file, encoding="ISO-8859-1") as fileobj: ofx = OfxParser.parse(fileobj) for transaction in ofx.account.statement.transactions: if transaction.amount < 0: label = get_label(transaction.memo, words_df) day = transaction.date.strftime("%Y-%m-%d") month = transaction.date.strftime("%Y-%m") year = transaction.date.year transactions_data.append( [ transaction.memo, transaction.amount, day, month, year, label ] ) # print(transaction.memo, "\t", transaction.amount, "\t", label) return transactions_data
def testForUnclosedTags(self): with open_file('fidelity.ofx') as f: ofx = OfxParser.parse(f) self.assertTrue(hasattr(ofx.account.statement, 'positions')) self.assertEqual(len(ofx.account.statement.positions), 6) self.assertEqual( ofx.account.statement.positions[0].units, Decimal('128.0'))
def import_ofx(self, ofx_file): ofx = OfxParser.parse(file(ofx_file)) idx = {} for s in ofx.security_list: idx[s.uniqueid] = s.ticker c = self.db.cursor() for t in ofx.account.statement.transactions: c.execute("SELECT id FROM stocks WHERE id = ?", [t.id]) row = c.fetchone() if row: print "Skipping duplicate transaction:", t.id continue spydate = t.tradeDate # Fidelity transactions can "close" on a weekend?!? if spydate.weekday() == 5: spydate = spydate - timedelta(days=1) elif spydate.weekday() == 6: spydate = spydate - timedelta(days=2) spy = ystockquote.get_historical_prices('SPY', spydate.strftime("%Y%m%d"), spydate.strftime("%Y%m%d")) spy_price = float(spy[1][4]) spy_units = (float(t.units) * float(t.unit_price)) / spy_price c.execute("INSERT INTO stocks VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", (t.id, idx[t.security], t.security, t.tradeDate, t.settleDate, float(t.units), float(t.unit_price), spy_units, spy_price)) self.db.commit()
def test_sync_order(self): ledger = Ledger(os.path.join('fixtures', 'empty.lgr')) sync = Synchronizer(ledger) ofx = OfxParser.parse(file(os.path.join('fixtures', 'checking_order.ofx'))) txns = sync.filter(ofx) self.assertTrue(txns[0].date < txns[1].date and txns[1].date < txns[2].date)
def test_transfer_txn(self): ofx = OfxParser.parse( open( os.path.join( 'fixtures', 'investment_401k.ofx'))) converter = OfxConverter(account=ofx.account, name="Foo", unknownaccount='Expenses:Unknown') if len(ofx.account.statement.transactions) > 2: # older versions of ofxparse would skip these transactions if hasattr(ofx.account.statement.transactions[2], 'tferaction'): # unmerged pull request self.assertEqualLedgerPosting( converter.convert( ofx.account.statement.transactions[2]).format(), """2014/06/30 Foo: transfer: out Foo -9.060702 BAZ @ $21.928764 ; ofxid: 1234.12345678.123456-01.3 Transfer $198.69 """) else: self.assertEqualLedgerPosting( converter.convert( ofx.account.statement.transactions[2]).format(), """2014/06/30 Foo: transfer Foo -9.060702 BAZ @ $21.928764 ; ofxid: 1234.12345678.123456-01.3 Transfer $198.69 """)
def main(): conf = cfg.ConfigOpts() register_opts(conf) conf(default_config_dirs=["etc"]) locale.setlocale(locale.LC_ALL, conf.locale) if conf.output_file: output_file = codecs.open(conf.output_file, 'w', 'utf-8') else: output_file = sys.stdout writer = csv.writer(output_file, conf.csv_dialect) with codecs.open(conf.input_file, encoding=conf.encoding) as f: try: ofx = OfxParser.parse(f) except Exception as e: raise type(e)(str(e) + ' parsing file %s' % conf.file).with_traceback( sys.exc_info()[2]) writer.writerow([conf.column_names[n] for n in conf.columns]) for transaction in ofx.account.statement.transactions: trn = [transaction.__getattribute__(c) for c in conf.columns] writer.writerow(format_row(conf, trn, ofx.account.curdef))
def extract(file, account_name, flag, currency): ofx = OfxParser.parse(strio(file.contents())) account = ofx.account statement = account.statement assert statement.currency.lower() == currency.lower(), ( statement.currency + " != " + currency ) ledger = [] # create transactions for transaction in statement.transactions: units = Amount(transaction.amount, currency) posting = data.Posting(account_name, units, None, None, None, None) ref = data.new_metadata(file.name, 0) entry = data.Transaction( ref, transaction.date.date(), flag, titlecase(transaction.payee), transaction.memo, data.EMPTY_SET, data.EMPTY_SET, [posting], ) ledger.append(entry) ledger = data.sorted(ledger) # make balance b = balance(file, account_name, currency, statement, ledger) if b != None: ledger.append(b) return ledger
def parse_ofx(text): s = StringIO.StringIO(text) ofx = OfxParser.parse(s) patterns = db.session.query(Pattern).filter(Pattern.pattern!='.').all() patterns.append( db.session.query(Pattern).filter(Pattern.pattern=='.').first() ) db_records = set([r.id for r in db.session.query(Record).all()]) records = [ Record(id=t.id, payee=t.payee, date=t.date, amount=t.amount) for t in ofx.account.statement.transactions if t.id not in db_records ] transactions = [] for record in records: matched = False for pattern in patterns: if pattern.match(record): transactions += pattern.transactions(record) matched = True break return transactions
def test_fresh_sync(self): ledger = Ledger(os.path.join('fixtures', 'empty.lgr')) sync = Synchronizer(ledger) ofx = OfxParser.parse(file(os.path.join('fixtures', 'checking.ofx'))) txns1 = ofx.account.statement.transactions txns2 = sync.filter(ofx) self.assertEqual(txns1, txns2)
def test_using_ofx_printer(self): with open_file('checking.ofx') as f: ofx = OfxParser.parse(f) fd, name = mkstemp() close(fd) printer = OfxPrinter(ofx=ofx, filename=name) printer.write(tabs=1)
def test_checking_custom_payee(self): with open(os.path.join('fixtures', 'checking.ofx'), 'rb') as ofx_file: ofx = OfxParser.parse(ofx_file) converter = OfxConverter(account=ofx.account, name="Foo", payee_format="{memo}") self.assertEqual( converter.format_payee(ofx.account.statement.transactions[0]), 'DIVIDEND EARNED FOR PERIOD OF 03/01/2011 THROUGH 03/31/2011 ANNUAL PERCENTAGE YIELD EARNED IS 0.05%' ) converter = OfxConverter(account=ofx.account, name="Foo", payee_format="{payee}") self.assertEqual( converter.format_payee(ofx.account.statement.transactions[0]), 'DIVIDEND EARNED FOR PERIOD OF 03') converter = OfxConverter(account=ofx.account, name="Foo", payee_format="{account}") self.assertEqual( converter.format_payee(ofx.account.statement.transactions[0]), 'Foo') converter = OfxConverter(account=ofx.account, name="Foo", payee_format=" {account} ") self.assertEqual( converter.format_payee(ofx.account.statement.transactions[0]), 'Foo')
def test_checking(self): with open(os.path.join('fixtures', 'checking.ofx'), 'rb') as ofx_file: ofx = OfxParser.parse(ofx_file) converter = OfxConverter(account=ofx.account, name="Foo") self.assertEqualLedgerPosting( converter.convert(ofx.account.statement.transactions[0]).format(), """2011/03/31 DIVIDEND EARNED FOR PERIOD OF 03/01/2011 THROUGH 03/31/2011 ANNUAL PERCENTAGE YIELD EARNED IS 0.05% Foo $0.01 ; ofxid: 1101.1452687~7.0000486 Expenses:Misc -$0.01 """) self.assertEqualLedgerPosting( converter.convert(ofx.account.statement.transactions[1]).format(), """2011/04/05 AUTOMATIC WITHDRAWAL, ELECTRIC BILL WEB(S ) Foo -$34.51 ; ofxid: 1101.1452687~7.0000487 Expenses:Misc $34.51 """) self.assertEqualLedgerPosting( converter.convert(ofx.account.statement.transactions[2]).format(), """2011/04/07 RETURNED CHECK FEE, CHECK # 319 FOR $45.33 ON 04/07/11 Foo -$25.00 ; ofxid: 1101.1452687~7.0000488 Expenses:Misc $25.00 """)
def test_transfer_txn(self): with open(os.path.join('fixtures', 'investment_401k.ofx'), 'rb') as ofx_file: ofx = OfxParser.parse(ofx_file) converter = OfxConverter(account=ofx.account, name="Foo", unknownaccount='Expenses:Unknown') if len(ofx.account.statement.transactions) > 2: # older versions of ofxparse would skip these transactions if hasattr(ofx.account.statement.transactions[2], 'tferaction'): # unmerged pull request self.assertEqualLedgerPosting( converter.convert( ofx.account.statement.transactions[2]).format(), """2014/06/30 Foo: transfer: out Foo -9.060702 BAZ @ $21.928764 ; ofxid: 1234.12345678.123456-01.3 Transfer $198.69 """) else: self.assertEqualLedgerPosting( converter.convert( ofx.account.statement.transactions[2]).format(), """2014/06/30 Foo: transfer Foo -9.060702 BAZ @ $21.928764 ; ofxid: 1234.12345678.123456-01.3 Transfer $198.69 """)
def test_fee(self): """Test that fees are parsed correctly. In this case we have a 7-cent fee. We need to make sure that the net sale price which shows up is the gross price of 3239.44 minus 7 cents which equals 3239.37 and that the 7 cent fee shows up as an extra posting. """ with open(os.path.join('fixtures', 'fidelity_fee.ofx'), 'rb') as ofx_file: ofx = OfxParser.parse(ofx_file) converter = OfxConverter(account=ofx.account, name="Foo", security_list=SecurityList(ofx)) # test fee self.assertEqualLedgerPosting( converter.convert(ofx.account.statement.transactions[1]).format(), """2012/08/01 SELL Foo -100.0 "929042109" @ $32.3944 ; ofxid: 7776.01234567890.0123456789021401420120801 Assets:Unknown $3239.37 Expenses:Fees $0.07 """) # test fee and comission self.assertEqualLedgerPosting( converter.convert(ofx.account.statement.transactions[0]).format(), """2020/05/22=2020/05/26 SELL Foo -1.0 "Z9977810Z" @ $8.27 ; ofxid: 7776.01234567890.987654321 Assets:Unknown $8.25 Expenses:Fees $0.02 Expenses:Commission $1.00 """)
def test_position(self): ofx = OfxParser.parse(file(os.path.join('fixtures', 'cusip.ofx'))) converter = OfxConverter(ofx=ofx, name="Foo", indent=4, unknownaccount='Expenses:Unknown') self.assertEqual(converter.format_position(ofx.account.statement.positions[0]), """P 2016/10/08 07:30:08 SHSAX 47.8600000 """)
def test_fresh_sync(self): ledger = Ledger(os.path.join('fixtures', 'empty.lgr')) sync = OfxSynchronizer(ledger) ofx = OfxParser.parse(file(os.path.join('fixtures', 'checking.ofx'))) txns1 = ofx.account.statement.transactions txns2 = sync.filter(ofx) self.assertEqual(txns1, txns2)
def process_ofx(self, cr, uid, data_file, journal_id=False, context=None): """ Import a file in the .OFX format""" if ofxparser is None: raise osv.except_osv(_("Error"), _("OFX parser unavailable because the `ofxparse` Python library cannot be found." "It can be downloaded and installed from `https://pypi.python.org/pypi/ofxparse`.")) try: tempfile = open("temp.ofx", "w+") tempfile.write(base64.decodestring(data_file)) tempfile.read() pathname = os.path.dirname('temp.ofx') path = os.path.join(os.path.abspath(pathname), 'temp.ofx') ofx = ofxparser.parse(file(path)) except: raise osv.except_osv(_('Import Error!'), _('Please check OFX file format is proper or not.')) line_ids = [] total_amt = 0.00 try: for transaction in ofx.account.statement.transactions: bank_account_id, partner_id = self._detect_partner(cr, uid, transaction.payee, identifying_field='owner_name', context=context) vals_line = { 'date': transaction.date, 'name': transaction.payee + ': ' + transaction.memo, 'ref': transaction.id, 'amount': transaction.amount, 'partner_id': partner_id, 'bank_account_id': bank_account_id, } total_amt += float(transaction.amount) line_ids.append((0, 0, vals_line)) except Exception, e: raise osv.except_osv(_('Error!'), _("Following problem has been occurred while importing your file, Please verify the file is proper or not.\n\n %s" % e.message))
def testTransferAggregate(self): with open_file('investment_401k.ofx') as f: ofx = OfxParser.parse(f) expected_txns = [{ 'id': '1', 'type': 'buymf', 'units': Decimal('8.846699'), 'unit_price': Decimal('22.2908'), 'total': Decimal('-197.2'), 'security': 'FOO', 'tferaction': None }, { 'id': '2', 'type': 'transfer', 'units': Decimal('6.800992'), 'unit_price': Decimal('29.214856'), 'total': Decimal('0.0'), 'security': 'BAR', 'tferaction': 'IN' }, { 'id': '3', 'type': 'transfer', 'units': Decimal('-9.060702'), 'unit_price': Decimal('21.928764'), 'total': Decimal('0.0'), 'security': 'BAZ', 'tferaction': 'OUT' }] for txn, expected_txn in zip(ofx.account.statement.transactions, expected_txns): self.assertEqual(txn.id, expected_txn['id']) self.assertEqual(txn.type, expected_txn['type']) self.assertEqual(txn.units, expected_txn['units']) self.assertEqual(txn.unit_price, expected_txn['unit_price']) self.assertEqual(txn.total, expected_txn['total']) self.assertEqual(txn.security, expected_txn['security']) self.assertEqual(txn.tferaction, expected_txn['tferaction']) expected_positions = [{ 'security': 'FOO', 'units': Decimal('17.604312'), 'unit_price': Decimal('22.517211'), 'market_value': Decimal('396.4') }, { 'security': 'BAR', 'units': Decimal('13.550983'), 'unit_price': Decimal('29.214855'), 'market_value': Decimal('395.89') }, { 'security': 'BAZ', 'units': Decimal('0.0'), 'unit_price': Decimal('0.0'), 'market_value': Decimal('0.0') }] for pos, expected_pos in zip(ofx.account.statement.positions, expected_positions): self.assertEqual(pos.security, expected_pos['security']) self.assertEqual(pos.units, expected_pos['units']) self.assertEqual(pos.unit_price, expected_pos['unit_price']) self.assertEqual(pos.market_value, expected_pos['market_value'])
def testEverything(self): ofx = OfxParser.parse(open_file('bank_medium.ofx')) self.assertEquals('12300 000012345678', ofx.account.number) self.assertEquals('160000100', ofx.account.routing_number) self.assertEquals('00', ofx.account.branch_id) self.assertEquals('CHECKING', ofx.account.account_type) self.assertEquals(Decimal('382.34'), ofx.account.statement.balance) self.assertEquals(datetime(2009, 5, 23, 12, 20, 17), ofx.account.statement.balance_date) # Todo: support values in decimal or int form. # self.assertEquals('15', # ofx.bank_account.statement.balance_in_pennies) self.assertEquals( Decimal('682.34'), ofx.account.statement.available_balance) self.assertEquals(datetime(2009, 5, 23, 12, 20, 17), ofx.account.statement.available_balance_date) self.assertEquals( datetime(2009, 4, 1), ofx.account.statement.start_date) self.assertEquals( datetime(2009, 5, 23, 12, 20, 17), ofx.account.statement.end_date) self.assertEquals(3, len(ofx.account.statement.transactions)) transaction = ofx.account.statement.transactions[0] self.assertEquals("MCDONALD'S #112", transaction.payee) self.assertEquals('pos', transaction.type) self.assertEquals(Decimal('-6.60'), transaction.amount)
def testEverything(self): ofx = OfxParser.parse(open_file('bank_medium.ofx')) self.assertEquals('12300 000012345678', ofx.account.number) self.assertEquals('160000100', ofx.account.routing_number) self.assertEquals('00', ofx.account.branch_id) self.assertEquals('CHECKING', ofx.account.account_type) self.assertEquals(Decimal('382.34'), ofx.account.statement.balance) self.assertEquals(datetime(2009, 5, 23, 12, 20, 17), ofx.account.statement.balance_date) # Todo: support values in decimal or int form. # self.assertEquals('15', # ofx.bank_account.statement.balance_in_pennies) self.assertEquals(Decimal('682.34'), ofx.account.statement.available_balance) self.assertEquals(datetime(2009, 5, 23, 12, 20, 17), ofx.account.statement.available_balance_date) self.assertEquals(datetime(2009, 4, 1), ofx.account.statement.start_date) self.assertEquals(datetime(2009, 5, 23, 12, 20, 17), ofx.account.statement.end_date) self.assertEquals(3, len(ofx.account.statement.transactions)) transaction = ofx.account.statement.transactions[0] self.assertEquals("MCDONALD'S #112", transaction.payee) self.assertEquals('pos', transaction.type) self.assertEquals(Decimal('-6.60'), transaction.amount)
def testForFourAccounts(self): ofx = OfxParser.parse(open_file('account_listing_aggregation.ofx')) self.assertTrue(hasattr(ofx, 'accounts')) self.assertEquals(len(ofx.accounts), 4) # first account account = ofx.accounts[0] self.assertEquals(account.account_type, 'SAVINGS') self.assertEquals(account.desc, 'USAA SAVINGS') self.assertEquals(account.institution.organization, 'USAA') self.assertEquals(account.number, '0000000001') self.assertEquals(account.routing_number, '314074269') # second account = ofx.accounts[1] self.assertEquals(account.account_type, 'CHECKING') self.assertEquals(account.desc, 'FOUR STAR CHECKING') self.assertEquals(account.institution.organization, 'USAA') self.assertEquals(account.number, '0000000002') self.assertEquals(account.routing_number, '314074269') # third account = ofx.accounts[2] self.assertEquals(account.account_type, 'CREDITLINE') self.assertEquals(account.desc, 'LINE OF CREDIT') self.assertEquals(account.institution.organization, 'USAA') self.assertEquals(account.number, '00000000000003') self.assertEquals(account.routing_number, '314074269') # fourth account = ofx.accounts[3] self.assertEquals(account.account_type, '') self.assertEquals(account.desc, 'MY CREDIT CARD') self.assertEquals(account.institution.organization, 'USAA') self.assertEquals(account.number, '4111111111111111')
def testMissingTransactionHeader(self): with open_file('ofx-v102-empty-tags.ofx') as f: ofx = OfxParser.parse(f, fail_fast=False) # Empty currency definition self.assertTrue(ofx.accounts[0].statement.warnings[0].startswith( "Currency definition was empty for <stmtrs><curdef></curdef>"))
def process_ofx(self, cr, uid, data_file, journal_id=False, context=None): """ Import a file in the .OFX format""" if ofxparser is None: raise osv.except_osv(_("Error"), _("OFX parser unavailable because the `ofxparse` Python library cannot be found." "It can be downloaded and installed from `https://pypi.python.org/pypi/ofxparse`.")) try: osuser = getpass.getuser() path = os.path.expanduser('~{}/temp.ofx'.format(osuser)) tempfile = open(path, "w+") tempfile.write(base64.decodestring(data_file)) tempfile.read() # pathname = os.path.dirname('temp.ofx') # path = os.path.join(os.path.abspath(pathname), 'temp.ofx') print "save import statement file {}".format(path) ofx = ofxparser.parse(file(path)) except: raise osv.except_osv(_('Import Error!'), _('Please check OFX file format is proper or not.')) line_ids = [] total_amt = 0.00 try: for transaction in ofx.account.statement.transactions: bank_account_id, partner_id = self._detect_partner(cr, uid, transaction.payee, identifying_field='owner_name', context=context) vals_line = { 'date': transaction.date, 'name': transaction.payee + ': ' + transaction.memo, 'ref': transaction.id, 'amount': transaction.amount, 'partner_id': partner_id, 'bank_account_id': False, } total_amt += float(transaction.amount) line_ids.append((0, 0, vals_line)) except Exception, e: raise osv.except_osv(_('Error!'), _("Following problem has been occurred while importing your file, Please verify the file is proper or not.\n\n %s" % e.message))
def testForUnclosedTags(self): with open_file('fidelity.ofx') as f: ofx = OfxParser.parse(f) self.assertTrue(hasattr(ofx.account.statement, 'positions')) self.assertEqual(len(ofx.account.statement.positions), 6) self.assertEqual(ofx.account.statement.positions[0].units, Decimal('128.0'))
def to_obp_json(account_holder, ofx_file): # if not an ofx file then exist if not ofx_file.endswith('.ofx'): return #Initiate the ofx object ofx = OfxParser.parse(file(ofx_file)) transactions = [] #Get Info about the Holders' Account account_id = ofx.account.number bank = ofx.account.institution.organization kind = ofx.account.account_type #For each transaction transform the OFX transaction to a OBP transaction for transaction in ofx.account.statement.transactions: obp_transaction = {} this_account = { "holder":account_holder, "number":account_id, "kind": kind, "bank":{ "IBAN":"unknown", "national_identifier":"unknown", "name": bank} } other_account = { "holder": transaction.payee or transaction.id, "number":"unknown", "kind": "unknown", "bank":{ "IBAN":"unknown", "national_identifier":"unknown", "name":"unknown"} } details = { "type_en":transaction.type, "type_de":transaction.type, "posted":{"$dt":convert_date(transaction.date)}, "completed":{"$dt":convert_date(transaction.date)}, "new_balance":{ "currency":ofx.account.statement.currency, "amount":str(ofx.account.statement.balance) }, "value":{ "currency":ofx.account.statement.currency, "amount":str(transaction.amount) }, "other_data":transaction.memo } obp_transaction = {'this_account':this_account, 'other_account':other_account, 'details' : details } transactions.append({'obp_transaction':obp_transaction}) #Serializing the object obpjson = json.dumps(transactions) #Return the newly created json return obpjson
def test_balance_assertion(self): ofx = OfxParser.parse(file(os.path.join('fixtures', 'checking.ofx'))) ledger = Ledger(os.path.join('fixtures', 'checking.lgr')) formatter = Formatter(account=ofx.account, name="Assets:Foo", ledger=ledger) self.assertEqual(formatter.format_balance(ofx.account.statement), """2013/05/25 * --Autosync Balance Assertion Assets:Foo $0.00 = $100.99 """)
def _check_ofx(self, data_file): if ofxparser is None: return False try: ofx = ofxparser.parse(StringIO.StringIO(data_file)) except: return False return ofx
def download_parsed(self, days=60): """Downloaded OFX response parsed by :py:meth:`OfxParser.parse` :param days: Number of days to look back at :type days: integer :rtype: :py:class:`ofxparser.Ofx` """ return OfxParser.parse(self.download(days=days))
def testReadAccount(self): with open_file('tiaacref.ofx') as f: ofx = OfxParser.parse(f) self.assertTrue(hasattr(ofx, 'account')) self.assertTrue(hasattr(ofx.account, 'account_id')) self.assertEqual(ofx.account.account_id, '111A1111 22B222 33C333') self.assertTrue(hasattr(ofx.account, 'type')) self.assertEqual(ofx.account.type, AccountType.Investment)
def test_balance_assertion(self): ofx = OfxParser.parse(file(os.path.join('fixtures', 'checking.ofx'))) ledger = Ledger(os.path.join('fixtures', 'checking.lgr')) converter = OfxConverter(ofx=ofx, name="Assets:Foo", ledger=ledger) self.assertEqualLedgerPosting(converter.format_balance(ofx.account.statement), """2013/05/25 * --Autosync Balance Assertion Assets:Foo $0.00 = $100.99 """)
def _check_ofx(self, file): if ofxparser is None: return False try: ofx = ofxparser.parse(file) except: return False return ofx
def _check_ofx(self, cr, uid, file, context=None): if ofxparser is None: return False try: ofx = ofxparser.parse(file) except: return False return ofx
def test_sync_order(self): ledger = Ledger(os.path.join('fixtures', 'empty.lgr')) sync = OfxSynchronizer(ledger) ofx = OfxParser.parse( file(os.path.join('fixtures', 'checking_order.ofx'))) txns = sync.filter(ofx) self.assertTrue(txns[0].date < txns[1].date and txns[1].date < txns[2].date)
def testTransferAggregate(self): with open_file('investment_401k.ofx') as f: ofx = OfxParser.parse(f) expected_txns = [{'id': '1', 'type': 'buymf', 'units': Decimal('8.846699'), 'unit_price': Decimal('22.2908'), 'total': Decimal('-197.2'), 'security': 'FOO', 'tferaction': None}, {'id': '2', 'type': 'transfer', 'units': Decimal('6.800992'), 'unit_price': Decimal('29.214856'), 'total': Decimal('0.0'), 'security': 'BAR', 'tferaction': 'IN'}, {'id': '3', 'type': 'transfer', 'units': Decimal('-9.060702'), 'unit_price': Decimal('21.928764'), 'total': Decimal('0.0'), 'security': 'BAZ', 'tferaction': 'OUT'}] for txn, expected_txn in zip(ofx.account.statement.transactions, expected_txns): self.assertEqual(txn.id, expected_txn['id']) self.assertEqual(txn.type, expected_txn['type']) self.assertEqual(txn.units, expected_txn['units']) self.assertEqual(txn.unit_price, expected_txn['unit_price']) self.assertEqual(txn.total, expected_txn['total']) self.assertEqual(txn.security, expected_txn['security']) self.assertEqual(txn.tferaction, expected_txn['tferaction']) expected_positions = [ { 'security': 'FOO', 'units': Decimal('17.604312'), 'unit_price': Decimal('22.517211'), 'market_value': Decimal('396.4') }, { 'security': 'BAR', 'units': Decimal('13.550983'), 'unit_price': Decimal('29.214855'), 'market_value': Decimal('395.89') }, { 'security': 'BAZ', 'units': Decimal('0.0'), 'unit_price': Decimal('0.0'), 'market_value': Decimal('0.0') } ] for pos, expected_pos in zip(ofx.account.statement.positions, expected_positions): self.assertEqual(pos.security, expected_pos['security']) self.assertEqual(pos.units, expected_pos['units']) self.assertEqual(pos.unit_price, expected_pos['unit_price']) self.assertEqual(pos.market_value, expected_pos['market_value'])