added code to update timestamps in Task, Customer Issue and Support Ticket

This commit is contained in:
Rushabh Mehta 2013-01-14 15:48:00 +05:30
parent 0c42dc4c22
commit be9ef4ac89
13 changed files with 152 additions and 101 deletions

View File

@ -0,0 +1,32 @@
import webnotes
def execute():
webnotes.reload_doc("core", "doctype", "docfield")
webnotes.reload_doc("support", "doctype", "support_ticket")
# customer issue resolved_by should be Profile
if webnotes.conn.sql("""select count(*) from `tabCustomer Issue`
where ifnull(resolved_by,"")!="" """)[0][0]:
webnotes.make_property_setter({
"doctype":"Customer Issue",
"fieldname": "resolved_by",
"property": "options",
"value": "Sales Person"
})
def get_communication_time(support_ticket, sort_order = 'asc'):
tmp = webnotes.conn.sql("""select creation from tabCommunication where
support_ticket=%s order by creation %s limit 1""" % ("%s", sort_order),
support_ticket)
return tmp and tmp[0][0] or None
# update in support ticket
webnotes.conn.auto_commit_on_many_writes = True
for st in webnotes.conn.sql("""select name, modified, status from
`tabSupport Ticket`""", as_dict=1):
webnotes.conn.sql("""update `tabSupport Ticket` set first_responded_on=%s where
name=%s""", (get_communication_time(st.name) or st.modified, st.name))
if st.status=="Closed":
webnotes.conn.sql("""update `tabSupport Ticket` set resolution_date=%s where
name=%s""", (get_communication_time(st.name, 'desc') or st.modified, st.name))

View File

@ -17,7 +17,7 @@
from __future__ import unicode_literals
import webnotes
from webnotes.utils import getdate
from webnotes.utils import getdate, today
from webnotes.model import db_exists
from webnotes.model.wrapper import copy_doclist
from webnotes import msgprint
@ -40,7 +40,7 @@ class DocType:
if cust:
ret = {'customer_name': cust and cust[0][0] or ''}
return ret
def validate(self):
if self.doc.exp_start_date and self.doc.exp_end_date and getdate(self.doc.exp_start_date) > getdate(self.doc.exp_end_date):
msgprint("'Expected Start Date' can not be greater than 'Expected End Date'")
@ -49,4 +49,14 @@ class DocType:
if self.doc.act_start_date and self.doc.act_end_date and getdate(self.doc.act_start_date) > getdate(self.doc.act_end_date):
msgprint("'Actual Start Date' can not be greater than 'Actual End Date'")
raise Exception
self.update_status()
def update_status(self):
status = webnotes.conn.get_value("Task", self.doc.name, "status")
if self.doc.status=="Working" and status !="Working" and not self.doc.act_start_date:
self.doc.act_start_date = today()
if self.doc.status=="Closed" and status != "Closed" and not self.doc.act_end_date:
self.doc.act_end_date = today()

View File

@ -2,9 +2,9 @@
{
"owner": "Administrator",
"docstatus": 0,
"creation": "2012-10-29 14:30:00",
"creation": "2013-01-10 16:34:17",
"modified_by": "Administrator",
"modified": "2013-01-02 12:40:26"
"modified": "2013-01-14 14:03:52"
},
{
"autoname": "TASK.#####",
@ -28,6 +28,8 @@
"parent": "Task",
"read": 1,
"doctype": "DocPerm",
"submit": 0,
"report": 1,
"parenttype": "DocType",
"role": "Projects User",
"parentfield": "permissions"
@ -191,14 +193,6 @@
"fieldname": "act_end_date",
"fieldtype": "Date"
},
{
"oldfieldtype": "Data",
"doctype": "DocField",
"label": "Total Hours (Actual)",
"oldfieldname": "act_total_hrs",
"fieldname": "act_total_hrs",
"fieldtype": "Data"
},
{
"oldfieldtype": "Currency",
"doctype": "DocField",
@ -253,7 +247,6 @@
"amend": 0,
"create": 0,
"doctype": "DocPerm",
"submit": 0,
"cancel": 0,
"permlevel": 1
}

