Merge pull request #201 from anandpdoshi/stable

Notifications fix and Support Ticket fix
diff --git a/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.js b/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.js
index c2b478e..e7fb676 100644
--- a/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.js
+++ b/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.js
@@ -443,3 +443,12 @@
 		refresh_field(['repeat_on_day_of_month', 'notification_email_address']);
 	}		
 }
+
+$import(Notification Control)
+cur_frm.cscript.on_submit = function(doc, cdt, cdn) {
+	var args = {
+		type: 'Sales Invoice',
+		doctype: 'Receivable Voucher'
+	}
+	cur_frm.cscript.notify(doc, args);
+}
diff --git a/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.py b/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.py
index 536bb6d..af6225b 100644
--- a/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.py
+++ b/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.py
@@ -570,9 +570,6 @@
 
 		self.update_c_form()
 
-		# on submit notification
-		# get_obj('Notification Control').notify_contact('Sales Invoice', self.doc.doctype,self.doc.name, self.doc.email_id, self.doc.contact_person)
-
 
 	def update_c_form(self):
 		"""Update amended id in C-form"""
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js
index d3fa37b..05fe049 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.js
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.js
@@ -245,3 +245,12 @@
 
   return out;
 }
+
+$import(Notification Control)
+cur_frm.cscript.on_submit = function(doc, cdt, cdn) {
+	var args = {
+		type: 'Purchase Order',
+		doctype: 'Purchase Order'
+	}
+	cur_frm.cscript.notify(doc, args);
+}
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index 1a5d2d7..752e348 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -207,8 +207,6 @@
     
     self.doc.indent_no = '';
   
-    # on submit notification
-    get_obj('Notification Control').notify_contact('Purchase Order', self.doc.doctype,self.doc.name, self.doc.email_id, self.doc.contact_person)
    
   # On Cancel
   # -------------------------------------------------------------------------------------------------------
diff --git a/erpnext/hr/doctype/expense_voucher/expense_voucher.js b/erpnext/hr/doctype/expense_voucher/expense_voucher.js
index 7b34a46..bdad2c5 100644
--- a/erpnext/hr/doctype/expense_voucher/expense_voucher.js
+++ b/erpnext/hr/doctype/expense_voucher/expense_voucher.js
@@ -84,6 +84,8 @@
   cur_frm.cscript.calculate_total(doc,cdt,cdn);
 }
 
+$import(Notification Control);
+
 cur_frm.cscript['Approve'] = function(doc,cdt,cdn){
 
   if(user == doc.exp_approver){
@@ -120,6 +122,13 @@
             refresh_field('approval_status');
             hide_field(['Update Voucher', 'Approve', 'Reject', 'Calculate Total Amount']);
             approve_voucher_dialog.hide();
+			var args = {
+				type: 'Expense Voucher Approved',
+				doctype: 'Expense Voucher',
+				contact_name: doc.employee_name,
+				send_to: doc.email_id
+			}
+			cur_frm.cscript.notify(doc, args);
           }
           else if(r.message == 'Incomplete'){
             $i('approve_voucher_dialog_response').innerHTML = 'Incomplete Voucher';
@@ -181,6 +190,13 @@
             refresh_field('approval_status');
             hide_field(['Update Voucher', 'Approve', 'Reject', 'Calculate Total Amount']);
             reject_voucher_dialog.hide();
+			var args = {
+				type: 'Expense Voucher Rejected',
+				doctype: 'Expense Voucher',
+				contact_name: doc.employee_name,
+				send_to: doc.email_id
+			}
+			cur_frm.cscript.notify(doc, args);
           }
         });
       }
@@ -211,3 +227,12 @@
     cur_frm.refresh_header();
   });
 }
