[FIX]stock_barcode_interface: rework of the barcode interface to use bootstrap only
authorCedric Snauwaert <csn@openerp.com>
Wed, 26 Feb 2014 16:10:03 +0000 (17:10 +0100)
committerCedric Snauwaert <csn@openerp.com>
Wed, 26 Feb 2014 16:10:03 +0000 (17:10 +0100)
bzr revid: csn@openerp.com-20140226161003-kzgg5xfcrn8ucspx

addons/stock/__init__.py
addons/stock/__openerp__.py
addons/stock/controllers/__init__.py [new file with mode: 0644]
addons/stock/controllers/main.py [new file with mode: 0644]
addons/stock/static/src/css/barcode.css [new file with mode: 0644]
addons/stock/static/src/css/picking.css [deleted file]
addons/stock/static/src/js/widgets.js
addons/stock/static/src/xml/picking.xml
addons/stock/stock.py
addons/stock/stock_view.xml

index a3e0493..7903619 100644 (file)
@@ -27,3 +27,5 @@ import report
 import wizard
 import res_config
 
+import controllers
+
index 20a6ee1..e8a5b5d 100644 (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': [
diff --git a/addons/stock/controllers/__init__.py b/addons/stock/controllers/__init__.py
new file mode 100644 (file)
index 0000000..039d971
--- /dev/null
@@ -0,0 +1 @@
+import main
\ No newline at end of file
diff --git a/addons/stock/controllers/main.py b/addons/stock/controllers/main.py
new file mode 100644 (file)
index 0000000..8db24ea
--- /dev/null
@@ -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
diff --git a/addons/stock/static/src/css/barcode.css b/addons/stock/static/src/css/barcode.css
new file mode 100644 (file)
index 0000000..8d095bb
--- /dev/null
@@ -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;
+}
\ No newline at end of file
diff --git a/addons/stock/static/src/css/picking.css b/addons/stock/static/src/css/picking.css
deleted file mode 100644 (file)
index 80a89ab..0000000
+++ /dev/null
@@ -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;
-    }
-}
-
index da0a873..04faf92 100644 (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();
index 0dcca4b..41aae87 100644 (file)
 
     <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>
                     <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>
 
     <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>
 
                     <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>
 
     <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>
         </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_not_found oe_hidden'>
-                                    Scanned picking could not be found
-                                </div>
 
-                                <div class='oe_picking_search_results'>
-                                </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>
 
index be4bbad..ac4f76e 100644 (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, [])
index 91f7b69..4f38fa3 100644 (file)
 
         <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
                                 <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"/>