fix: test case
This commit is contained in:
@@ -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]
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -444,8 +444,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:
|
||||
@@ -458,6 +456,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()
|
||||
|
||||
@@ -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"))
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user