Merge branch '4.0.0-wip' of github.com:webnotes/erpnext into 4.0-hotfix
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 3eb69fd..561aa4d 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -16,4 +16,5 @@
 execute:webnotes.reload_doc('accounts', 'doctype', 'pos_setting') # 2014-01-29
 execute:webnotes.reload_doc('selling', 'doctype', 'customer') # 2014-01-29
 execute:webnotes.reload_doc('buying', 'doctype', 'supplier') # 2014-01-29
-erpnext.patches.4_0.map_charge_to_taxes_and_charges
\ No newline at end of file
+erpnext.patches.4_0.map_charge_to_taxes_and_charges
+execute:webnotes.reload_doc('support', 'doctype', 'newsletter') # 2014-01-31
\ No newline at end of file
diff --git a/erpnext/selling/doctype/customer/customer.js b/erpnext/selling/doctype/customer/customer.js
index f2568d6..d12527d 100644
--- a/erpnext/selling/doctype/customer/customer.js
+++ b/erpnext/selling/doctype/customer/customer.js
@@ -3,7 +3,7 @@
 
 {% include 'setup/doctype/contact_control/contact_control.js' %};
 
-cur_frm.cscript.onload = function(doc,dt,dn){
+cur_frm.cscript.onload = function(doc, dt, dn) {
 	cur_frm.cscript.load_defaults(doc, dt, dn);
 }
 
@@ -27,8 +27,8 @@
 	}else{		
 		unhide_field(['address_html','contact_html']);
 		// make lists
-		cur_frm.cscript.make_address(doc,dt,dn);
-		cur_frm.cscript.make_contact(doc,dt,dn);
+		cur_frm.cscript.make_address(doc, dt, dn);
+		cur_frm.cscript.make_contact(doc, dt, dn);
 
 		cur_frm.communication_view = new wn.views.CommunicationList({
 			parent: cur_frm.fields_dict.communication_html.wrapper,
@@ -67,7 +67,7 @@
 			}
 			cur_frm.dashboard.set_badge_count(r.message);
 		}
-	})
+	});
 }
 
 cur_frm.cscript.make_address = function() {
@@ -104,7 +104,6 @@
 		// note: render_contact_row is defined in contact_control.js
 	}
 	cur_frm.contact_list.run();
-
 }
 
 cur_frm.fields_dict['customer_group'].get_query = function(doc, dt, dn) {
@@ -113,7 +112,6 @@
 	}
 }
 
-
 cur_frm.fields_dict.lead_name.get_query = function(doc, cdt, cdn) {
 	return{
 		query: "erpnext.controllers.queries.lead_query"
@@ -124,4 +122,4 @@
 	return{
 		filters:{'selling': 1}
 	}
-}
+}
\ No newline at end of file
diff --git a/erpnext/setup/doctype/contact_control/contact_control.js b/erpnext/setup/doctype/contact_control/contact_control.js
index d857ccd..2e45df6 100755
--- a/erpnext/setup/doctype/contact_control/contact_control.js
+++ b/erpnext/setup/doctype/contact_control/contact_control.js
@@ -1,32 +1,21 @@
 // Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
 // License: GNU General Public License v3. See license.txt
 
