[WIP]barcode interface: allow to enter qty when highlight one line
bzr revid: csn@openerp.com-20140310165707-72sgol8cwlzlbb85
This commit is contained in:
parent
a2bf8d640c
commit
ca880533ee
|
@ -54,6 +54,42 @@
|
|||
color: #6d2c70;
|
||||
}
|
||||
|
||||
/*Blinking text*/
|
||||
.blink_me {
|
||||
-webkit-animation-name: blinker;
|
||||
-webkit-animation-duration: 1s;
|
||||
-webkit-animation-timing-function: linear;
|
||||
-webkit-animation-iteration-count: infinite;
|
||||
|
||||
-moz-animation-name: blinker;
|
||||
-moz-animation-duration: 1s;
|
||||
-moz-animation-timing-function: linear;
|
||||
-moz-animation-iteration-count: infinite;
|
||||
|
||||
animation-name: blinker;
|
||||
animation-duration: 1s;
|
||||
animation-timing-function: linear;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
|
||||
@-moz-keyframes blinker {
|
||||
0% { opacity: 1.0; }
|
||||
50% { opacity: 0.0; }
|
||||
100% { opacity: 1.0; }
|
||||
}
|
||||
|
||||
@-webkit-keyframes blinker {
|
||||
0% { opacity: 1.0; }
|
||||
50% { opacity: 0.0; }
|
||||
100% { opacity: 1.0; }
|
||||
}
|
||||
|
||||
@keyframes blinker {
|
||||
0% { opacity: 1.0; }
|
||||
50% { opacity: 0.0; }
|
||||
100% { opacity: 1.0; }
|
||||
}
|
||||
|
||||
/*hide OpenERP leftbar, table should use all width by default and display vertical scrollbar if needed*/
|
||||
.oe_leftbar {
|
||||
display: none;
|
||||
|
|
|
@ -64,6 +64,7 @@ function openerp_picking_widgets(instance){
|
|||
renderElement: function(){
|
||||
var self = this;
|
||||
this._super();
|
||||
this.disconnect_numpad();
|
||||
this.$('.js_pack_scan').click(function(){
|
||||
var id = parseInt($(this).attr('op-id'));
|
||||
self.getParent().scan_product_id(id);
|
||||
|
@ -75,10 +76,30 @@ function openerp_picking_widgets(instance){
|
|||
else{
|
||||
$(this).addClass('warning');
|
||||
}
|
||||
self.check_change_quantity();
|
||||
});
|
||||
//remove navigtion bar from default openerp GUI
|
||||
$('td.navbar').html('<div></div>');
|
||||
},
|
||||
check_change_quantity: function(){
|
||||
var self = this;
|
||||
if (this.$('.js_pack_op_line.warning:not(.hidden)').length === 1){
|
||||
cur_id = this.$('.js_pack_op_line.warning:not(.hidden)')[0].attributes.getNamedItem('data-id').value;
|
||||
op_id = parseInt(cur_id);
|
||||
this.$('.js_pack_op_line:not(.hidden)[data-id='+op_id+'] > .js_row_qty').addClass('blink_me');
|
||||
var value = [0,0]
|
||||
_.each(this.rows, function(row){
|
||||
if (row.cols.id === op_id){
|
||||
value = [row.cols.rem, row.cols.qty, row.cols.uom];
|
||||
}
|
||||
});
|
||||
this.connect_numpad(value, op_id);
|
||||
}
|
||||
else{
|
||||
this.disconnect_numpad();
|
||||
this.$('.js_row_qty.blink_me').removeClass('blink_me');
|
||||
}
|
||||
},
|
||||
on_searchbox: function(query){
|
||||
//hide line that has no location matching the query and highlight location that match the query
|
||||
if (query !== '') {
|
||||
|
@ -98,14 +119,12 @@ function openerp_picking_widgets(instance){
|
|||
//get ids of visible on the screen
|
||||
pack_op_ids = []
|
||||
if (this.$('.js_pack_op_line.warning:not(.js_pack_op_line.hidden)').length > 0){
|
||||
console.log('some selected');
|
||||
this.$('.js_pack_op_line.warning:not(.js_pack_op_line.hidden)').each(function(){
|
||||
cur_id = this.attributes.getNamedItem('data-id').value;
|
||||
pack_op_ids.push(parseInt(cur_id));
|
||||
});
|
||||
}
|
||||
else{
|
||||
console.log('nothing selected');
|
||||
this.$('.js_pack_op_line:not(.js_pack_op_line.hidden)').each(function(){
|
||||
cur_id = this.attributes.getNamedItem('data-id').value;
|
||||
pack_op_ids.push(parseInt(cur_id));
|
||||
|
@ -120,7 +139,58 @@ function openerp_picking_widgets(instance){
|
|||
});
|
||||
//return only those visible with rem qty > 0 and container empty
|
||||
return _.intersection(pack_op_ids, list);
|
||||
}
|
||||
},
|
||||
unhighlight: function(){
|
||||
this.$('.js_pack_op_line.warning').removeClass('warning');
|
||||
this.$('.js_row_qty.blink_me').removeClass('blink_me');
|
||||
},
|
||||
connect_numpad: function(value, op_id){
|
||||
var self = this;
|
||||
var numpad = [];
|
||||
var numpad_timestamp;
|
||||
var processed = value[0];
|
||||
var total = value[1];
|
||||
var uom = '';
|
||||
if (value[2] !== undefined){ uom = value[2]; }
|
||||
|
||||
this.refresh = function(){
|
||||
if (numpad.length === 0){
|
||||
self.$('.js_row_qty.blink_me').text(processed + ' / ' + total + ' ' + uom);
|
||||
}
|
||||
else {
|
||||
self.$('.js_row_qty.blink_me').text(parseInt(numpad.join('')) + ' / ' + total + ' ' + uom);
|
||||
}
|
||||
}
|
||||
|
||||
this.numpad_handler = function(e){
|
||||
console.log(e.keyCode);
|
||||
if(numpad_timestamp + 1500 < new Date().getTime()){
|
||||
numpad = [];
|
||||
}
|
||||
if(e.keyCode === 27){ // ESC
|
||||
numpad = [];
|
||||
}
|
||||
else if(e.keyCode === 8){ // BACKSPACE
|
||||
numpad.pop();
|
||||
}else if(e.keyCode >= 48 && e.keyCode <= 57){ // NUMPAD NUMBERS
|
||||
numpad.push(e.keyCode - 48);
|
||||
}else if(e.keyCode === 13){ // ENTER
|
||||
self.unhighlight();
|
||||
self.disconnect_numpad();
|
||||
if(numpad.length > 0){
|
||||
self.getParent().set_operation_quantity(parseInt(numpad.join('')), op_id);
|
||||
}
|
||||
// numpad = [];
|
||||
}
|
||||
self.refresh();
|
||||
numpad_timestamp = new Date().getTime();
|
||||
};
|
||||
$('body').on('keydown', this.numpad_handler);
|
||||
},
|
||||
disconnect_numpad: function(){
|
||||
jQuery.event.trigger({ type : 'keydown', which : 27 });
|
||||
$('body').off('keydown', this.numpad_handler);
|
||||
},
|
||||
});
|
||||
|
||||
// module.PackageEditorWidget = instance.web.Widget.extend({
|
||||
|
@ -462,7 +532,7 @@ function openerp_picking_widgets(instance){
|
|||
this._super();
|
||||
var self = this;
|
||||
instance.webclient.set_content_full_screen(true);
|
||||
this.connect_numpad();
|
||||
// this.connect_numpad();
|
||||
this.barcode_scanner.connect(function(ean){
|
||||
self.scan(ean);
|
||||
});
|
||||
|
@ -574,19 +644,16 @@ function openerp_picking_widgets(instance){
|
|||
new instance.web.Model('stock.picking')
|
||||
.call('process_barcode_from_ui', [self.picking.id, ean])
|
||||
.then(function(result){
|
||||
if (typeof(result)!="boolean"){
|
||||
if (result.filter_loc !== false){
|
||||
//check if we have receive a location as answer
|
||||
if (result.filter_loc !== undefined){
|
||||
self.$('.oe_searchbox').val(result.filter_loc);
|
||||
self.on_searchbox(result.filter_loc);
|
||||
}
|
||||
}
|
||||
else{
|
||||
console.log(result.operation_id);
|
||||
if (result.operation_id !== false){
|
||||
return self.refresh_ui(self.picking.id);
|
||||
//TODO add a then to highlight the line that was scanned, do same to scan_product_id
|
||||
// .then(function(product_id){
|
||||
// self.
|
||||
// });
|
||||
}
|
||||
});
|
||||
},
|
||||
|
@ -594,7 +661,7 @@ function openerp_picking_widgets(instance){
|
|||
var self = this;
|
||||
new instance.web.Model('stock.picking')
|
||||
.call('process_product_id_from_ui', [self.picking.id, product_id])
|
||||
.then(function(){
|
||||
.then(function(result){
|
||||
return self.refresh_ui(self.picking.id);
|
||||
});
|
||||
},
|
||||
|
@ -740,53 +807,64 @@ function openerp_picking_widgets(instance){
|
|||
return null;
|
||||
}
|
||||
},
|
||||
set_operation_quantity: function(quantity){
|
||||
set_operation_quantity: function(quantity, op_id){
|
||||
var self = this;
|
||||
var op = this.get_selected_operation();
|
||||
if( !op ){
|
||||
//TODO typing the ean of a product manually ?
|
||||
//(scanning the barcode is already handled somewhere else, and i don't know how to differenciate the 2 operations)
|
||||
// and the result is that if i uncomment the next line, scanning a product counts it twice
|
||||
//self.scan(quantity);
|
||||
}
|
||||
|
||||
else {if(typeof quantity === 'number' && quantity >= 0){
|
||||
if(quantity >= 0){
|
||||
new instance.web.Model('stock.pack.operation')
|
||||
.call('write',[[op],{'product_qty': quantity }])
|
||||
.call('write',[[op_id],{'qty_done': quantity }])
|
||||
.then(function(){
|
||||
self.refresh_ui(self.picking.id);
|
||||
});
|
||||
}}
|
||||
}
|
||||
|
||||
},
|
||||
connect_numpad: function(){
|
||||
var self = this;
|
||||
var numpad = [];
|
||||
var numpad_timestamp;
|
||||
// set_operation_quantity: function(quantity){
|
||||
// var self = this;
|
||||
// var op = this.get_selected_operation();
|
||||
// if( !op ){
|
||||
// //TODO typing the ean of a product manually ?
|
||||
// //(scanning the barcode is already handled somewhere else, and i don't know how to differenciate the 2 operations)
|
||||
// // and the result is that if i uncomment the next line, scanning a product counts it twice
|
||||
// //self.scan(quantity);
|
||||
// }
|
||||
|
||||
// else {if(typeof quantity === 'number' && quantity >= 0){
|
||||
// new instance.web.Model('stock.pack.operation')
|
||||
// .call('write',[[op],{'product_qty': quantity }])
|
||||
// .then(function(){
|
||||
// self.refresh_ui(self.picking.id);
|
||||
// });
|
||||
// }}
|
||||
|
||||
// },
|
||||
// connect_numpad: function(){
|
||||
// var self = this;
|
||||
// var numpad = [];
|
||||
// var numpad_timestamp;
|
||||
|
||||
this.numpad_handler = function(e){
|
||||
if(numpad_timestamp + 1500 < new Date().getTime()){
|
||||
numpad = [];
|
||||
}
|
||||
if(e.keyCode === 27 || e.keyCode === 8){ // ESC or BACKSPACE
|
||||
numpad = [];
|
||||
}else if(e.keyCode >= 48 && e.keyCode <= 57){ // NUMPAD NUMBERS
|
||||
numpad.push(e.keyCode - 48);
|
||||
}else if(e.keyCode === 13){ // ENTER
|
||||
if(numpad.length > 0){
|
||||
self.set_operation_quantity(parseInt(numpad.join('')));
|
||||
}
|
||||
numpad = [];
|
||||
}else{
|
||||
numpad = [];
|
||||
}
|
||||
numpad_timestamp = new Date().getTime();
|
||||
};
|
||||
$('body').on('keypress', this.numpad_handler);
|
||||
},
|
||||
disconnect_numpad: function(){
|
||||
$('body').off('keypress', this.numpad_handler);
|
||||
},
|
||||
// this.numpad_handler = function(e){
|
||||
// if(numpad_timestamp + 1500 < new Date().getTime()){
|
||||
// numpad = [];
|
||||
// }
|
||||
// if(e.keyCode === 27 || e.keyCode === 8){ // ESC or BACKSPACE
|
||||
// numpad = [];
|
||||
// }else if(e.keyCode >= 48 && e.keyCode <= 57){ // NUMPAD NUMBERS
|
||||
// numpad.push(e.keyCode - 48);
|
||||
// }else if(e.keyCode === 13){ // ENTER
|
||||
// if(numpad.length > 0){
|
||||
// self.set_operation_quantity(parseInt(numpad.join('')));
|
||||
// }
|
||||
// numpad = [];
|
||||
// }else{
|
||||
// numpad = [];
|
||||
// }
|
||||
// numpad_timestamp = new Date().getTime();
|
||||
// };
|
||||
// $('body').on('keypress', this.numpad_handler);
|
||||
// },
|
||||
// disconnect_numpad: function(){
|
||||
// $('body').off('keypress', this.numpad_handler);
|
||||
// },
|
||||
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) {
|
||||
|
@ -795,7 +873,7 @@ function openerp_picking_widgets(instance){
|
|||
},
|
||||
destroy: function(){
|
||||
this._super();
|
||||
this.disconnect_numpad();
|
||||
// this.disconnect_numpad();
|
||||
this.barcode_scanner.disconnect();
|
||||
$('body').off('keyup',this.hotkey_handler);
|
||||
instance.webclient.set_content_full_screen(false);
|
||||
|
|
|
@ -51,13 +51,14 @@
|
|||
<h2><strong><div class='oe_pick_list_header'>
|
||||
Operations Informations
|
||||
</div></strong></h2>
|
||||
<table class='table table-condensed'>
|
||||
<table class='table table-condensed js_op_table_todo'>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center">Product</th>
|
||||
<th class='text-center'>Quantity</th>
|
||||
<th>From</th>
|
||||
<th>To</th>
|
||||
<th>Container</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
|
@ -65,12 +66,13 @@
|
|||
<t t-foreach="widget.get_rows()" t-as="row">
|
||||
<tr t-att-class="row.classes + ' js_pack_op_line'" t-att-data-id="row.cols.id">
|
||||
<td class="text-center"> <span class='btn btn-default pull-left js_pack_scan' t-att-op-id='row.cols.product_id'>➔</span> <t t-esc="row.cols.product" /> </td>
|
||||
<td class='text-center'><t t-esc="row.cols.rem" /> / <t t-esc="row.cols.qty" /> <t t-esc="row.cols.uom" /></td>
|
||||
<td class='text-center js_row_qty'><t t-esc="row.cols.rem" /> / <t t-esc="row.cols.qty" /> <t t-esc="row.cols.uom" /></td>
|
||||
<td class="js_loc"> <t t-esc="row.cols.loc" />
|
||||
<t t-if="row.cols.lot" ><span> : <t t-esc="row.cols.lot" /></span></t>
|
||||
<t t-if="row.cols.pack" ><span> : <t t-esc="row.cols.pack" /></span></t>
|
||||
<t t-if="row.cols.lot" ><span> : <t t-esc="row.cols.lot" /></span></t>
|
||||
</td>
|
||||
<td class="js_loc"> <t t-esc="row.cols.dest" /> </td>
|
||||
<td class=""><t t-esc="row.cols.container"></t></td>
|
||||
</tr>
|
||||
</t>
|
||||
</tbody>
|
||||
|
|
|
@ -1263,29 +1263,35 @@ class stock_picking(osv.osv):
|
|||
product_obj = self.pool.get('product.product')
|
||||
stock_operation_obj = self.pool.get('stock.pack.operation')
|
||||
stock_location_obj = self.pool.get('stock.location')
|
||||
answer = {'filter_loc': False, 'operation_id': False}
|
||||
#check if the barcode correspond to a location
|
||||
matching_location_ids = stock_location_obj.search(cr, uid, [('loc_barcode', '=', barcode_str)], context=context)
|
||||
if matching_location_ids:
|
||||
#if we have a location, return immediatly with the location name
|
||||
location = stock_location_obj.browse(cr, uid, matching_location_ids[0], context=None)
|
||||
return {'filter_loc': stock_location_obj._name_get(cr, uid, location, context=None)}
|
||||
answer['filter_loc'] = stock_location_obj._name_get(cr, uid, location, context=None)
|
||||
return answer
|
||||
# return {'filter_loc': stock_location_obj._name_get(cr, uid, location, context=None)}
|
||||
#check if the barcode correspond to a product
|
||||
matching_product_ids = product_obj.search(cr, uid, ['|', ('ean13', '=', barcode_str), ('default_code', '=', barcode_str)], context=context)
|
||||
if matching_product_ids:
|
||||
self.process_product_id_from_ui(cr, uid, picking_id, matching_product_ids[0], context=context)
|
||||
|
||||
op_id = self.process_product_id_from_ui(cr, uid, picking_id, matching_product_ids[0], context=context)
|
||||
answer['operation_id'] = op_id
|
||||
return answer
|
||||
#check if the barcode correspond to a lot
|
||||
matching_lot_ids = lot_obj.search(cr, uid, [('name', '=', barcode_str)], context=context)
|
||||
if matching_lot_ids:
|
||||
lot = lot_obj.browse(cr, uid, matching_lot_ids[0], context=context)
|
||||
stock_operation_obj._search_and_increment(cr, uid, picking_id, [('product_id', '=', lot.product_id.id), ('lot_id', '=', lot.id)], context=context)
|
||||
|
||||
op_id = stock_operation_obj._search_and_increment(cr, uid, picking_id, [('product_id', '=', lot.product_id.id), ('lot_id', '=', lot.id)], context=context)
|
||||
answer['operation_id'] = op_id
|
||||
return answer
|
||||
#check if the barcode correspond to a package
|
||||
matching_package_ids = package_obj.search(cr, uid, [('name', '=', barcode_str)], context=context)
|
||||
if matching_package_ids:
|
||||
stock_operation_obj._search_and_increment(cr, uid, picking_id, [('package_id', '=', matching_package_ids[0])], context=context)
|
||||
|
||||
return False
|
||||
op_id = stock_operation_obj._search_and_increment(cr, uid, picking_id, [('package_id', '=', matching_package_ids[0])], context=context)
|
||||
answer['operation_id'] = op_id
|
||||
return answer
|
||||
return answer
|
||||
|
||||
class stock_production_lot(osv.osv):
|
||||
_name = 'stock.production.lot'
|
||||
|
@ -3688,7 +3694,7 @@ class stock_pack_operation(osv.osv):
|
|||
update_dict['product_uom_id'] = uom_id
|
||||
values.update(update_dict)
|
||||
operation_id = self.create(cr, uid, values, context=context)
|
||||
return True
|
||||
return operation_id
|
||||
|
||||
|
||||
class stock_move_operation_link(osv.osv):
|
||||
|
|
Loading…
Reference in New Issue