feat: make material transfer warehouse validation optional (backport #50461) (#50462)

Co-authored-by: Mihir Kandoi <kandoimihir@gmail.com>
This commit is contained in:
mergify[bot]
2025-11-11 07:18:41 +00:00
committed by GitHub
parent de14c0838c
commit 1747e83cb1
3 changed files with 44 additions and 33 deletions

View File

@@ -807,43 +807,45 @@ class StockEntry(StockController):
and target to ensure a meaningful transfer is occurring.
Raises:
frappe.ValidationError: If warehouses are same and no inventory dimensions differ
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:
if frappe.get_single_value("Stock Settings", "validate_material_transfer_warehouses"):
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, Target Warehouse and Inventory Dimensions cannot be the exact same for Material Transfer"
"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:

View File

@@ -36,6 +36,7 @@
"show_barcode_field",
"clean_description_html",
"allow_internal_transfer_at_arms_length_price",
"validate_material_transfer_warehouses",
"serial_and_batch_item_settings_tab",
"section_break_7",
"allow_existing_serial_no",
@@ -530,6 +531,13 @@
"label": "Update Price List Based On",
"mandatory_depends_on": "eval: doc.auto_insert_price_list_rate_if_missing",
"options": "Rate\nPrice List Rate"
},
{
"default": "0",
"description": "If enabled, the source and target warehouse in the Material Transfer Stock Entry must be different else an error will be thrown. If inventory dimensions are present, same source and target warehouse can be allowed but atleast any one of the inventory dimension fields must be different.",
"fieldname": "validate_material_transfer_warehouses",
"fieldtype": "Check",
"label": "Validate Material Transfer Warehouses"
}
],
"icon": "icon-cog",
@@ -537,8 +545,8 @@
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"modified": "2025-10-17 18:32:35.829395",
"modified_by": "hello@aerele.in",
"modified": "2025-11-11 11:35:39.864923",
"modified_by": "Administrator",
"module": "Stock",
"name": "Stock Settings",
"owner": "Administrator",
@@ -563,4 +571,4 @@
"sort_order": "ASC",
"states": [],
"track_changes": 1
}
}

View File

@@ -67,6 +67,7 @@ class StockSettings(Document):
update_price_list_based_on: DF.Literal["Rate", "Price List Rate"]
use_naming_series: DF.Check
use_serial_batch_fields: DF.Check
validate_material_transfer_warehouses: DF.Check
valuation_method: DF.Literal["FIFO", "Moving Average", "LIFO"]
# end: auto-generated types