fix: replacing serial and batch bundle on pos with auto fetch serial nos (#46236)
* fix: replacing serial and batch bundle on pos with auto fetch serial nos
* fix: reserved serial no
added a check to look for serial no in reserved serial nos list before removing it as there might be a situation where an item is returned which was already consolidated.
(cherry picked from commit 35512d40bb)
Co-authored-by: Diptanil Saha <diptanil@frappe.io>
This commit is contained in:
@@ -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(
|
||||
`<div class="btn btn-sm btn-secondary auto-fetch-btn" style="margin-top: 6px">${__(
|
||||
"Select Serial No / Batch No"
|
||||
)}</div>`
|
||||
);
|
||||
} 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(
|
||||
`<div class="btn btn-sm btn-secondary auto-fetch-btn" style="margin-top: 6px">${label}</div>`
|
||||
);
|
||||
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(`<div class="grid-filler no-select"></div>`);
|
||||
}
|
||||
const label = __("Auto Fetch Serial Numbers");
|
||||
this.$form_container.append(
|
||||
`<div class="btn btn-sm btn-secondary auto-fetch-btn">${label}</div>`
|
||||
);
|
||||
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);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user