// 在OpenERP的Web框架内,
// 通过声明一个函数来声明一个JavaScript模块【openerp.ext_picking就是这个JS模块】,
// 并把这个函数放在全局变量openerp的属性内.
// 这个属性名称必须和OpenERP addon 模块名称一致【文件夹就是ext_picking】
// 【采用匿名函数封装,函数openerp_ext_picking_widgets通过后面的openerp_ext_picking_widgets(openerp)调用】
function openerp_ext_picking_widgets(instance) { var extmodule = instance.ext_stock;
var module = instance.picking;
var _t = instance.web._t;
var QWeb = instance.web.qweb; // This widget makes sure that the scaling is disabled on mobile devices.
// Widgets that want to display fullscreen on mobile phone need to extend this
// widget.
// MobileWidget 如果在手机端显示,需要扩展该部件
// start()在部件初始化后,被自动调用。它接受指令去显示其内容。用它向用户显示一些内容。
// 要做到这一点,我们使用所有部件都有的 $el 属性。该属性是一个 jQuery对象, 表示部件对应的 HTML 标签的根标签。
// 部件包含了多个 HTML 标签,这些 HTM 标签有一个统一的根标签。
// 默认情况下,部件都有一个空的根标签:一个<div>
// $('#oe-mobilewidget-viewport'):选择指定的id的HTML元素
// $('head'):选择特定的HTML元素, .append():追加内容到后面
// 销毁部件 destroy()
extmodule.MobileWidget = instance.web.Widget.extend({
start: function () {
if (!$('#oe-mobilewidget-viewport').length) {
$('head').append('<meta id="oe-mobilewidget-viewport" name="viewport" content="initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">');
}
return this._super();
}, destroy: function () {
$('#oe-mobilewidget-viewport').remove();
return this._super();
},
}); // 操作界面
// 在部件中重载init()时,必须以父部件作为第一参数传入,并调用传入给this._super()
// 重载方法,使用 this._super()调用原来的方法
// get_header: 调用父部件下的 get_header() 方法
extmodule.PickingEditorWidget = instance.web.Widget.extend({
template: 'PickingEditorWidget',
init: function (parent, options) {
this._super(parent, options);
var self = this;
this.rows = [];
this.search_filter = "";
// 伪类选择器jQuery.expr[":"]
jQuery.expr[":"].Contains = jQuery.expr.createPseudo(function (arg) {
return function (elem) {
return jQuery(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
};
});
},
get_header: function () {
return this.getParent().get_header();
},
get_location: function () {
var model = this.getParent();
var locations = [];
var self = this;
_.each(model.locations, function (loc) {
locations.push({name: loc.complete_name, id: loc.id,});
}); return locations;
},
get_logisticunit: function () {
var model = this.getParent();
var ul = [];
var self = this;
_.each(model.uls, function (ulog) {
ul.push({name: ulog.name, id: ulog.id,});
});
return ul;
},
get_rows: function () {
var model = this.getParent();
this.rows = [];
var self = this;
var pack_created = [];
_.each(model.packoplines, function (packopline) {
var pack = undefined;
var color = "";
if (packopline.product_id[1] !== undefined) {
pack = packopline.package_id[1];
}
if (packopline.product_qty == packopline.qty_done) {
color = "success ";
}
if (packopline.product_qty < packopline.qty_done) {
color = "danger ";
}
//also check that we don't have a line already existing for that package
if (packopline.result_package_id[1] !== undefined && $.inArray(packopline.result_package_id[0], pack_created) === -1) {
var myPackage = $.grep(model.packages, function (e) {
return e.id == packopline.result_package_id[0];
})[0];
self.rows.push({
cols: {
product: packopline.result_package_id[1],
qty: '',
rem: '',
uom: undefined,
lot: undefined,
pack: undefined,
container: packopline.result_package_id[1],
container_id: undefined,
loc: packopline.location_id[1],
dest: packopline.location_dest_id[1],
id: packopline.result_package_id[0],
product_id: undefined,
can_scan: false,
head_container: true,
processed: packopline.processed,
package_id: myPackage.id,
ul_id: myPackage.ul_id[0],
display_name: 'select'+packopline.result_package_id[0],
},
classes: ('success container_head ') + (packopline.processed === "true" ? 'processed hidden ' : ''),
});
pack_created.push(packopline.result_package_id[0]);
}
self.rows.push({
cols: {
product: packopline.product_id[1] || packopline.package_id[1],
qty: packopline.product_qty,
rem: packopline.qty_done,
uom: packopline.product_uom_id[1],
lot: packopline.lot_id[1],
pack: pack,
container: packopline.result_package_id[1],
container_id: packopline.result_package_id[0],
loc: packopline.location_id[1],
dest: packopline.location_dest_id[1],
id: packopline.id,
product_id: packopline.product_id[0],
can_scan: packopline.result_package_id[1] === undefined ? true : false,
head_container: false,
processed: packopline.processed,
package_id: undefined,
ul_id: -1,
display_name: 'select'+packopline.id,
},
classes: color + (packopline.result_package_id[1] !== undefined ? 'in_container_hidden ' : '') + (packopline.processed === "true" ? 'processed hidden ' : ''),
});
});
//sort element by things to do, then things done, then grouped by packages
group_by_container = _.groupBy(self.rows, function (row) {
return row.cols.container;
});
var sorted_row = [];
if (group_by_container.undefined !== undefined) {
group_by_container.undefined.sort(function (a, b) {
return (b.classes === '') - (a.classes === '');
});
$.each(group_by_container.undefined, function (key, value) {
sorted_row.push(value);
});
} $.each(group_by_container, function (key, value) {
if (key !== 'undefined') {
$.each(value, function (k, v) {
sorted_row.push(v);
});
}
}); return sorted_row;
},
// .text:设置元素内的内容
renderElement: function () {
var self = this;
this._super();
this.check_content_screen(); this.$('.js_pick_done').click(function () {
self.getParent().done();
});
this.$('.js_pick_print').click(function () {
self.getParent().print_picking();
});
this.$('.oe_pick_app_header').text(self.get_header());
this.$('.oe_searchbox').keyup(function (event) {
self.on_searchbox($(this).val());
});
this.$('.js_putinpack').click(function () {
self.getParent().pack();
});
this.$('.js_drop_down').click(function () {
self.getParent().drop_down();
});
this.$('.js_clear_search').click(function () {
self.on_searchbox('');
self.$('.oe_searchbox').val('');
});
this.$('.oe_searchbox').focus(function () {
self.getParent().barcode_scanner.disconnect();
});
this.$('.oe_searchbox').blur(function () {
self.getParent().barcode_scanner.connect(function (ean) {
self.getParent().scan(ean);
});
});
// #js_select关闭扫码
this.$('#js_select').focus(function () {
self.getParent().barcode_scanner.disconnect();
});
this.$('#js_select').blur(function () {
self.getParent().barcode_scanner.connect(function (ean) {
self.getParent().scan(ean);
});
});
this.$('#js_select').change(function () {
var selection = self.$('#js_select option:selected').attr('value');
if (selection === "ToDo") {
self.getParent().$('.js_pick_pack').removeClass('hidden');
self.getParent().$('.js_drop_down').removeClass('hidden');
self.$('.js_pack_op_line.processed').addClass('hidden');
self.$('.js_pack_op_line:not(.processed)').removeClass('hidden')
}
else {
self.getParent().$('.js_pick_pack').addClass('hidden');
self.getParent().$('.js_drop_down').addClass('hidden');
self.$('.js_pack_op_line.processed').removeClass('hidden');
self.$('.js_pack_op_line:not(.processed)').addClass('hidden')
}
self.on_searchbox(self.search_filter);
});
this.$('.js_plus').click(function () {
var id = $(this).data('product-id');
var op_id = $(this).parents("[data-id]:first").data('id');
self.getParent().scan_product_id(id, true, op_id);
});
this.$('.js_minus').click(function () {
var id = $(this).data('product-id');
var op_id = $(this).parents("[data-id]:first").data('id');
self.getParent().scan_product_id(id, false, op_id);
});
this.$('.js_unfold').click(function () {
var op_id = $(this).parent().data('id');
var line = $(this).parent();
//select all js_pack_op_line with class in_container_hidden and correct container-id
select = self.$('.js_pack_op_line.in_container_hidden[data-container-id=' + op_id + ']')
if (select.length > 0) {
//we unfold
line.addClass('warning');
select.removeClass('in_container_hidden');
select.addClass('in_container');
}
else {
//we fold
line.removeClass('warning');
select = self.$('.js_pack_op_line.in_container[data-container-id=' + op_id + ']')
select.removeClass('in_container');
select.addClass('in_container_hidden');
}
});
this.$('.js_create_lot').click(function () {
var op_id = $(this).parents("[data-id]:first").data('id');
var lot_name = false;
self.$('.js_lot_scan').val('');
var $lot_modal = self.$el.siblings('#js_LotChooseModal');
//disconnect scanner to prevent scanning a product in the back while dialog is open
self.getParent().barcode_scanner.disconnect();
$lot_modal.modal();
//focus input
$lot_modal.on('shown.bs.modal', function () {
self.$('.js_lot_scan').focus();
});
//reactivate scanner when dialog close 关闭对话框激活扫描界面
$lot_modal.on('hidden.bs.modal', function () {
self.getParent().barcode_scanner.connect(function (ean) {
self.getParent().scan(ean);
});
});
self.$('.js_lot_scan').focus();
//button action
self.$('.js_validate_lot').click(function () {
//get content of input
var name = self.$('.js_lot_scan').val();
if (name.length !== 0) {
lot_name = name;
}
$lot_modal.modal('hide');
//we need this here since it is not sure the hide event
//will be catch because we refresh the view after the create_lot call
self.getParent().barcode_scanner.connect(function (ean) {
self.getParent().scan(ean);
});
self.getParent().create_lot(op_id, lot_name);
});
});
this.$('.js_delete_pack').click(function () {
var pack_id = $(this).parents("[data-id]:first").data('id');
self.getParent().delete_package_op(pack_id);
});
this.$('.js_print_pack').click(function () {
var pack_id = $(this).parents("[data-id]:first").data('id');
// $(this).parents("[data-id]:first").data('id')
self.getParent().print_package(pack_id);
});
this.$('.js_submit_value').submit(function (event) {
var op_id = $(this).parents("[data-id]:first").data('id');
var value = parseFloat($("input", this).val());
if (value >= 0) {
self.getParent().set_operation_quantity(value, op_id);
}
$("input", this).val("");
return false;
});
this.$('.js_qty').focus(function () {
self.getParent().barcode_scanner.disconnect();
});
this.$('.js_qty').blur(function () {
var op_id = $(this).parents("[data-id]:first").data('id');
var value = parseFloat($(this).val());
if (value >= 0) {
self.getParent().set_operation_quantity(value, op_id);
} self.getParent().barcode_scanner.connect(function (ean) {
self.getParent().scan(ean);
});
});
this.$('.js_change_src').click(function () {
var op_id = $(this).parents("[data-id]:first").data('id');//data('op_id');
self.$('#js_loc_select').addClass('source');
self.$('#js_loc_select').data('op-id', op_id);
self.$el.siblings('#js_LocationChooseModal').modal();
});
this.$('.js_change_dst').click(function () {
var op_id = $(this).parents("[data-id]:first").data('id');
self.$('#js_loc_select').data('op-id', op_id);
self.$el.siblings('#js_LocationChooseModal').modal();
});
this.$('.js_pack_change_dst').click(function () {
var op_id = $(this).parents("[data-id]:first").data('id');
self.$('#js_loc_select').addClass('pack');
self.$('#js_loc_select').data('op-id', op_id);
self.$el.siblings('#js_LocationChooseModal').modal();
}); this.$('.js_validate_location').click(function () {
//get current selection
var select_dom_element = self.$('#js_loc_select');
var loc_id = self.$('#js_loc_select option:selected').data('loc-id');
var src_dst = false;
var op_id = select_dom_element.data('op-id'); if (select_dom_element.hasClass('pack')) {
select_dom_element.removeClass('source');
op_ids = [];
self.$('.js_pack_op_line[data-container-id=' + op_id + ']').each(function () {
op_ids.push($(this).data('id'));
});
op_id = op_ids;
}
else if (select_dom_element.hasClass('source')) {
src_dst = true;
select_dom_element.removeClass('source');
}
if (loc_id === false) {
//close window
self.$el.siblings('#js_LocationChooseModal').modal('hide');
}
else {
self.$el.siblings('#js_LocationChooseModal').modal('hide');
self.getParent().change_location(op_id, parseInt(loc_id), src_dst); }
});
// 扫描产品
this.$('.js_clear_search2').click(function () {
self.on_searchbox2('');
self.$('.oe_searchbox2').val('');
});
this.$('#oe_searchbox2').keyup(function (event) {
self.getParent().scan($(this).val());
self.on_searchbox2($(this).val());
});
this.$('#oe_searchbox2').focus(function () {
self.getParent().barcode_scanner.disconnect();
});
this.$('#oe_searchbox2').blur(function () {
self.$('#oe_searchbox2').val('');
self.getParent().barcode_scanner.connect(function (ean) {
self.getParent().scan(ean);
});
}); // 更改目标位置
this.$('.js_select_class').blur(function () {
self.getParent().barcode_scanner.connect(function (ean) {
self.getParent().scan(ean);
});
});
this.$('.js_select_class').focus(function () {
// self.getParent().barcode_scanner.disconnect();
});
this.$('.js_select_class').change(function () {
//get current selection
var op_id = $(this).parents("[data-id]:first").data('id'); $(this).parents("[data-id]:first").css('background-color', 'grey'); var select_str = 'select' + op_id;
var select_dom_element = self.$('#' + select_str);
var loc_id = self.$('#'+ select_str + ' option:selected').data('loc-id');
var src_dst = false;
self.$('#'+select_str).data('op-id', op_id); if (select_dom_element.hasClass('pack')) {
select_dom_element.removeClass('source');
op_ids = [];
self.$('.js_pack_op_line[data-container-id=' + op_id + ']').each(function () {
op_ids.push($(this).data('id'));
});
op_id = op_ids;
}
else if (select_dom_element.hasClass('source')) {
src_dst = true;
select_dom_element.removeClass('source');
}
if (loc_id === false) {
//close window
self.$el.siblings('#js_LocationChooseModal').modal('hide');
}
else {
self.$el.siblings('#js_LocationChooseModal').modal('hide');
self.getParent().change_location(op_id, parseInt(loc_id), src_dst);
} });
// this.$('.js_LocationChooseModal2').on('change', function (){
// return $(this).attr('id');
// });
this.$('.js_pack_configure').click(function () {
var pack_id = $(this).parents(".js_pack_op_line:first").data('package-id');
var ul_id = $(this).parents(".js_pack_op_line:first").data('ulid');
self.$('#js_packconf_select').val(ul_id);
self.$('#js_packconf_select').data('pack-id', pack_id);
self.$el.siblings('#js_PackConfModal').modal();
});
this.$('.js_validate_pack').click(function () {
//get current selection
var select_dom_element = self.$('#js_packconf_select');
var ul_id = self.$('#js_packconf_select option:selected').data('ul-id');
var pack_id = select_dom_element.data('pack-id');
self.$el.siblings('#js_PackConfModal').modal('hide');
if (pack_id) {
self.getParent().set_package_pack(pack_id, ul_id);
$('.container_head[data-package-id="' + pack_id + '"]').data('ulid', ul_id);
}
}); //remove navigtion bar from default openerp GUI
$('td.navbar').html('<div></div>');
},
on_searchbox: function (query) {
//hide line that has no location matching the query and highlight location that match the query
this.search_filter = query;
var processed = ".processed";
if (this.$('#js_select option:selected').attr('value') == "ToDo") {
processed = ":not(.processed)";
}
if (query !== '') {
this.$('.js_loc:not(.js_loc:Contains(' + query + '))').removeClass('info');
this.$('.js_loc:Contains(' + query + ')').addClass('info');
this.$('.js_pack_op_line' + processed + ':not(.js_pack_op_line:has(.js_loc:Contains(' + query + ')))').addClass('hidden');
this.$('.js_pack_op_line' + processed + ':has(.js_loc:Contains(' + query + '))').removeClass('hidden');
}
//if no query specified, then show everything
if (query === '') {
this.$('.js_loc').removeClass('info');
this.$('.js_pack_op_line' + processed + '.hidden').removeClass('hidden');
}
this.check_content_screen();
}, on_searchbox2: function (query) { this.check_content_screen();
}, check_content_screen: function () {
//get all visible element and if none has positive qty, disable put in pack and process button
var self = this;
var processed = this.$('.js_pack_op_line.processed');
var qties = this.$('.js_pack_op_line:not(.processed):not(.hidden) .js_qty').map(function () {
return $(this).val()
});
var container = this.$('.js_pack_op_line.container_head:not(.processed):not(.hidden)')
var disabled = true;
$.each(qties, function (index, value) {
if (parseInt(value) > 0) {
disabled = false;
}
}); if (disabled) {
if (container.length === 0) {
self.$('.js_drop_down').addClass('disabled');
}
else {
self.$('.js_drop_down').removeClass('disabled');
}
self.$('.js_pick_pack').addClass('disabled');
if (processed.length === 0) {
self.$('.js_pick_done').addClass('disabled');
}
else {
self.$('.js_pick_done').removeClass('disabled');
}
}
else {
self.$('.js_drop_down').removeClass('disabled');
self.$('.js_pick_pack').removeClass('disabled');
self.$('.js_pick_done').removeClass('disabled');
}
},
get_current_op_selection: function (ignore_container) {
//get ids of visible on the screen
pack_op_ids = []
this.$('.js_pack_op_line:not(.processed):not(.js_pack_op_line.hidden):not(.container_head)').each(function () {
cur_id = $(this).data('id');
pack_op_ids.push(parseInt(cur_id));
});
//get list of element in this.rows where rem > 0 and container is empty is specified
list = []
_.each(this.rows, function (row) {
if (row.cols.rem > 0 && (ignore_container || row.cols.container === undefined)) {
list.push(row.cols.id);
}
});
//return only those visible with rem qty > 0 and container empty
return _.intersection(pack_op_ids, list);
},
remove_blink: function () {
this.$('.js_pack_op_line.blink_me').removeClass('blink_me');
},
// ----------------修改blink 扫描产品刷新页面
blink: function (op_id) {
this.$('.js_pack_op_line[data-id="' + op_id + '"]').addClass('blink_me');// 在数量发生改变的行增加类,产生闪烁效果
},
check_done: function () {
var model = this.getParent();
var self = this;
var done = true;
_.each(model.packoplines, function (packopline) {
if (packopline.processed === "false") {
done = false;
return done;
}
});
return done;
},
get_visible_ids: function () {
var self = this;
var visible_op_ids = []
var op_ids = this.$('.js_pack_op_line:not(.processed):not(.hidden):not(.container_head):not(.in_container):not(.in_container_hidden)').map(function () {
return $(this).data('id');
});
$.each(op_ids, function (key, op_id) {
visible_op_ids.push(parseInt(op_id));
});
return visible_op_ids;
},
}); // PickingMenuWidget 继承自 MobileWidget
// bind() 方法为被选元素添加一个或多个事件处理程序,并规定事件发生时运行的函数。
extmodule.PickingMenuWidget = extmodule.MobileWidget.extend({
template: 'PickingMenuWidget',
init: function (parent, params) {
this._super(parent, params);
var self = this;
$(window).bind('hashchange', function () {
var states = $.bbq.getState();
if (states.action === "stock.ui") {
self.do_action({
type: 'ir.actions.client',
tag: 'stock.ui',
target: 'current',
}, {
clear_breadcrumbs: true,
});
}
});
this.picking_types = [];
this.loaded = this.load();
this.scanning_type = 0;
// 实例化部件BarcodeScanner
this.barcode_scanner = new extmodule.BarcodeScanner();
this.pickings_by_type = {};
this.pickings_by_id = {};
this.picking_search_string = "";
},
load: function () {
var self = this;
return new instance.web.Model('stock.picking.type').get_func('search_read')([], [])
.then(function (types) {
self.picking_types = types;
type_ids = [];
for (var i = 0; i < types.length; i++) {
self.pickings_by_type[types[i].id] = [];
type_ids.push(types[i].id);
}
self.pickings_by_type[0] = []; return new instance.web.Model('stock.picking').call('search_read', [[['state', 'in', ['assigned', 'partially_available']], ['picking_type_id', 'in', type_ids]], []], {context: new instance.web.CompoundContext()}); }).then(function (pickings) {
self.pickings = pickings;
for (var i = 0; i < pickings.length; i++) {
var picking = pickings[i];
self.pickings_by_type[picking.picking_type_id[0]].push(picking);
self.pickings_by_id[picking.id] = picking;
self.picking_search_string += '' + picking.id + ':' + (picking.name ? picking.name.toUpperCase() : '') + '\n';
} });
},
renderElement: function () {
this._super();
var self = this;
this.$('.js_pick_quit').click(function () {
self.quit();
});
this.$('.js_pick_scan').click(function () {
self.scan_picking($(this).data('id'));
});
this.$('.js_pick_last').click(function () {
self.goto_last_picking_of_type($(this).data('id'));
});
this.$('.oe_searchbox').keyup(function (event) {
self.on_searchbox($(this).val());
});
//remove navigtion bar from default openerp GUI
$('td.navbar').html('<div></div>');
},
start: function () {
this._super();
var self = this;
instance.webclient.set_content_full_screen(true);
this.barcode_scanner.connect(function (barcode) {
self.on_scan(barcode);
});
this.loaded.then(function () {
self.renderElement();
});
},
goto_picking: function (picking_id) {
$.bbq.pushState('#action=stock.ui&picking_id=' + picking_id);
$(window).trigger('hashchange');
},
goto_last_picking_of_type: function (type_id) {
$.bbq.pushState('#action=stock.ui&picking_type_id=' + type_id);
$(window).trigger('hashchange');
},
search_picking: function (barcode) {
try {
var re = RegExp("([0-9]+):.*?" + barcode.toUpperCase(), "gi");
}
catch (e) {
//avoid crash if a not supported char is given (like '\' or ')')
return [];
} var results = [];
for (var i = 0; i < 100; i++) {
r = re.exec(this.picking_search_string);
if (r) {
var picking = this.pickings_by_id[Number(r[1])];
if (picking) {
results.push(picking);
}
} else {
break;
}
}
return results;
},
on_scan: function (barcode) {
var self = this;
for (var i = 0, len = this.pickings.length; i < len; i++) {
var picking = this.pickings[i];
if (picking.name.toUpperCase() === $.trim(barcode.toUpperCase())) {
this.goto_picking(picking.id);
break;
}
}
this.$('.js_picking_not_found').removeClass('hidden'); clearTimeout(this.picking_not_found_timeout);
this.picking_not_found_timeout = setTimeout(function () {
self.$('.js_picking_not_found').addClass('hidden');
}, 2000); },
on_searchbox: function (query) {
var self = this;
clearTimeout(this.searchbox_timeout);
this.searchbox_timout = setTimeout(function () {
if (query) {
self.$('.js_picking_not_found').addClass('hidden');
self.$('.js_picking_categories').addClass('hidden');
self.$('.js_picking_search_results').html(
QWeb.render('PickingSearchResults', {results: self.search_picking(query)})
);
self.$('.js_picking_search_results .oe_picking').click(function () {
self.goto_picking($(this).data('id'));
});
self.$('.js_picking_search_results').removeClass('hidden');
} else {
self.$('.js_title_label').removeClass('hidden');
self.$('.js_picking_categories').removeClass('hidden');
self.$('.js_picking_search_results').addClass('hidden');
}
}, 100);
},
quit: function () {
return new instance.web.Model("ir.model.data").get_func("search_read")([['name', '=', 'action_picking_type_form']], ['res_id']).pipe(function (res) {
window.location = '/web#action=' + res[0]['res_id'];
});
},
destroy: function () {
this._super();
this.barcode_scanner.disconnect();
instance.webclient.set_content_full_screen(false);
},
});
// 把部件注册为客户端的action。当我们点击菜单项时,客户端action让部件显示出来
openerp.web.client_actions.add('stock.menu', 'instance.ext_stock.PickingMenuWidget'); // PickingMainWidget 继承自 MobileWidget
// 'hashchange': 监听浏览器url变化?
// bbq: 返回按钮和查询库
// $.bbq.getState():返回浏览器地址栏参数和值
extmodule.PickingMainWidget = extmodule.MobileWidget.extend({
template: 'PickingMainWidget',
init: function (parent, params) {
this._super(parent, params);
var self = this; $(window).bind('hashchange', function () {
var states = $.bbq.getState();
if (states.action === "stock.menu") {
self.do_action({
type: 'ir.actions.client',
tag: 'stock.menu',
target: 'current',
}, {
clear_breadcrumbs: true,
});
}
});
init_hash = $.bbq.getState();
this.picking_type_id = init_hash.picking_type_id ? init_hash.picking_type_id : 0;
this.picking_id = init_hash.picking_id ? init_hash.picking_id : undefined;
this.picking = null;
this.pickings = [];
this.packoplines = null;
this.selected_operation = {id: null, picking_id: null};
this.packages = null;
this.barcode_scanner = new extmodule.BarcodeScanner();
this.locations = [];
this.uls = [];
if (this.picking_id) {
this.loaded = this.load(this.picking_id);
} else {
this.loaded = this.load();
}
// -----------------------------
this.select_id = null;
this.barcode_scan_bool = false; }, // load the picking data from the server. If picking_id is undefined, it will take the first picking
// belonging to the category
// instance.web.Model('stock.picking'):js创建类(数据表)实例
// .call 调用类(数据表)实例的方法,返回deferred
// .then(): 异步执行, then()前的方法执行完后再执行then()内部的程序,then()有两个参数,那么第一个参数是done()方法的回调函数,第二个参数是fail()方法的回调方法
// CompoundContext这个类用来传递用户上下文(语言,时区等)给服务器
// deferred 是jQuery的回调函数解决方案
// .resolve():手动改变deferred对象的运行状态为"已完成",从而立即触发done()方法
// .reject()将deferred对象的运行状态变为"已失败",从而立即触发fail()方法
load: function (picking_id) {
var self = this; function load_picking_list(type_id) {
var pickings = new $.Deferred();
new instance.web.Model('stock.picking')
.call('get_next_picking_for_ui', [{'default_picking_type_id': parseInt(type_id)}])
.then(function (picking_ids) {
if (!picking_ids || picking_ids.length === 0) {
(new instance.web.Dialog(self, {
title: _t('No Picking Available'),
buttons: [{
text: _t('Ok'),
click: function () {
self.menu();
}
}]
}, _t('<p>We could not find a picking to display.</p>'))).open(); pickings.reject();
} else {
self.pickings = picking_ids;
pickings.resolve(picking_ids);
}
});
return pickings;
} // if we have a specified picking id, we load that one, and we load the picking of the same type as the active list
// 有指定就显示指定picking_id的记录
if (picking_id) {
var loaded_picking = new instance.web.Model('stock.picking')
.call('read', [[parseInt(picking_id)], [], new instance.web.CompoundContext()])
.then(function (picking) {
self.picking = picking[0];
self.picking_type_id = picking[0].picking_type_id[0];
return load_picking_list(self.picking.picking_type_id[0]);
});
} else {
// if we don't have a specified picking id, we load the pickings belong to the specified type, and then we take
// the first one of that list as the active picking
// 没有指定就显示默认第一条picking_id的记录
var loaded_picking = new $.Deferred();
load_picking_list(self.picking_type_id)
.then(function () {
return new instance.web.Model('stock.picking').call('read', [self.pickings[0], [], new instance.web.CompoundContext()]);
})
.then(function (picking) {
self.picking = picking;
self.picking_type_id = picking.picking_type_id[0];
loaded_picking.resolve();
});
} return loaded_picking.then(function () {
if (!_.isEmpty(self.locations)) {
return $.when();
}
return new instance.web.Model('stock.location').call('search', [[['usage', '=', 'internal']]]).then(function (locations_ids) {
return new instance.web.Model('stock.location').call('read', [locations_ids, []]).then(function (locations) {
self.locations = locations;
});
});
}).then(function () {
return new instance.web.Model('stock.picking').call('check_group_pack').then(function (result) {
return self.show_pack = result;
});
}).then(function () {
return new instance.web.Model('stock.picking').call('check_group_lot').then(function (result) {
return self.show_lot = result;
});
}).then(function () {
if (self.picking.pack_operation_exist === false) {
self.picking.recompute_pack_op = false;
return new instance.web.Model('stock.picking').call('do_prepare_partial', [[self.picking.id]]);
}
}).then(function () {
return new instance.web.Model('stock.pack.operation').call('search', [[['picking_id', '=', self.picking.id]]])
}).then(function (pack_op_ids) {
return new instance.web.Model('stock.pack.operation').call('read', [pack_op_ids, [], new instance.web.CompoundContext()])
}).then(function (operations) {
self.packoplines = operations;
var package_ids = []; for (var i = 0; i < operations.length; i++) {
if (!_.contains(package_ids, operations[i].result_package_id[0])) {
if (operations[i].result_package_id[0]) {
package_ids.push(operations[i].result_package_id[0]);
}
}
}
return new instance.web.Model('stock.quant.package').call('read', [package_ids, [], new instance.web.CompoundContext()])
}).then(function (packages) {
self.packages = packages;
}).then(function () {
return new instance.web.Model('product.ul').call('search', [[]])
}).then(function (uls_ids) {
return new instance.web.Model('product.ul').call('read', [uls_ids, []])
}).then(function (uls) {
self.uls = uls;
});
},
start: function () {
this._super();
var self = this;
instance.webclient.set_content_full_screen(true);
this.barcode_scanner.connect(function (ean) {
self.scan(ean);
}); this.$('.js_pick_quit').click(function () {
self.quit();
});
this.$('.js_pick_prev').click(function () {
self.picking_prev();
});
this.$('.js_pick_next').click(function () {
self.picking_next();
});
this.$('.js_pick_menu').click(function () {
self.menu();
});
this.$('.js_reload_op').click(function () {
self.reload_pack_operation();
});
// -----------------------------------------------
$(document).click(function(e) {
self.select_id = $(e.target).attr("id")
}); $.when(this.loaded).done(function () {
// 实例化部件PickingEditorWidget
self.picking_editor = new extmodule.PickingEditorWidget(self);
self.picking_editor.replace(self.$('.oe_placeholder_picking_editor')); if (self.picking.id === self.pickings[0]) {
self.$('.js_pick_prev').addClass('disabled');
} else {
self.$('.js_pick_prev').removeClass('disabled');
} if (self.picking.id === self.pickings[self.pickings.length - 1]) {
self.$('.js_pick_next').addClass('disabled');
} else {
self.$('.js_pick_next').removeClass('disabled');
}
if (self.picking.recompute_pack_op) {
self.$('.oe_reload_op').removeClass('hidden');
}
else {
self.$('.oe_reload_op').addClass('hidden');
}
if (!self.show_pack) {
self.$('.js_pick_pack').addClass('hidden');
}
if (!self.show_lot) {
self.$('.js_create_lot').addClass('hidden');
} }).fail(function (error) {
console.log(error);
}); }, on_searchbox: function (query) {
var self = this;
self.picking_editor.on_searchbox(query.toUpperCase());
},
on_searchbox2: function (query) {
var self = this;
self.picking_editor.on_searchbox2(query.toUpperCase());
},
// reloads the data from the provided picking and refresh the ui.
// (if no picking_id is provided, gets the first picking in the db)
refresh_ui: function (picking_id) {
var self = this;
var remove_search_filter = "";
if (self.picking.id === picking_id) {
remove_search_filter = self.$('.oe_searchbox').val();
}
return this.load(picking_id)
.then(function () {
self.picking_editor.remove_blink();
self.picking_editor.renderElement();
if (!self.show_pack) {
self.$('.js_pick_pack').addClass('hidden');
}
if (!self.show_lot) {
self.$('.js_create_lot').addClass('hidden');
}
if (self.picking.recompute_pack_op) {
self.$('.oe_reload_op').removeClass('hidden');
}
else {
self.$('.oe_reload_op').addClass('hidden');
} if (self.picking.id === self.pickings[0]) {
self.$('.js_pick_prev').addClass('disabled');
} else {
self.$('.js_pick_prev').removeClass('disabled');
} if (self.picking.id === self.pickings[self.pickings.length - 1]) {
self.$('.js_pick_next').addClass('disabled');
} else {
self.$('.js_pick_next').removeClass('disabled');
}
if (remove_search_filter === "") {
self.$('.oe_searchbox').val('');
self.on_searchbox('');
}
else {
self.$('.oe_searchbox').val(remove_search_filter);
self.on_searchbox(remove_search_filter);
} // ------------------------------------
self.$('.oe_searchbox2').val('');
self.on_searchbox2('');
});
},
get_header: function () {
if (this.picking) {
return this.picking.name;
} else {
return '';
}
},
menu: function () {
$.bbq.pushState('#action=stock.menu');
$(window).trigger('hashchange');
},
scan: function (ean) { //scans a barcode, sends it to the server, then reload the ui
var self = this;
var product_visible_ids = this.picking_editor.get_visible_ids(); return new instance.web.Model('stock.picking')
.call('process_barcode_from_ui', [self.picking.id, ean, product_visible_ids])
.then(function (result) { if (result.filter_loc !== false) {
//check if we have receive a location as answer
if (result.filter_loc !== undefined) { var modal_loc_hidden = self.$('#js_LocationChooseModal').attr('aria-hidden');
// var modal_loc_hidden2 = self.$("td[id^='select']").attr('aria-hidden');
if (modal_loc_hidden === "false") {
var line = self.$('#js_LocationChooseModal .js_loc_option[data-loc-id=' + result.filter_loc_id + ']').attr('selected', 'selected');
}
// -----------------------------------------------------
else if (self.select_id != undefined ){
var line = self.$('#' + self.select_id + ' .js_loc_option[data-loc-id=' + result.filter_loc_id + ']').attr('selected', 'selected');
self.$('#'+ self.select_id).change();
}
else {
self.$('.oe_searchbox').val(result.filter_loc);
self.on_searchbox(result.filter_loc);
}
}
} console.log('oe_searchbox2' + self.$('.oe_searchbox2').val()); if (result.operation_id !== false) {
self.refresh_ui(self.picking.id).then(function () {
return self.picking_editor.blink(result.operation_id);
});
}
});
}, scan_product_id: function (product_id, increment, op_id) { //performs the same operation as a scan, but with product id instead
var self = this;
return new instance.web.Model('stock.picking')
.call('process_product_id_from_ui', [self.picking.id, product_id, op_id, increment])
.then(function (result) {
return self.refresh_ui(self.picking.id);
});
},
pack: function () {
var self = this;
var pack_op_ids = self.picking_editor.get_current_op_selection(false);
if (pack_op_ids.length !== 0) {
return new instance.web.Model('stock.picking')
.call('action_pack', [[[self.picking.id]], pack_op_ids])
.then(function (pack) {
//TODO: the functionality using current_package_id in context is not needed anymore
instance.session.user_context.current_package_id = false;
return self.refresh_ui(self.picking.id);
});
}
},
drop_down: function () {
var self = this;
var pack_op_ids = self.picking_editor.get_current_op_selection(true);
if (pack_op_ids.length !== 0) {
return new instance.web.Model('stock.pack.operation')
.call('action_drop_down', [pack_op_ids])
.then(function () {
return self.refresh_ui(self.picking.id).then(function () {
if (self.picking_editor.check_done()) {
return self.done();
}
});
});
}
},
done: function () {
var self = this;
return new instance.web.Model('stock.picking')
.call('action_done_from_ui', [self.picking.id, {'default_picking_type_id': self.picking_type_id}])
.then(function (new_picking_ids) {
if (new_picking_ids) {
return self.refresh_ui(new_picking_ids[0]);
}
else {
return 0;
}
});
},
create_lot: function (op_id, lot_name) {
var self = this;
return new instance.web.Model('stock.pack.operation')
.call('create_and_assign_lot', [parseInt(op_id), lot_name])
.then(function () {
return self.refresh_ui(self.picking.id);
});
},
change_location: function (op_id, loc_id, is_src_dst) {
var self = this;
var vals = {'location_dest_id': loc_id}; if (is_src_dst) {
vals = {'location_id': loc_id};
}
return new instance.web.Model('stock.pack.operation')
.call('write', [op_id, vals])
.then(function () {
return self.refresh_ui(self.picking.id);
});
},
print_package: function (package_id) {
var self = this;
return new instance.web.Model('stock.quant.package')
.call('action_print', [[package_id]])
.then(function (action) {
return self.do_action(action);
});
},
print_picking: function () {
var self = this;
return new instance.web.Model('stock.picking.type').call('read', [[self.picking_type_id], ['code'], new instance.web.CompoundContext()])
.then(function (pick_type) {
return new instance.web.Model('stock.picking').call('do_print_picking', [[self.picking.id]])
.then(function (action) {
return self.do_action(action);
});
});
},
picking_next: function () {
for (var i = 0; i < this.pickings.length; i++) {
if (this.pickings[i] === this.picking.id) {
if (i < this.pickings.length - 1) {
$.bbq.pushState('picking_id=' + this.pickings[i + 1]);
this.refresh_ui(this.pickings[i + 1]);
return;
}
}
}
},
picking_prev: function () {
for (var i = 0; i < this.pickings.length; i++) {
if (this.pickings[i] === this.picking.id) {
if (i > 0) {
$.bbq.pushState('picking_id=' + this.pickings[i - 1]);
this.refresh_ui(this.pickings[i - 1]);
return;
}
}
}
},
delete_package_op: function (pack_id) {
var self = this;
return new instance.web.Model('stock.pack.operation').call('search', [[['result_package_id', '=', pack_id]]])
.then(function (op_ids) {
return new instance.web.Model('stock.pack.operation').call('write', [op_ids, {'result_package_id': false}])
.then(function () {
return self.refresh_ui(self.picking.id);
});
});
},
set_operation_quantity: function (quantity, op_id) {
var self = this;
if (quantity >= 0) {
return new instance.web.Model('stock.pack.operation')
.call('write', [[op_id], {'qty_done': quantity}])
.then(function () {
self.refresh_ui(self.picking.id);
});
} },
set_package_pack: function (package_id, pack) {
var self = this;
return new instance.web.Model('stock.quant.package')
.call('write', [[package_id], {'ul_id': pack}]);
return;
},
reload_pack_operation: function () {
var self = this;
return new instance.web.Model('stock.picking')
.call('do_prepare_partial', [[self.picking.id]])
.then(function () {
self.refresh_ui(self.picking.id);
});
},
quit: function () {
this.destroy();
return new instance.web.Model("ir.model.data").get_func("search_read")([['name', '=', 'action_picking_type_form']], ['res_id']).pipe(function (res) {
window.location = '/web#action=' + res[0]['res_id'];
});
},
destroy: function () {
this._super();
// this.disconnect_numpad();
this.barcode_scanner.disconnect();
instance.webclient.set_content_full_screen(false);
},
});
openerp.web.client_actions.add('stock.ui', 'instance.ext_stock.PickingMainWidget'); extmodule.BarcodeScanner = instance.web.Class.extend({
connect: function (callback) {
var code = "";
var timeStamp = 0;
var timeout = null; this.handler = function (e) { if (e.which === 13) { //ignore returns which 属性指示按了哪个键或按钮
return;
}
if (timeStamp + 50 < new Date().getTime()) {
code = "";
} timeStamp = new Date().getTime(); //getTime() 返回从1970年1月1日至今的毫秒数
clearTimeout(timeout); // setTimeout()和clearTimeout()一起使用,停止计时器 code += String.fromCharCode(e.which); // fromCharCode可接受一个指定的Unicode值,然后返回一个字符串 timeout = setTimeout(function () {
if (code.length >= 3) {
// console.log('callback:>>>>' +callback);
callback(code);
}
code = "";
}, 100);
}; $('body').on('keypress', this.handler);
},
disconnect: function () {
$('body').off('keypress', this.handler);
},
}); } openerp.ext_stock = function (openerp) {
openerp.ext_stock = openerp.ext_stock || {};
openerp_ext_picking_widgets(openerp);
}

  