-// common partner functions
-// =========================
-
-
-// get sates on country trigger
-// -----------------------------
-cur_frm.cscript.get_states=function(doc,dt,dn){
-   return $c('runserverobj', args={'method':'check_state', 'docs':wn.model.compress(make_doclist(doc.doctype, doc.name))},
-    function(r,rt){
-      if(r.message) {
-        set_field_options('state', r.message);
-      }
-    }  
-  );
-
+cur_frm.cscript.get_states=function(doc, dt, dn) {
+	return $c('runserverobj', args={'method': 'check_state', 'docs':wn.model.compress(make_doclist(doc.doctype, doc.name))},
+		function(r, rt) {
+			if(r.message)
+				set_field_options('state', r.message);
+		}
+	);
 }
 
 cur_frm.cscript.country = function(doc, dt, dn) {
-  cur_frm.cscript.get_states(doc, dt, dn);
+	cur_frm.cscript.get_states(doc, dt, dn);
 }
 
-
-// get query select Territory
-// ---------------------------
-if(cur_frm.fields_dict['territory']){
-	cur_frm.fields_dict['territory'].get_query = function(doc,dt,dn) {
+if(cur_frm.fields_dict['territory']) {
+	cur_frm.fields_dict['territory'].get_query = function(doc, dt, dn) {
 		return {
 			filters: {
 				'is_group': "No" 
@@ -58,7 +47,7 @@
 			}
 		});
 	data.description = description.join('<br />');
-	
+
 	cur_frm.cscript.render_row_in_wrapper(wrapper, data, 'Contact');
 }
 
@@ -68,17 +57,17 @@
 	data.primary = '';
 	if (data.is_primary_address) data.primary += ' [Preferred for Billing]';
 	if (data.is_shipping_address) data.primary += ' [Preferred for Shipping]';
-	
+
 	// prepare address
 	var address = [];
 	$.each(['address_line1', 'address_line2', 'city', 'state', 'country', 'pincode'],
 		function(i, v) {
 			if(data[v]) address.push(data[v]);
 		});
-	
+
 	data.address = address.join('<br />');
 	data.address = "<p class='address-list'>" + data.address + "</p>";
-	
+
 	// prepare description
 	var description = [];
 	$.each([
@@ -95,9 +84,9 @@
 			}
 		});
 	data.description = description.join('<br />');
-	
+
 	cur_frm.cscript.render_row_in_wrapper(wrapper, data, 'Address');
-	
+
 	$(wrapper).find('p.address-list').css({
 		'padding-left': '10px',
 		'margin-bottom': '-10px'
@@ -107,21 +96,21 @@
 cur_frm.cscript.render_row_in_wrapper = function(wrapper, data, doctype) {
 	// render
 	var $wrapper = $(wrapper);
-	
+
 	data.doctype = doctype.toLowerCase();
-	
+
 	$wrapper.append(repl("\
 		<h4><a class='link_type'>%(fullname)s</a>%(primary)s</h4>\
 		<div class='description'>\
 			<p>%(description)s</p>\
 			<p><a class='delete link_type'>delete this %(doctype)s</a></p>\
 		</div>", data));
-	
+
 	// make link
 	$wrapper.find('h4 a.link_type').click(function() {
 		loaddoc(doctype, data.name);
 	});
-	
+
 	// css
 	$wrapper.css({ 'margin': '0px' });
 	$wrapper.find('div.description').css({
@@ -129,17 +118,15 @@
 		'line-height': '150%',
 	});
 	$wrapper.find('h6').css({ 'display': 'inline-block' });
-	
+
 	// show delete
 	var $delete_doc = $wrapper.find('a.delete');
-	if (wn.model.can_delete(doctype)) {
+	if (wn.model.can_delete(doctype))
 		$delete_doc.toggle(true);
-	} else {
+	else
 		$delete_doc.toggle(false);
-	}
-	$delete_doc.css({
-		'padding-left': '0px'
-	});
+
+	$delete_doc.css({ 'padding-left': '0px' });
 
 	$delete_doc.click(function() {
 		cur_frm.cscript.delete_doc(doctype, data.name);
@@ -184,17 +171,16 @@
 				[doctype, doc.doctype.toLowerCase().replace(" ", "_"), '=', doc.name],
 			],
 		});
-		
+
 		if (make_new_doc) {
 			RecordListView = RecordListView.extend({
 				make_new_doc: make_new_doc,
 			});
 		}
-		
+
 		var record_list_view = new RecordListView(doctype, wrapper, ListView);
 		if (!cur_frm[doctype.toLowerCase().replace(" ", "_") + "_list"]) {
 			cur_frm[doctype.toLowerCase().replace(" ", "_") + "_list"] = record_list_view;
 		}
 	});
-}
-
+}
\ No newline at end of file
diff --git a/erpnext/setup/doctype/naming_series/naming_series.js b/erpnext/setup/doctype/naming_series/naming_series.js
index e59756b..4f6a4c9 100644
--- a/erpnext/setup/doctype/naming_series/naming_series.js
+++ b/erpnext/setup/doctype/naming_series/naming_series.js
@@ -1,8 +1,7 @@
 // Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
 // License: GNU General Public License v3. See license.txt
 
