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
Exemple #2
0
 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
Exemple #3
0
    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)
Exemple #4
0
    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())))
Exemple #5
0
    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, "")
Exemple #6
0
    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, '')
Exemple #7
0
    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, '')
Exemple #8
0
    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)
Exemple #9
0
 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")
Exemple #10
0
 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')
Exemple #12
0
 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
Exemple #13
0
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]
Exemple #14
0
 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')
Exemple #15
0
 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')
Exemple #16
0
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]))
Exemple #17
0
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
Exemple #18
0
    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
""")
Exemple #20
0
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
Exemple #21
0
 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'))
Exemple #22
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)
Exemple #24
0
 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_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
""")
Exemple #26
0
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))
Exemple #27
0
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
Exemple #28
0
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)
Exemple #30
0
 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
""")
Exemple #36
0
 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)
Exemple #37
0
 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 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))
Exemple #39
0
    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'])
Exemple #40
0
    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)
Exemple #41
0
 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)
Exemple #42
0
    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)
Exemple #43
0
    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')
Exemple #44
0
    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))
Exemple #46
0
 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'))
Exemple #47
0
    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 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
""")
Exemple #50
0
 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
Exemple #51
0
    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))
Exemple #52
0
 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
""")
Exemple #54
0
 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 _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
Exemple #57
0
 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)
Exemple #58
0
    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'])