mirror of
https://github.com/frappe/frappe_docker.git
synced 2026-06-22 15:55:09 +00:00
172 lines
No EOL
7.7 KiB
JavaScript
172 lines
No EOL
7.7 KiB
JavaScript
frappe.templates['item_dashboard'] = '<div> <div class="result"> </div> <div class="more hidden" style="padding: 15px;"> <a class="btn btn-default btn-xs btn-more">More</a> </div> </div>';
|
|
frappe.templates['item_dashboard_list'] = '{% for d in data %} <div class="dashboard-list-item"> <div class="row"> <div class="col-sm-3 small" style="margin-top: 8px;"> <a data-type="warehouse" data-name="{{ d.warehouse }}">{{ d.warehouse }}</a> </div> <div class="col-sm-3 small" style="margin-top: 8px;"> {% if show_item %} <a data-type="item" data-name="{{ d.item_code }}">{{ d.item_code }} {% if d.item_name != d.item_code %}({{ d.item_name }}){% endif %} </a> {% endif %} </div> <div class="col-sm-4 small"> <span class="inline-graph"> <span class="inline-graph-half" title="{{ __("Reserved Qty") }}"> <span class="inline-graph-count">{{ d.total_reserved }}</span> <span class="inline-graph-bar"> <span class="inline-graph-bar-inner" style="width: {{ cint(Math.abs(d.total_reserved)/max_count * 100) || 5 }}%"> </span> </span> </span> <span class="inline-graph-half" title="{{ __("Actual Qty {0} / Waiting Qty {1}", [d.actual_qty, d.pending_qty]) }}"> <span class="inline-graph-count"> {{ d.actual_qty }} {{ (d.pending_qty > 0) ? ("(" + d.pending_qty+ ")") : "" }} </span> <span class="inline-graph-bar"> <span class="inline-graph-bar-inner dark" style="width: {{ cint(d.actual_qty/max_count * 100) }}%"> </span> {% if d.pending_qty > 0 %} <span class="inline-graph-bar-inner" title="{{ __("Projected Qty") }}" style="width: {{ cint(d.pending_qty/max_count * 100) }}%"> </span> {% endif %} </span> </span> </span> </div> <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-warehouse="{{ d.warehouse }}" data-actual_qty="{{ d.actual_qty }}" data-item="{{ d.item_code }}">{{ __("Move") }}</a> {% endif %} <button style="margin-left: 7px;" class="btn btn-default btn-xs btn-add" data-warehouse="{{ d.warehouse }}" data-actual_qty="{{ d.actual_qty }}" data-item="{{ d.item_code }}" data-rate="{{ d.valuation_rate }}">{{ __("Add") }}</a> </div> </div> </div> {% endfor %} ';
|
|
|
|
|
|
frappe.provide('erpnext.stock');
|
|
|
|
erpnext.stock.ItemDashboard = Class.extend({
|
|
init: function init(opts) {
|
|
$.extend(this, opts);
|
|
this.make();
|
|
},
|
|
make: function make() {
|
|
var me = this;
|
|
this.start = 0;
|
|
if (!this.sort_by) {
|
|
this.sort_by = 'projected_qty';
|
|
this.sort_order = 'asc';
|
|
}
|
|
|
|
this.content = $(frappe.render_template('item_dashboard')).appendTo(this.parent);
|
|
this.result = this.content.find('.result');
|
|
|
|
this.content.on('click', '.btn-move', function () {
|
|
erpnext.stock.move_item($(this).attr('data-item'), $(this).attr('data-warehouse'), null, $(this).attr('data-actual_qty'), null, function () {
|
|
me.refresh();
|
|
});
|
|
});
|
|
|
|
this.content.on('click', '.btn-add', function () {
|
|
erpnext.stock.move_item($(this).attr('data-item'), null, $(this).attr('data-warehouse'), $(this).attr('data-actual_qty'), $(this).attr('data-rate'), function () {
|
|
me.refresh();
|
|
});
|
|
});
|
|
|
|
this.content.find('.btn-more').on('click', function () {
|
|
me.start += 20;
|
|
me.refresh();
|
|
});
|
|
},
|
|
refresh: function refresh() {
|
|
if (this.before_refresh) {
|
|
this.before_refresh();
|
|
}
|
|
|
|
var me = this;
|
|
frappe.call({
|
|
method: 'erpnext.stock.dashboard.item_dashboard.get_data',
|
|
args: {
|
|
item_code: this.item_code,
|
|
warehouse: this.warehouse,
|
|
item_group: this.item_group,
|
|
start: this.start,
|
|
sort_by: this.sort_by,
|
|
sort_order: this.sort_order
|
|
},
|
|
callback: function callback(r) {
|
|
me.render(r.message);
|
|
}
|
|
});
|
|
},
|
|
render: function render(data) {
|
|
if (this.start === 0) {
|
|
this.max_count = 0;
|
|
this.result.empty();
|
|
}
|
|
|
|
var context = this.get_item_dashboard_data(data, this.max_count, true);
|
|
this.max_count = this.max_count;
|
|
|
|
if (data && data.length === 21) {
|
|
this.content.find('.more').removeClass('hidden');
|
|
|
|
data.splice(-1);
|
|
} else {
|
|
this.content.find('.more').addClass('hidden');
|
|
}
|
|
|
|
$(frappe.render_template('item_dashboard_list', context)).appendTo(this.result);
|
|
},
|
|
get_item_dashboard_data: function get_item_dashboard_data(data, max_count, show_item) {
|
|
if (!max_count) max_count = 0;
|
|
if (!data) data = [];
|
|
data.forEach(function (d) {
|
|
d.actual_or_pending = d.projected_qty + d.reserved_qty + d.reserved_qty_for_production;
|
|
d.pending_qty = 0;
|
|
d.total_reserved = d.reserved_qty + d.reserved_qty_for_production;
|
|
if (d.actual_or_pending > d.actual_qty) {
|
|
d.pending_qty = d.actual_or_pending - d.actual_qty;
|
|
}
|
|
|
|
max_count = Math.max(d.actual_or_pending, d.actual_qty, d.total_reserved, max_count);
|
|
});
|
|
return {
|
|
data: data,
|
|
max_count: max_count,
|
|
show_item: show_item || false
|
|
};
|
|
}
|
|
});
|
|
|
|
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,
|
|
callback: function callback(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);
|
|
});
|
|
});
|
|
}; |