+
+$import(Notification Control)
+cur_frm.cscript.on_submit = function(doc, cdt, cdn) {
+	var args = {
+		type: 'Expense Voucher',
+		doctype: 'Expense Voucher'
+	}
+	cur_frm.cscript.notify(doc, args);
+}
diff --git a/erpnext/hr/doctype/expense_voucher/expense_voucher.py b/erpnext/hr/doctype/expense_voucher/expense_voucher.py
index 01db068..4352cca 100644
--- a/erpnext/hr/doctype/expense_voucher/expense_voucher.py
+++ b/erpnext/hr/doctype/expense_voucher/expense_voucher.py
@@ -72,7 +72,7 @@
     
     set(self.doc, 'approval_status', 'Approved')    
     # on approval notification
-    get_obj('Notification Control').notify_contact('Expense Voucher Approved', self.doc.doctype, self.doc.name, self.doc.email_id, self.doc.employee_name)
+    #get_obj('Notification Control').notify_contact('Expense Voucher Approved', self.doc.doctype, self.doc.name, self.doc.email_id, self.doc.employee_name)
 
     return cstr('Approved')
   
@@ -83,7 +83,7 @@
     set(self.doc, 'approval_status', 'Rejected')    
 
     # on approval notification
-    get_obj('Notification Control').notify_contact('Expense Voucher Rejected', self.doc.doctype, self.doc.name, self.doc.email_id, self.doc.employee_name)
+    #get_obj('Notification Control').notify_contact('Expense Voucher Rejected', self.doc.doctype, self.doc.name, self.doc.email_id, self.doc.employee_name)
 
     return cstr('Rejected')
   
@@ -140,4 +140,4 @@
     set(self.doc, 'approval_status', 'Submitted')
   
   def on_cancel(self):
-    set(self.doc, 'approval_status', 'Cancelled')
\ No newline at end of file
+    set(self.doc, 'approval_status', 'Cancelled')
diff --git a/erpnext/selling/doctype/quotation/quotation.js b/erpnext/selling/doctype/quotation/quotation.js
index 4c205a9..9ff676f 100644
--- a/erpnext/selling/doctype/quotation/quotation.js
+++ b/erpnext/selling/doctype/quotation/quotation.js
@@ -303,3 +303,12 @@
   else
     return repl("SELECT name, item_name, description FROM tabItem WHERE `tabItem`.%(key)s LIKE '%s' %(cond)s ORDER BY tabItem.item_code DESC LIMIT 50", {cond:cond});
 }
+
+$import(Notification Control)
+cur_frm.cscript.on_submit = function(doc, cdt, cdn) {
+	var args = {
+		type: 'Quotation',
+		doctype: 'Quotation'
+	}
+	cur_frm.cscript.notify(doc, args);
+}
diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py
index 10bccaf..01e67eb 100644
--- a/erpnext/selling/doctype/quotation/quotation.py
+++ b/erpnext/selling/doctype/quotation/quotation.py
@@ -25,9 +25,6 @@
     self.tname = 'Quotation Detail'
     self.fname = 'quotation_details'
     
-    # Notification objects
-    self.notify_obj = get_obj('Notification Control')
-
   # Autoname
   # ---------
   def autoname(self):
@@ -306,8 +303,6 @@
     #update enquiry status
     self.update_enquiry('submit')
     
-    # on submit notification
-    self.notify_obj.notify_contact('Quotation', self.doc.doctype, self.doc.name, self.doc.email_id, self.doc.contact_person)
     
 # ON CANCEL
 # ==========================================================================
diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js
index 949abcd..c7e9b82 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.js
+++ b/erpnext/selling/doctype/sales_order/sales_order.js
@@ -335,4 +335,11 @@
   return 'SELECT `tabTerritory`.`name`,`tabTerritory`.`parent_territory` FROM `tabTerritory` WHERE `tabTerritory`.`is_group` = "No" AND `tabTerritory`.`docstatus`!= 2 AND `tabTerritory`.%(key)s LIKE "%s"  ORDER BY  `tabTerritory`.`name` ASC LIMIT 50';
 }
 
-
+$import(Notification Control)
+cur_frm.cscript.on_submit = function(doc, cdt, cdn) {
+	var args = {
+		type: 'Sales Order',
+		doctype: 'Sales Order'
+	}
+	cur_frm.cscript.notify(doc, args);
+}
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 72245eb..aefe666 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -366,10 +366,6 @@
 		# set SO status
 		set(self.doc, 'status', 'Submitted')
 	
