Permalink
Browse files

Merge branch 'development'

  • Loading branch information...
2 parents 523d3e2 + 1c42094 commit 77319b4db02c37eb4b1a0ce597310b14a56e5200 @evandavey committed Mar 30, 2012
View
@@ -1,8 +1,88 @@
-#BankDownloadProcessor
+#django-bankdownloads
-* Set of tools to read in and standardise bank transaction downloads
+* django app to import and standardise bank transaction downloads
-* Capable of reading csv or ofx files and converting to a clean and standardised format
+* imports ofx (open financial exchange format) via the ofxparse library
+
+* imports csv using regex to match data columns
+
+* bankid and accountid taken from original file if possible, otherwise from a filename in the format
+
+ <bankid>-<accountid>-YYYYMMDD.<ext>
+
+* creates a standardised data dictionary with headers:
+
+ date
+ transid
+ value
+ currency
+ memo
+ payee
+ accountid
+ bankid
+ fxcurrency
+ fxrate
+ fxamount
+
+* outputs data in ofx format
+
+
+##Requirements
+
+* working django site
+
+##Install
+
+1. Get the code
+
+ > git clone git://github.com/evandavey/django-bankdownloads.git django-bankdownloads
+
+2. Install via pip
+
+ > pip install django-bankdownloads
+
+3. Add 'bankdownloads' to INSTALLED_APPS
+
+4. Add BANKDOWNLOADS_IMPORT_PATH,BANKDOWNLOADS_OUTPUT_PATH,BANKDOWNLOADS_EMAILS and BANKDOWNLOADS_NOTIFIER_EXCLUDES to settings
+
+##Use
+
+* provides a 'BankDownload' class that can be reused in other applications
+
+ > mydownload = BankDownload()
+
+ > mydownload.original_file=[file]
+
+ > mydownload.save()
+
+* access standardised data via the 'data' property
+
+ > data = mydownload.data
+
+ > ofx = mydownload.export_ofx()
+
+* use management command bankdownloads_notifier to email if data is missing for a given month
+
+* use management command bankdownloads_processor to batch import bank downloads and output standardised ofx
+
+##Authors
+
+Evan Davey evan.davey@cochranedavey.com
+
+##Licenses
+
+CC-SA-NC
+
+[Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License][cc-nc-sa].
+
+![][img-cc-nc-sa]
+
+
+[cc-nc-sa]: http://creativecommons.org/licenses/by-nc-sa/3.0/
+
+[img-cc-nc-sa]: http://i.creativecommons.org/l/by-nc-sa/3.0/88x31.png
+
+
+
-* bankdowload-processor script compares checksums of new files to those stored in a database to allow automatic processing of new files
@@ -1 +1,8 @@
-from bankdownload import *
+VERSION = (0, 1, 0)
+
+__version__ = ".".join(map(str, VERSION[0:3])) + "".join(VERSION[3:])
+__author__ = "Evan Davey"
+__contact__ = "evan.davey@cochranedavey.com"
+__homepage__ = "http://celeryproject.org"
+__docformat__ = "markdown"
+__license__ = "Creative Commons Share Alike Non Commercial Use"
View
@@ -0,0 +1,24 @@
+from django.contrib import admin
+from bankdownloads.models import *
+
+
+class BankDownloadAdmin(admin.ModelAdmin):
+ """ Object to control the behaviour of the linked object in the Admin interface
+ """
+ list_display = ['original_file_name','checksum','upload_date','records','start_date','end_date']
+ list_filter = ['bank_id','account_id']
+ ordering = ['upload_date']
+ search_fields = ['original_file']
+
+
+
+admin.site.register(BankDownload,BankDownloadAdmin)
+
+
+
+
+
+
+
+
+
View
@@ -1,207 +0,0 @@
-import csv
-import sys
-import hashlib
-import time
-import os
-
-#Parent class that defines basic attributes and methods for BankCSV files
-class BankCSV:
-
-
-
- def __init__(self,path):
- self.bankid = ""
- self.path = path
- self.data =[]
- self.accountid = ""
-
- def __repr__(self):
-
- ostr="Name:"+self.bankid+"\n"
- ostr+="Acc:"+self.accountid+"\n"
- ostr+="Path:"+self.path+"\n"
-
- self.printdata()
-
- return ostr
-
- def wipeclear(self):
-
- print "wiping " + self.bankid
- self.bankid=''
- self.path=''
- self.accountid=''
- del self.data[:]
-
- def GetData(self):
- return self.data
-
- def GetAccountId(self):
- return self.accountid
-
- def GetBankId(self):
- return self.bankid
-
- def printdata(self):
-
- for row in self.data:
- print row
-
- def GetAccountIdFromPath(self):
-
- try:
-
- filename=self.path
- filename=os.path.basename(self.path)
- return filename.split('-')[1]
-
- except:
- return ""
-
- def GetAccountIdRabo(self):
-
- ofile = open(self.path, "r")
- reader = csv.reader(ofile)
- header=reader.next()
- accid=''
- if len(header) == 3:
- accid=header[1]
- accid=accid.replace("-","")
-
-
- return accid
- ofile.close()
-
-
- def format_val(self,val):
-
- val=val.strip().replace('$','').replace(',','')
-
- if val:
- val=float(val)
- return val
- else:
- return 0
-
- def load(self):
-
- # data definitions
- csvs=[
- {'bankid':'CBACashManagement',
- 'header': ['Date','Description','Debit($)','Credit($)','Balance($)',''],
- 'currency': 'AUD',
- 'header_row': 1,
- 'data_row': 2,
- 'date_col':0,
- 'date_format':"%d/%m/%Y",
- 'credit_col':3,
- 'memo_col': 1,
- 'accountid':self.GetAccountIdFromPath()
- },
- {'bankid':'RaboPlus',
- 'header': ['Operation number', 'Operation date', 'Description', 'Operation amount', 'Currency', 'Value date', 'Counterparty account', 'Counterparty name :', 'Communication 1 :', 'Communication 2 :', 'Operation reference'],
- 'currency': 'AUD',
- 'header_row': 2,
- 'data_row': 3,
- 'date_col':1,
- 'date_format':"%d-%m-%Y",
- 'credit_col':3,
- 'memo_col': 2,
- 'payee_col': 6,
- 'accountid':self.GetAccountIdRabo(),
- },
- {'bankid':'INGDirect',
- 'header': ['Date',' Description',' Debit',' Credit',' Balance'],
- 'header_row': 1,
- 'currency': 'AUD',
- 'data_row': 2,
- 'date_col':0,
- 'date_format':"%d/%m/%Y",
- 'credit_col':3,
- 'debit_col':2,
- 'memo_col': 1,
- 'accountid':self.GetAccountIdFromPath(),
- },
- {'bankid':'FSFSuper',
- 'header': ['Transaction Date','Payroll End Date','Employer','Transaction Type','Investment Option','Transaction Units','Unit Price','Transaction Amount'],
- 'header_row': 1,
- 'currency': 'AUD',
- 'data_row': 2,
- 'date_col':0,
- 'date_format':"%d/%m/%Y",
- 'credit_col':7,
- 'memo_col': 3,
- 'accountid':self.GetAccountIdFromPath(),
- },
- ]
-
- for c in csvs:
- f = open(self.path, "r")
- reader = csv.reader(f)
-
- for i in range(0,c['header_row']):
- try:
- header=reader.next()
- except:
- continue
- i=i+1
-
-
- if header == c['header']:
- self.bankid=c['bankid']
- self.accountid=c['accountid']
- print "....found csv for %s,%s" % (self.bankid,self.accountid)
-
- for row in reader:
- if len(row)==0:
- continue
-
- dt=row[c['date_col']]
- dt = time.strptime(dt, c['date_format'])
- dt = time.strftime("%Y%m%d", dt)
-
- curr=c['currency']
- fxcurr=curr
- fxrate=1
-
- try:
- payee=row[c['payee_col']].strip()
- except:
- payee=""
-
- try:
- memo=row[c['memo_col']].strip()
- except:
- memo=""
-
- try:
- debit=abs(self.format_val(row[c['debit_col']]))*-1
- debit=float(debit)
- except:
- print 'Error reading debit'
- debit=0.0
-
- try:
- credit=abs(self.format_val(row[c['credit_col']]))
- credit=float(credit)
-
- except:
- print 'Error reading credit'
- credit=0.0
-
- if (debit):
- val = round(debit,2)
- else:
- val = round(credit,2)
-
- fxamount=val
-
- transid=hashlib.md5(self.bankid+dt+str(val)+payee+memo).hexdigest()
- self.data.append({"transid":transid,"bankid":self.bankid,"accountid":self.accountid,"date":dt,"payee":payee,"memo":memo,"value":val,"currency":curr,"fxcurrency":fxcurr,"fxamount":fxamount,"fxrate":fxrate})
-
- f.close()
- return
- f.close()
- print "**NO MATCH**"
- return
-
Oops, something went wrong.

0 comments on commit 77319b4

Please sign in to comment.