-// Settings
-cur_frm.cscript.onload_post_render = function(doc, cdt, cdn){
+cur_frm.cscript.onload_post_render = function(doc, cdt, cdn) {
 	return cur_frm.call({
 		doc: cur_frm.doc,
 		method: 'get_transactions',
@@ -10,7 +9,7 @@
 			cur_frm.cscript.update_selects(r);
 			cur_frm.cscript.select_doc_for_series(doc, cdt, cdn);
 		}
-	})
+	});
 }
 
 cur_frm.cscript.update_selects = function(r) {
@@ -18,29 +17,27 @@
 	set_field_options('prefix', r.message.prefixes);
 }
 
-
 cur_frm.cscript.select_doc_for_series = function(doc, cdt, cdn) {
 	cur_frm.toggle_display(['help_html','set_options', 'user_must_always_select', 'update'], 
-		doc.select_doc_for_series)
+		doc.select_doc_for_series);
 
 	var callback = function(r, rt){
 		locals[cdt][cdn].set_options = r.message;
 		refresh_field('set_options');
-		if(r.message && r.message.split('\n')[0]=='') {
-			cur_frm.set_value('user_must_always_select', 1)
-		}
+		if(r.message && r.message.split('\n')[0]=='')
+			cur_frm.set_value('user_must_always_select', 1);
 	}
 
 	if(doc.select_doc_for_series)
-		return $c_obj(make_doclist(doc.doctype, doc.name),'get_options','',callback)
+		return $c_obj(make_doclist(doc.doctype, doc.name),'get_options','',callback);
 }
 
 cur_frm.cscript.update = function() {
-	return cur_frm.call_server('update_series', '', cur_frm.cscript.update_selects)
+	return cur_frm.call_server('update_series', '', cur_frm.cscript.update_selects);
 }
 
 cur_frm.cscript.prefix = function(doc, dt, dn) {
 	return cur_frm.call_server('get_current', '', function(r) {
 		refresh_field('current_value');
-	})
-}
+	});
+}
\ No newline at end of file
diff --git a/erpnext/setup/doctype/naming_series/naming_series.py b/erpnext/setup/doctype/naming_series/naming_series.py
index 092de20..10cdac2 100644
--- a/erpnext/setup/doctype/naming_series/naming_series.py
+++ b/erpnext/setup/doctype/naming_series/naming_series.py
@@ -5,10 +5,9 @@
 import webnotes
 
 from webnotes.utils import cstr
-from webnotes import msgprint
+from webnotes import msgprint, throw, _
 import webnotes.model.doctype
 
-
 class DocType:
 	def __init__(self, d, dl):
 		self.doc, self.doclist = d, dl
@@ -24,7 +23,7 @@
 			"prefixes": "\n".join([''] + [i[0] for i in 
 				webnotes.conn.sql("""select name from tabSeries order by name""")])
 		}
-	
+
 	def scrub_options_list(self, ol):
 		options = filter(lambda x: x, [cstr(n.upper()).strip() for n in ol])
 		return options
@@ -33,29 +32,29 @@
 		"""update series list"""
 		self.check_duplicate()
 		series_list = self.doc.set_options.split("\n")
-		
+
 		# set in doctype
 		self.set_series_for(self.doc.select_doc_for_series, series_list)
-		
+
 		# create series
 		map(self.insert_series, [d.split('.')[0] for d in series_list])
-		
-		msgprint('Series Updated')
-		
+
+		msgprint(_("Series Updated"))
+
 		return self.get_transactions()
-	
+
 	def set_series_for(self, doctype, ol):
 		options = self.scrub_options_list(ol)
-		
+
 		# validate names
 		for i in options: self.validate_series_name(i)
-		
+
 		if self.doc.user_must_always_select:
 			options = [''] + options
 			default = ''
 		else:
 			default = options[0]
-		
+
 		# update in property setter
 		from webnotes.model.doc import Document
 		prop_dict = {'options': "\n".join(options), 'default': default}
@@ -81,11 +80,11 @@
 		self.doc.set_options = "\n".join(options)
 
 		webnotes.clear_cache(doctype=doctype)
-			
+
 	def check_duplicate(self):
 		from webnotes.core.doctype.doctype.doctype import DocType
 		dt = DocType()
