-
-
Save bodhidogma/bc13a67bd27b4b3a147d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import csv | |
| import sys | |
| from collections import namedtuple | |
| from datetime import datetime | |
| import re | |
| # | |
| # OFX Specification: http://www.ofx.net/ | |
| # | |
| # Instructions (as of 02/15/2015): | |
| # Login to Paypal site (https://www.paypal.com) and | |
| # go to "Activity" | |
| # under "Statements", select "Activity Export" | |
| # select your data / date range | |
| # select a comma delimited (CSV) file type for download | |
| # click "Download History" | |
| # convert file using this script: "paypal2ofx.py < pp.csv > pp.ofx" | |
| # import ofx file | |
| LocalCurrency = "USD" | |
| NowTime = '{0:%Y%m%d%H%M%S}'.format(datetime.now()) | |
| rows = csv.reader(sys.stdin) | |
| fields = [field.strip().lower().replace(' ', '_').replace('/', '_') | |
| for field in rows.next() if field.strip() != ''] | |
| PaypalRecord = namedtuple('PaypalRecord', fields) | |
| transactions = [PaypalRecord(*row[0:len(fields)]) for row in rows] | |
| def convert_datetime(record): | |
| d = datetime.strptime(record.date+' '+record.time,'%m/%d/%Y %H:%M:%S') | |
| # need to put TZ offset in | |
| return '{0:%Y%m%d%H%M%S}[:{1}]'.format(d, record.time_zone) | |
| # Statement Transaction (STMTTRN) | |
| def emit_transaction(date, amount, fit_id, name, memo, trntype): | |
| name = re.sub(r'[&]+','',name) | |
| memo = re.sub(r'[&]+','',memo) | |
| print """ | |
| \t <STMTTRN> | |
| \t <TRNTYPE>{5} | |
| \t <DTPOSTED>{0} | |
| \t <TRNAMT>{1} | |
| \t <FITID>{2:.32} | |
| \t <NAME>{3:.32} | |
| \t <MEMO>{4:.255} | |
| \t </STMTTRN>""".format(date, amount, fit_id, name, memo,trntype) | |
| print """OFXHEADER:100 | |
| DATA:OFXSGML | |
| VERSION:102 | |
| SECURITY:NONE | |
| ENCODING:USASCII | |
| CHARSET:1252 | |
| COMPRESSION:NONE | |
| OLDFILEUID:NONE | |
| NEWFILEUID:NONE | |
| <OFX> | |
| <SIGNONMSGSRSV1> | |
| <SONRS> | |
| <STATUS> | |
| <CODE>0 | |
| <SEVERITY>INFO | |
| </STATUS> | |
| <DTSERVER>{0} | |
| <LANGUAGE>ENG | |
| <FI> | |
| <ORG>PayPal | |
| <FID>12345 | |
| </FI> | |
| </SONRS> | |
| </SIGNONMSGSRSV1> | |
| <BANKMSGSRSV1> | |
| <STMTTRNRS> | |
| <TRNUID>1 | |
| <STATUS> | |
| <CODE>0 | |
| <SEVERITY>INFO | |
| </STATUS> | |
| <STMTRS> | |
| <CURDEF>{1} | |
| <BANKACCTFROM> | |
| <BANKID>12345 | |
| <ACCTID>12345 | |
| <ACCTTYPE>CHECKING | |
| </BANKACCTFROM> | |
| <BANKTRANLIST> | |
| """.format( NowTime, LocalCurrency) | |
| print "\t <DTSTART>{0}".format( convert_datetime(transactions[-1]) ) | |
| print "\t <DTEND>{0}".format( convert_datetime(transactions[0]) ) | |
| for transaction in transactions: | |
| # | |
| memo = "%s: %s %s" % (transaction.name, transaction.item_title, transaction.item_id) | |
| amount = transaction.gross | |
| trntype = "OTHER" | |
| # payment sent | |
| if float(amount) < 0 and transaction.to_email_address != '': | |
| trntype = "DEBIT" | |
| name = transaction.name | |
| memo = "%s (TX) %s %s" % (transaction.to_email_address, transaction.item_title, transaction.item_id) | |
| # payment received | |
| elif float(amount) > 0 and transaction.from_email_address != '': | |
| trntype = "CREDIT" | |
| name = transaction.name | |
| memo = "%s (RX) %s %s" % (transaction.from_email_address, transaction.item_title, transaction.item_id) | |
| else: | |
| name = transaction.type | |
| # check for local currency | |
| if transaction.currency != LocalCurrency: | |
| memo = "({0} ${1}) {2}".format(transaction.currency, amount, memo) | |
| if float(amount) <0 : | |
| amount = -1 | |
| else: | |
| amount = 1 | |
| # sys.stderr.write("Warning: Non-%s transaction, input manually\n" % (LocalCurrency) ) | |
| # | |
| emit_transaction(convert_datetime(transaction), | |
| amount, transaction.transaction_id, name, memo, trntype) | |
| # paypal fees | |
| if float(transaction.fee) != 0: | |
| trntype = "FEE" | |
| emit_transaction(convert_datetime(transaction), | |
| transaction.fee, "%sFEE" % transaction.transaction_id, "Paypal Fee",'',trntype) | |
| print """ | |
| </BANKTRANLIST> | |
| <LEDGERBAL> | |
| <BALAMT>{0} | |
| <DTASOF>{1} | |
| </LEDGERBAL> | |
| </STMTRS> | |
| </STMTTRNRS> | |
| </BANKMSGSRSV1> | |
| </OFX> | |
| """.format(transactions[0].balance, convert_datetime(transactions[0])) | |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Updated tool to add required fields for MS Money Sunset edition.
Allowed non local currency to be imported as well.