Merge branch 'marination-stock-dashboard' into develop
This commit is contained in:
commit
ddec05ee07
@ -81,7 +81,7 @@ def get_charts():
|
|||||||
"timespan": "Last Year",
|
"timespan": "Last Year",
|
||||||
"color": "#a83333",
|
"color": "#a83333",
|
||||||
"value_based_on": "base_net_total",
|
"value_based_on": "base_net_total",
|
||||||
"filters_json": json.dumps({"docstatus": 1}),
|
"filters_json": json.dumps([["Purchase Invoice", "docstatus", "=", 1]]),
|
||||||
"chart_type": "Sum",
|
"chart_type": "Sum",
|
||||||
"timeseries": 1,
|
"timeseries": 1,
|
||||||
"based_on": "posting_date",
|
"based_on": "posting_date",
|
||||||
@ -99,7 +99,7 @@ def get_charts():
|
|||||||
"timespan": "Last Year",
|
"timespan": "Last Year",
|
||||||
"color": "#7b933d",
|
"color": "#7b933d",
|
||||||
"value_based_on": "base_net_total",
|
"value_based_on": "base_net_total",
|
||||||
"filters_json": json.dumps({"docstatus": 1}),
|
"filters_json": json.dumps([["Sales Invoice", "docstatus", "=", 1]]),
|
||||||
"chart_type": "Sum",
|
"chart_type": "Sum",
|
||||||
"timeseries": 1,
|
"timeseries": 1,
|
||||||
"based_on": "posting_date",
|
"based_on": "posting_date",
|
||||||
|
@ -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",
|
||||||
|
@ -27,7 +27,10 @@ erpnext.get_sales_trends_filters = function() {
|
|||||||
{ "value": "Territory", "label": __("Territory") },
|
{ "value": "Territory", "label": __("Territory") },
|
||||||
{ "value": "Project", "label": __("Project") }
|
{ "value": "Project", "label": __("Project") }
|
||||||
],
|
],
|
||||||
"default": "Item"
|
"default": "Item",
|
||||||
|
"dashboard_config": {
|
||||||
|
"read_only": 1,
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname":"group_by",
|
"fieldname":"group_by",
|
||||||
|
0
erpnext/stock/dashboard_chart_source/__init__.py
Normal file
0
erpnext/stock/dashboard_chart_source/__init__.py
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
frappe.provide('frappe.dashboards.chart_sources');
|
||||||
|
|
||||||
|
frappe.dashboards.chart_sources["Warehouse wise Stock Value"] = {
|
||||||
|
method: "erpnext.stock.dashboard_chart_source.warehouse_wise_stock_value.warehouse_wise_stock_value.get",
|
||||||
|
filters: [
|
||||||
|
{
|
||||||
|
fieldname: "company",
|
||||||
|
label: __("Company"),
|
||||||
|
fieldtype: "Link",
|
||||||
|
options: "Company",
|
||||||
|
default: frappe.defaults.get_user_default("Company")
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"creation": "2020-05-14 14:27:44.108017",
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "Dashboard Chart Source",
|
||||||
|
"idx": 0,
|
||||||
|
"modified": "2020-05-14 14:27:44.108017",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Stock",
|
||||||
|
"name": "Warehouse wise Stock Value",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"source_name": "Warehouse wise Stock Value ",
|
||||||
|
"timeseries": 0
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe, json
|
||||||
|
from frappe import _
|
||||||
|
from frappe.utils.dashboard import cache_source
|
||||||
|
from erpnext.stock.utils import get_stock_value_from_bin
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
@cache_source
|
||||||
|
def get(chart_name = None, chart = None, no_cache = None, filters = None, from_date = None,
|
||||||
|
to_date = None, timespan = None, time_interval = None, heatmap_year = None):
|
||||||
|
labels, datapoints = [], []
|
||||||
|
filters = frappe.parse_json(filters)
|
||||||
|
|
||||||
|
warehouse_filters = [['is_group', '=', 0]]
|
||||||
|
if filters and filters.get("company"):
|
||||||
|
warehouse_filters.append(['company', '=', filters.get("company")])
|
||||||
|
|
||||||
|
warehouses = frappe.get_list("Warehouse", fields=['name'], filters=warehouse_filters, order_by='name')
|
||||||
|
|
||||||
|
for wh in warehouses:
|
||||||
|
balance = get_stock_value_from_bin(warehouse=wh.name)
|
||||||
|
wh["balance"] = balance[0][0]
|
||||||
|
|
||||||
|
warehouses = [x for x in warehouses if not (x.get('balance') == None)]
|
||||||
|
|
||||||
|
if not warehouses:
|
||||||
|
return []
|
||||||
|
|
||||||
|
sorted_warehouse_map = sorted(warehouses, key = lambda i: i['balance'], reverse=True)
|
||||||
|
|
||||||
|
if len(sorted_warehouse_map) > 10:
|
||||||
|
sorted_warehouse_map = sorted_warehouse_map[:10]
|
||||||
|
|
||||||
|
for warehouse in sorted_warehouse_map:
|
||||||
|
labels.append(_(warehouse.get("name")))
|
||||||
|
datapoints.append(warehouse.get("balance"))
|
||||||
|
|
||||||
|
return{
|
||||||
|
"labels": labels,
|
||||||
|
"datasets": [{
|
||||||
|
"name": _("Stock Value"),
|
||||||
|
"values": datapoints
|
||||||
|
}],
|
||||||
|
"type": "bar"
|
||||||
|
}
|
175
erpnext/stock/dashboard_fixtures.py
Normal file
175
erpnext/stock/dashboard_fixtures.py
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
|
import frappe
|
||||||
|
import json
|
||||||
|
from frappe import _
|
||||||
|
from frappe.utils import nowdate
|
||||||
|
from erpnext.accounts.utils import get_fiscal_year
|
||||||
|
|
||||||
|
def get_data():
|
||||||
|
return frappe._dict({
|
||||||
|
"dashboards": get_dashboards(),
|
||||||
|
"charts": get_charts(),
|
||||||
|
"number_cards": get_number_cards(),
|
||||||
|
})
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
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():
|
||||||
|
return [{
|
||||||
|
"name": "Stock",
|
||||||
|
"dashboard_name": "Stock",
|
||||||
|
"charts": [
|
||||||
|
{ "chart": "Warehouse wise Stock Value", "width": "Full"},
|
||||||
|
{ "chart": "Purchase Receipt Trends", "width": "Half"},
|
||||||
|
{ "chart": "Delivery Trends", "width": "Half"},
|
||||||
|
{ "chart": "Oldest Items", "width": "Half"},
|
||||||
|
{ "chart": "Item Shortage Summary", "width": "Half"}
|
||||||
|
],
|
||||||
|
"cards": [
|
||||||
|
{ "card": "Total Active Items"},
|
||||||
|
{ "card": "Total Warehouses"},
|
||||||
|
{ "card": "Total Stock Value"}
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
|
||||||
|
def get_charts():
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
"doctype": "Dashboard Chart",
|
||||||
|
"name": "Purchase Receipt Trends",
|
||||||
|
"time_interval": "Monthly",
|
||||||
|
"chart_name": _("Purchase Receipt Trends"),
|
||||||
|
"timespan": "Last Year",
|
||||||
|
"color": "#7b933d",
|
||||||
|
"value_based_on": "base_net_total",
|
||||||
|
"filters_json": json.dumps([["Purchase Receipt", "docstatus", "=", 1]]),
|
||||||
|
"chart_type": "Sum",
|
||||||
|
"timeseries": 1,
|
||||||
|
"based_on": "posting_date",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"document_type": "Purchase Receipt",
|
||||||
|
"type": "Bar",
|
||||||
|
"width": "Half",
|
||||||
|
"is_public": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "Dashboard Chart",
|
||||||
|
"name": "Delivery Trends",
|
||||||
|
"time_interval": "Monthly",
|
||||||
|
"chart_name": _("Delivery Trends"),
|
||||||
|
"timespan": "Last Year",
|
||||||
|
"color": "#7b933d",
|
||||||
|
"value_based_on": "base_net_total",
|
||||||
|
"filters_json": json.dumps([["Delivery Note", "docstatus", "=", 1]]),
|
||||||
|
"chart_type": "Sum",
|
||||||
|
"timeseries": 1,
|
||||||
|
"based_on": "posting_date",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"document_type": "Delivery Note",
|
||||||
|
"type": "Bar",
|
||||||
|
"width": "Half",
|
||||||
|
"is_public": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Warehouse wise Stock Value",
|
||||||
|
"chart_name": _("Warehouse wise Stock Value"),
|
||||||
|
"chart_type": "Custom",
|
||||||
|
"doctype": "Dashboard Chart",
|
||||||
|
"filters_json": json.dumps({}),
|
||||||
|
"is_custom": 0,
|
||||||
|
"is_public": 1,
|
||||||
|
"owner": "Administrator",
|
||||||
|
"source": "Warehouse wise Stock Value",
|
||||||
|
"type": "Bar"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Oldest Items",
|
||||||
|
"chart_name": _("Oldest Items"),
|
||||||
|
"chart_type": "Report",
|
||||||
|
"custom_options": json.dumps({
|
||||||
|
"colors": ["#5e64ff"]
|
||||||
|
}),
|
||||||
|
"doctype": "Dashboard Chart",
|
||||||
|
"filters_json": json.dumps({
|
||||||
|
"company": company.name,
|
||||||
|
"to_date": nowdate(),
|
||||||
|
"show_warehouse_wise_stock": 0
|
||||||
|
}),
|
||||||
|
"is_custom": 1,
|
||||||
|
"is_public": 1,
|
||||||
|
"owner": "Administrator",
|
||||||
|
"report_name": "Stock Ageing",
|
||||||
|
"type": "Bar"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Item Shortage Summary",
|
||||||
|
"chart_name": _("Item Shortage Summary"),
|
||||||
|
"chart_type": "Report",
|
||||||
|
"doctype": "Dashboard Chart",
|
||||||
|
"filters_json": json.dumps({
|
||||||
|
"company": company.name
|
||||||
|
}),
|
||||||
|
"is_custom": 1,
|
||||||
|
"is_public": 1,
|
||||||
|
"owner": "Administrator",
|
||||||
|
"report_name": "Item Shortage Report",
|
||||||
|
"type": "Bar"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
def get_number_cards():
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
"name": "Total Active Items",
|
||||||
|
"label": _("Total Active Items"),
|
||||||
|
"function": "Count",
|
||||||
|
"doctype": "Number Card",
|
||||||
|
"document_type": "Item",
|
||||||
|
"filters_json": json.dumps([["Item", "disabled", "=", 0]]),
|
||||||
|
"is_public": 1,
|
||||||
|
"owner": "Administrator",
|
||||||
|
"show_percentage_stats": 1,
|
||||||
|
"stats_time_interval": "Monthly"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Total Warehouses",
|
||||||
|
"label": _("Total Warehouses"),
|
||||||
|
"function": "Count",
|
||||||
|
"doctype": "Number Card",
|
||||||
|
"document_type": "Warehouse",
|
||||||
|
"filters_json": json.dumps([["Warehouse", "disabled", "=", 0]]),
|
||||||
|
"is_public": 1,
|
||||||
|
"owner": "Administrator",
|
||||||
|
"show_percentage_stats": 1,
|
||||||
|
"stats_time_interval": "Monthly"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Total Stock Value",
|
||||||
|
"label": _("Total Stock Value"),
|
||||||
|
"function": "Sum",
|
||||||
|
"aggregate_function_based_on": "stock_value",
|
||||||
|
"doctype": "Number Card",
|
||||||
|
"document_type": "Bin",
|
||||||
|
"filters_json": json.dumps([]),
|
||||||
|
"is_public": 1,
|
||||||
|
"owner": "Administrator",
|
||||||
|
"show_percentage_stats": 1,
|
||||||
|
"stats_time_interval": "Daily"
|
||||||
|
}
|
||||||
|
]
|
@ -1,9 +1,14 @@
|
|||||||
{
|
{
|
||||||
"cards": [
|
"cards": [
|
||||||
|
{
|
||||||
|
"hidden": 0,
|
||||||
|
"label": "Items and Pricing",
|
||||||
|
"links": "[\n {\n \"label\": \"Item\",\n \"name\": \"Item\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Item Group\",\n \"link\": \"Tree/Item Group\",\n \"name\": \"Item Group\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Product Bundle\",\n \"name\": \"Product Bundle\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Price List\",\n \"name\": \"Price List\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Item Price\",\n \"name\": \"Item Price\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Shipping Rule\",\n \"name\": \"Shipping Rule\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Pricing Rule\",\n \"name\": \"Pricing Rule\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Item Alternative\",\n \"name\": \"Item Alternative\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Item Manufacturer\",\n \"name\": \"Item Manufacturer\",\n \"type\": \"doctype\"\n }\n]"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"label": "Stock Transactions",
|
"label": "Stock Transactions",
|
||||||
"links": "[\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 \"Item\",\n \"Customer\"\n ],\n \"label\": \"Delivery Note\",\n \"name\": \"Delivery Note\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Supplier\"\n ],\n \"label\": \"Purchase Receipt\",\n \"name\": \"Purchase Receipt\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Material Request\",\n \"name\": \"Material Request\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Pick List\",\n \"name\": \"Pick List\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Delivery Trip\",\n \"name\": \"Delivery Trip\",\n \"type\": \"doctype\"\n }\n]"
|
"links": "[\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Material Request\",\n \"name\": \"Material Request\",\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 \"Item\",\n \"Customer\"\n ],\n \"label\": \"Delivery Note\",\n \"name\": \"Delivery Note\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\",\n \"Supplier\"\n ],\n \"label\": \"Purchase Receipt\",\n \"name\": \"Purchase Receipt\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"label\": \"Pick List\",\n \"name\": \"Pick List\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Delivery Trip\",\n \"name\": \"Delivery Trip\",\n \"type\": \"doctype\"\n }\n]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@ -13,12 +18,7 @@
|
|||||||
{
|
{
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"label": "Settings",
|
"label": "Settings",
|
||||||
"links": "[\n {\n \"label\": \"Stock Settings\",\n \"name\": \"Stock Settings\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Warehouse\",\n \"name\": \"Warehouse\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Unit of Measure (UOM)\",\n \"name\": \"UOM\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Brand\",\n \"name\": \"Brand\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Item Attribute\",\n \"name\": \"Item Attribute\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Item Variant Settings\",\n \"name\": \"Item Variant Settings\",\n \"type\": \"doctype\"\n }\n]"
|
"links": "[\n {\n \"label\": \"Stock Settings\",\n \"name\": \"Stock Settings\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Warehouse\",\n \"name\": \"Warehouse\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Unit of Measure (UOM)\",\n \"name\": \"UOM\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Item Variant Settings\",\n \"name\": \"Item Variant Settings\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Brand\",\n \"name\": \"Brand\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Item Attribute\",\n \"name\": \"Item Attribute\",\n \"type\": \"doctype\"\n }\n]"
|
||||||
},
|
|
||||||
{
|
|
||||||
"hidden": 0,
|
|
||||||
"label": "Items and Pricing",
|
|
||||||
"links": "[\n {\n \"label\": \"Item\",\n \"name\": \"Item\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Product Bundle\",\n \"name\": \"Product Bundle\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"icon\": \"fa fa-sitemap\",\n \"label\": \"Item Group\",\n \"link\": \"Tree/Item Group\",\n \"name\": \"Item Group\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Price List\",\n \"name\": \"Price List\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Item Price\",\n \"name\": \"Item Price\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Shipping Rule\",\n \"name\": \"Shipping Rule\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Pricing Rule\",\n \"name\": \"Pricing Rule\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Item Alternative\",\n \"name\": \"Item Alternative\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Item Manufacturer\",\n \"name\": \"Item Manufacturer\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Item Variant Settings\",\n \"name\": \"Item Variant Settings\",\n \"type\": \"doctype\"\n }\n]"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@ -41,34 +41,46 @@
|
|||||||
"links": "[\n {\n \"dependencies\": [\n \"Material Request\"\n ],\n \"doctype\": \"Material Request\",\n \"is_query_report\": true,\n \"label\": \"Requested Items To Be Transferred\",\n \"name\": \"Requested Items To Be Transferred\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Stock Ledger Entry\"\n ],\n \"doctype\": \"Stock Ledger Entry\",\n \"is_query_report\": true,\n \"label\": \"Batch Item Expiry Status\",\n \"name\": \"Batch Item Expiry Status\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Price List\"\n ],\n \"doctype\": \"Price List\",\n \"is_query_report\": true,\n \"label\": \"Item Prices\",\n \"name\": \"Item Prices\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Itemwise Recommended Reorder Level\",\n \"name\": \"Itemwise Recommended Reorder Level\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Item Variant Details\",\n \"name\": \"Item Variant Details\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Order\"\n ],\n \"doctype\": \"Purchase Order\",\n \"is_query_report\": true,\n \"label\": \"Subcontracted Raw Materials To Be Transferred\",\n \"name\": \"Subcontracted Raw Materials To Be Transferred\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Order\"\n ],\n \"doctype\": \"Purchase Order\",\n \"is_query_report\": true,\n \"label\": \"Subcontracted Item To Be Received\",\n \"name\": \"Subcontracted Item To Be Received\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Stock Ledger Entry\"\n ],\n \"doctype\": \"Stock Ledger Entry\",\n \"is_query_report\": true,\n \"label\": \"Stock and Account Value Comparison\",\n \"name\": \"Stock and Account Value Comparison\",\n \"type\": \"report\"\n }\n]"
|
"links": "[\n {\n \"dependencies\": [\n \"Material Request\"\n ],\n \"doctype\": \"Material Request\",\n \"is_query_report\": true,\n \"label\": \"Requested Items To Be Transferred\",\n \"name\": \"Requested Items To Be Transferred\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Stock Ledger Entry\"\n ],\n \"doctype\": \"Stock Ledger Entry\",\n \"is_query_report\": true,\n \"label\": \"Batch Item Expiry Status\",\n \"name\": \"Batch Item Expiry Status\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Price List\"\n ],\n \"doctype\": \"Price List\",\n \"is_query_report\": true,\n \"label\": \"Item Prices\",\n \"name\": \"Item Prices\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Itemwise Recommended Reorder Level\",\n \"name\": \"Itemwise Recommended Reorder Level\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Item\"\n ],\n \"doctype\": \"Item\",\n \"is_query_report\": true,\n \"label\": \"Item Variant Details\",\n \"name\": \"Item Variant Details\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Order\"\n ],\n \"doctype\": \"Purchase Order\",\n \"is_query_report\": true,\n \"label\": \"Subcontracted Raw Materials To Be Transferred\",\n \"name\": \"Subcontracted Raw Materials To Be Transferred\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Purchase Order\"\n ],\n \"doctype\": \"Purchase Order\",\n \"is_query_report\": true,\n \"label\": \"Subcontracted Item To Be Received\",\n \"name\": \"Subcontracted Item To Be Received\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Stock Ledger Entry\"\n ],\n \"doctype\": \"Stock Ledger Entry\",\n \"is_query_report\": true,\n \"label\": \"Stock and Account Value Comparison\",\n \"name\": \"Stock and Account Value Comparison\",\n \"type\": \"report\"\n }\n]"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"cards_label": "Masters & Reports",
|
||||||
"category": "Modules",
|
"category": "Modules",
|
||||||
"charts": [],
|
"charts": [
|
||||||
|
{
|
||||||
|
"chart_name": "Warehouse wise Stock Value"
|
||||||
|
}
|
||||||
|
],
|
||||||
"creation": "2020-03-02 15:43:10.096528",
|
"creation": "2020-03-02 15:43:10.096528",
|
||||||
"developer_mode_only": 0,
|
"developer_mode_only": 0,
|
||||||
"disable_user_customization": 0,
|
"disable_user_customization": 0,
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Desk Page",
|
"doctype": "Desk Page",
|
||||||
"extends_another_page": 0,
|
"extends_another_page": 0,
|
||||||
"icon": "",
|
"hide_custom": 0,
|
||||||
"idx": 0,
|
"idx": 0,
|
||||||
"is_standard": 1,
|
"is_standard": 1,
|
||||||
"label": "Stock",
|
"label": "Stock",
|
||||||
"modified": "2020-04-01 11:28:51.148421",
|
"modified": "2020-05-19 17:36:08.185652",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Stock",
|
"name": "Stock",
|
||||||
|
"onboarding": "Stock",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"pin_to_bottom": 0,
|
"pin_to_bottom": 0,
|
||||||
"pin_to_top": 0,
|
"pin_to_top": 0,
|
||||||
"shortcuts": [
|
"shortcuts": [
|
||||||
{
|
{
|
||||||
|
"color": "#cef6d1",
|
||||||
|
"format": "{} available",
|
||||||
"label": "Item",
|
"label": "Item",
|
||||||
"link_to": "Item",
|
"link_to": "Item",
|
||||||
|
"stats_filter": "{\n \"disabled\" : 0\n}",
|
||||||
"type": "DocType"
|
"type": "DocType"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "Pricing Rule",
|
"color": "#ffe8cd",
|
||||||
"link_to": "Pricing Rule",
|
"format": "{} Pending",
|
||||||
|
"label": "Material Request",
|
||||||
|
"link_to": "Material Request",
|
||||||
|
"stats_filter": "{\n \"company\": [\"like\", '%' + frappe.defaults.get_global_default(\"company\") + '%'],\n \"status\": \"Pending\"\n}",
|
||||||
"type": "DocType"
|
"type": "DocType"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -76,6 +88,22 @@
|
|||||||
"link_to": "Stock Entry",
|
"link_to": "Stock Entry",
|
||||||
"type": "DocType"
|
"type": "DocType"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"color": "#ffe8cd",
|
||||||
|
"format": "{} to Bill",
|
||||||
|
"label": "Purchase Receipt",
|
||||||
|
"link_to": "Purchase Receipt",
|
||||||
|
"stats_filter": "{\n \"company\": [\"like\", '%' + frappe.defaults.get_global_default(\"company\") + '%'],\n \"status\": \"To Bill\"\n}",
|
||||||
|
"type": "DocType"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"color": "#ffe8cd",
|
||||||
|
"format": "{} to Bill",
|
||||||
|
"label": "Delivery Note",
|
||||||
|
"link_to": "Delivery Note",
|
||||||
|
"stats_filter": "{\n \"company\": [\"like\", '%' + frappe.defaults.get_global_default(\"company\") + '%'],\n \"status\": \"To Bill\"\n}",
|
||||||
|
"type": "DocType"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"label": "Stock Ledger",
|
"label": "Stock Ledger",
|
||||||
"link_to": "Stock Ledger",
|
"link_to": "Stock Ledger",
|
||||||
@ -85,6 +113,12 @@
|
|||||||
"label": "Stock Balance",
|
"label": "Stock Balance",
|
||||||
"link_to": "Stock Balance",
|
"link_to": "Stock Balance",
|
||||||
"type": "Report"
|
"type": "Report"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Stock Dashboard",
|
||||||
|
"link_to": "Stock",
|
||||||
|
"type": "Dashboard"
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"shortcuts_label": "Quick Access"
|
||||||
}
|
}
|
@ -15,3 +15,37 @@ frappe.ui.form.on('Stock Settings', {
|
|||||||
frm.set_query("sample_retention_warehouse", filters);
|
frm.set_query("sample_retention_warehouse", filters);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
frappe.tour['Stock Settings'] = [
|
||||||
|
{
|
||||||
|
fieldname: "item_naming_by",
|
||||||
|
title: __("Item Naming By"),
|
||||||
|
description: __("By default, the Item Name is set as per the Item Code entered. If you want Items to be named by a set Naming Series choose the 'Naming Series' option.")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname: "default_warehouse",
|
||||||
|
title: __("Default Warehouse"),
|
||||||
|
description: __("Set a Default Warehouse for Inventory Transactions. This will be fetched into the Default Warehouse in the Item master.")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname: "allow_negative_stock",
|
||||||
|
title: __("Allow Negative Stock"),
|
||||||
|
description: __("This will allow stock items to be displayed in negative values. Using this option depends on your use case. With this option unchecked, the system warns before obstructing a transaction that is causing negative stock.")
|
||||||
|
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname: "valuation_method",
|
||||||
|
title: __("Valuation Method"),
|
||||||
|
description: __("Choose between FIFO and Moving Average Valuation Methods. Click ") + "<a href='https://docs.erpnext.com/docs/user/manual/en/stock/articles/item-valuation-fifo-and-moving-average'>here</a>" + __(" to know more about them.")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname: "show_barcode_field",
|
||||||
|
title: __("Show Barcode Field"),
|
||||||
|
description: __("Show 'Scan Barcode' field above every child table to insert Items with ease.")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname: "automatically_set_serial_nos_based_on_fifo",
|
||||||
|
title: __("Automatically Set Serial Nos based on FIFO"),
|
||||||
|
description: __("Serial numbers for stock will be set automatically based on the Items entered based on first in first out in transactions like Purchase/Sales Invoices, Delivery Notes, etc.")
|
||||||
|
}
|
||||||
|
];
|
||||||
|
54
erpnext/stock/module_onboarding/stock/stock.json
Normal file
54
erpnext/stock/module_onboarding/stock/stock.json
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
{
|
||||||
|
"allow_roles": [
|
||||||
|
{
|
||||||
|
"role": "Manufacturing Manager"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "Stock Manager"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "Manufacturing User"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "Stock User"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"creation": "2020-05-15 03:18:44.400108",
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "Module Onboarding",
|
||||||
|
"documentation_url": "https://docs.erpnext.com/docs/user/manual/en/stock",
|
||||||
|
"idx": 0,
|
||||||
|
"is_complete": 0,
|
||||||
|
"modified": "2020-05-19 19:03:23.602423",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Stock",
|
||||||
|
"name": "Stock",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"step": "Setup your Warehouse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step": "Create a Product"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step": "Introduction to Stock Entry"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step": "Create a Stock Entry"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step": "Create a Supplier"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step": "Create a Purchase Receipt"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step": "Stock Settings"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"subtitle": "Inventory, Warehouses, Analysis and more.",
|
||||||
|
"success_message": "The Stock Module is all set up!",
|
||||||
|
"title": "Let's Setup the Stock Module.",
|
||||||
|
"user_can_dismiss": 1
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"action": "Update Settings",
|
||||||
|
"creation": "2020-05-06 15:53:44.667414",
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "Onboarding Step",
|
||||||
|
"idx": 0,
|
||||||
|
"is_complete": 0,
|
||||||
|
"is_mandatory": 0,
|
||||||
|
"is_single": 0,
|
||||||
|
"is_skipped": 0,
|
||||||
|
"modified": "2020-05-12 18:30:06.323797",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"name": "Buying Settings",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"reference_document": "Buying Settings",
|
||||||
|
"show_full_form": 0,
|
||||||
|
"title": "Configure Buying Settings.",
|
||||||
|
"validate_action": 1
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"action": "Create Entry",
|
||||||
|
"creation": "2020-05-12 18:16:06.624554",
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "Onboarding Step",
|
||||||
|
"idx": 0,
|
||||||
|
"is_complete": 0,
|
||||||
|
"is_mandatory": 0,
|
||||||
|
"is_single": 0,
|
||||||
|
"is_skipped": 0,
|
||||||
|
"modified": "2020-05-12 18:30:02.489949",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"name": "Create a Product",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"reference_document": "Item",
|
||||||
|
"show_full_form": 0,
|
||||||
|
"title": "Create a Product",
|
||||||
|
"validate_action": 1
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"action": "Create Entry",
|
||||||
|
"creation": "2020-05-19 18:59:13.266713",
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "Onboarding Step",
|
||||||
|
"idx": 0,
|
||||||
|
"is_complete": 0,
|
||||||
|
"is_mandatory": 0,
|
||||||
|
"is_single": 0,
|
||||||
|
"is_skipped": 0,
|
||||||
|
"modified": "2020-05-19 18:59:13.266713",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"name": "Create a Purchase Receipt",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"reference_document": "Purchase Receipt",
|
||||||
|
"show_full_form": 1,
|
||||||
|
"title": "Create a Purchase Receipt",
|
||||||
|
"validate_action": 1
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"action": "Create Entry",
|
||||||
|
"creation": "2020-05-15 03:20:16.277043",
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "Onboarding Step",
|
||||||
|
"idx": 0,
|
||||||
|
"is_complete": 0,
|
||||||
|
"is_mandatory": 0,
|
||||||
|
"is_single": 0,
|
||||||
|
"is_skipped": 0,
|
||||||
|
"modified": "2020-05-15 03:30:58.047696",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"name": "Create a Stock Entry",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"reference_document": "Stock Entry",
|
||||||
|
"show_full_form": 1,
|
||||||
|
"title": "Create a Stock Entry",
|
||||||
|
"validate_action": 1
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"action": "Create Entry",
|
||||||
|
"creation": "2020-05-14 22:09:10.043554",
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "Onboarding Step",
|
||||||
|
"idx": 0,
|
||||||
|
"is_complete": 0,
|
||||||
|
"is_mandatory": 0,
|
||||||
|
"is_single": 0,
|
||||||
|
"is_skipped": 0,
|
||||||
|
"modified": "2020-05-14 22:09:10.043554",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"name": "Create a Supplier",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"reference_document": "Supplier",
|
||||||
|
"show_full_form": 0,
|
||||||
|
"title": "Create a Supplier",
|
||||||
|
"validate_action": 1
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"action": "Watch Video",
|
||||||
|
"creation": "2020-05-15 02:47:17.958806",
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "Onboarding Step",
|
||||||
|
"idx": 0,
|
||||||
|
"is_complete": 0,
|
||||||
|
"is_mandatory": 0,
|
||||||
|
"is_single": 0,
|
||||||
|
"is_skipped": 0,
|
||||||
|
"modified": "2020-05-19 18:55:41.457289",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"name": "Introduction to Stock Entry",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"show_full_form": 0,
|
||||||
|
"title": "Introduction to the multi-purpose stock transaction",
|
||||||
|
"validate_action": 1,
|
||||||
|
"video_url": "https://www.youtube.com/watch?v=Njt107hlY3I"
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"action": "Go to Page",
|
||||||
|
"creation": "2020-05-19 18:54:19.383397",
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "Onboarding Step",
|
||||||
|
"idx": 0,
|
||||||
|
"is_complete": 0,
|
||||||
|
"is_mandatory": 0,
|
||||||
|
"is_single": 0,
|
||||||
|
"is_skipped": 0,
|
||||||
|
"modified": "2020-05-19 18:54:19.383397",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"name": "Setup your Warehouse",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"path": "Tree/Warehouse",
|
||||||
|
"reference_document": "Warehouse",
|
||||||
|
"show_full_form": 0,
|
||||||
|
"title": "Setup your Warehouse",
|
||||||
|
"validate_action": 1
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"action": "Show Form Tour",
|
||||||
|
"creation": "2020-05-15 02:53:57.209967",
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "Onboarding Step",
|
||||||
|
"idx": 0,
|
||||||
|
"is_complete": 0,
|
||||||
|
"is_mandatory": 0,
|
||||||
|
"is_single": 1,
|
||||||
|
"is_skipped": 0,
|
||||||
|
"modified": "2020-05-15 03:55:15.444151",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"name": "Stock Settings",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"reference_document": "Stock Settings",
|
||||||
|
"show_full_form": 0,
|
||||||
|
"title": "Explore Stock Settings",
|
||||||
|
"validate_action": 1
|
||||||
|
}
|
@ -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):
|
||||||
@ -11,4 +12,38 @@ def execute(filters=None):
|
|||||||
conditions = get_columns(filters, "Delivery Note")
|
conditions = get_columns(filters, "Delivery Note")
|
||||||
data = get_data(filters, conditions)
|
data = get_data(filters, conditions)
|
||||||
|
|
||||||
return conditions["columns"], data
|
chart_data = get_chart_data(data, filters)
|
||||||
|
|
||||||
|
return conditions["columns"], data, None, chart_data
|
||||||
|
|
||||||
|
def get_chart_data(data, filters):
|
||||||
|
if not data:
|
||||||
|
return []
|
||||||
|
|
||||||
|
labels, datapoints = [], []
|
||||||
|
|
||||||
|
if filters.get("group_by"):
|
||||||
|
# consider only consolidated row
|
||||||
|
data = [row for row in data if row[0]]
|
||||||
|
|
||||||
|
if len(data) > 10:
|
||||||
|
# get top 10 if data too long
|
||||||
|
data = sorted(data, key = lambda i: i[-1],reverse=True)
|
||||||
|
data = data[:10]
|
||||||
|
|
||||||
|
for row in data:
|
||||||
|
labels.append(row[0])
|
||||||
|
datapoints.append(row[-1])
|
||||||
|
|
||||||
|
return {
|
||||||
|
"data": {
|
||||||
|
"labels" : labels,
|
||||||
|
"datasets" : [
|
||||||
|
{
|
||||||
|
"name": _("Total Delivered Amount"),
|
||||||
|
"values": datapoints
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"type" : "bar"
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
/* eslint-disable */
|
||||||
|
|
||||||
|
frappe.query_reports["Item Shortage Report"] = {
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"fieldname": "company",
|
||||||
|
"label": __("Company"),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"width": "80",
|
||||||
|
"options": "Company",
|
||||||
|
"reqd": 1,
|
||||||
|
"default": frappe.defaults.get_default("company")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "warehouse",
|
||||||
|
"label": __("Warehouse"),
|
||||||
|
"fieldtype": "MultiSelectList",
|
||||||
|
"width": "100",
|
||||||
|
get_data: function(txt) {
|
||||||
|
return frappe.db.get_link_options('Warehouse', txt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
@ -1,22 +1,23 @@
|
|||||||
{
|
{
|
||||||
"add_total_row": 0,
|
"add_total_row": 0,
|
||||||
"apply_user_permissions": 1,
|
|
||||||
"creation": "2013-08-20 13:43:30",
|
"creation": "2013-08-20 13:43:30",
|
||||||
|
"disable_prepared_report": 0,
|
||||||
"disabled": 0,
|
"disabled": 0,
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Report",
|
"doctype": "Report",
|
||||||
"idx": 3,
|
"idx": 3,
|
||||||
"is_standard": "Yes",
|
"is_standard": "Yes",
|
||||||
"json": "{\"add_total_row\": 0, \"sort_by\": \"Bin.projected_qty\", \"sort_order\": \"asc\", \"sort_by_next\": \"\", \"filters\": [[\"Bin\", \"projected_qty\", \"<\", \"0\"]], \"sort_order_next\": \"desc\", \"columns\": [[\"warehouse\", \"Bin\"], [\"item_code\", \"Bin\"], [\"actual_qty\", \"Bin\"], [\"ordered_qty\", \"Bin\"], [\"planned_qty\", \"Bin\"], [\"reserved_qty\", \"Bin\"], [\"projected_qty\", \"Bin\"]]}",
|
"json": "{\"add_total_row\": 0, \"sort_by\": \"Bin.projected_qty\", \"sort_order\": \"asc\", \"sort_by_next\": \"\", \"filters\": [[\"Bin\", \"projected_qty\", \"<\", \"0\"]], \"sort_order_next\": \"desc\", \"columns\": [[\"warehouse\", \"Bin\"], [\"item_code\", \"Bin\"], [\"actual_qty\", \"Bin\"], [\"ordered_qty\", \"Bin\"], [\"planned_qty\", \"Bin\"], [\"reserved_qty\", \"Bin\"], [\"projected_qty\", \"Bin\"]]}",
|
||||||
"modified": "2017-02-24 20:00:46.439935",
|
"modified": "2020-05-14 12:32:07.158991",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Item Shortage Report",
|
"name": "Item Shortage Report",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"query": "SELECT bin.warehouse as \"Warehouse:Link/Warehouse:150\",\n\tbin.item_code as \"Item Code:Link/Item:100\",\n\tbin.actual_qty as \"Actual Quantity:Float:120\",\n\tbin.ordered_qty as \"Ordered Quantity:Float:120\",\n\tbin.planned_qty as \"Planned Quantity:Float:120\",\n\tbin.reserved_qty as \"Reserved Quantity:Float:120\",\n\tbin.projected_qty as \"Project Quantity:Float:120\",\n\titem.item_name as \"Item Name:Data:150\",\n\titem.description as \"Description::200\"\nFROM tabBin as bin\nINNER JOIN tabItem as item\nON bin.item_code=item.name\nWHERE bin.projected_qty<0\nORDER BY bin.projected_qty;",
|
"prepared_report": 0,
|
||||||
|
"query": "",
|
||||||
"ref_doctype": "Bin",
|
"ref_doctype": "Bin",
|
||||||
"report_name": "Item Shortage Report",
|
"report_name": "Item Shortage Report",
|
||||||
"report_type": "Query Report",
|
"report_type": "Script Report",
|
||||||
"roles": [
|
"roles": [
|
||||||
{
|
{
|
||||||
"role": "Sales User"
|
"role": "Sales User"
|
||||||
|
@ -0,0 +1,162 @@
|
|||||||
|
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
from frappe import _
|
||||||
|
|
||||||
|
def execute(filters=None):
|
||||||
|
columns = get_columns()
|
||||||
|
conditions = get_conditions(filters)
|
||||||
|
data = get_data(conditions, filters)
|
||||||
|
|
||||||
|
if not data:
|
||||||
|
return [], [], None, []
|
||||||
|
|
||||||
|
chart_data = get_chart_data(data)
|
||||||
|
|
||||||
|
return columns, data, None, chart_data
|
||||||
|
|
||||||
|
def get_conditions(filters):
|
||||||
|
conditions = ""
|
||||||
|
|
||||||
|
if filters.get("warehouse"):
|
||||||
|
conditions += "AND warehouse in %(warehouse)s"
|
||||||
|
if filters.get("company"):
|
||||||
|
conditions += "AND company = %(company)s"
|
||||||
|
|
||||||
|
return conditions
|
||||||
|
|
||||||
|
def get_data(conditions, filters):
|
||||||
|
data = frappe.db.sql("""
|
||||||
|
SELECT
|
||||||
|
bin.warehouse,
|
||||||
|
bin.item_code,
|
||||||
|
bin.actual_qty ,
|
||||||
|
bin.ordered_qty ,
|
||||||
|
bin.planned_qty ,
|
||||||
|
bin.reserved_qty ,
|
||||||
|
bin.reserved_qty_for_production,
|
||||||
|
bin.projected_qty ,
|
||||||
|
warehouse.company,
|
||||||
|
item.item_name ,
|
||||||
|
item.description
|
||||||
|
FROM
|
||||||
|
`tabBin` bin,
|
||||||
|
`tabWarehouse` warehouse,
|
||||||
|
`tabItem` item
|
||||||
|
WHERE
|
||||||
|
bin.projected_qty<0
|
||||||
|
AND warehouse.name = bin.warehouse
|
||||||
|
AND bin.item_code=item.name
|
||||||
|
{0}
|
||||||
|
ORDER BY bin.projected_qty;""".format(conditions), filters, as_dict=1)
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
def get_chart_data(data):
|
||||||
|
labels, datapoints = [], []
|
||||||
|
|
||||||
|
for row in data:
|
||||||
|
labels.append(row.get("item_code"))
|
||||||
|
datapoints.append(row.get("projected_qty"))
|
||||||
|
|
||||||
|
if len(data) > 10:
|
||||||
|
labels = labels[:10]
|
||||||
|
datapoints = datapoints[:10]
|
||||||
|
|
||||||
|
return {
|
||||||
|
"data": {
|
||||||
|
"labels": labels,
|
||||||
|
"datasets":[
|
||||||
|
{
|
||||||
|
"name": _("Projected Qty"),
|
||||||
|
"values": datapoints
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"type": "bar"
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_columns():
|
||||||
|
columns = [
|
||||||
|
{
|
||||||
|
"label": _("Warehouse"),
|
||||||
|
"fieldname": "warehouse",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Warehouse",
|
||||||
|
"width": 150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Item"),
|
||||||
|
"fieldname": "item_code",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Item",
|
||||||
|
"width": 150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Actual Quantity"),
|
||||||
|
"fieldname": "actual_qty",
|
||||||
|
"fieldtype": "Float",
|
||||||
|
"width": 120,
|
||||||
|
"convertible": "qty"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Ordered Quantity"),
|
||||||
|
"fieldname": "ordered_qty",
|
||||||
|
"fieldtype": "Float",
|
||||||
|
"width": 120,
|
||||||
|
"convertible": "qty"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Planned Quantity"),
|
||||||
|
"fieldname": "planned_qty",
|
||||||
|
"fieldtype": "Float",
|
||||||
|
"width": 120,
|
||||||
|
"convertible": "qty"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Reserved Quantity"),
|
||||||
|
"fieldname": "reserved_qty",
|
||||||
|
"fieldtype": "Float",
|
||||||
|
"width": 120,
|
||||||
|
"convertible": "qty"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Reserved Quantity for Production"),
|
||||||
|
"fieldname": "reserved_qty_for_production",
|
||||||
|
"fieldtype": "Float",
|
||||||
|
"width": 120,
|
||||||
|
"convertible": "qty"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Projected Quantity"),
|
||||||
|
"fieldname": "projected_qty",
|
||||||
|
"fieldtype": "Float",
|
||||||
|
"width": 120,
|
||||||
|
"convertible": "qty"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Company"),
|
||||||
|
"fieldname": "company",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Company",
|
||||||
|
"width": 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Item Name"),
|
||||||
|
"fieldname": "item_name",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"width": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Description"),
|
||||||
|
"fieldname": "description",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"width": 120
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
return columns
|
||||||
|
|
||||||
|
|
@ -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):
|
||||||
@ -11,4 +12,39 @@ def execute(filters=None):
|
|||||||
conditions = get_columns(filters, "Purchase Receipt")
|
conditions = get_columns(filters, "Purchase Receipt")
|
||||||
data = get_data(filters, conditions)
|
data = get_data(filters, conditions)
|
||||||
|
|
||||||
return conditions["columns"], data
|
chart_data = get_chart_data(data, filters)
|
||||||
|
|
||||||
|
return conditions["columns"], data, None, chart_data
|
||||||
|
|
||||||
|
def get_chart_data(data, filters):
|
||||||
|
if not data:
|
||||||
|
return []
|
||||||
|
|
||||||
|
labels, datapoints = [], []
|
||||||
|
|
||||||
|
if filters.get("group_by"):
|
||||||
|
# consider only consolidated row
|
||||||
|
data = [row for row in data if row[0]]
|
||||||
|
|
||||||
|
if len(data) > 10:
|
||||||
|
# get top 10 if data too long
|
||||||
|
data = sorted(data, key = lambda i: i[-1],reverse=True)
|
||||||
|
data = data[:10]
|
||||||
|
|
||||||
|
for row in data:
|
||||||
|
labels.append(row[0])
|
||||||
|
datapoints.append(row[-1])
|
||||||
|
|
||||||
|
return {
|
||||||
|
"data": {
|
||||||
|
"labels" : labels,
|
||||||
|
"datasets" : [
|
||||||
|
{
|
||||||
|
"name": _("Total Received Amount"),
|
||||||
|
"values": datapoints
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"type" : "bar",
|
||||||
|
"colors":["#5e64ff"]
|
||||||
|
}
|
@ -37,7 +37,9 @@ def execute(filters=None):
|
|||||||
|
|
||||||
data.append(row)
|
data.append(row)
|
||||||
|
|
||||||
return columns, data
|
chart_data = get_chart_data(data, filters)
|
||||||
|
|
||||||
|
return columns, data, None, chart_data
|
||||||
|
|
||||||
def get_average_age(fifo_queue, to_date):
|
def get_average_age(fifo_queue, to_date):
|
||||||
batch_age = age_qty = total_qty = 0.0
|
batch_age = age_qty = total_qty = 0.0
|
||||||
@ -51,7 +53,7 @@ def get_average_age(fifo_queue, to_date):
|
|||||||
age_qty += batch_age * 1
|
age_qty += batch_age * 1
|
||||||
total_qty += 1
|
total_qty += 1
|
||||||
|
|
||||||
return (age_qty / total_qty) if total_qty else 0.0
|
return flt(age_qty / total_qty, 2) if total_qty else 0.0
|
||||||
|
|
||||||
def get_columns(filters):
|
def get_columns(filters):
|
||||||
columns = [
|
columns = [
|
||||||
@ -230,3 +232,34 @@ def get_sle_conditions(filters):
|
|||||||
where wh.lft >= {0} and rgt <= {1})""".format(lft, rgt))
|
where wh.lft >= {0} and rgt <= {1})""".format(lft, rgt))
|
||||||
|
|
||||||
return "and {}".format(" and ".join(conditions)) if conditions else ""
|
return "and {}".format(" and ".join(conditions)) if conditions else ""
|
||||||
|
|
||||||
|
def get_chart_data(data, filters):
|
||||||
|
if not data:
|
||||||
|
return []
|
||||||
|
|
||||||
|
labels, datapoints = [], []
|
||||||
|
|
||||||
|
if filters.get("show_warehouse_wise_stock"):
|
||||||
|
return {}
|
||||||
|
|
||||||
|
data.sort(key = lambda row: row[6], reverse=True)
|
||||||
|
|
||||||
|
if len(data) > 10:
|
||||||
|
data = data[:10]
|
||||||
|
|
||||||
|
for row in data:
|
||||||
|
labels.append(row[0])
|
||||||
|
datapoints.append(row[6])
|
||||||
|
|
||||||
|
return {
|
||||||
|
"data" : {
|
||||||
|
"labels": labels,
|
||||||
|
"datasets": [
|
||||||
|
{
|
||||||
|
"name": _("Average Age"),
|
||||||
|
"values": datapoints
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"type" : "bar"
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user