Merge pull request #3972 from nabinhait/fix

Item Price Fix
diff --git a/erpnext/change_log/current/calendar_for_sales_order.md b/erpnext/change_log/current/calendar_for_sales_order.md
new file mode 100644
index 0000000..0b244c8
--- /dev/null
+++ b/erpnext/change_log/current/calendar_for_sales_order.md
@@ -0,0 +1 @@
+- Added Calendar and Gantt Views for Sales Order based on Delivery Date
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index 7a6a535..80abe0d 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -51,7 +51,7 @@
 
 email_append_to = ["Job Applicant", "Opportunity", "Issue"]
 
-calendars = ["Task", "Production Order", "Time Log", "Leave Application"]
+calendars = ["Task", "Production Order", "Time Log", "Leave Application", "Sales Order"]
 
 website_generators = ["Item Group", "Item", "Sales Partner"]
 
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.py b/erpnext/manufacturing/doctype/production_order/production_order.py
index 6299736..19746fc 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.py
+++ b/erpnext/manufacturing/doctype/production_order/production_order.py
@@ -329,15 +329,15 @@
 			frappe.throw(_("Production Order cannot be raised against a Item Template"), ItemHasVariantError)
 
 		validate_end_of_life(self.production_item)
-		
+
 	def validate_qty(self):
 		if not self.qty > 0:
 			frappe.throw(_("Quantity to Manufacture must be greater than 0."))
-			
+
 	def validate_operation_time(self):
 		for d in self.operations:
 			if not d.time_in_mins > 0:
-				frappe.throw(_("Operation Time must be greater than 0 for Operation {0}".format(d.operation))) 
+				frappe.throw(_("Operation Time must be greater than 0 for Operation {0}".format(d.operation)))
 
 @frappe.whitelist()
 def get_item_details(item):
@@ -381,19 +381,17 @@
 
 @frappe.whitelist()
 def get_events(start, end, filters=None):
-	from frappe.desk.reportview import build_match_conditions
-	if not frappe.has_permission("Production Order"):
-		frappe.msgprint(_("No Permission"), raise_exception=1)
+	"""Returns events for Gantt / Calendar view rendering.
 
-	conditions = build_match_conditions("Production Order")
-	conditions = conditions and (" and " + conditions) or ""
-	if filters:
-		filters = json.loads(filters)
-		for key in filters:
-			if filters[key]:
-				conditions += " and " + key + ' = "' + filters[key].replace('"', '\"') + '"'
+	:param start: Start date-time.
+	:param end: End date-time.
+	:param filters: Filters (JSON).
+	"""
+	from frappe.desk.calendar import get_event_conditions
+	conditions = get_event_conditions("Production Order", filters)
 
