fix: add server-side validation for closed sales order for linked material request
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index 06b2753..3880792 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -442,6 +442,13 @@
 				frappe.throw(_("Row #{0}: {1} can not be negative for item {2}".format(item_row['idx'],
 					frappe.get_meta(item_row.doctype).get_label(fieldname), item_row['item_code'])))
 
+	def check_for_on_hold_or_closed_status(self, ref_doctype, ref_fieldname):
+		for d in self.get("items"):
+			if d.get(ref_fieldname):
+				status = frappe.db.get_value(ref_doctype, d.get(ref_fieldname), "status")
+				if status in ("Closed", "On Hold"):
+					frappe.throw(_("{0} {1} is {2}").format(ref_doctype,d.get(ref_fieldname), status))
+
 	def update_stock_ledger(self, allow_negative_stock=False, via_landed_cost_voucher=False):
 		self.update_ordered_and_reserved_qty()
 
diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py
index 7a199a4..ec10367 100644
--- a/erpnext/stock/doctype/material_request/material_request.py
+++ b/erpnext/stock/doctype/material_request/material_request.py
@@ -62,6 +62,7 @@
 		super(MaterialRequest, self).validate()
 
 		self.validate_schedule_date()
+		self.check_for_on_hold_or_closed_status('Sales Order', 'sales_order')
 		self.validate_uom_is_integer("uom", "qty")
 
 		if not self.status:
@@ -100,6 +101,7 @@
 
 	def before_cancel(self):
 		# if MRQ is already closed, no point saving the document
+		self.check_for_on_hold_or_closed_status("Sales Order", "sales_order")
 		check_for_closed_status(self.doctype, self.name)
 		self.set_status(update=True, status='Cancelled')