From 28929df0e8f85e12f4e896b377a373cbada53357 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Tue, 3 Feb 2026 17:57:16 +0530 Subject: [PATCH] fix: zero valuation rate if returning from different warehouse --- .../controllers/sales_and_purchase_return.py | 26 ++++++++++- .../purchase_receipt/test_purchase_receipt.py | 44 +++++++++++++++++++ .../serial_and_batch_bundle.py | 8 +++- 3 files changed, 74 insertions(+), 4 deletions(-) diff --git a/erpnext/controllers/sales_and_purchase_return.py b/erpnext/controllers/sales_and_purchase_return.py index d3d5cb808f3..a53eb2130a8 100644 --- a/erpnext/controllers/sales_and_purchase_return.py +++ b/erpnext/controllers/sales_and_purchase_return.py @@ -770,12 +770,34 @@ def get_filters( if reference_voucher_detail_no: filters["voucher_detail_no"] = reference_voucher_detail_no - if voucher_type in ["Purchase Receipt", "Purchase Invoice"] and item_row and item_row.get("warehouse"): - filters["warehouse"] = item_row.get("warehouse") + warehouses = [] + if voucher_type in ["Purchase Receipt", "Purchase Invoice"] and item_row: + if reference_voucher_detail_no: + warehouses = get_warehouses_for_return(voucher_type, reference_voucher_detail_no) + + if item_row.get("warehouse") and item_row.get("warehouse") in warehouses: + filters["warehouse"] = item_row.get("warehouse") return filters +def get_warehouses_for_return(voucher_type, name): + warehouses = [] + warehouse_details = frappe.get_all( + voucher_type + " Item", + filters={"name": name, "docstatus": 1}, + fields=["warehouse", "rejected_warehouse"], + ) + + for d in warehouse_details: + if d.warehouse: + warehouses.append(d.warehouse) + if d.rejected_warehouse: + warehouses.append(d.rejected_warehouse) + + return warehouses + + def get_returned_serial_nos(child_doc, parent_doc, serial_no_field=None, ignore_voucher_detail_no=None): from erpnext.stock.doctype.serial_no.serial_no import ( get_serial_nos as get_serial_nos_from_serial_no, diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py index 1685c9d98a8..c91b9e22632 100644 --- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py @@ -4872,6 +4872,50 @@ class TestPurchaseReceipt(FrappeTestCase): make_purchase_entry.posting_date = pr1.posting_date self.assertRaises(NegativeStockError, make_purchase_entry.submit) + def test_purchase_return_from_different_warehouse(self): + from erpnext.controllers.sales_and_purchase_return import make_return_doc + from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry + + item_code = make_item( + "Test Purchase Return From Different Warehouse Item", + { + "is_stock_item": 1, + "has_batch_no": 1, + "create_new_batch": 1, + "batch_number_series": "TPRFDWU.#####", + }, + ).name + + pr1 = make_purchase_receipt( + item_code=item_code, + posting_date=add_days(today(), -4), + qty=100, + rate=100, + warehouse="_Test Warehouse - _TC", + ) + + batch1 = get_batch_from_bundle(pr1.items[0].serial_and_batch_bundle) + + make_stock_entry( + item_code=item_code, + qty=100, + posting_date=add_days(today(), -1), + source="_Test Warehouse - _TC", + target="_Test Warehouse 1 - _TC", + batch_no=batch1, + use_serial_batch_fields=1, + ) + + make_purchase_entry = make_return_doc("Purchase Receipt", pr1.name) + make_purchase_entry.items[0].warehouse = "_Test Warehouse 1 - _TC" + make_purchase_entry.submit() + make_purchase_entry.reload() + + sabb = frappe.get_doc("Serial and Batch Bundle", make_purchase_entry.items[0].serial_and_batch_bundle) + for row in sabb.entries: + self.assertEqual(row.warehouse, "_Test Warehouse 1 - _TC") + self.assertEqual(row.incoming_rate, 100) + def prepare_data_for_internal_transfer(): from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_internal_supplier diff --git a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py index 8ab75360c08..f51254784d9 100644 --- a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py +++ b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py @@ -440,6 +440,8 @@ class SerialandBatchBundle(Document): ) def get_valuation_rate_for_return_entry(self, return_against): + from erpnext.controllers.sales_and_purchase_return import get_warehouses_for_return + if not self.voucher_detail_no: return {} @@ -469,9 +471,11 @@ class SerialandBatchBundle(Document): ["Serial and Batch Bundle", "voucher_detail_no", "=", return_against_voucher_detail_no], ] + # Added to handle rejected warehouse case if self.voucher_type in ["Purchase Receipt", "Purchase Invoice"]: - # Added to handle rejected warehouse case - filters.append(["Serial and Batch Entry", "warehouse", "=", self.warehouse]) + warehouses = get_warehouses_for_return(self.voucher_type, return_against_voucher_detail_no) + if self.warehouse in warehouses: + filters.append(["Serial and Batch Entry", "warehouse", "=", self.warehouse]) bundle_data = frappe.get_all( "Serial and Batch Bundle",