fire modal on item_code, events, validation
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js
index 8f82b6a..538c08f 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.js
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.js
@@ -41,6 +41,8 @@
}
}
});
+
+
},
refresh: function(frm) {
if(!frm.doc.docstatus) {
@@ -76,9 +78,6 @@
frm.fields_dict.items.grid.refresh();
frm.cscript.toggle_related_fields(frm.doc);
},
- after_save: function(frm) {
- erpnext.select_batch_and_serial_no(frm);
- },
company: function(frm) {
if(frm.doc.company) {
var company_doc = frappe.get_doc(":Company", frm.doc.company);
@@ -177,6 +176,7 @@
d[k] = v;
});
refresh_field("items");
+ erpnext.select_batch_and_serial_no(frm, d);
}
}
});
@@ -546,22 +546,23 @@
}
});
-erpnext.select_batch_and_serial_no = (frm) => {
+erpnext.select_batch_and_serial_no = (frm, d = undefined) => {
let get_warehouse = (item) => {
- return cstr(item.s_warehouse) ? cstr(item.s_warehouse) : cstr(item.t_warehouse);
+ return cstr(item.s_warehouse) ? ['Source Warehouse', cstr(item.s_warehouse)]
+ : ['Target Warehouse', cstr(item.t_warehouse)];
}
- let show_modal_with_oldest_batch = (item, item_code, total_qty, warehouse, has_batch) => {
+ let show_modal_with_oldest_batch = (item, item_code, total_qty, warehouse_details, has_batch) => {
frappe.call({
method: 'erpnext.stock.doctype.batch.batch.get_batches_by_oldest',
args: {
- warehouse: warehouse,
+ warehouse: warehouse_details[1],
item_code: item_code
},
callback: (r) => {
if (r.message) {
batch_rows_by_oldest = [];
- if(cstr(item.s_warehouse)) {
+ if(warehouse_details[0] === 'Source Warehouse') {
qty = total_qty;
for(var i = 0; i < r.message.length; i++) {
batch_row = {name: 'batch 1'};
@@ -578,54 +579,47 @@
}
}
}
- erpnext.show_batch_serial_modal(frm, item, item_code, total_qty, warehouse, has_batch, batch_rows_by_oldest);
+ erpnext.show_batch_serial_modal(frm, item, item_code, total_qty,
+ warehouse_details, has_batch, batch_rows_by_oldest);
}
}
});
}
- frm.doc.items.forEach(function(d) {
+ if(d) {
if(d.has_batch_no && !d.batch_no) {
- show_modal_with_oldest_batch(d, d.item_code, d.qty, get_warehouse(d), 1);
+ if(get_warehouse(d)) {
+ show_modal_with_oldest_batch(d, d.item_code, d.qty, get_warehouse(d), 1);
+ } else {
+ d.item_code = '';
+ refresh_field('items');
+ frappe.throw("Please select a warehouse.");
+ }
} else if(d.has_serial_no && !d.serial_no) {
erpnext.show_batch_serial_modal(frm, d, d.item_code, d.qty, get_warehouse(d), 0);
}
- });
-
-
+ }
}
-erpnext.show_batch_serial_modal = (frm, item, item_code, qty, warehouse, has_batch, oldest = undefined) => {
+erpnext.show_batch_serial_modal = (frm, item, item_code, qty, warehouse_details,
+ has_batch, oldest = undefined) => {
+
let data = oldest ? oldest : []
let title = "";
let fields = [
+ {fieldname: frappe.model.scrub(warehouse_details[0]), read_only: 1, fieldtype:'Link',
+ options: 'Warehouse', label: __(warehouse_details[0]), 'default': warehouse_details[1]},
+ {fieldtype:'Column Break'},
{fieldname: 'item_code', read_only: 1, fieldtype:'Link', options: 'Item',
label: __('Item Code'), 'default': item_code},
{fieldtype:'Column Break'},
- {fieldname: 'qty', read_only: 1, fieldtype:'Float', label: __('Qty'), 'default': qty},
+ {fieldname: 'qty', fieldtype:'Float', label: __(has_batch ? 'Total Qty' : 'Qty'), 'default': qty},
];
- let set_available_qty = (item_code, batch_no, warehouse, field) => {
- frappe.call({
- method: 'erpnext.stock.doctype.batch.batch.get_batch_qty',
- args: {
- batch_no: batch_no,
- warehouse: warehouse,
- item_code: item_code
- },
- callback: (r) => {
- if (r.message) {
- field.set_value(r.message);
- field.$input.trigger('change');
- }
- }
- });
- }
-
if(has_batch) {
title = __("Select Batch Numbers");
fields = fields.concat([
- {fieldtype:'Section Break', label: __('Batch No')},
+ {fieldtype:'Section Break', label: __('Batches')},
{fieldname: 'batches', fieldtype: 'Table',
fields: [
{fieldtype:'Link', fieldname:'batch_no', options: 'Batch',
@@ -633,10 +627,11 @@
return {filters: {item: item_code }};
}},
{fieldtype:'Float', read_only: 1, fieldname:'available_qty',
- label: __('Available'), in_list_view:1},
+ label: __('Available'), in_list_view:1, 'default': 0},
{fieldtype:'Float', fieldname:'selected_qty',
- label: __('Qty'), in_list_view:1},
+ label: __('Qty'), in_list_view:1, 'default': 0},
],
+ in_place_edit: true,
data: data,
get_data: function() {
return this.data;
@@ -649,11 +644,37 @@
let row = grid.grid_rows_by_docname[name];
row.on_grid_fields[2].set_value('0');
row.on_grid_fields[2].$input.trigger('change');
- set_available_qty(item_code, row.doc.batch_no, warehouse, row.on_grid_fields[1]);
+ set_available_qty(item_code, row.doc.batch_no, warehouse_details[1], row.on_grid_fields[1]);
+ });
+
+ grid.wrapper.on('change', 'input[data-fieldname="selected_qty"]', function(e) {
+ // check if batch is selected
+ if($(this).val().length !== 0) {
+ let $row = $(this).closest('.grid-row');
+
+ let $batch = $row.find('input[data-fieldname="batch_no"]');
+ if($batch.val() === '') {
+ $(this).val('').trigger('change');
+ frappe.throw(__("Please select a batch"));
+ } else {
+ // check if greater than available if source
+ let $available = $row.find('input[data-fieldname="available_qty"]');
+ if(warehouse_details[0] === 'Source Warehouse' &&
+ parseInt($available.val()) < parseInt($(this).val())) {
+
+ $(this).val('').trigger('change');
+ frappe.throw(__(`For transfer from source, selected quantity cannot be
+ greater than available quantity`));
+ }
+ }
+ }
+
});
}
+
}
]);
+
} else {
title = __("Select Serial Numbers");
fields = fields.concat([
@@ -675,68 +696,24 @@
fields: fields
});
- let serial_no_link = dialog.fields_dict.serial_no_select;
- if(serial_no_link) {
- serial_no_link.$input.on('change', function(e) {
- let serial_no_list = dialog.fields_dict.serial_no;
- if(serial_no_link.get_value()) {
- let new_line = '\n';
- if(!serial_no_list.get_value()) {
- new_line = '';
- }
- serial_no_list.set_value(serial_no_list.get_value() + new_line + serial_no_link.get_value());
- serial_no_link.$input.val('');
- serial_no_link.set_value('');
- }
- });
- }
-
- item_temp = {};
- Object.assign(item_temp, item);
- delete item_temp['batch_no'];
- delete item_temp['qty'];
- delete item_temp['idx'];
+ erpnext.bind_dialog_events(dialog);
let validate_batch_dialog = (values) => {
- var sum = 0;
-
- values.batches.map((batch) => {
- sum += parseInt(batch.selected_qty);
- if(batch.batch_no && batch.selected_qty) {
- if(parseInt(batch.selected_qty) > parseInt(batch.available_qty)
- && cstr(item.s_warehouse)) {
- frappe.throw(__("Cannot select more than the available qty"));
- return false;
- }
- } else {
- if(!batch.batch_no) {
- frappe.throw(__("Please select batch_no"));
- return false;
- } else {
- frappe.throw(__("Please select qty"));
- return false;
- }
+ if(values.batches.length === 0 || !values.batches) {
+ frappe.throw(__("Please select batches for batched item " + values.item_code));
+ return false;
+ }
+ values.batches.map((batch, i) => {
+ if(!batch.selected_qty || batch.selected_qty === 0 ) {
+ frappe.throw(__("Please select quantity on row " + (i+1)));
+ return false;
}
});
-
- // validate total_qty
- if(sum > values.qty) {
- frappe.confirm(__(`Total of selected quantities is greater than the previously
- set item quantity. Update?`), function(){
- return true;
- });
- } else if (sum < values.qty){
- frappe.confirm(__(`Total of selected quantities is less than the previously
- set item quantity. Update?`), function(){
- return true;
- });
- } else {
- return true;
- }
+ return true;
}
let set_batched_items = () => {
- var values = dialog.get_values();
+ let values = dialog.get_values();
if(!validate_batch_dialog(values)) {
return;
}
@@ -745,47 +722,103 @@
if(i === 0) {
item.batch_no = batch.batch_no;
item.qty = batch.selected_qty;
- console.log("item", item, frm.doc.items);
} else {
var row = frm.add_child("items");
- Object.assign(row, item_temp);
- console.log("item", item_temp);
-
- row.item_code = item_temp.item_code;
+ row.item_code = item.item_code;
+ if(item.s_warehouse) {
+ row.s_warehouse = item.s_warehouse;
+ } else {
+ row.t_warehouse = item.t_warehouse;
+ }
row.batch_no = batch.batch_no;
row.qty = batch.selected_qty;
- console.log("row", row, frm.doc.items);
}
- refresh_field("items");
});
}
let validate_serial_no_dialog = (values) => {
- var serial_nos = values.serial_no || '';
+ let serial_nos = values.serial_no || '';
if (!serial_nos || !serial_nos.replace(/\s/g, '').length) {
- frappe.throw(__("Please enter serial numbers"));
+ frappe.throw(__("Please enter serial numbers for serialized item " + values.item_code));
return false;
}
return true;
}
let set_serialized_items = () => {
- var values = dialog.get_values();
+ let values = dialog.get_values();
if (!validate_serial_no_dialog(values)) {
return;
}
item.serial_no = values.serial_no;
+ item.qty = values.qty;
+ }
+
+ function set_available_qty(item_code, batch_no, warehouse, field) {
+ frappe.call({
+ method: 'erpnext.stock.doctype.batch.batch.get_batch_qty',
+ args: {
+ batch_no: batch_no,
+ warehouse: warehouse,
+ item_code: item_code
+ },
+ callback: (r) => {
+ if (r.message) {
+ field.set_value(r.message);
+ field.$input.trigger('change');
+ }
+ }
+ });
}
dialog.set_primary_action(__('Get Items'), function() {
- if(has_batch) {
- set_batched_items();
- } else {
- set_serialized_items();
- }
-
+ has_batch ? set_batched_items() : set_serialized_items();
refresh_field("items");
dialog.hide();
})
dialog.show();
}
+
+erpnext.bind_dialog_events = (dialog) => {
+ let serial_no_link = dialog.fields_dict.serial_no_select;
+ let serial_no_list = dialog.fields_dict.serial_no;
+ let batches_field = dialog.fields_dict.batches;
+ let qty_field = dialog.fields_dict.qty;
+
+ let update_quantity = (batch) => {
+ if(batch) {
+ let total_qty = 0;
+ batches_field.grid.wrapper.find('input[data-fieldname="selected_qty"]').each(function() {
+ total_qty += Number($(this).val());
+ });
+ qty_field.set_input(total_qty);
+ } else {
+ serial_numbers = serial_no_list.get_value().replace(/\n/g, ' ').match(/\S+/g) || [];
+ qty_field.set_input(serial_numbers.length);
+ }
+ }
+
+ if(serial_no_link) {
+ serial_no_link.$input.on('change', function(e) {
+ if(serial_no_link.get_value()) {
+ let new_line = '\n';
+ if(!serial_no_list.get_value()) {
+ new_line = '';
+ }
+ serial_no_list.set_value(serial_no_list.get_value() + new_line + serial_no_link.get_value());
+ update_quantity(0);
+ }
+ serial_no_link.set_value('');
+ });
+
+ serial_no_list.$input.on('input', function() {
+ update_quantity(0);
+ });
+ }
+
+ if(batches_field) {
+ batches_field.grid.wrapper.on('change', function(e) {
+ update_quantity(1);
+ });
+ }
+}
\ No newline at end of file