From b5aee6a9cda2eac395efdb26f83b684b9ac14721 Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Sun, 5 Jul 2026 15:10:17 +0530 Subject: [PATCH 1/2] fix(buying): show earliest schedule date as required date When a Material Request lists the same item on multiple rows, the consolidated row showed Max(schedule_date), understating urgency. Use Min - the earliest date the item is needed. --- .../requested_items_to_order_and_receive.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py b/erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py index b6f9bb13795..d1d9bd8266c 100644 --- a/erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py +++ b/erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py @@ -6,7 +6,7 @@ import copy import frappe from frappe import _ -from frappe.query_builder.functions import Coalesce, Max, Sum +from frappe.query_builder.functions import Coalesce, Max, Min, Sum from frappe.utils import cint, date_diff, flt, getdate @@ -47,7 +47,7 @@ def get_data(filters): # non-grouped columns are constant per grouped mr.name / item_code -> Max() keeps the # GROUP BY valid on postgres while returning the same value MySQL picked. Max(mr.transaction_date).as_("date"), - Max(mr_item.schedule_date).as_("required_date"), + Min(mr_item.schedule_date).as_("required_date"), mr_item.item_code.as_("item_code"), Sum(Coalesce(mr_item.qty, 0)).as_("qty"), Sum(Coalesce(mr_item.stock_qty, 0)).as_("stock_qty"), From a5d0b25ac4e937f2454d540750bc854f751bdbb0 Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Sun, 5 Jul 2026 15:32:02 +0530 Subject: [PATCH 2/2] test: assert earliest schedule date wins for duplicate MR item rows --- ...st_requested_items_to_order_and_receive.py | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/erpnext/buying/report/requested_items_to_order_and_receive/test_requested_items_to_order_and_receive.py b/erpnext/buying/report/requested_items_to_order_and_receive/test_requested_items_to_order_and_receive.py index acf29b75043..efb83e41d0a 100644 --- a/erpnext/buying/report/requested_items_to_order_and_receive/test_requested_items_to_order_and_receive.py +++ b/erpnext/buying/report/requested_items_to_order_and_receive/test_requested_items_to_order_and_receive.py @@ -2,7 +2,7 @@ # See license.txt import frappe -from frappe.utils import add_days, today +from frappe.utils import add_days, getdate, today from erpnext.buying.doctype.purchase_order.mapper import make_purchase_receipt from erpnext.buying.report.requested_items_to_order_and_receive.requested_items_to_order_and_receive import ( @@ -44,6 +44,36 @@ class TestRequestedItemsToOrderAndReceive(ERPNextTestSuite): self.assertEqual(data[0].ordered_qty, 0.0) self.assertEqual(data[1].ordered_qty, 57.0) + def test_required_date_is_earliest_schedule_date(self): + create_item("Test MR Report Dup Item") + mr = frappe.copy_doc(self.globalTestRecords["Material Request"][0]) + mr.transaction_date = today() + mr.schedule_date = add_days(today(), 5) + mr.set("items", mr.items[:1]) + row = mr.items[0] + row.item_code = "Test MR Report Dup Item" + row.item_name = "Test MR Report Dup Item" + row.description = "Test MR Report Dup Item" + row.uom = "Nos" + row.schedule_date = add_days(today(), 5) + mr.append( + "items", + { + "item_code": "Test MR Report Dup Item", + "item_name": "Test MR Report Dup Item", + "description": "Test MR Report Dup Item", + "uom": "Nos", + "qty": row.qty, + "warehouse": row.warehouse, + "schedule_date": add_days(today(), 1), + }, + ) + mr.submit() + + data = get_data(self.filters.update({"item_code": "Test MR Report Dup Item"})) + self.assertEqual(len(data), 1) + self.assertEqual(getdate(data[0].required_date), getdate(add_days(today(), 1))) + def setup_material_request(self, order=False, receive=False, days=0): po = None mr = frappe.copy_doc(self.globalTestRecords["Material Request"][0])