fix: auto create serial no on scan

This commit is contained in:
Rohit Waghchaure 2024-01-22 12:50:24 +05:30
parent 5d94f0bde5
commit fc0d2aeeff
4 changed files with 120 additions and 47 deletions

View File

@ -105,11 +105,27 @@ erpnext.utils.BarcodeScanner = class BarcodeScanner {
this.frm.has_items = false; this.frm.has_items = false;
} }
if (serial_no && this.is_duplicate_serial_no(row, item_code, serial_no)) { 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(); this.clean_up();
reject(); reject();
return; return;
} }
});
} else {
this.run_serially_tasks(row, data, resolve);
}
});
}
run_serially_tasks(row, data, resolve) {
const {item_code, barcode, batch_no, serial_no, uom} = data;
frappe.run_serially([ frappe.run_serially([
() => this.set_serial_and_batch(row, item_code, serial_no, batch_no), () => this.set_serial_and_batch(row, item_code, serial_no, batch_no),
@ -119,16 +135,15 @@ erpnext.utils.BarcodeScanner = class BarcodeScanner {
}), }),
() => this.set_barcode_uom(row, uom), () => this.set_barcode_uom(row, uom),
() => this.clean_up(), () => this.clean_up(),
() => resolve(row),
() => { () => {
if (row.serial_and_batch_bundle && !this.frm.is_new()) { if (row.serial_and_batch_bundle && !this.frm.is_new()) {
this.frm.save(); this.frm.save();
} }
frappe.flags.trigger_from_barcode_scanner = false; frappe.flags.trigger_from_barcode_scanner = false;
} },
() => resolve(row),
]); ]);
});
} }
set_item(row, item_code, barcode, batch_no, serial_no) { set_item(row, item_code, barcode, batch_no, serial_no) {
@ -475,26 +490,32 @@ erpnext.utils.BarcodeScanner = class BarcodeScanner {
} }
} }
is_duplicate_serial_no(row, item_code, serial_no) { 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) { if (this.frm.is_new() || !row.serial_and_batch_bundle) {
let is_duplicate = this.check_duplicate_serial_no_in_localstorage(item_code, serial_no); is_duplicate = this.check_duplicate_serial_no_in_localstorage(item_code, serial_no);
if (is_duplicate) { if (is_duplicate) {
this.show_alert(__("Serial No {0} is already added", [serial_no]), "orange"); this.show_alert(__("Serial No {0} is already added", [serial_no]), "orange");
} }
return is_duplicate; resolve(is_duplicate);
} else if (row.serial_and_batch_bundle) { } else if (row.serial_and_batch_bundle) {
this.check_duplicate_serial_no_in_db(row, serial_no, (r) => { this.check_duplicate_serial_no_in_db(row, serial_no, (r) => {
if (r.message) { if (r.message) {
this.show_alert(__("Serial No {0} is already added", [serial_no]), "orange"); this.show_alert(__("Serial No {0} is already added", [serial_no]), "orange");
} }
return r.message; 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({ frappe.call({
method: "erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle.is_duplicate_serial_no", method: "erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle.is_duplicate_serial_no",
args: { args: {
@ -504,7 +525,7 @@ erpnext.utils.BarcodeScanner = class BarcodeScanner {
callback(r) { callback(r) {
response(r); response(r);
} }
}) });
} }
check_duplicate_serial_no_in_localstorage(item_code, serial_no) { 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() 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', options: 'Barcode',
fieldname: 'scan_batch_no', fieldname: 'scan_batch_no',
label: __('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, fields = [...fields,
{ {
fieldtype: 'Check', fieldtype: 'Check',
label: __('Upload Using CSV file'), label: __('Import Using CSV file'),
fieldname: 'upload_using_csv', fieldname: 'import_using_csv_file',
default: 0, default: 0,
}, },
{ {
fieldtype: 'Section Break', 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', fieldtype: 'Small Text',
label: __('Serial Nos'), label: __('Enter Serial Nos'),
fieldname: 'upload_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', fieldtype: 'Column Break',
depends_on: 'eval:doc.upload_using_csv === 0', depends_on: 'eval:doc.import_using_csv_file === 0',
}, },
{ {
fieldtype: 'Button', fieldtype: 'Button',
fieldname: 'make_serial_nos', fieldname: 'make_serial_nos',
label: __('Create Serial Nos'), label: __('Create Serial Nos'),
depends_on: 'eval:doc.upload_using_csv === 0', depends_on: 'eval:doc.import_using_csv_file === 0',
click: () => { click: () => {
this.create_serial_nos(); this.create_serial_nos();
} }
}, },
{ {
fieldtype: 'Section Break', 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) { if (r.message) {
this.dialog.fields_dict.entries.df.data = []; this.dialog.fields_dict.entries.df.data = [];
this.set_data(r.message); 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() { update_serial_batch_no() {
const { scan_serial_no, scan_batch_no } = this.dialog.get_values(); 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 = [ let fields = [
{ {
"label": __("Using CSV File"), "label": __("Import Using CSV file"),
"fieldname": "using_csv_file", "fieldname": "using_csv_file",
"default": 1, "default": 1,
"fieldtype": "Check", "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") 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() @frappe.whitelist()
def is_duplicate_serial_no(bundle_id, serial_no): def is_duplicate_serial_no(bundle_id, serial_no):
return frappe.db.exists("Serial and Batch Entry", {"parent": bundle_id, "serial_no": serial_no}) return frappe.db.exists("Serial and Batch Entry", {"parent": bundle_id, "serial_no": serial_no})