Merge pull request #34061 from rohitwaghchaure/feat-allow-to-make-in-transit-entry

feat: allow to make in transit transfer entry from material request
diff --git a/erpnext/stock/doctype/material_request/material_request.js b/erpnext/stock/doctype/material_request/material_request.js
index 156e591..c1f1b0d 100644
--- a/erpnext/stock/doctype/material_request/material_request.js
+++ b/erpnext/stock/doctype/material_request/material_request.js
@@ -110,8 +110,11 @@
 
 				if (frm.doc.material_request_type === "Material Transfer") {
 					add_create_pick_list_button();
-					frm.add_custom_button(__("Transfer Material"),
+					frm.add_custom_button(__("Material Transfer"),
 						() => frm.events.make_stock_entry(frm), __('Create'));
+
+					frm.add_custom_button(__("Material Transfer (In Transit)"),
+						() => frm.events.make_in_transit_stock_entry(frm), __('Create'));
 				}
 
 				if (frm.doc.material_request_type === "Material Issue") {
@@ -333,6 +336,46 @@
 		});
 	},
 
+	make_in_transit_stock_entry(frm) {
+		frappe.prompt(
+			[
+				{
+					label: __('In Transit Warehouse'),
+					fieldname: 'in_transit_warehouse',
+					fieldtype: 'Link',
+					options: 'Warehouse',
+					reqd: 1,
+					get_query: () => {
+						return{
+							filters: {
+								'company': frm.doc.company,
+								'is_group': 0,
+								'warehouse_type': 'Transit'
+							}
+						}
+					}
+				}
+			],
+			(values) => {
+				frappe.call({
+					method: "erpnext.stock.doctype.material_request.material_request.make_in_transit_stock_entry",
+					args: {
+						source_name: frm.doc.name,
+						in_transit_warehouse: values.in_transit_warehouse
+					},
+					callback: function(r) {
+						if (r.message) {
+							let doc = frappe.model.sync(r.message);
+							frappe.set_route('Form', doc[0].doctype, doc[0].name);
+						}
+					}
+				})
+			},
+			__('In Transit Transfer'),
+			__("Create Stock Entry")
+		)
+	},
+
 	create_pick_list: (frm) => {
 		frappe.model.open_mapped_doc({
 			method: "erpnext.stock.doctype.material_request.material_request.create_pick_list",
diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py
index 94f63a5..6426fe8 100644
--- a/erpnext/stock/doctype/material_request/material_request.py
+++ b/erpnext/stock/doctype/material_request/material_request.py
@@ -716,3 +716,14 @@
 	doc.set_item_locations()
 
 	return doc
+
+
+@frappe.whitelist()
+def make_in_transit_stock_entry(source_name, in_transit_warehouse):
+	ste_doc = make_stock_entry(source_name)
+	ste_doc.add_to_transit = 1
+
+	for row in ste_doc.items:
+		row.t_warehouse = in_transit_warehouse
+
+	return ste_doc
diff --git a/erpnext/stock/doctype/material_request/test_material_request.py b/erpnext/stock/doctype/material_request/test_material_request.py
index f0a9499..a707c74 100644
--- a/erpnext/stock/doctype/material_request/test_material_request.py
+++ b/erpnext/stock/doctype/material_request/test_material_request.py
@@ -11,6 +11,7 @@
 
 from erpnext.stock.doctype.item.test_item import create_item
 from erpnext.stock.doctype.material_request.material_request import (
+	make_in_transit_stock_entry,
 	make_purchase_order,
 	make_stock_entry,
 	make_supplier_quotation,
@@ -56,6 +57,22 @@
 		self.assertEqual(se.doctype, "Stock Entry")
 		self.assertEqual(len(se.get("items")), len(mr.get("items")))
 
+	def test_in_transit_make_stock_entry(self):
+		mr = frappe.copy_doc(test_records[0]).insert()
+
+		self.assertRaises(frappe.ValidationError, make_stock_entry, mr.name)
+
+		mr = frappe.get_doc("Material Request", mr.name)
+		mr.material_request_type = "Material Transfer"
+		mr.submit()
+
+		in_transit_warehouse = get_in_transit_warehouse(mr.company)
+		se = make_in_transit_stock_entry(mr.name, in_transit_warehouse)
+
+		self.assertEqual(se.doctype, "Stock Entry")
+		for row in se.get("items"):
+			self.assertEqual(row.t_warehouse, in_transit_warehouse)
+
 	def _insert_stock_entry(self, qty1, qty2, warehouse=None):
 		se = frappe.get_doc(
 			{
@@ -742,6 +759,36 @@
 		self.assertEqual(existing_requested_qty, current_requested_qty)
 
 
+def get_in_transit_warehouse(company):
+	if not frappe.db.exists("Warehouse Type", "Transit"):
+		frappe.get_doc(
+			{
+				"doctype": "Warehouse Type",
+				"name": "Transit",
+			}
+		).insert()
+
+	in_transit_warehouse = frappe.db.exists(
+		"Warehouse", {"warehouse_type": "Transit", "company": company}
+	)
+
+	if not in_transit_warehouse:
+		in_transit_warehouse = (
+			frappe.get_doc(
+				{
+					"doctype": "Warehouse",
+					"warehouse_name": "Transit",
+					"warehouse_type": "Transit",
+					"company": company,
+				}
+			)
+			.insert()
+			.name
+		)
+
+	return in_transit_warehouse
+
+
 def make_material_request(**args):
 	args = frappe._dict(args)
 	mr = frappe.new_doc("Material Request")