Merge pull request #31271 from dj12djdjs/fix-reserve-qty
fix(stock): don't reserve qty on sales return.
This commit is contained in:
commit
12325cb685
@ -29,6 +29,7 @@
|
|||||||
"allow_multiple_items",
|
"allow_multiple_items",
|
||||||
"allow_against_multiple_purchase_orders",
|
"allow_against_multiple_purchase_orders",
|
||||||
"allow_sales_order_creation_for_expired_quotation",
|
"allow_sales_order_creation_for_expired_quotation",
|
||||||
|
"dont_reserve_sales_order_qty_on_sales_return",
|
||||||
"hide_tax_id",
|
"hide_tax_id",
|
||||||
"enable_discount_accounting"
|
"enable_discount_accounting"
|
||||||
],
|
],
|
||||||
@ -186,6 +187,12 @@
|
|||||||
"fieldname": "over_order_allowance",
|
"fieldname": "over_order_allowance",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"label": "Over Order Allowance (%)"
|
"label": "Over Order Allowance (%)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"fieldname": "dont_reserve_sales_order_qty_on_sales_return",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Don't Reserve Sales Order Qty on Sales Return"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-cog",
|
"icon": "fa fa-cog",
|
||||||
@ -193,7 +200,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-03-03 11:16:54.333615",
|
"modified": "2023-02-04 12:37:53.380857",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Selling",
|
"module": "Selling",
|
||||||
"name": "Selling Settings",
|
"name": "Selling Settings",
|
||||||
@ -222,4 +229,4 @@
|
|||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"states": [],
|
"states": [],
|
||||||
"track_changes": 1
|
"track_changes": 1
|
||||||
}
|
}
|
||||||
|
@ -1180,6 +1180,53 @@ class TestDeliveryNote(FrappeTestCase):
|
|||||||
|
|
||||||
self.assertTrue(return_dn.docstatus == 1)
|
self.assertTrue(return_dn.docstatus == 1)
|
||||||
|
|
||||||
|
def test_reserve_qty_on_sales_return(self):
|
||||||
|
frappe.db.set_single_value("Selling Settings", "dont_reserve_sales_order_qty_on_sales_return", 0)
|
||||||
|
self.reserved_qty_check()
|
||||||
|
|
||||||
|
def test_dont_reserve_qty_on_sales_return(self):
|
||||||
|
frappe.db.set_single_value("Selling Settings", "dont_reserve_sales_order_qty_on_sales_return", 1)
|
||||||
|
self.reserved_qty_check()
|
||||||
|
|
||||||
|
def reserved_qty_check(self):
|
||||||
|
from erpnext.controllers.sales_and_purchase_return import make_return_doc
|
||||||
|
from erpnext.selling.doctype.sales_order.sales_order import make_delivery_note
|
||||||
|
from erpnext.stock.stock_balance import get_reserved_qty
|
||||||
|
|
||||||
|
dont_reserve_qty = frappe.db.get_single_value(
|
||||||
|
"Selling Settings", "dont_reserve_sales_order_qty_on_sales_return"
|
||||||
|
)
|
||||||
|
|
||||||
|
item = make_item().name
|
||||||
|
warehouse = "_Test Warehouse - _TC"
|
||||||
|
qty_to_reserve = 5
|
||||||
|
|
||||||
|
so = make_sales_order(item_code=item, qty=qty_to_reserve)
|
||||||
|
|
||||||
|
# Make qty avl for test.
|
||||||
|
make_stock_entry(item_code=item, to_warehouse=warehouse, qty=10, basic_rate=100)
|
||||||
|
|
||||||
|
# Test that item qty has been reserved on submit of sales order.
|
||||||
|
self.assertEqual(get_reserved_qty(item, warehouse), qty_to_reserve)
|
||||||
|
|
||||||
|
dn = make_delivery_note(so.name)
|
||||||
|
dn.save().submit()
|
||||||
|
|
||||||
|
# Test that item qty is no longer reserved since qty has been delivered.
|
||||||
|
self.assertEqual(get_reserved_qty(item, warehouse), 0)
|
||||||
|
|
||||||
|
dn_return = make_return_doc("Delivery Note", dn.name)
|
||||||
|
dn_return.save().submit()
|
||||||
|
|
||||||
|
returned = frappe.get_doc("Delivery Note", dn_return.name)
|
||||||
|
returned.update_prevdoc_status()
|
||||||
|
|
||||||
|
# Test that item qty is not reserved on sales return, if selling setting don't reserve qty is checked.
|
||||||
|
self.assertEqual(get_reserved_qty(item, warehouse), 0 if dont_reserve_qty else qty_to_reserve)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
frappe.db.set_single_value("Selling Settings", "dont_reserve_sales_order_qty_on_sales_return", 0)
|
||||||
|
|
||||||
|
|
||||||
def create_delivery_note(**args):
|
def create_delivery_note(**args):
|
||||||
dn = frappe.new_doc("Delivery Note")
|
dn = frappe.new_doc("Delivery Note")
|
||||||
|
@ -94,10 +94,13 @@ def get_balance_qty_from_sle(item_code, warehouse):
|
|||||||
|
|
||||||
|
|
||||||
def get_reserved_qty(item_code, warehouse):
|
def get_reserved_qty(item_code, warehouse):
|
||||||
|
dont_reserve_on_return = frappe.get_cached_value(
|
||||||
|
"Selling Settings", "Selling Settings", "dont_reserve_sales_order_qty_on_sales_return"
|
||||||
|
)
|
||||||
reserved_qty = frappe.db.sql(
|
reserved_qty = frappe.db.sql(
|
||||||
"""
|
f"""
|
||||||
select
|
select
|
||||||
sum(dnpi_qty * ((so_item_qty - so_item_delivered_qty) / so_item_qty))
|
sum(dnpi_qty * ((so_item_qty - so_item_delivered_qty - if(dont_reserve_qty_on_return, so_item_returned_qty, 0)) / so_item_qty))
|
||||||
from
|
from
|
||||||
(
|
(
|
||||||
(select
|
(select
|
||||||
@ -112,6 +115,12 @@ def get_reserved_qty(item_code, warehouse):
|
|||||||
where name = dnpi.parent_detail_docname
|
where name = dnpi.parent_detail_docname
|
||||||
and delivered_by_supplier = 0
|
and delivered_by_supplier = 0
|
||||||
) as so_item_delivered_qty,
|
) as so_item_delivered_qty,
|
||||||
|
(
|
||||||
|
select returned_qty from `tabSales Order Item`
|
||||||
|
where name = dnpi.parent_detail_docname
|
||||||
|
and delivered_by_supplier = 0
|
||||||
|
) as so_item_returned_qty,
|
||||||
|
{dont_reserve_on_return} as dont_reserve_qty_on_return,
|
||||||
parent, name
|
parent, name
|
||||||
from
|
from
|
||||||
(
|
(
|
||||||
@ -125,7 +134,9 @@ def get_reserved_qty(item_code, warehouse):
|
|||||||
) dnpi)
|
) dnpi)
|
||||||
union
|
union
|
||||||
(select stock_qty as dnpi_qty, qty as so_item_qty,
|
(select stock_qty as dnpi_qty, qty as so_item_qty,
|
||||||
delivered_qty as so_item_delivered_qty, parent, name
|
delivered_qty as so_item_delivered_qty,
|
||||||
|
returned_qty as so_item_returned_qty,
|
||||||
|
{dont_reserve_on_return}, parent, name
|
||||||
from `tabSales Order Item` so_item
|
from `tabSales Order Item` so_item
|
||||||
where item_code = %s and warehouse = %s
|
where item_code = %s and warehouse = %s
|
||||||
and (so_item.delivered_by_supplier is null or so_item.delivered_by_supplier = 0)
|
and (so_item.delivered_by_supplier is null or so_item.delivered_by_supplier = 0)
|
||||||
|
Loading…
Reference in New Issue
Block a user