refactor: disable quick entry for batched and serialized items
diff --git a/erpnext/stock/dashboard/item_dashboard.js b/erpnext/stock/dashboard/item_dashboard.js
index ed325a1..c84acc5 100644
--- a/erpnext/stock/dashboard/item_dashboard.js
+++ b/erpnext/stock/dashboard/item_dashboard.js
@@ -19,13 +19,24 @@
this.content.on('click', '.btn-move', function() {
let item = unescape($(this).attr('data-item'));
let warehouse = unescape($(this).attr('data-warehouse'));
- open_stock_entry(item, warehouse, "Material Transfer");
+ let actual_qty = unescape($(this).attr('data-actual_qty'));
+ let disable_quick_entry = Number(unescape($(this).attr('data-disable_quick_entry')));
+
+ if (disable_quick_entry) open_stock_entry(item, warehouse, "Material Transfer");
+
+ else erpnext.stock.move_item(item, warehouse, null, actual_qty, null, function() { me.refresh(); })
});
this.content.on('click', '.btn-add', function() {
let item = unescape($(this).attr('data-item'));
let warehouse = unescape($(this).attr('data-warehouse'));
- open_stock_entry(item, warehouse);
+ let actual_qty = unescape($(this).attr('data-actual_qty'));
+ let disable_quick_entry = Number(unescape($(this).attr('data-disable_quick_entry')));
+ let rate = unescape($(this).attr('data-rate'));
+
+ if (disable_quick_entry) open_stock_entry(item, warehouse);
+
+ else erpnext.stock.move_item(item, null, warehouse, actual_qty, rate, function() { me.refresh(); })
});
function open_stock_entry(item, warehouse, entry_type) {
@@ -124,4 +135,89 @@
show_item: show_item || false
}
}
-})
\ No newline at end of file
+})
+
+erpnext.stock.move_item = function(item, source, target, actual_qty, rate, callback) {
+ var dialog = new frappe.ui.Dialog({
+ title: target ? __('Add Item') : __('Move Item'),
+ fields: [
+ {fieldname: 'item_code', label: __('Item'),
+ fieldtype: 'Link', options: 'Item', read_only: 1},
+ {fieldname: 'source', label: __('Source Warehouse'),
+ fieldtype: 'Link', options: 'Warehouse', read_only: 1},
+ {fieldname: 'target', label: __('Target Warehouse'),
+ fieldtype: 'Link', options: 'Warehouse', reqd: 1},
+ {fieldname: 'qty', label: __('Quantity'), reqd: 1,
+ fieldtype: 'Float', description: __('Available {0}', [actual_qty]) },
+ {fieldname: 'rate', label: __('Rate'), fieldtype: 'Currency', hidden: 1 },
+ ],
+ })
+ dialog.show();
+ dialog.get_field('item_code').set_input(item);
+
+ if(source) {
+ dialog.get_field('source').set_input(source);
+ } else {
+ dialog.get_field('source').df.hidden = 1;
+ dialog.get_field('source').refresh();
+ }
+
+ if(rate) {
+ dialog.get_field('rate').set_value(rate);
+ dialog.get_field('rate').df.hidden = 0;
+ dialog.get_field('rate').refresh();
+ }
+
+ if(target) {
+ dialog.get_field('target').df.read_only = 1;
+ dialog.get_field('target').value = target;
+ dialog.get_field('target').refresh();
+ }
+
+ dialog.set_primary_action(__('Submit'), function() {
+ var values = dialog.get_values();
+ if(!values) {
+ return;
+ }
+ if(source && values.qty > actual_qty) {
+ frappe.msgprint(__('Quantity must be less than or equal to {0}', [actual_qty]));
+ return;
+ }
+ if(values.source === values.target) {
+ frappe.msgprint(__('Source and target warehouse must be different'));
+ }
+
+ frappe.call({
+ method: 'erpnext.stock.doctype.stock_entry.stock_entry_utils.make_stock_entry',
+ args: values,
+ freeze: true,
+ callback: function(r) {
+ frappe.show_alert(__('Stock Entry {0} created',
+ ['<a href="#Form/Stock Entry/'+r.message.name+'">' + r.message.name+ '</a>']));
+ dialog.hide();
+ callback(r);
+ },
+ });
+ });
+
+ $('<p style="margin-left: 10px;"><a class="link-open text-muted small">'
+ + __("Add more items or open full form") + '</a></p>')
+ .appendTo(dialog.body)
+ .find('.link-open')
+ .on('click', function() {
+ frappe.model.with_doctype('Stock Entry', function() {
+ var doc = frappe.model.get_new_doc('Stock Entry');
+ doc.from_warehouse = dialog.get_value('source');
+ doc.to_warehouse = dialog.get_value('target');
+ var row = frappe.model.add_child(doc, 'items');
+ row.item_code = dialog.get_value('item_code');
+ row.f_warehouse = dialog.get_value('target');
+ row.t_warehouse = dialog.get_value('target');
+ row.qty = dialog.get_value('qty');
+ row.conversion_factor = 1;
+ row.transfer_qty = dialog.get_value('qty');
+ row.basic_rate = dialog.get_value('rate');
+ frappe.set_route('Form', doc.doctype, doc.name);
+ })
+ });
+}
\ No newline at end of file
diff --git a/erpnext/stock/dashboard/item_dashboard.py b/erpnext/stock/dashboard/item_dashboard.py
index 487c765..7634ff0 100644
--- a/erpnext/stock/dashboard/item_dashboard.py
+++ b/erpnext/stock/dashboard/item_dashboard.py
@@ -44,7 +44,9 @@
for item in items:
item.update({
- 'item_name': frappe.get_cached_value("Item", item.item_code, 'item_name')
+ 'item_name': frappe.get_cached_value("Item", item.item_code, 'item_name'),
+ 'disable_quick_entry': frappe.get_cached_value("Item", item.item_code, 'has_batch_no')
+ or frappe.get_cached_value("Item", item.item_code, 'has_serial_no'),
})
return items
diff --git a/erpnext/stock/dashboard/item_dashboard_list.html b/erpnext/stock/dashboard/item_dashboard_list.html
index 5a3fa2e..e1914ed 100644
--- a/erpnext/stock/dashboard/item_dashboard_list.html
+++ b/erpnext/stock/dashboard/item_dashboard_list.html
@@ -43,11 +43,13 @@
<div class="col-sm-2 text-right" style="margin-top: 8px;">
{% if d.actual_qty %}
<button class="btn btn-default btn-xs btn-move"
+ data-disable_quick_entry="{{ d.disable_quick_entry }}"
data-warehouse="{{ d.warehouse }}"
data-actual_qty="{{ d.actual_qty }}"
data-item="{{ escape(d.item_code) }}">{{ __("Move") }}</a>
{% endif %}
<button style="margin-left: 7px;" class="btn btn-default btn-xs btn-add"
+ data-disable_quick_entry="{{ d.disable_quick_entry }}"
data-warehouse="{{ d.warehouse }}"
data-actual_qty="{{ d.actual_qty }}"
data-item="{{ escape(d.item_code) }}"