added onboarding for manufacturing
diff --git a/erpnext/manufacturing/dashboard_fixtures.py b/erpnext/manufacturing/dashboard_fixtures.py
new file mode 100644
index 0000000..de3775f
--- /dev/null
+++ b/erpnext/manufacturing/dashboard_fixtures.py
@@ -0,0 +1,216 @@
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+
+import frappe, erpnext, json
+from frappe import _
+
+def get_data():
+ return frappe._dict({
+ "dashboards": get_dashboards(),
+ "charts": get_charts(),
+ "number_cards": get_number_cards(),
+ })
+
+def get_dashboards():
+ return [{
+ "name": "Manufacturing Dashboard",
+ "dashboard_name": "Manufacturing Dashboard",
+ "charts": [
+ { "chart": "Produced Quantity", "width": "Half" },
+ { "chart": "Completed Operation", "width": "Half" },
+ { "chart": "Work Order Analysis", "width": "Half" },
+ { "chart": "Quality Inspection Analysis", "width": "Half" },
+ { "chart": "Pending Work Order", "width": "Half" },
+ { "chart": "Last Month Downtime Analysis", "width": "Half" },
+ { "chart": "Work Order Qty Analysis", "width": "Full" },
+ { "chart": "Job Card Analysis", "width": "Full" }
+ ],
+ "cards": [
+ { "card": "Total Work Order" },
+ { "card": "Completed Work Order" },
+ { "card": "Ongoing Job Card" },
+ { "card": "Total Quality Inspection"}
+ ]
+ }]
+
+def get_charts():
+ company = erpnext.get_default_company()
+
+ if not company:
+ company = frappe.db.get_value("Company", {"is_group": 0}, "name")
+
+ return [{
+ "doctype": "Dashboard Chart",
+ "based_on": "creation",
+ "time_interval": "Yearly",
+ "chart_type": "Sum",
+ "chart_name": "Produced Quantity",
+ "document_type": "Work Order",
+ "filters_json": json.dumps({}),
+ "group_by_type": "Count",
+ "time_interval": "Quarterly",
+ "timespan": "Last Year",
+ "owner": "Administrator",
+ "type": "Line",
+ "value_based_on": "qty",
+ "is_public": 1,
+ "timeseries": 1
+ }, {
+ "doctype": "Dashboard Chart",
+ "based_on": "creation",
+ "time_interval": "Yearly",
+ "chart_type": "Sum",
+ "chart_name": "Completed Operation",
+ "document_type": "Work Order Operation",
+ "filters_json": json.dumps({}),
+ "group_by_type": "Count",
+ "time_interval": "Quarterly",
+ "timespan": "Last Year",
+ "owner": "Administrator",
+ "type": "Line",
+ "value_based_on": "completed_qty",
+ "is_public": 1,
+ "timeseries": 1
+ }, {
+ "doctype": "Dashboard Chart",
+ "time_interval": "Yearly",
+ "chart_type": "Report",
+ "chart_name": "Work Order Analysis",
+ "timespan": "Last Year",
+ "report_name": "Work Order Summary",
+ "owner": "Administrator",
+ "filters_json": json.dumps({"company": company, "charts_based_on": "Status"}),
+ "type": "Donut",
+ "is_public": 1,
+ "is_custom": 1,
+ "custom_options": json.dumps({
+ "axisOptions": {
+ "shortenYAxisNumbers": 1
+ },
+ "height": 300
+ }),
+ }, {
+ "doctype": "Dashboard Chart",
+ "time_interval": "Yearly",
+ "chart_type": "Report",
+ "chart_name": "Quality Inspection Analysis",
+ "timespan": "Last Year",
+ "report_name": "Quality Inspection Summary",
+ "owner": "Administrator",
+ "filters_json": json.dumps({}),
+ "type": "Donut",
+ "is_public": 1,
+ "is_custom": 1,
+ "custom_options": json.dumps({
+ "axisOptions": {
+ "shortenYAxisNumbers": 1
+ },
+ "height": 300
+ }),
+ }, {
+ "doctype": "Dashboard Chart",
+ "time_interval": "Yearly",
+ "chart_type": "Report",
+ "chart_name": "Pending Work Order",
+ "timespan": "Last Year",
+ "report_name": "Work Order Summary",
+ "filters_json": json.dumps({"company": company, "charts_based_on": "Age"}),
+ "owner": "Administrator",
+ "type": "Donut",
+ "is_public": 1,
+ "is_custom": 1,
+ "custom_options": json.dumps({
+ "axisOptions": {
+ "shortenYAxisNumbers": 1
+ },
+ "height": 300
+ }),
+ }, {
+ "doctype": "Dashboard Chart",
+ "time_interval": "Yearly",
+ "chart_type": "Report",
+ "chart_name": "Last Month Downtime Analysis",
+ "timespan": "Last Year",
+ "filters_json": json.dumps({}),
+ "report_name": "Downtime Analysis",
+ "owner": "Administrator",
+ "is_public": 1,
+ "is_custom": 1,
+ "type": "Bar"
+ }, {
+ "doctype": "Dashboard Chart",
+ "time_interval": "Yearly",
+ "chart_type": "Report",
+ "chart_name": _("Work Order Qty Analysis"),
+ "timespan": "Last Year",
+ "report_name": "Work Order Summary",
+ "filters_json": json.dumps({"company": company, "charts_based_on": "Quantity"}),
+ "owner": "Administrator",
+ "type": "Bar",
+ "is_public": 1,
+ "is_custom": 1,
+ "custom_options": json.dumps({
+ "barOptions": { "stacked": 1 }
+ }),
+ }, {
+ "doctype": "Dashboard Chart",
+ "time_interval": "Yearly",
+ "chart_type": "Report",
+ "chart_name": "Job Card Analysis",
+ "timespan": "Last Year",
+ "report_name": "Job Card Summary",
+ "owner": "Administrator",
+ "is_public": 1,
+ "is_custom": 1,
+ "filters_json": json.dumps({"company": company, "range":"Monthly"}),
+ "custom_options": json.dumps({
+ "barOptions": { "stacked": 1 }
+ }),
+ "type": "Bar"
+ }]
+
+def get_number_cards():
+ return [{
+ "doctype": "Number Card",
+ "document_type": "Work Order",
+ "name": "Total Work Order",
+ "filters_json": json.dumps([]),
+ "function": "Count",
+ "is_public": 1,
+ "label": _("Total Work Order"),
+ "show_percentage_stats": 1,
+ "stats_time_interval": "Daily"
+ },
+ {
+ "doctype": "Number Card",
+ "document_type": "Work Order",
+ "name": "Completed Work Order",
+ "filters_json": json.dumps([['Work Order', 'status','=','Completed', False]]),
+ "function": "Count",
+ "is_public": 1,
+ "label": _("Completed Work Order"),
+ "show_percentage_stats": 1,
+ "stats_time_interval": "Daily"
+ },
+ {
+ "doctype": "Number Card",
+ "document_type": "Job Card",
+ "name": "Ongoing Job Card",
+ "filters_json": json.dumps([['Job Card', 'status','!=','Completed', False]]),
+ "function": "Count",
+ "is_public": 1,
+ "label": _("Ongoing Job Card"),
+ "show_percentage_stats": 1,
+ "stats_time_interval": "Daily"
+ },
+ {
+ "doctype": "Number Card",
+ "document_type": "Quality Inspection",
+ "name": "Total Quality Inspection",
+ "filters_json": json.dumps([]),
+ "function": "Count",
+ "is_public": 1,
+ "label": _("Total Quality Inspection"),
+ "show_percentage_stats": 1,
+ "stats_time_interval": "Daily"
+ }]
\ No newline at end of file
diff --git a/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json b/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json
index 0464b76..f6bbf3d 100644
--- a/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json
+++ b/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json
@@ -3,7 +3,7 @@
{
"hidden": 0,
"label": "Production",
- "links": "[\n {\n \"dependencies\": [\n \"Item\",\n \"BOM\"\n ],\n \"description\": \"Orders released for production.\",\n \"label\": \"Work Order\",\n \"name\": \"Work Order\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"BOM\"\n ],\n \"description\": \"Generate Material Requests (MRP) and Work Orders.\",\n \"label\": \"Production Plan\",\n \"name\": \"Production Plan\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Stock Entry\",\n \"name\": \"Stock Entry\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Job Card\",\n \"name\": \"Job Card\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Downtime Entry\",\n \"name\": \"Downtime Entry\",\n \"type\": \"doctype\"\n }\n]"
+ "links": "[\n {\n \"dependencies\": [\n \"Item\",\n \"BOM\"\n ],\n \"description\": \"Orders released for production.\",\n \"label\": \"Work Order\",\n \"name\": \"Work Order\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"BOM\"\n ],\n \"description\": \"Generate Material Requests (MRP) and Work Orders.\",\n \"label\": \"Production Plan\",\n \"name\": \"Production Plan\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Stock Entry\",\n \"name\": \"Stock Entry\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Activity Type\"\n ],\n \"description\": \"Time Sheet for manufacturing.\",\n \"label\": \"Timesheet\",\n \"name\": \"Timesheet\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Job Card\",\n \"name\": \"Job Card\",\n \"type\": \"doctype\"\n }\n]"
},
{
"hidden": 0,
@@ -13,7 +13,7 @@
{
"hidden": 0,
"label": "Reports",
- "links": "[\n {\n \"dependencies\": [\n \"Work Order\"\n ],\n \"doctype\": \"Work Order\",\n \"is_query_report\": true,\n \"label\": \"Work Order Summary\",\n \"name\": \"Work Order Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Work Order\"\n ],\n \"doctype\": \"Work Order\",\n \"is_query_report\": true,\n \"label\": \"Issued Items Against Work Order\",\n \"name\": \"Issued Items Against Work Order\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Work Order\"\n ],\n \"doctype\": \"Work Order\",\n \"is_query_report\": true,\n \"label\": \"Production Analytics\",\n \"name\": \"Production Analytics\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Quality Inspection\"\n ],\n \"doctype\": \"Quality Inspection\",\n \"is_query_report\": true,\n \"label\": \"Quality Inspection Summary\",\n \"name\": \"Quality Inspection Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Downtime Entry\"\n ],\n \"doctype\": \"Downtime Entry\",\n \"is_query_report\": true,\n \"label\": \"Downtime Analysis\",\n \"name\": \"Downtime Analysis\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Job Card\"\n ],\n \"doctype\": \"Job Card\",\n \"is_query_report\": true,\n \"label\": \"Job Card Summary\",\n \"name\": \"Job Card Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"BOM\"\n ],\n \"doctype\": \"BOM\",\n \"is_query_report\": true,\n \"label\": \"BOM Search\",\n \"name\": \"BOM Search\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"BOM\"\n ],\n \"doctype\": \"BOM\",\n \"is_query_report\": true,\n \"label\": \"BOM Stock Report\",\n \"name\": \"BOM Stock Report\",\n \"type\": \"report\"\n }\n]"
+ "links": "[{\n\t\"dependencies\": [\"Work Order\"],\n\t\"name\": \"Work Order Summary\",\n\t\"is_query_report\": true,\n\t\"type\": \"report\",\n\t\"doctype\": \"Work Order\",\n\t\"label\": \"Work Order Summary\"\n}, {\n\t\"dependencies\": [\"Work Order\"],\n\t\"name\": \"Production Analytics\",\n\t\"is_query_report\": true,\n\t\"type\": \"report\",\n\t\"doctype\": \"Work Order\",\n\t\"label\": \"Production Analytics\"\n}, {\n\t\"dependencies\": [\"Quality Inspection\"],\n\t\"name\": \"Quality Inspection Summary\",\n\t\"is_query_report\": true,\n\t\"type\": \"report\",\n\t\"doctype\": \"Quality Inspection\",\n\t\"label\": \"Quality Inspection Summary\"\n}, {\n\t\"dependencies\": [\"Downtime Entry\"],\n\t\"name\": \"Downtime Analysis\",\n\t\"is_query_report\": true,\n\t\"type\": \"report\",\n\t\"doctype\": \"Downtime Entry\",\n\t\"label\": \"Downtime Analysis\"\n}, {\n\t\"dependencies\": [\"Job Card\"],\n\t\"name\": \"Job Card Summary\",\n\t\"is_query_report\": true,\n\t\"type\": \"report\",\n\t\"doctype\": \"Job Card\",\n\t\"label\": \"Job Card Summary\"\n}, {\n\t\"dependencies\": [\"BOM\"],\n\t\"name\": \"BOM Search\",\n\t\"is_query_report\": true,\n\t\"type\": \"report\",\n\t\"doctype\": \"BOM\",\n\t\"label\": \"BOM Search\"\n}, {\n\t\"dependencies\": [\"BOM\"],\n\t\"name\": \"BOM Stock Report\",\n\t\"is_query_report\": true,\n\t\"type\": \"report\",\n\t\"doctype\": \"BOM\",\n\t\"label\": \"BOM Stock Report\"\n}]"
},
{
"hidden": 0,
@@ -32,12 +32,7 @@
}
],
"category": "Domains",
- "charts": [
- {
- "chart_name": "Production Analysis",
- "label": "Production Analysis"
- }
- ],
+ "charts": [],
"creation": "2020-03-02 17:11:37.032604",
"developer_mode_only": 0,
"disable_user_customization": 0,
@@ -47,29 +42,59 @@
"idx": 0,
"is_standard": 1,
"label": "Manufacturing",
- "modified": "2020-04-27 00:17:26.323677",
+ "modified": "2020-05-14 15:06:45.963942",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Manufacturing",
+ "onboarding": "Manufacturing",
"owner": "Administrator",
"pin_to_bottom": 0,
"pin_to_top": 0,
"restrict_to_domain": "Manufacturing",
"shortcuts": [
{
+ "format": "{} Active",
"label": "Item",
"link_to": "Item",
+ "restrict_to_domain": "Manufacturing",
+ "stats_filter": "{\n \"disabled\": 0\n}",
"type": "DocType"
},
{
+ "format": "{} Active",
"label": "BOM",
"link_to": "BOM",
+ "restrict_to_domain": "Manufacturing",
+ "stats_filter": "{\n \"is_active\": 1\n}",
"type": "DocType"
},
{
+ "format": "{} Open",
"label": "Work Order",
"link_to": "Work Order",
+ "restrict_to_domain": "Manufacturing",
+ "stats_filter": "{ \"status\": \n (\n \"in\", [\"Draft\", \"Not Started\", \"In Process\"]\n )\n}",
"type": "DocType"
+ },
+ {
+ "format": "{} Open",
+ "label": "Production Plan",
+ "link_to": "Production Plan",
+ "restrict_to_domain": "Manufacturing",
+ "stats_filter": "{ \"status\": \n (\n \"!=\", \"Completed\"\n )\n}",
+ "type": "DocType"
+ },
+ {
+ "label": "Work Order Summary",
+ "link_to": "Work Order Summary",
+ "restrict_to_domain": "Manufacturing",
+ "type": "Report"
+ },
+ {
+ "label": "BOM Stock Report",
+ "link_to": "BOM Stock Report",
+ "restrict_to_domain": "Manufacturing",
+ "type": "Report"
}
]
}
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/work_order/work_order.json b/erpnext/manufacturing/doctype/work_order/work_order.json
index 8be2287..585a09d 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order.json
+++ b/erpnext/manufacturing/doctype/work_order/work_order.json
@@ -496,7 +496,7 @@
"image_field": "image",
"is_submittable": 1,
"links": [],
- "modified": "2020-04-24 19:32:43.323054",
+ "modified": "2020-05-05 19:32:43.323054",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Work Order",
diff --git a/erpnext/manufacturing/onboarding/manufacturing/manufacturing.json b/erpnext/manufacturing/onboarding/manufacturing/manufacturing.json
new file mode 100644
index 0000000..50584e1
--- /dev/null
+++ b/erpnext/manufacturing/onboarding/manufacturing/manufacturing.json
@@ -0,0 +1,54 @@
+{
+ "allow_roles": [
+ {
+ "role": "Manufacturing User"
+ },
+ {
+ "role": "Manufacturing Manager"
+ },
+ {
+ "role": "Item Manager"
+ },
+ {
+ "role": "Stock User"
+ }
+ ],
+ "creation": "2020-05-05 16:37:08.238935",
+ "docstatus": 0,
+ "doctype": "Onboarding",
+ "documentation_url": "https://docs.erpnext.com/docs/user/manual/en/manufacturing",
+ "idx": 0,
+ "is_complete": 0,
+ "modified": "2020-05-12 16:22:07.050224",
+ "modified_by": "Administrator",
+ "module": "Manufacturing",
+ "name": "Manufacturing",
+ "owner": "Administrator",
+ "steps": [
+ {
+ "step": "Introduction to Manufacturing"
+ },
+ {
+ "step": "Warehouse"
+ },
+ {
+ "step": "Workstation"
+ },
+ {
+ "step": "Operation"
+ },
+ {
+ "step": "Create Product"
+ },
+ {
+ "step": "Create BOM"
+ },
+ {
+ "step": "Work Order"
+ }
+ ],
+ "subtitle": "Products, Raw Materials, BOM, Work Order and more.",
+ "success_message": "Manufacturing module is all setup!",
+ "title": "Let's Setup Manufacturing Module",
+ "user_can_dismiss": 1
+}
\ No newline at end of file
diff --git a/erpnext/manufacturing/onboarding_step/create_bom/create_bom.json b/erpnext/manufacturing/onboarding_step/create_bom/create_bom.json
new file mode 100644
index 0000000..969c2fa
--- /dev/null
+++ b/erpnext/manufacturing/onboarding_step/create_bom/create_bom.json
@@ -0,0 +1,16 @@
+{
+ "action": "Create Entry",
+ "creation": "2020-05-05 16:41:20.239696",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_mandatory": 1,
+ "is_skipped": 0,
+ "modified": "2020-05-05 16:41:20.239696",
+ "modified_by": "Administrator",
+ "name": "Create BOM",
+ "owner": "Administrator",
+ "reference_document": "BOM",
+ "title": "Create BOM"
+}
\ No newline at end of file
diff --git a/erpnext/manufacturing/onboarding_step/create_product/create_product.json b/erpnext/manufacturing/onboarding_step/create_product/create_product.json
new file mode 100644
index 0000000..082f31e
--- /dev/null
+++ b/erpnext/manufacturing/onboarding_step/create_product/create_product.json
@@ -0,0 +1,16 @@
+{
+ "action": "Create Entry",
+ "creation": "2020-05-05 16:42:31.476275",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_mandatory": 1,
+ "is_skipped": 0,
+ "modified": "2020-05-05 16:42:31.476275",
+ "modified_by": "Administrator",
+ "name": "Create Product",
+ "owner": "Administrator",
+ "reference_document": "Item",
+ "title": "Create Product"
+}
\ No newline at end of file
diff --git a/erpnext/manufacturing/onboarding_step/introduction_to_manufacturing/introduction_to_manufacturing.json b/erpnext/manufacturing/onboarding_step/introduction_to_manufacturing/introduction_to_manufacturing.json
new file mode 100644
index 0000000..6e5c3a9
--- /dev/null
+++ b/erpnext/manufacturing/onboarding_step/introduction_to_manufacturing/introduction_to_manufacturing.json
@@ -0,0 +1,17 @@
+{
+ "action": "Update Settings",
+ "creation": "2020-05-05 16:40:23.676406",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_mandatory": 0,
+ "is_skipped": 0,
+ "modified": "2020-05-05 16:40:23.676406",
+ "modified_by": "Administrator",
+ "name": "Introduction to Manufacturing",
+ "owner": "Administrator",
+ "reference_document": "Manufacturing Settings",
+ "title": "Manufacturing Settings",
+ "video_url": "https://www.youtube.com/watch?v=UVGfzwOOZC4"
+}
\ No newline at end of file
diff --git a/erpnext/manufacturing/onboarding_step/operation/operation.json b/erpnext/manufacturing/onboarding_step/operation/operation.json
new file mode 100644
index 0000000..6f84db1
--- /dev/null
+++ b/erpnext/manufacturing/onboarding_step/operation/operation.json
@@ -0,0 +1,15 @@
+{
+ "action": "Create Entry",
+ "creation": "2020-05-12 16:15:31.706756",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_mandatory": 0,
+ "is_skipped": 0,
+ "modified": "2020-05-12 16:17:06.943067",
+ "modified_by": "Administrator",
+ "name": "Operation",
+ "owner": "Administrator",
+ "title": "Create Operation"
+}
\ No newline at end of file
diff --git a/erpnext/manufacturing/onboarding_step/warehouse/warehouse.json b/erpnext/manufacturing/onboarding_step/warehouse/warehouse.json
new file mode 100644
index 0000000..36f5204
--- /dev/null
+++ b/erpnext/manufacturing/onboarding_step/warehouse/warehouse.json
@@ -0,0 +1,15 @@
+{
+ "action": "Create Entry",
+ "creation": "2020-05-12 16:13:34.014554",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_mandatory": 0,
+ "is_skipped": 0,
+ "modified": "2020-05-12 16:16:48.345846",
+ "modified_by": "Administrator",
+ "name": "Warehouse",
+ "owner": "Administrator",
+ "title": "Create Warehouse"
+}
\ No newline at end of file
diff --git a/erpnext/manufacturing/onboarding_step/work_order/work_order.json b/erpnext/manufacturing/onboarding_step/work_order/work_order.json
new file mode 100644
index 0000000..57e4e7b
--- /dev/null
+++ b/erpnext/manufacturing/onboarding_step/work_order/work_order.json
@@ -0,0 +1,15 @@
+{
+ "action": "Create Entry",
+ "creation": "2020-05-12 16:15:56.084682",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_mandatory": 0,
+ "is_skipped": 0,
+ "modified": "2020-05-12 16:17:33.675304",
+ "modified_by": "Administrator",
+ "name": "Work Order",
+ "owner": "Administrator",
+ "title": "Create Work Order"
+}
\ No newline at end of file
diff --git a/erpnext/manufacturing/onboarding_step/workstation/workstation.json b/erpnext/manufacturing/onboarding_step/workstation/workstation.json
new file mode 100644
index 0000000..6c1a069
--- /dev/null
+++ b/erpnext/manufacturing/onboarding_step/workstation/workstation.json
@@ -0,0 +1,15 @@
+{
+ "action": "Create Entry",
+ "creation": "2020-05-12 16:14:14.930214",
+ "docstatus": 0,
+ "doctype": "Onboarding Step",
+ "idx": 0,
+ "is_complete": 0,
+ "is_mandatory": 0,
+ "is_skipped": 0,
+ "modified": "2020-05-12 16:16:58.808906",
+ "modified_by": "Administrator",
+ "name": "Workstation",
+ "owner": "Administrator",
+ "title": "Create Workstation"
+}
\ No newline at end of file
diff --git a/erpnext/manufacturing/report/downtime_analysis/downtime_analysis.py b/erpnext/manufacturing/report/downtime_analysis/downtime_analysis.py
index d69ec18..dfc6b02 100644
--- a/erpnext/manufacturing/report/downtime_analysis/downtime_analysis.py
+++ b/erpnext/manufacturing/report/downtime_analysis/downtime_analysis.py
@@ -47,8 +47,7 @@
{"name": "Dataset 1", "values": datasets}
]
},
- "type": "bar",
- "colors": ["#ff5858"]
+ "type": "bar"
}
return chart
diff --git a/erpnext/manufacturing/report/job_card_summary/job_card_summary.py b/erpnext/manufacturing/report/job_card_summary/job_card_summary.py
index 0f60c13..ae1e4f3 100644
--- a/erpnext/manufacturing/report/job_card_summary/job_card_summary.py
+++ b/erpnext/manufacturing/report/job_card_summary/job_card_summary.py
@@ -49,33 +49,22 @@
def get_chart_data(job_card_details, filters):
labels, periodic_data = prepare_chart_data(job_card_details, filters)
- not_start, in_progress, on_hold, completed = [], [], [] , []
+ pending, completed = [], []
datasets = []
for d in labels:
- not_start.append(periodic_data.get("Open").get(d))
- in_progress.append(periodic_data.get("Work In Progress").get(d))
- on_hold.append(periodic_data.get("On Hold").get(d))
+ pending.append(periodic_data.get("Pending").get(d))
completed.append(periodic_data.get("Completed").get(d))
- datasets.append({'name':'Open', 'values': not_start})
- datasets.append({'name':'Work In Progress', 'values': in_progress})
- datasets.append({'name':'On Hold', 'values': on_hold})
- datasets.append({'name':'Completed', 'values': completed})
+ datasets.append({"name": "Pending", "values": pending})
+ datasets.append({"name": "Completed", "values": completed})
chart = {
"data": {
'labels': labels,
'datasets': datasets
},
- "type": "bar",
- "colors": ["#ff5858", "#ffa00a", "#5e64ff", "#98d85b"],
- "axisOptions": {
- "xAxisMode": "tick"
- },
- "barOptions": {
- "stacked": 1
- }
+ "type": "bar"
}
return chart
@@ -84,9 +73,7 @@
labels = []
periodic_data = {
- "Open": {},
- "Work In Progress": {},
- "On Hold": {},
+ "Pending": {},
"Completed": {}
}
@@ -100,10 +87,12 @@
for d in job_card_details:
if getdate(d.from_time) >= from_date and getdate(d.to_time) <= end_date:
- if periodic_data.get(d.status) and periodic_data.get(d.status).get(period):
- periodic_data[d.status][period] += 1
+ status = "Completed" if d.status == "Completed" else "Pending"
+
+ if periodic_data.get(status) and periodic_data.get(status).get(period):
+ periodic_data[status][period] += 1
else:
- periodic_data[d.status][period] = 1
+ periodic_data[status][period] = 1
return labels, periodic_data
diff --git a/erpnext/manufacturing/report/production_analytics/production_analytics.py b/erpnext/manufacturing/report/production_analytics/production_analytics.py
index f0bdfed..f62cd25 100644
--- a/erpnext/manufacturing/report/production_analytics/production_analytics.py
+++ b/erpnext/manufacturing/report/production_analytics/production_analytics.py
@@ -38,6 +38,7 @@
def get_periodic_data(filters, entry):
periodic_data = {
+ "All Work Orders": {},
"Not Started": {},
"Overdue": {},
"Pending": {},
@@ -50,6 +51,7 @@
period = get_period(end_date, filters)
for d in entry:
if getdate(d.creation) <= getdate(from_date) or getdate(d.creation) <= getdate(end_date) :
+ periodic_data = update_periodic_data(periodic_data, "All Work Orders", period)
if d.status == 'Completed':
if getdate(d.actual_end_date) < getdate(from_date) or getdate(d.modified) < getdate(from_date):
periodic_data = update_periodic_data(periodic_data, "Completed", period)
@@ -97,7 +99,7 @@
periodic_data = get_periodic_data(filters,entry)
- labels = ["Not Started", "Overdue", "Pending", "Completed"]
+ labels = ["All Work Orders", "Not Started", "Overdue", "Pending", "Completed"]
chart_data = get_chart_data(periodic_data,columns)
ranges = get_period_date_ranges(filters)
@@ -121,11 +123,13 @@
datasets = []
for d in labels:
+ all_data.append(periodic_data.get("All Work Orders").get(d))
not_start.append(periodic_data.get("Not Started").get(d))
overdue.append(periodic_data.get("Overdue").get(d))
pending.append(periodic_data.get("Pending").get(d))
completed.append(periodic_data.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})
@@ -135,14 +139,12 @@
"data": {
'labels': labels,
'datasets': datasets
- },
- "type": "bar",
- "colors": ["#5e64ff", "#ff5858", "#ffa00a", "#98d85b"]
+ }
}
+ chart["type"] = "line"
return chart
-
diff --git a/erpnext/manufacturing/report/quality_inspection_summary/quality_inspection_summary.py b/erpnext/manufacturing/report/quality_inspection_summary/quality_inspection_summary.py
index 9c1bfa4..6192632 100644
--- a/erpnext/manufacturing/report/quality_inspection_summary/quality_inspection_summary.py
+++ b/erpnext/manufacturing/report/quality_inspection_summary/quality_inspection_summary.py
@@ -50,8 +50,7 @@
'datasets': datasets
},
"type": "donut",
- "height": 300,
- "colors": ["#ff5858", "#98d85b"]
+ "height": 300
}
return chart
diff --git a/erpnext/manufacturing/report/work_order_summary/work_order_summary.js b/erpnext/manufacturing/report/work_order_summary/work_order_summary.js
index 33b147d..ec9fe35 100644
--- a/erpnext/manufacturing/report/work_order_summary/work_order_summary.js
+++ b/erpnext/manufacturing/report/work_order_summary/work_order_summary.js
@@ -54,5 +54,12 @@
fieldtype: "Int",
default: "0"
},
+ {
+ label: __("Charts Based On"),
+ fieldname:"charts_based_on",
+ fieldtype: "Select",
+ options: ["Status", "Age", "Quantity"],
+ default: "Status"
+ },
]
};
diff --git a/erpnext/manufacturing/report/work_order_summary/work_order_summary.py b/erpnext/manufacturing/report/work_order_summary/work_order_summary.py
index 92c31ab..bc09ed4 100644
--- a/erpnext/manufacturing/report/work_order_summary/work_order_summary.py
+++ b/erpnext/manufacturing/report/work_order_summary/work_order_summary.py
@@ -3,8 +3,9 @@
from __future__ import unicode_literals
import frappe
-from frappe.utils import date_diff, today
+from frappe.utils import date_diff, today, getdate, flt
from frappe import _
+from erpnext.stock.report.stock_analytics.stock_analytics import (get_period_date_ranges, get_period)
def execute(filters=None):
columns, data = [], []
@@ -46,7 +47,15 @@
return res
-def get_chart_data(periodic_data, columns):
+def get_chart_data(data, filters):
+ if filters.get("charts_based_on") == "Status":
+ return get_chart_based_on_status(data)
+ elif filters.get("charts_based_on") == "Age":
+ return get_chart_based_on_age(data)
+ else:
+ return get_chart_based_on_qty(data, filters)
+
+def get_chart_based_on_status(data):
labels = ["Not Started", "In Process", "Stopped", "Completed"]
status_wise_data = {
@@ -56,7 +65,7 @@
"Completed": 0
}
- for d in periodic_data:
+ for d in data:
if d.status == "In Process" and d.produced_qty:
status_wise_data["Completed"] += d.produced_qty
@@ -71,12 +80,100 @@
'datasets': [{'name':'Qty Wise Chart', 'values': values}]
},
"type": "donut",
- "height": 300,
- "colors": ["#ff5858", "#ffa00a", "#5e64ff", "#98d85b"]
+ "height": 300
}
return chart
+def get_chart_based_on_age(data):
+ labels = ["0-30 Days", "30-60 Days", "60-90 Days", "90 Above"]
+
+ age_wise_data = {
+ "0-30 Days": 0,
+ "30-60 Days": 0,
+ "60-90 Days": 0,
+ "90 Above": 0
+ }
+
+ for d in data:
+ if d.age > 0 and d.age <= 30:
+ age_wise_data["0-30 Days"] += 1
+ elif d.age > 30 and d.age <= 60:
+ age_wise_data["30-60 Days"] += 1
+ elif d.age > 60 and d.age <= 90:
+ age_wise_data["60-90 Days"] += 1
+ else:
+ age_wise_data["90 Above"] += 1
+
+ values = [age_wise_data["0-30 Days"], age_wise_data["30-60 Days"],
+ age_wise_data["60-90 Days"], age_wise_data["90 Above"]]
+
+ chart = {
+ "data": {
+ 'labels': labels,
+ 'datasets': [{'name':'Qty Wise Chart', 'values': values}]
+ },
+ "type": "donut",
+ "height": 300
+ }
+
+ return chart
+
+def get_chart_based_on_qty(data, filters):
+ labels, periodic_data = prepare_chart_data(data, filters)
+
+ pending, completed = [], []
+ datasets = []
+
+ for d in labels:
+ pending.append(periodic_data.get("Pending").get(d))
+ completed.append(periodic_data.get("Completed").get(d))
+
+ datasets.append({"name": "Pending", "values": pending})
+ datasets.append({"name": "Completed", "values": completed})
+
+ chart = {
+ "data": {
+ 'labels': labels,
+ 'datasets': datasets
+ },
+ "type": "bar",
+ "barOptions": {
+ "stacked": 1
+ }
+ }
+
+ return chart
+
+def prepare_chart_data(data, filters):
+ labels = []
+
+ periodic_data = {
+ "Pending": {},
+ "Completed": {}
+ }
+
+ filters.range = "Monthly"
+
+ ranges = get_period_date_ranges(filters)
+ for from_date, end_date in ranges:
+ period = get_period(end_date, filters)
+ if period not in labels:
+ labels.append(period)
+
+ if period not in periodic_data["Pending"]:
+ periodic_data["Pending"][period] = 0
+
+ if period not in periodic_data["Completed"]:
+ periodic_data["Completed"][period] = 0
+
+ for d in data:
+ if getdate(d.planned_start_date) >= from_date and getdate(d.planned_start_date) <= end_date:
+ periodic_data["Pending"][period] += (flt(d.qty) - flt(d.produced_qty))
+ periodic_data["Completed"][period] += flt(d.produced_qty)
+
+ return labels, periodic_data
+
def get_columns(filters):
columns = [
{
diff --git a/erpnext/patches/v13_0/update_actual_start_and_end_date_in_wo.py b/erpnext/patches/v13_0/update_actual_start_and_end_date_in_wo.py
index 3fab004..331c559 100644
--- a/erpnext/patches/v13_0/update_actual_start_and_end_date_in_wo.py
+++ b/erpnext/patches/v13_0/update_actual_start_and_end_date_in_wo.py
@@ -6,6 +6,7 @@
import frappe
from frappe.utils import add_to_date
+from frappe.utils.dashboard import get_config, make_records
def execute():
frappe.reload_doc("manufacturing", "doctype", "work_order")
@@ -33,11 +34,9 @@
planned_end_date = add_to_date(doc.planned_start_date, minutes=doc.lead_time)
doc.db_set("planned_end_date", doc.actual_start_date, update_modified=False)
-
frappe.db.sql(""" UPDATE `tabJob Card` as jc, `tabWork Order` as wo
SET
jc.production_item = wo.production_item, jc.item_name = wo.item_name
WHERE
jc.work_order = wo.name and IFNULL(jc.production_item, "") = ""
- """)
-
+ """)
\ No newline at end of file
diff --git a/erpnext/setup/setup_wizard/data/dashboard_charts.py b/erpnext/setup/setup_wizard/data/dashboard_charts.py
deleted file mode 100644
index f5b6681..0000000
--- a/erpnext/setup/setup_wizard/data/dashboard_charts.py
+++ /dev/null
@@ -1,247 +0,0 @@
-from __future__ import unicode_literals
-from frappe import _
-import frappe
-import json
-
-def get_company_for_dashboards():
- company = frappe.defaults.get_defaults().company
- if company:
- return company
- else:
- company_list = frappe.get_list("Company")
- if company_list:
- return company_list[0].name
- return None
-
-def get_default_dashboards():
- company = frappe.get_doc("Company", get_company_for_dashboards())
- income_account = company.default_income_account or get_account("Income Account", company.name)
- expense_account = company.default_expense_account or get_account("Expense Account", company.name)
- bank_account = company.default_bank_account or get_account("Bank", company.name)
-
- return {
- "Dashboards": [
- {
- "doctype": "Dashboard",
- "dashboard_name": "Accounts",
- "charts": [
- { "chart": "Outgoing Bills (Sales Invoice)" },
- { "chart": "Incoming Bills (Purchase Invoice)" },
- { "chart": "Bank Balance" },
- { "chart": "Income" },
- { "chart": "Expenses" },
- { "chart": "Patient Appointments" }
- ]
- },
- {
- "doctype": "Dashboard",
- "dashboard_name": "Manufacturing",
- "charts": [
- { "chart": "Work Order Analysis", "width": "Half" },
- { "chart": "Quality Inspection Analysis", "width": "Half" },
- { "chart": "Long Time Pending Work Orders", "width": "Half" },
- { "chart": "Downtime Analysis", "width": "Half" },
- { "chart": "Production Analysis", "width": "Full" },
- { "chart": "Job Card Analysis", "width": "Full" }
- ]
- }
- ],
- "Charts": [
- {
- "doctype": "Dashboard Chart",
- "time_interval": "Quarterly",
- "chart_name": "Income",
- "timespan": "Last Year",
- "color": None,
- "filters_json": json.dumps({"company": company.name, "account": income_account}),
- "source": "Account Balance Timeline",
- "chart_type": "Custom",
- "timeseries": 1,
- "owner": "Administrator",
- "type": "Line",
- "width": "Half"
- },
- {
- "doctype": "Dashboard Chart",
- "time_interval": "Quarterly",
- "chart_name": "Expenses",
- "timespan": "Last Year",
- "color": None,
- "filters_json": json.dumps({"company": company.name, "account": expense_account}),
- "source": "Account Balance Timeline",
- "chart_type": "Custom",
- "timeseries": 1,
- "owner": "Administrator",
- "type": "Line",
- "width": "Half"
- },
- {
- "doctype": "Dashboard Chart",
- "time_interval": "Quarterly",
- "chart_name": "Bank Balance",
- "timespan": "Last Year",
- "color": "#ffb868",
- "filters_json": json.dumps({"company": company.name, "account": bank_account}),
- "source": "Account Balance Timeline",
- "chart_type": "Custom",
- "timeseries": 1,
- "owner": "Administrator",
- "type": "Line",
- "width": "Half"
- },
- {
- "doctype": "Dashboard Chart",
- "time_interval": "Monthly",
- "chart_name": "Incoming Bills (Purchase Invoice)",
- "timespan": "Last Year",
- "color": "#a83333",
- "value_based_on": "base_grand_total",
- "filters_json": json.dumps({}),
- "chart_type": "Sum",
- "timeseries": 1,
- "based_on": "posting_date",
- "owner": "Administrator",
- "document_type": "Purchase Invoice",
- "type": "Bar",
- "width": "Half"
- },
- {
- "doctype": "Dashboard Chart",
- "time_interval": "Monthly",
- "chart_name": "Outgoing Bills (Sales Invoice)",
- "timespan": "Last Year",
- "color": "#7b933d",
- "value_based_on": "base_grand_total",
- "filters_json": json.dumps({}),
- "chart_type": "Sum",
- "timeseries": 1,
- "based_on": "posting_date",
- "owner": "Administrator",
- "document_type": "Sales Invoice",
- "type": "Bar",
- "width": "Half"
- },
- {
- "doctype": "Dashboard Chart",
- "time_interval": "Daily",
- "chart_name": "Patient Appointments",
- "timespan": "Last Month",
- "color": "#77ecca",
- "filters_json": json.dumps({}),
- "chart_type": "Count",
- "timeseries": 1,
- "based_on": "appointment_datetime",
- "owner": "Administrator",
- "document_type": "Patient Appointment",
- "type": "Line",
- "width": "Half"
- }
- {
- "doctype": "Dashboard Chart",
- "time_interval": "Yearly",
- "chart_type": "Report",
- "chart_name": "Work Order Analysis",
- "timespan": "Last Year",
- "report_name": "Work Order Summary",
- "owner": "Administrator",
- "filters_json": json.dumps({"company": company.name}),
- "bar": "Donut",
- "custom_options": json.dumps({
- "axisOptions": {
- "shortenYAxisNumbers": 1
- },
- "height": 300,
- "colors": ["#ff5858", "#ffa00a", "#5e64ff", "#98d85b"]
- }),
- },
- {
- "doctype": "Dashboard Chart",
- "time_interval": "Yearly",
- "chart_type": "Report",
- "chart_name": "Quality Inspection Analysis",
- "timespan": "Last Year",
- "report_name": "Quality Inspection Summary",
- "owner": "Administrator",
- "filters_json": json.dumps({}),
- "bar": "Donut",
- "custom_options": json.dumps({
- "axisOptions": {
- "shortenYAxisNumbers": 1
- },
- "height": 300,
- "colors": ["#ff5858", "#98d85b"]
- }),
- },
- {
- "doctype": "Dashboard Chart",
- "time_interval": "Yearly",
- "chart_type": "Report",
- "chart_name": "Long Time Pending Work Orders",
- "timespan": "Last Year",
- "report_name": "Work Order Summary",
- "filters_json": json.dumps({"company": company.name, "age":180}),
- "owner": "Administrator",
- "bar": "Bar",
- "custom_options": json.dumps({
- "colors": ["#ff5858"],
- "x_field": "name",
- "y_fields": ["age"],
- "y_axis_fields": [{"__islocal": "true", "idx": 1, "y_field": "age"}],
- "chart_type": "Bar"
- }),
- },
- {
- "doctype": "Dashboard Chart",
- "time_interval": "Yearly",
- "chart_type": "Report",
- "chart_name": "Downtime Analysis",
- "timespan": "Last Year",
- "filters_json": json.dumps({}),
- "report_name": "Downtime Analysis",
- "owner": "Administrator",
- "bar": "Bar",
- "custom_options": json.dumps({
- "colors": ["#ff5858"]
- }),
- },
- {
- "doctype": "Dashboard Chart",
- "time_interval": "Yearly",
- "chart_type": "Report",
- "chart_name": "Production Analysis",
- "timespan": "Last Year",
- "report_name": "Production Analytics",
- "owner": "Administrator",
- "filters_json": json.dumps({"company": company.name, "range":"Monthly"}),
- "bar": "Bar",
- "custom_options": json.dumps({
- "colors": ["#7cd6fd", "#ff5858", "#ffa00a", "#98d85b"]
- }),
- },
- {
- "doctype": "Dashboard Chart",
- "time_interval": "Yearly",
- "chart_type": "Report",
- "chart_name": "Job Card Analysis",
- "timespan": "Last Year",
- "report_name": "Job Card Summary",
- "owner": "Administrator",
- "filters_json": json.dumps({"company": company.name, "range":"Monthly"}),
- "bar": "Bar",
- "custom_options": json.dumps({
- "axisOptions": {
- "xAxisMode": "tick"
- },
- "barOptions": {
- "stacked": 1
- },
- "colors": ["#ff5858", "#ffa00a", "#5e64ff", "#98d85b"]
- }),
- },
- ]
- }
-
-def get_account(account_type, company):
- accounts = frappe.get_list("Account", filters={"account_type": account_type, "company": company})
- if accounts:
- return accounts[0].name