mirror of
https://github.com/frappe/erpnext.git
synced 2026-03-07 12:33:19 +00:00
feat: update stock balance report to support multi-select for items and warehouses
(cherry picked from commit 0d2a88bafc)
This commit is contained in:
@@ -36,38 +36,37 @@ frappe.query_reports["Stock Balance"] = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldname: "item_code",
|
fieldname: "item_code",
|
||||||
label: __("Item"),
|
label: __("Items"),
|
||||||
fieldtype: "Link",
|
fieldtype: "MultiSelectList",
|
||||||
width: "80",
|
width: "80",
|
||||||
options: "Item",
|
options: "Item",
|
||||||
get_query: function () {
|
get_data: function (txt) {
|
||||||
let item_group = frappe.query_report.get_filter_value("item_group");
|
let item_group = frappe.query_report.get_filter_value("item_group");
|
||||||
|
|
||||||
return {
|
let filters = {
|
||||||
query: "erpnext.controllers.queries.item_query",
|
...(item_group && { item_group }),
|
||||||
filters: {
|
is_stock_item: 1,
|
||||||
...(item_group && { item_group }),
|
|
||||||
is_stock_item: 1,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return frappe.db.get_link_options("Item", txt, filters);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldname: "warehouse",
|
fieldname: "warehouse",
|
||||||
label: __("Warehouse"),
|
label: __("Warehouses"),
|
||||||
fieldtype: "Link",
|
fieldtype: "MultiSelectList",
|
||||||
width: "80",
|
width: "80",
|
||||||
options: "Warehouse",
|
options: "Warehouse",
|
||||||
get_query: () => {
|
get_data: (txt) => {
|
||||||
let warehouse_type = frappe.query_report.get_filter_value("warehouse_type");
|
let warehouse_type = frappe.query_report.get_filter_value("warehouse_type");
|
||||||
let company = frappe.query_report.get_filter_value("company");
|
let company = frappe.query_report.get_filter_value("company");
|
||||||
|
|
||||||
return {
|
let filters = {
|
||||||
filters: {
|
...(warehouse_type && { warehouse_type }),
|
||||||
...(warehouse_type && { warehouse_type }),
|
...(company && { company }),
|
||||||
...(company && { company }),
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return frappe.db.get_link_options("Warehouse", txt, filters);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ from frappe.query_builder import Order
|
|||||||
from frappe.query_builder.functions import Coalesce
|
from frappe.query_builder.functions import Coalesce
|
||||||
from frappe.utils import add_days, cint, date_diff, flt, getdate
|
from frappe.utils import add_days, cint, date_diff, flt, getdate
|
||||||
from frappe.utils.nestedset import get_descendants_of
|
from frappe.utils.nestedset import get_descendants_of
|
||||||
|
from pypika.terms import ExistsCriterion
|
||||||
|
|
||||||
import erpnext
|
import erpnext
|
||||||
from erpnext.stock.doctype.inventory_dimension.inventory_dimension import get_inventory_dimensions
|
from erpnext.stock.doctype.inventory_dimension.inventory_dimension import get_inventory_dimensions
|
||||||
@@ -24,8 +25,8 @@ class StockBalanceFilter(TypedDict):
|
|||||||
from_date: str
|
from_date: str
|
||||||
to_date: str
|
to_date: str
|
||||||
item_group: str | None
|
item_group: str | None
|
||||||
item: str | None
|
item: list[str] | None
|
||||||
warehouse: str | None
|
warehouse: list[str] | None
|
||||||
warehouse_type: str | None
|
warehouse_type: str | None
|
||||||
include_uom: str | None # include extra info in converted UOM
|
include_uom: str | None # include extra info in converted UOM
|
||||||
show_stock_ageing_data: bool
|
show_stock_ageing_data: bool
|
||||||
@@ -345,8 +346,29 @@ class StockBalanceReport:
|
|||||||
def apply_warehouse_filters(self, query, sle) -> str:
|
def apply_warehouse_filters(self, query, sle) -> str:
|
||||||
warehouse_table = frappe.qb.DocType("Warehouse")
|
warehouse_table = frappe.qb.DocType("Warehouse")
|
||||||
|
|
||||||
if self.filters.get("warehouse"):
|
if warehouses := self.filters.get("warehouse"):
|
||||||
query = apply_warehouse_filter(query, sle, self.filters)
|
warehouse_range = frappe.get_all(
|
||||||
|
"Warehouse",
|
||||||
|
filters={
|
||||||
|
"name": ("in", warehouses),
|
||||||
|
},
|
||||||
|
fields=["lft", "rgt"],
|
||||||
|
as_list=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
child_query = frappe.qb.from_(warehouse_table).select(warehouse_table.name)
|
||||||
|
|
||||||
|
range_conditions = [
|
||||||
|
(warehouse_table.lft >= lft) & (warehouse_table.rgt <= rgt) for lft, rgt in warehouse_range
|
||||||
|
]
|
||||||
|
|
||||||
|
combined_condition = range_conditions[0]
|
||||||
|
for condition in range_conditions[1:]:
|
||||||
|
combined_condition = combined_condition | condition
|
||||||
|
|
||||||
|
child_query = child_query.where(combined_condition & (warehouse_table.name == sle.warehouse))
|
||||||
|
query = query.where(ExistsCriterion(child_query))
|
||||||
|
|
||||||
elif warehouse_type := self.filters.get("warehouse_type"):
|
elif warehouse_type := self.filters.get("warehouse_type"):
|
||||||
query = (
|
query = (
|
||||||
query.join(warehouse_table)
|
query.join(warehouse_table)
|
||||||
@@ -361,13 +383,11 @@ class StockBalanceReport:
|
|||||||
children = get_descendants_of("Item Group", item_group, ignore_permissions=True)
|
children = get_descendants_of("Item Group", item_group, ignore_permissions=True)
|
||||||
query = query.where(item_table.item_group.isin([*children, item_group]))
|
query = query.where(item_table.item_group.isin([*children, item_group]))
|
||||||
|
|
||||||
for field in ["item_code", "brand"]:
|
if item_codes := self.filters.get("item_code"):
|
||||||
if not self.filters.get(field):
|
query = query.where(item_table.name.isin(item_codes))
|
||||||
continue
|
|
||||||
elif field == "item_code":
|
if brand := self.filters.get("brand"):
|
||||||
query = query.where(item_table.name == self.filters.get(field))
|
query = query.where(item_table.brand == brand)
|
||||||
else:
|
|
||||||
query = query.where(item_table[field] == self.filters.get(field))
|
|
||||||
|
|
||||||
return query
|
return query
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user