refactor email digest
diff --git a/erpnext/setup/doctype/email_digest/email_digest.js b/erpnext/setup/doctype/email_digest/email_digest.js
index 9d8d5b5..0ff5736 100644
--- a/erpnext/setup/doctype/email_digest/email_digest.js
+++ b/erpnext/setup/doctype/email_digest/email_digest.js
@@ -22,7 +22,7 @@
 	cur_frm.add_custom_button('View Now', function() {
 		doc = locals[dt][dn];
 		if(doc.__unsaved != 1) {
-			$c_obj(make_doclist(dt, dn), 'get', '', function(r, rt) {
+			$c_obj(make_doclist(dt, dn), 'get_digest_msg', '', function(r, rt) {
 				if(r.exc) {
 					msgprint(err_msg);
 					console.log(r.exc);
@@ -33,7 +33,7 @@
 						width: 800
 					});
 
-					$a(d.body, 'div', '', '', r['message'][1]);
+					$a(d.body, 'div', '', '', r['message']);
 
 					d.show();
 				}
diff --git a/erpnext/setup/doctype/email_digest/email_digest.py b/erpnext/setup/doctype/email_digest/email_digest.py
index da18c54..aa3f245 100644
--- a/erpnext/setup/doctype/email_digest/email_digest.py
+++ b/erpnext/setup/doctype/email_digest/email_digest.py
@@ -16,697 +16,330 @@
 
 from __future__ import unicode_literals
 import webnotes
-import webnotes.utils
+from webnotes.utils import fmt_money, formatdate, now_datetime, cstr
+from datetime import timedelta
+from dateutil.relativedelta import relativedelta
+
+content_sequence = ["income_year_to_date", "bank_balance",
+	"income", "expenses_booked", "collections", "payments",
+	"invoiced_amount", "payables",
+	"new_leads", "new_enquiries", "new_quotations", "new_sales_orders",
+	"new_delivery_notes", "new_purchase_requests", "new_supplier_quotations",
+	"new_purchase_orders", "new_purchase_receipts", "new_stock_entries",
+	"new_support_tickets", "new_communications", "new_projects"]
 
 class DocType:
 	def __init__(self, doc, doclist=[]):
 		self.doc, self.doclist = doc, doclist
-		self.sending = False
-
 
 	def get_profiles(self):
-		"""
-			Get a list of profiles
-		"""
+		"""get list of profiles"""
 		import webnotes
 		profile_list = webnotes.conn.sql("""
-			SELECT name, enabled FROM tabProfile
-			WHERE docstatus=0 AND name NOT IN ('Administrator', 'Guest')
-			ORDER BY enabled DESC, name ASC""", as_dict=1)
+			select name, enabled from tabProfile
+			where docstatus=0 and name not in ('Administrator', 'Guest')
+			order by enabled desc, name asc""", as_dict=1)
+
 		if self.doc.recipient_list:
 			recipient_list = self.doc.recipient_list.split("\n")
 		else:
 			recipient_list = []
 		for p in profile_list:
-			if p['name'] in recipient_list: p['checked'] = 1
-			else: p['checked'] = 0
+			p["checked"] = p["name"] in recipient_list and 1 or 0
+
 		webnotes.response['profile_list'] = profile_list
-
-
-	def get_standard_data(self):
-		"""
-			Executes standard queries
-		"""
-		res = {}
-		query_dict = {
-
-			'invoiced_amount': self.generate_gle_query({
-				'type': 'invoiced_amount',
-				'field': 'debit',
-				'master_type': 'Customer',
-			}),
-
-			'payables': self.generate_gle_query({
-				'type': 'payables',
-				'field': 'credit',
-				'master_type': 'Supplier',
-			}),
-
-			'collections': self.generate_gle_query({
-				'type': 'collections',
-				'field': 'credit',
-				'master_type': 'Customer',
-			}),
-
-			'payments': self.generate_gle_query({
-				'type': 'payments',
-				'field': 'debit',
-				'master_type': 'Supplier',
-			}),
-
-			'income': self.generate_gle_query({
-				'type': 'income',
-				'debit_or_credit': 'Credit'
-			}),
-
-			'income_year_to_date': self.generate_gle_query({
-				'type': 'income_year_to_date',
-				'debit_or_credit': 'Credit'
-			}),
-
-			'expenses_booked': self.generate_gle_query({
-				'type': 'expenses_booked',
-				'debit_or_credit': 'Debit'
-			}),
-
-			'bank_balance': self.generate_gle_query({
-				'type': 'bank_balance'
-			}),
-
-			'new_leads': self.generate_new_type_query({
-				'type': 'new_leads',
-				'doctype': 'Lead'
-			}),
-
-			'new_enquiries': self.generate_new_type_query({
-				'type': 'new_enquiries',
-				'doctype': 'Opportunity'
-			}),
-
-			'new_quotations': self.generate_new_type_query({
-				'type': 'new_quotations',
-				'doctype': 'Quotation',
-				'sum_col': 'grand_total'
-			}),
-
-			'new_sales_orders': self.generate_new_type_query({
-				'type': 'new_sales_orders',
-				'doctype': 'Sales Invoice',
-				'sum_col': 'grand_total'
-			}),
-
-			'new_purchase_orders': self.generate_new_type_query({
-				'type': 'new_purchase_orders',
-				'doctype': 'Purchase Order',
-				'sum_col': 'grand_total'
-			}),
-
-			'new_transactions': self.generate_new_type_query({
-				'type': 'new_transactions',
-				'doctype': 'Feed'
-			}),
-
-			'stock_below_rl': ""
-		}
-
-		result = {}
-
-		for query in query_dict.keys():
-			if self.doc.fields[query] and query_dict[query]:
-				#webnotes.msgprint(query)
-				res = webnotes.conn.sql(query_dict[query], as_dict=1)
-				if query in ['income', 'income_year_to_date']:
-					for r in res:
-						r['value'] = float(r['credit'] - r['debit'])
-				elif query in ['expenses_booked', 'bank_balance']:
-					for r in res:
-						r['value'] = float(r['debit'] - r['credit'])
-				#webnotes.msgprint(query)
-				#webnotes.msgprint(res)
-				result[query] = res and (len(res)==1 and res[0]) or (res or None)
-				if result[query] is None:
-					del result[query]
-		
-		return result
-
-
-	def generate_gle_query(self, args):
-		"""
-			Returns generated query string based 'tabGL Entry' and 'tabAccount'
-		"""
-		self.process_args(args)
-
-		query = None
-
-		if args['type'] in ['invoiced_amount', 'payables']:
-			query = """
-				SELECT
-					IFNULL(SUM(IFNULL(gle.%(field)s, 0)), 0) AS '%(field)s',
-					%(common_select)s
-				FROM
-					%(common_from)s
-				WHERE
-					%(common_where)s AND
-					ac.master_type = '%(master_type)s' AND
-					%(start_date_condition)s AND
-					%(end_date_condition)s""" % args
-
-		elif args['type'] in ['collections', 'payments']:
-			args['bc_accounts_regex'] = self.get_bc_accounts_regex()
-			if args['bc_accounts_regex']:
-				query = """
-					SELECT
-						IFNULL(SUM(IFNULL(gle.%(field)s, 0)), 0) AS '%(field)s',
-						%(common_select)s
-					FROM
-						%(common_from)s
-					WHERE
-						%(common_where)s AND
-						ac.master_type = '%(master_type)s' AND
-						gle.against REGEXP '%(bc_accounts_regex)s' AND
-						%(start_date_condition)s AND
-						%(end_date_condition)s""" % args
-
-		elif args['type'] in ['income', 'expenses_booked']:
-			query = """
-				SELECT
-					IFNULL(SUM(IFNULL(gle.debit, 0)), 0) AS 'debit',
-					IFNULL(SUM(IFNULL(gle.credit, 0)), 0) AS 'credit',
-					%(common_select)s
-				FROM
-					%(common_from)s
-				WHERE
-					%(common_where)s AND
-					ac.is_pl_account = 'Yes' AND
-					ac.debit_or_credit = '%(debit_or_credit)s' AND					
-					%(start_date_condition)s AND
-					%(end_date_condition)s""" % args
-
-		elif args['type'] == 'income_year_to_date':
-			query = """
-				SELECT
-					IFNULL(SUM(IFNULL(gle.debit, 0)), 0) AS 'debit',
-					IFNULL(SUM(IFNULL(gle.credit, 0)), 0) AS 'credit',
-					%(common_select)s
-				FROM
-					%(common_from)s
-				WHERE
-					%(common_where)s AND
-					ac.is_pl_account = 'Yes' AND
-					ac.debit_or_credit = '%(debit_or_credit)s' AND					
-					%(fiscal_start_date_condition)s AND
-					%(end_date_condition)s""" % args
-
-		elif args['type'] == 'bank_balance':
-			query = """
-				SELECT
-					ac.account_name AS 'name',
-					IFNULL(SUM(IFNULL(gle.debit, 0)), 0) AS 'debit',
-					IFNULL(SUM(IFNULL(gle.credit, 0)), 0) AS 'credit',
-					%(common_select)s
-				FROM
-					%(common_from)s
-				WHERE
-					%(common_where)s AND
-					ac.account_type = 'Bank or Cash' AND
-					%(end_date_condition)s
-				GROUP BY
-					ac.account_name""" % args
-
-		return query
-
-
-	def process_args(self, args):
-		"""
-			Adds common conditions in dictionary "args"
-		"""
-		start_date, end_date = self.get_start_end_dates()
-		fiscal_year = webnotes.utils.get_defaults()['fiscal_year']
-		fiscal_start_date = webnotes.conn.get_value('Fiscal Year', fiscal_year,
-				'year_start_date')
-
-		if 'new' in args['type']:
-			args.update({
-				'company': self.doc.company,
-				'start_date': start_date,
-				'end_date': end_date,
-				'sum_if_reqd': ''
-			})
-			if args['type'] in ['new_quotations', 'new_sales_orders', 'new_purchase_orders']:
-				args['sum_if_reqd'] = "IFNULL(SUM(IFNULL(%(sum_col)s, 0)), 0) AS '%(sum_col)s'," % args
-			
-			if args['type'] == 'new_transactions':
-				# tabFeed doesn't have company column
-				# using this arg to set condition of feed_type as null
-				# so that comments, logins and assignments are not counted
-				args['company_condition'] = "feed_type IS NULL AND"
-			else:
-				args['company_condition'] = "company = '%(company)s' AND" % args
-				
-		else:
-			args.update({
-				'common_select': "COUNT(*) AS 'count'",
-
-				'common_from': "`tabGL Entry` gle, `tabAccount` ac",
-
-				'common_where': """
-					gle.company = '%s' AND
-					gle.account = ac.name AND
-					ac.docstatus < 2 AND
-					IFNULL(gle.is_cancelled, 'No') = 'No'""" % self.doc.company,
-
-				'start_date_condition': "gle.posting_date >= '%s'" % start_date,
-
-				'end_date_condition': "gle.posting_date <= '%s'" % end_date,
-
-				'fiscal_start_date_condition': "gle.posting_date >= '%s'" % fiscal_start_date
-			})
-
-
-	def get_start_end_dates(self):
-		"""
-			Returns start and end date depending on the frequency of email digest
-		"""
-		from datetime import datetime, date, timedelta
-		from webnotes.utils import now_datetime
-		today = now_datetime().date()
-		year, month, day = today.year, today.month, today.day
-		
-		if self.doc.frequency == 'Daily':
-			if self.sending:
-				start_date = end_date = today - timedelta(days=1)
-			else:
-				start_date = end_date = today
-		
-		elif self.doc.frequency == 'Weekly':
-			if self.sending:
-				start_date = today - timedelta(days=today.weekday(), weeks=1)
-				end_date = start_date + timedelta(days=6)
-			else:
-				start_date = today - timedelta(days=today.weekday())
-				end_date = start_date + timedelta(days=6)
-
-		else:
-			import calendar
-			
-			if self.sending:
-				if month == 1:
-					year = year - 1
-					prev_month = 12
-				else:
-					prev_month = month - 1
-				start_date = date(year, prev_month, 1)
-				last_day = calendar.monthrange(year, prev_month)[1]
-				end_date = date(year, prev_month, last_day)
-			else:
-				start_date = date(year, month, 1)
-				last_day = calendar.monthrange(year, month)[1]
-				end_date = date(year, month, last_day)
-
-		return start_date, end_date
-
-
-	def generate_new_type_query(self, args):
-		"""
-			Returns generated query string for calculating new transactions created
-		"""
-		self.process_args(args)
-
-		query = """
-			SELECT
-				%(sum_if_reqd)s
-				COUNT(*) AS 'count'
-			FROM
-				`tab%(doctype)s`
-			WHERE
-				docstatus < 2 AND
-				%(company_condition)s
-				DATE(creation) >= '%(start_date)s' AND
-				DATE(creation) <= '%(end_date)s'""" % args
-
-		return query
 	
-	
-	def get_bc_accounts_regex(self):
-		"""
-			Returns a regular expression of 'Bank or Cash' type account list
-		"""
-		bc_account_list = webnotes.conn.sql("""
-			SELECT name
-			FROM `tabAccount`
-			WHERE account_type = 'Bank or Cash'""", as_list=1)
-		
-		if bc_account_list:		
-			return '(' + '|'.join([ac[0] for ac in bc_account_list]) + ')'
-	
-
-	def get(self):
-		"""
-			* Execute Query
-			* Prepare Email Body from Print Format
-		"""
-		result, email_body = self.execute_queries()
-		#webnotes.msgprint(result)
-		#webnotes.msgprint(email_body)
-		return result, email_body
-
-
-	def execute_queries(self):
-		"""
-			* If standard==1, execute get_standard_data
-			* If standard==0, execute python code in custom_code field
-		"""
-		result = {}
-		if int(self.doc.use_standard)==1:
-			result = self.get_standard_data()
-			email_body = self.get_standard_body(result)
-		else:
-			result, email_body = self.execute_custom_code(self.doc)
-
-		#webnotes.msgprint(result)
-
-		return result, email_body
-
-
-	def execute_custom_code(self, doc):
-		"""
-			Execute custom python code
-		"""
-		pass
-
-
 	def send(self):
-		"""
-			* Execute get method
-			* Send email to recipients
-		"""
-		if not self.doc.recipient_list: return
-
-		self.sending = True
-		result, email_body = self.get()
+		# send email only to enabled users
+		valid_users = [p[0] for p in webnotes.conn.sql("""select name from `tabProfile`
+			where enabled=1""")]
+		recipients = filter(lambda r: r in valid_users,
+			self.doc.recipient_list.split("\n"))
 		
-		recipient_list = self.doc.recipient_list.split("\n")
-
-		# before sending, check if user is disabled or not
-		# do not send if disabled
-		profile_list = webnotes.conn.sql("SELECT name, enabled FROM tabProfile", as_dict=1)
-		for profile in profile_list:
-			if profile['name'] in recipient_list and profile['enabled'] == 0:
-				del recipient_list[recipient_list.index(profile['name'])]
-
 		from webnotes.utils.email_lib import sendmail
-		try:
-			sendmail(
-				recipients=recipient_list,
-				sender='notifications+email_digest@erpnext.com',
-				subject=self.doc.frequency + ' Digest',
-				msg=email_body
-			)
-		except Exception, e:
-			webnotes.msgprint('There was a problem in sending your email. Please contact support@erpnext.com')
-			webnotes.errprint(webnotes.getTraceback())
+		sendmail(recipients=recipients, subject=(self.doc.frequency + " Digest"),
+			sender="ERPNext Notifications <notifications+email_digest@erpnext.com>",
+			msg=self.get_digest_msg())
+				
+	def get_digest_msg(self):
+		""""""
+		self.from_date, self.to_date = self.get_from_to_date()
+		self.currency = webnotes.conn.get_value("Company", self.doc.company,
+			"default_currency")
+		
+		out = []
+		for ctype in content_sequence:
+			if self.doc.fields.get(ctype) and hasattr(self, "get_"+ctype):
+				# appends [value, html]
+				out.append(getattr(self, "get_"+ctype)())
+		
+		return self.get_msg_html(out)
+		
+	def get_msg_html(self, out):
+		with_value = "\n".join([o[1] for o in out if o[0]])
+		
+		# seperate out no value items
+		no_value = [o[1] for o in out if not o[0]]
+		if no_value:
+			no_value = """<hr><h4>No Updates For:</h4><br>""" + "\n".join(no_value)
+		
+		date = self.doc.frequency == "Daily" and formatdate(self.from_date) or \
+			"%s to %s" % (formatdate(self.from_date), formatdate(self.to_date))
+		
+		msg = """<h2>%(digest)s</h2>
+			<p style='color: grey'>%(date)s</p>
+			<h4>%(company)s</h4>
+			<hr>
+			%(with_value)s
+			%(no_value)s""" % {
+				"digest": self.doc.frequency + " Digest",
+				"date": date,
+				"company": self.doc.company,
+				"with_value": with_value,
+				"no_value": no_value or ""
+			}
+		
+		return msg
+	
+	def get_income_year_to_date(self):
+		return self.get_income(webnotes.conn.get_defaults("year_start_date"), 
+			"Income Year To Date")
+			
+	def get_bank_balance(self):
+		# account is of type "Bank or Cash"
+		accounts = dict([[a["name"], [a["account_name"], 0]] for a in self.get_accounts()
+			if a["account_type"]=="Bank or Cash"])
+		ackeys = accounts.keys()
+		
+		for gle in self.get_gl_entries(None, self.to_date):
+			if gle["account"] in ackeys:
+				accounts[gle["account"]][1] += gle["debit"] - gle["credit"]
+		
+		# build html
+		out = self.get_html("Bank/Cash Balance", "", "")
+		for ac in ackeys:
+			out += "\n" + self.get_html(accounts[ac][0], self.currency,
+				fmt_money(accounts[ac][1]), style="margin-left: 17px")
+		return sum((accounts[ac][1] for ac in ackeys)), out
+		
+	def get_income(self, from_date=None, label=None):
+		# account is PL Account and Credit type account
+		accounts = [a["name"] for a in self.get_accounts()
+			if a["is_pl_account"]=="Yes" and a["debit_or_credit"]=="Credit"]
+			
+		income = 0
+		for gle in self.get_gl_entries(from_date or self.from_date, self.to_date):
+			if gle["account"] in accounts:
+				income += gle["credit"] - gle["debit"]
+		
+		return income, self.get_html(label or "Income", self.currency, fmt_money(income))
+		
+	def get_expenses_booked(self):
+		# account is PL Account and Debit type account
+		accounts = [a["name"] for a in self.get_accounts()
+			if a["is_pl_account"]=="Yes" and a["debit_or_credit"]=="Debit"]
+			
+		expense = 0
+		for gle in self.get_gl_entries(self.from_date, self.to_date):
+			if gle["account"] in accounts:
+				expense += gle["debit"] - gle["credit"]
+		
+		return expense, self.get_html("Expenses", self.currency, fmt_money(expense))
+	
+	def get_collections(self):
+		return self.get_party_total("Customer", "credit", "Collections")
+	
+	def get_payments(self):
+		return self.get_party_total("Supplier", "debit", "Payments")
+		
+	def get_party_total(self, party_type, gle_field, label):
+		import re
+		# account is of master_type Customer or Supplier
+		accounts = [a["name"] for a in self.get_accounts()
+			if a["master_type"]==party_type]
 
+		# account is "Bank or Cash"
+		bc_accounts = [a["name"] for a in self.get_accounts() 
+			if a["account_type"]=="Bank or Cash"]
+		bc_regex = re.compile("(%s)" % "|".join(bc_accounts))
+		
+		total = 0
+		for gle in self.get_gl_entries(self.from_date, self.to_date):
+			# check that its made against a bank or cash account
+			if gle["account"] in accounts and gle["against"] and \
+					bc_regex.findall(gle["against"]):
+				total += gle[gle_field]
+
+		return total, self.get_html(label, self.currency, fmt_money(total))
+		
+	def get_invoiced_amount(self):
+		# aka receivables
+		return self.get_booked_total("Customer", "debit", "Receivables")
+
+	def get_payables(self):
+		return self.get_booked_total("Supplier", "credit", "Payables")
+		
+	def get_booked_total(self, party_type, gle_field, label):
+		# account is of master_type Customer or Supplier
+		accounts = [a["name"] for a in self.get_accounts()
+			if a["master_type"]==party_type]
+	
+		total = 0
+		for gle in self.get_gl_entries(self.from_date, self.to_date):
+			if gle["account"] in accounts:
+				total += gle[gle_field]
+
+		return total, self.get_html(label, self.currency, fmt_money(total))
+		
+	def get_new_leads(self):
+		return self.get_new_count("Lead", "New Leads")
+		
+	def get_new_enquiries(self):
+		return self.get_new_count("Opportunity", "New Opportunities")
+	
+	def get_new_quotations(self):
+		return self.get_new_sum("Quotation", "New Quotations", "grand_total")
+		
+	def get_new_sales_orders(self):
+		return self.get_new_sum("Sales Order", "New Sales Orders", "grand_total")
+		
+	def get_new_delivery_notes(self):
+		return self.get_new_sum("Delivery Note", "New Delivery Notes", "grand_total")
+		
+	def get_new_purchase_requests(self):
+		return self.get_new_count("Purchase Request", "New Purchase Requests")
+		
+	def get_new_supplier_quotations(self):
+		return self.get_new_sum("Supplier Quotation", "New Supplier Quotations",
+			"grand_total")
+	
+	def get_new_purchase_orders(self):
+		return self.get_new_sum("Purchase Order", "New Purchase Orders", "grand_total")
+	
+	def get_new_purchase_receipts(self):
+		return self.get_new_sum("Purchase Receipt", "New Purchase Receipts",
+			"grand_total")
+	
+	def get_new_stock_entries(self):
+		return self.get_new_sum("Stock Entry", "New Stock Entries", "total_amount")
+		
+	def get_new_support_tickets(self):
+		return self.get_new_count("Support Ticket", "New Support Tickets", False)
+		
+	def get_new_communications(self):
+		return self.get_new_count("Communication", "New Communications", False)
+		
+	def get_new_projects(self):
+		return self.get_new_count("Project", "New Projects", False)
+	
+	def get_new_count(self, doctype, label, filter_by_company=True):
+		if filter_by_company:
+			company = """and company="%s" """ % self.doc.company
+		else:
+			company = ""
+		count = webnotes.conn.sql("""select count(*) from `tab%s`
+			where docstatus < 2 %s and
+			date(creation)>=%s and date(creation)<=%s""" % (doctype, company, "%s", "%s"),
+			(self.from_date, self.to_date))
+		count = count and count[0][0] or 0
+		
+		return count, self.get_html(label, None, count)
+		
+	def get_new_sum(self, doctype, label, sum_field):
+		count_sum = webnotes.conn.sql("""select count(*), sum(ifnull(`%s`, 0))
+			from `tab%s` where docstatus < 2 and company = %s and
+			date(creation)>=%s and date(creation)<=%s""" % (sum_field, doctype, "%s",
+			"%s", "%s"), (self.doc.company, self.from_date, self.to_date))
+		count, total = count_sum and count_sum[0] or (0, 0)
+		
+		return count, self.get_html(label, self.currency, 
+			"%s - (%s)" % (fmt_money(total), cstr(count)))
+		
+	def get_html(self, label, currency, value, style=None):
+		"""get html output"""
+		return """<p style="padding: 5px; %(style)s">
+			<span>%(label)s</span>: 
+			<span style="font-weight: bold; font-size: 110%%">
+				<span style="color: grey">%(currency)s</span>%(value)s
+			</span></p>""" % {
+				"style": style or "",
+				"label": label,
+				"currency": currency and (currency+" ") or "",
+				"value": value
+			}
+		
+	def get_gl_entries(self, from_date=None, to_date=None):
+		"""get valid GL Entries filtered by company and posting date"""
+		if from_date==self.from_date and to_date==self.to_date and \
+				hasattr(self, "gl_entries"):
+			return self.gl_entries
+		
+		gl_entries = webnotes.conn.sql("""select `account`, 
+			ifnull(credit, 0) as credit, ifnull(debit, 0) as debit, `against`
+			from `tabGL Entry`
+			where company=%s and ifnull(is_cancelled, "No")="No" and
+			posting_date <= %s %s""" % ("%s", "%s", 
+			from_date and "and posting_date>='%s'" % from_date or ""),
+			(self.doc.company, to_date or self.to_date), as_dict=1)
+		
+		# cache if it is the normal cases
+		if from_date==self.from_date and to_date==self.to_date:
+			self.gl_entries = gl_entries
+		
+		return gl_entries
+		
+	def get_accounts(self):
+		if not hasattr(self, "accounts"):
+			self.accounts = webnotes.conn.sql("""select name, is_pl_account,
+				debit_or_credit, account_type, account_name, master_type
+				from `tabAccount` where company=%s and docstatus < 2""",
+				(self.doc.company,), as_dict=1)
+		return self.accounts
+		
+	def get_from_to_date(self):
+		today = now_datetime().date()
+		
+		# decide from date based on email digest frequency
+		if self.doc.frequency == "Daily":
+			# from date, to_date is yesterday
+			from_date = to_date = today - timedelta(days=1)
+		elif self.doc.frequency == "Weekly":
+			# from date is the previous week's monday
+			from_date = today - timedelta(days=today.weekday(), weeks=1)
+			# to date is sunday i.e. the previous day
+			to_date = from_date + timedelta(days=6)
+		else:
+			# from date is the 1st day of the previous month
+			from_date = today - relativedelta(days=today.day-1, months=1)
+			# to date is the last day of the previous month
+			to_date = today - relativedelta(days=today.day)
+
+		return from_date, to_date
 
 	def get_next_sending(self):
-		import datetime
-		
-		start_date, end_date = self.get_start_end_dates()
-		
-		send_date = end_date + datetime.timedelta(days=1)
-		
-		from webnotes.utils import formatdate
-		str_date = formatdate(str(send_date))
+		from_date, to_date = self.get_from_to_date()
 
-		self.doc.next_send = str_date + " at midnight"
-
+		send_date = to_date + timedelta(days=1)
+		
+		if self.doc.frequency == "Daily":
+			next_send_date = send_date + timedelta(days=1)
+		elif self.doc.frequency == "Weekly":
+			next_send_date = send_date + timedelta(weeks=1)
+		else:
+			next_send_date = send_date + relativedelta(months=1)
+		self.doc.next_send = formatdate(next_send_date) + " at midnight"
+		
 		return send_date
-
-
+		
 	def onload(self):
-		"""
-
-		"""
 		self.get_next_sending()
 
-
-	def get_standard_body(self, result):
-		"""
-			Generate email body depending on the result
-		"""
-		from webnotes.utils import fmt_money
-		from webnotes.model.doc import Document
-		company = Document('Company', self.doc.company)
-		currency = company.default_currency
-
-		def table(args):
-			table_body = ""
-			
-			if isinstance(args['body'], basestring):
-				return """<p>%(head)s: <span style='font-size: 110%%; font-weight: bold;'>%(body)s</span></p>""" % args
-			else:
-				return ("""<p>%(head)s:</p> """ % args) +\
-				 	"".join(map(lambda b: "<p style='margin-left: 17px;'>%s</p>" % b, args['body']))
-
-
-		currency_amount_str = "<span style='color: grey;'>%s</span> %s"
-
-		body_dict = {
-
-			'invoiced_amount': {
-				'table': result.get('invoiced_amount') and \
-					table({
-						'head': 'Invoiced Amount',
-						'body': currency_amount_str \
-							% (currency, fmt_money(result['invoiced_amount'].get('debit')))
-					}),
-				'idx': 300,
-				'value': result.get('invoiced_amount') and result['invoiced_amount'].get('debit')
-			},
-
-			'payables': {
-				'table': result.get('payables') and \
-					table({
-						'head': 'Payables',
-						'body': currency_amount_str \
-							% (currency, fmt_money(result['payables'].get('credit')))
-					}),
-				'idx': 200,
-				'value': result.get('payables') and result['payables'].get('credit')
-			},
-
-			'collections': {
-				'table': result.get('collections') and \
-					table({
-						'head': 'Collections',
-						'body': currency_amount_str \
-							% (currency, fmt_money(result['collections'].get('credit')))
-					}),
-				'idx': 301,
-				'value': result.get('collections') and result['collections'].get('credit')
-			},
-
-			'payments': {
-				'table': result.get('payments') and \
-					table({
-						'head': 'Payments',
-						'body': currency_amount_str \
-							% (currency, fmt_money(result['payments'].get('debit')))
-					}),
-				'idx': 201,
-				'value': result.get('payments') and result['payments'].get('debit')
-			},
-
-			'income': {
-				'table': result.get('income') and \
-					table({
-						'head': 'Income',
-						'body': currency_amount_str \
-							% (currency, fmt_money(result['income'].get('value')))
-					}),
-				'idx': 302,
-				'value': result.get('income') and result['income'].get('value')
-			},
-
-			'income_year_to_date': {
-				'table': result.get('income_year_to_date') and \
-					table({
-						'head': 'Income Year To Date',
-						'body': currency_amount_str \
-							% (currency, fmt_money(result['income_year_to_date'].get('value')))
-					}),
-				'idx': 303,
-				'value': result.get('income_year_to_date') and \
-				 	result['income_year_to_date'].get('value')
-			},
-
-			'expenses_booked': {
-				'table': result.get('expenses_booked') and \
-					table({
-						'head': 'Expenses Booked',
-						'body': currency_amount_str \
-							% (currency, fmt_money(result['expenses_booked'].get('value')))
-					}),
-				'idx': 202,
-				'value': result.get('expenses_booked') and result['expenses_booked'].get('value')
-			},
-
-			'bank_balance': {
-				'table': result.get('bank_balance') and \
-					table({
-						'head': 'Bank / Cash Balance',
-						'body': [(bank['name'] + ": <span style='font-size: 110%%; font-weight: bold;'>" \
-									+ currency_amount_str % \
-									(currency, fmt_money(bank.get('value'))) + '</span>')
-							for bank in (isinstance(result['bank_balance'], list) and \
-								result['bank_balance'] or \
-								[result['bank_balance']])
-						]
-					}),
-				'idx': 0,
-				'value': 0.1
-			},
-
-			'new_leads': {
-				'table': result.get('new_leads') and \
-					table({
-						'head': 'New Leads',
-						'body': '%s' % result['new_leads'].get('count')
-					}),
-				'idx': 100,
-				'value': result.get('new_leads') and result['new_leads'].get('count')
-			},
-
-			'new_enquiries': {
-				'table': result.get('new_enquiries') and \
-					table({
-						'head': 'New Enquiries',
-						'body': '%s' % result['new_enquiries'].get('count')
-					}),
-				'idx': 101,
-				'value': result.get('new_enquiries') and result['new_enquiries'].get('count')
-			},
-
-			'new_quotations': {
-				'table': result.get('new_quotations') and \
-					table({
-						'head': 'New Quotations',
-						'body': '%s' % result['new_quotations'].get('count')
-					}),
-				'idx': 102,
-				'value': result.get('new_quotations') and result['new_quotations'].get('count')
-			},
-
-			'new_sales_orders': {
-				'table': result.get('new_sales_orders') and \
-					table({
-						'head': 'New Sales Orders',
-						'body': '%s' % result['new_sales_orders'].get('count')
-					}),
-				'idx': 103,
-				'value': result.get('new_sales_orders') and result['new_sales_orders'].get('count')
-			},
-
-			'new_purchase_orders': {
-				'table': result.get('new_purchase_orders') and \
-					table({
-						'head': 'New Purchase Orders',
-						'body': '%s' % result['new_purchase_orders'].get('count')
-					}),
-				'idx': 104,
-				'value': result.get('new_purchase_orders') and \
-				 	result['new_purchase_orders'].get('count')
-			},
-
-			'new_transactions': {
-				'table': result.get('new_transactions') and \
-					table({
-						'head': 'New Transactions',
-						'body': '%s' % result['new_transactions'].get('count')
-					}),
-				'idx': 105,
-				'value': result.get('new_transactions') and result['new_transactions'].get('count')
-			}
-
-			#'stock_below_rl': 
-		}
-
-		table_list = []
-
-		# Sort these keys depending on idx value
-		bd_keys = sorted(body_dict, key=lambda x: \
-			(-webnotes.utils.flt(body_dict[x]['value']), body_dict[x]['idx']))
-
-		new_section = False
-
-		def set_new_section(new_section):
-			if not new_section:
-				table_list.append("<hr /><h4>No Updates For:</h4><br>")
-				new_section = True
-			return new_section			
-
-		for k in bd_keys:
-			if self.doc.fields[k]:
-				if k in result:
-					if not body_dict[k].get('value') and not new_section:
-						new_section = set_new_section(new_section)
-					table_list.append(body_dict[k]['table'])
-				elif k in ['collections', 'payments']:
-					new_section = set_new_section(new_section)
-					table_list.append(\
-						"<p>[" + \
-							k.capitalize() + \
-							"]<br />Missing: Account of type 'Bank or Cash'\
-						</p>")
-				elif k=='bank_balance':
-					new_section = set_new_section(new_section)
-					table_list.append(\
-						"<p>[" + \
-							"Bank Balance" + \
-							"]<br />Alert: GL Entry not found for Account of type 'Bank or Cash'\
-						</p>")
-					
-
-		from webnotes.utils import formatdate
-		start_date, end_date = self.get_start_end_dates()
-		digest_daterange = self.doc.frequency=='Daily' \
-			and formatdate(str(start_date)) \
-			or (formatdate(str(start_date)) + " to " + (formatdate(str(end_date))))
-
-		email_body = """
-					<h2>%s</h2>
-					<p style='color: grey'>%s</p>
-					<h4>%s</h4>
-					<hr>
-				""" \
-					% ((self.doc.frequency + " Digest"), \
-						digest_daterange, self.doc.company) \
-				+ "".join(table_list) + """\
-				<br><p></p>
-			"""
-
-		return email_body
-
-
 def send():
-	"""
-
-	"""
-	edigest_list = webnotes.conn.sql("""
-		SELECT name FROM `tabEmail Digest`
-		WHERE enabled=1 and docstatus<2
-	""", as_list=1)
-
 	from webnotes.model.code import get_obj
-	from webnotes.utils import now_datetime
-
 	now_date = now_datetime().date()
 	
-	for ed in edigest_list:
-		if ed[0]:
-			ed_obj = get_obj('Email Digest', ed[0])
-			ed_obj.sending = True
-			send_date = ed_obj.get_next_sending()
-			#webnotes.msgprint([ed[0], now_date, send_date])
-
-			if (now_date == send_date):
-				ed_obj.send()
+	for ed in webnotes.conn.sql("""select name from `tabEmail Digest`
+			where enabled=1 and docstatus<2""", as_list=1):
+		ed_obj = get_obj('Email Digest', ed[0])
+		if (now_date == ed_obj.get_next_sending()):
+			ed_obj.send()
diff --git a/erpnext/setup/doctype/email_digest/email_digest.txt b/erpnext/setup/doctype/email_digest/email_digest.txt
index 7aa39ca..9de8c28 100644
--- a/erpnext/setup/doctype/email_digest/email_digest.txt
+++ b/erpnext/setup/doctype/email_digest/email_digest.txt
@@ -3,11 +3,11 @@
 
 	# These values are common in all dictionaries
 	{
-		'creation': '2012-07-03 13:30:54',
-		'docstatus': 0,
-		'modified': '2012-07-12 16:29:08',
-		'modified_by': u'Administrator',
-		'owner': u'Administrator'
+		u'creation': '2012-07-12 23:29:44',
+		u'docstatus': 0,
+		u'modified': '2012-09-15 19:34:37',
+		u'modified_by': u'Administrator',
+		u'owner': u'Administrator'
 	},
 
 	# These values are common for all DocType
@@ -16,10 +16,10 @@
 		'autoname': u'Prompt',
 		'colour': u'White:FFF',
 		'description': u'Send regular summary reports via Email.',
-		'doctype': 'DocType',
+		u'doctype': u'DocType',
 		'document_type': u'System',
 		'module': u'Setup',
-		'name': '__common__',
+		u'name': u'__common__',
 		'section_style': u'Simple',
 		'show_in_menu': 0,
 		'version': 1
@@ -27,8 +27,8 @@
 
 	# These values are common for all DocField
 	{
-		'doctype': u'DocField',
-		'name': '__common__',
+		u'doctype': u'DocField',
+		u'name': u'__common__',
 		'parent': u'Email Digest',
 		'parentfield': u'fields',
 		'parenttype': u'DocType'
@@ -36,8 +36,8 @@
 
 	# These values are common for all DocPerm
 	{
-		'doctype': u'DocPerm',
-		'name': '__common__',
+		u'doctype': u'DocPerm',
+		u'name': u'__common__',
 		'parent': u'Email Digest',
 		'parentfield': u'permissions',
 		'parenttype': u'DocType',
@@ -47,28 +47,13 @@
 
 	# DocType, Email Digest
 	{
-		'doctype': 'DocType',
-		'name': u'Email Digest'
-	},
-
-	# DocPerm
-	{
-		'cancel': 1,
-		'create': 1,
-		'doctype': u'DocPerm',
-		'permlevel': 0,
-		'write': 1
-	},
-
-	# DocPerm
-	{
-		'doctype': u'DocPerm',
-		'permlevel': 1
+		u'doctype': u'DocType',
+		u'name': u'Email Digest'
 	},
 
 	# DocField
 	{
-		'doctype': u'DocField',
+		u'doctype': u'DocField',
 		'fieldname': u'settings',
 		'fieldtype': u'Section Break',
 		'label': u'Email Digest Settings',
@@ -77,7 +62,7 @@
 
 	# DocField
 	{
-		'doctype': u'DocField',
+		u'doctype': u'DocField',
 		'fieldname': u'column_break0',
 		'fieldtype': u'Column Break',
 		'permlevel': 0
@@ -85,7 +70,7 @@
 
 	# DocField
 	{
-		'doctype': u'DocField',
+		u'doctype': u'DocField',
 		'fieldname': u'enabled',
 		'fieldtype': u'Check',
 		'label': u'Enabled',
@@ -94,7 +79,7 @@
 
 	# DocField
 	{
-		'doctype': u'DocField',
+		u'doctype': u'DocField',
 		'fieldname': u'company',
 		'fieldtype': u'Select',
 		'label': u'For Company',
@@ -106,11 +91,11 @@
 	# DocField
 	{
 		'allow_on_submit': 0,
-		'doctype': u'DocField',
+		u'doctype': u'DocField',
 		'fieldname': u'frequency',
 		'fieldtype': u'Select',
 		'label': u'How frequently?',
-		'options': u'\nDaily\nWeekly\nMonthly',
+		'options': u'Daily\nWeekly\nMonthly',
 		'permlevel': 0,
 		'reqd': 1
 	},
@@ -118,7 +103,7 @@
 	# DocField
 	{
 		'depends_on': u'eval:doc.enabled',
-		'doctype': u'DocField',
+		u'doctype': u'DocField',
 		'fieldname': u'next_send',
 		'fieldtype': u'Data',
 		'label': u'Next email will be sent on:',
@@ -127,19 +112,7 @@
 
 	# DocField
 	{
-		'default': u'1',
-		'doctype': u'DocField',
-		'fieldname': u'use_standard',
-		'fieldtype': u'Check',
-		'hidden': 1,
-		'label': u'Use standard?',
-		'permlevel': 0,
-		'search_index': 0
-	},
-
-	# DocField
-	{
-		'doctype': u'DocField',
+		u'doctype': u'DocField',
 		'fieldname': u'column_break1',
 		'fieldtype': u'Column Break',
 		'permlevel': 0
@@ -148,7 +121,7 @@
 	# DocField
 	{
 		'description': u'Note: Email will not be sent to disabled users',
-		'doctype': u'DocField',
+		u'doctype': u'DocField',
 		'fieldname': u'recipient_list',
 		'fieldtype': u'Text',
 		'label': u'Recipients',
@@ -158,7 +131,7 @@
 
 	# DocField
 	{
-		'doctype': u'DocField',
+		u'doctype': u'DocField',
 		'fieldname': u'addremove_recipients',
 		'fieldtype': u'Button',
 		'label': u'Add/Remove Recipients',
@@ -169,9 +142,8 @@
 	# DocField
 	{
 		'colour': u'White:FFF',
-		'depends_on': u'eval:doc.use_standard',
 		'description': u'Check all the items below that you want to send in this digest.',
-		'doctype': u'DocField',
+		u'doctype': u'DocField',
 		'fieldname': u'select_digest_content',
 		'fieldtype': u'Section Break',
 		'label': u'Select Digest Content',
@@ -180,8 +152,8 @@
 
 	# DocField
 	{
-		'depends_on': u'eval:doc.use_standard',
-		'doctype': u'DocField',
+		'colour': u'White:FFF',
+		u'doctype': u'DocField',
 		'fieldname': u'new_leads',
 		'fieldtype': u'Check',
 		'label': u'New Leads',
@@ -190,8 +162,7 @@
 
 	# DocField
 	{
-		'depends_on': u'eval:doc.use_standard',
-		'doctype': u'DocField',
+		u'doctype': u'DocField',
 		'fieldname': u'new_enquiries',
 		'fieldtype': u'Check',
 		'label': u'New Enquiries',
@@ -200,8 +171,7 @@
 
 	# DocField
 	{
-		'depends_on': u'eval:doc.use_standard',
-		'doctype': u'DocField',
+		u'doctype': u'DocField',
 		'fieldname': u'new_quotations',
 		'fieldtype': u'Check',
 		'label': u'New Quotations',
@@ -210,8 +180,7 @@
 
 	# DocField
 	{
-		'depends_on': u'eval:doc.use_standard',
-		'doctype': u'DocField',
+		u'doctype': u'DocField',
 		'fieldname': u'new_sales_orders',
 		'fieldtype': u'Check',
 		'label': u'New Sales Orders',
@@ -220,8 +189,34 @@
 
 	# DocField
 	{
-		'depends_on': u'eval:doc.use_standard',
-		'doctype': u'DocField',
+		u'doctype': u'DocField',
+		'fieldname': u'new_delivery_notes',
+		'fieldtype': u'Check',
+		'label': u'New Delivery Notes',
+		'permlevel': 0
+	},
+
+	# DocField
+	{
+		u'doctype': u'DocField',
+		'fieldname': u'new_purchase_requests',
+		'fieldtype': u'Check',
+		'label': u'New Purchase Requests',
+		'permlevel': 0
+	},
+
+	# DocField
+	{
+		u'doctype': u'DocField',
+		'fieldname': u'new_supplier_quotations',
+		'fieldtype': u'Check',
+		'label': u'New Supplier Quotations',
+		'permlevel': 0
+	},
+
+	# DocField
+	{
+		u'doctype': u'DocField',
 		'fieldname': u'new_purchase_orders',
 		'fieldtype': u'Check',
 		'label': u'New Purchase Orders',
@@ -230,27 +225,52 @@
 
 	# DocField
 	{
-		'depends_on': u'eval:doc.use_standard',
-		'doctype': u'DocField',
-		'fieldname': u'new_transactions',
+		u'doctype': u'DocField',
+		'fieldname': u'new_purchase_receipts',
 		'fieldtype': u'Check',
-		'label': u'New Transactions',
+		'label': u'New Purchase Receipts',
 		'permlevel': 0
 	},
 
 	# DocField
 	{
-		'depends_on': u'eval:doc.use_standard',
-		'doctype': u'DocField',
-		'fieldname': u'payables',
+		u'doctype': u'DocField',
+		'fieldname': u'new_stock_entries',
 		'fieldtype': u'Check',
-		'label': u'Payables',
+		'label': u'New Stock Entries',
 		'permlevel': 0
 	},
 
 	# DocField
 	{
-		'doctype': u'DocField',
+		u'doctype': u'DocField',
+		'fieldname': u'new_support_tickets',
+		'fieldtype': u'Check',
+		'label': u'New Support Tickets',
+		'permlevel': 0
+	},
+
+	# DocField
+	{
+		u'doctype': u'DocField',
+		'fieldname': u'new_communications',
+		'fieldtype': u'Check',
+		'label': u'New Communications',
+		'permlevel': 0
+	},
+
+	# DocField
+	{
+		u'doctype': u'DocField',
+		'fieldname': u'new_projects',
+		'fieldtype': u'Check',
+		'label': u'New Projects',
+		'permlevel': 0
+	},
+
+	# DocField
+	{
+		u'doctype': u'DocField',
 		'fieldname': u'cb1',
 		'fieldtype': u'Column Break',
 		'permlevel': 0
@@ -258,58 +278,7 @@
 
 	# DocField
 	{
-		'depends_on': u'eval:doc.use_standard',
-		'doctype': u'DocField',
-		'fieldname': u'payments',
-		'fieldtype': u'Check',
-		'label': u'Payments',
-		'permlevel': 0
-	},
-
-	# DocField
-	{
-		'depends_on': u'eval:doc.use_standard',
-		'doctype': u'DocField',
-		'fieldname': u'expenses_booked',
-		'fieldtype': u'Check',
-		'label': u'Expenses Booked',
-		'permlevel': 0
-	},
-
-	# DocField
-	{
-		'depends_on': u'eval:doc.use_standard',
-		'doctype': u'DocField',
-		'fieldname': u'invoiced_amount',
-		'fieldtype': u'Check',
-		'label': u'Invoiced Amount (Receivables)',
-		'permlevel': 0
-	},
-
-	# DocField
-	{
-		'depends_on': u'eval:doc.use_standard',
-		'doctype': u'DocField',
-		'fieldname': u'collections',
-		'fieldtype': u'Check',
-		'label': u'Collections',
-		'permlevel': 0
-	},
-
-	# DocField
-	{
-		'depends_on': u'eval:doc.use_standard',
-		'doctype': u'DocField',
-		'fieldname': u'income',
-		'fieldtype': u'Check',
-		'label': u'Income',
-		'permlevel': 0
-	},
-
-	# DocField
-	{
-		'depends_on': u'eval:doc.use_standard',
-		'doctype': u'DocField',
+		u'doctype': u'DocField',
 		'fieldname': u'income_year_to_date',
 		'fieldtype': u'Check',
 		'label': u'Income Year to Date',
@@ -318,8 +287,7 @@
 
 	# DocField
 	{
-		'depends_on': u'eval:doc.use_standard',
-		'doctype': u'DocField',
+		u'doctype': u'DocField',
 		'fieldname': u'bank_balance',
 		'fieldtype': u'Check',
 		'label': u'Bank Balance',
@@ -328,11 +296,70 @@
 
 	# DocField
 	{
-		'doctype': u'DocField',
-		'fieldname': u'stock_below_rl',
+		u'doctype': u'DocField',
+		'fieldname': u'income',
 		'fieldtype': u'Check',
-		'hidden': 1,
-		'label': u'Stock Items below re-order level',
+		'label': u'Income',
 		'permlevel': 0
+	},
+
+	# DocField
+	{
+		u'doctype': u'DocField',
+		'fieldname': u'expenses_booked',
+		'fieldtype': u'Check',
+		'label': u'Expenses Booked',
+		'permlevel': 0
+	},
+
+	# DocField
+	{
+		u'doctype': u'DocField',
+		'fieldname': u'collections',
+		'fieldtype': u'Check',
+		'label': u'Collections',
+		'permlevel': 0
+	},
+
+	# DocField
+	{
+		u'doctype': u'DocField',
+		'fieldname': u'payments',
+		'fieldtype': u'Check',
+		'label': u'Payments',
+		'permlevel': 0
+	},
+
+	# DocField
+	{
+		u'doctype': u'DocField',
+		'fieldname': u'invoiced_amount',
+		'fieldtype': u'Check',
+		'label': u'Receivables',
+		'permlevel': 0
+	},
+
+	# DocField
+	{
+		u'doctype': u'DocField',
+		'fieldname': u'payables',
+		'fieldtype': u'Check',
+		'label': u'Payables',
+		'permlevel': 0
+	},
+
+	# DocPerm
+	{
+		'cancel': 1,
+		'create': 1,
+		u'doctype': u'DocPerm',
+		'permlevel': 0,
+		'write': 1
+	},
+
+	# DocPerm
+	{
+		u'doctype': u'DocPerm',
+		'permlevel': 1
 	}
 ]
\ No newline at end of file