mirror of
https://github.com/frappe/erpnext.git
synced 2026-04-13 03:45:08 +00:00
committed by
Mergify
parent
b8a07a437b
commit
ae3dd5b831
@@ -1590,6 +1590,80 @@ class TestStockReconciliation(FrappeTestCase, StockTestMixin):
|
|||||||
|
|
||||||
self.assertFalse(status == "Active")
|
self.assertFalse(status == "Active")
|
||||||
|
|
||||||
|
def test_stock_reconciliation_for_batch_with_backward(self):
|
||||||
|
# Make stock inward for 10 -> Stock Reco for 20 after two days
|
||||||
|
# Make backdated delivery note for 10 qty between stock inward and stock reco
|
||||||
|
# Check the state of the current serial and batch bundle in the stock reco
|
||||||
|
# The state should be cancelled
|
||||||
|
|
||||||
|
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
|
||||||
|
|
||||||
|
item_code = "Test Stock Reco for Batch with Backward"
|
||||||
|
|
||||||
|
self.make_item(
|
||||||
|
item_code, {"has_batch_no": 1, "create_new_batch": 1, "batch_number_series": "BCN-CB.#####"}
|
||||||
|
)
|
||||||
|
|
||||||
|
warehouse = "_Test Warehouse - _TC"
|
||||||
|
|
||||||
|
se = make_stock_entry(
|
||||||
|
posting_date=add_days(nowdate(), -2),
|
||||||
|
posting_time="02:00",
|
||||||
|
item_code=item_code,
|
||||||
|
target=warehouse,
|
||||||
|
qty=10,
|
||||||
|
basic_rate=100,
|
||||||
|
)
|
||||||
|
|
||||||
|
batch_no = get_batch_from_bundle(se.items[0].serial_and_batch_bundle)
|
||||||
|
|
||||||
|
sr = create_stock_reconciliation(
|
||||||
|
item_code=item_code,
|
||||||
|
warehouse=warehouse,
|
||||||
|
qty=20,
|
||||||
|
rate=200,
|
||||||
|
use_serial_batch_fields=1,
|
||||||
|
batch_no=batch_no,
|
||||||
|
posting_date=nowdate(),
|
||||||
|
posting_time="03:00",
|
||||||
|
)
|
||||||
|
|
||||||
|
current_sabb = sr.items[0].current_serial_and_batch_bundle
|
||||||
|
|
||||||
|
self.assertTrue(frappe.db.get_value("Serial and Batch Bundle", current_sabb, "docstatus") == 1)
|
||||||
|
|
||||||
|
self.assertTrue(
|
||||||
|
frappe.db.get_value(
|
||||||
|
"Stock Ledger Entry", {"serial_and_batch_bundle": current_sabb, "is_cancelled": 0}, "name"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.assertTrue(sr.items[0].current_serial_and_batch_bundle)
|
||||||
|
self.assertTrue(sr.items[0].current_qty)
|
||||||
|
self.assertTrue(sr.items[0].current_qty == 10)
|
||||||
|
|
||||||
|
se = make_stock_entry(
|
||||||
|
posting_date=add_days(nowdate(), -1),
|
||||||
|
posting_time="02:00",
|
||||||
|
item_code=item_code,
|
||||||
|
source=warehouse,
|
||||||
|
qty=10,
|
||||||
|
basic_rate=100,
|
||||||
|
use_serial_batch_fields=1,
|
||||||
|
batch_no=batch_no,
|
||||||
|
)
|
||||||
|
|
||||||
|
sr.reload()
|
||||||
|
self.assertFalse(sr.items[0].current_serial_and_batch_bundle)
|
||||||
|
self.assertTrue(sr.items[0].current_qty == 0)
|
||||||
|
|
||||||
|
self.assertFalse(frappe.db.get_value("Serial and Batch Bundle", current_sabb, "docstatus") == 1)
|
||||||
|
|
||||||
|
self.assertFalse(
|
||||||
|
frappe.db.get_value(
|
||||||
|
"Stock Ledger Entry", {"serial_and_batch_bundle": current_sabb, "is_cancelled": 0}, "name"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def create_batch_item_with_batch(item_name, batch_id):
|
def create_batch_item_with_batch(item_name, batch_id):
|
||||||
batch_item_doc = create_item(item_name, is_stock_item=1)
|
batch_item_doc = create_item(item_name, is_stock_item=1)
|
||||||
|
|||||||
@@ -974,10 +974,12 @@ class update_entries_after:
|
|||||||
self.wh_data.valuation_rate = self.get_fallback_rate(sle)
|
self.wh_data.valuation_rate = self.get_fallback_rate(sle)
|
||||||
|
|
||||||
def reset_actual_qty_for_stock_reco(self, sle):
|
def reset_actual_qty_for_stock_reco(self, sle):
|
||||||
doc = frappe.get_cached_doc("Stock Reconciliation", sle.voucher_no)
|
doc = frappe.get_doc("Stock Reconciliation", sle.voucher_no)
|
||||||
doc.recalculate_current_qty(sle.voucher_detail_no, sle.creation, sle.actual_qty > 0)
|
doc.recalculate_current_qty(sle.voucher_detail_no, sle.creation, sle.actual_qty > 0)
|
||||||
|
|
||||||
if sle.actual_qty < 0:
|
if sle.actual_qty < 0:
|
||||||
|
doc.reload()
|
||||||
|
|
||||||
sle.actual_qty = (
|
sle.actual_qty = (
|
||||||
flt(frappe.db.get_value("Stock Reconciliation Item", sle.voucher_detail_no, "current_qty"))
|
flt(frappe.db.get_value("Stock Reconciliation Item", sle.voucher_detail_no, "current_qty"))
|
||||||
* -1
|
* -1
|
||||||
@@ -986,6 +988,16 @@ class update_entries_after:
|
|||||||
if abs(sle.actual_qty) == 0.0:
|
if abs(sle.actual_qty) == 0.0:
|
||||||
sle.is_cancelled = 1
|
sle.is_cancelled = 1
|
||||||
|
|
||||||
|
if sle.serial_and_batch_bundle:
|
||||||
|
for row in doc.items:
|
||||||
|
if row.name == sle.voucher_detail_no:
|
||||||
|
row.db_set("current_serial_and_batch_bundle", "")
|
||||||
|
|
||||||
|
sabb_doc = frappe.get_doc("Serial and Batch Bundle", sle.serial_and_batch_bundle)
|
||||||
|
sabb_doc.voucher_detail_no = None
|
||||||
|
sabb_doc.voucher_no = None
|
||||||
|
sabb_doc.cancel()
|
||||||
|
|
||||||
if sle.serial_and_batch_bundle and frappe.get_cached_value("Item", sle.item_code, "has_serial_no"):
|
if sle.serial_and_batch_bundle and frappe.get_cached_value("Item", sle.item_code, "has_serial_no"):
|
||||||
self.update_serial_no_status(sle)
|
self.update_serial_no_status(sle)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user