fix: auto create serial no on scan

(cherry picked from commit fc0d2aeeffed9a2f87be0d87f0a0af0e837c5955)
This commit is contained in:
Rohit Waghchaure 2024-01-22 12:50:24 +05:30 committed by Mergify
parent c76145985d
commit ca93f671df
4 changed files with 120 additions and 47 deletions

View File

@ -105,32 +105,47 @@ erpnext.utils.BarcodeScanner = class BarcodeScanner {
this.frm.has_items = false;
}
if (serial_no && this.is_duplicate_serial_no(row, item_code, serial_no)) {
this.clean_up();
reject();
return;
if (serial_no) {
this.is_duplicate_serial_no(row, item_code, serial_no)
.then((is_duplicate) => {
if (!is_duplicate) {
this.run_serially_tasks(row, data, resolve);
} else {
this.clean_up();
reject();
return;
}
});
} else {
this.run_serially_tasks(row, data, resolve);
}
frappe.run_serially([
() => this.set_serial_and_batch(row, item_code, serial_no, batch_no),
() => this.set_barcode(row, barcode),
() => this.set_item(row, item_code, barcode, batch_no, serial_no).then(qty => {
this.show_scan_message(row.idx, row.item_code, qty);
}),
() => this.set_barcode_uom(row, uom),
() => this.clean_up(),
() => resolve(row),
() => {
if (row.serial_and_batch_bundle && !this.frm.is_new()) {
this.frm.save();
}
frappe.flags.trigger_from_barcode_scanner = false;
}
]);
});
}
run_serially_tasks(row, data, resolve) {
const {item_code, barcode, batch_no, serial_no, uom} = data;
frappe.run_serially([
() => this.set_serial_and_batch(row, item_code, serial_no, batch_no),
() => this.set_barcode(row, barcode),
() => this.set_item(row, item_code, barcode, batch_no, serial_no).then(qty => {
this.show_scan_message(row.idx, row.item_code, qty);
}),
() => this.set_barcode_uom(row, uom),
() => this.clean_up(),
() => {
if (row.serial_and_batch_bundle && !this.frm.is_new()) {
this.frm.save();
}
frappe.flags.trigger_from_barcode_scanner = false;
},
() => resolve(row),
]);
}
set_item(row, item_code, barcode, batch_no, serial_no) {
return new Promise(resolve => {
const increment = async (value = 1) => {
@ -475,26 +490,32 @@ erpnext.utils.BarcodeScanner = class BarcodeScanner {
}
}
is_duplicate_serial_no(row, item_code, serial_no) {
if (this.frm.is_new() || !row.serial_and_batch_bundle) {
let is_duplicate = this.check_duplicate_serial_no_in_localstorage(item_code, serial_no);
if (is_duplicate) {
this.show_alert(__("Serial No {0} is already added", [serial_no]), "orange");
}
return is_duplicate;
} else if (row.serial_and_batch_bundle) {
this.check_duplicate_serial_no_in_db(row, serial_no, (r) => {
if (r.message) {
async is_duplicate_serial_no(row, item_code, serial_no) {
let is_duplicate = false;
const promise = new Promise((resolve, reject) => {
if (this.frm.is_new() || !row.serial_and_batch_bundle) {
is_duplicate = this.check_duplicate_serial_no_in_localstorage(item_code, serial_no);
if (is_duplicate) {
this.show_alert(__("Serial No {0} is already added", [serial_no]), "orange");
}
return r.message;
})
}
resolve(is_duplicate);
} else if (row.serial_and_batch_bundle) {
this.check_duplicate_serial_no_in_db(row, serial_no, (r) => {
if (r.message) {
this.show_alert(__("Serial No {0} is already added", [serial_no]), "orange");
}
is_duplicate = r.message;
resolve(is_duplicate);
})
}
});
return await promise;
}
async check_duplicate_serial_no_in_db(row, serial_no, response) {
check_duplicate_serial_no_in_db(row, serial_no, response) {
frappe.call({
method: "erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle.is_duplicate_serial_no",
args: {
@ -504,7 +525,7 @@ erpnext.utils.BarcodeScanner = class BarcodeScanner {
callback(r) {
response(r);
}
})
});
}
check_duplicate_serial_no_in_localstorage(item_code, serial_no) {

View File

@ -135,7 +135,7 @@ erpnext.SerialBatchPackageSelector = class SerialNoBatchBundleUpdate {
filters: this.get_serial_no_filters()
};
},
onchange: () => this.update_serial_batch_no()
onchange: () => this.scan_barcode_data()
});
}
@ -145,7 +145,7 @@ erpnext.SerialBatchPackageSelector = class SerialNoBatchBundleUpdate {
options: 'Barcode',
fieldname: 'scan_batch_no',
label: __('Scan Batch No'),
onchange: () => this.update_serial_batch_no()
onchange: () => this.scan_barcode_data()
});
}
@ -190,36 +190,38 @@ erpnext.SerialBatchPackageSelector = class SerialNoBatchBundleUpdate {
fields = [...fields,
{
fieldtype: 'Check',
label: __('Upload Using CSV file'),
fieldname: 'upload_using_csv',
label: __('Import Using CSV file'),
fieldname: 'import_using_csv_file',
default: 0,
},
{
fieldtype: 'Section Break',
depends_on: 'eval:doc.upload_using_csv === 0',
label: __('{0} {1} Manually', [primary_label, label]),
depends_on: 'eval:doc.import_using_csv_file === 0',
},
{
fieldtype: 'Small Text',
label: __('Serial Nos'),
label: __('Enter Serial Nos'),
fieldname: 'upload_serial_nos',
depends_on: 'eval:doc.upload_using_csv === 0',
depends_on: 'eval:doc.import_using_csv_file === 0',
description: __('Enter each serial no in a new line'),
},
{
fieldtype: 'Column Break',
depends_on: 'eval:doc.upload_using_csv === 0',
depends_on: 'eval:doc.import_using_csv_file === 0',
},
{
fieldtype: 'Button',
fieldname: 'make_serial_nos',
label: __('Create Serial Nos'),
depends_on: 'eval:doc.upload_using_csv === 0',
depends_on: 'eval:doc.import_using_csv_file === 0',
click: () => {
this.create_serial_nos();
}
},
{
fieldtype: 'Section Break',
depends_on: 'eval:doc.upload_using_csv === 1',
depends_on: 'eval:doc.import_using_csv_file === 1',
}
];
}
@ -262,6 +264,7 @@ erpnext.SerialBatchPackageSelector = class SerialNoBatchBundleUpdate {
if (r.message) {
this.dialog.fields_dict.entries.df.data = [];
this.set_data(r.message);
this.update_bundle_entries();
}
}
});
@ -439,6 +442,26 @@ erpnext.SerialBatchPackageSelector = class SerialNoBatchBundleUpdate {
}
}
scan_barcode_data() {
const { scan_serial_no, scan_batch_no } = this.dialog.get_values();
if (scan_serial_no || scan_batch_no) {
frappe.call({
method: 'erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle.is_serial_batch_no_exists',
args: {
item_code: this.item.item_code,
type_of_transaction: this.item.type_of_transaction,
serial_no: scan_serial_no,
batch_no: scan_batch_no,
},
callback: (r) => {
this.update_serial_batch_no();
}
})
}
}
update_serial_batch_no() {
const { scan_serial_no, scan_batch_no } = this.dialog.get_values();

View File

@ -74,7 +74,7 @@ frappe.ui.form.on('Serial and Batch Bundle', {
let fields = [
{
"label": __("Using CSV File"),
"label": __("Import Using CSV file"),
"fieldname": "using_csv_file",
"default": 1,
"fieldtype": "Check",

View File

@ -2095,6 +2095,35 @@ def get_batch_no_from_serial_no(serial_no):
return frappe.get_cached_value("Serial No", serial_no, "batch_no")
@frappe.whitelist()
def is_serial_batch_no_exists(item_code, type_of_transaction, serial_no=None, batch_no=None):
if serial_no and not frappe.db.exists("Serial No", serial_no):
if type_of_transaction != "Inward":
frappe.throw(_("Serial No {0} does not exists").format(serial_no))
make_serial_no(serial_no, item_code)
if batch_no and frappe.db.exists("Batch", batch_no):
if type_of_transaction != "Inward":
frappe.throw(_("Batch No {0} does not exists").format(batch_no))
make_batch_no(batch_no, item_code)
def make_serial_no(serial_no, item_code):
serial_no_doc = frappe.new_doc("Serial No")
serial_no_doc.serial_no = serial_no
serial_no_doc.item_code = item_code
serial_no_doc.save(ignore_permissions=True)
def make_batch_no(batch_no, item_code):
batch_doc = frappe.new_doc("Batch")
batch_doc.batch_id = batch_no
batch_doc.item = item_code
batch_doc.save(ignore_permissions=True)
@frappe.whitelist()
def is_duplicate_serial_no(bundle_id, serial_no):
return frappe.db.exists("Serial and Batch Entry", {"parent": bundle_id, "serial_no": serial_no})