Commits

Jason R. Coombs  committed 7665143

Implemented construction of a portfolio from an input file

  • Participants
  • Parent commits 02cae6f

Comments (0)

Files changed (2)

File jaraco/financial/ledger.py

 import bisect
 import datetime
 
+import jaraco.util.itertools
+
 class Transaction(object):
 	payee = None
-	amount = None
 	date = None
 	designation = None
+	"SimpleDesination, SplitDesignation, or Ledger"
 	source = None
 	"Where was this transaction sourced ('manual', 'bank download')"
 
-	def __init__(self, amount, **kwargs):
-		self.amount = amount
+	def __init__(self, **kwargs):
 		self.__dict__.update(kwargs)
 		if not 'date' in vars(self):
 			self.date = datetime.datetime.utcnow()
 
+	@property
+	def amount(self):
+		"""
+		The total of the amounts of the designations of this transaction.
+		"""
+		return sum(
+			item.amount
+			for item in jaraco.util.itertools.always_list(self.designation)
+		)
+
 	# for the purpose of sorting transactions chronologically, sort by date
 	def __lt__(self, other):
 		return self.date < other.date
 	"""
 	A list of transactions, sorted by date.
 	"""
-	add = bisect.insort_right
+	def add(self, item):
+		bisect.insort_right(self, item)
 
 class Named(object):
 	def __init__(self, name, *args, **kwargs):

File jaraco/financial/merchant.py

+"""
+A collection of Merchant-processing routines for Cornerstone, LLC.
+"""
+
 from __future__ import print_function, unicode_literals
 
 import re
 import collections
+import pickle
+import decimal
+import datetime
 
 from bs4 import BeautifulSoup
 
+from . import ledger
+
 def load_report(source):
 	"""
 	Load a report as downloaded from Translink
 
 	@classmethod
 	def from_row(cls, row):
-		dates = filter(None, map(Date.from_key, row))
-		return [Transaction(date, row[date]) for date in dates]
+		return [
+			Transaction(date, row[date])
+			for date in map(Date.from_key, row)
+			if date and row[date]
+		]
 
 	def __repr__(self):
 		return 'Transaction({date}, {amount})'.format(**vars(self))
 			return None
 		return cls(key)
 
-
-def get_agents(table):
-	return map(Agent.from_row, table)
+	def as_object(self):
+		"Return self as a datetime.date object (1st of the month)"
+		month, year = map(int, self.split('/'))
+		return datetime.date(year, month, 1)
 
 def data(row):
 	return [
 	rows = [collections.OrderedDict(zip(header, data(row)))
 		for row in rows]
 	return rows
+
+def parse_amount(amount_str):
+	"""
+	>>> parse_amount('$20.0')
+	20.0
+	>>> parse_amount('(30)')
+	-30
+	>>> parse_amount('($30.1)')
+	-30.1
+	"""
+	amount_str = amount_str.replace('$', '').replace(',', '')
+	if amount_str.startswith('(') and amount_str.endswith(')'):
+		amount_str = '-'+amount_str.strip('()')
+	return decimal.Decimal(amount_str)
+
+def build_portfolio():
+	"Build a portfolio from a report"
+	portfolio = dict()
+	try:
+		with open('portfolio.pickle', 'rb') as pfp:
+			portfolio = pickle.load(pfp)
+	except:
+		pass
+	import sys
+	filename = sys.argv[1]
+	report = load_report(filename)
+	for agent in report:
+		agent_lgr = portfolio.setdefault(agent, ledger.Ledger())
+		for merchant, residuals in agent.accounts.iteritems():
+			for residual in residuals:
+				amount = parse_amount(residual.amount)
+				date = residual.date.as_object()
+				designation = ledger.SimpleDesignation(
+					descriptor = "Residuals Earned : " + unicode(merchant),
+					amount = amount,
+					)
+				txn = ledger.Transaction(date=date,
+					designation=designation)
+				agent_lgr.add(txn)
+	with open('portfolio.pickle', 'wb') as pfp:
+		pickle.dump(portfolio, pfp, protocol=pickle.HIGHEST_PROTOCOL)
+
+if __name__ == '__main__':
+	build_portfolio()