View File

@ -32,6 +32,7 @@ erpnext.utils.Controller = Class.extend({
var defaults = {
posting_date: wn.datetime.get_today(),
posting_time: wn.datetime.now_time()
}
$.each(defaults, function(k, v) {

View File

@ -219,7 +219,7 @@ data_map = {
# Support
"Support Ticket": {
"columns": ["name","status","creation","modified"],
"columns": ["name","status","creation","resolution_date","first_responded_on"],
"conditions": ["docstatus < 2"],
"order_by": "creation"
}

View File

@ -100,7 +100,7 @@ class DocType:
def validate_posting_time(self):
""" Validate posting time format"""
if self.doc.posting_time and len(self.doc.posting_time.split(':')) > 2:
if self.doc.posting_time and len(self.doc.posting_time.split(':')) > 3:
msgprint("Wrong format of posting time, can not complete the transaction. If you think \
you entered posting time correctly, please contact ERPNext support team.")
raise Exception
@ -108,6 +108,4 @@ class DocType:
def scrub_posting_time(self):
if not self.doc.posting_time or self.doc.posting_time == '00:0':
self.doc.posting_time = '00:00'
if len(self.doc.posting_time.split(':')) > 2:
self.doc.posting_time = '00:00'

View File

@ -15,15 +15,17 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
cur_frm.cscript.onload = function(doc,cdt,cdn){
if(!doc.status) set_multiple(dt,dn,{status:'Open'});
if(!doc.status)
set_multiple(dt,dn,{status:'Open'});
if(doc.__islocal){
hide_field(['customer_address','contact_person']);
}
}
}
cur_frm.cscript.refresh = function(doc,ct,cdn){
if(doc.docstatus == 1 && (doc.status == 'Open' || doc.status == 'Work In Progress'))
cur_frm.add_custom_button('Make Maintenance Visit', cur_frm.cscript['Make Maintenance Visit']);
cur_frm.add_custom_button('Make Maintenance Visit',
cur_frm.cscript['Make Maintenance Visit']);
}
@ -109,11 +111,9 @@ cur_frm.add_fetch('serial_no', 'description', 'description');
cur_frm.add_fetch('serial_no', 'maintenance_status', 'warranty_amc_status');
cur_frm.add_fetch('serial_no', 'warranty_expiry_date', 'warranty_expiry_date');
cur_frm.add_fetch('serial_no', 'amc_expiry_date', 'amc_expiry_date');
if (cstr(doc.customer) == '') {
cur_frm.add_fetch('serial_no', 'customer', 'customer');
cur_frm.add_fetch('serial_no', 'customer_name', 'customer_name');
cur_frm.add_fetch('serial_no', 'delivery_address', 'customer_address');
}
cur_frm.add_fetch('serial_no', 'customer', 'customer');
cur_frm.add_fetch('serial_no', 'customer_name', 'customer_name');
cur_frm.add_fetch('serial_no', 'delivery_address', 'customer_address');
// ----------
// item code

View File

@ -21,6 +21,7 @@ import webnotes
from webnotes.model import db_exists
from webnotes.model.wrapper import copy_doclist
from webnotes import session, msgprint
from webnotes.utils import today
sql = webnotes.conn.sql
@ -43,6 +44,11 @@ class DocType(TransactionBase):
if session['user'] != 'Guest' and not self.doc.customer:
msgprint("Please select Customer from whom issue is raised",
raise_exception=True)
if self.doc.status=="Closed" and \
webnotes.conn.get_value("Customer Issue", self.doc.name, "status")!="Closed":
self.doc.resolution_date = today()
self.doc.resolved_by = webnotes.session.user
def on_cancel(self):
lst = sql("select t1.name from `tabMaintenance Visit` t1, `tabMaintenance Visit Purpose` t2 where t2.parent = t1.name and t2.prevdoc_docname = '%s' and t1.docstatus!=2"%(self.doc.name))

View File

@ -2,9 +2,9 @@
{
"owner": "harshada@webnotestech.com",
"docstatus": 0,
"creation": "2012-11-28 11:26:23",
"creation": "2013-01-10 16:34:30",
"modified_by": "Administrator",
"modified": "2012-12-03 17:10:41"
"modified": "2013-01-14 12:41:48"
},
{
"is_submittable": 1,
@ -27,6 +27,7 @@
"read": 1,
"doctype": "DocPerm",
"parenttype": "DocType",
"report": 1,
"parentfield": "permissions"
},
{
@ -51,7 +52,6 @@
"permlevel": 0,
"no_copy": 1,
"oldfieldtype": "Select",
"colour": "White:FFF",
"doctype": "DocField",
"label": "Status",
"oldfieldname": "status",
@ -87,12 +87,10 @@
{
"print_hide": 1,
"oldfieldtype": "Link",
"colour": "White:FFF",
"doctype": "DocField",
"label": "Customer",
"oldfieldname": "customer",
"permlevel": 0,
"trigger": "Client",
"fieldname": "customer",
"fieldtype": "Link",
"search_index": 1,
@ -140,28 +138,24 @@
},
{
"description": "Item, Warranty, AMC (Annual Maintenance Contract) details will be automatically fetched when Serial Number is selected.",
"colour": "White:FFF",
"doctype": "DocField",
"label": "Serial No",
"trigger": "Client",
"options": "Serial No",
"fieldname": "serial_no",
"fieldtype": "Link",
"options": "Serial No",
"permlevel": 0
},
{
"oldfieldtype": "Link",
"colour": "White:FFF",
"doctype": "DocField",
"label": "Item Code",
"oldfieldname": "item_code",
"permlevel": 0,
"trigger": "Client",
"options": "Item",
"fieldname": "item_code",
"fieldtype": "Link",
"search_index": 1,
"reqd": 0,
"options": "Item",
"permlevel": 0,
"in_filter": 1
},
{
@ -174,7 +168,6 @@
},
{
"oldfieldtype": "Data",
"colour": "White:FFF",
"doctype": "DocField",
"label": "Item Name",
"oldfieldname": "item_name",
@ -185,7 +178,6 @@
},
{
"oldfieldtype": "Small Text",
"colour": "White:FFF",
"doctype": "DocField",
"label": "Description",
"oldfieldname": "description",
@ -196,7 +188,6 @@
"permlevel": 1
},
{
"colour": "White:FFF",
"doctype": "DocField",
"label": "Warranty / AMC Status",
"options": "\nUnder Warranty\nOut of Warranty\nUnder AMC\nOut of AMC",
@ -223,7 +214,6 @@
{
"description": "To assign this issue, use the \"Assign\" button in the sidebar.",
"oldfieldtype": "Section Break",
"colour": "White:FFF",
"doctype": "DocField",
"label": "Resolution",
"options": "Simple",
@ -238,7 +228,7 @@
"label": "Resolution Date",
"oldfieldname": "resolution_date",
"fieldname": "resolution_date",
"fieldtype": "Date",
"fieldtype": "Datetime",
"search_index": 1,
"permlevel": 0,
"in_filter": 1
@ -249,7 +239,7 @@
"doctype": "DocField",
"label": "Resolved By",
"oldfieldname": "resolved_by",
"options": "Sales Person",
"options": "Profile",
"fieldname": "resolved_by",
"fieldtype": "Link",
"search_index": 1,
@ -300,7 +290,6 @@
{
"print_hide": 1,
"oldfieldtype": "Link",
"colour": "White:FFF",
"doctype": "DocField",
"label": "Territory",
"oldfieldname": "territory",
@ -373,12 +362,10 @@
{
"print_hide": 1,
"oldfieldtype": "Link",
"colour": "White:FFF",
"doctype": "DocField",
"label": "Company",
"oldfieldname": "company",
"permlevel": 0,
"trigger": "Client",
"fieldname": "company",
"fieldtype": "Link",
"search_index": 1,

View File

@ -85,25 +85,26 @@ $.extend(cur_frm.cscript, {
},
'Close Ticket': function() {
var doc = cur_frm.doc
if(doc.name)
$c_obj(make_doclist(doc.doctype, doc.name),'close_ticket','',function(r,rt) {
if(!r.exc) {
cur_frm.refresh();
}
});
cur_frm.cscript.set_status("Closed");
},
'Re-Open Ticket': function() {
var doc = cur_frm.doc
if(doc.name)
$c_obj(make_doclist(doc.doctype, doc.name),'reopen_ticket','',function(r,rt) {
if(!r.exc) {
cur_frm.refresh();
}
});
}
cur_frm.cscript.set_status("Open");
},
set_status: function(status) {
wn.call({
method:"support.doctype.support_ticket.support_ticket.set_status",
args: {
name: cur_frm.doc.name,
status: status
},
callback: function(r) {
if(!r.exc) cur_frm.reload_doc();
}
})
}
})

View File

@ -19,6 +19,7 @@ import webnotes
from utilities.transaction_base import TransactionBase
from home import update_feed
from webnotes.utils import now
class DocType(TransactionBase):
def __init__(self, doc, doclist=[]):
@ -40,6 +41,9 @@ class DocType(TransactionBase):
if signature:
content += '<p>' + signature + '</p>'
return content
def validate(self):
self.update_status()
def on_communication_sent(self, comm):
webnotes.conn.set(self.doc, 'status', 'Waiting for Customer')
@ -47,15 +51,23 @@ class DocType(TransactionBase):
webnotes.conn.set(self.doc, 'lead', comm.lead)
if comm.contact and not self.doc.contact:
webnotes.conn.set(self.doc, 'contact', comm.contact)
def close_ticket(self):
webnotes.conn.set(self.doc,'status','Closed')
update_feed(self)
def reopen_ticket(self):
webnotes.conn.set(self.doc,'status','Open')
update_feed(self)
def on_trash(self):
webnotes.conn.sql("""update `tabCommunication` set support_ticket=NULL
where support_ticket=%s""", (self.doc.name,))
def update_status(self):
status = webnotes.conn.get_value("Support Ticket", self.doc.name, "status")
if self.doc.status!="Open" and status =="Open":
self.doc.first_responded_on = now()
if self.doc.status=="Closed" and status !="Closed":
self.doc.resolution_date = now()
if self.doc.status=="Open" and status !="Open":
self.doc.resolution_date = ""
@webnotes.whitelist()
def set_status(name, status):
st = webnotes.model_wrapper("Support Ticket", name)
st.doc.status = status
st.save()

View File

@ -2,9 +2,9 @@
{
"owner": "Administrator",
"docstatus": 0,
"creation": "2012-11-02 17:17:05",
"creation": "2013-01-10 16:34:31",
"modified_by": "Administrator",
"modified": "2012-11-28 10:45:19"
"modified": "2013-01-14 14:15:37"
},
{
"autoname": "naming_series:",
@ -25,10 +25,11 @@
"name": "__common__",
"parent": "Support Ticket",
"amend": 0,
"submit": 0,
"doctype": "DocPerm",
"submit": 0,
"read": 1,
"parenttype": "DocType",
"report": 1,
"parentfield": "permissions"
},
{
@ -52,7 +53,6 @@
"permlevel": 1,
"no_copy": 1,
"oldfieldtype": "Select",
"colour": "White:FFF",
"doctype": "DocField",
"label": "Status",
"oldfieldname": "status",
@ -117,7 +117,6 @@
"permlevel": 1
},
{
"colour": "White:FFF",
"doctype": "DocField",
"label": "Additional Info",
"fieldname": "additional_info",
@ -152,12 +151,10 @@
{
"print_hide": 1,
"oldfieldtype": "Link",
"colour": "White:FFF",
"doctype": "DocField",
"label": "Customer",
"oldfieldname": "customer",
"permlevel": 1,
"trigger": "Client",
"fieldname": "customer",
"fieldtype": "Link",
"search_index": 1,
@ -218,31 +215,26 @@
"permlevel": 1
},
{
"depends_on": "eval:!doc.__islocal",
"doctype": "DocField",
"label": "First Responded On",
"fieldname": "first_responded_on",
"fieldtype": "Datetime",
"permlevel": 0
},
{
"no_copy": 1,
"search_index": 0,
"colour": "White:FFF",
"depends_on": "eval:!doc.__islocal",
"doctype": "DocField",
"label": "Resolution Date",
"oldfieldname": "resolution_date",
"fieldname": "resolution_date",
"fieldtype": "Date",
"fieldtype": "Datetime",
"search_index": 0,
"oldfieldtype": "Date",
"permlevel": 1,
"in_filter": 0
},
{
"oldfieldtype": "Time",
"doctype": "DocField",
"label": "Resolution Time",
"oldfieldname": "resolution_time",
"fieldname": "resolution_time",
"fieldtype": "Time",
"depends_on": "eval:!doc.__islocal",
"permlevel": 1
},
{
"colour": "White:FFF",
"doctype": "DocField",
"label": "Content Type",
"fieldname": "content_type",

View File

@ -53,8 +53,12 @@ erpnext.SupportAnalytics = wn.views.GridReportWithPlot.extend({
checked:true};
var days_to_close = {status:"Days to Close", "id":"days-to-close",
checked:false};
var total_closed = {};
var hours_to_close = {status:"Hours to Close", "id":"hours-to-close",
checked:false};
var hours_to_respond = {status:"Hours to Respond", "id":"hours-to-respond",
checked:false};
var total_responded = {};
$.each(wn.report_dump.data["Support Ticket"], function(i, d) {
@ -62,25 +66,40 @@ erpnext.SupportAnalytics = wn.views.GridReportWithPlot.extend({
var date = d.creation.split(" ")[0];
var col = me.column_map[date];
if(col) {
// just count
var day_diff = dateutil.get_diff(d.modified, d.creation);
var hour_diff = dateutil.get_hour_diff(d.modified, d.creation);
total_tickets[col.field] = flt(total_tickets[col.field]) + 1;
days_to_close[col.field] = flt(days_to_close[col.field]) + day_diff;
hours_to_close[col.field] = flt(hours_to_close[col.field]) + hour_diff;
if(d.status=="Closed") {
// just count
total_closed[col.field] = flt(total_closed[col.field]) + 1;
days_to_close[col.field] = flt(days_to_close[col.field])
+ dateutil.get_diff(d.resolution_date, d.creation);
hours_to_close[col.field] = flt(hours_to_close[col.field])
+ dateutil.get_hour_diff(d.resolution_date, d.creation);
}
if (d.first_responded_on) {
total_responded[col.field] = flt(total_responded[col.field]) + 1;
hours_to_respond[col.field] = flt(hours_to_respond[col.field])
+ dateutil.get_hour_diff(d.first_responded_on, d.creation);
}
}
});
// make averages
$.each(this.columns, function(i, col) {
if(col.formatter==me.currency_formatter && total_tickets[col.field]) {
days_to_close[col.field] = flt(days_to_close[col.field]) / flt(total_tickets[col.field]);
hours_to_close[col.field] = flt(hours_to_close[col.field]) / flt(total_tickets[col.field]);
days_to_close[col.field] = flt(days_to_close[col.field]) /
flt(total_closed[col.field]);
hours_to_close[col.field] = flt(hours_to_close[col.field]) /
flt(total_closed[col.field]);
hours_to_respond[col.field] = flt(hours_to_respond[col.field]) /
flt(total_responded[col.field]);
}
})
this.data = [total_tickets, days_to_close, hours_to_close];
this.data = [total_tickets, days_to_close, hours_to_close, hours_to_respond];
},
get_plot_points: function(item, col, idx) {