Production Analytics Query Report (#15673)

* Production Analytics Query Report

* Changes in production analytics report

* Updated json file and other changes
diff --git a/erpnext/manufacturing/report/production_analytics/__init__.py b/erpnext/manufacturing/report/production_analytics/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/manufacturing/report/production_analytics/__init__.py
diff --git a/erpnext/manufacturing/report/production_analytics/production_analytics.js b/erpnext/manufacturing/report/production_analytics/production_analytics.js
new file mode 100644
index 0000000..b7b8f05
--- /dev/null
+++ b/erpnext/manufacturing/report/production_analytics/production_analytics.js
@@ -0,0 +1,46 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+/* eslint-disable */
+
+frappe.query_reports["Production Analytics"] = {
+	"filters": [
+		{
+			fieldname: "company",
+			label: __("Company"),
+			fieldtype: "Link",
+			options: "Company",
+			default: frappe.defaults.get_user_default("Company"),
+			reqd: 1
+		},
+		{
+			fieldname: "from_date",
+			label: __("From Date"),
+			fieldtype: "Date",
+			default: frappe.defaults.get_user_default("year_start_date"),
+			reqd: 1
+		},
+		{
+			fieldname:"to_date",
+			label: __("To Date"),
+			fieldtype: "Date",
+			default: frappe.defaults.get_user_default("year_end_date"),
+			reqd: 1
+		},
+		{
+			fieldname: "range",
+			label: __("Range"),
+			fieldtype: "Select",
+			options: [
+				{ "value": "Weekly", "label": __("Weekly") },
+				{ "value": "Monthly", "label": __("Monthly") },
+				{ "value": "Quarterly", "label": __("Quarterly") },
+				{ "value": "Yearly", "label": __("Yearly") }
+			],
+			default: "Monthly",
+			reqd: 1
+		}
+	],
+	"formatter": function(value, row, column, data) {
+		return value;
+	}
+}
diff --git a/erpnext/manufacturing/report/production_analytics/production_analytics.json b/erpnext/manufacturing/report/production_analytics/production_analytics.json
new file mode 100644
index 0000000..023e0a8
--- /dev/null
+++ b/erpnext/manufacturing/report/production_analytics/production_analytics.json
@@ -0,0 +1,27 @@
+{
+ "add_total_row": 0, 
+ "creation": "2018-10-11 19:28:37.085066", 
+ "disabled": 0, 
+ "docstatus": 0, 
+ "doctype": "Report", 
+ "idx": 0, 
+ "is_standard": "Yes", 
+ "letter_head": "", 
+ "modified": "2018-10-11 19:28:37.085066", 
+ "modified_by": "Administrator", 
+ "module": "Manufacturing", 
+ "name": "Production Analytics", 
+ "owner": "Administrator", 
+ "prepared_report": 0, 
+ "ref_doctype": "Work Order", 
+ "report_name": "Production Analytics", 
+ "report_type": "Script Report", 
+ "roles": [
+  {
+   "role": "Manufacturing User"
+  }, 
+  {
+   "role": "Stock User"
+  }
+ ]
+}
\ No newline at end of file
diff --git a/erpnext/manufacturing/report/production_analytics/production_analytics.py b/erpnext/manufacturing/report/production_analytics/production_analytics.py
new file mode 100644
index 0000000..1dc821c
--- /dev/null
+++ b/erpnext/manufacturing/report/production_analytics/production_analytics.py
@@ -0,0 +1,162 @@
+# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe import _
+from frappe.utils import getdate
+from erpnext.selling.report.sales_analytics.sales_analytics import (get_period_date_ranges,get_period)
+
+def execute(filters=None):
+	columns = get_columns(filters)
+	data, chart = get_data(filters,columns)
+	return columns, data,None ,chart
+
+def get_columns(filters):
+
+	columns =[
+		{
+			"label": _("Status"),
+			"fieldname": "Status",
+			"fieldtype": "Data",
+			"width": 140
+		}]
+
+	ranges = get_period_date_ranges(period=filters["range"], year_start_date = filters["from_date"],year_end_date=filters["to_date"])
+
+	for dummy, end_date in ranges:
+
+		label = field_name = get_period(end_date,filters["range"])
+
+		columns.append(
+			{
+			"label": _(label),
+			"field_name":field_name,
+			"fieldtype": "Float",
+			"width": 120
+		},
+		)
+
+	return columns
+
+def get_data_list(filters,entry):
+
+	data_list = {
+		"All Work Orders" : {},
+		"Not Started" : {},
+		"Overdue" : {},
+		"Pending" : {},
+		"Completed" : {}
+	}
+
+	ranges = get_period_date_ranges(period=filters["range"], year_start_date = filters["from_date"],year_end_date=filters["to_date"])
+
+	for from_date,end_date in ranges:
+		period = get_period(end_date,filters["range"])
+		for d in entry:
+			if getdate(d.creation) <= getdate(from_date) or getdate(d.creation) <= getdate(end_date) :
+				data_list = update_data_list(data_list,"All Work Orders",period)
+
+				if d.status == 'Completed':
+					if getdate(d.actual_end_date) < getdate(from_date) or getdate(d.modified) < getdate(from_date):
+						data_list = update_data_list(data_list, "Completed",period)
+
+					elif getdate(d.actual_start_date) < getdate(from_date) :
+						data_list = update_data_list(data_list, "Pending", period)
+
+					elif getdate(d.planned_start_date) < getdate(from_date) :
+						data_list = update_data_list(data_list, "Overdue", period)
+						
+					else:
+						data_list = update_data_list(data_list, "Not Started", period)
+
+				elif d.status == 'In Process':
+					if getdate(d.actual_start_date) < getdate(from_date) :
+						data_list = update_data_list(data_list, "Pending", period)
+
+					elif getdate(d.planned_start_date) < getdate(from_date) :
+						data_list = update_data_list(data_list, "Overdue", period)
+
+					else:
+						data_list = update_data_list(data_list, "Not Started", period)
+
+				elif d.status == 'Not Started':
+					if getdate(d.planned_start_date) < getdate(from_date) :
+						data_list = update_data_list(data_list, "Overdue", period)
+
+					else:
+						data_list = update_data_list(data_list, "Not Started", period)
+	return data_list
+
+def update_data_list(data_list, status, period):
+	if data_list.get(status).get(period):
+		data_list[status][period] += 1
+	else:
+		data_list[status][period] = 1
+
+	return data_list
+
+def get_data(filters,columns):
+
+	data = []
+
+	entry = frappe.get_all("Work Order",
+		fields=["creation", "modified", "actual_start_date", "actual_end_date", "planned_start_date", "planned_end_date", "status"],
+		filters={"docstatus" : 1, "company" : filters["company"] })
+
+	data_list = get_data_list(filters,entry)
+
+	labels = ["All Work Orders", "Not Started", "Overdue", "Pending", "Completed"]
+
+	chart_data = get_chart_data(data_list,columns)
+
+	ranges = get_period_date_ranges(period=filters["range"], year_start_date = filters["from_date"],year_end_date=filters["to_date"])
+
+	for label in labels:
+		work = {}
+		work["Status"] = label
+		for dummy,end_date in ranges:
+			period = get_period(end_date,filters["range"])
+			if data_list.get(label).get(period):
+				work[period] = data_list.get(label).get(period)
+			else:
+				work[period] = 0.0
+		data.append(work)
+
+	return data, chart_data
+
+def get_chart_data(data_list,columns):
+
+	labels = [d.get("label") for d in columns[1:]]
+
+	all_data, not_start, overdue, pending, completed = [], [], [] , [], []
+	datasets = []
+
+	for d in labels:
+		all_data.append(data_list.get("All Work Orders").get(d))
+		not_start.append(data_list.get("Not Started").get(d))
+		overdue.append(data_list.get("Overdue").get(d))
+		pending.append(data_list.get("Pending").get(d))
+		completed.append(data_list.get("Completed").get(d))
+
+	datasets.append({'name':'All Work Orders', 'values': all_data})
+	datasets.append({'name':'Not Started', 'values': not_start})
+	datasets.append({'name':'Overdue', 'values': overdue})
+	datasets.append({'name':'Pending', 'values': pending})
+	datasets.append({'name':'Completed', 'values': completed})
+
+	chart = {
+		"data": {
+			'labels': labels,
+			'datasets':datasets
+		}
+	}
+
+	chart["type"] = "line"
+
+	return chart
+
+
+
+
+