From 056d51937bc376b040370d7e8714947409827e39 Mon Sep 17 00:00:00 2001 From: Kavin <78342682+kavin0411@users.noreply.github.com> Date: Sat, 20 Sep 2025 17:29:35 +0530 Subject: [PATCH 1/3] chore: rename stock qty label (cherry picked from commit fc967fceb2b2c6b251aae71aae2731b8e1668d08) --- erpnext/stock/doctype/pick_list_item/pick_list_item.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/stock/doctype/pick_list_item/pick_list_item.json b/erpnext/stock/doctype/pick_list_item/pick_list_item.json index e7af1c6a005..5101369263c 100644 --- a/erpnext/stock/doctype/pick_list_item/pick_list_item.json +++ b/erpnext/stock/doctype/pick_list_item/pick_list_item.json @@ -124,7 +124,7 @@ "fieldname": "stock_qty", "fieldtype": "Float", "in_list_view": 1, - "label": "Stock Qty", + "label": "Qty (in Stock UOM)", "read_only": 1 }, { @@ -252,7 +252,7 @@ ], "istable": 1, "links": [], - "modified": "2025-05-31 19:57:43.531298", + "modified": "2025-09-20 17:25:01.139613", "modified_by": "Administrator", "module": "Stock", "name": "Pick List Item", From bc7f884ae12dccd443ff9a409708f7c95dae4b98 Mon Sep 17 00:00:00 2001 From: Kavin <78342682+kavin0411@users.noreply.github.com> Date: Tue, 23 Sep 2025 08:39:39 +0530 Subject: [PATCH 2/3] feat: populate available qty in pick list locations (cherry picked from commit d8756fc7de20145fdac0f7f977cddfd694fbf415) --- .../doctype/sales_order/sales_order.py | 5 +++ erpnext/stock/doctype/pick_list/pick_list.js | 17 ++++++++-- erpnext/stock/doctype/pick_list/pick_list.py | 21 ++++++++++-- .../pick_list_item/pick_list_item.json | 33 ++++++++++++++++++- .../doctype/pick_list_item/pick_list_item.py | 2 ++ 5 files changed, 73 insertions(+), 5 deletions(-) diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index 0118e89cd3c..eb6134d4259 100755 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -1762,6 +1762,11 @@ def create_pick_list(source_name, target_doc=None): target.qty = qty_to_be_picked target.stock_qty = qty_to_be_picked * flt(source.conversion_factor) + # update available qty + bin_details = get_bin_details(source.item_code, source.warehouse, source_parent.company) + target.actual_qty = bin_details.get("actual_qty") + target.company_total_stock = bin_details.get("company_total_stock") + def update_packed_item_qty(source, target, source_parent) -> None: qty = flt(source.qty) for item in source_parent.items: diff --git a/erpnext/stock/doctype/pick_list/pick_list.js b/erpnext/stock/doctype/pick_list/pick_list.js index d021973a01f..e426cb73730 100644 --- a/erpnext/stock/doctype/pick_list/pick_list.js +++ b/erpnext/stock/doctype/pick_list/pick_list.js @@ -354,10 +354,12 @@ frappe.ui.form.on("Pick List Item", { item_code: (frm, cdt, cdn) => { let row = frappe.get_doc(cdt, cdn); if (row.item_code) { - get_item_details(row.item_code).then((data) => { + get_item_details(row.item_code, row.uom, row.warehouse, frm.doc.company).then((data) => { frappe.model.set_value(cdt, cdn, "uom", data.stock_uom); frappe.model.set_value(cdt, cdn, "stock_uom", data.stock_uom); frappe.model.set_value(cdt, cdn, "conversion_factor", 1); + frappe.model.set_value(cdt, cdn, "actual_qty", data.actual_qty); + frappe.model.set_value(cdt, cdn, "company_total_stock", data.company_total_stock); }); } }, @@ -371,6 +373,15 @@ frappe.ui.form.on("Pick List Item", { } }, + warehouse: (frm, cdt, cdn) => { + let row = frappe.get_doc(cdt, cdn); + if (row.warehouse) { + get_item_details(row.item_code, row.warehouse).then((data) => { + frappe.model.set_value(cdt, cdn, "actual_qty", data.actual_qty); + }); + } + }, + qty: (frm, cdt, cdn) => { let row = frappe.get_doc(cdt, cdn); frappe.model.set_value(cdt, cdn, "stock_qty", row.qty * row.conversion_factor); @@ -412,11 +423,13 @@ frappe.ui.form.on("Pick List Item", { }, }); -function get_item_details(item_code, uom = null) { +function get_item_details(item_code, uom = null, warehouse = null, company = null) { if (item_code) { return frappe.xcall("erpnext.stock.doctype.pick_list.pick_list.get_item_details", { item_code, uom, + warehouse, + company, }); } } diff --git a/erpnext/stock/doctype/pick_list/pick_list.py b/erpnext/stock/doctype/pick_list/pick_list.py index 9417751f682..f49a4c955cc 100644 --- a/erpnext/stock/doctype/pick_list/pick_list.py +++ b/erpnext/stock/doctype/pick_list/pick_list.py @@ -21,7 +21,7 @@ from erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle impor get_auto_batch_nos, get_picked_serial_nos, ) -from erpnext.stock.get_item_details import get_conversion_factor +from erpnext.stock.get_item_details import get_company_total_stock, get_conversion_factor from erpnext.stock.serial_batch_bundle import ( SerialBatchCreation, get_batches_from_bundle, @@ -74,6 +74,9 @@ class PickList(TransactionBase): if self.has_reserved_stock(): self.set_onload("has_reserved_stock", True) + for item in self.get("locations"): + item.update(get_item_details(item.item_code, item.uom, item.warehouse, self.company)) + def validate(self): self.validate_expired_batches() self.validate_for_qty() @@ -1442,15 +1445,29 @@ def get_pending_work_orders(doctype, txt, searchfield, start, page_length, filte @frappe.whitelist() -def get_item_details(item_code, uom=None): +def get_item_details(item_code, uom=None, warehouse=None, company=None): details = frappe.db.get_value("Item", item_code, ["stock_uom", "name"], as_dict=1) details.uom = uom or details.stock_uom if uom: details.update(get_conversion_factor(item_code, uom)) + if warehouse: + details.actual_qty = flt(get_actual_qty(item_code, warehouse)) + + if company: + details.company_total_stock = get_company_total_stock(item_code, company) + return details +def get_actual_qty(item_code, warehouse): + return frappe.db.get_value( + "Bin", + {"item_code": item_code, "warehouse": warehouse}, + "actual_qty", + ) + + def update_delivery_note_item(source, target, delivery_note): cost_center = frappe.db.get_value("Project", delivery_note.project, "cost_center") if not cost_center: diff --git a/erpnext/stock/doctype/pick_list_item/pick_list_item.json b/erpnext/stock/doctype/pick_list_item/pick_list_item.json index 5101369263c..a33123e3e16 100644 --- a/erpnext/stock/doctype/pick_list_item/pick_list_item.json +++ b/erpnext/stock/doctype/pick_list_item/pick_list_item.json @@ -22,6 +22,10 @@ "conversion_factor", "stock_uom", "delivered_qty", + "available_quantity_section", + "actual_qty", + "column_break_kyek", + "company_total_stock", "serial_no_and_batch_section", "pick_serial_and_batch", "serial_and_batch_bundle", @@ -248,11 +252,38 @@ "print_hide": 1, "read_only": 1, "report_hide": 1 + }, + { + "fieldname": "available_quantity_section", + "fieldtype": "Section Break", + "label": "Available Qty" + }, + { + "allow_on_submit": 1, + "fieldname": "actual_qty", + "fieldtype": "Float", + "label": "Qty (Warehouse)", + "no_copy": 1, + "print_hide": 1, + "read_only": 1 + }, + { + "fieldname": "column_break_kyek", + "fieldtype": "Column Break" + }, + { + "allow_on_submit": 1, + "fieldname": "company_total_stock", + "fieldtype": "Float", + "label": "Qty (Company)", + "no_copy": 1, + "print_hide": 1, + "read_only": 1 } ], "istable": 1, "links": [], - "modified": "2025-09-20 17:25:01.139613", + "modified": "2025-09-23 00:02:57.817040", "modified_by": "Administrator", "module": "Stock", "name": "Pick List Item", diff --git a/erpnext/stock/doctype/pick_list_item/pick_list_item.py b/erpnext/stock/doctype/pick_list_item/pick_list_item.py index af23a424949..bdba97f4056 100644 --- a/erpnext/stock/doctype/pick_list_item/pick_list_item.py +++ b/erpnext/stock/doctype/pick_list_item/pick_list_item.py @@ -15,7 +15,9 @@ class PickListItem(Document): if TYPE_CHECKING: from frappe.types import DF + actual_qty: DF.Float batch_no: DF.Link | None + company_total_stock: DF.Float conversion_factor: DF.Float delivered_qty: DF.Float description: DF.Text | None From a463f4a41988f81fdf0bc7b6b6372d77877c5d95 Mon Sep 17 00:00:00 2001 From: Kavin <78342682+kavin-114@users.noreply.github.com> Date: Tue, 23 Sep 2025 10:56:14 +0530 Subject: [PATCH 3/3] refactor: fetching qty on warehouse trigger Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> (cherry picked from commit e3ab0e7c6760b9ca702526c2d360301569f4416c) --- erpnext/stock/doctype/pick_list/pick_list.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/erpnext/stock/doctype/pick_list/pick_list.js b/erpnext/stock/doctype/pick_list/pick_list.js index e426cb73730..9ea7f006df8 100644 --- a/erpnext/stock/doctype/pick_list/pick_list.js +++ b/erpnext/stock/doctype/pick_list/pick_list.js @@ -374,12 +374,12 @@ frappe.ui.form.on("Pick List Item", { }, warehouse: (frm, cdt, cdn) => { - let row = frappe.get_doc(cdt, cdn); - if (row.warehouse) { - get_item_details(row.item_code, row.warehouse).then((data) => { - frappe.model.set_value(cdt, cdn, "actual_qty", data.actual_qty); - }); - } + const row = frappe.get_doc(cdt, cdn); + if (!row.item_code || !row.warehouse) return; + get_item_details(row.item_code, row.uom, row.warehouse, frm.doc.company).then((data) => { + frappe.model.set_value(cdt, cdn, "actual_qty", data.actual_qty); + frappe.model.set_value(cdt, cdn, "company_total_stock", data.company_total_stock); + }); }, qty: (frm, cdt, cdn) => {