Merge pull request #5748 from rohitwaghchaure/v7_timesheet_issue

[WIP] Timesheet overlap issue and fields rearranged
diff --git a/erpnext/hr/doctype/salary_structure/salary_structure.js b/erpnext/hr/doctype/salary_structure/salary_structure.js
index 10b7544..fab7ac4 100755
--- a/erpnext/hr/doctype/salary_structure/salary_structure.js
+++ b/erpnext/hr/doctype/salary_structure/salary_structure.js
@@ -32,8 +32,8 @@
 	},
 
 	toggle_fields: function(frm) {
-		frm.toggle_display('time_sheet_earning_detail', frm.doc.salary_slip_based_on_timesheet);
-		frm.toggle_reqd('salary_component', frm.doc.salary_slip_based_on_timesheet);
+		frm.toggle_display(['salary_component', 'hour_rate'], frm.doc.salary_slip_based_on_timesheet);
+		frm.toggle_reqd(['salary_component', 'hour_rate'], frm.doc.salary_slip_based_on_timesheet);
 	}
 })
 
diff --git a/erpnext/hr/doctype/salary_structure/salary_structure.json b/erpnext/hr/doctype/salary_structure/salary_structure.json
index 08b0355..4cdc67b 100644
--- a/erpnext/hr/doctype/salary_structure/salary_structure.json
+++ b/erpnext/hr/doctype/salary_structure/salary_structure.json
@@ -8,6 +8,7 @@
  "docstatus": 0, 
  "doctype": "DocType", 
  "document_type": "Document", 