-		# on submit notification		
-		if self.doc.email_id:
-			get_obj('Notification Control').notify_contact('Sales Order',self.doc.doctype,self.doc.name, self.doc.email_id, self.doc.contact_person)
-				
  
 # ON CANCEL
 # ===============================================================================================
diff --git a/erpnext/setup/doctype/notification_control/notification_control.js b/erpnext/setup/doctype/notification_control/notification_control.js
index f18e38d..112395e 100644
--- a/erpnext/setup/doctype/notification_control/notification_control.js
+++ b/erpnext/setup/doctype/notification_control/notification_control.js
@@ -7,4 +7,40 @@
     }
     $c_obj('Notification Control','get_message',doc.select_transaction, callback)
   }
-}
\ No newline at end of file
+}
+
+cur_frm.cscript.notify = function(doc, args) {
+	if(validate_email(args['send_to'] || doc.contact_email || '')) {
+		$c_obj('Notification Control', 'get_formatted_message', {
+			type: args['type'],
+			doctype: args['doctype'],
+			contact_name: args['contact_name'] || doc.contact_display
+		}, function(r, rt) {
+			if(!r.exc) {
+				var res = JSON.parse(r.message);
+				var send_from = (function() {
+					if(user!='Administrator') {
+						return user;
+					} else {
+						var cp = locals['Control Panel']['Control Panel'];
+						return (cp.auto_email_id || 'automail@erpnext.com');
+					}
+				})();
+				if(res.send) {
+					var print_heading = (doc.select_print_heading || args['type'])
+					sendmail(
+						args['send_to'] || doc.contact_email,
+						send_from,
+						send_from,
+						doc.company + " - " + print_heading,
+						res.message,
+						res.print_format
+					);
+					msgprint('This ' + print_heading + ' is being sent to <b>'
+						+ (args['send_to'] || doc.contact_email) + '</b><br />...');
+				}
+			}
+			//console.log(JSON.parse(r.message));
+		});
+	}
+}
diff --git a/erpnext/setup/doctype/notification_control/notification_control.py b/erpnext/setup/doctype/notification_control/notification_control.py
index 70d863d..216c46b 100644
--- a/erpnext/setup/doctype/notification_control/notification_control.py
+++ b/erpnext/setup/doctype/notification_control/notification_control.py
@@ -3,27 +3,12 @@
 
 from webnotes.utils import validate_email_add, cint, cstr
 from webnotes.model.doc import Document
+from webnotes.model.code import get_obj
 from webnotes import msgprint
 
 sql = webnotes.conn.sql
 	
 # -----------------------------------------------------------------------------------------
-
-def get_formatted_message(head, body):
-	if head:
-		head = '<div style="font-size: 19px; margin-bottom: 13px; color: #333; font-family: Arial;">%s</div>' % head
-	else:
-		head = ''
-
-	return '''
-	<div style="margin: 13px">
-	%(head)s
-	<p style="font-size: 14px; line-height: 1.7em; color: #555; font-family: Arial;">
-	%(body)s
-	</p>
-	</div>
-	''' % {'head':head, 'body':body.replace('\n', '<br>')}
-
 # Notification control
 class DocType:
 	def __init__(self,d,dl):
@@ -43,62 +28,64 @@
 		webnotes.conn.set(self.doc, fn, self.doc.custom_message)
 		msgprint("Custom Message for %s updated!" % self.doc.select_transaction)
 
