fix: disallow material transfer if source and target warehouse are same (#50331)

* fix: disallow material transfer if source and target warehouse are same (#48697)

* fix: disallow material transfer if source and target warehouse are same

* fix: check on child row level instead of parent level

* chore: add docstring to function
This commit is contained in:
Mihir Kandoi
2025-11-04 15:14:18 +05:30
committed by GitHub
parent ac901dee3c
commit d920520843

View File

@@ -241,6 +241,8 @@ class StockEntry(StockController):
self.reset_default_field_value("from_warehouse", "items", "s_warehouse")
self.reset_default_field_value("to_warehouse", "items", "t_warehouse")
self.validate_same_source_target_warehouse_during_material_transfer()
def on_submit(self):
self.validate_closed_subcontracting_order()
self.make_bundle_using_old_serial_batch_fields()
@@ -796,6 +798,53 @@ class StockEntry(StockController):
title=_("Missing Item"),
)
def validate_same_source_target_warehouse_during_material_transfer(self):
"""
Validate Material Transfer entries where source and target warehouses are identical.
For Material Transfer purpose, if an item has the same source and target warehouse,
require that at least one inventory dimension (if configured) differs between source
and target to ensure a meaningful transfer is occurring.
Raises:
frappe.ValidationError: If warehouses are same and no inventory dimensions differ
"""
from erpnext.stock.doctype.inventory_dimension.inventory_dimension import get_inventory_dimensions
inventory_dimensions = get_inventory_dimensions()
if self.purpose == "Material Transfer":
for item in self.items:
if cstr(item.s_warehouse) == cstr(item.t_warehouse):
if not inventory_dimensions:
frappe.throw(
_(
"Row #{0}: Source and Target Warehouse cannot be the same for Material Transfer"
).format(item.idx),
title=_("Invalid Source and Target Warehouse"),
)
else:
difference_found = False
for dimension in inventory_dimensions:
fieldname = (
dimension.source_fieldname
if dimension.source_fieldname.startswith("to_")
else f"to_{dimension.source_fieldname}"
)
if (
item.get(dimension.source_fieldname)
and item.get(fieldname)
and item.get(dimension.source_fieldname) != item.get(fieldname)
):
difference_found = True
break
if not difference_found:
frappe.throw(
_(
"Row #{0}: Source, Target Warehouse and Inventory Dimensions cannot be the exact same for Material Transfer"
).format(item.idx),
title=_("Invalid Source and Target Warehouse"),
)
def get_matched_items(self, item_code):
for row in self.items:
if row.item_code == item_code or row.original_item == item_code: