Commit 28ab4fb6 by François C.

La Cagette Custom Pos : improve 'Unknown barcode experience'

parent 4fd5831c
...@@ -6,7 +6,13 @@ ...@@ -6,7 +6,13 @@
Adaptation pour corriger des fonctions""", Adaptation pour corriger des fonctions""",
'description': """ 'description': """
Recherche par num. de coop Recherche par num. de coop\n
Après une recherche, le champ perd le focus\n
Utilisation du pavé numérique du clavier sur le panier\n
Personnalisation de la popup d'erreur "codebarre non reconnu" :\n
- Faire clignoter la popup d'erreur quand le codebarre n'est pas reconnu
- Jouer le son d'erreur plusieurs fois
- Afficher dans la popup le dernier produit scanné
""", """,
'author': "fracolo", 'author': "fracolo",
...@@ -20,6 +26,7 @@ ...@@ -20,6 +26,7 @@
# any module necessary for this one to work correctly # any module necessary for this one to work correctly
'depends': ['base', 'point_of_sale'], 'depends': ['base', 'point_of_sale'],
'qweb': ['static/src/xml/qweb.xml'],
# 'qweb': ['static/src/xml/qweb.xml'], # 'qweb': ['static/src/xml/qweb.xml'],
# always loaded # always loaded
'data': [ 'data': [
......
.pos .clientlist-screen .client-picture {width: 192px !important; height: 192px !important;} .pos .clientlist-screen .client-picture {width: 192px !important; height: 192px !important;}
.pos .clientlist-screen .client-picture > img {width: 128px !important; height: 128px !important;} .pos .clientlist-screen .client-picture > img {width: 128px !important; height: 128px !important;}
.blink-popup-barcode {
background: #FF6961 !important;
}
.popup-barcode{
-webkit-transition: background 0.5s ease-in-out;
-ms-transition: background 0.5s ease-in-out;
transition: background 0.5s ease-in-out;
}
odoo.define('lacagette_custom_pos.DB', function(require) { odoo.define('lacagette_custom_pos.DB', function(require) {
"use strict"; "use strict";
var PosDB = require('point_of_sale.DB'); var PosDB = require('point_of_sale.DB');
PosDB.include({ PosDB.include({
_partner_search_string: function(partner){ _partner_search_string: function(partner){
var str = partner.name; var str = partner.name;
//Diacritric search //Diacritric search
try { try {
str += '|' + Diacritics.replace(partner.name) str += '|' + Diacritics.replace(partner.name)
} catch(e) { } catch(e) {
console.log(e) console.log(e)
} }
if(partner.barcode){ if(partner.barcode){
str += '|' + partner.barcode; str += '|' + partner.barcode;
} }
if(partner.barcode_base){ if(partner.barcode_base){
str += '|' + partner.barcode_base; str += '|' + partner.barcode_base;
} }
str = '' + partner.id + ':' + str.replace(':','') + '\n'; str = '' + partner.id + ':' + str.replace(':','') + '\n';
return str; return str;
}, }
});
/* Custom behavior on barcode error */
var popups = require('point_of_sale.popups');
var gui = require('point_of_sale.gui');
// Custom popup definition
var CustomErrorBarcodePopupWidget = popups.extend({
template:'CustomErrorBarcodePopupWidget',
show: function(options) {
this._super(options);
// Play the error sound every second
this.gui.play_sound('error');
var playSoundInterval = setInterval(() => {
this.gui.play_sound('error');
}, 1300)
// stop after 4s
setTimeout(function() {
clearInterval(playSoundInterval)
}, 3000)
}
}); });
gui.define_popup({name:'custom-error-barcode', widget: CustomErrorBarcodePopupWidget});
var screens = require('point_of_sale.screens');
screens.ScreenWidget.include({
// Redefine action on barcode error
barcode_error_action: function(code) {
var show_code;
if (code.code.length > 32) {
show_code = code.code.substring(0,29)+'...';
} else {
show_code = code.code;
}
// Only on products screen
if (this.gui.get_current_screen() == 'products') {
// Get last product scanned
var orderlines = this.pos.get_order().orderlines.models
var last_product_name = orderlines.length > 0
? orderlines[orderlines.length-1].product.display_name
: 'Panier vide'
// Display custom popum with options
this.gui.show_popup('custom-error-barcode', {
barcode: show_code,
last_product_name: last_product_name
});
var popup_barcode = $('.popup-barcode')
// Make popup blink
if (popup_barcode.length != 0) {
var backgroundInterval = setInterval(function(){
popup_barcode.toggleClass("blink-popup-barcode");
}, 750)
setTimeout(function() {
clearInterval(backgroundInterval)
popup_barcode.removeClass("blink-popup-barcode")
}, 5000)
}
} else {
this.gui.show_popup('error-barcode',show_code);
}
}
})
/* Make search input loose focus after 5s without a key press */
screens.ProductCategoriesWidget.include({
// Redefine init function of the widget handling research
init: function(parent, options){
var self = this;
this._super(parent,options);
this.product_type = options.product_type || 'all'; // 'all' | 'weightable'
this.onlyWeightable = options.onlyWeightable || false;
this.category = this.pos.root_category;
this.breadcrumb = [];
this.subcategories = [];
this.product_list_widget = options.product_list_widget || null;
this.category_cache = new screens.DomCache();
this.start_categ_id = this.pos.config.iface_start_categ_id ? this.pos.config.iface_start_categ_id[0] : 0;
this.set_category(this.pos.db.get_category_by_id(this.start_categ_id));
this.switch_category_handler = function(event){
self.set_category(self.pos.db.get_category_by_id(Number(this.dataset.categoryId)));
self.renderElement();
};
this.clear_search_handler = function(event){
self.clear_search();
};
var search_timeout = null;
var blur_timeout = null;
this.search_handler = function(event){
if(event.type == "keypress" || event.keyCode === 46 || event.keyCode === 8){
clearTimeout(search_timeout);
var searchbox = this;
search_timeout = setTimeout(function(){
self.perform_search(self.category, searchbox.value, event.which === 13);
},70);
// Add timeout: loose focus after 5s without a keypress
clearTimeout(blur_timeout)
blur_timeout = setTimeout(function() {
$('.searchbox input').blur()
}, 5000)
}
};
}
})
/* Enable keyboard numpad on products screen */
screens.ProductScreenWidget.include({
// Redefine init function to add en event listener on this screen
start: function(){
var self = this;
this.actionpad = new screens.ActionpadWidget(this,{});
this.actionpad.replace(this.$('.placeholder-ActionpadWidget'));
this.numpad = new screens.NumpadWidget(this,{});
this.numpad.replace(this.$('.placeholder-NumpadWidget'));
this.order_widget = new screens.OrderWidget(this,{
numpad_state: this.numpad.state,
});
this.order_widget.replace(this.$('.placeholder-OrderWidget'));
this.product_list_widget = new screens.ProductListWidget(this,{
click_product_action: function(product){ self.click_product(product); },
product_list: this.pos.db.get_product_by_category(0)
});
this.product_list_widget.replace(this.$('.placeholder-ProductListWidget'));
this.product_categories_widget = new screens.ProductCategoriesWidget(this,{
product_list_widget: this.product_list_widget,
});
this.product_categories_widget.replace(this.$('.placeholder-ProductCategoriesWidget'));
this.action_buttons = {};
var classes = [];
for (var i = 0; i < classes.length; i++) {
var classe = classes[i];
if ( !classe.condition || classe.condition.call(this) ) {
var widget = new classe.widget(this,{});
widget.appendTo(this.$('.control-buttons'));
this.action_buttons[classe.name] = widget;
}
}
if (_.size(this.action_buttons)) {
this.$('.control-buttons').removeClass('oe_hidden');
}
// Add listener on keypress
$(document).on("keypress", (e) => {
// Only on products screen & when not focused on searchbox
if (this.gui.get_current_screen() == 'products'
&& !$('.searchbox input').is(":focus")) {
if (e.which >= 48 && e.which <= 57 || e.which == 46) {
this.numpad.state.appendNewChar(e.key);
} else if (e.which == 45) {
try {
// setMinusSign is a custom method
this.numpad.state.setMinusSign();
} catch (e) {
console.log(e)
}
} else if (e.which == 43) {
try {
// setPlusSign is a custom method
this.numpad.state.setPlusSign();
} catch (e) {
console.log(e)
}
}
}
});
}
})
}); });
<?xml version="1.0" encoding="UTF-8"?>
<template>
<div t-name="CustomErrorBarcodePopupWidget">
<div class="modal-dialog">
<div class="popup popup-barcode">
<p class="title">Unknown Barcode
<br />
<span class='barcode'><t t-esc="widget.options.barcode" /></span>
</p>
<p class="body">
Le Point de Vente n'a pas pu trouver de produit associé
au code-barre scanné.
</p>
<p class="body last-product-scanned">
Dernier produit scanné :
<br />
<b><t t-esc="widget.options.last_product_name" /></b>
</p>
<div class="footer">
<div class="button cancel">
Ok
</div>
</div>
</div>
</div>
</div>
</template>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment