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
+
+
+
+
+