import six
class OfxPrinter():
ofx = None
out_filename = None
out_handle = None
term = "\r\n"
def __init__(self, ofx, filename, term="\r\n"):
self.ofx = ofx
self.out_filename = filename
self.term = term
def writeLine(self, data, tabs=0, term=None):
if term is None:
term = self.term
tabbing = (tabs * "\t") if (tabs > 0) else ''
return self.out_handle.write(
"{0}{1}{2}".format(
tabbing,
data,
term
)
)
def writeHeaders(self):
for k, v in six.iteritems(self.ofx.headers):
if v is None:
self.writeLine("{0}:NONE".format(k))
else:
self.writeLine("{0}:{1}".format(k, v))
self.writeLine("")
def writeSignOn(self, tabs=0):
# signon already has newlines and tabs in it
# TODO: reimplement signon printing with tabs
self.writeLine(self.ofx.signon.__str__(), term="")
def printDate(self, dt, msec_digs=3):
strdt = dt.strftime('%Y%m%d%H%M%S')
strdt_msec = dt.strftime('%f')
if len(strdt_msec) < msec_digs:
strdt_msec += ('0' * (msec_digs - len(strdt_msec)))
elif len(strdt_msec) > msec_digs:
strdt_msec = strdt_msec[:msec_digs]
return strdt + '.' + strdt_msec
def writeTrn(self, trn, tabs=5):
self.writeLine("", tabs=tabs)
tabs += 1
self.writeLine("{}".format(trn.type.upper()), tabs=tabs)
self.writeLine("{}".format(
self.printDate(trn.date)
), tabs=tabs)
self.writeLine("{0:.2f}".format(float(trn.amount)), tabs=tabs)
self.writeLine("{}".format(trn.id), tabs=tabs)
if len(str(trn.checknum)) > 0:
self.writeLine("{}".format(
trn.checknum
), tabs=tabs)
self.writeLine("{}".format(trn.payee), tabs=tabs)
if len(trn.memo.strip()) > 0:
self.writeLine("{}".format(trn.memo), tabs=tabs)
tabs -= 1
self.writeLine("", tabs=tabs)
def writeLedgerBal(self, statement, tabs=4):
bal = getattr(statement, 'balance', None)
baldt = getattr(statement, 'balance_date', None)
if bal and baldt:
self.writeLine("", tabs=tabs)
self.writeLine("{0:.2f}".format(float(bal)), tabs=tabs+1)
self.writeLine("{0}".format(
self.printDate(baldt)
), tabs=tabs+1)
self.writeLine("", tabs=tabs)
def writeAvailBal(self, statement, tabs=4):
bal = getattr(statement, 'available_balance', None)
baldt = getattr(statement, 'available_balance_date', None)
if bal and baldt:
self.writeLine("", tabs=tabs)
self.writeLine("{0:.2f}".format(float(bal)), tabs=tabs+1)
self.writeLine("{0}".format(
self.printDate(baldt)
), tabs=tabs+1)
self.writeLine("", tabs=tabs)
def writeStmTrs(self, tabs=3):
for acct in self.ofx.accounts:
self.writeLine("", tabs=tabs)
tabs += 1
if acct.curdef:
self.writeLine("{0}".format(
acct.curdef
), tabs=tabs)
if acct.routing_number or acct.account_id or acct.account_type:
self.writeLine("", tabs=tabs)
if acct.routing_number:
self.writeLine("{0}".format(
acct.routing_number
), tabs=tabs+1)
if acct.account_id:
self.writeLine("{0}".format(
acct.account_id
), tabs=tabs+1)
if acct.account_type:
self.writeLine("{0}".format(
acct.account_type
), tabs=tabs+1)
self.writeLine("", tabs=tabs)
self.writeLine("", tabs=tabs)
tabs += 1
self.writeLine("{0}".format(
self.printDate(acct.statement.start_date)
), tabs=tabs)
self.writeLine("{0}".format(
self.printDate(acct.statement.end_date)
), tabs=tabs)
for trn in acct.statement.transactions:
self.writeTrn(trn, tabs=tabs)
tabs -= 1
self.writeLine("", tabs=tabs)
self.writeLedgerBal(acct.statement, tabs=tabs)
self.writeAvailBal(acct.statement, tabs=tabs)
tabs -= 1
self.writeLine("", tabs=tabs)
def writeBankMsgsRsv1(self, tabs=1):
self.writeLine("", tabs=tabs)
tabs += 1
self.writeLine("", tabs=tabs)
tabs += 1
if self.ofx.trnuid is not None:
self.writeLine("{0}".format(
self.ofx.trnuid
), tabs=tabs)
if self.ofx.status:
self.writeLine("", tabs=tabs)
self.writeLine("{0}".format(
self.ofx.status['code']
), tabs=tabs+1)
self.writeLine("{0}".format(
self.ofx.status['severity']
), tabs=tabs+1)
self.writeLine("
", tabs=tabs)
self.writeStmTrs(tabs=tabs)
tabs -= 1
self.writeLine("", tabs=tabs)
tabs -= 1
self.writeLine("", tabs=tabs)
def writeOfx(self, tabs=0):
self.writeLine("", tabs=tabs)
tabs += 1
self.writeSignOn(tabs=tabs)
self.writeBankMsgsRsv1(tabs=tabs)
tabs -= 1
# No newline at end of file
self.writeLine("", tabs=tabs, term="")
def writeToFile(self, fileObject, tabs=0):
if self.out_handle:
raise Exception("Already writing file")
self.out_handle = fileObject
self.writeHeaders()
self.writeOfx(tabs=tabs)
self.out_handle.flush()
self.out_handle = None
def write(self, filename=None, tabs=0):
if filename is None:
filename = self.out_filename
with open(filename, 'w') as f:
self.writeToFile(f)