From 861aa9e08a4c95bbe26afab14c7bdd61637f80cd Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Tue, 6 Dec 2022 16:52:45 +0530 Subject: [PATCH] feat: warehouse wise stock balance --- .../warehouse_wise_stock_balance/__init__.py | 0 .../warehouse_wise_stock_balance.js | 20 +++ .../warehouse_wise_stock_balance.json | 30 ++++ .../warehouse_wise_stock_balance.py | 89 ++++++++++ erpnext/stock/workspace/stock/stock.json | 163 ++++++++++-------- 5 files changed, 226 insertions(+), 76 deletions(-) create mode 100644 erpnext/stock/report/warehouse_wise_stock_balance/__init__.py create mode 100644 erpnext/stock/report/warehouse_wise_stock_balance/warehouse_wise_stock_balance.js create mode 100644 erpnext/stock/report/warehouse_wise_stock_balance/warehouse_wise_stock_balance.json create mode 100644 erpnext/stock/report/warehouse_wise_stock_balance/warehouse_wise_stock_balance.py diff --git a/erpnext/stock/report/warehouse_wise_stock_balance/__init__.py b/erpnext/stock/report/warehouse_wise_stock_balance/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/stock/report/warehouse_wise_stock_balance/warehouse_wise_stock_balance.js b/erpnext/stock/report/warehouse_wise_stock_balance/warehouse_wise_stock_balance.js new file mode 100644 index 0000000000..58a043ec20 --- /dev/null +++ b/erpnext/stock/report/warehouse_wise_stock_balance/warehouse_wise_stock_balance.js @@ -0,0 +1,20 @@ +// Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt +/* eslint-disable */ + +frappe.query_reports["Warehouse Wise Stock Balance"] = { + "filters": [ + { + "fieldname":"company", + "label": __("Company"), + "fieldtype": "Link", + "options": "Company", + "reqd": 1, + "default": frappe.defaults.get_user_default("Company") + } + ], + "initial_depth": 3, + "tree": true, + "parent_field": "parent_warehouse", + "name_field": "warehouse" +}; diff --git a/erpnext/stock/report/warehouse_wise_stock_balance/warehouse_wise_stock_balance.json b/erpnext/stock/report/warehouse_wise_stock_balance/warehouse_wise_stock_balance.json new file mode 100644 index 0000000000..4f7ec65de3 --- /dev/null +++ b/erpnext/stock/report/warehouse_wise_stock_balance/warehouse_wise_stock_balance.json @@ -0,0 +1,30 @@ +{ + "add_total_row": 0, + "columns": [], + "creation": "2022-12-06 14:15:31.924345", + "disable_prepared_report": 0, + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "filters": [], + "idx": 0, + "is_standard": "Yes", + "json": "{}", + "modified": "2022-12-06 14:16:55.969214", + "modified_by": "Administrator", + "module": "Stock", + "name": "Warehouse Wise Stock Balance", + "owner": "Administrator", + "prepared_report": 0, + "ref_doctype": "Stock Ledger Entry", + "report_name": "Warehouse Wise Stock Balance", + "report_type": "Script Report", + "roles": [ + { + "role": "Stock User" + }, + { + "role": "Accounts Manager" + } + ] +} \ No newline at end of file diff --git a/erpnext/stock/report/warehouse_wise_stock_balance/warehouse_wise_stock_balance.py b/erpnext/stock/report/warehouse_wise_stock_balance/warehouse_wise_stock_balance.py new file mode 100644 index 0000000000..81700099fa --- /dev/null +++ b/erpnext/stock/report/warehouse_wise_stock_balance/warehouse_wise_stock_balance.py @@ -0,0 +1,89 @@ +# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from typing import Any, Dict, List, Optional, TypedDict + +import frappe +from frappe import _ +from frappe.query_builder.functions import Sum + + +class StockBalanceFilter(TypedDict): + company: Optional[str] + warehouse: Optional[str] + + +SLEntry = Dict[str, Any] + + +def execute(filters=None): + columns, data = [], [] + columns = get_columns() + data = get_data(filters) + + return columns, data + + +def get_warehouse_wise_balance(filters: StockBalanceFilter) -> List[SLEntry]: + sle = frappe.qb.DocType("Stock Ledger Entry") + + query = ( + frappe.qb.from_(sle) + .select(sle.warehouse, Sum(sle.stock_value_difference).as_("stock_balance")) + .where((sle.docstatus < 2) & (sle.is_cancelled == 0)) + .groupby(sle.warehouse) + ) + + if filters.get("company"): + query = query.where(sle.company == filters.get("company")) + + data = query.run(as_list=True) + return frappe._dict(data) if data else frappe._dict() + + +def get_warehouses(report_filters: StockBalanceFilter): + return frappe.get_all( + "Warehouse", + fields=["name", "parent_warehouse", "is_group"], + filters={"company": report_filters.company, "disabled": 0}, + order_by="lft", + ) + + +def get_data(filters: StockBalanceFilter): + warehouse_balance = get_warehouse_wise_balance(filters) + warehouses = get_warehouses(filters) + + for warehouse in warehouses: + warehouse["stock_balance"] = warehouse_balance.get(warehouse.name, 0) + + update_indent(warehouses) + + return warehouses + + +def update_indent(warehouses): + for warehouse in warehouses: + + def add_indent(warehouse, indent): + warehouse.indent = indent + for child in warehouses: + if child.parent_warehouse == warehouse.name: + warehouse.stock_balance += child.stock_balance + add_indent(child, indent + 1) + + if warehouse.is_group: + add_indent(warehouse, warehouse.indent or 0) + + +def get_columns(): + return [ + { + "label": _("Warehouse"), + "fieldname": "name", + "fieldtype": "Link", + "options": "Warehouse", + "width": 200, + }, + {"label": _("Stock Balance"), "fieldname": "stock_balance", "fieldtype": "Float", "width": 150}, + ] diff --git a/erpnext/stock/workspace/stock/stock.json b/erpnext/stock/workspace/stock/stock.json index ed33067e73..de5e6de8f1 100644 --- a/erpnext/stock/workspace/stock/stock.json +++ b/erpnext/stock/workspace/stock/stock.json @@ -5,7 +5,7 @@ "label": "Warehouse wise Stock Value" } ], - "content": "[{\"type\":\"onboarding\",\"data\":{\"onboarding_name\":\"Stock\",\"col\":12}},{\"type\":\"chart\",\"data\":{\"chart_name\":\"Warehouse wise Stock Value\",\"col\":12}},{\"type\":\"spacer\",\"data\":{\"col\":12}},{\"type\":\"header\",\"data\":{\"text\":\"Quick Access\",\"col\":12}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Item\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Material Request\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Stock Entry\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Purchase Receipt\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Delivery Note\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Stock Ledger\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Stock Balance\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Dashboard\",\"col\":3}},{\"type\":\"spacer\",\"data\":{\"col\":12}},{\"type\":\"header\",\"data\":{\"text\":\"Masters & Reports\",\"col\":12}},{\"type\":\"card\",\"data\":{\"card_name\":\"Items and Pricing\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Stock Transactions\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Stock Reports\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Settings\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Serial No and Batch\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Tools\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Key Reports\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Other Reports\",\"col\":4}}]", + "content": "[{\"type\":\"onboarding\",\"data\":{\"onboarding_name\":\"Stock\",\"col\":12}},{\"type\":\"chart\",\"data\":{\"chart_name\":\"Warehouse wise Stock Value\",\"col\":12}},{\"type\":\"spacer\",\"data\":{\"col\":12}},{\"type\":\"header\",\"data\":{\"text\":\"Quick Access\",\"col\":12}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Item\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Material Request\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Stock Entry\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Purchase Receipt\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Delivery Note\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Stock Ledger\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Stock Balance\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Dashboard\",\"col\":3}},{\"type\":\"spacer\",\"data\":{\"col\":12}},{\"type\":\"header\",\"data\":{\"text\":\"Masters & Reports\",\"col\":12}},{\"type\":\"card\",\"data\":{\"card_name\":\"Items and Pricing\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Stock Transactions\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Stock Reports\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Settings\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Serial No and Batch\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Tools\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Key Reports\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Other Reports\",\"col\":4}}]", "creation": "2020-03-02 15:43:10.096528", "docstatus": 0, "doctype": "Workspace", @@ -207,80 +207,6 @@ "onboard": 0, "type": "Link" }, - { - "hidden": 0, - "is_query_report": 0, - "label": "Stock Reports", - "link_count": 0, - "onboard": 0, - "type": "Card Break" - }, - { - "dependencies": "Item", - "hidden": 0, - "is_query_report": 1, - "label": "Stock Ledger", - "link_count": 0, - "link_to": "Stock Ledger", - "link_type": "Report", - "onboard": 1, - "type": "Link" - }, - { - "dependencies": "Item", - "hidden": 0, - "is_query_report": 1, - "label": "Stock Balance", - "link_count": 0, - "link_to": "Stock Balance", - "link_type": "Report", - "onboard": 1, - "type": "Link" - }, - { - "dependencies": "Item", - "hidden": 0, - "is_query_report": 1, - "label": "Stock Projected Qty", - "link_count": 0, - "link_to": "Stock Projected Qty", - "link_type": "Report", - "onboard": 1, - "type": "Link" - }, - { - "dependencies": "Item", - "hidden": 0, - "is_query_report": 0, - "label": "Stock Summary", - "link_count": 0, - "link_to": "stock-balance", - "link_type": "Page", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "Item", - "hidden": 0, - "is_query_report": 1, - "label": "Stock Ageing", - "link_count": 0, - "link_to": "Stock Ageing", - "link_type": "Report", - "onboard": 0, - "type": "Link" - }, - { - "dependencies": "Item", - "hidden": 0, - "is_query_report": 1, - "label": "Item Price Stock", - "link_count": 0, - "link_to": "Item Price Stock", - "link_type": "Report", - "onboard": 0, - "type": "Link" - }, { "hidden": 0, "is_query_report": 0, @@ -705,15 +631,100 @@ "link_type": "Report", "onboard": 0, "type": "Link" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Stock Reports", + "link_count": 7, + "onboard": 0, + "type": "Card Break" + }, + { + "dependencies": "Item", + "hidden": 0, + "is_query_report": 1, + "label": "Stock Ledger", + "link_count": 0, + "link_to": "Stock Ledger", + "link_type": "Report", + "onboard": 1, + "type": "Link" + }, + { + "dependencies": "Item", + "hidden": 0, + "is_query_report": 1, + "label": "Stock Balance", + "link_count": 0, + "link_to": "Stock Balance", + "link_type": "Report", + "onboard": 1, + "type": "Link" + }, + { + "dependencies": "Item", + "hidden": 0, + "is_query_report": 1, + "label": "Stock Projected Qty", + "link_count": 0, + "link_to": "Stock Projected Qty", + "link_type": "Report", + "onboard": 1, + "type": "Link" + }, + { + "dependencies": "Item", + "hidden": 0, + "is_query_report": 0, + "label": "Stock Summary", + "link_count": 0, + "link_to": "stock-balance", + "link_type": "Page", + "onboard": 0, + "type": "Link" + }, + { + "dependencies": "Item", + "hidden": 0, + "is_query_report": 1, + "label": "Stock Ageing", + "link_count": 0, + "link_to": "Stock Ageing", + "link_type": "Report", + "onboard": 0, + "type": "Link" + }, + { + "dependencies": "Item", + "hidden": 0, + "is_query_report": 1, + "label": "Item Price Stock", + "link_count": 0, + "link_to": "Item Price Stock", + "link_type": "Report", + "onboard": 0, + "type": "Link" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Warehouse Wise Stock Balance", + "link_count": 0, + "link_to": "Warehouse Wise Stock Balance", + "link_type": "Report", + "onboard": 0, + "type": "Link" } ], - "modified": "2022-01-13 17:47:38.339931", + "modified": "2022-12-06 17:03:56.397272", "modified_by": "Administrator", "module": "Stock", "name": "Stock", "owner": "Administrator", "parent_page": "", "public": 1, + "quick_lists": [], "restrict_to_domain": "", "roles": [], "sequence_id": 24.0,