Merge branch 'prod_ana' of https://github.com/bcornwellmott/erpnext into bcornwellmott-prod_ana
diff --git a/erpnext/config/manufacturing.py b/erpnext/config/manufacturing.py
index 0f76952..a930ddc 100644
--- a/erpnext/config/manufacturing.py
+++ b/erpnext/config/manufacturing.py
@@ -112,13 +112,18 @@
"is_query_report": True,
"name": "Completed Production Orders",
"doctype": "Production Order"
+ },{
+ "type": "page",
+ "name": "production-analytics",
+ "label": _("Production Analytics"),
+ "icon": "fa fa-bar-chart",
},
{
"type": "report",
"is_query_report": True,
"name": "BOM Search",
"doctype": "BOM"
- },
+ }
]
},
{
diff --git a/erpnext/manufacturing/page/production_analytics/__init__.py b/erpnext/manufacturing/page/production_analytics/__init__.py
new file mode 100644
index 0000000..baffc48
--- /dev/null
+++ b/erpnext/manufacturing/page/production_analytics/__init__.py
@@ -0,0 +1 @@
+from __future__ import unicode_literals
diff --git a/erpnext/manufacturing/page/production_analytics/production_analytics.js b/erpnext/manufacturing/page/production_analytics/production_analytics.js
new file mode 100644
index 0000000..bcf5a04
--- /dev/null
+++ b/erpnext/manufacturing/page/production_analytics/production_analytics.js
@@ -0,0 +1,158 @@
+// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
+// License: GNU General Public License v3. See license.txt
+
+frappe.pages['production-analytics'].on_page_load = function(wrapper) {
+ frappe.ui.make_app_page({
+ parent: wrapper,
+ title: __('Production Analytics'),
+ single_column: true
+ });
+
+ new erpnext.ProductionAnalytics(wrapper);
+
+
+ frappe.breadcrumbs.add("Manufacturing");
+}
+
+erpnext.ProductionAnalytics = frappe.views.GridReportWithPlot.extend({
+ init: function(wrapper) {
+ this._super({
+ title: __("Production Analytics"),
+ page: wrapper,
+ parent: $(wrapper).find('.layout-main'),
+ page: wrapper.page,
+ doctypes: ["Item", "Company", "Fiscal Year", "Production Order"]
+ });
+
+ },
+ setup_columns: function() {
+
+ var std_columns = [
+ {id: "_check", name: __("Plot"), field: "_check", width: 30,
+ formatter: this.check_formatter},
+ {id: "name", name: __("Status"), field: "name", width: 100},
+ ];
+
+ this.make_date_range_columns();
+ this.columns = std_columns.concat(this.columns);
+ },
+ filters: [
+ {fieldtype:"Select", label: __("Company"), link:"Company", fieldname: "company",
+ default_value: __("Select Company...")},
+ {fieldtype:"Date", label: __("From Date"), fieldname: "from_date"},
+ {fieldtype:"Date", label: __("To Date"), fieldname: "to_date"},
+ {fieldtype:"Select", label: __("Range"), fieldname: "range",
+ options:[{label: __("Daily"), value: "Daily"}, {label: __("Weekly"), value: "Weekly"},
+ {label: __("Monthly"), value: "Monthly"}, {label: __("Quarterly"), value: "Quarterly"},
+ {label: __("Yearly"), value: "Yearly"}]}
+ ],
+ setup_filters: function() {
+ var me = this;
+ this._super();
+
+ this.trigger_refresh_on_change(["company"]);
+ this.trigger_refresh_on_change(["range"]);
+
+ this.show_zero_check()
+ this.setup_chart_check();
+
+ },
+ init_filter_values: function() {
+ this._super();
+ this.filter_inputs.range.val('Monthly');
+ },
+ setup_chart: function() {
+ var me = this;
+
+ var chart_data = this.get_chart_data ? this.get_chart_data() : null;
+
+ this.chart = new frappe.ui.Chart({
+ wrapper: this.chart_area,
+ data: chart_data
+ });
+ },
+ set_default_values: function() {
+ var values = {
+ from_date: dateutil.str_to_user(dateutil.add_months(dateutil.now_datetime(),-12) ),
+ to_date: dateutil.str_to_user(dateutil.add_months(dateutil.now_datetime(),1))
+ }
+
+ var me = this;
+ $.each(values, function(i, v) {
+ if(me.filter_inputs[i] && !me.filter_inputs[i].val())
+ me.filter_inputs[i].val(v);
+ })
+ },
+
+ prepare_data: function() {
+ // add Opening, Closing, Totals rows
+ // if filtered by account and / or voucher
+ var me = this;
+ var all_open_orders = {name:"All Production Orders", "id": "all-open-pos",
+ checked:true};
+ var not_started = {name:"Not Started", "id":"not-started-pos",
+ checked:true};
+ var overdue = {name:"Overdue (Not Started)", "id":"overdue-pos",
+ checked:true};
+ var pending = {name:"Pending", "id":"pending-pos",
+ checked:true};
+ var completed = {name:"Completed", "id":"completed-pos",
+ checked:true};
+
+ $.each(frappe.report_dump.data["Production Order"], function(i, d) {
+ var dateobj = dateutil.str_to_obj(d.creation);
+ var date = dateutil.str_to_user(d.creation.split(" ")[0]);
+
+ $.each(me.columns, function(i,col) {
+ if (i > 1){
+ var start_period = dateutil.user_to_obj(dateutil.str_to_user(col.id));
+ var end_period = dateutil.user_to_obj(dateutil.str_to_user(col.name));
+ var astart_date = dateutil.user_to_obj(dateutil.str_to_user(d.actual_start_date));
+ var planned_start_date = dateutil.user_to_obj(dateutil.str_to_user(d.planned_start_date));
+ var aend_date = dateutil.user_to_obj(dateutil.str_to_user(d.actual_end_date));
+ var modified = dateutil.user_to_obj(dateutil.str_to_user(d.modified));
+
+ if (dateobj <= start_period || dateobj <= end_period) {
+ all_open_orders[col.field] = flt(all_open_orders[col.field]) + 1;
+
+ if(d.status=="Completed") {
+ if(aend_date < start_period || modified < start_period) {
+ completed[col.field] = flt(completed[col.field]) + 1;
+ }
+ else if (astart_date < start_period) {
+ pending[col.field] = flt(pending[col.field]) + 1;
+ }
+ else if (planned_start_date < start_period) {
+ overdue[col.field] = flt(overdue[col.field]) + 1;
+ } else {
+ not_started[col.field] = flt(not_started[col.field]) + 1;
+ }
+ }else if(d.status == "In Process")
+ {
+ if (astart_date < start_period || modified < start_period){
+ pending[col.field] = flt(pending[col.field]) + 1;
+ }else if (planned_start_date < start_period) {
+ overdue[col.field] = flt(overdue[col.field]) + 1;
+ }else{
+ not_started[col.field] = flt(not_started[col.field]) + 1;
+ }
+ }else if(d.status == "Not Started") {
+ if (planned_start_date < start_period){
+ overdue[col.field] = flt(overdue[col.field]) + 1;
+ }else{
+ not_started[col.field] = flt(not_started[col.field]) + 1;
+ }
+ }
+ }
+ }
+ });
+ });
+ if(me.columns.length < 30){
+ this.chart_area.toggle(true);
+ }else {
+ this.chart_area.toggle(false);
+ }
+ this.data = [all_open_orders, not_started, overdue, pending, completed];
+
+ }
+});
diff --git a/erpnext/manufacturing/page/production_analytics/production_analytics.json b/erpnext/manufacturing/page/production_analytics/production_analytics.json
new file mode 100644
index 0000000..e045614
--- /dev/null
+++ b/erpnext/manufacturing/page/production_analytics/production_analytics.json
@@ -0,0 +1,23 @@
+{
+ "creation": "2012-09-21 20:15:16.000000",
+ "docstatus": 0,
+ "doctype": "Page",
+ "icon": "fa fa-bar-chart",
+ "idx": 1,
+ "modified": "2013-07-11 14:43:52.000000",
+ "modified_by": "Administrator",
+ "module": "Buying",
+ "name": "production-analytics",
+ "owner": "Administrator",
+ "page_name": "production-analytics",
+ "roles": [
+ {
+ "role": "Analytics"
+ },
+ {
+ "role": "Manufacturing Manager"
+ }
+ ],
+ "standard": "Yes",
+ "title": "Production Analytics"
+}
\ No newline at end of file
diff --git a/erpnext/startup/report_data_map.py b/erpnext/startup/report_data_map.py
index 4dc326e..6cdd889 100644
--- a/erpnext/startup/report_data_map.py
+++ b/erpnext/startup/report_data_map.py
@@ -269,7 +269,7 @@
},
"Purchase Receipt": {
"columns": ["name", "supplier", "posting_date", "company"],
- "conditions": ["docstatus=1"],
+ "conditions": ["docstatus=1"],
"order_by": "posting_date",
"links": {
"supplier": ["Supplier", "name"],
@@ -278,7 +278,7 @@
},
"Purchase Receipt Item[Purchase Analytics]": {
"columns": ["name", "parent", "item_code", "qty", "base_net_amount"],
- "conditions": ["docstatus=1", "ifnull(parent, '')!=''"],
+ "conditions": ["docstatus=1", "ifnull(parent, '')!=''"],
"order_by": "parent",
"links": {
"parent": ["Purchase Receipt", "name"],
@@ -290,6 +290,12 @@
"columns": ["name","status","creation","resolution_date","first_responded_on"],
"conditions": ["docstatus < 2"],
"order_by": "creation"
- }
+ },
+ # Manufacturing
+ "Production Order": {
+ "columns": ["name","status","creation","planned_start_date","planned_end_date","status","actual_start_date","actual_end_date", "modified"],
+ "conditions": ["docstatus = 1"],
+ "order_by": "creation"
+ }
}