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