-	# notify contact
-	# --------------
-	def notify_contact(self, key, dt, dn, contact_email, contact_nm):
-
-		if contact_email:
-			dt_small = dt.replace(' ','_').lower()
-
-			if cint(self.doc.fields.get(dt_small)):
-				self.send_notification(key, dt, dn, contact_email, contact_nm)
-			
-	# send notification
-	def send_notification(self, key, dt, dn, contact_email, contact_nm):
-		import webnotes.utils.encrypt
-		import os
-		from webnotes.utils.email_lib import sendmail
-		
-		cp = Document('Control Panel', 'Control Panel')
-		
-		banner = cp.client_name
-
-		sender_nm = sql("select concat_ws(' ', first_name, last_name) from tabProfile where name = %s", webnotes.session['user'])[0][0] or ''
-		
-		if contact_nm:
-			contact_nm = ' ' + contact_nm
-		else:
-			contact_nm = ''
-		
-		msg = '''
-		<div style="margin-bottom: 13px;">%(company_banner)s</div>
-		Hi%(contact)s,
-
-		%(message)s
-
-		<a href="http://%(domain)s/v170/index.cgi?page=Form/%(dt)s/%(dn)s&ac_name=%(account)s&akey=%(akey)s">Click here to see the document.</a></p>
-
-		Thanks,
-		%(sent_by)s
-		%(company_name)s
-		''' % {
-			'company_banner': banner, 
-			'contact': contact_nm, 
-			'message': self.doc.fields[key.lower().replace(' ','_')+'_message'],
-			'sent_by': sender_nm, 
-			'company_name':cp.company_name,
-			'dt': dt.replace(' ', '%20'),
-			'dn': dn.replace('/', '%2F'),
-			'domain': os.environ.get('HTTP_HOST'),
-			'account': cp.account_id,
-			'akey': webnotes.utils.encrypt.encrypt(dn)
+	
+	def get_formatted_message(self, args):
+		"""
+			args can contain:
+				* type
+				* doctype
+				* contact_name
+		"""
+		import json
+		args = json.loads(args)
+		res = {
+			'send': 0,
+			'message': self.prepare_message(args),
+			'print_format': self.get_default_print_format(args)
 		}
 
-		if not validate_email_add(webnotes.session['user']):
-			sender = "automail@webnotestech.com"
-		else:
-			sender = webnotes.session['user']
-		
-		rec_lst = [contact_email, sender]
-		subject = cp.company_name + ' - ' + dt
-		sendmail(rec_lst, sender, get_formatted_message(None, msg), subject)
+		dt_small = args.get('doctype').replace(' ', '_').lower()
+		if cint(self.doc.fields.get(dt_small)):
+			res['send'] = 1
+
+		return json.dumps(res)
+
+
+	def prepare_message(self, args):
+		"""
+			Prepares message body
+		"""
+		if args.get('type') and args.get('doctype'):
+			msg_dict = {}
+			msg_dict['message'] = self.get_message(args.get('type'))
+			msg_dict['company'] = Document('Control Panel', 'Control Panel').company_name
+			msg_dict['salutation'] = "Hi" + (args.get('contact_name') and (" " + args.get('contact_name')) or "")
+			msg_dict['send_from'] = webnotes.conn.sql("""\
+				SELECT CONCAT_WS(' ', first_name, last_name)
+				FROM `tabProfile`
+				WHERE name = %s""", webnotes.session['user'], as_list=1)[0][0] or ''
+			
+			return """\
+				<div>
+					%(salutation)s,
+
+					%(message)s
+					
+					Thanks,
+					%(send_from)s
+					%(company)s
+				</div>""" % msg_dict
+
+		else: return ""
+
+
+	def get_default_print_format(self, args):
+		"""
+			Get default print format from doclayer
+		"""
+		doclayer = get_obj('DocLayer', 'DocLayer')
+		doclayer.doc.doc_type = args.get('doctype')
+		doclayer.get()
+		if doclayer.doc.default_print_format:
+			return doclayer.doc.default_print_format
+		else: return 'Standard'
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.js b/erpnext/stock/doctype/delivery_note/delivery_note.js
index 8f9fa6d..7399530 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.js
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.js
@@ -350,3 +350,12 @@
 
   return out;
 }
+
+$import(Notification Control)
+cur_frm.cscript.on_submit = function(doc, cdt, cdn) {
+	var args = {
+		type: 'Delivery Note',
+		doctype: 'Delivery Note'
+	}
+	cur_frm.cscript.notify(doc, args);
+}
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index 93f72df..8fc1abc 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -25,9 +25,6 @@
 		self.tname = 'Delivery Note Detail'
 		self.fname = 'delivery_note_details'
 
