Merge pull request #58090 from frappe/mergify/bp/version-16-hotfix/pr-58073

fix(manufacturing): show full date range in MRP chart (backport #58073)
This commit is contained in:
Mihir Kandoi
2026-08-12 15:25:53 +05:30
committed by GitHub
2 changed files with 81 additions and 9 deletions

View File

@@ -268,22 +268,17 @@ class MaterialRequirementsPlanningReport:
def get_detailed_view_chart_data(self, data):
chart_data = frappe._dict({})
i = 0
sorted_data = sorted(data, key=lambda x: getdate(x.get("delivery_date")))
for row in sorted_data:
if getdate(row.deliver_date) < getdate(today()):
continue
if not row.delivery_date:
continue
if i == 10:
break
if getdate(row.delivery_date) < getdate(today()):
continue
delivery_date = formatdate(row.delivery_date, "dd MMM")
delivery_date = getdate(row.delivery_date)
if delivery_date not in chart_data:
i += 1
chart_data[delivery_date] = frappe._dict(
{
"demand": 0.0,
@@ -299,6 +294,7 @@ class MaterialRequirementsPlanningReport:
demand_data = []
supply_data = []
delivery_dates = list(chart_data)
for row in chart_data:
value = chart_data[row]
@@ -307,7 +303,7 @@ class MaterialRequirementsPlanningReport:
return {
"data": {
"labels": list(chart_data.keys()),
"labels": self.get_detailed_chart_labels(delivery_dates),
"datasets": [
{
"name": _("Demand"),
@@ -325,6 +321,10 @@ class MaterialRequirementsPlanningReport:
"title": _("Demand vs Supply"),
}
def get_detailed_chart_labels(self, delivery_dates):
date_format = "dd MMM yyyy" if len({date.year for date in delivery_dates}) > 1 else "dd MMM"
return [formatdate(date, date_format) for date in delivery_dates]
def get_bucket_view_chart_data(self, data):
chart_data = frappe._dict({})
labels = []

View File

@@ -0,0 +1,72 @@
# Copyright (c) 2024, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import frappe
from frappe.tests.classes.context_managers import freeze_time
from frappe.utils import add_days, formatdate, today
from erpnext.manufacturing.report.material_requirements_planning_report.material_requirements_planning_report import (
MaterialRequirementsPlanningReport,
)
from erpnext.tests.utils import ERPNextTestSuite
class TestMaterialRequirementsPlanningReport(ERPNextTestSuite):
def test_detailed_chart_includes_full_date_range(self):
with freeze_time("2026-08-12"):
start_date = add_days(today(), 1)
delivery_dates = [add_days(start_date, offset) for offset in range(12)]
rows = [make_chart_row(delivery_date) for delivery_date in delivery_dates]
rows.append(make_chart_row(delivery_dates[-1], planned_qty=2))
chart = MaterialRequirementsPlanningReport(frappe._dict()).get_detailed_view_chart_data(rows)
self.assertEqual(
chart["data"]["labels"],
[formatdate(delivery_date, "dd MMM") for delivery_date in delivery_dates],
)
self.assertEqual(chart["data"]["datasets"][0]["values"], [1] * 11 + [3])
def test_detailed_chart_distinguishes_delivery_dates_across_years(self):
with freeze_time("2026-08-12"):
delivery_dates = ["2026-08-15", "2027-08-15"]
rows = [
make_chart_row(delivery_dates[0]),
make_chart_row(delivery_dates[1], planned_qty=2),
]
chart = MaterialRequirementsPlanningReport(frappe._dict()).get_detailed_view_chart_data(rows)
self.assertEqual(
chart["data"]["labels"],
[formatdate(delivery_date, "dd MMM yyyy") for delivery_date in delivery_dates],
)
self.assertEqual(chart["data"]["datasets"][0]["values"], [1, 2])
def test_detailed_chart_excludes_past_and_empty_delivery_dates(self):
with freeze_time("2026-08-12"):
delivery_dates = [today(), add_days(today(), 1)]
rows = [
make_chart_row(add_days(today(), -1)),
make_chart_row(None),
*[make_chart_row(delivery_date) for delivery_date in delivery_dates],
]
chart = MaterialRequirementsPlanningReport(frappe._dict()).get_detailed_view_chart_data(rows)
self.assertEqual(
chart["data"]["labels"],
[formatdate(delivery_date, "dd MMM") for delivery_date in delivery_dates],
)
def make_chart_row(delivery_date, planned_qty=1):
return frappe._dict(
{
"delivery_date": delivery_date,
"planned_qty": planned_qty,
"in_hand_qty": 0,
"po_ordered_qty": 0,
"wo_ordered_qty": 0,
}
)