+ "editable_grid": 0, 
  "fields": [
   {
    "allow_on_submit": 0, 
@@ -353,6 +354,31 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "fieldname": "time_sheet_earning_detail", 
+   "fieldtype": "Section Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
    "depends_on": "", 
    "fieldname": "salary_slip_based_on_timesheet", 
    "fieldtype": "Check", 
@@ -379,14 +405,13 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "fieldname": "time_sheet_earning_detail", 
-   "fieldtype": "Section Break", 
+   "fieldname": "column_break_17", 
+   "fieldtype": "Column Break", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
-   "label": "", 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
@@ -432,30 +457,6 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "fieldname": "column_break_17", 
-   "fieldtype": "Column Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_list_view": 0, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
    "depends_on": "", 
    "fieldname": "hour_rate", 
    "fieldtype": "Currency", 
@@ -779,7 +780,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2016-07-02 18:04:06.529332", 
+ "modified": "2016-07-13 23:56:01.550518", 
  "modified_by": "Administrator", 
  "module": "HR", 
  "name": "Salary Structure", 
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 83519e6..979c1a5 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -291,4 +291,5 @@
 erpnext.patches.v7_0.rename_prevdoc_fields
 erpnext.patches.v7_0.rename_time_sheet_doctype
 execute:frappe.delete_doc_if_exists("Report", "Customers Not Buying Since Long Time")
-erpnext.patches.v7_0.make_is_group_fieldtype_as_check
\ No newline at end of file
+erpnext.patches.v7_0.make_is_group_fieldtype_as_check
+execute:frappe.reload_doc('projects', 'doctype', 'timesheet', force=True)
diff --git a/erpnext/projects/doctype/timesheet/test_timesheet.py b/erpnext/projects/doctype/timesheet/test_timesheet.py
index 281414b..300933a 100644
--- a/erpnext/projects/doctype/timesheet/test_timesheet.py
+++ b/erpnext/projects/doctype/timesheet/test_timesheet.py
@@ -86,28 +86,30 @@
 
 	return salary_structure
 
-def make_timesheet(employee, simulate=False, billable = 0):
-	update_activity_type("_Test Activity Type")
+def make_timesheet(employee, simulate=False, billable = 0, activity_type="_Test Activity Type", project=None, task=None):
+	update_activity_type(activity_type)
 	timesheet = frappe.new_doc("Timesheet")
 	timesheet.employee = employee
 	timesheet_detail = timesheet.append('time_logs', {})
 	timesheet_detail.billable = billable
-	timesheet_detail.activity_type = "_Test Activity Type"
+	timesheet_detail.activity_type = activity_type
 	timesheet_detail.from_time = now_datetime()
 	timesheet_detail.hours = 2
 	timesheet_detail.to_time = timesheet_detail.from_time + datetime.timedelta(hours= timesheet_detail.hours)
+	timesheet_detail.project = project
+	timesheet_detail.task = task
 
 	for data in timesheet.get('time_logs'):
 		if simulate:
 			while True:
 				try:
-					timesheet.save()
+					timesheet.save(ignore_permissions=True)
 					break
 				except OverlapError:
 					data.from_time = data.from_time + datetime.timedelta(minutes=10)
 					data.to_time = data.from_time + datetime.timedelta(hours= data.hours)
 		else:
-			timesheet.save()
+			timesheet.save(ignore_permissions=True)
 
 	timesheet.submit()
 
diff --git a/erpnext/projects/doctype/timesheet/timesheet.js b/erpnext/projects/doctype/timesheet/timesheet.js
index dfd7abe..4d16295 100644
--- a/erpnext/projects/doctype/timesheet/timesheet.js
+++ b/erpnext/projects/doctype/timesheet/timesheet.js
@@ -1,5 +1,6 @@
 // Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
 // License: GNU General Public License v3. See license.txt
+cur_frm.add_fetch('employee', 'employee_name', 'employee_name');
 
 frappe.ui.form.on("Timesheet", {
 	setup: function(frm) {
diff --git a/erpnext/projects/doctype/timesheet/timesheet.json b/erpnext/projects/doctype/timesheet/timesheet.json
index ac6093e..a15522b 100644
--- a/erpnext/projects/doctype/timesheet/timesheet.json
+++ b/erpnext/projects/doctype/timesheet/timesheet.json
@@ -225,8 +225,9 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "depends_on": "employee", 
    "fieldname": "employee_name", 
-   "fieldtype": "Read Only", 
+   "fieldtype": "Data", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -235,12 +236,12 @@
    "label": "Employee Name", 
    "length": 0, 
    "no_copy": 0, 
-   "options": "employee.employee_name", 
+   "options": "", 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 1, 
    "print_hide_if_no_value": 0, 
-   "read_only": 0, 
+   "read_only": 1, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 0, 
@@ -636,7 +637,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2016-07-13 01:18:57.918882", 
+ "modified": "2016-07-13 23:44:05.086570", 
  "modified_by": "Administrator", 
  "module": "Projects", 
  "name": "Timesheet", 
@@ -661,6 +662,66 @@
    "share": 1, 
    "submit": 1, 
    "write": 1
+  }, 
+  {
+   "amend": 1, 
+   "apply_user_permissions": 0, 
+   "cancel": 1, 
+   "create": 1, 
+   "delete": 1, 
+   "email": 1, 
+   "export": 1, 
+   "if_owner": 0, 
+   "import": 0, 
+   "permlevel": 0, 
+   "print": 1, 
+   "read": 1, 
+   "report": 1, 
+   "role": "HR User", 
+   "set_user_permissions": 0, 
+   "share": 1, 
+   "submit": 1, 
+   "write": 1
+  }, 
+  {
+   "amend": 1, 
+   "apply_user_permissions": 0, 
+   "cancel": 1, 
+   "create": 1, 
+   "delete": 1, 
+   "email": 1, 
+   "export": 1, 
+   "if_owner": 0, 
+   "import": 0, 
+   "permlevel": 0, 
+   "print": 1, 
+   "read": 1, 
+   "report": 1, 
+   "role": "Manufacturing User", 
+   "set_user_permissions": 0, 
+   "share": 1, 
+   "submit": 1, 
+   "write": 1
+  }, 
+  {
+   "amend": 0, 
+   "apply_user_permissions": 0, 
+   "cancel": 0, 
+   "create": 1, 
+   "delete": 0, 
+   "email": 0, 
+   "export": 0, 
+   "if_owner": 0, 
+   "import": 0, 
+   "permlevel": 0, 
+   "print": 0, 
+   "read": 1, 
+   "report": 0, 
+   "role": "Employee", 
+   "set_user_permissions": 0, 
+   "share": 0, 
+   "submit": 0, 
+   "write": 1
   }
  ], 
  "quick_entry": 0, 
diff --git a/erpnext/projects/doctype/timesheet/timesheet.py b/erpnext/projects/doctype/timesheet/timesheet.py
index 24a3796..686f7c2 100644
--- a/erpnext/projects/doctype/timesheet/timesheet.py
+++ b/erpnext/projects/doctype/timesheet/timesheet.py
@@ -141,31 +141,34 @@
 
 	def validate_overlap(self, data):
 		if self.production_order:
-			self.validate_overlap_for("workstation", data)
+			self.validate_overlap_for("workstation", data, data.workstation)
 		else:
-			self.validate_overlap_for("user", data)
-			self.validate_overlap_for("employee", data)
+			self.validate_overlap_for("user", data, self.user)
+			self.validate_overlap_for("employee", data, self.employee)
 
-	def validate_overlap_for(self, fieldname, args):
-		existing = self.get_overlap_for(fieldname, args)
+	def validate_overlap_for(self, fieldname, args, value):
+		if not value: return
+
+		existing = self.get_overlap_for(fieldname, args, value)
 		if existing:
 			frappe.throw(_("Row {0}: From Time and To Time overlap with existing from and to time").format(args.idx),
 				OverlapError)
 
-	def get_overlap_for(self, fieldname, args):
-		if not args.get(fieldname):
-			return
+	def get_overlap_for(self, fieldname, args, value):
+		cond = "ts.`{0}`".format(fieldname)
+		if fieldname == 'workstation':
+			cond = "tsd.`{0}`".format(fieldname)
 
 		existing = frappe.db.sql("""select ts.name as name, tsd.from_time as from_time, tsd.to_time as to_time from 
-			`tabTimesheet Detail` tsd, `tabTimesheet` ts where tsd.`{0}`=%(val)s and tsd.parent = ts.name and
+			`tabTimesheet Detail` tsd, `tabTimesheet` ts where {0}=%(val)s and tsd.parent = ts.name and
 			(
 				(%(from_time)s > tsd.from_time and %(from_time)s < tsd.to_time) or
 				(%(to_time)s > tsd.from_time and %(to_time)s < tsd.to_time) or
 				(%(from_time)s <= tsd.from_time and %(to_time)s >= tsd.to_time))
 			and tsd.name!=%(name)s
-			and ts.docstatus < 2""".format(fieldname),
+			and ts.docstatus < 2""".format(cond),
 			{
-				"val": args.get(fieldname),
+				"val": value,
 				"from_time": args.from_time,
 				"to_time": args.to_time,
 				"name": args.name or "No Name"
@@ -184,7 +187,7 @@
 		if self.time_logs:
 			for data in self.time_logs:
 				if data.idx == index:
-					overlapping = self.get_overlap_for("workstation", data)
+					overlapping = self.get_overlap_for("workstation", data, data.workstation)
 					if not overlapping:
 						frappe.throw(_("Logical error: Must find overlapping"))