fix(stock): apply transit warehouse filter to target warehouse in items table (#59192)

(cherry picked from commit 893fc75df4)
This commit is contained in:
Afsal Syed
2026-09-22 12:18:07 +05:30
committed by Afsal Syed
parent d4b1be1154
commit ae96dad151
3 changed files with 116 additions and 13 deletions

View File

@@ -907,22 +907,15 @@ frappe.ui.form.on("Stock Entry", {
add_to_transit: function (frm) {
if (frm.doc.purpose == "Material Transfer") {
var filters = {
is_group: 0,
company: frm.doc.company,
};
if (frm.doc.add_to_transit) {
filters["warehouse_type"] = "Transit";
frm.set_value("to_warehouse", "");
(frm.doc.items || []).forEach((item) => {
if (item.t_warehouse) {
frappe.model.set_value(item.doctype, item.name, "t_warehouse", "");
}
});
frm.trigger("set_transit_warehouse");
}
frm.fields_dict.to_warehouse.get_query = function () {
return {
filters: filters,
};
};
}
},
@@ -1228,6 +1221,28 @@ frappe.ui.form.on("Landed Cost Taxes and Charges", {
});
erpnext.stock.StockEntry = class StockEntry extends erpnext.stock.StockController {
setup_warehouse_query() {
super.setup_warehouse_query();
const transit_warehouse_query = () => {
const filters = {
is_group: 0,
company: this.frm.doc.company,
};
if (this.frm.doc.purpose === "Material Transfer" && this.frm.doc.add_to_transit) {
filters["warehouse_type"] = "Transit";
}
return {
filters: filters,
};
};
this.frm.set_query("to_warehouse", transit_warehouse_query);
this.frm.set_query("t_warehouse", "items", transit_warehouse_query);
}
setup() {
var me = this;

View File

@@ -1024,6 +1024,46 @@ class StockEntry(StockController, SubcontractingInwardController):
if not (d.s_warehouse or d.t_warehouse):
frappe.throw(_("At least one warehouse is mandatory"))
self.validate_transit_warehouses()
def validate_transit_warehouses(self):
if not self.add_to_transit:
return
target_warehouses = {row.t_warehouse for row in self.items if row.t_warehouse}
if self.to_warehouse:
target_warehouses.add(self.to_warehouse)
if not target_warehouses:
return
transit_warehouses = set(
frappe.get_all(
"Warehouse",
filters={
"name": ("in", list(target_warehouses)),
"warehouse_type": "Transit",
"company": self.company,
},
pluck="name",
)
)
if self.to_warehouse and self.to_warehouse not in transit_warehouses:
frappe.throw(
_(
"Default Target Warehouse {0} must be a Transit warehouse when Add to Transit is enabled."
).format(frappe.bold(self.to_warehouse))
)
for row in self.items:
if row.t_warehouse and row.t_warehouse not in transit_warehouses:
frappe.throw(
_(
"Row #{0}: Target Warehouse {1} must be a Transit warehouse when Add to Transit is enabled."
).format(row.idx, frappe.bold(row.t_warehouse))
)
def validate_work_order(self):
if self.purpose in (
"Manufacture",

View File

@@ -208,7 +208,8 @@ class TestStockEntry(ERPNextTestSuite):
company = "_Test Company"
create_warehouse("Test From Warehouse")
create_warehouse("Test Transit Warehouse")
create_warehouse("Test Transit Warehouse", properties={"warehouse_type": "Transit"})
frappe.db.set_value("Warehouse", "Test Transit Warehouse - _TC", "warehouse_type", "Transit")
create_warehouse("Test To Warehouse")
create_item(
@@ -259,6 +260,53 @@ class TestStockEntry(ERPNextTestSuite):
transit_entry.reload()
self.assertEqual(transit_entry.per_transferred, 100)
def test_add_to_transit_non_transit_target_warehouse_validation(self):
from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
item_code = "_Test Transit Item 2"
company = "_Test Company"
create_warehouse("Test Source Warehouse")
create_warehouse("Test Regular Target Warehouse")
create_item(
item_code=item_code,
is_stock_item=1,
is_purchase_item=1,
company=company,
)
make_stock_entry(
item_code=item_code,
target="Test Source Warehouse - _TC",
qty=10,
basic_rate=100,
expense_account="Stock Adjustment - _TC",
cost_center="Main - _TC",
)
# Submitting or saving with add_to_transit=1 and a non-transit target warehouse must be rejected
se = frappe.new_doc("Stock Entry")
se.purpose = "Material Transfer"
se.stock_entry_type = "Material Transfer"
se.company = company
se.from_warehouse = "Test Source Warehouse - _TC"
se.to_warehouse = "Test Regular Target Warehouse - _TC"
se.add_to_transit = 1
se.append(
"items",
{
"item_code": item_code,
"s_warehouse": "Test Source Warehouse - _TC",
"t_warehouse": "Test Regular Target Warehouse - _TC",
"qty": 5,
"basic_rate": 100,
"expense_account": "Stock Adjustment - _TC",
"cost_center": "Main - _TC",
},
)
self.assertRaises(frappe.ValidationError, se.save)
def test_material_receipt_gl_entry(self):
company = frappe.db.get_value("Warehouse", "Stores - TCP1", "company")