Merge pull request #49690 from frappe/mergify/bp/version-15-hotfix/pr-49684

feat: populate available qty in pick list locations (backport #49684)
This commit is contained in:
rohitwaghchaure
2025-09-23 12:07:00 +05:30
committed by GitHub
5 changed files with 74 additions and 6 deletions

View File

@@ -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:

View File

@@ -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) => {
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) => {
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,
});
}
}

View File

@@ -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:

View File

@@ -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",
@@ -124,7 +128,7 @@
"fieldname": "stock_qty",
"fieldtype": "Float",
"in_list_view": 1,
"label": "Stock Qty",
"label": "Qty (in Stock UOM)",
"read_only": 1
},
{
@@ -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-05-31 19:57:43.531298",
"modified": "2025-09-23 00:02:57.817040",
"modified_by": "Administrator",
"module": "Stock",
"name": "Pick List Item",

View File

@@ -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