diff --git a/accounts/report/accounts_receivable/accounts_receivable.py b/accounts/report/accounts_receivable/accounts_receivable.py
index 86a2475..18fd35c 100644
--- a/accounts/report/accounts_receivable/accounts_receivable.py
+++ b/accounts/report/accounts_receivable/accounts_receivable.py
@@ -3,150 +3,158 @@
 
 from __future__ import unicode_literals
 import webnotes
-from webnotes import msgprint, _
-from webnotes.utils import getdate, nowdate, flt, cstr
+from webnotes import _
+from webnotes.utils import getdate, nowdate, flt
+
+class AccountsReceivableReport(object):
+	def __init__(self, filters=None):
+		self.filters = webnotes._dict(filters or {})
+		self.filters.report_date = getdate(self.filters.report_date or nowdate())
+		self.age_as_on = getdate(nowdate()) \
+			if self.filters.report_date > getdate(nowdate()) \
+			else self.filters.report_date
+			
+	def run(self):
+		return self.get_columns(), self.get_data()
+		
+	def get_columns(self):
+		return [
+			"Posting Date:Date:80", "Account:Link/Account:150", "Customer::150", 
+			"Voucher Type::110", "Voucher No::120", "Remarks::150", 
+			"Due Date:Date:80", "Territory:Link/Territory:80", 
+			"Invoiced Amount:Currency:100", "Payment Received:Currency:100", 
+			"Outstanding Amount:Currency:100", "Age:Int:50", "0-30:Currency:100",
+			"30-60:Currency:100", "60-90:Currency:100", "90-Above:Currency:100"
+		]
+		
+	def get_data(self):
+		data = []
+		future_vouchers = self.get_entries_after(self.filters.report_date)
+		for gle in self.get_entries_till(self.filters.report_date):
+			if self.is_receivable(gle, future_vouchers):
+				outstanding_amount = self.get_outstanding_amount(gle, self.filters.report_date)
+				if abs(outstanding_amount) > 0.01:
+					due_date = self.get_due_date(gle)
+					invoiced_amount = gle.debit if (gle.debit > 0) else 0
+					payment_received = invoiced_amount - outstanding_amount
+					row = [gle.posting_date, gle.account, self.get_customer(gle.account),
+						gle.voucher_type, gle.voucher_no, gle.remarks, due_date,
+						self.get_territory(gle.account), invoiced_amount, payment_received,
+						outstanding_amount]
+					entry_date = due_date if self.filters.ageing_based_on=="Due Date" \
+						else gle.posting_date
+					row += self.get_age(entry_date, outstanding_amount)
+					data.append(row)
+		return data
+				
+	def get_entries_after(self, report_date):
+		# returns a distinct list
+		return list(set([(e.voucher_type, e.voucher_no) for e in self.get_gl_entries()
+			if getdate(e.posting_date) > report_date]))
+			
+	def get_entries_till(self, report_date):
+		# returns a generator
+		return (e for e in self.get_gl_entries() 
+			if getdate(e.posting_date) <= report_date)
+			
+	def is_receivable(self, gle, future_vouchers):
+		return ((not gle.against_voucher) or (gle.against_voucher==gle.voucher_no) or 
+			((gle.against_voucher_type, gle.against_voucher) in future_vouchers))
+			
+	def get_outstanding_amount(self, gle, report_date):
+		payment_received = 0.0
+		for e in self.get_gl_entries_for(gle.account, gle.voucher_type, gle.voucher_no):
+			if getdate(e.posting_date) <= report_date and e.name!=gle.name:
+				payment_received += (flt(e.credit) - flt(e.debit))
+					
+		return flt(gle.debit) - flt(gle.credit) - payment_received
+		
+	def get_age(self, entry_date, oustanding_amount):
+		# [0-30, 30-60, 60-90, 90-above]
+		outstanding_range = [0.0, 0.0, 0.0, 0.0]
+		if not (self.age_as_on and entry_date):
+			return [0] + outstanding_range
+			
+		age = (self.age_as_on - getdate(entry_date)).days or 0
+		index = None
+		for i, days in enumerate([30, 60, 90]):
+			if age <= days:
+				index = i
+				break
+		
+		if index is None: index = 3
+		outstanding_range[index] = oustanding_amount
+		
+		return [age] + outstanding_range
+			
+	def get_customer(self, account):
+		return self.get_account_map().get(account).get("customer_name") or ""
+		
+	def get_territory(self, account):
+		return self.get_account_map().get(account).get("territory") or ""
+		
+	def get_account_map(self):
+		if not hasattr(self, "account_map"):
+			self.account_map = dict(((r.name, r) for r in webnotes.conn.sql("""select 
+				account.name, customer.customer_name, customer.territory
+				from `tabAccount` account, `tabCustomer` customer 
+				where account.master_type="Customer" 
+				and customer.name=account.master_name""", as_dict=True)))
+				
+		return self.account_map
+		
+	def get_due_date(self, gle):
+		if not hasattr(self, "invoice_due_date_map"):
+			# TODO can be restricted to posting date
+			self.invoice_due_date_map = dict(webnotes.conn.sql("""select name, due_date
+				from `tabSales Invoice` where docstatus=1"""))
+				
+		return gle.voucher_type == "Sales Invoice" \
+			and self.invoice_due_date_map.get(gle.voucher_no) or ""
+		
+	def get_gl_entries(self):
+		if not hasattr(self, "gl_entries"):
+			conditions, values = self.prepare_conditions()
+			self.gl_entries = webnotes.conn.sql("""select * from `tabGL Entry`
+				where docstatus < 2 {} order by posting_date, account""".format(conditions),
+				values, as_dict=True)
+				
+		return self.gl_entries
+		
+	def prepare_conditions(self):
+		conditions = [""]
+		values = {}
+		
+		if self.filters.company:
+			conditions.append("company=%(company)s")
+			values["company"] = self.filters.company
+		
+		if self.filters.account:
+			conditions.append("account=%(account)s")
+			values["account"] = self.filters.account
+		else:
+			account_map = self.get_account_map()
+			if not account_map:
+				webnotes.throw(_("No Customer Accounts found."))
+			else:
+				accounts_list = ['"{}"'.format(ac) for ac in account_map]
+				conditions.append("account in ({})".format(", ".join(accounts_list)))
+		
+		return " and ".join(conditions), values
+		
+	def get_gl_entries_for(self, account, against_voucher_type, against_voucher):
+		if not hasattr(self, "gl_entries_map"):
+			self.gl_entries_map = {}
+			for gle in self.get_gl_entries():
+				if gle.against_voucher_type and gle.against_voucher:
+					self.gl_entries_map.setdefault(gle.account, {})\
+						.setdefault(gle.against_voucher_type, {})\
+						.setdefault(gle.against_voucher, [])\
+						.append(gle)
+		
+		return self.gl_entries_map.get(account, {})\
+			.get(against_voucher_type, {})\
+			.get(against_voucher, [])
 
 def execute(filters=None):
