fix: negative valuation rate in PR return (backport #37424) (#37462) * fix: negative valuation rate in PR return (#37424) * fix: negative valuation rate in PR return * test: add test case for PR return (cherry picked from commit26ad688584) # Conflicts: # erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py * chore: `conflicts` --------- Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com> (cherry picked from commit66ad823417) Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
This commit is contained in:
@@ -14,7 +14,8 @@ from erpnext.controllers.sales_and_purchase_return import get_rate_for_return
|
|||||||
from erpnext.controllers.stock_controller import StockController
|
from erpnext.controllers.stock_controller import StockController
|
||||||
from erpnext.controllers.subcontracting import Subcontracting
|
from erpnext.controllers.subcontracting import Subcontracting
|
||||||
from erpnext.stock.get_item_details import get_conversion_factor
|
from erpnext.stock.get_item_details import get_conversion_factor
|
||||||
from erpnext.stock.utils import get_incoming_rate
|
from erpnext.stock.stock_ledger import get_previous_sle
|
||||||
|
from erpnext.stock.utils import get_incoming_rate, get_valuation_method
|
||||||
|
|
||||||
|
|
||||||
class QtyMismatchError(ValidationError):
|
class QtyMismatchError(ValidationError):
|
||||||
@@ -504,6 +505,17 @@ class BuyingController(StockController, Subcontracting):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if self.is_return:
|
if self.is_return:
|
||||||
|
if get_valuation_method(d.item_code) == "Moving Average":
|
||||||
|
previous_sle = get_previous_sle(
|
||||||
|
{
|
||||||
|
"item_code": d.item_code,
|
||||||
|
"warehouse": d.warehouse,
|
||||||
|
"posting_date": self.posting_date,
|
||||||
|
"posting_time": self.posting_time,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
outgoing_rate = flt(previous_sle.get("valuation_rate"))
|
||||||
|
else:
|
||||||
outgoing_rate = get_rate_for_return(
|
outgoing_rate = get_rate_for_return(
|
||||||
self.doctype, self.name, d.item_code, self.return_against, item_row=d
|
self.doctype, self.name, d.item_code, self.return_against, item_row=d
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1996,6 +1996,60 @@ class TestPurchaseReceipt(FrappeTestCase):
|
|||||||
ste7.reload()
|
ste7.reload()
|
||||||
self.assertEqual(ste7.items[0].valuation_rate, valuation_rate)
|
self.assertEqual(ste7.items[0].valuation_rate, valuation_rate)
|
||||||
|
|
||||||
|
def test_valuation_rate_in_return_purchase_receipt_for_moving_average(self):
|
||||||
|
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
|
||||||
|
from erpnext.stock.stock_ledger import get_previous_sle
|
||||||
|
|
||||||
|
# Step - 1: Create an Item (Valuation Method = Moving Average)
|
||||||
|
item_code = make_item(properties={"is_stock_item": 1, "valuation_method": "Moving Average"}).name
|
||||||
|
|
||||||
|
# Step - 2: Create a Purchase Receipt (Qty = 10, Rate = 100)
|
||||||
|
pr = make_purchase_receipt(qty=10, rate=100, item_code=item_code)
|
||||||
|
|
||||||
|
# Step - 3: Create a Material Receipt Stock Entry (Qty = 100, Basic Rate = 10)
|
||||||
|
warehouse = "_Test Warehouse - _TC"
|
||||||
|
make_stock_entry(
|
||||||
|
purpose="Material Receipt",
|
||||||
|
item_code=item_code,
|
||||||
|
to_warehouse=warehouse,
|
||||||
|
qty=100,
|
||||||
|
rate=10,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Step - 4: Create a Material Issue Stock Entry (Qty = 100, Basic Rate = 18.18 [Auto Fetched])
|
||||||
|
make_stock_entry(
|
||||||
|
purpose="Material Issue", item_code=item_code, from_warehouse=warehouse, qty=100
|
||||||
|
)
|
||||||
|
|
||||||
|
# Step - 5: Create a Return Purchase Return (Qty = -8, Rate = 100 [Auto fetched])
|
||||||
|
return_pr = make_purchase_receipt(
|
||||||
|
is_return=1,
|
||||||
|
return_against=pr.name,
|
||||||
|
item_code=item_code,
|
||||||
|
qty=-8,
|
||||||
|
)
|
||||||
|
|
||||||
|
sle = frappe.db.get_value(
|
||||||
|
"Stock Ledger Entry",
|
||||||
|
{"voucher_no": return_pr.name, "voucher_detail_no": return_pr.items[0].name},
|
||||||
|
["posting_date", "posting_time", "outgoing_rate", "valuation_rate"],
|
||||||
|
as_dict=1,
|
||||||
|
)
|
||||||
|
previous_sle_valuation_rate = get_previous_sle(
|
||||||
|
{
|
||||||
|
"item_code": item_code,
|
||||||
|
"warehouse": warehouse,
|
||||||
|
"posting_date": sle.posting_date,
|
||||||
|
"posting_time": sle.posting_time,
|
||||||
|
}
|
||||||
|
).get("valuation_rate")
|
||||||
|
|
||||||
|
# Test - 1: Valuation Rate should be equal to Outgoing Rate
|
||||||
|
self.assertEqual(flt(sle.outgoing_rate, 2), flt(sle.valuation_rate, 2))
|
||||||
|
|
||||||
|
# Test - 2: Valuation Rate should be equal to Previous SLE Valuation Rate
|
||||||
|
self.assertEqual(flt(sle.valuation_rate, 2), flt(previous_sle_valuation_rate, 2))
|
||||||
|
|
||||||
|
|
||||||
def prepare_data_for_internal_transfer():
|
def prepare_data_for_internal_transfer():
|
||||||
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_internal_supplier
|
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_internal_supplier
|
||||||
|
|||||||
@@ -658,6 +658,9 @@ class update_entries_after(object):
|
|||||||
get_rate_for_return, # don't move this import to top
|
get_rate_for_return, # don't move this import to top
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if self.valuation_method == "Moving Average":
|
||||||
|
rate = self.data[self.args.warehouse].previous_sle.valuation_rate
|
||||||
|
else:
|
||||||
rate = get_rate_for_return(
|
rate = get_rate_for_return(
|
||||||
sle.voucher_type,
|
sle.voucher_type,
|
||||||
sle.voucher_no,
|
sle.voucher_no,
|
||||||
@@ -665,7 +668,6 @@ class update_entries_after(object):
|
|||||||
voucher_detail_no=sle.voucher_detail_no,
|
voucher_detail_no=sle.voucher_detail_no,
|
||||||
sle=sle,
|
sle=sle,
|
||||||
)
|
)
|
||||||
|
|
||||||
elif (
|
elif (
|
||||||
sle.voucher_type in ["Purchase Receipt", "Purchase Invoice"]
|
sle.voucher_type in ["Purchase Receipt", "Purchase Invoice"]
|
||||||
and sle.voucher_detail_no
|
and sle.voucher_detail_no
|
||||||
|
|||||||
Reference in New Issue
Block a user