[FIX]stock_barcode_interface: rework of the barcode interface to use bootstrap only

bzr revid: csn@openerp.com-20140226161003-kzgg5xfcrn8ucspx
This commit is contained in:
Cedric Snauwaert 2014-02-26 17:10:03 +01:00
parent 7b17e234e6
commit 8e779fa761
10 changed files with 357 additions and 454 deletions

View File

@ -27,3 +27,5 @@ import report
import wizard
import res_config
import controllers

View File

@ -103,7 +103,6 @@ Dashboard / Reports for Warehouse Management will include:
'application': True,
'auto_install': False,
'css': [
'static/src/css/picking.css',
'static/src/css/stock.css',
],
'js': [

View File

@ -0,0 +1 @@
import main

View File

@ -0,0 +1,80 @@
# -*- coding: utf-8 -*-
import logging
import simplejson
import os
import openerp
import time
import random
from openerp import http
from openerp.http import request
from openerp.addons.web.controllers.main import manifest_list, module_boot, html_template
_logger = logging.getLogger(__name__)
html_template = """<!DOCTYPE html>
<html>
<head>
<title>Barcode Scanner</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
<meta http-equiv="content-type" content="text/html, charset=utf-8" />
<meta name="viewport" content=" width=1024, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="mobile-web-app-capable" content="yes">
<link rel="shortcut icon" sizes="80x51" href="/stock/static/src/img/scan.png">
<link rel="shortcut icon" href="/web/static/src/img/favicon.ico" type="image/x-icon"/>
<link rel="stylesheet" href="/stock/static/src/css/barcode.css" />
<link rel="stylesheet" href="/web/static/lib/bootstrap/css/bootstrap.css" />
%(js)s
<script type="text/javascript">
$(function() {
var s = new openerp.init(%(modules)s);
%(init)s
});
</script>
</head>
<body>
<!--[if lte IE 8]>
<script src="//ajax.googleapis.com/ajax/libs/chrome-frame/1/CFInstall.min.js"></script>
<script>CFInstall.check({mode: "overlay"});</script>
<![endif]-->
</body>
</html>
"""
class BarcodeController(http.Controller):
@http.route('/barcode/web/<int:page>', type='http', auth='none')
def a(self, debug=False, **k):
if not request.session.uid:
return http.local_redirect('/web/login?redirect=/barcode/web')
js_list = manifest_list('js',db=request.db, debug=debug)
css_list = manifest_list('css',db=request.db, debug=debug)
#get request path
url_picking_type_id = request.httprequest.path[len('/barcode/web/'):]
try:
active_id = int(url_picking_type_id)
except Exception:
active_id = 0
js = "\n".join('<script type="text/javascript" src="%s"></script>' % i for i in js_list)
#css = "\n".join('<link rel="stylesheet" href="%s">' % i for i in css_list)
r = html_template % {
'js': js,
# 'css': css,
'modules': simplejson.dumps(module_boot(request.db)),
'init': """
var wc = new s.web.WebClient();
wc.show_application = function(){
wc.action_manager.do_action("stock.ui", {additional_context: {'active_id': %s}});
};
wc.appendTo($(document.body));
""" % active_id
}
return r

View File

@ -0,0 +1,118 @@
/*hide OpenERP leftbar, table should use all width by default and display vertical scrollbar if needed*/
.oe_leftbar {
display: none;
}
table.oe_webclient.oe_content_full_screen{
width: 100%;
}
body{
overflow-y: visible !important;
}
/* --- Styling of OpenERP Elements ---
Needed for loading and error box */
/* Increase z-index value to insure that loading goes above navbar of bootstrap*/
.openerp .oe_loading {
display: none;
z-index: 1000;
position: fixed;
top: 0;
right: 50%;
padding: 4px 12px;
background: #a61300;
color: white;
text-align: center;
border: 1px solid #990000;
border-top: none;
-moz-border-radius-bottomright: 8px;
-moz-border-radius-bottomleft: 8px;
border-bottom-right-radius: 8px;
border-bottom-left-radius: 8px;
}
.openerp.ui-dialog {
display: none;
height: auto !important;
padding: 6px;
background-color: rgba(60, 60, 60, 0.7);
border: 1px solid;
border-color: #888888 #555555 #444444;
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
border-radius: 8px;
-moz-box-shadow: 0 1px 12px rgba(0, 0, 0, 0.6);
-webkit-box-shadow: 0 1px 12px rgba(0, 0, 0, 0.6);
box-shadow: 0 1px 12px rgba(0, 0, 0, 0.6);
-webkit-background-clip: padding-box;
-moz-background-clip: padding-box;
background-clip: padding-box;
}
.openerp.ui-dialog .ui-dialog-content {
padding: 0;
}
.openerp.ui-dialog .ui-dialog-titlebar, .openerp.ui-dialog .ui-dialog-content, .openerp.ui-dialog .ui-dialog-buttonpane {
padding: 16px;
}
.openerp.ui-dialog .ui-dialog-titlebar {
border-top: none;
border-left: none;
border-right: none;
border-bottom: 1px solid #cacaca;
-moz-border-radius: 2px 2px 0 0;
-webkit-border-radius: 2px 2px 0 0;
border-radius: 2px 2px 0 0;
background-color: #ededed;
background-image: -webkit-gradient(linear, left top, left bottom, from(#fcfcfc), to(#dedede));
background-image: -webkit-linear-gradient(top, #fcfcfc, #dedede);
background-image: -moz-linear-gradient(top, #fcfcfc, #dedede);
background-image: -ms-linear-gradient(top, #fcfcfc, #dedede);
background-image: -o-linear-gradient(top, #fcfcfc, #dedede);
background-image: linear-gradient(to bottom, #fcfcfc, #dedede);
}
.openerp.ui-dialog .ui-dialog-titlebar .ui-dialog-title {
margin: 0;
padding: 0;
}
.openerp.ui-dialog .ui-dialog-content {
background: white;
width: auto !important;
}
.openerp.ui-dialog .ui-dialog-buttonpane {
border-top: 1px solid #e0e0e0;
background: #f5f7f9;
margin: 0;
-moz-border-radius: 0 0 2px 2px;
-webkit-border-radius: 0 0 2px 2px;
border-radius: 0 0 2px 2px;
}
.openerp.ui-dialog .ui-dialog-buttonpane button {
margin: 0 4px 0 0;
}
.openerp.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
float: left;
}
.openerp.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset .ui-button {
margin-right: 4px;
}
.openerp.ui-dialog .ui-dialog-titlebar-close {
display: none;
}
.openerp.ui-dialog .ui-dialog-titlebar-close:before {
content: "×";
font-size: 18px;
font-weight: bold;
line-height: 16px;
color: black;
text-shadow: 0 1px 0 white;
padding: 0;
cursor: pointer;
background: transparent;
border: 0;
}
.openerp.ui-dialog .ui-dialog-titlebar-close:before:hover {
color: black;
text-decoration: none;
}

View File

@ -1,291 +0,0 @@
/* ----------------------- *
* PICKING WIDGET LAYOUT *
* ----------------------- */
.oe_pick_widget {
position: absolute;
top: 0px; right: 0px; bottom: 0px; left: 0px;
color: #444444;
background: #686868;
text-shadow: none;
font-family: 'Lato', 'Open Sans', Arial, Helvetica, sans-serif;
}
.oe_pick_widget .oe_pick_layout {
width: 100%;
height: 100%;
}
.oe_pick_widget .oe_hidden{
display: none !important;
}
.oe_pick_widget .oe_pick_header{
background: #454343;
background-image: linear-gradient(#646060,#262626);
}
.oe_pick_widget .oe_pick_body_cont{
height: 100%;
}
.oe_pick_widget .oe_pick_body{
width: 100%;
height: 100%;
background-color: white;
background: url('/web/static/src/img/form_sheetbg.png');
box-shadow: 0px 9px 5px -5px rgba(0, 0, 0, 0.16) inset;
overflow: hidden;
overflow-y: auto;
}
.oe_pick_widget .oe_pick_app{
width: 600px;
background: white;
margin: 40px auto;
padding: 20px;
border: solid 1px rgb(228, 228, 255);
box-shadow: 0px 2px 3px rgba(114, 114, 175, 0.11);
}
.oe_pick_widget .oe_pick_toolbar{
width: 600px;
margin: auto;
text-align: center;
}
.oe_pick_widget .oe_pick_button{
display: inline-block;
min-width: 64px;
padding: 5px 10px;
font-size: 18px;
border-radius: 3px;
margin: 10px 5px;
text-align: center;
line-height: 30px;
background: #b2b3d7;
background: linear-gradient(#b2b3d7, #7f82ac);
color: #273072;
border: 1px solid #353A7E;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 1px rgba(255, 255, 255, 0.8) inset;
cursor: pointer;
text-shadow: 0 1px 1px rgba(255, 255, 255, 0.5);
}
.oe_pick_widget .oe_pick_button.oe_disabled {
cursor: default;
background-color: #5A5A5A;
background: linear-gradient(#666666, #474747);
border: solid 1px rgb(44, 44, 44);
color: rgb(53, 53, 53);
box-shadow: 0px 1px 1px rgba(255, 255, 255, 0.32) inset;
}
.oe_pick_widget .oe_pick_button:not(.oe_disabled):active,
.oe_pick_widget .oe_pick_button:not(.oe_disabled).oe_active{
background: rgb(92, 84, 133);
box-shadow: 0px 1px 0px 1px rgba(0,0,0,0.3) inset;
margin: 11px 6px;
border: none;
color: white;
text-shadow: 0px 1px rgba(0,0,0, 0.3);
}
.oe_pick_widget .oe_pick_button.oe_small{
min-width: 0px;
width: 32px;
}
.oe_pick_widget .oe_pick_right_toolbar{
float: right;
border-left: solid 1px rgba(0,0,0,0.3);
padding-left: 8px;
padding-right: 8px;
margin-left: 8px;
}
.oe_pick_widget .oe_pick_col_small{ width: 60px; }
.oe_pick_widget .oe_pick_col_medium{ width: 100px; }
.oe_pick_widget .oe_pick_col_big{ width: 200px; }
.oe_pick_widget .oe_pick_col_expand{ width: 100%; }
.oe_pick_widget .oe_centeralign{ text-align: center; }
.oe_pick_widget .oe_invalid{
background: rgb(255, 226, 226);
color: rgb(168, 6, 6);
}
.oe_pick_widget .oe_pick_app_header{
font-size: 24px;
margin-left: 5px;
margin-bottom: 10px;
}
.oe_pick_widget .oe_pick_app_title{
font-size: 20px;
margin-top: 0px;
}
.oe_pick_widget .oe_pick_app_subtitle{
font-size: 16px;
font-weight: normal;
}
.oe_pick_widget .oe_pick_app_info{
margin-left: 4px;
opacity: 0.5;
}
/* ----------------------- *
* PICKING TABLES *
* ----------------------- */
.oe_pick_widget .oe_pick_list{
margin: 0px 0px 20px 0px;
padding: 5px;
}
.oe_pick_widget .oe_pick_list_header{
font-size: 20px;
margin-bottom: 5px;
}
.oe_pick_widget .oe_pick_list_table{
background: whitesmoke;
width: 100%;
table-layout: fixed;
font-size: 16px;
border-radius: 3px;
}
.oe_pick_widget .oe_pick_list_table tbody tr:nth-child(odd){
background: rgb(250,250,250);
}
.oe_pick_widget .oe_pick_list_table tbody tr.oe_selected{
background: rgb(236, 236, 247);
outline: solid 1px rgba(79, 107, 255, 0.25);
}
.oe_pick_widget .oe_pick_list_table td,
.oe_pick_widget .oe_pick_list_table th {
padding: 5px;
overflow: hidden;
text-overflow: ellipsis;
}
.oe_pick_widget .oe_pick_list_table thead{
background: rgb(224, 225, 235);
border-top-left-radius: 3px;
border-top-right-radius: 3px;
}
.oe_pick_widget .oe_pick_list_table th {
background: none;
border: none;
font-weight: bold;
}
.oe_pick_widget .oe_row_button{
display: inline-block;
background: rgb(238, 237, 248);
padding: 2px 4px;
line-height: 14px;
color: rgb(137, 127, 173);
border-radius: 3px;
border: solid 1px rgba(0, 0, 0, 0.09);
cursor: pointer;
}
.oe_pick_widget .oe_expanded{
text-align: center;
min-width: 32px;
}
.oe_pick_widget .js_pack_select,
.oe_pick_widget .js_pack_op{
cursor: pointer;
}
/* ----------------------- *
* MAIN PICKING MENU *
* ----------------------- */
.oe_pick_widget .oe_picking{
background: rgb(223, 226, 246);
padding: 10px;
margin-bottom: 3px;
border-radius: 3px;
border-bottom: solid 2px rgb(189, 189, 241);
cursor: pointer;
}
.oe_pick_widget .oe_picking.oe_empty {
border: solid 1px rgb(228, 226, 241);
background: white;
cursor: default;
}
.oe_pick_widget .oe_picking > .oe_picking_name{
display: inline-block;
min-width: 100px;
margin-right: 10px;
}
.oe_pick_widget .oe_search_empty{
padding: 10px;
border-radius: 3px;
background: rgb(228, 226, 241);
text-align: center;
}
/* ----------------------- *
* SEARCH BOX *
* ----------------------- */
.oe_pick_widget .oe_searchbox{
margin-top: 13px;
}
.oe_pick_widget .oe_searchbox input{
padding: 8px;
}
.oe_pick_widget .oe_picking_not_found{
padding: 8px;
margin: 24px 0px;
text-align: center;
background: rgb(239, 240, 247);
border-radius: 3px;
color: rgb(119, 77, 77);
}
/* ----------------------- *
* RESPONSIVENESS *
* ----------------------- */
@media screen and (max-width:642px){
.oe_pick_widget .oe_pick_body{
background: white;
background-image: none;
box-shadow: none;
}
.oe_pick_widget .oe_pick_app{
width: auto;
max-width: 600px;
margin: 0 auto;
border: none;
box-shadow: none;
padding-left: 5px;
padding-right: 5px;
}
.oe_pick_widget .oe_pick_toolbar{
width: auto;
}
.oe_pick_widget .oe_pick_right_toolbar{
float: none;
text-align: center;
border-left: none;
margin-left: 0px;
}
.oe_pick_widget .oe_pick_button{
margin-top: 3px;
margin-bottom: 3px;
}
}
@media screen and (max-width:450px){
.oe_pick_widget .oe_pick_list_header{
font-size: 16px;
}
.oe_pick_widget .oe_pick_list_table{
font-size: 12px;
}
.oe_pick_widget .oe_pick_col_small{
width: 50px;
}
}
@media screen and (max-width:326px){
.oe_pick_widget .oe_pick_toolbar{
width: 326px;
}
}

View File

@ -40,7 +40,7 @@ function openerp_picking_widgets(instance){
loc: moveline.location_id[1],
id: moveline.product_id[0],
},
classes: (moveline.qty_remaining < 0 ? 'oe_invalid' : '')
classes: (moveline.qty_remaining < 0 ? 'danger' : '')
});
});
@ -78,7 +78,7 @@ function openerp_picking_widgets(instance){
uom: op.product_uom ? product_uom[1] : '',
qty: op.product_qty,
},
classes: 'js_pack_op '+ (op.id === model.get_selected_operation() ? 'oe_selected' : ''),
classes: 'js_pack_op '+ (op.id === model.get_selected_operation() ? 'warning' : ''),
att_op_id: op.id,
});
});
@ -90,12 +90,12 @@ function openerp_picking_widgets(instance){
this._super();
var model = this.getParent();
this.$('.js_pack_op').click(function(){
if (!this.classList.contains('oe_selected')){
self.$('.js_pack_op').removeClass('oe_selected');
$(this).addClass('oe_selected');
if (!this.classList.contains('warning')){
self.$('.js_pack_op').removeClass('warning');
$(this).addClass('warning');
model.set_selected_operation(parseInt($(this).attr('op-id')));
} else {
$(this).removeClass('oe_selected');
$(this).removeClass('warning');
model.set_selected_operation(null);
};
});
@ -115,7 +115,7 @@ function openerp_picking_widgets(instance){
rows.push({
cols:{ pack: pack.name},
id: pack.id,
classes: pack === current_package ? ' oe_selected' : '' ,
classes: pack === current_package ? ' warning' : '' ,
});
});
return rows;
@ -127,7 +127,11 @@ function openerp_picking_widgets(instance){
var pack_id = parseInt($(this).attr('pack-id'));
$('.js_pack_print', this).click(function(){ model.print_package(pack_id); });
$('.js_pack_plus', this).click(function(){ model.copy_package_op(pack_id); });
$('.js_pack_minus', this).click(function(){ model.delete_package_op(pack_id); });
$('.js_pack_minus', this).click(function(){
if(model.get_selected_package() && model.get_selected_package().id === pack_id){
model.deselect_package();
}
model.delete_package_op(pack_id); });
$('.js_pack_select', this).click(function(){
if(model.get_selected_package() && model.get_selected_package().id === pack_id){
model.deselect_package();
@ -185,7 +189,7 @@ function openerp_picking_widgets(instance){
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 input').keyup(function(event){
this.$('.oe_searchbox').keyup(function(event){
self.on_searchbox($(this).val());
});
//remove navigtion bar from default openerp GUI
@ -194,6 +198,7 @@ function openerp_picking_widgets(instance){
start: function(){
this._super();
var self = this;
instance.webclient.set_content_full_screen(true);
this.barcode_scanner.connect(function(barcode){
self.on_scan(barcode);
});
@ -240,7 +245,6 @@ function openerp_picking_widgets(instance){
},
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())){
@ -248,11 +252,11 @@ function openerp_picking_widgets(instance){
break;
}
}
this.$('.oe_picking_not_found').removeClass('oe_hidden');
this.$('.oe_picking_not_found').removeClass('hidden');
clearTimeout(this.picking_not_found_timeout);
this.picking_not_found_timeout = setTimeout(function(){
self.$('.oe_picking_not_found').addClass('oe_hidden');
self.$('.oe_picking_not_found').addClass('hidden');
},2000);
},
@ -262,24 +266,27 @@ function openerp_picking_widgets(instance){
clearTimeout(this.searchbox_timeout);
this.searchbox_timout = setTimeout(function(){
if(query){
self.$('.oe_picking_not_found').addClass('oe_hidden');
self.$('.oe_picking_categories').addClass('oe_hidden');
self.$('.oe_title_label').addClass('hidden');
self.$('.oe_picking_not_found').addClass('hidden');
self.$('.oe_picking_categories').addClass('hidden');
self.$('.oe_picking_search_results').html(
QWeb.render('PickingSearchResults',{results:self.search_picking(query)})
);
self.$('.oe_picking_search_results .oe_picking').click(function(){
self.goto_picking($(this).data('id'));
});
self.$('.oe_picking_search_results').removeClass('oe_hidden');
self.$('.oe_picking_search_results').removeClass('hidden');
}else{
self.$('.oe_picking_categories').removeClass('oe_hidden');
self.$('.oe_picking_search_results').addClass('oe_hidden');
self.$('.oe_title_label').removeClass('hidden');
self.$('.oe_picking_categories').removeClass('hidden');
self.$('.oe_picking_search_results').addClass('hidden');
}
},100);
},
quit: function(){
instance.webclient.set_content_full_screen(false);
window.location = '/'; // FIXME Ask niv how to do it correctly
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();
@ -431,15 +438,15 @@ function openerp_picking_widgets(instance){
self.package_selector.replace(self.$('.oe_placeholder_package_selector'));
if( self.picking.id === self.pickings[0]){
self.$('.js_pick_prev').addClass('oe_disabled');
self.$('.js_pick_prev').addClass('disabled');
}else{
self.$('.js_pick_prev').removeClass('oe_disabled');
self.$('.js_pick_prev').removeClass('disabled');
}
if( self.picking.id === self.pickings[self.pickings.length-1] ){
self.$('.js_pick_next').addClass('oe_disabled');
self.$('.js_pick_next').addClass('disabled');
}else{
self.$('.js_pick_next').removeClass('oe_disabled');
self.$('.js_pick_next').removeClass('disabled');
}
self.$('.oe_pick_app_header').text(self.get_header());
@ -458,15 +465,15 @@ function openerp_picking_widgets(instance){
self.package_selector.renderElement();
if( self.picking.id === self.pickings[0]){
self.$('.js_pick_prev').addClass('oe_disabled');
self.$('.js_pick_prev').addClass('disabled');
}else{
self.$('.js_pick_prev').removeClass('oe_disabled');
self.$('.js_pick_prev').removeClass('disabled');
}
if( self.picking.id === self.pickings[self.pickings.length-1] ){
self.$('.js_pick_next').addClass('oe_disabled');
self.$('.js_pick_next').addClass('disabled');
}else{
self.$('.js_pick_next').removeClass('oe_disabled');
self.$('.js_pick_next').removeClass('disabled');
}
self.$('.oe_pick_app_header').text(self.get_header());
});
@ -695,7 +702,9 @@ function openerp_picking_widgets(instance){
},
quit: function(){
this.destroy();
window.location = '/'; // FIXME Ask niv how to do it correctly
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();

View File

@ -48,26 +48,17 @@
<t t-name='PickingEditorWidget'>
<div class='oe_pick_list'>
<div class='oe_pick_list_header'>
<h2><strong><div class='oe_pick_list_header'>
Operations To Process
</div>
<table class='oe_pick_list_table'>
<colgroup>
<col class='oe_pick_col_expand'></col>
<col class='oe_pick_col_small'></col>
<col class='oe_pick_col_small'></col>
<col class='oe_pick_col_small'></col>
<col class='oe_pick_col_expand'></col>
<col class='oe_pick_col_small'></col>
</colgroup>
</div></strong></h2>
<table class='table table-striped'>
<thead>
<tr>
<th>Product</th>
<th class='oe_centeralign'>Qty</th>
<th class='oe_centeralign'>Rem</th>
<th class='oe_centeralign'>UoM</th>
<th class='text-center'>Qty</th>
<th class='text-center'>Rem</th>
<th class='text-center'>UoM</th>
<th>Location</th>
<th>Scan</th>
</tr>
@ -77,11 +68,11 @@
<t t-foreach="widget.get_rows()" t-as="row">
<tr t-att-class="row.classes">
<td> <t t-esc="row.cols.product" /> </td>
<td class='oe_centeralign'> <t t-esc="row.cols.qty" /> </td>
<td class='oe_centeralign'> <t t-esc="row.cols.rem" /> </td>
<td class='oe_centeralign'> <t t-esc="row.cols.uom" /> </td>
<td class='text-center'> <t t-esc="row.cols.qty" /> </td>
<td class='text-center'> <t t-esc="row.cols.rem" /> </td>
<td class='text-center'> <t t-esc="row.cols.uom" /> </td>
<td> <t t-esc="row.cols.loc" /> </td>
<td><span class='oe_row_button oe_expanded js_pack_scan' t-att-op-id='row.cols.id'></span></td>
<td><span class='btn btn-default js_pack_scan' t-att-op-id='row.cols.id'></span></td>
</tr>
</t>
</tbody>
@ -92,20 +83,14 @@
<t t-name='PackageEditorWidget'>
<div class='oe_pick_list'>
<div class='oe_pick_list_header'> <t t-esc="widget.get_header()" /> </div>
<table class='oe_pick_list_table'>
<colgroup>
<col class='oe_pick_col_expand'></col>
<col class='oe_pick_col_small'></col>
<col class='oe_pick_col_small'></col>
</colgroup>
<h2><strong><div class='oe_pick_list_header'> <t t-esc="widget.get_header()" /> </div></strong></h2>
<table class='table table-striped'>
<thead>
<tr>
<th>Product</th>
<th class='oe_centeralign'>Qty</th>
<th class='oe_centeralign'>UoM</th>
<th class='text-center'>Qty</th>
<th class='text-center'>UoM</th>
</tr>
</thead>
@ -113,8 +98,8 @@
<t t-foreach="widget.get_rows()" t-as="row">
<tr t-att-class="row.classes" t-att-op-id="row.att_op_id">
<td> <t t-esc="row.cols.product" /> </td>
<td class='oe_centeralign'> <t t-esc="row.cols.qty" /> </td>
<td class='oe_centeralign'> <t t-esc="row.cols.uom" /> </td>
<td class='qty text-center'> <t t-esc="row.cols.qty" /> </td>
<td class='text-center'> <t t-esc="row.cols.uom" /> </td>
</tr>
</t>
</tbody>
@ -125,29 +110,25 @@
<t t-name='PackageSelectorWidget'>
<div class='oe_pick_list'>
<div class='oe_pick_list_header'><t t-esc="widget.get_header()" /></div>
<table class='oe_pick_list_table'>
<colgroup>
<col class='oe_pick_col_expand'></col>
<col class='oe_pick_col_small'></col>
<col class='oe_pick_col_small'></col>
<col class='oe_pick_col_small'></col>
</colgroup>
<h2><strong><div class='oe_pick_list_header'><t t-esc="widget.get_header()" /></div></strong></h2>
<table class='table table-striped'>
<thead>
<tr>
<th>Package</th> <th></th> <th></th> <th></th>
<th>Package</th> <th></th>
</tr>
</thead>
<tbody>
<t t-foreach="widget.get_rows()" t-as="row">
<tr t-att-class="'js_pack_row' + row.classes" t-att-pack-id="row.id">
<td class='js_pack_select'> <t t-esc="row.cols.pack" /> </td>
<td class='oe_centeralign'> <span class='oe_row_button js_pack_print'>Print</span> </td>
<td class='oe_centeralign'> <span class='oe_row_button js_pack_plus'>Copy</span> </td>
<td class='oe_centeralign'> <span class='oe_row_button js_pack_minus'>Delete</span> </td>
<td class='js_pack_select col-md-8'> <t t-esc="row.cols.pack" /> </td>
<td class='text-right col-md-4'>
<div class='btn btn-default js_pack_print'>Print</div>
<div class='btn btn-default js_pack_plus'>Copy</div>
<div class='btn btn-default js_pack_minus'>Delete</div>
</td>
</tr>
</t>
</tbody>
@ -156,116 +137,121 @@
</div>
</t>
<t t-name="PickingSearchResults">
<h3><span class="label label-info">Search Results</span></h3>
<t t-if="results.length === 0">
<div class='oe_search_empty'>
<div class='alert alert-warning'>
No picking found.
</div>
</t>
<t t-if="results.length > 0">
<t t-foreach="results" t-as="picking">
<div class="oe_picking" t-att-data-id="picking.id">
<span class='oe_picking_name'><t t-esc="picking.name" /></span>
</div>
</t>
<table class="table table-bordered table-striped">
<t t-foreach="results" t-as="picking">
<tr>
<td>
<div class="oe_picking" t-att-data-id="picking.id">
<span class='oe_picking_name'><t t-esc="picking.name" /></span>
</div>
</td>
</tr>
</t>
</table>
</t>
</t>
<t t-name="PickingMenuWidget">
<div class='oe_pick_widget'>
<table class='oe_pick_layout'>
<tr class='oe_pick_header_row'>
<td class='oe_pick_header'>
<div class='oe_pick_right_toolbar'>
<div class='oe_pick_button js_pick_quit'> Quit </div>
</div>
<div class='oe_pick_toolbar'>
<div class='oe_searchbox oe_left'>
<input type='text' placeholder='Search'/>
<div class="row">
<div class="navbar navbar-inverse navbar-static-top" role="navigation">
<div class="container">
<div class="navbar-header navbar-form navbar-right">
<div class='form-group'>
<input type='text' class="oe_searchbox form-control" placeholder='Search'/>
<button type="button" class="btn btn-danger js_pick_quit">Quit</button>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="jumbotron">
<div class="container">
<h3><span class="oe_title_label label label-info">Pickings</span></h3>
<div class='oe_picking_not_found alert alert-warning hidden'>
Scanned picking could not be found
</div>
</td>
</tr>
<tr class='oe_pick_body_row'>
<td class='oe_pick_body_cont'>
<div class='oe_pick_body'>
<div class='oe_pick_app'>
<h3 class='oe_pick_app_title'>Pickings</h3>
<div class='oe_picking_search_results'>
</div>
<div class='oe_picking_not_found oe_hidden'>
Scanned picking could not be found
</div>
<div class='oe_picking_search_results'>
</div>
<div class='oe_picking_categories'>
<p>
Select the type of picking you want to process.
</p>
<t t-foreach="widget.picking_types" t-as="type">
<div class='oe_picking_categories'>
<p>
Select the type of picking you want to process.
</p>
<table class="table table-striped">
<t t-foreach="widget.picking_types" t-as="type">
<tr>
<td>
<div t-att-class="'oe_picking ' + (widget.pickings_by_type[type.id].length === 0 ? 'oe_empty':'js_pick_last') "
t-att-data-id="type.id">
<span class='oe_picking_name'><t t-esc="type.complete_name" /></span>
<t t-if="widget.pickings_by_type[type.id].length === 0">
<span class='oe_pick_app_info'>Nothing to do</span>
</t>
<t t-if="widget.pickings_by_type[type.id].length === 1">
<span class='oe_pick_app_info'>1 picking</span>
</t>
<t t-if="widget.pickings_by_type[type.id].length > 1">
<span class='oe_pick_app_info'><t t-esc="widget.pickings_by_type[type.id].length" /> pickings </span>
<span><t t-esc="type.complete_name"/></span>
<t t-if="widget.pickings_by_type[type.id].length > 0">
<span class='badge pull-right'><t t-esc="widget.pickings_by_type[type.id].length" /> picking(s) </span>
</t>
</div>
</t>
</div>
</div>
</td>
</tr>
</t>
</table>
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</t>
<t t-name="PickingMainWidget">
<div class='oe_pick_widget'>
<table class='oe_pick_layout'>
<tr class='oe_pick_header_row'>
<td class='oe_pick_header'>
<div class='oe_pick_right_toolbar'>
<div class='oe_pick_button js_pick_menu'> Menu </div>
<div class='row'>
<div class="navbar navbar-inverse navbar-static-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="btn btn-default navbar-btn js_pick_prev">&lt; Previous</button>
<button type="button" class="btn btn-default navbar-btn js_pick_next">Next &gt;</button>
</div>
<div class='oe_pick_toolbar'>
<div class='oe_pick_button oe_disabled js_pick_prev'>&lt; Previous</div>
<div class='oe_pick_button oe_disabled js_pick_next'>Next &gt;</div>
<div class="navbar-right">
<button type="button" class="btn btn-primary navbar-btn js_pick_menu">Menu</button>
</div>
</td>
</tr>
<tr class='oe_pick_body_row'>
<td class='oe_pick_body_cont'>
<div class='oe_pick_body'>
<div class='oe_pick_app'>
<div class='oe_pick_button js_pick_done'> Done </div>
<div class='oe_pick_button js_pick_print'> Print </div>
<div class='oe_pick_app_header'>
<t t-esc='widget.get_header()' />
</div>
<div class='oe_pick_button js_pick_pack'> Put in Pack </div>
<div class='oe_placeholder_picking_editor'></div>
<div class='oe_placeholder_package_editor'></div>
<div class='oe_placeholder_package_selector'></div>
<div class='oe_placeholder_menu'></div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="jumbotron">
<div class="container">
<div>
<div class="text-right">
<button type="button" class='btn btn-danger js_pick_done'> Done </button>
<button type="button" class='btn btn-info js_pick_print'> Print </button>
</div>
<div>
<h2><span class="oe_pick_app_header label label-info"><t t-esc='widget.get_header()' /></span></h2>
</div>
<div class="text-left">
<button type="button" class='btn btn-default js_pick_pack'> Put in Pack </button>
</div>
</div>
</td>
</tr>
</table>
<div class='oe_placeholder_picking_editor'></div>
<div class='oe_placeholder_package_editor'></div>
<div class='oe_placeholder_package_selector'></div>
<div class='oe_placeholder_menu'></div>
</div>
</div>
</div>
</div>
</t>

View File

@ -3730,6 +3730,11 @@ class stock_picking_type(osv.osv):
_description = "The picking type determines the picking view"
_order = 'sequence'
def open_barcode_interface(self, cr, uid, ids, context=None):
final_url="/barcode/web/"+str(ids[0]) if len(ids) else '0'
return {'type': 'ir.actions.act_url', 'url':final_url, 'target': 'self',}
def _get_tristate_values(self, cr, uid, ids, field_name, arg, context=None):
picking_obj = self.pool.get('stock.picking')
res = dict.fromkeys(ids, [])

View File

@ -1245,12 +1245,6 @@
<menuitem action="action_move_form2" id="menu_action_move_form2" parent="menu_traceability" sequence="3" groups="stock.group_locations"/>
<record id="action_stock_stock_ui" model="ir.actions.client">
<field name="name">Stock picking</field>
<field name="tag">stock.ui</field>
<field name="res_model">stock</field>
</record>
<!--
Reception Picking (By Stock Move)
From stock_partial_move_view
@ -1461,7 +1455,7 @@
<div class="oe_kanban_content">
<h4 class="oe_center"><field name="complete_name"/></h4>
<div class="oe_right">
<a name="%(action_stock_stock_ui)d" type="action">
<a name="open_barcode_interface" type="object">
<img src="/stock/static/src/img/scan.png"
alt="Click to launch the barcode interface"
class="oe_stock_scan_image" title="Click to launch the barcode interface"/>