odoo widgets.js 笔记的更多相关文章

  1. Data Visualization and D3.js 笔记(1)

    课程地址: https://classroom.udacity.com/courses/ud507 什么是数据可视化? 高效传达一个故事/概念,探索数据的pattern 通过颜色.尺寸.形式在视觉上表 ...

  2. js笔记-0

    #js笔记-0 数组: indexOf方法: Array也可以通过indexOf()来搜索一个指定的元素的位置: var arr = [10, 20, '30', 'xyz']; arr.indexO ...

  3. PPK谈JS笔记第一弹

    以下内容是读书笔记,再一次温习JS好书:PPK谈JS window.load=initializePageaddEventSimple('window','load',function(){}) lo ...

  4. 面向小白的JS笔记 - #Codecademy#学习笔记

    前言 最初浏览过<JavaScript秘密花园>,前一段时间读过一点点<JavaScript语言精粹>和一点点<JavaScript高级程序设计>(一点点是指都只是 ...

  5. require.js笔记

    笔记参考来源:阮一峰  http://www.ruanyifeng.com/blog/2012/10/javascript_module.html   1. 浏览器端的模块只能采用“异步加载”方式 = ...

  6. JS笔记 入门第四

    小测试: 注意:取消所有的设定可以直接使用 document.getElementById("txt").removeAttribute("style"); 这 ...

  7. JS笔记 入门第二

    输出内容 document.write(); alert("hello!"); alert(mynum); </script> 注:alert弹出消息对话框(包含一个确 ...

  8. Node.js笔记1

    Node.js入门笔记 1. node -help 可以显示帮助信息2. node REPL 模式(Read-eval-print loop) 输入—求值—输出循环 直接在cmd输入node 可以进入 ...

  9. JS笔记 入门第一

    WHY? 一.你知道,为什么JavaScript非常值得我们学习吗? 1. 所有主流浏览器都支持JavaScript. 2. 目前,全世界大部分网页都使用JavaScript. 3. 它可以让网页呈现 ...

随机推荐

  1. RCC, Reset and Clock Control

  2. VMware Workstation 添加磁盘 挂载目录(centos)

    参考文档: Linux命令大全 需求:测试环境虚拟机某个目录下空间不足,准备通过添加一块磁盘,并将该目录挂载到该磁盘 前面几步在测试服务器上操作的,截图困难,所以网上找了几张设置图 关闭虚拟机(没测试 ...

  3. D3.js的基础部分之数组的处理 集合(Set)(v3版本)

    数组的处理 之 集合(set) 集合(Set)是数学中常用的概念,表示具有某种特定性质的事物的总体.集合里的项叫做元素.集合的相关方法有:   d3.set([array]) //使用数组来构建集合, ...

  4. 初学者学习PHP开发应该掌握的几段精华代码

    来自:http://hi.baidu.com/dckhello/item/d62b16d8994bf93449e1ddb0 经典循环例子 <HTML><HEAD><TIT ...

  5. 【CSP-S/J 2019】初赛注意事项

    UPD:10-25-13:33 正式成绩出了,省里500多名应该进了吧... UPD:10-20-10:07 现在又很慌啊,怎么感觉82又一点都不稳啊... 然后现在又不太想写文化课作业...我是不是 ...

  6. leetcode-第10周双周赛-5079-三个有序数组的交集

    题目描述: 自己的提交: class Solution: def arraysIntersection(self, arr1: List[int], arr2: List[int], arr3: Li ...

  7. 初识Qgis

    折腾了一天,qgis终于能在跟了自己8年的本本上顺利打开了,官网先后下载了3.8和3.4版本的都出现了同样的问题,"could not load qgis_app.dll",goo ...

  8. Jmeter-BeanShell断言:将数据库结果封装成list作为参数

    import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjso ...

  9. thinkphp 字段定义

    通常每个模型类是操作某个数据表,在大多数情况下,系统会自动获取当前数据表的字段信息. 系统会在模型首次实例化的时候自动获取数据表的字段信息(而且只需要一次,以后会永久缓存字段信息,除非设置不缓存或者删 ...

  10. Redis-GEO

    一. Redis的GEO特性 Redis3.2版本提供了GEO功能,支持存储地理位置信息用来实现诸如摇一摇,附近位置这类依赖于地理位置信息的功能.二. 命令2.1 增加地理位置信息 命令:geoadd ...