merge
diff --git a/patches/january_2013/update_closed_on.py b/patches/january_2013/update_closed_on.py
new file mode 100644
index 0000000..138549a
--- /dev/null
+++ b/patches/january_2013/update_closed_on.py
@@ -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))
diff --git a/projects/doctype/task/task.py b/projects/doctype/task/task.py
index 83f8995..79fca9a 100644
--- a/projects/doctype/task/task.py
+++ b/projects/doctype/task/task.py
@@ -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 @@
 		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 @@
 		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()
+		
\ No newline at end of file
diff --git a/projects/doctype/task/task.txt b/projects/doctype/task/task.txt
index 9b8c2eb..e95c456 100644
--- a/projects/doctype/task/task.txt
+++ b/projects/doctype/task/task.txt
@@ -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"
@@ -192,14 +194,6 @@
   "fieldtype": "Date"
  }, 
  {
-  "oldfieldtype": "Data", 
-  "doctype": "DocField", 
-  "label": "Total Hours (Actual)", 
-  "oldfieldname": "act_total_hrs", 
-  "fieldname": "act_total_hrs", 
-  "fieldtype": "Data"
- }, 
- {
   "oldfieldtype": "Currency", 
   "doctype": "DocField", 
   "label": "Actual Budget", 
@@ -253,7 +247,6 @@
   "amend": 0, 
   "create": 0, 
   "doctype": "DocPerm", 
-  "submit": 0, 
   "cancel": 0, 
   "permlevel": 1
  }
diff --git a/public/js/utils.js b/public/js/utils.js
index 805f578..436c532 100644
--- a/public/js/utils.js
+++ b/public/js/utils.js
@@ -34,6 +34,7 @@
 		
 		var defaults = {
 			posting_date: wn.datetime.get_today(),
+			posting_time: wn.datetime.now_time()
 		}
 		
 		$.each(defaults, function(k, v) {
diff --git a/startup/report_data_map.py b/startup/report_data_map.py
index 41d6cb8..228a8ae 100644
--- a/startup/report_data_map.py
+++ b/startup/report_data_map.py
@@ -219,7 +219,7 @@
 	
 	# Support
 	"Support Ticket": {
-		"columns": ["name","status","creation","modified"],
+		"columns": ["name","status","creation","resolution_date","first_responded_on"],
 		"conditions": ["docstatus < 2"],
 		"order_by": "creation"
 	}
diff --git a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
index 9b73c6b..2b1af33 100644
--- a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
+++ b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
@@ -102,6 +102,4 @@
 	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'
 			
\ No newline at end of file
diff --git a/support/doctype/customer_issue/customer_issue.js b/support/doctype/customer_issue/customer_issue.js
index 835509f..523b240 100644
--- a/support/doctype/customer_issue/customer_issue.js
+++ b/support/doctype/customer_issue/customer_issue.js
@@ -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', '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
diff --git a/support/doctype/customer_issue/customer_issue.py b/support/doctype/customer_issue/customer_issue.py
index 0a08d82..af93f33 100644
--- a/support/doctype/customer_issue/customer_issue.py
+++ b/support/doctype/customer_issue/customer_issue.py
@@ -21,6 +21,7 @@
 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 @@
 		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))
diff --git a/support/doctype/customer_issue/customer_issue.txt b/support/doctype/customer_issue/customer_issue.txt
index 9225eb3..1b01803 100644
--- a/support/doctype/customer_issue/customer_issue.txt
+++ b/support/doctype/customer_issue/customer_issue.txt
@@ -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, 
diff --git a/support/doctype/support_ticket/support_ticket.js b/support/doctype/support_ticket/support_ticket.js
index 3484bf3..159dddd 100644
--- a/support/doctype/support_ticket/support_ticket.js
+++ b/support/doctype/support_ticket/support_ticket.js
@@ -85,25 +85,26 @@
 	}, 
 	
 	'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();
+			}
+		})
+		
+	}
 	
 })
 
diff --git a/support/doctype/support_ticket/support_ticket.py b/support/doctype/support_ticket/support_ticket.py
index 0f4a25e..43b8283 100644
--- a/support/doctype/support_ticket/support_ticket.py
+++ b/support/doctype/support_ticket/support_ticket.py
@@ -19,6 +19,7 @@
 
 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 @@
 		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 @@
 			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()
+	
diff --git a/support/doctype/support_ticket/support_ticket.txt b/support/doctype/support_ticket/support_ticket.txt
index b2bdadb..b475db5 100644
--- a/support/doctype/support_ticket/support_ticket.txt
+++ b/support/doctype/support_ticket/support_ticket.txt
@@ -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", 
diff --git a/support/page/support_analytics/support_analytics.js b/support/page/support_analytics/support_analytics.js
index e310df3..60384bb 100644
--- a/support/page/support_analytics/support_analytics.js
+++ b/support/page/support_analytics/support_analytics.js
@@ -53,8 +53,12 @@
 			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 @@
 			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) {