mirror of
https://github.com/frappe/erpnext.git
synced 2026-04-27 02:28:30 +00:00
fix: valuation rate for non batchwise valuation
(cherry picked from commit b6312bca9c)
# Conflicts:
# erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
This commit is contained in:
committed by
Mergify
parent
85f635ac4a
commit
3008c7ad82
@@ -4529,6 +4529,286 @@ class TestPurchaseReceipt(FrappeTestCase):
|
||||
|
||||
self.assertEqual(sles, [1500.0, 1500.0])
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
@IntegrationTestCase.change_settings("Stock Settings", {"allow_negative_stock": 0})
|
||||
def test_multiple_transactions_with_same_posting_datetime(self):
|
||||
from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note
|
||||
from erpnext.stock.stock_ledger import NegativeStockError
|
||||
|
||||
item_code = make_item(
|
||||
"Test Item for Multiple Txn with Same Posting Datetime", {"is_stock_item": 1}
|
||||
).name
|
||||
|
||||
pr = make_purchase_receipt(
|
||||
item_code=item_code,
|
||||
qty=100,
|
||||
rate=100,
|
||||
posting_date=today(),
|
||||
posting_time="10:00:00",
|
||||
)
|
||||
|
||||
create_delivery_note(
|
||||
item_code=item_code,
|
||||
qty=100,
|
||||
rate=100,
|
||||
posting_date=today(),
|
||||
posting_time="10:00:00",
|
||||
)
|
||||
|
||||
make_purchase_receipt(
|
||||
item_code=item_code,
|
||||
qty=150,
|
||||
rate=100,
|
||||
posting_date=today(),
|
||||
posting_time="10:00:00",
|
||||
)
|
||||
|
||||
self.assertRaises(NegativeStockError, pr.cancel)
|
||||
|
||||
@IntegrationTestCase.change_settings(
|
||||
"Buying Settings", {"set_landed_cost_based_on_purchase_invoice_rate": 1, "maintain_same_rate": 0}
|
||||
)
|
||||
def test_set_lcv_from_pi_created_against_po(self):
|
||||
from erpnext.buying.doctype.purchase_order.purchase_order import (
|
||||
make_purchase_invoice as make_pi_against_po,
|
||||
)
|
||||
from erpnext.buying.doctype.purchase_order.purchase_order import (
|
||||
make_purchase_receipt as make_pr_against_po,
|
||||
)
|
||||
from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order
|
||||
|
||||
original_value = frappe.db.get_single_value("Accounts Settings", "over_billing_allowance")
|
||||
|
||||
frappe.db.set_single_value("Accounts Settings", "over_billing_allowance", 100)
|
||||
|
||||
item_code = create_item("Test Item for LCV from PI against PO").name
|
||||
|
||||
po = create_purchase_order(item_code=item_code, qty=10, rate=400)
|
||||
pr = make_pr_against_po(po.name)
|
||||
pr.items[0].qty = 5
|
||||
item = frappe.copy_doc(pr.items[0])
|
||||
item.qty = 2
|
||||
pr.append("items", item)
|
||||
|
||||
item = frappe.copy_doc(pr.items[0])
|
||||
item.qty = 3
|
||||
pr.append("items", item)
|
||||
pr.submit()
|
||||
|
||||
pi = make_pi_against_po(po.name)
|
||||
pi.items[0].rate = 500
|
||||
pi.submit()
|
||||
|
||||
pr.reload()
|
||||
for row in pr.items:
|
||||
self.assertTrue(row.amount_difference_with_purchase_invoice)
|
||||
amt_diff = 5000 * (row.qty / 10) - row.amount
|
||||
self.assertEqual(row.amount_difference_with_purchase_invoice, amt_diff)
|
||||
|
||||
frappe.db.set_single_value("Accounts Settings", "over_billing_allowance", original_value)
|
||||
|
||||
def test_purchase_return_with_and_without_return_against_rejected_qty(self):
|
||||
from erpnext.stock.doctype.purchase_receipt.purchase_receipt import (
|
||||
make_purchase_return as _make_purchase_return,
|
||||
)
|
||||
from erpnext.stock.doctype.purchase_receipt.purchase_receipt import (
|
||||
make_purchase_return_against_rejected_warehouse,
|
||||
)
|
||||
|
||||
item_code = create_item("Test Item for PR against Rejected Qty").name
|
||||
warehouse = "_Test Warehouse - _TC"
|
||||
|
||||
company = frappe.db.get_value("Warehouse", warehouse, "company")
|
||||
rejected_wh = create_warehouse("_Test Rejected Warehouse", company=company)
|
||||
|
||||
pr = make_purchase_receipt(
|
||||
item_code=item_code,
|
||||
qty=10,
|
||||
rejected_qty=5,
|
||||
rate=100,
|
||||
warehouse=warehouse,
|
||||
rejected_warehouse=rejected_wh,
|
||||
)
|
||||
|
||||
# Purchase Return against rejected qty partially
|
||||
return_entry = make_purchase_return_against_rejected_warehouse(pr.name)
|
||||
return_entry.items[0].qty = -2
|
||||
return_entry.items[0].received_qty = -2
|
||||
return_entry.save()
|
||||
return_entry.submit()
|
||||
pr.reload()
|
||||
|
||||
# Purchase Return against rejected qty partially
|
||||
return_entry = _make_purchase_return(pr.name)
|
||||
|
||||
self.assertEqual(return_entry.items[0].qty, -10)
|
||||
self.assertEqual(return_entry.items[0].rejected_qty, -3) # 5-2=3
|
||||
|
||||
return_entry.items[0].qty = -8
|
||||
return_entry.items[0].stock_qty = -8
|
||||
return_entry.items[0].received_qty = -11
|
||||
|
||||
return_entry.save()
|
||||
return_entry.submit()
|
||||
|
||||
pr.reload()
|
||||
|
||||
# Purchase Return against rejected qty partially
|
||||
return_entry = _make_purchase_return(pr.name)
|
||||
|
||||
self.assertEqual(return_entry.items[0].qty, -2)
|
||||
self.assertEqual(return_entry.items[0].rejected_qty, 0) # 3-3=0
|
||||
|
||||
def test_do_not_use_batchwise_valuation_with_fifo(self):
|
||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
|
||||
|
||||
item_code = make_item(
|
||||
"Test Item Do Not Use Batchwise Valuation with FIFO",
|
||||
{
|
||||
"is_stock_item": 1,
|
||||
"has_batch_no": 1,
|
||||
"batch_number_series": "BN-TESTDNUBVWF-.#####",
|
||||
"valuation_method": "FIFO",
|
||||
},
|
||||
).name
|
||||
|
||||
doc = frappe.new_doc("Batch")
|
||||
doc.update(
|
||||
{
|
||||
"batch_id": "BN-TESTDNUBVWF-00001",
|
||||
"item": item_code,
|
||||
}
|
||||
).insert()
|
||||
|
||||
doc.db_set("use_batchwise_valuation", 0)
|
||||
doc.reload()
|
||||
|
||||
self.assertTrue(doc.use_batchwise_valuation == 0)
|
||||
|
||||
doc = frappe.new_doc("Batch")
|
||||
doc.update(
|
||||
{
|
||||
"batch_id": "BN-TESTDNUBVWF-00002",
|
||||
"item": item_code,
|
||||
}
|
||||
).insert()
|
||||
|
||||
self.assertTrue(doc.use_batchwise_valuation == 1)
|
||||
|
||||
warehouse = "_Test Warehouse - _TC"
|
||||
make_stock_entry(
|
||||
item_code=item_code,
|
||||
qty=10,
|
||||
rate=100,
|
||||
target=warehouse,
|
||||
batch_no="BN-TESTDNUBVWF-00001",
|
||||
use_serial_batch_fields=1,
|
||||
)
|
||||
|
||||
se1 = make_stock_entry(
|
||||
item_code=item_code,
|
||||
qty=10,
|
||||
rate=200,
|
||||
target=warehouse,
|
||||
batch_no="BN-TESTDNUBVWF-00001",
|
||||
use_serial_batch_fields=1,
|
||||
)
|
||||
|
||||
stock_queue = frappe.db.get_value(
|
||||
"Stock Ledger Entry",
|
||||
{
|
||||
"item_code": item_code,
|
||||
"warehouse": warehouse,
|
||||
"is_cancelled": 0,
|
||||
"voucher_type": "Stock Entry",
|
||||
"voucher_no": se1.name,
|
||||
},
|
||||
"stock_queue",
|
||||
)
|
||||
|
||||
stock_queue = frappe.parse_json(stock_queue)
|
||||
|
||||
self.assertEqual(stock_queue, [[10, 100.0], [10, 200.0]])
|
||||
|
||||
se2 = make_stock_entry(
|
||||
item_code=item_code,
|
||||
qty=10,
|
||||
rate=2,
|
||||
target=warehouse,
|
||||
batch_no="BN-TESTDNUBVWF-00002",
|
||||
use_serial_batch_fields=1,
|
||||
)
|
||||
|
||||
stock_queue = frappe.db.get_value(
|
||||
"Stock Ledger Entry",
|
||||
{
|
||||
"item_code": item_code,
|
||||
"warehouse": warehouse,
|
||||
"is_cancelled": 0,
|
||||
"voucher_type": "Stock Entry",
|
||||
"voucher_no": se2.name,
|
||||
},
|
||||
"stock_queue",
|
||||
)
|
||||
|
||||
stock_queue = frappe.parse_json(stock_queue)
|
||||
self.assertEqual(stock_queue, [[10, 100.0], [10, 200.0]])
|
||||
|
||||
se3 = make_stock_entry(
|
||||
item_code=item_code,
|
||||
qty=20,
|
||||
source=warehouse,
|
||||
batch_no="BN-TESTDNUBVWF-00001",
|
||||
use_serial_batch_fields=1,
|
||||
)
|
||||
|
||||
ste_details = frappe.db.get_value(
|
||||
"Stock Ledger Entry",
|
||||
{
|
||||
"item_code": item_code,
|
||||
"warehouse": warehouse,
|
||||
"is_cancelled": 0,
|
||||
"voucher_type": "Stock Entry",
|
||||
"voucher_no": se3.name,
|
||||
},
|
||||
["stock_queue", "stock_value_difference"],
|
||||
as_dict=1,
|
||||
)
|
||||
|
||||
stock_queue = frappe.parse_json(ste_details.stock_queue)
|
||||
self.assertEqual(stock_queue, [])
|
||||
self.assertEqual(ste_details.stock_value_difference, 3000 * -1)
|
||||
|
||||
se4 = make_stock_entry(
|
||||
item_code=item_code,
|
||||
qty=20,
|
||||
rate=0,
|
||||
target=warehouse,
|
||||
batch_no="BN-TESTDNUBVWF-00001",
|
||||
use_serial_batch_fields=1,
|
||||
do_not_submit=1,
|
||||
)
|
||||
|
||||
se4.items[0].basic_rate = 0.0
|
||||
se4.items[0].allow_zero_valuation_rate = 1
|
||||
se4.submit()
|
||||
|
||||
stock_queue = frappe.db.get_value(
|
||||
"Stock Ledger Entry",
|
||||
{
|
||||
"item_code": item_code,
|
||||
"warehouse": warehouse,
|
||||
"is_cancelled": 0,
|
||||
"voucher_type": "Stock Entry",
|
||||
"voucher_no": se4.name,
|
||||
},
|
||||
"stock_queue",
|
||||
)
|
||||
|
||||
self.assertEqual(frappe.parse_json(stock_queue), [[20, 0.0]])
|
||||
|
||||
>>>>>>> b6312bca9c (fix: valuation rate for non batchwise valuation)
|
||||
|
||||
def prepare_data_for_internal_transfer():
|
||||
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_internal_supplier
|
||||
|
||||
@@ -713,17 +713,16 @@ class SerialandBatchBundle(Document):
|
||||
is_packed_item = True
|
||||
|
||||
stock_queue = []
|
||||
batches = []
|
||||
if prev_sle and prev_sle.stock_queue:
|
||||
batches = frappe.get_all(
|
||||
"Batch",
|
||||
filters={
|
||||
"name": ("in", [d.batch_no for d in self.entries if d.batch_no]),
|
||||
"use_batchwise_valuation": 0,
|
||||
},
|
||||
pluck="name",
|
||||
)
|
||||
batches = frappe.get_all(
|
||||
"Batch",
|
||||
filters={
|
||||
"name": ("in", [d.batch_no for d in self.entries if d.batch_no]),
|
||||
"use_batchwise_valuation": 0,
|
||||
},
|
||||
pluck="name",
|
||||
)
|
||||
|
||||
if prev_sle and prev_sle.stock_queue and parse_json(prev_sle.stock_queue):
|
||||
if batches and valuation_method == "FIFO":
|
||||
stock_queue = parse_json(prev_sle.stock_queue)
|
||||
|
||||
@@ -750,7 +749,7 @@ class SerialandBatchBundle(Document):
|
||||
if d.qty:
|
||||
d.stock_value_difference = flt(d.qty) * d.incoming_rate
|
||||
|
||||
if stock_queue and valuation_method == "FIFO" and d.batch_no in batches:
|
||||
if valuation_method == "FIFO" and d.batch_no in batches and d.incoming_rate is not None:
|
||||
stock_queue.append([d.qty, d.incoming_rate])
|
||||
d.stock_queue = json.dumps(stock_queue)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user