diff --git a/erpnext/selling/page/point_of_sale/pos_item_details.js b/erpnext/selling/page/point_of_sale/pos_item_details.js index e0abdd4f4c3..a0476ee6bda 100644 --- a/erpnext/selling/page/point_of_sale/pos_item_details.js +++ b/erpnext/selling/page/point_of_sale/pos_item_details.js @@ -216,22 +216,16 @@ erpnext.PointOfSale.ItemDetails = class { } make_auto_serial_selection_btn(item) { - if (item.has_serial_no || item.has_batch_no) { - if (item.has_serial_no && item.has_batch_no) { - this.$form_container.append( - `
${__( - "Select Serial No / Batch No" - )}
` - ); - } else { - const classname = item.has_serial_no ? ".serial_no-control" : ".batch_no-control"; - const label = item.has_serial_no ? __("Select Serial No") : __("Select Batch No"); - this.$form_container - .find(classname) - .append( - `
${label}
` - ); + const doc = this.events.get_frm().doc; + if (!doc.is_return && (item.has_serial_no || item.serial_no)) { + if (!item.has_batch_no) { + this.$form_container.append(`
`); } + const label = __("Auto Fetch Serial Numbers"); + this.$form_container.append( + `
${label}
` + ); + this.$form_container.find(".serial_no-control").find("textarea").css("height", "6rem"); } } @@ -416,18 +410,41 @@ erpnext.PointOfSale.ItemDetails = class { bind_auto_serial_fetch_event() { this.$form_container.on("click", ".auto-fetch-btn", () => { - let frm = this.events.get_frm(); - let item_row = this.item_row; - item_row.type_of_transaction = "Outward"; + this.batch_no_control && this.batch_no_control.set_value(""); + let qty = this.qty_control.get_value(); + let conversion_factor = this.conversion_factor_control.get_value(); + let expiry_date = this.item_row.has_batch_no ? this.events.get_frm().doc.posting_date : ""; - new erpnext.SerialBatchPackageSelector(frm, item_row, (r) => { - if (r) { - frappe.model.set_value(item_row.doctype, item_row.name, { - serial_and_batch_bundle: r.name, - qty: Math.abs(r.total_qty), - use_serial_batch_fields: 0, - }); + let numbers = frappe.call({ + method: "erpnext.stock.doctype.serial_no.serial_no.auto_fetch_serial_number", + args: { + qty: qty * conversion_factor, + item_code: this.current_item.item_code, + warehouse: this.warehouse_control.get_value() || "", + batch_nos: this.current_item.batch_no || "", + posting_date: expiry_date, + for_doctype: "POS Invoice", + }, + }); + + numbers.then((data) => { + let auto_fetched_serial_numbers = data.message; + let records_length = auto_fetched_serial_numbers.length; + if (!records_length) { + const warehouse = this.warehouse_control.get_value().bold(); + const item_code = this.current_item.item_code.bold(); + frappe.msgprint( + __( + "Serial numbers unavailable for Item {0} under warehouse {1}. Please try changing warehouse.", + [item_code, warehouse] + ) + ); + } else if (records_length < qty) { + frappe.msgprint(__("Fetched only {0} available serial numbers.", [records_length])); + this.qty_control.set_value(records_length); } + numbers = auto_fetched_serial_numbers.join(`\n`); + this.serial_no_control.set_value(numbers); }); }); } diff --git a/erpnext/stock/doctype/serial_no/serial_no.py b/erpnext/stock/doctype/serial_no/serial_no.py index 274ce0f0d9d..1560db6a114 100644 --- a/erpnext/stock/doctype/serial_no/serial_no.py +++ b/erpnext/stock/doctype/serial_no/serial_no.py @@ -230,15 +230,17 @@ def get_pos_reserved_serial_nos(filters): pos_transacted_sr_nos = query.run(as_dict=True) - reserved_sr_nos = set() - returned_sr_nos = set() + reserved_sr_nos = list() + returned_sr_nos = list() for d in pos_transacted_sr_nos: if d.is_return == 0: - [reserved_sr_nos.add(x) for x in get_serial_nos(d.serial_no)] + [reserved_sr_nos.append(x) for x in get_serial_nos(d.serial_no)] elif d.is_return == 1: - [returned_sr_nos.add(x) for x in get_serial_nos(d.serial_no)] + [returned_sr_nos.append(x) for x in get_serial_nos(d.serial_no)] - reserved_sr_nos = list(reserved_sr_nos - returned_sr_nos) + for x in returned_sr_nos: + if x in reserved_sr_nos: + reserved_sr_nos.remove(x) return reserved_sr_nos @@ -254,12 +256,7 @@ def fetch_serial_numbers(filters, qty, do_not_include=None): query = ( frappe.qb.from_(serial_no) .select(serial_no.name) - .where( - (serial_no.item_code == filters["item_code"]) - & (serial_no.warehouse == filters["warehouse"]) - & (Coalesce(serial_no.sales_invoice, "") == "") - & (Coalesce(serial_no.delivery_document_no, "") == "") - ) + .where((serial_no.item_code == filters["item_code"]) & (serial_no.warehouse == filters["warehouse"])) .orderby(serial_no.creation) .limit(qty or 1) )