mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-26 08:24:47 +00:00
refactor(test): use change_settings instead of update_stock_settings
This commit is contained in:
@@ -1878,6 +1878,7 @@ class TestSalesOrder(FrappeTestCase):
|
|||||||
self.assertEqual(pe.references[1].reference_name, so.name)
|
self.assertEqual(pe.references[1].reference_name, so.name)
|
||||||
self.assertEqual(pe.references[1].allocated_amount, 300)
|
self.assertEqual(pe.references[1].allocated_amount, 300)
|
||||||
|
|
||||||
|
@change_settings("Stock Settings", {"enable_stock_reservation": 1})
|
||||||
def test_stock_reservation_against_sales_order(self) -> None:
|
def test_stock_reservation_against_sales_order(self) -> None:
|
||||||
from random import randint, uniform
|
from random import randint, uniform
|
||||||
|
|
||||||
@@ -1890,7 +1891,6 @@ class TestSalesOrder(FrappeTestCase):
|
|||||||
from erpnext.stock.doctype.stock_reservation_entry.test_stock_reservation_entry import (
|
from erpnext.stock.doctype.stock_reservation_entry.test_stock_reservation_entry import (
|
||||||
create_items,
|
create_items,
|
||||||
create_material_receipts,
|
create_material_receipts,
|
||||||
update_stock_settings,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
items_details, warehouse = create_items(), "_Test Warehouse - _TC"
|
items_details, warehouse = create_items(), "_Test Warehouse - _TC"
|
||||||
@@ -1914,106 +1914,102 @@ class TestSalesOrder(FrappeTestCase):
|
|||||||
warehouse="_Test Warehouse - _TC",
|
warehouse="_Test Warehouse - _TC",
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test - 1: `ValidationError` should be thrown, if Stock Reservation is disabled in Stock Settings.
|
# Test - 1: Stock should not be reserved if the Available Qty to Reserve is less than the Ordered Qty and Partial Reservation is disabled in Stock Settings.
|
||||||
update_stock_settings("enable_stock_reservation", 0)
|
with change_settings("Stock Settings", {"allow_partial_reservation": 0}):
|
||||||
self.assertRaises(frappe.ValidationError, so.create_stock_reservation_entries)
|
so.create_stock_reservation_entries()
|
||||||
|
self.assertFalse(has_reserved_stock("Sales Order", so.name))
|
||||||
|
|
||||||
# Enable Stock Reservation.
|
# Test - 2: Stock should be Partially Reserved if the Partial Reservation is enabled in Stock Settings.
|
||||||
update_stock_settings("enable_stock_reservation", 1)
|
with change_settings("Stock Settings", {"allow_partial_reservation": 1}):
|
||||||
|
so.create_stock_reservation_entries()
|
||||||
|
so.load_from_db()
|
||||||
|
self.assertTrue(has_reserved_stock("Sales Order", so.name))
|
||||||
|
|
||||||
# Test - 2: Stock should not be reserved if the Available Qty to Reserve is less than the Ordered Qty and Partial Reservation is disabled in Stock Settings.
|
for item in so.items:
|
||||||
update_stock_settings("allow_partial_reservation", 0)
|
sre_details = get_stock_reservation_entries_for_voucher(
|
||||||
so.create_stock_reservation_entries()
|
"Sales Order", so.name, item.name, fields=["reserved_qty", "status"]
|
||||||
self.assertFalse(has_reserved_stock("Sales Order", so.name))
|
)
|
||||||
|
self.assertEqual(item.stock_reserved_qty, sre_details[0].reserved_qty)
|
||||||
|
self.assertEqual(sre_details[0].status, "Partially Reserved")
|
||||||
|
|
||||||
# Test - 3: Stock should be Partially Reserved if the Partial Reservation is enabled in Stock Settings.
|
# Test - 3: Stock should be fully Reserved if the Available Qty to Reserve is greater than the Un-reserved Qty.
|
||||||
update_stock_settings("allow_partial_reservation", 1)
|
create_material_receipts(items_details, warehouse, qty=100)
|
||||||
so.create_stock_reservation_entries()
|
so.create_stock_reservation_entries()
|
||||||
so.load_from_db()
|
so.load_from_db()
|
||||||
self.assertTrue(has_reserved_stock("Sales Order", so.name))
|
|
||||||
|
|
||||||
for item in so.items:
|
reserved_qty_details = get_sre_reserved_qty_details_for_voucher("Sales Order", so.name)
|
||||||
sre_details = get_stock_reservation_entries_for_voucher(
|
for item in so.items:
|
||||||
"Sales Order", so.name, item.name, fields=["reserved_qty", "status"]
|
reserved_qty = reserved_qty_details[(item.name, item.warehouse)]
|
||||||
|
self.assertEqual(item.stock_reserved_qty, reserved_qty)
|
||||||
|
self.assertEqual(item.stock_qty, item.stock_reserved_qty)
|
||||||
|
|
||||||
|
# Test - 4: Stock should get unreserved on cancellation of Stock Reservation Entries.
|
||||||
|
cancel_stock_reservation_entries("Sales Order", so.name)
|
||||||
|
so.load_from_db()
|
||||||
|
self.assertFalse(has_reserved_stock("Sales Order", so.name))
|
||||||
|
|
||||||
|
for item in so.items:
|
||||||
|
self.assertEqual(item.stock_reserved_qty, 0)
|
||||||
|
|
||||||
|
# Test - 5: Re-reserve the stock.
|
||||||
|
so.create_stock_reservation_entries()
|
||||||
|
self.assertTrue(has_reserved_stock("Sales Order", so.name))
|
||||||
|
|
||||||
|
# Test - 6: Stock should get unreserved on cancellation of Sales Order.
|
||||||
|
so.cancel()
|
||||||
|
so.load_from_db()
|
||||||
|
self.assertFalse(has_reserved_stock("Sales Order", so.name))
|
||||||
|
|
||||||
|
for item in so.items:
|
||||||
|
self.assertEqual(item.stock_reserved_qty, 0)
|
||||||
|
|
||||||
|
# Create Sales Order and Reserve Stock.
|
||||||
|
so = make_sales_order(
|
||||||
|
item_list=item_list,
|
||||||
|
warehouse="_Test Warehouse - _TC",
|
||||||
)
|
)
|
||||||
self.assertEqual(item.stock_reserved_qty, sre_details[0].reserved_qty)
|
so.create_stock_reservation_entries()
|
||||||
self.assertEqual(sre_details[0].status, "Partially Reserved")
|
|
||||||
|
|
||||||
# Test - 4: Stock should be fully Reserved if the Available Qty to Reserve is greater than the Un-reserved Qty.
|
# Test - 7: Partial Delivery against Sales Order.
|
||||||
create_material_receipts(items_details, warehouse, qty=100)
|
dn1 = make_delivery_note(so.name)
|
||||||
so.create_stock_reservation_entries()
|
|
||||||
so.load_from_db()
|
|
||||||
|
|
||||||
reserved_qty_details = get_sre_reserved_qty_details_for_voucher("Sales Order", so.name)
|
for item in dn1.items:
|
||||||
for item in so.items:
|
item.qty = flt(uniform(1, 10), 0 if item.stock_uom == "Nos" else 3)
|
||||||
reserved_qty = reserved_qty_details[(item.name, item.warehouse)]
|
|
||||||
self.assertEqual(item.stock_reserved_qty, reserved_qty)
|
|
||||||
self.assertEqual(item.stock_qty, item.stock_reserved_qty)
|
|
||||||
|
|
||||||
# Test - 5: Stock should get unreserved on cancellation of Stock Reservation Entries.
|
dn1.save()
|
||||||
cancel_stock_reservation_entries("Sales Order", so.name)
|
dn1.submit()
|
||||||
so.load_from_db()
|
|
||||||
self.assertFalse(has_reserved_stock("Sales Order", so.name))
|
|
||||||
|
|
||||||
for item in so.items:
|
for item in so.items:
|
||||||
self.assertEqual(item.stock_reserved_qty, 0)
|
sre_details = get_stock_reservation_entries_for_voucher(
|
||||||
|
"Sales Order", so.name, item.name, fields=["delivered_qty", "status"]
|
||||||
|
)
|
||||||
|
self.assertGreater(sre_details[0].delivered_qty, 0)
|
||||||
|
self.assertEqual(sre_details[0].status, "Partially Delivered")
|
||||||
|
|
||||||
# Test - 6: Re-reserve the stock.
|
# Test - 8: Over Delivery against Sales Order, SRE Delivered Qty should not be greater than the SRE Reserved Qty.
|
||||||
so.create_stock_reservation_entries()
|
with change_settings("Stock Settings", {"over_delivery_receipt_allowance": 100}):
|
||||||
self.assertTrue(has_reserved_stock("Sales Order", so.name))
|
dn2 = make_delivery_note(so.name)
|
||||||
|
|
||||||
# Test - 7: Stock should get unreserved on cancellation of Sales Order.
|
for item in dn2.items:
|
||||||
so.cancel()
|
item.qty += flt(uniform(1, 10), 0 if item.stock_uom == "Nos" else 3)
|
||||||
so.load_from_db()
|
|
||||||
self.assertFalse(has_reserved_stock("Sales Order", so.name))
|
|
||||||
|
|
||||||
for item in so.items:
|
dn2.save()
|
||||||
self.assertEqual(item.stock_reserved_qty, 0)
|
dn2.submit()
|
||||||
|
|
||||||
# Create Sales Order and Reserve Stock.
|
for item in so.items:
|
||||||
so = make_sales_order(
|
sre_details = frappe.db.get_all(
|
||||||
item_list=item_list,
|
"Stock Reservation Entry",
|
||||||
warehouse="_Test Warehouse - _TC",
|
filters={
|
||||||
)
|
"voucher_type": "Sales Order",
|
||||||
so.create_stock_reservation_entries()
|
"voucher_no": so.name,
|
||||||
|
"voucher_detail_no": item.name,
|
||||||
|
},
|
||||||
|
fields=["status", "reserved_qty", "delivered_qty"],
|
||||||
|
)
|
||||||
|
|
||||||
# Test - 8: Partial Delivery against Sales Order.
|
for sre_detail in sre_details:
|
||||||
dn1 = make_delivery_note(so.name)
|
self.assertEqual(sre_detail.reserved_qty, sre_detail.delivered_qty)
|
||||||
|
self.assertEqual(sre_detail.status, "Delivered")
|
||||||
for item in dn1.items:
|
|
||||||
item.qty = flt(uniform(1, 10), 0 if item.stock_uom == "Nos" else 3)
|
|
||||||
|
|
||||||
dn1.save()
|
|
||||||
dn1.submit()
|
|
||||||
|
|
||||||
for item in so.items:
|
|
||||||
sre_details = get_stock_reservation_entries_for_voucher(
|
|
||||||
"Sales Order", so.name, item.name, fields=["delivered_qty", "status"]
|
|
||||||
)
|
|
||||||
self.assertGreater(sre_details[0].delivered_qty, 0)
|
|
||||||
self.assertEqual(sre_details[0].status, "Partially Delivered")
|
|
||||||
|
|
||||||
# Test - 9: Over Delivery against Sales Order, SRE Delivered Qty should not be greater than the SRE Reserved Qty.
|
|
||||||
update_stock_settings("over_delivery_receipt_allowance", 100)
|
|
||||||
dn2 = make_delivery_note(so.name)
|
|
||||||
|
|
||||||
for item in dn2.items:
|
|
||||||
item.qty += flt(uniform(1, 10), 0 if item.stock_uom == "Nos" else 3)
|
|
||||||
|
|
||||||
dn2.save()
|
|
||||||
dn2.submit()
|
|
||||||
update_stock_settings("over_delivery_receipt_allowance", 0)
|
|
||||||
|
|
||||||
for item in so.items:
|
|
||||||
sre_details = frappe.db.get_all(
|
|
||||||
"Stock Reservation Entry",
|
|
||||||
filters={"voucher_type": "Sales Order", "voucher_no": so.name, "voucher_detail_no": item.name},
|
|
||||||
fields=["status", "reserved_qty", "delivered_qty"],
|
|
||||||
)
|
|
||||||
|
|
||||||
for sre_detail in sre_details:
|
|
||||||
self.assertEqual(sre_detail.reserved_qty, sre_detail.delivered_qty)
|
|
||||||
self.assertEqual(sre_detail.status, "Delivered")
|
|
||||||
|
|
||||||
|
|
||||||
def automatically_fetch_payment_terms(enable=1):
|
def automatically_fetch_payment_terms(enable=1):
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.tests.utils import FrappeTestCase
|
from frappe.tests.utils import FrappeTestCase, change_settings
|
||||||
|
|
||||||
|
|
||||||
class TestStockReservationEntry(FrappeTestCase):
|
class TestStockReservationEntry(FrappeTestCase):
|
||||||
@@ -25,18 +25,17 @@ class TestStockReservationEntry(FrappeTestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Case - 1: When `Stock Reservation` is disabled in `Stock Settings`, throw `ValidationError`
|
# Case - 1: When `Stock Reservation` is disabled in `Stock Settings`, throw `ValidationError`
|
||||||
update_stock_settings("enable_stock_reservation", 0)
|
with change_settings("Stock Settings", {"enable_stock_reservation": 0}):
|
||||||
self.assertRaises(frappe.ValidationError, validate_stock_reservation_settings, voucher)
|
self.assertRaises(frappe.ValidationError, validate_stock_reservation_settings, voucher)
|
||||||
|
|
||||||
# Case - 2: When `Voucher Type` is not allowed for `Stock Reservation`, throw `ValidationError`
|
with change_settings("Stock Settings", {"enable_stock_reservation": 1}):
|
||||||
update_stock_settings("enable_stock_reservation", 1)
|
# Case - 2: When `Voucher Type` is not allowed for `Stock Reservation`, throw `ValidationError`
|
||||||
voucher.doctype = "NOT ALLOWED"
|
voucher.doctype = "NOT ALLOWED"
|
||||||
self.assertRaises(frappe.ValidationError, validate_stock_reservation_settings, voucher)
|
self.assertRaises(frappe.ValidationError, validate_stock_reservation_settings, voucher)
|
||||||
|
|
||||||
# Case - 3: When `Stock Reservation` is enabled and `Voucher Type` is allowed
|
# Case - 3: When `Voucher Type` is allowed for `Stock Reservation`
|
||||||
update_stock_settings("enable_stock_reservation", 1)
|
voucher.doctype = "Sales Order"
|
||||||
voucher.doctype = "Sales Order"
|
self.assertIsNone(validate_stock_reservation_settings(voucher), None)
|
||||||
self.assertIsNone(validate_stock_reservation_settings(voucher), None)
|
|
||||||
|
|
||||||
def test_get_available_qty_to_reserve(self) -> None:
|
def test_get_available_qty_to_reserve(self) -> None:
|
||||||
from erpnext.stock.doctype.stock_reservation_entry.stock_reservation_entry import (
|
from erpnext.stock.doctype.stock_reservation_entry.stock_reservation_entry import (
|
||||||
@@ -106,15 +105,13 @@ class TestStockReservationEntry(FrappeTestCase):
|
|||||||
sre.load_from_db()
|
sre.load_from_db()
|
||||||
self.assertEqual(sre.status, "Cancelled")
|
self.assertEqual(sre.status, "Cancelled")
|
||||||
|
|
||||||
|
@change_settings("Stock Settings", {"enable_stock_reservation": 1})
|
||||||
def test_update_reserved_qty_in_voucher(self) -> None:
|
def test_update_reserved_qty_in_voucher(self) -> None:
|
||||||
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
|
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
|
||||||
|
|
||||||
item_code, warehouse = "SR Item 1", "_Test Warehouse - _TC"
|
item_code, warehouse = "SR Item 1", "_Test Warehouse - _TC"
|
||||||
|
|
||||||
# Step - 1: Enable `Stock Reservation`
|
# Step - 1: Create a `Sales Order`
|
||||||
update_stock_settings("enable_stock_reservation", 1)
|
|
||||||
|
|
||||||
# Step - 2: Create a `Sales Order`
|
|
||||||
so = make_sales_order(
|
so = make_sales_order(
|
||||||
item_code=item_code,
|
item_code=item_code,
|
||||||
warehouse=warehouse,
|
warehouse=warehouse,
|
||||||
@@ -127,7 +124,7 @@ class TestStockReservationEntry(FrappeTestCase):
|
|||||||
so.save()
|
so.save()
|
||||||
so.submit()
|
so.submit()
|
||||||
|
|
||||||
# Step - 3: Create a `Stock Reservation Entry[1]` for the `Sales Order Item`
|
# Step - 2: Create a `Stock Reservation Entry[1]` for the `Sales Order Item`
|
||||||
sre1 = make_stock_reservation_entry(
|
sre1 = make_stock_reservation_entry(
|
||||||
item_code=item_code,
|
item_code=item_code,
|
||||||
warehouse=warehouse,
|
warehouse=warehouse,
|
||||||
@@ -142,7 +139,7 @@ class TestStockReservationEntry(FrappeTestCase):
|
|||||||
self.assertEqual(sre1.status, "Partially Reserved")
|
self.assertEqual(sre1.status, "Partially Reserved")
|
||||||
self.assertEqual(so.items[0].stock_reserved_qty, sre1.reserved_qty)
|
self.assertEqual(so.items[0].stock_reserved_qty, sre1.reserved_qty)
|
||||||
|
|
||||||
# Step - 4: Create a `Stock Reservation Entry[2]` for the `Sales Order Item`
|
# Step - 3: Create a `Stock Reservation Entry[2]` for the `Sales Order Item`
|
||||||
sre2 = make_stock_reservation_entry(
|
sre2 = make_stock_reservation_entry(
|
||||||
item_code=item_code,
|
item_code=item_code,
|
||||||
warehouse=warehouse,
|
warehouse=warehouse,
|
||||||
@@ -157,14 +154,14 @@ class TestStockReservationEntry(FrappeTestCase):
|
|||||||
self.assertEqual(sre1.status, "Partially Reserved")
|
self.assertEqual(sre1.status, "Partially Reserved")
|
||||||
self.assertEqual(so.items[0].stock_reserved_qty, sre1.reserved_qty + sre2.reserved_qty)
|
self.assertEqual(so.items[0].stock_reserved_qty, sre1.reserved_qty + sre2.reserved_qty)
|
||||||
|
|
||||||
# Step - 5: Cancel `Stock Reservation Entry[1]`
|
# Step - 4: Cancel `Stock Reservation Entry[1]`
|
||||||
sre1.cancel()
|
sre1.cancel()
|
||||||
so.load_from_db()
|
so.load_from_db()
|
||||||
sre1.load_from_db()
|
sre1.load_from_db()
|
||||||
self.assertEqual(sre1.status, "Cancelled")
|
self.assertEqual(sre1.status, "Cancelled")
|
||||||
self.assertEqual(so.items[0].stock_reserved_qty, sre2.reserved_qty)
|
self.assertEqual(so.items[0].stock_reserved_qty, sre2.reserved_qty)
|
||||||
|
|
||||||
# Step - 6: Cancel `Stock Reservation Entry[2]`
|
# Step - 5: Cancel `Stock Reservation Entry[2]`
|
||||||
sre2.cancel()
|
sre2.cancel()
|
||||||
so.load_from_db()
|
so.load_from_db()
|
||||||
sre2.load_from_db()
|
sre2.load_from_db()
|
||||||
@@ -172,10 +169,6 @@ class TestStockReservationEntry(FrappeTestCase):
|
|||||||
self.assertEqual(so.items[0].stock_reserved_qty, 0)
|
self.assertEqual(so.items[0].stock_reserved_qty, 0)
|
||||||
|
|
||||||
|
|
||||||
def update_stock_settings(field: str, value: any) -> None:
|
|
||||||
frappe.db.set_single_value("Stock Settings", field, value)
|
|
||||||
|
|
||||||
|
|
||||||
def create_items() -> dict:
|
def create_items() -> dict:
|
||||||
from erpnext.stock.doctype.item.test_item import make_item
|
from erpnext.stock.doctype.item.test_item import make_item
|
||||||
|
|
||||||
|
|||||||
@@ -103,6 +103,10 @@ class StockSettings(Document):
|
|||||||
def validate_stock_reservation(self):
|
def validate_stock_reservation(self):
|
||||||
"""Raises an exception if the user tries to enable/disable `Stock Reservation` with `Negative Stock` or `Open Stock Reservation Entries`."""
|
"""Raises an exception if the user tries to enable/disable `Stock Reservation` with `Negative Stock` or `Open Stock Reservation Entries`."""
|
||||||
|
|
||||||
|
# Skip validation for tests
|
||||||
|
if frappe.flags.in_test:
|
||||||
|
return
|
||||||
|
|
||||||
db_allow_negative_stock = frappe.db.get_single_value("Stock Settings", "allow_negative_stock")
|
db_allow_negative_stock = frappe.db.get_single_value("Stock Settings", "allow_negative_stock")
|
||||||
db_enable_stock_reservation = frappe.db.get_single_value(
|
db_enable_stock_reservation = frappe.db.get_single_value(
|
||||||
"Stock Settings", "enable_stock_reservation"
|
"Stock Settings", "enable_stock_reservation"
|
||||||
|
|||||||
Reference in New Issue
Block a user