mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-14 07:01:56 +00:00
fix: handle multi-select stock ageing filters (#55776)
This commit is contained in:
@@ -11,6 +11,7 @@ from frappe.query_builder.functions import Abs, Count
|
|||||||
from frappe.utils import cint, date_diff, flt, get_datetime
|
from frappe.utils import cint, date_diff, flt, get_datetime
|
||||||
|
|
||||||
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
|
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
|
||||||
|
from erpnext.stock.doctype.warehouse.warehouse import apply_warehouse_filter
|
||||||
from erpnext.stock.valuation import round_off_if_near_zero
|
from erpnext.stock.valuation import round_off_if_near_zero
|
||||||
|
|
||||||
Filters = frappe._dict
|
Filters = frappe._dict
|
||||||
@@ -936,9 +937,7 @@ class FIFOSlots:
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
for field in ["item_code"]:
|
query = self._apply_filter(query, sle, "item_code")
|
||||||
if self.filters.get(field):
|
|
||||||
query = query.where(sle[field] == self.filters.get(field))
|
|
||||||
|
|
||||||
if self.filters.get("warehouse"):
|
if self.filters.get("warehouse"):
|
||||||
query = self._get_warehouse_conditions(sle, query)
|
query = self._get_warehouse_conditions(sle, query)
|
||||||
@@ -985,9 +984,7 @@ class FIFOSlots:
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
for field in ["item_code"]:
|
query = self._apply_filter(query, sle, "item_code")
|
||||||
if self.filters.get(field):
|
|
||||||
query = query.where(sle[field] == self.filters.get(field))
|
|
||||||
|
|
||||||
if self.filters.get("warehouse"):
|
if self.filters.get("warehouse"):
|
||||||
query = self._get_warehouse_conditions(sle, query)
|
query = self._get_warehouse_conditions(sle, query)
|
||||||
@@ -1020,27 +1017,25 @@ class FIFOSlots:
|
|||||||
"has_batch_no",
|
"has_batch_no",
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.filters.get("item_code"):
|
item = self._apply_filter(item, item_table, "item_code")
|
||||||
item = item.where(item_table.item_code == self.filters.get("item_code"))
|
|
||||||
|
|
||||||
if self.filters.get("brand"):
|
if self.filters.get("brand"):
|
||||||
item = item.where(item_table.brand == self.filters.get("brand"))
|
item = item.where(item_table.brand == self.filters.get("brand"))
|
||||||
|
|
||||||
return item
|
return item
|
||||||
|
|
||||||
|
def _apply_filter(self, query, table, fieldname: str):
|
||||||
|
filter_value = self.filters.get(fieldname)
|
||||||
|
if not filter_value:
|
||||||
|
return query
|
||||||
|
|
||||||
|
if isinstance(filter_value, list | tuple | set):
|
||||||
|
return query.where(table[fieldname].isin(filter_value))
|
||||||
|
|
||||||
|
return query.where(table[fieldname] == filter_value)
|
||||||
|
|
||||||
def _get_warehouse_conditions(self, sle, sle_query) -> str:
|
def _get_warehouse_conditions(self, sle, sle_query) -> str:
|
||||||
warehouse = frappe.qb.DocType("Warehouse")
|
return apply_warehouse_filter(sle_query, sle, self.filters)
|
||||||
lft, rgt = frappe.db.get_value("Warehouse", self.filters.get("warehouse"), ["lft", "rgt"])
|
|
||||||
|
|
||||||
warehouse_results = (
|
|
||||||
frappe.qb.from_(warehouse)
|
|
||||||
.select("name")
|
|
||||||
.where((warehouse.lft >= lft) & (warehouse.rgt <= rgt))
|
|
||||||
.run()
|
|
||||||
)
|
|
||||||
warehouse_results = [x[0] for x in warehouse_results]
|
|
||||||
|
|
||||||
return sle_query.where(sle.warehouse.isin(warehouse_results))
|
|
||||||
|
|
||||||
def prepare_stock_reco_voucher_wise_count(self):
|
def prepare_stock_reco_voucher_wise_count(self):
|
||||||
self.stock_reco_voucher_wise_count = frappe._dict()
|
self.stock_reco_voucher_wise_count = frappe._dict()
|
||||||
|
|||||||
@@ -129,6 +129,18 @@ class TestStockAgeing(FrappeTestCase):
|
|||||||
self.assertEqual(queue[0][0], 10.0)
|
self.assertEqual(queue[0][0], 10.0)
|
||||||
self.assertEqual(queue[1][0], 10.0)
|
self.assertEqual(queue[1][0], 10.0)
|
||||||
|
|
||||||
|
def test_item_filter_supports_multi_select_values(self):
|
||||||
|
bundle = frappe.qb.DocType("Serial and Batch Bundle")
|
||||||
|
query = frappe.qb.from_(bundle).select(bundle.name)
|
||||||
|
|
||||||
|
filtered_query = FIFOSlots(frappe._dict(item_code=["Item A"]), [])._apply_filter(
|
||||||
|
query, bundle, "item_code"
|
||||||
|
)
|
||||||
|
|
||||||
|
sql = filtered_query.get_sql()
|
||||||
|
self.assertIn(" IN ", sql)
|
||||||
|
self.assertNotIn("=[", sql)
|
||||||
|
|
||||||
def test_basic_stock_reconciliation(self):
|
def test_basic_stock_reconciliation(self):
|
||||||
"""
|
"""
|
||||||
Ledger (same wh): [+30, reco reset >> 50, -10]
|
Ledger (same wh): [+30, reco reset >> 50, -10]
|
||||||
|
|||||||
Reference in New Issue
Block a user