From 28b5efcbe1a043b720462823cd428e450dbc47c6 Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Tue, 23 Jun 2026 10:37:21 +0530 Subject: [PATCH 1/2] fix(manufacturing): keep MPS cumulative lead-time fractional across engines get_item_lead_time in Master Production Schedule computes manufacturing_time_in_mins / 1440 + purchase_time + buffer_time. As in the MRP report, manufacturing_time_in_mins is an Int column and 1440 an int literal, so the division truncates on PostgreSQL (720/1440 -> 0) while MariaDB yields 0.5. The value is summed over the BOM tree, ceil'd, and drives the planned order-release date, so it diverged by engine. Use a float numerator (1440.0). MariaDB output is unchanged; PostgreSQL now matches it. --- .../master_production_schedule.py | 2 +- .../test_master_production_schedule.py | 27 ++++++++++++++++++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.py b/erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.py index 48e04ebf050..b48f4d34ccd 100644 --- a/erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.py +++ b/erpnext/manufacturing/doctype/master_production_schedule/master_production_schedule.py @@ -453,7 +453,7 @@ def get_item_lead_time(item_code): query = ( frappe.qb.from_(doctype) .select( - ((doctype.manufacturing_time_in_mins / 1440) + doctype.purchase_time + doctype.buffer_time).as_( + ((doctype.manufacturing_time_in_mins / 1440.0) + doctype.purchase_time + doctype.buffer_time).as_( "cumulative_lead_time" ) ) diff --git a/erpnext/manufacturing/doctype/master_production_schedule/test_master_production_schedule.py b/erpnext/manufacturing/doctype/master_production_schedule/test_master_production_schedule.py index e695b11bcb5..faeb050a73b 100644 --- a/erpnext/manufacturing/doctype/master_production_schedule/test_master_production_schedule.py +++ b/erpnext/manufacturing/doctype/master_production_schedule/test_master_production_schedule.py @@ -1,4 +1,29 @@ # Copyright (c) 2025, Frappe Technologies Pvt. Ltd. and Contributors # See license.txt -# import frappe +import frappe + +from erpnext.manufacturing.doctype.master_production_schedule.master_production_schedule import ( + get_item_lead_time, +) +from erpnext.stock.doctype.item.test_item import make_item +from erpnext.tests.utils import ERPNextTestSuite + + +class TestMasterProductionSchedule(ERPNextTestSuite): + def test_cumulative_lead_time_is_not_int_truncated(self): + """cumulative_lead_time = manufacturing_time_in_mins / 1440 + purchase_time + buffer_time. + manufacturing_time_in_mins is an Int column; integer/integer division truncates on + PostgreSQL (720/1440 -> 0) while MariaDB yields 0.5, changing the planned release date.""" + item = make_item("_Test MPS Lead Time Item", {"is_stock_item": 1}).name + frappe.get_doc( + { + "doctype": "Item Lead Time", + "item_code": item, + "manufacturing_time_in_mins": 720, + "purchase_time": 0, + "buffer_time": 0, + } + ).insert() + # 720 / 1440 = 0.5; a truncating integer division on PostgreSQL would give 0. + self.assertAlmostEqual(float(get_item_lead_time(item)), 0.5, places=2) From d2255325956326e4c3501554f6baaf04bbcb7619 Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Tue, 23 Jun 2026 13:20:58 +0530 Subject: [PATCH 2/2] test(manufacturing): make MPS lead-time fixture idempotent Delete any existing Item Lead Time for the test item before inserting, so the test is re-runnable on a shared database (addresses review feedback). --- .../test_master_production_schedule.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/erpnext/manufacturing/doctype/master_production_schedule/test_master_production_schedule.py b/erpnext/manufacturing/doctype/master_production_schedule/test_master_production_schedule.py index faeb050a73b..606ba2dba5a 100644 --- a/erpnext/manufacturing/doctype/master_production_schedule/test_master_production_schedule.py +++ b/erpnext/manufacturing/doctype/master_production_schedule/test_master_production_schedule.py @@ -16,6 +16,8 @@ class TestMasterProductionSchedule(ERPNextTestSuite): manufacturing_time_in_mins is an Int column; integer/integer division truncates on PostgreSQL (720/1440 -> 0) while MariaDB yields 0.5, changing the planned release date.""" item = make_item("_Test MPS Lead Time Item", {"is_stock_item": 1}).name + # idempotent across re-runs / a shared CI database + frappe.db.delete("Item Lead Time", {"item_code": item}) frappe.get_doc( { "doctype": "Item Lead Time",