mirror of
https://github.com/frappe/erpnext.git
synced 2026-02-12 17:23:38 +00:00
fix: add validation for transferred qty and handle MR transfer status for in-transit entry. (backport #50683) (#51134)
fix: add validation for transferred qty and handle MR transfer status for in-transit entry. (#50683)
* fix: add validation for transferred qty
* fix: modify if statement
* test: add unit test for mr transfer status in-transit entry
(cherry picked from commit 890316a793)
Co-authored-by: Logesh Periyasamy <logeshperiyasamy24@gmail.com>
This commit is contained in:
@@ -19,6 +19,7 @@ from erpnext.stock.doctype.material_request.material_request import (
|
||||
make_supplier_quotation,
|
||||
raise_work_orders,
|
||||
)
|
||||
from erpnext.stock.doctype.stock_entry.stock_entry import make_stock_in_entry
|
||||
from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
|
||||
|
||||
|
||||
@@ -926,6 +927,49 @@ class TestMaterialRequest(FrappeTestCase):
|
||||
pl_for_pending = create_pick_list(mr.name)
|
||||
self.assertEqual(pl_for_pending.locations[0].qty, 5)
|
||||
|
||||
def test_mr_status_with_partial_and_excess_end_transit(self):
|
||||
material_request = make_material_request(
|
||||
material_request_type="Material Transfer",
|
||||
item_code="_Test Item Home Desktop 100",
|
||||
)
|
||||
|
||||
in_transit_wh = get_in_transit_warehouse(material_request.company)
|
||||
|
||||
# Make sure stock is available in source warehouse
|
||||
self._insert_stock_entry(20.0, 20.0)
|
||||
|
||||
# Stock Entry (Transfer to In-Transit)
|
||||
stock_entry_1 = make_in_transit_stock_entry(material_request.name, in_transit_wh)
|
||||
stock_entry_1.items[0].update(
|
||||
{
|
||||
"qty": 5,
|
||||
"s_warehouse": "_Test Warehouse 1 - _TC",
|
||||
}
|
||||
)
|
||||
stock_entry_1.save().submit()
|
||||
|
||||
stock_entry_2 = make_in_transit_stock_entry(material_request.name, in_transit_wh)
|
||||
stock_entry_2.items[0].update(
|
||||
{
|
||||
"qty": 5,
|
||||
"s_warehouse": "_Test Warehouse 1 - _TC",
|
||||
}
|
||||
)
|
||||
stock_entry_2.save().submit()
|
||||
|
||||
end_transit_1 = make_stock_in_entry(stock_entry_1.name)
|
||||
end_transit_1.save().submit()
|
||||
|
||||
# Material Request Transfer Status should still be In Transit
|
||||
material_request.load_from_db()
|
||||
self.assertEqual(material_request.transfer_status, "In Transit")
|
||||
|
||||
end_transit_2 = make_stock_in_entry(stock_entry_2.name)
|
||||
end_transit_2.items[0].update({"qty": 6}) # More than transferred
|
||||
end_transit_2.save()
|
||||
|
||||
self.assertRaises(frappe.ValidationError, end_transit_2.submit)
|
||||
|
||||
|
||||
def get_in_transit_warehouse(company):
|
||||
if not frappe.db.exists("Warehouse Type", "Transit"):
|
||||
|
||||
@@ -8,6 +8,7 @@ from collections import defaultdict
|
||||
import frappe
|
||||
from frappe import _, bold
|
||||
from frappe.model.mapper import get_mapped_doc
|
||||
from frappe.query_builder import DocType
|
||||
from frappe.query_builder.functions import Sum
|
||||
from frappe.utils import (
|
||||
cint,
|
||||
@@ -2815,6 +2816,17 @@ class StockEntry(StockController):
|
||||
},
|
||||
)
|
||||
|
||||
if d.docstatus == 1:
|
||||
transfer_qty = frappe.get_value("Stock Entry Detail", d.ste_detail, "transfer_qty")
|
||||
|
||||
if transferred_qty and transferred_qty[0]:
|
||||
if transferred_qty[0].qty > transfer_qty:
|
||||
frappe.throw(
|
||||
_(
|
||||
"Row {0}: Transferred quantity cannot be greater than the requested quantity."
|
||||
).format(d.idx)
|
||||
)
|
||||
|
||||
stock_entries[(d.against_stock_entry, d.ste_detail)] = (
|
||||
transferred_qty[0].qty if transferred_qty and transferred_qty[0] else 0.0
|
||||
) or 0.0
|
||||
@@ -2878,7 +2890,7 @@ class StockEntry(StockController):
|
||||
parent_se = frappe.get_value("Stock Entry", self.outgoing_stock_entry, "add_to_transit")
|
||||
|
||||
for item in self.items:
|
||||
material_request = item.material_request or None
|
||||
material_request = item.get("material_request")
|
||||
if self.purpose == "Material Transfer" and material_request not in material_requests:
|
||||
if self.outgoing_stock_entry and parent_se:
|
||||
material_request = frappe.get_value(
|
||||
@@ -2887,6 +2899,11 @@ class StockEntry(StockController):
|
||||
|
||||
if material_request and material_request not in material_requests:
|
||||
material_requests.append(material_request)
|
||||
if status == "Completed":
|
||||
qty = get_transferred_qty(material_request)
|
||||
if qty.get("transfer_qty") > qty.get("transferred_qty"):
|
||||
status = "In Transit"
|
||||
|
||||
frappe.db.set_value("Material Request", material_request, "transfer_status", status)
|
||||
|
||||
def set_serial_no_batch_for_finished_good(self):
|
||||
@@ -3545,3 +3562,18 @@ def get_batchwise_serial_nos(item_code, row):
|
||||
batchwise_serial_nos[batch_no] = sorted([serial_no.name for serial_no in serial_nos])
|
||||
|
||||
return batchwise_serial_nos
|
||||
|
||||
|
||||
def get_transferred_qty(material_request):
|
||||
sed = DocType("Stock Entry Detail")
|
||||
|
||||
query = (
|
||||
frappe.qb.from_(sed)
|
||||
.select(
|
||||
Sum(sed.transfer_qty).as_("transfer_qty"),
|
||||
Sum(sed.transferred_qty).as_("transferred_qty"),
|
||||
)
|
||||
.where((sed.material_request == material_request) & (sed.docstatus == 1))
|
||||
).run(as_dict=True)
|
||||
|
||||
return query[0]
|
||||
|
||||
Reference in New Issue
Block a user