added onboarding for manufacturing
This commit is contained in:
parent
34f4a2398b
commit
366bce678f
216
erpnext/manufacturing/dashboard_fixtures.py
Normal file
216
erpnext/manufacturing/dashboard_fixtures.py
Normal file
@ -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"
|
||||
}]
|
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
@ -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",
|
||||
|
@ -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
|
||||
}
|
@ -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"
|
||||
}
|
@ -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"
|
||||
}
|
@ -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"
|
||||
}
|
@ -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"
|
||||
}
|
@ -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"
|
||||
}
|
@ -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"
|
||||
}
|
@ -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"
|
||||
}
|
@ -47,8 +47,7 @@ def get_chart_data(data, columns):
|
||||
{"name": "Dataset 1", "values": datasets}
|
||||
]
|
||||
},
|
||||
"type": "bar",
|
||||
"colors": ["#ff5858"]
|
||||
"type": "bar"
|
||||
}
|
||||
|
||||
return chart
|
||||
|
@ -49,33 +49,22 @@ def get_data(filters):
|
||||
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 @@ def prepare_chart_data(job_card_details, filters):
|
||||
labels = []
|
||||
|
||||
periodic_data = {
|
||||
"Open": {},
|
||||
"Work In Progress": {},
|
||||
"On Hold": {},
|
||||
"Pending": {},
|
||||
"Completed": {}
|
||||
}
|
||||
|
||||
@ -100,10 +87,12 @@ def prepare_chart_data(job_card_details, filters):
|
||||
|
||||
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
|
||||
|
||||
|
@ -38,6 +38,7 @@ def get_columns(filters):
|
||||
|
||||
def get_periodic_data(filters, entry):
|
||||
periodic_data = {
|
||||
"All Work Orders": {},
|
||||
"Not Started": {},
|
||||
"Overdue": {},
|
||||
"Pending": {},
|
||||
@ -50,6 +51,7 @@ def get_periodic_data(filters, entry):
|
||||
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 @@ def get_data(filters, columns):
|
||||
|
||||
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 @@ def get_chart_data(periodic_data, columns):
|
||||
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 @@ def get_chart_data(periodic_data, columns):
|
||||
"data": {
|
||||
'labels': labels,
|
||||
'datasets': datasets
|
||||
},
|
||||
"type": "bar",
|
||||
"colors": ["#5e64ff", "#ff5858", "#ffa00a", "#98d85b"]
|
||||
}
|
||||
}
|
||||
chart["type"] = "line"
|
||||
|
||||
return chart
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -50,8 +50,7 @@ def get_chart_data(periodic_data, columns):
|
||||
'datasets': datasets
|
||||
},
|
||||
"type": "donut",
|
||||
"height": 300,
|
||||
"colors": ["#ff5858", "#98d85b"]
|
||||
"height": 300
|
||||
}
|
||||
|
||||
return chart
|
||||
|
@ -54,5 +54,12 @@ frappe.query_reports["Work Order Summary"] = {
|
||||
fieldtype: "Int",
|
||||
default: "0"
|
||||
},
|
||||
{
|
||||
label: __("Charts Based On"),
|
||||
fieldname:"charts_based_on",
|
||||
fieldtype: "Select",
|
||||
options: ["Status", "Age", "Quantity"],
|
||||
default: "Status"
|
||||
},
|
||||
]
|
||||
};
|
||||
|
@ -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 @@ def get_data(filters):
|
||||
|
||||
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 @@ def get_chart_data(periodic_data, columns):
|
||||
"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 @@ def get_chart_data(periodic_data, columns):
|
||||
'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 = [
|
||||
{
|
||||
|
@ -6,6 +6,7 @@ from __future__ import unicode_literals
|
||||
|
||||
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 @@ def execute():
|
||||
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, "") = ""
|
||||
""")
|
||||
|
||||
""")
|
@ -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
|
Loading…
Reference in New Issue
Block a user