Merge pull request #48155 from rohitwaghchaure/fixed-test-case-for-sre-for-so

fix: test case
This commit is contained in:
rohitwaghchaure
2025-06-19 17:18:14 +05:30
committed by GitHub
6 changed files with 52 additions and 13 deletions

View File

@@ -839,7 +839,7 @@ class SellingController(StockController):
sre_doc = frappe.get_doc("Stock Reservation Entry", sre)
qty_can_be_deliver = 0
if sre_doc.reservation_based_on == "Serial and Batch" and item.serial_and_batch_bundle:
if sre_doc.reservation_based_on == "Serial and Batch":
sbb = frappe.get_doc("Serial and Batch Bundle", item.serial_and_batch_bundle)
if sre_doc.has_serial_no:
delivered_serial_nos = [d.serial_no for d in sbb.entries]

View File

@@ -1100,7 +1100,13 @@ def make_delivery_note(source_name, target_doc=None, kwargs=None):
dn_item.qty = flt(sre.reserved_qty) / flt(dn_item.get("conversion_factor", 1))
dn_item.warehouse = sre.warehouse
if sre.reservation_based_on == "Serial and Batch" and (sre.has_serial_no or sre.has_batch_no):
use_serial_batch_fields = frappe.get_single_value("Stock Settings", "use_serial_batch_fields")
if (
not use_serial_batch_fields
and sre.reservation_based_on == "Serial and Batch"
and (sre.has_serial_no or sre.has_batch_no)
):
dn_item.serial_and_batch_bundle = get_ssb_bundle_for_voucher(sre)
target_doc.append("items", dn_item)

View File

@@ -454,8 +454,6 @@ class DeliveryNote(SellingController):
self.update_prevdoc_status()
self.update_billing_status()
self.update_stock_reservation_entries()
if not self.is_return:
self.check_credit_limit()
elif self.issue_credit_note:
@@ -468,6 +466,8 @@ class DeliveryNote(SellingController):
self.make_bundle_for_sales_purchase_return(table_name)
self.make_bundle_using_old_serial_batch_fields(table_name)
self.update_stock_reservation_entries()
# Updating stock ledger should always be called after updating prevdoc status,
# because updating reserved qty in bin depends upon updated delivered qty in SO
self.update_stock_ledger()

View File

@@ -1802,7 +1802,10 @@ def get_available_serial_nos(kwargs):
filters["warehouse"] = kwargs.warehouse
# Since SLEs are not present against Reserved Stock [POS invoices, SRE], need to ignore reserved serial nos.
ignore_serial_nos = get_reserved_serial_nos(kwargs)
ignore_serial_nos, consider_serial_nos = get_reserved_serial_nos(kwargs)
if consider_serial_nos:
filters["name"] = ("in", consider_serial_nos)
# To ignore serial nos in the same record for the draft state
if kwargs.get("ignore_serial_nos"):
@@ -1911,19 +1914,23 @@ def get_reserved_serial_nos(kwargs) -> list:
"""Returns a list of `Serial No` reserved in POS Invoice and Stock Reservation Entry."""
ignore_serial_nos = []
consider_serial_nos = []
# Extend the list by serial nos reserved in POS Invoice
ignore_serial_nos.extend(get_reserved_serial_nos_for_pos(kwargs))
reserved_entries = get_reserved_serial_nos_for_sre(kwargs)
if not reserved_entries:
return ignore_serial_nos
return ignore_serial_nos, consider_serial_nos
reserved_voucher_details = get_reserved_voucher_details(kwargs)
if not reserved_voucher_details:
return ignore_serial_nos, consider_serial_nos
serial_nos = []
for entry in reserved_entries:
if entry.voucher_no in reserved_voucher_details:
consider_serial_nos.append(entry.serial_no)
continue
if kwargs.get("serial_nos") and entry.serial_no in kwargs.get("serial_nos"):
@@ -1939,7 +1946,7 @@ def get_reserved_serial_nos(kwargs) -> list:
# Extend the list by serial nos reserved via SRE
ignore_serial_nos.extend(serial_nos)
return ignore_serial_nos
return ignore_serial_nos, consider_serial_nos
def get_reserved_voucher_details(kwargs):
@@ -1958,15 +1965,15 @@ def get_reserved_voucher_details(kwargs):
"Delivery Note": {
"name": kwargs.get("sabb_voucher_detail_no"),
"parent": kwargs.get("sabb_voucher_no"),
"docstatus": 1,
"docstatus": ("<", 2),
},
"Stock Entry": {
"name": kwargs.get("sabb_voucher_no"),
"docstatus": 1,
"docstatus": ("<", 2),
},
"Work Order": {
"name": kwargs.get("sabb_voucher_no"),
"docstatus": 1,
"docstatus": ("<", 2),
},
}.get(kwargs.get("sabb_voucher_type"))

View File

@@ -5,7 +5,7 @@ from random import randint
import frappe
from frappe.tests import IntegrationTestCase
from frappe.utils import today
from frappe.utils import cint, today
from erpnext.selling.doctype.sales_order.sales_order import create_pick_list, make_delivery_note
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
@@ -250,6 +250,8 @@ class TestStockReservationEntry(IntegrationTestCase):
},
)
def test_stock_reservation_against_sales_order(self) -> None:
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
items_details = create_items()
se = create_material_receipt(items_details, self.warehouse, qty=10)
@@ -326,16 +328,29 @@ class TestStockReservationEntry(IntegrationTestCase):
so = make_sales_order(
item_list=item_list,
warehouse=self.warehouse,
do_not_submit=True,
)
for row in so.items:
row.qty = 80
so.save()
so.submit()
so.create_stock_reservation_entries()
# Test - 7: Partial Delivery against Sales Order.
dn1 = make_delivery_note(so.name)
item_wise_serial_nos = {}
for item in dn1.items:
item.qty = randint(1, 10)
item.qty = 10
dn1.save()
for row in dn1.items:
if row.serial_no:
item_wise_serial_nos.setdefault(row.item_code, []).extend(get_serial_nos(row.serial_no))
dn1.submit()
for item in so.items:
@@ -350,9 +365,17 @@ class TestStockReservationEntry(IntegrationTestCase):
dn2 = make_delivery_note(so.name)
for item in dn2.items:
item.qty += randint(1, 10)
item.qty = 80
dn2.save()
for row in dn2.items:
if row.item_code in item_wise_serial_nos:
consumed_serial_no = ", ".join(item_wise_serial_nos[row.item_code])
picked_serial_no = get_serial_nos(row.serial_no)
serial_nos = list(set(picked_serial_no) - set(consumed_serial_no))
row.serial_no = "\n".join(serial_nos)
dn2.submit()
for item in so.items:

View File

@@ -202,6 +202,9 @@ def update_stock(ctx, out, doc=None):
"item_code": ctx.item_code,
"warehouse": ctx.warehouse,
"based_on": frappe.get_single_value("Stock Settings", "pick_serial_and_batch_based_on"),
"sabb_voucher_no": doc.get("name"),
"sabb_voucher_detail_no": ctx.child_docname,
"sabb_voucher_type": ctx.doctype,
}
)