2023-03-21 05:24:41 +00:00
|
|
|
erpnext.SerialBatchPackageSelector = class SerialNoBatchBundleUpdate {
|
2022-10-10 07:58:19 +00:00
|
|
|
constructor(frm, item, callback) {
|
|
|
|
this.frm = frm;
|
|
|
|
this.item = item;
|
|
|
|
this.qty = item.qty;
|
|
|
|
this.callback = callback;
|
2023-03-13 09:21:43 +00:00
|
|
|
this.bundle = this.item?.is_rejected ?
|
|
|
|
this.item.rejected_serial_and_batch_bundle : this.item.serial_and_batch_bundle;
|
|
|
|
|
2022-10-10 07:58:19 +00:00
|
|
|
this.make();
|
|
|
|
this.render_data();
|
|
|
|
}
|
|
|
|
|
|
|
|
make() {
|
2022-12-05 09:18:18 +00:00
|
|
|
let label = this.item?.has_serial_no ? __('Serial No') : __('Batch No');
|
2023-03-13 09:21:43 +00:00
|
|
|
let primary_label = this.bundle
|
2022-12-05 09:18:18 +00:00
|
|
|
? __('Update') : __('Add');
|
|
|
|
|
|
|
|
if (this.item?.has_serial_no && this.item?.batch_no) {
|
|
|
|
label = __('Serial No / Batch No');
|
|
|
|
}
|
|
|
|
|
|
|
|
primary_label += ' ' + label;
|
|
|
|
|
2022-10-10 07:58:19 +00:00
|
|
|
this.dialog = new frappe.ui.Dialog({
|
2022-12-05 09:18:18 +00:00
|
|
|
title: this.item?.title || primary_label,
|
2022-10-10 07:58:19 +00:00
|
|
|
fields: this.get_dialog_fields(),
|
2022-12-05 09:18:18 +00:00
|
|
|
primary_action_label: primary_label,
|
2022-10-10 07:58:19 +00:00
|
|
|
primary_action: () => this.update_ledgers()
|
|
|
|
});
|
2022-12-05 09:18:18 +00:00
|
|
|
|
2022-10-10 07:58:19 +00:00
|
|
|
this.dialog.show();
|
|
|
|
}
|
|
|
|
|
|
|
|
get_serial_no_filters() {
|
2022-12-05 09:18:18 +00:00
|
|
|
let warehouse = this.item?.outward ?
|
2023-03-13 09:21:43 +00:00
|
|
|
(this.item.warehouse || this.item.s_warehouse) : "";
|
2022-12-05 09:18:18 +00:00
|
|
|
|
2022-10-10 07:58:19 +00:00
|
|
|
return {
|
|
|
|
'item_code': this.item.item_code,
|
2022-12-05 09:18:18 +00:00
|
|
|
'warehouse': ["=", warehouse]
|
2022-10-10 07:58:19 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
get_dialog_fields() {
|
|
|
|
let fields = [];
|
|
|
|
|
|
|
|
if (this.item.has_serial_no) {
|
|
|
|
fields.push({
|
|
|
|
fieldtype: 'Link',
|
|
|
|
fieldname: 'scan_serial_no',
|
|
|
|
label: __('Scan Serial No'),
|
|
|
|
options: 'Serial No',
|
|
|
|
get_query: () => {
|
|
|
|
return {
|
|
|
|
filters: this.get_serial_no_filters()
|
|
|
|
};
|
|
|
|
},
|
|
|
|
onchange: () => this.update_serial_batch_no()
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.item.has_batch_no && this.item.has_serial_no) {
|
|
|
|
fields.push({
|
|
|
|
fieldtype: 'Column Break',
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.item.has_batch_no) {
|
|
|
|
fields.push({
|
|
|
|
fieldtype: 'Link',
|
|
|
|
fieldname: 'scan_batch_no',
|
|
|
|
label: __('Scan Batch No'),
|
|
|
|
options: 'Batch',
|
2023-04-04 06:20:38 +00:00
|
|
|
get_query: () => {
|
|
|
|
return {
|
|
|
|
filters: {
|
|
|
|
'item': this.item.item_code
|
|
|
|
}
|
|
|
|
};
|
|
|
|
},
|
2022-10-10 07:58:19 +00:00
|
|
|
onchange: () => this.update_serial_batch_no()
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2023-03-13 09:21:43 +00:00
|
|
|
if (this.frm.doc.doctype === 'Stock Entry'
|
|
|
|
&& this.frm.doc.purpose === 'Manufacture') {
|
|
|
|
fields.push({
|
|
|
|
fieldtype: 'Column Break',
|
|
|
|
});
|
|
|
|
|
|
|
|
fields.push({
|
|
|
|
fieldtype: 'Link',
|
|
|
|
fieldname: 'work_order',
|
|
|
|
label: __('For Work Order'),
|
|
|
|
options: 'Work Order',
|
|
|
|
read_only: 1,
|
|
|
|
default: this.frm.doc.work_order,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2022-12-05 09:18:18 +00:00
|
|
|
if (this.item?.outward) {
|
2023-04-04 06:20:38 +00:00
|
|
|
fields = [...this.get_filter_fields(), ...fields];
|
2022-10-10 07:58:19 +00:00
|
|
|
}
|
|
|
|
|
2022-12-05 09:18:18 +00:00
|
|
|
fields.push({
|
|
|
|
fieldtype: 'Section Break',
|
|
|
|
});
|
|
|
|
|
2022-10-10 07:58:19 +00:00
|
|
|
fields.push({
|
2023-03-21 05:24:41 +00:00
|
|
|
fieldname: 'entries',
|
2022-10-10 07:58:19 +00:00
|
|
|
fieldtype: 'Table',
|
|
|
|
allow_bulk_edit: true,
|
|
|
|
data: [],
|
|
|
|
fields: this.get_dialog_table_fields(),
|
|
|
|
});
|
|
|
|
|
|
|
|
return fields;
|
|
|
|
}
|
|
|
|
|
2022-12-05 09:18:18 +00:00
|
|
|
get_filter_fields() {
|
|
|
|
return [
|
|
|
|
{
|
|
|
|
fieldtype: 'Section Break',
|
|
|
|
label: __('Auto Fetch')
|
|
|
|
},
|
|
|
|
{
|
|
|
|
fieldtype: 'Float',
|
|
|
|
fieldname: 'qty',
|
|
|
|
default: this.item.qty || 0,
|
|
|
|
label: __('Qty to Fetch'),
|
2023-04-04 06:20:38 +00:00
|
|
|
onchange: () => this.get_auto_data()
|
2022-12-05 09:18:18 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
fieldtype: 'Column Break',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
fieldtype: 'Select',
|
|
|
|
options: ['FIFO', 'LIFO', 'Expiry'],
|
|
|
|
default: 'FIFO',
|
|
|
|
fieldname: 'based_on',
|
2023-04-04 06:20:38 +00:00
|
|
|
label: __('Fetch Based On'),
|
|
|
|
onchange: () => this.get_auto_data()
|
2022-12-05 09:18:18 +00:00
|
|
|
},
|
|
|
|
{
|
2023-04-04 06:20:38 +00:00
|
|
|
fieldtype: 'Section Break',
|
2022-12-05 09:18:18 +00:00
|
|
|
},
|
|
|
|
]
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-10-10 07:58:19 +00:00
|
|
|
get_dialog_table_fields() {
|
|
|
|
let fields = []
|
|
|
|
|
|
|
|
if (this.item.has_serial_no) {
|
|
|
|
fields.push({
|
|
|
|
fieldtype: 'Link',
|
|
|
|
options: 'Serial No',
|
|
|
|
fieldname: 'serial_no',
|
|
|
|
label: __('Serial No'),
|
|
|
|
in_list_view: 1,
|
|
|
|
get_query: () => {
|
|
|
|
return {
|
|
|
|
filters: this.get_serial_no_filters()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
2022-12-05 09:18:18 +00:00
|
|
|
}
|
|
|
|
|
2023-03-13 09:21:43 +00:00
|
|
|
let batch_fields = []
|
2022-12-05 09:18:18 +00:00
|
|
|
if (this.item.has_batch_no) {
|
2023-03-13 09:21:43 +00:00
|
|
|
batch_fields = [
|
2022-10-10 07:58:19 +00:00
|
|
|
{
|
|
|
|
fieldtype: 'Link',
|
|
|
|
options: 'Batch',
|
|
|
|
fieldname: 'batch_no',
|
|
|
|
label: __('Batch No'),
|
|
|
|
in_list_view: 1,
|
2023-04-04 06:20:38 +00:00
|
|
|
get_query: () => {
|
|
|
|
return {
|
|
|
|
filters: {
|
|
|
|
'item': this.item.item_code
|
|
|
|
}
|
|
|
|
};
|
|
|
|
},
|
2023-03-13 09:21:43 +00:00
|
|
|
}
|
|
|
|
]
|
|
|
|
|
|
|
|
if (!this.item.has_serial_no) {
|
|
|
|
batch_fields.push({
|
2022-10-10 07:58:19 +00:00
|
|
|
fieldtype: 'Float',
|
|
|
|
fieldname: 'qty',
|
|
|
|
label: __('Quantity'),
|
|
|
|
in_list_view: 1,
|
2023-03-13 09:21:43 +00:00
|
|
|
})
|
|
|
|
}
|
2022-10-10 07:58:19 +00:00
|
|
|
}
|
|
|
|
|
2023-03-13 09:21:43 +00:00
|
|
|
fields = [...fields, ...batch_fields];
|
|
|
|
|
2022-10-10 07:58:19 +00:00
|
|
|
fields.push({
|
|
|
|
fieldtype: 'Data',
|
|
|
|
fieldname: 'name',
|
|
|
|
label: __('Name'),
|
|
|
|
hidden: 1,
|
2023-03-13 09:21:43 +00:00
|
|
|
});
|
2022-10-10 07:58:19 +00:00
|
|
|
|
|
|
|
return fields;
|
|
|
|
}
|
|
|
|
|
2022-12-05 09:18:18 +00:00
|
|
|
get_auto_data() {
|
|
|
|
const { qty, based_on } = this.dialog.get_values();
|
|
|
|
|
|
|
|
if (!qty) {
|
|
|
|
frappe.throw(__('Please enter Qty to Fetch'));
|
|
|
|
}
|
|
|
|
|
2023-04-04 06:20:38 +00:00
|
|
|
if (!based_on) {
|
|
|
|
based_on = 'FIFO';
|
|
|
|
}
|
|
|
|
|
2022-12-05 09:18:18 +00:00
|
|
|
frappe.call({
|
|
|
|
method: 'erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle.get_auto_data',
|
|
|
|
args: {
|
|
|
|
item_code: this.item.item_code,
|
2023-03-13 09:21:43 +00:00
|
|
|
warehouse: this.item.warehouse || this.item.s_warehouse,
|
2022-12-05 09:18:18 +00:00
|
|
|
has_serial_no: this.item.has_serial_no,
|
|
|
|
has_batch_no: this.item.has_batch_no,
|
|
|
|
qty: qty,
|
|
|
|
based_on: based_on
|
|
|
|
},
|
|
|
|
callback: (r) => {
|
|
|
|
if (r.message) {
|
2023-03-21 05:24:41 +00:00
|
|
|
this.dialog.fields_dict.entries.df.data = r.message;
|
|
|
|
this.dialog.fields_dict.entries.grid.refresh();
|
2022-12-05 09:18:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2022-10-10 07:58:19 +00:00
|
|
|
update_serial_batch_no() {
|
|
|
|
const { scan_serial_no, scan_batch_no } = this.dialog.get_values();
|
|
|
|
|
|
|
|
if (scan_serial_no) {
|
2023-03-21 05:24:41 +00:00
|
|
|
this.dialog.fields_dict.entries.df.data.push({
|
2022-10-10 07:58:19 +00:00
|
|
|
serial_no: scan_serial_no
|
|
|
|
});
|
|
|
|
|
|
|
|
this.dialog.fields_dict.scan_serial_no.set_value('');
|
|
|
|
} else if (scan_batch_no) {
|
2023-03-21 05:24:41 +00:00
|
|
|
this.dialog.fields_dict.entries.df.data.push({
|
2022-10-10 07:58:19 +00:00
|
|
|
batch_no: scan_batch_no
|
|
|
|
});
|
|
|
|
|
|
|
|
this.dialog.fields_dict.scan_batch_no.set_value('');
|
|
|
|
}
|
|
|
|
|
2023-03-21 05:24:41 +00:00
|
|
|
this.dialog.fields_dict.entries.grid.refresh();
|
2022-10-10 07:58:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
update_ledgers() {
|
2023-03-21 05:24:41 +00:00
|
|
|
let entries = this.dialog.get_values().entries;
|
2022-10-10 07:58:19 +00:00
|
|
|
|
2023-03-21 05:24:41 +00:00
|
|
|
if (entries && !entries.length || !entries) {
|
|
|
|
frappe.throw(__('Please add atleast one Serial No / Batch No'));
|
2022-10-10 07:58:19 +00:00
|
|
|
}
|
2023-03-21 05:24:41 +00:00
|
|
|
|
|
|
|
frappe.call({
|
|
|
|
method: 'erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle.add_serial_batch_ledgers',
|
|
|
|
args: {
|
|
|
|
entries: entries,
|
|
|
|
child_row: this.item,
|
|
|
|
doc: this.frm.doc,
|
|
|
|
}
|
|
|
|
}).then(r => {
|
|
|
|
this.callback && this.callback(r.message);
|
2023-03-24 04:44:09 +00:00
|
|
|
this.frm.save();
|
2023-03-21 05:24:41 +00:00
|
|
|
this.dialog.hide();
|
|
|
|
})
|
2022-10-10 07:58:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
render_data() {
|
2023-03-13 09:21:43 +00:00
|
|
|
if (!this.frm.is_new() && this.bundle) {
|
2022-10-10 07:58:19 +00:00
|
|
|
frappe.call({
|
2022-11-24 11:46:21 +00:00
|
|
|
method: 'erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle.get_serial_batch_ledgers',
|
2022-10-10 07:58:19 +00:00
|
|
|
args: {
|
|
|
|
item_code: this.item.item_code,
|
2023-03-13 09:21:43 +00:00
|
|
|
name: this.bundle,
|
2022-10-10 07:58:19 +00:00
|
|
|
voucher_no: this.item.parent,
|
|
|
|
}
|
|
|
|
}).then(r => {
|
|
|
|
if (r.message) {
|
|
|
|
this.set_data(r.message);
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
set_data(data) {
|
|
|
|
data.forEach(d => {
|
2023-03-21 05:24:41 +00:00
|
|
|
this.dialog.fields_dict.entries.df.data.push(d);
|
2022-10-10 07:58:19 +00:00
|
|
|
});
|
|
|
|
|
2023-03-21 05:24:41 +00:00
|
|
|
this.dialog.fields_dict.entries.grid.refresh();
|
2022-10-10 07:58:19 +00:00
|
|
|
}
|
|
|
|
}
|