From ee0635246fe8f9014e1d6330c652b4e074a7ed2d Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 19 Jun 2026 21:50:13 +0530 Subject: [PATCH] refactor(sales_order): simplify create_stock_reservation_entries The method (cyclomatic complexity C/14) mixed packed-item separation, SRE creation and packed-item reservation. Extract _extract_packed_item_details, _packed_items_to_reserve and _reserve_packed_items (verbatim moves). Drops C/14 -> A/3; no C-rank function remains in the module. No behaviour change (stock-reservation, product-bundle and pick-list reservation suites green). --- .../sales_order/services/reservation.py | 55 +++++++++++-------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/erpnext/selling/doctype/sales_order/services/reservation.py b/erpnext/selling/doctype/sales_order/services/reservation.py index b647cdcb82c..238f68af879 100644 --- a/erpnext/selling/doctype/sales_order/services/reservation.py +++ b/erpnext/selling/doctype/sales_order/services/reservation.py @@ -85,15 +85,7 @@ class SalesOrderStockReservation: create_stock_reservation_entries_for_so_items as create_stock_reservation_entries, ) - packed_items = [] - if items_details: - for item in items_details: - if not frappe.db.exists("Sales Order Item", item.get("sales_order_item")): - item["qty"] = item.pop("qty_to_reserve") - packed_items.append(item) - - for item in packed_items: - items_details.remove(item) + packed_items = self._extract_packed_item_details(items_details) sre_count = 0 if items_details != []: @@ -104,22 +96,41 @@ class SalesOrderStockReservation: notify=notify, ) - items = [] - if packed_items: - items = packed_items - elif not items_details: - items = [item for item in self.doc.packed_items if item.reserve_stock] - + items = self._packed_items_to_reserve(items_details, packed_items) if items: - from erpnext.stock.doctype.stock_reservation_entry.stock_reservation_entry import StockReservation + self._reserve_packed_items(items, sre_count, notify) - stock_reservation = StockReservation(doc=self.doc, items=items) - stock_reservation.table_name = "packed_items" - stock_reservation.qty_field = "qty" - is_sre_created = stock_reservation.make_stock_reservation_entries() + def _extract_packed_item_details(self, items_details: list[dict] | None) -> list: + """Pull packed-item rows (whose Sales Order Item no longer exists) out of items_details.""" + packed_items = [] + if items_details: + for item in items_details: + if not frappe.db.exists("Sales Order Item", item.get("sales_order_item")): + item["qty"] = item.pop("qty_to_reserve") + packed_items.append(item) - if notify and is_sre_created and not sre_count: - frappe.msgprint(_("Stock Reservation Entries Created"), alert=True, indicator="green") + for item in packed_items: + items_details.remove(item) + + return packed_items + + def _packed_items_to_reserve(self, items_details: list[dict] | None, packed_items: list) -> list: + if packed_items: + return packed_items + if not items_details: + return [item for item in self.doc.packed_items if item.reserve_stock] + return [] + + def _reserve_packed_items(self, items: list, sre_count: int, notify: bool) -> None: + from erpnext.stock.doctype.stock_reservation_entry.stock_reservation_entry import StockReservation + + stock_reservation = StockReservation(doc=self.doc, items=items) + stock_reservation.table_name = "packed_items" + stock_reservation.qty_field = "qty" + is_sre_created = stock_reservation.make_stock_reservation_entries() + + if notify and is_sre_created and not sre_count: + frappe.msgprint(_("Stock Reservation Entries Created"), alert=True, indicator="green") def cancel_stock_reservation_entries(self, sre_list: list | None = None, notify: bool = True) -> None: """Cancel Stock Reservation Entries for Sales Order Items."""