Newsletter: Bulk Send via worker
diff --git a/erpnext/support/doctype/newsletter/newsletter.py b/erpnext/support/doctype/newsletter/newsletter.py
index 88040e2..aaf4ddf 100644
--- a/erpnext/support/doctype/newsletter/newsletter.py
+++ b/erpnext/support/doctype/newsletter/newsletter.py
@@ -8,11 +8,12 @@
 from frappe.utils import cstr
 from frappe import throw, _
 from frappe.model.document import Document
+import erpnext.tasks
 
 class Newsletter(Document):
 	def onload(self):
 		if self.email_sent:
-			self.get("__onload").status_count = dict(frappe.db.sql("""select status, count(*)
+			self.get("__onload").status_count = dict(frappe.db.sql("""select status, count(name)
 				from `tabBulk Email` where ref_doctype=%s and ref_docname=%s
 				group by status""", (self.doctype, self.name))) or None
 
@@ -28,7 +29,13 @@
 			throw(_("Newsletter has already been sent"))
 
 		self.recipients = self.get_recipients()
-		self.send_bulk()
+
+		if frappe.local.is_ajax:
+			# to avoid request timed out!
+			self.validate_send()
+			erpnext.tasks.send_newsletter.delay(frappe.local.site, self.name)
+		else:
+			self.send_bulk()
 
 		frappe.msgprint(_("Scheduled to send to {0} recipients").format(len(self.recipients)))
 
@@ -77,6 +84,10 @@
 			return email_list
 
 	def send_bulk(self):
+		if not self.get("recipients"):
+			# in case it is called via worker
+			self.recipients = self.get_recipients()
+
 		self.validate_send()
 
 		sender = self.send_from or frappe.utils.get_formatted_email(self.owner)
@@ -98,10 +109,6 @@
 		if self.get("__islocal"):
 			throw(_("Please save the Newsletter before sending"))
 
-		from frappe import conf
-		if (conf.get("status") or None) == "Trial":
-			throw(_("Newsletters is not allowed for Trial users"))
-
 @frappe.whitelist()
 def get_lead_options():
 	return {
diff --git a/erpnext/tasks.py b/erpnext/tasks.py
new file mode 100644
index 0000000..da2ab03
--- /dev/null
+++ b/erpnext/tasks.py
@@ -0,0 +1,29 @@
+# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
+# MIT License. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.celery_app import celery_task, task_logger
+
+@celery_task()
+def send_newsletter(site, newsletter):
+	try:
+		frappe.connect(site=site)
+		doc = frappe.get_doc("Newsletter", newsletter)
+		doc.send_bulk()
+
+	except:
+		frappe.db.rollback()
+		task_logger.warn(frappe.get_traceback())
+
+		# wasn't able to send emails :(
+		doc.db_set("email_sent", 0)
+		frappe.db.commit()
+
+		raise
+
+	else:
+		frappe.db.commit()
+
+	finally:
+		frappe.destroy()