-	data = frappe.db.sql("""select name, production_item, planned_start_date, planned_end_date
+	data = frappe.db.sql("""select name, production_item, planned_start_date,
+		planned_end_date, status
 		from `tabProduction Order`
 		where ((ifnull(planned_start_date, '0000-00-00')!= '0000-00-00') \
 				and (planned_start_date between %(start)s and %(end)s) \
@@ -427,4 +425,4 @@
 def get_default_warehouse():
 	wip_warehouse = frappe.db.get_single_value("Manufacturing Settings", "default_wip_warehouse")
 	fg_warehouse = frappe.db.get_single_value("Manufacturing Settings", "default_fg_warehouse")
-	return {"wip_warehouse": wip_warehouse, "fg_warehouse": fg_warehouse}
\ No newline at end of file
+	return {"wip_warehouse": wip_warehouse, "fg_warehouse": fg_warehouse}
diff --git a/erpnext/manufacturing/doctype/production_order/production_order_calendar.js b/erpnext/manufacturing/doctype/production_order/production_order_calendar.js
index a43b25e..2832494 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order_calendar.js
+++ b/erpnext/manufacturing/doctype/production_order/production_order_calendar.js
@@ -10,6 +10,15 @@
 		"allDay": "allDay"
 	},
 	gantt: true,
+	get_css_class: function(data) {
+		if(data.status==="Completed") {
+			return "success";
+		} else if(data.status==="In Process") {
+			return "warning";
+		} else {
+			return "danger";
+		}
+	},
 	filters: [
 		{
 			"fieldtype": "Link",
diff --git a/erpnext/projects/doctype/task/task.py b/erpnext/projects/doctype/task/task.py
index fcd756b..28cfcd3 100644
--- a/erpnext/projects/doctype/task/task.py
+++ b/erpnext/projects/doctype/task/task.py
@@ -42,7 +42,7 @@
 			for d in self.depends_on:
 				if frappe.db.get_value("Task", d.task, "status") != "Closed":
 					frappe.throw(_("Cannot close task as its dependant task {0} is not closed.").format(d.task))
-			
+
 			from frappe.desk.form.assign_to import clear
 			clear(self.doctype, self.name)
 
@@ -107,18 +107,14 @@
 
 @frappe.whitelist()
 def get_events(start, end, filters=None):
-	from frappe.desk.reportview import build_match_conditions
-	if not frappe.has_permission("Task"):
-		frappe.msgprint(_("No Permission"), raise_exception=1)
+	"""Returns events for Gantt / Calendar view rendering.
 
-	conditions = build_match_conditions("Task")
-	conditions = conditions and (" and " + conditions) or ""
-
-	if filters:
-		filters = json.loads(filters)
-		for key in filters:
-			if filters[key]:
-				conditions += " and " + key + ' = "' + filters[key].replace('"', '\"') + '"'
+	:param start: Start date-time.
+	:param end: End date-time.
+	:param filters: Filters (JSON).
+	"""
+	from frappe.desk.calendar import get_event_conditions
+	conditions = get_event_conditions("Task", filters)
 
 	data = frappe.db.sql("""select name, exp_start_date, exp_end_date,
 		subject, status, project from `tabTask`
diff --git a/erpnext/projects/doctype/time_log/time_log.py b/erpnext/projects/doctype/time_log/time_log.py
index 6e937c0..ed89307 100644
--- a/erpnext/projects/doctype/time_log/time_log.py
+++ b/erpnext/projects/doctype/time_log/time_log.py
@@ -2,7 +2,7 @@
 # License: GNU General Public License v3. See license.txt
 
 from __future__ import unicode_literals
-import frappe, json
+import frappe
 from frappe import _
 from frappe.utils import cstr, flt, get_datetime, get_time, getdate
 from dateutil.relativedelta import relativedelta
@@ -248,17 +248,8 @@
 	:param end: End date-time.
 	:param filters: Filters like workstation, project etc.
 	"""
-	from frappe.desk.reportview import build_match_conditions
-	if not frappe.has_permission("Time Log"):
-		frappe.msgprint(_("No Permission"), raise_exception=1)
-
-	conditions = build_match_conditions("Time Log")
-	conditions = conditions and (" and " + conditions) or ""
-	if filters:
-		filters = json.loads(filters)
-		for key in filters:
-			if filters[key]:
-				conditions += " and " + key + ' = "' + filters[key].replace('"', '\"') + '"'
+	from frappe.desk.calendar import get_event_conditions
+	conditions = get_event_conditions("Time Log", filters)
 
 	data = frappe.db.sql("""select name, from_time, to_time,
 		activity_type, task, project, production_order, workstation from `tabTime Log`
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 0b5eb37..065d329 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -471,3 +471,24 @@
 		}, target_doc)
 
 		return doclist
+
+@frappe.whitelist()
+def get_events(start, end, filters=None):
+	"""Returns events for Gantt / Calendar view rendering.
+
+	:param start: Start date-time.
+	:param end: End date-time.
+	:param filters: Filters (JSON).
+	"""
+	from frappe.desk.calendar import get_event_conditions
+	conditions = get_event_conditions("Sales Order", filters)
+
+	data = frappe.db.sql("""select name, customer_name, delivery_status, billing_status, delivery_date
+		from `tabSales Order`
+		where (ifnull(delivery_date, '0000-00-00')!= '0000-00-00') \
+				and (delivery_date between %(start)s and %(end)s) {conditions}
+		""".format(conditions=conditions), {
+			"start": start,
+			"end": end
+		}, as_dict=True, update={"allDay": 0})
+	return data
diff --git a/erpnext/selling/doctype/sales_order/sales_order_calendar.js b/erpnext/selling/doctype/sales_order/sales_order_calendar.js
new file mode 100644
index 0000000..8724daa
--- /dev/null
+++ b/erpnext/selling/doctype/sales_order/sales_order_calendar.js
@@ -0,0 +1,45 @@
+// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
+// License: GNU General Public License v3. See license.txt
+
+frappe.views.calendar["Sales Order"] = {
+	field_map: {
+		"start": "delivery_date",
+		"end": "delivery_date",
+		"id": "name",
+		"title": "customer_name",
+		"allDay": "allDay"
+	},
+	gantt: true,
+	filters: [
+		{
+			"fieldtype": "Link",
+			"fieldname": "customer",
+			"options": "Customer",
+			"label": __("Customer")
+		},
+		{
+			"fieldtype": "Select",
+			"fieldname": "delivery_status",
+			"options": "Not Delivered\nFully Delivered\nPartly Delivered\nClosed\nNot Applicable",
+			"label": __("Delivery Status")
+		},
+		{
+			"fieldtype": "Select",
+			"fieldname": "billing_status",
+			"options": "Not Billed\nFully Billed\nPartly Billed\nClosed",
+			"label": __("Billing Status")
+		},
+	],
+	get_events_method: "erpnext.selling.doctype.sales_order.sales_order.get_events",
+	get_css_class: function(data) {
+		if(data.status=="Stopped") {
+			return "";
+		} if(data.delivery_status=="Not Delivered") {
+			return "danger";
+		} else if(data.delivery_status=="Partly Delivered") {
+			return "warning";
+		} else if(data.delivery_status=="Fully Delivered") {
+			return "success";
+		}
+	}
+}