-		# Notification objects
-		self.notify_obj = get_obj('Notification Control')
-
 	# Autoname
 	# ---------
 	def autoname(self):
@@ -321,9 +318,6 @@
 		# set DN status
 		set(self.doc, 'status', 'Submitted')
 
-		# on submit notification
-		self.notify_obj.notify_contact('Delivery Note',self.doc.doctype,self.doc.name, self.doc.email_id, self.doc.contact_person)
-
 
 	# *********** Checks whether actual quantity is present in warehouse *************
 	def check_qty_in_stock(self):
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
index aa75b61..b5c68c2 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
@@ -287,3 +287,12 @@
 
   return out;
 }
+
+$import(Notification Control)
+cur_frm.cscript.on_submit = function(doc, cdt, cdn) {
+	var args = {
+		type: 'Purchase Receipt',
+		doctype: 'Purchase Receipt'
+	}
+	cur_frm.cscript.notify(doc, args);
+}
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index bb2b456..944fa8a 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -254,10 +254,6 @@
     # Update last purchase rate
     pc_obj.update_last_purchase_rate(self, 1)
 
-    # on submit notification
-    get_obj('Notification Control').notify_contact('Purchase Receipt', self.doc.doctype,self.doc.name, self.doc.email_id, self.doc.contact_person)
-
-
 
 
   #On Cancel
diff --git a/erpnext/support/doctype/support_ticket/__init__.py b/erpnext/support/doctype/support_ticket/__init__.py
index f629cbd..fcf4e32 100644
--- a/erpnext/support/doctype/support_ticket/__init__.py
+++ b/erpnext/support/doctype/support_ticket/__init__.py
@@ -40,18 +40,32 @@
 		else:
 			content, content_type = mail.html_content, 'text/html'
 			
-		thread_id = mail.get_thread_id()
+		thread_list = mail.get_thread_id()
 
-		if webnotes.conn.exists('Support Ticket', thread_id):
-			from webnotes.model.code import get_obj
-			
-			st = get_obj('Support Ticket', thread_id)
-			st.make_response_record(content, mail.mail['From'], content_type)
-			webnotes.conn.set(st.doc, 'status', 'Open')
-			update_feed(st.doc)
-			# extract attachments
-			self.save_attachments(st.doc, mail.attachments)
-			return
+
+		email_id = mail.mail['From']
+		if "<" in mail.mail['From']:
+			import re
+			re_result = re.findall('(?<=\<)(\S+)(?=\>)', mail.mail['From'])
+			if re_result and re_result[0]: email_id = res_result[0]
+
+
+		for thread_id in thread_list:
+			exists = webnotes.conn.sql("""\
+				SELECT name
+				FROM `tabSupport Ticket`
+				WHERE name=%s AND raised_by LIKE %s
+				""", (thread_id, "%" + email_id + "%"))
+			if exists and exists[0] and exists[0][0]:
+				from webnotes.model.code import get_obj
+				
+				st = get_obj('Support Ticket', thread_id)
+				st.make_response_record(content, mail.mail['From'], content_type)
+				webnotes.conn.set(st.doc, 'status', 'Open')
+				update_feed(st.doc)
+				# extract attachments
+				self.save_attachments(st.doc, mail.attachments)
+				return
 				
 		# new ticket
 		from webnotes.model.doc import Document
diff --git a/index.html b/index.html
index a085f8c..b04284a 100644
--- a/index.html
+++ b/index.html
@@ -3,7 +3,7 @@
 	<meta charset="utf-8">
 	<title>ERPNext</title>
 	<meta name="author" content="">
-	<script type="text/javascript">window._version_number="340"
+	<script type="text/javascript">window._version_number="348"
 
 wn={}
 wn.provide=function(namespace){var nsl=namespace.split('.');var l=nsl.length;var parent=window;for(var i=0;i<l;i++){var n=nsl[i];if(!parent[n]){parent[n]={}}
diff --git a/versions-master.db b/versions-master.db
index 728c868..799c9af 100644
--- a/versions-master.db
+++ b/versions-master.db
Binary files differ