diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py index 80985e8dfc1..d5053613ae3 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py @@ -513,6 +513,15 @@ class PurchaseReceipt(BuyingController): ) def make_stock_received_but_not_billed_entry(item): + if ( + self.get("is_return") + and item.return_qty_from_rejected_warehouse + and not frappe.db.get_single_value( + "Buying Settings", "set_valuation_rate_for_rejected_materials" + ) + ): + return 0.0 + account = ( warehouse_account[item.from_warehouse]["account"] if item.from_warehouse else stock_asset_rbnb ) diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py index 034f7cc77f7..9049894fa71 100644 --- a/erpnext/stock/stock_ledger.py +++ b/erpnext/stock/stock_ledger.py @@ -1422,7 +1422,10 @@ class update_entries_after: return 0.0 stock_queue.remove_stock( - qty=abs(actual_qty), outgoing_rate=outgoing_rate, rate_generator=rate_generator + qty=abs(actual_qty), + outgoing_rate=outgoing_rate, + rate_generator=rate_generator, + is_return_purchase_entry=self.is_return_purchase_entry(sle), ) _qty, stock_value = stock_queue.get_total_stock_and_value() @@ -1440,6 +1443,12 @@ class update_entries_after: if self.wh_data.qty_after_transaction: self.wh_data.valuation_rate = self.wh_data.stock_value / self.wh_data.qty_after_transaction + def is_return_purchase_entry(self, sle): + if sle.voucher_type in ["Purchase Invoice", "Purchase Receipt"]: + return frappe.get_cached_value(sle.voucher_type, sle.voucher_no, "is_return") + + return False + def update_batched_values(self, sle): from erpnext.stock.serial_batch_bundle import BatchNoValuation diff --git a/erpnext/stock/valuation.py b/erpnext/stock/valuation.py index b1df982c906..9ce3c88c57b 100644 --- a/erpnext/stock/valuation.py +++ b/erpnext/stock/valuation.py @@ -18,7 +18,11 @@ class BinWiseValuation(ABC): @abstractmethod def remove_stock( - self, qty: float, outgoing_rate: float = 0.0, rate_generator: Callable[[], float] | None = None + self, + qty: float, + outgoing_rate: float = 0.0, + rate_generator: Callable[[], float] | None = None, + is_return_purchase_entry: bool = False, ) -> list[StockBin]: pass @@ -96,7 +100,11 @@ class FIFOValuation(BinWiseValuation): self.queue[-1][QTY] = qty def remove_stock( - self, qty: float, outgoing_rate: float = 0.0, rate_generator: Callable[[], float] | None = None + self, + qty: float, + outgoing_rate: float = 0.0, + rate_generator: Callable[[], float] | None = None, + is_return_purchase_entry: bool = False, ) -> list[StockBin]: """Remove stock from the queue and return popped bins. @@ -115,7 +123,7 @@ class FIFOValuation(BinWiseValuation): self.queue.append([0, rate_generator()]) index = None - if outgoing_rate > 0: + if outgoing_rate > 0 or is_return_purchase_entry: # Find the entry where rate matched with outgoing rate for idx, fifo_bin in enumerate(self.queue): if fifo_bin[RATE] == outgoing_rate: @@ -202,7 +210,11 @@ class LIFOValuation(BinWiseValuation): self.stack[-1][QTY] = qty def remove_stock( - self, qty: float, outgoing_rate: float = 0.0, rate_generator: Callable[[], float] | None = None + self, + qty: float, + outgoing_rate: float = 0.0, + rate_generator: Callable[[], float] | None = None, + is_return_purchase_entry: bool = False, ) -> list[StockBin]: """Remove stock from the stack and return popped bins.