fix: Fixed Dashboard Charts, modified fixtures and minor changes
This commit is contained in:
parent
e46916be56
commit
a74d433cd8
@ -3,7 +3,8 @@
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
import json
|
import json
|
||||||
|
from frappe.utils import nowdate
|
||||||
|
from erpnext.accounts.utils import get_fiscal_year
|
||||||
|
|
||||||
def get_data():
|
def get_data():
|
||||||
return frappe._dict({
|
return frappe._dict({
|
||||||
@ -23,108 +24,172 @@ def get_company_for_dashboards():
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
company = frappe.get_doc("Company", get_company_for_dashboards())
|
company = frappe.get_doc("Company", get_company_for_dashboards())
|
||||||
|
fiscal_year = get_fiscal_year(nowdate(), as_dict=1)
|
||||||
|
fiscal_year_name = fiscal_year.get("name")
|
||||||
|
start_date = str(fiscal_year.get("year_start_date"))
|
||||||
|
end_date = str(fiscal_year.get("year_end_date"))
|
||||||
|
|
||||||
def get_dashboards():
|
def get_dashboards():
|
||||||
return [{
|
return [{
|
||||||
"name": "Buying",
|
"name": "Buying",
|
||||||
"dashboard_name": "Buying",
|
"dashboard_name": "Buying",
|
||||||
"charts": [
|
"charts": [
|
||||||
{ "chart": "Purchase Analytics", "width": "Full"},
|
{ "chart": "Top Suppliers", "width": "Full"},
|
||||||
{ "chart": "Material Request Purchase Analysis", "width": "Half"},
|
{ "chart": "Material Request Analysis", "width": "Half"},
|
||||||
{ "chart": "Purchase Order Analysis", "width": "Half"},
|
{ "chart": "Purchase Order Analysis", "width": "Half"},
|
||||||
{ "chart": "Requested Items to Order", "width": "Full"}
|
{ "chart": "Purchase Order Trends", "width": "Full"}
|
||||||
|
],
|
||||||
|
"cards": [
|
||||||
|
{ "card": "Purchase Orders to Receive"},
|
||||||
|
{ "card": "Purchase Order Expenses"},
|
||||||
|
{ "card": "Active Suppliers"},
|
||||||
|
{ "card": "Active Supplier Quotations"}
|
||||||
]
|
]
|
||||||
}]
|
}]
|
||||||
|
|
||||||
def get_charts():
|
def get_charts():
|
||||||
return [
|
return [
|
||||||
{
|
|
||||||
"name": "Purchase Analytics",
|
|
||||||
"doctype": "Dashboard Chart",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"report_name": "Purchase Analytics",
|
|
||||||
"filters_json": json.dumps({
|
|
||||||
"tree_type": "Item",
|
|
||||||
"doc_type": "Purchase Receipt",
|
|
||||||
"value_quantity": "Value",
|
|
||||||
"from_date": "2020-03-01",
|
|
||||||
"to_date": "2020-07-31",
|
|
||||||
"company": company.name,
|
|
||||||
"range": "Weekly"
|
|
||||||
}),
|
|
||||||
"x_field": "entity",
|
|
||||||
"type": "Bar",
|
|
||||||
'timeseries': 0,
|
|
||||||
"chart_type": "Report",
|
|
||||||
"chart_name": "Purchase Analytics",
|
|
||||||
"custom_options": json.dumps({
|
|
||||||
"x_field": "entity",
|
|
||||||
"chart_type": "Bar",
|
|
||||||
"y_axis_fields": [{"idx": 1, "__islocal": "true", "y_field": "total"}],
|
|
||||||
"y_fields": ["total"]
|
|
||||||
})
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Material Request Purchase Analysis",
|
|
||||||
"doctype": "Dashboard Chart",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"document_type": "Material Request",
|
|
||||||
"filters_json": '[["Material Request","status","not in",["Draft","Cancelled","Stopped",null],false],["Material Request","material_request_type","=","Purchase",false],["Material Request","company","=", "{company}", false]]'.format(company=company.name),
|
|
||||||
"is_custom": 0,
|
|
||||||
"type": "Donut",
|
|
||||||
"timeseries": 0,
|
|
||||||
"chart_type": "Group By",
|
|
||||||
"group_by_based_on": "status",
|
|
||||||
"chart_name": "Material Request Purchase Analysis",
|
|
||||||
"group_by_type": "Count",
|
|
||||||
"custom_options": json.dumps({"height": 300})
|
|
||||||
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "Purchase Order Analysis",
|
"name": "Purchase Order Analysis",
|
||||||
"doctype": "Dashboard Chart",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"report_name": "Purchase Order Analysis",
|
|
||||||
"filters_json": json.dumps({
|
|
||||||
"company": company.name,
|
|
||||||
"from_date": "2020-04-04",
|
|
||||||
"to_date": "2020-07-04",
|
|
||||||
"chart_based_on": "Quantity"
|
|
||||||
}),
|
|
||||||
"is_custom": 1,
|
|
||||||
"type": "Donut",
|
|
||||||
"timeseries": 0,
|
|
||||||
"chart_type": "Report",
|
|
||||||
"chart_name": "Purchase Order Analysis",
|
"chart_name": "Purchase Order Analysis",
|
||||||
|
"chart_type": "Report",
|
||||||
"custom_options": json.dumps({
|
"custom_options": json.dumps({
|
||||||
"type": "donut",
|
"type": "donut",
|
||||||
"height": 300,
|
"height": 300,
|
||||||
"axisOptions": {"shortenYAxisNumbers": 1}
|
"axisOptions": {"shortenYAxisNumbers": 1}
|
||||||
})
|
}),
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Requested Items to Order",
|
|
||||||
"doctype": "Dashboard Chart",
|
"doctype": "Dashboard Chart",
|
||||||
"owner": "Administrator",
|
|
||||||
"report_name": "Requested Items to Order",
|
|
||||||
"filters_json": json.dumps({
|
"filters_json": json.dumps({
|
||||||
"company": company.name,
|
"company": company.name,
|
||||||
"from_date": "2020-04-01",
|
"from_date": start_date,
|
||||||
"to_date": "2020-07-01",
|
"to_date": end_date
|
||||||
"group_by_mr": 0
|
|
||||||
}),
|
}),
|
||||||
"is_custom": 1,
|
"is_custom": 1,
|
||||||
"type": "Bar",
|
"is_public": 1,
|
||||||
"timeseries": 0,
|
"owner": "Administrator",
|
||||||
|
"report_name": "Purchase Order Analysis",
|
||||||
|
"type": "Donut"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Material Request Analysis",
|
||||||
|
"chart_name": "Material Request Analysis",
|
||||||
|
"chart_type": "Group By",
|
||||||
|
"custom_options": json.dumps({"height": 300}),
|
||||||
|
"doctype": "Dashboard Chart",
|
||||||
|
"document_type": "Material Request",
|
||||||
|
"filters_json": json.dumps(
|
||||||
|
[["Material Request", "status", "not in", ["Draft", "Cancelled", "Stopped", None], False],
|
||||||
|
["Material Request", "material_request_type", "=", "Purchase", False],
|
||||||
|
["Material Request", "company", "=", company.name, False]]
|
||||||
|
),
|
||||||
|
"group_by_based_on": "status",
|
||||||
|
"group_by_type": "Count",
|
||||||
|
"is_custom": 0,
|
||||||
|
"is_public": 1,
|
||||||
|
"number_of_groups": 0,
|
||||||
|
"owner": "Administrator",
|
||||||
|
"type": "Donut"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Purchase Order Trends",
|
||||||
|
"chart_name": "Purchase Order Trends",
|
||||||
"chart_type": "Report",
|
"chart_type": "Report",
|
||||||
"chart_name": "Requested Items to Order",
|
|
||||||
"custom_options": json.dumps({
|
"custom_options": json.dumps({
|
||||||
"type": "bar",
|
"type": "line",
|
||||||
"barOptions": {"stacked": 1},
|
"regionFill": 1,
|
||||||
"axisOptions": {"shortenYAxisNumbers": 1}
|
"axisOptions": {"shortenYAxisNumbers": 1},
|
||||||
})
|
"tooltipOptions": {}
|
||||||
|
}),
|
||||||
|
"doctype": "Dashboard Chart",
|
||||||
|
"filters_json": json.dumps({
|
||||||
|
"company": company.name,
|
||||||
|
"period": "Monthly",
|
||||||
|
"fiscal_year": fiscal_year_name,
|
||||||
|
"period_based_on": "posting_date",
|
||||||
|
"based_on": "Item"
|
||||||
|
}),
|
||||||
|
"is_custom": 1,
|
||||||
|
"is_public": 1,
|
||||||
|
"owner": "Administrator",
|
||||||
|
"report_name": "Purchase Order Trends",
|
||||||
|
"type": "Line"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Top Suppliers",
|
||||||
|
"chart_name": "Top Suppliers",
|
||||||
|
"chart_type": "Report",
|
||||||
|
"doctype": "Dashboard Chart",
|
||||||
|
"filters_json": json.dumps({
|
||||||
|
"company": company.name,
|
||||||
|
"period": "Monthly",
|
||||||
|
"fiscal_year": fiscal_year_name,
|
||||||
|
"period_based_on": "posting_date",
|
||||||
|
"based_on": "Supplier"
|
||||||
|
}),
|
||||||
|
"is_custom": 1,
|
||||||
|
"is_public": 1,
|
||||||
|
"owner": "Administrator",
|
||||||
|
"report_name": "Purchase Receipt Trends",
|
||||||
|
"type": "Bar"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_number_cards():
|
def get_number_cards():
|
||||||
return [{}]
|
return [
|
||||||
|
{
|
||||||
|
"name": "Purchase Order Expenses",
|
||||||
|
"aggregate_function_based_on": "base_grand_total",
|
||||||
|
"doctype": "Number Card",
|
||||||
|
"document_type": "Purchase Order",
|
||||||
|
"filters_json": json.dumps(
|
||||||
|
[["Purchase Order", "transaction_date", "Between", [start_date,end_date], False],
|
||||||
|
["Purchase Order", "status", "not in", ["Draft","On Hold","Cancelled","Closed", None], False],
|
||||||
|
["Purchase Order", "company", "=", company.name, False]]
|
||||||
|
),
|
||||||
|
"function": "Sum",
|
||||||
|
"is_public": 1,
|
||||||
|
"label": "Purchase Order Expenses",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"show_percentage_stats": 1,
|
||||||
|
"stats_time_interval": "Monthly"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Purchase Orders to Receive",
|
||||||
|
"doctype": "Number Card",
|
||||||
|
"document_type": "Purchase Order",
|
||||||
|
"filters_json": json.dumps(
|
||||||
|
[["Purchase Order", "status", "in", ["To Receive and Bill", "To Receive", None], False],
|
||||||
|
["Purchase Order", "company", "=", company.name, False]]
|
||||||
|
),
|
||||||
|
"function": "Count",
|
||||||
|
"is_public": 1,
|
||||||
|
"label": "Purchase Orders to Receive",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"show_percentage_stats": 1,
|
||||||
|
"stats_time_interval": "Weekly"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Active Suppliers",
|
||||||
|
"doctype": "Number Card",
|
||||||
|
"document_type": "Supplier",
|
||||||
|
"filters_json": json.dumps([["Supplier", "disabled", "=", "0"]]),
|
||||||
|
"function": "Count",
|
||||||
|
"is_public": 1,
|
||||||
|
"label": "Active Suppliers",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"show_percentage_stats": 1,
|
||||||
|
"stats_time_interval": "Monthly"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Active Supplier Quotations",
|
||||||
|
"doctype": "Number Card",
|
||||||
|
"document_type": "Supplier Quotation",
|
||||||
|
"filters_json": json.dumps([["Supplier Quotation", "status", "=", "Submitted", False]]),
|
||||||
|
"function": "Count",
|
||||||
|
"is_public": 1,
|
||||||
|
"label": "Active Supplier Quotations",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"show_percentage_stats": 1,
|
||||||
|
"stats_time_interval": "Monthly"
|
||||||
|
}
|
||||||
|
]
|
@ -16,7 +16,7 @@ frappe.tour['Buying Settings'] = [
|
|||||||
{
|
{
|
||||||
fieldname: "buying_price_list",
|
fieldname: "buying_price_list",
|
||||||
title: "Default Buying Price List",
|
title: "Default Buying Price List",
|
||||||
description: __("Configure the default Price List when creating a new Buying transaction, the default is set as 'Standard Buying'. Item prices will be fetched from this Price List. You can modify the 'Price List' by using the arrow at the right-end of the field to change the currency and country.")
|
description: __("Configure the default Price List when creating a new Buying transaction, the default is set as 'Standard Buying'. Item prices will be fetched from this Price List.")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldname: "po_required",
|
fieldname: "po_required",
|
||||||
|
@ -761,7 +761,7 @@
|
|||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"oldfieldname": "status",
|
"oldfieldname": "status",
|
||||||
"oldfieldtype": "Select",
|
"oldfieldtype": "Select",
|
||||||
"options": "\nDraft\nSubmitted\nStopped\nCancelled",
|
"options": "\nDraft\nSubmitted\nStopped\nCancelled\nExpired",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1,
|
"read_only": 1,
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
@ -803,7 +803,7 @@
|
|||||||
"idx": 29,
|
"idx": 29,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-04-15 11:44:52.958022",
|
"modified": "2020-05-15 21:24:12.639482",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Supplier Quotation",
|
"name": "Supplier Quotation",
|
||||||
|
@ -58,14 +58,6 @@ frappe.query_reports["Purchase Order Analysis"] = {
|
|||||||
return options
|
return options
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"fieldname": "chart_based_on",
|
|
||||||
"label": __("Chart Based On"),
|
|
||||||
"fieldtype": "Select",
|
|
||||||
"width": "80",
|
|
||||||
"options": "Quantity\nAmount",
|
|
||||||
"default": "Quantity"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"fieldname": "group_by_po",
|
"fieldname": "group_by_po",
|
||||||
"label": __("Group by Purchase Order"),
|
"label": __("Group by Purchase Order"),
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"add_total_row": 0,
|
"add_total_row": 1,
|
||||||
"creation": "2020-05-04 18:41:28.625119",
|
"creation": "2020-05-04 18:41:28.625119",
|
||||||
"disable_prepared_report": 0,
|
"disable_prepared_report": 0,
|
||||||
"disabled": 0,
|
"disabled": 0,
|
||||||
@ -7,7 +7,7 @@
|
|||||||
"doctype": "Report",
|
"doctype": "Report",
|
||||||
"idx": 0,
|
"idx": 0,
|
||||||
"is_standard": "Yes",
|
"is_standard": "Yes",
|
||||||
"modified": "2020-05-04 18:41:28.625119",
|
"modified": "2020-05-15 20:57:52.623455",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Purchase Order Analysis",
|
"name": "Purchase Order Analysis",
|
||||||
|
@ -82,10 +82,9 @@ def get_data(conditions, filters):
|
|||||||
return data
|
return data
|
||||||
|
|
||||||
def prepare_data(data, filters):
|
def prepare_data(data, filters):
|
||||||
completed, pending = 0,0
|
completed, pending = 0, 0
|
||||||
chart_based_on = filters.get("chart_based_on")
|
pending_field = "pending_amount"
|
||||||
pending_field = "pending_qty" if chart_based_on == "Quantity" else "pending_amount"
|
completed_field = "billed_amount"
|
||||||
completed_field = "received_qty" if chart_based_on == "Quantity" else "billed_amount"
|
|
||||||
|
|
||||||
if filters.get("group_by_po"):
|
if filters.get("group_by_po"):
|
||||||
purchase_order_map = {}
|
purchase_order_map = {}
|
||||||
@ -116,7 +115,7 @@ def prepare_data(data, filters):
|
|||||||
for field in fields:
|
for field in fields:
|
||||||
po_row[field] = flt(row[field]) + flt(po_row[field])
|
po_row[field] = flt(row[field]) + flt(po_row[field])
|
||||||
|
|
||||||
chart_data = prepare_chart_data(chart_based_on, pending, completed)
|
chart_data = prepare_chart_data(pending, completed)
|
||||||
|
|
||||||
if filters.get("group_by_po"):
|
if filters.get("group_by_po"):
|
||||||
data = []
|
data = []
|
||||||
@ -126,8 +125,8 @@ def prepare_data(data, filters):
|
|||||||
|
|
||||||
return data, chart_data
|
return data, chart_data
|
||||||
|
|
||||||
def prepare_chart_data(chart_based_on, pending, completed):
|
def prepare_chart_data(pending, completed):
|
||||||
labels = ["Qty to Receive","Received Qty"] if chart_based_on == "Quantity" else ["Amount to Bill","Billed Amount"]
|
labels = ["Amount to Bill", "Billed Amount"]
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"data" : {
|
"data" : {
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
|
from frappe import _
|
||||||
from erpnext.controllers.trends import get_columns,get_data
|
from erpnext.controllers.trends import get_columns,get_data
|
||||||
|
|
||||||
def execute(filters=None):
|
def execute(filters=None):
|
||||||
@ -10,5 +11,45 @@ def execute(filters=None):
|
|||||||
data = []
|
data = []
|
||||||
conditions = get_columns(filters, "Purchase Order")
|
conditions = get_columns(filters, "Purchase Order")
|
||||||
data = get_data(filters, conditions)
|
data = get_data(filters, conditions)
|
||||||
|
chart_data = get_chart_data(data, conditions, filters)
|
||||||
|
|
||||||
return conditions["columns"], data
|
return conditions["columns"], data, None, chart_data
|
||||||
|
|
||||||
|
def get_chart_data(data, conditions, filters):
|
||||||
|
if not (data and conditions):
|
||||||
|
return []
|
||||||
|
|
||||||
|
datapoints = []
|
||||||
|
|
||||||
|
start = 2 if filters.get("based_on") in ["Item", "Supplier"] else 1
|
||||||
|
if filters.get("group_by"):
|
||||||
|
start += 1
|
||||||
|
|
||||||
|
# fetch only periodic columns as labels
|
||||||
|
columns = conditions.get("columns")[start:-2][1::2]
|
||||||
|
labels = [column.split(':')[0] for column in columns]
|
||||||
|
datapoints = [0] * len(labels)
|
||||||
|
|
||||||
|
for row in data:
|
||||||
|
# If group by filter, don't add first row of group (it's already summed)
|
||||||
|
if not row[start-1]:
|
||||||
|
continue
|
||||||
|
# Remove None values and compute only periodic data
|
||||||
|
row = [x if x else 0 for x in row[start:-2]]
|
||||||
|
row = row[1::2]
|
||||||
|
|
||||||
|
for i in range(len(row)):
|
||||||
|
datapoints[i] += row[i]
|
||||||
|
|
||||||
|
return {
|
||||||
|
"data" : {
|
||||||
|
"labels" : labels,
|
||||||
|
"datasets" : [
|
||||||
|
{
|
||||||
|
"name" : _("{0}").format(filters.get("period")) + _(" Revenue"),
|
||||||
|
"values" : datapoints
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"type" : "line"
|
||||||
|
}
|
@ -51,7 +51,10 @@ erpnext.get_purchase_trends_filters = function() {
|
|||||||
{ "value": "Supplier Group", "label": __("Supplier Group") },
|
{ "value": "Supplier Group", "label": __("Supplier Group") },
|
||||||
{ "value": "Project", "label": __("Project") }
|
{ "value": "Project", "label": __("Project") }
|
||||||
],
|
],
|
||||||
"default": "Item"
|
"default": "Item",
|
||||||
|
"dashboard_config": {
|
||||||
|
"read_only": 1
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname":"group_by",
|
"fieldname":"group_by",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user