-	if not filters: filters = {}
-	columns = get_columns()
-	entries = get_gl_entries(filters)
-	account_customer = dict(webnotes.conn.sql("""select account.name, customer.customer_name
-		from `tabAccount` account, `tabCustomer` customer 
-		where account.master_type="Customer" and customer.name=account.master_name"""))
-	
-	entries_after_report_date = [[gle.voucher_type, gle.voucher_no] 
-		for gle in get_gl_entries(filters, upto_report_date=False)]
-	
-	account_territory_map = get_account_territory_map()
-	si_due_date_map = get_si_due_date_map()
-		
-	# Age of the invoice on this date
-	age_on = getdate(filters.get("report_date")) > getdate(nowdate()) \
-		and nowdate() or filters.get("report_date")
-
-	data = []
-	for gle in entries:
-		if cstr(gle.against_voucher) == gle.voucher_no or not gle.against_voucher \
-				or [gle.against_voucher_type, gle.against_voucher] in entries_after_report_date:
-			
-			due_date = (gle.voucher_type == "Sales Invoice") \
-				and si_due_date_map.get(gle.voucher_no) or ""
-		
-			invoiced_amount = gle.debit > 0 and gle.debit or 0		
-			outstanding_amount = get_outstanding_amount(gle, 
-				filters.get("report_date") or nowdate())
-		
-			if abs(flt(outstanding_amount)) > 0.01:
-				payment_amount = invoiced_amount - outstanding_amount
-				row = [gle.posting_date, gle.account, account_customer.get(gle.account, ""), 
-					gle.voucher_type, gle.voucher_no, 
-					gle.remarks, due_date, account_territory_map.get(gle.account), 
-					invoiced_amount, payment_amount, outstanding_amount]
-				# Ageing
-				if filters.get("ageing_based_on") == "Due Date":
-					ageing_based_on_date = due_date
-				else:
-					ageing_based_on_date = gle.posting_date
-				row += get_ageing_data(ageing_based_on_date, age_on, outstanding_amount)
-								
-				data.append(row)
-								
-	return columns, data
-	
-def get_columns():
-	return [
-		"Posting Date:Date:80", "Account:Link/Account:150", "Customer::150", "Voucher Type::110", 
-		"Voucher No::120", "Remarks::150", "Due Date:Date:80", "Territory:Link/Territory:80", 
-		"Invoiced Amount:Currency:100", "Payment Received:Currency:100", 
-		"Outstanding Amount:Currency:100", "Age:Int:50", "0-30:Currency:100", 
-		"30-60:Currency:100", "60-90:Currency:100", "90-Above:Currency:100"
-	]
-	
-def get_gl_entries(filters, upto_report_date=True):
-	conditions, customer_accounts = get_conditions(filters, upto_report_date)
-	return webnotes.conn.sql("""select * from `tabGL Entry` 
-		where docstatus < 2 %s order by posting_date, account""" % 
-		(conditions), tuple(customer_accounts), as_dict=1)
-	
-def get_conditions(filters, upto_report_date=True):
-	conditions = ""
-	if filters.get("company"):
-		conditions += " and company='%s'" % filters["company"]
-	
-	customer_accounts = []
-	if filters.get("account"):
-		customer_accounts = [filters["account"]]
-	else:
-		customer_accounts = webnotes.conn.sql_list("""select name from `tabAccount` 
-			where ifnull(master_type, '') = 'Customer' and docstatus < 2 %s""" % 
-			conditions, filters)
-	
-	if customer_accounts:
-		conditions += " and account in (%s)" % (", ".join(['%s']*len(customer_accounts)))
-	else:
-		msgprint(_("No Customer Accounts found. Customer Accounts are identified based on \
-			'Master Type' value in account record."), raise_exception=1)
-		
-	if filters.get("report_date"):
-		if upto_report_date:
-			conditions += " and posting_date<='%s'" % filters["report_date"]
-		else:
-			conditions += " and posting_date>'%s'" % filters["report_date"]
-		
-	return conditions, customer_accounts
-	
-def get_account_territory_map():
-	account_territory_map = {}
-	for each in webnotes.conn.sql("""select t2.name, t1.territory from `tabCustomer` t1, 
-			`tabAccount` t2 where t1.name = t2.master_name"""):
-		account_territory_map[each[0]] = each[1]
-		
-	return account_territory_map
-	
-def get_si_due_date_map():
-	""" get due_date from sales invoice """
-	si_due_date_map = {}
-	for t in webnotes.conn.sql("""select name, due_date from `tabSales Invoice`"""):
-		si_due_date_map[t[0]] = t[1]
-		
-	return si_due_date_map
-
-def get_outstanding_amount(gle, report_date):
-	payment_amount = webnotes.conn.sql("""
-		select sum(ifnull(credit, 0)) - sum(ifnull(debit, 0)) 
-		from `tabGL Entry` 
-		where account = %s and posting_date <= %s and against_voucher_type = %s 
-		and against_voucher = %s and name != %s""", 
-		(gle.account, report_date, gle.voucher_type, gle.voucher_no, gle.name))[0][0]
-		
-	return flt(gle.debit) - flt(gle.credit) - flt(payment_amount)
-
-def get_payment_amount(gle, report_date, entries_after_report_date):
-	payment_amount = 0
-	if flt(gle.credit) > 0 and (not gle.against_voucher or 
-		[gle.against_voucher_type, gle.against_voucher] in entries_after_report_date):
-			payment_amount = gle.credit
-	elif flt(gle.debit) > 0:
-		payment_amount = webnotes.conn.sql("""
-			select sum(ifnull(credit, 0)) - sum(ifnull(debit, 0)) from `tabGL Entry` 
-			where account = %s and posting_date <= %s and against_voucher_type = %s 
-			and against_voucher = %s and name != %s""", 
-			(gle.account, report_date, gle.voucher_type, gle.voucher_no, gle.name))[0][0]
-	
-	return flt(payment_amount)
-
-def get_ageing_data(ageing_based_on_date, age_on, outstanding_amount):
-	val1 = val2 = val3 = val4 = diff = 0
-	diff = age_on and ageing_based_on_date \
-		and (getdate(age_on) - getdate(ageing_based_on_date)).days or 0
-
-	if diff <= 30:
-		val1 = outstanding_amount
-	elif 30 < diff <= 60:
-		val2 = outstanding_amount
-	elif 60 < diff <= 90:
-		val3 = outstanding_amount
-	elif diff > 90:
-		val4 = outstanding_amount
-		
-	return [diff, val1, val2, val3, val4]
\ No newline at end of file
+	return AccountsReceivableReport(filters).run()
\ No newline at end of file