-	
+
 		parent = list(set(
 			webnotes.conn.sql_list("""select dt.name 
 				from `tabDocField` df, `tabDocType` dt 
@@ -105,15 +104,20 @@
 				if i[0]:
 					existing_series = [d.split('.')[0] for d in i[0].split("\n")]
 					if series.split(".")[0] in existing_series:
-						msgprint("Oops! Series name %s is already in use in %s. \
-							Please select a new one" % (series, i[1]), raise_exception=1)
-			
+						throw("{oops}! {sr} {series} {msg} {existing_series}. {select}".format(**{
+							"oops": _("Oops"),
+							"sr": _("Series Name"),
+							"series": series,
+							"msg": _("is already in use in"),
+							"existing_series": i[1],
+							"select": _("Please select a new one")
+						}))
+
 	def validate_series_name(self, n):
 		import re
 		if not re.match("^[a-zA-Z0-9-/.#]*$", n):
-			msgprint('Special Characters except "-" and "/" not allowed in naming series',
-				raise_exception=True)
-		
+			throw('Special Characters except "-" and "/" not allowed in naming series')
+
 	def get_options(self, arg=''):
 		sr = webnotes.model.doctype.get_property(self.doc.select_doc_for_series, 
 			'options', 'naming_series')
@@ -121,14 +125,14 @@
 
 	def get_current(self, arg=None):
 		"""get series current"""
-		self.doc.current_value = webnotes.conn.get_value("Series", 
-			self.doc.prefix.split('.')[0], "current")
+		if self.doc.prefix:
+			self.doc.current_value = webnotes.conn.get_value("Series", 
+				self.doc.prefix.split('.')[0], "current")
 
 	def insert_series(self, series):
 		"""insert series if missing"""
 		if not webnotes.conn.exists('Series', series):
-			webnotes.conn.sql("insert into tabSeries (name, current) values (%s, 0)", 
-				(series))			
+			webnotes.conn.sql("insert into tabSeries (name, current) values (%s, 0)", (series))
 
 	def update_series_start(self):
 		if self.doc.prefix:
@@ -136,9 +140,9 @@
 			self.insert_series(prefix)
 			webnotes.conn.sql("update `tabSeries` set current = %s where name = %s", 
 				(self.doc.current_value, prefix))
-			msgprint("Series Updated Successfully")
+			msgprint(_("Series Updated Successfully"))
 		else:
-			msgprint("Please select prefix first")
+			msgprint(_("Please select prefix first"))
 
 def set_by_naming_series(doctype, fieldname, naming_series, hide_name_field=True):
 	from webnotes.core.doctype.property_setter.property_setter import make_property_setter
@@ -148,7 +152,8 @@
 
 		# set values for mandatory
 		webnotes.conn.sql("""update `tab{doctype}` set naming_series={s} where 
-			ifnull(naming_series, '')=''""".format(doctype=doctype, s="%s"), get_default_naming_series(doctype))
+			ifnull(naming_series, '')=''""".format(doctype=doctype, s="%s"), 
+			get_default_naming_series(doctype))
 
 		if hide_name_field:
 			make_property_setter(doctype, fieldname, "reqd", 0, "Check")
@@ -160,13 +165,13 @@
 		if hide_name_field:
 			make_property_setter(doctype, fieldname, "hidden", 0, "Check")
 			make_property_setter(doctype, fieldname, "reqd", 1, "Check")
-			
+
 			# set values for mandatory
 			webnotes.conn.sql("""update `tab{doctype}` set `{fieldname}`=`name` where 
 				ifnull({fieldname}, '')=''""".format(doctype=doctype, fieldname=fieldname))
-		
+
 def get_default_naming_series(doctype):
 	from webnotes.model.doctype import get_property
 	naming_series = get_property(doctype, "options", "naming_series")
 	naming_series = naming_series.split("\n")
-	return naming_series[0] or naming_series[1]	
\ No newline at end of file
+	return naming_series[0] or naming_series[1]
\ No newline at end of file
diff --git a/erpnext/support/doctype/newsletter/newsletter.py b/erpnext/support/doctype/newsletter/newsletter.py
index 164d7df..d07d873 100644
--- a/erpnext/support/doctype/newsletter/newsletter.py
+++ b/erpnext/support/doctype/newsletter/newsletter.py
@@ -6,7 +6,7 @@
 import webnotes
 import webnotes.utils
 from webnotes.utils import cstr
-from webnotes import _
+from webnotes import msgprint, throw, _
 
 class DocType():
 	def __init__(self, d, dl):
@@ -22,18 +22,24 @@
 		self.recipients = self.doc.test_email_id.split(",")
 		self.send_to_doctype = "Lead"
 		self.send_bulk()
-		webnotes.msgprint("""Scheduled to send to %s""" % self.doc.test_email_id)
+		msgprint("{send} {email}".format**{
+			"send": _("Scheduled to send to"),
+			"email": self.doc.test_email_id
+		})
 
 	def send_emails(self):
 		"""send emails to leads and customers"""
 		if self.doc.email_sent:
-			webnotes.msgprint("""Newsletter has already been sent""", raise_exception=1)
+			throw(_("Newsletter has already been sent"))
 
 		self.recipients = self.get_recipients()
 		self.send_bulk()
 		
-		webnotes.msgprint("""Scheduled to send to %d %s(s)""" % (len(self.recipients), 
-			self.send_to_doctype))
+		msgprint("{send} {recipients} {doctype}(s)".format(**{
+			"send": _("Scheduled to send to"),
+			"recipients": len(self.recipients),
+			"doctype": self.send_to_doctype
+		}))
 
 		webnotes.conn.set(self.doc, "email_sent", 1)
 	
@@ -62,6 +68,12 @@
 			return webnotes.conn.sql_list("""select email_id from tabLead 
 				where ifnull(email_id, '') != '' %s""" % (conditions or ""))
 
+		elif self.doc.send_to_type=="Employee":
+			self.send_to_doctype = "Employee"
+			return webnotes.conn.sql_list("""select 
+				if(ifnull(company_email, '')!='', company_email, personal_email) as email_id 
+				from `tabEmployee` where status='Active'""")
+
 		elif self.doc.email_list:
 			email_list = [cstr(email).strip() for email in self.doc.email_list.split(",")]
 			for email in email_list:
@@ -79,7 +91,7 @@
 		
 		if not webnotes.flags.in_test:
 			webnotes.conn.auto_commit_on_many_writes = True
-		
+
 		send(recipients = self.recipients, sender = sender, 
 			subject = self.doc.subject, message = self.doc.message,
 			doctype = self.send_to_doctype, email_field = "email_id",
@@ -90,13 +102,12 @@
 
 	def validate_send(self):
 		if self.doc.fields.get("__islocal"):
-			webnotes.msgprint(_("""Please save the Newsletter before sending."""),
-				raise_exception=1)
+			throw(_("Please save the Newsletter before sending."))
 
 		from webnotes import conf
 		if (conf.get("status") or None) == "Trial":
-			webnotes.msgprint(_("""Sending newsletters is not allowed for Trial users, \
-				to prevent abuse of this feature."""), raise_exception=1)
+			throw(_("Sending newsletters is not allowed for Trial users, \
+				to prevent abuse of this feature."))
 
 @webnotes.whitelist()
 def get_lead_options():
diff --git a/erpnext/support/doctype/newsletter/newsletter.txt b/erpnext/support/doctype/newsletter/newsletter.txt
index 7cf149a..d0ce1f4 100644
--- a/erpnext/support/doctype/newsletter/newsletter.txt
+++ b/erpnext/support/doctype/newsletter/newsletter.txt
@@ -2,7 +2,7 @@
  {
   "creation": "2013-01-10 16:34:31", 
   "docstatus": 0, 
-  "modified": "2014-01-31 17:32:47", 
+  "modified": "2014-02-03 11:32:22", 
   "modified_by": "Administrator", 
   "owner": "Administrator"
  }, 
@@ -27,7 +27,7 @@
  {
   "cancel": 0, 
   "create": 1, 
-  "delete": 0, 
+  "delete": 1, 
   "doctype": "DocPerm", 
   "email": 0, 
   "name": "__common__", 
@@ -66,7 +66,7 @@
   "fieldname": "send_to_type", 
   "fieldtype": "Select", 
   "label": "Send To Type", 
-  "options": "Lead\nContact\nCustom"
+  "options": "Lead\nContact\nEmployee\nCustom"
  }, 
  {
   "doctype": "DocField", 
@@ -93,7 +93,7 @@
   "fieldname": "contact_type", 
   "fieldtype": "Select", 
   "label": "Contact Type", 
-  "options": "Customer\nSupplier\nCustom"
+  "options": "Customer\nSupplier"
  }, 
  {
   "depends_on": "eval:doc.send_to_type==\"Custom\"",