[IMP] point_of_sale: various fixes and improvements
bzr revid: fva@openerp.com-20120730154143-kz57aldzo1yalfx9
This commit is contained in:
parent
b3f6c148c5
commit
ccf07028cf
|
@ -658,8 +658,16 @@
|
|||
display: inline-block;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
.point-of-sale .greyed-out{
|
||||
color: #AAA;
|
||||
}
|
||||
.point-of-sale .pos-step-container input{
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.point-of-sale .pos-payment-container {
|
||||
text-align: left;
|
||||
min-width: 500px;
|
||||
}
|
||||
.point-of-sale .pos-payment-container .left-block{
|
||||
display: inline-block;
|
||||
|
@ -821,6 +829,28 @@
|
|||
font-family: "Inconsolata";
|
||||
}
|
||||
|
||||
/* e) The Welcome Screen */
|
||||
.point-of-sale .goodbye-message{
|
||||
position: absolute;
|
||||
left:50%;
|
||||
top:30%;
|
||||
width:500px;
|
||||
height:400px;
|
||||
margin-left: -250px;
|
||||
margin-top: -200px;
|
||||
padding:10px;
|
||||
padding-top:20px;
|
||||
text-align:center;
|
||||
font-size:20px;
|
||||
font-weight:bold;
|
||||
background-color: #F0EEEE;
|
||||
border: 1px solid #E0DDDD;
|
||||
-webkit-box-shadow: 0px 10px 20px rgba(0,0,0, 0.3);
|
||||
-moz-box-shadow: 0px 10px 20px rgba(0,0,0, 0.3);
|
||||
-ms-box-shadow: 0px 10px 20px rgba(0,0,0, 0.3);
|
||||
z-index:1150;
|
||||
}
|
||||
|
||||
/* ********* The OrderWidget ********* */
|
||||
|
||||
.point-of-sale .order-container{
|
||||
|
@ -1017,6 +1047,23 @@
|
|||
-webkit-transition-timing-function: ease-out;
|
||||
}
|
||||
|
||||
.point-of-sale .pos-actionbar .button.disabled{
|
||||
color:#AAA;
|
||||
}
|
||||
.point-of-sale .pos-actionbar .button.disabled:hover{
|
||||
border: 1px solid #cacaca;
|
||||
border-radius: 4px;
|
||||
|
||||
background: #e2e2e2;
|
||||
background: -webkit-linear-gradient(#f0f0f0, #e2e2e2);
|
||||
background: -moz-linear-gradient(#f0f0f0, #e2e2e2);
|
||||
background: -ms-linear-gradient(#f0f0f0, #e2e2e2);
|
||||
background: linear-gradient(#f0f0f0, #e2e2e2);
|
||||
-webkit-box-shadow: 0px 2px 2px rgba(0,0,0, 0.1);
|
||||
-moz-box-shadow: 0px 2px 2px rgba(0,0,0, 0.1);
|
||||
box-shadow: 0px 2px 2px rgba(0,0,0, 0.1);
|
||||
}
|
||||
|
||||
.point-of-sale .pos-actionbar .button.rightalign{
|
||||
float:right;
|
||||
}
|
||||
|
|
|
@ -1,35 +1,30 @@
|
|||
- Affichage Catégories doivent respecter le poids
|
||||
- Affichage Catégories par poids doivent avoir une hiérarchie plate
|
||||
- Le Onscreen keyboard ne fonctionne plus
|
||||
- Scrolling dans la sélection produit et dans
|
||||
v Affichage Catégories doivent respecter le poids
|
||||
v Affichage Catégories par poids doivent avoir une hiérarchie plate
|
||||
v Le Onscreen keyboard ne fonctionne plus
|
||||
v Scrolling dans la sélection produit et dans
|
||||
la liste de courses
|
||||
- Réductions
|
||||
- Redesign liste de courses
|
||||
v Réductions
|
||||
v Redesign liste de courses
|
||||
- Redesign du receipt
|
||||
- générer les données de printing
|
||||
- popups d'erreur certainement buggés
|
||||
- bugs scans produits par prix par poids
|
||||
- si pas photo photo par defaut
|
||||
x générer les données de printing
|
||||
x popups d'erreur certainement buggés
|
||||
v bugs scans produits par prix par poids
|
||||
v si pas photo photo par defaut
|
||||
- WebSQL
|
||||
- Redesign header, bouton retour aux backend en mode caissière
|
||||
- bouton exit en mode caissière doit retourner au backend.
|
||||
v Redesign header, bouton retour aux backend en mode caissière
|
||||
v bouton exit en mode caissière doit retourner au backend.
|
||||
- user preferences : désactiver la balance etc.
|
||||
- posting orders
|
||||
- login alternatif
|
||||
- bug ajout ligne payment à zero + curseur dedans + suppression + design plus grand
|
||||
- si case print via proxy cochée, alors on skip l'ecran receipt
|
||||
- bouton exit self checkout
|
||||
- demarrage en mode self-checkout si self-checkout
|
||||
- produits poid code barre non reconnus
|
||||
- activer popup client aux écrans self-checkout
|
||||
- discount pas plus grand que 100
|
||||
v bug ajout ligne payment à zero + curseur dedans + suppression + design plus grand
|
||||
v si case print via proxy cochée, alors on skip l'ecran receipt
|
||||
v bouton exit self checkout
|
||||
v demarrage en mode self-checkout si self-checkout
|
||||
v produits poid code barre non reconnus
|
||||
v activer popup client aux écrans self-checkout
|
||||
v discount pas plus grand que 100
|
||||
- numpad state parfois sans state
|
||||
- numpad state en mode pesée ?? le cacher ?
|
||||
- numpad dans l'écran payment pour pouvoir entrer le montant
|
||||
v numpad dans l'écran payment pour pouvoir entrer le montant
|
||||
- différence de total. Methode d'arrondis
|
||||
Bellevue Kriek
|
||||
Chaufontaine pétillante 33
|
||||
Boon Framboise
|
||||
Chaufontaine pétillante 50 avec discount 50%
|
||||
- mettre toutes les lignes de payement dans l'order
|
||||
|
||||
|
|
|
@ -17,7 +17,9 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
|
|||
delay_payment: function(){ this.activate(); this.payment_status = 'waiting_for_payment'; },
|
||||
}))();
|
||||
|
||||
//window.debug_devices = debug_devices;
|
||||
if(jQuery.deparam(jQuery.param.querystring()).debug !== undefined){
|
||||
window.debug_devices = debug_devices;
|
||||
}
|
||||
|
||||
// this object interfaces with the local proxy to communicate to the various hardware devices
|
||||
// connected to the Point of Sale. As the communication only goes from the POS to the proxy,
|
||||
|
@ -42,21 +44,26 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
|
|||
success_callback = success_callback || function(){};
|
||||
error_callback = error_callback || function(){};
|
||||
|
||||
if(debug_devices && debug_devices.active){
|
||||
|
||||
if(jQuery.deparam(jQuery.param.querystring()).debug !== undefined){
|
||||
console.log('PROXY:',name,params);
|
||||
}else{
|
||||
}
|
||||
|
||||
if(!(debug_devices && debug_devices.active)){
|
||||
this.connection.rpc('/pos/'+name, params || {}, success_callback, error_callback);
|
||||
}
|
||||
},
|
||||
|
||||
//a product has been scanned and recognized with success
|
||||
scan_item_success: function(){
|
||||
this.message('scan_item_success');
|
||||
// ean is a parsed ean object
|
||||
scan_item_success: function(ean){
|
||||
this.message('scan_item_success',ean);
|
||||
},
|
||||
|
||||
//a product has been scanned but not recognized
|
||||
scan_item_error_unrecognized: function(){
|
||||
this.message('scan_item_error_unrecognized');
|
||||
// a product has been scanned but not recognized
|
||||
// ean is a parsed ean object
|
||||
scan_item_error_unrecognized: function(ean){
|
||||
this.message('scan_item_error_unrecognized',ean);
|
||||
},
|
||||
|
||||
//the client is asking for help
|
||||
|
@ -331,6 +338,7 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
|
|||
value: 0,
|
||||
unit: 'none',
|
||||
};
|
||||
console.log('ean',ean);
|
||||
|
||||
function match_prefix(prefix_set, type){
|
||||
for(prefix in prefix_set){
|
||||
|
@ -402,7 +410,7 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
|
|||
var parse_result = self.parse_ean(codeNumbers.join(''));
|
||||
|
||||
if (parse_result.type === 'error') { //most likely a checksum error, raise warning
|
||||
console.error('ERROR: barcode checksum error:',parse_result);
|
||||
console.warn('WARNING: barcode checksum error:',parse_result);
|
||||
}else if(parse_result.type in {'unit':'', 'weight':'', 'price':''}){ //ean is associated to a product
|
||||
if(self.action_callback['product']){
|
||||
self.action_callback['product'](parse_result);
|
||||
|
|
|
@ -608,15 +608,10 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
return false;
|
||||
}else if(this.get_discount() > 0){ // we don't merge discounted orderlines
|
||||
return false;
|
||||
}else if(this.get_product_type() === 'unit'){
|
||||
return true;
|
||||
}else if(this.get_product_type() === 'weight'){
|
||||
return true;
|
||||
}else if(this.get_product_type() === 'price'){
|
||||
return this.get_product().get('list_price') === orderline.get_product().get('list_price');
|
||||
}else{
|
||||
console.error('point_of_sale/pos_models.js/Orderline.can_be_merged_with() : unknown product type:',this.get('product_type'));
|
||||
}else if(this.price !== orderline.price){
|
||||
return false;
|
||||
}else{
|
||||
return true;
|
||||
}
|
||||
},
|
||||
merge: function(orderline){
|
||||
|
|
|
@ -160,12 +160,13 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
// there's an error.
|
||||
barcode_product_action: function(ean){
|
||||
if(this.pos_widget.scan_product(ean)){
|
||||
this.pos.proxy.scan_item_success();
|
||||
this.pos.proxy.scan_item_success(ean);
|
||||
if(this.barcode_product_screen){
|
||||
this.pos_widget.screen_selector.set_current_screen(this.barcode_product_screen);
|
||||
}
|
||||
}else{
|
||||
if(this.barcode_product_error_popup){
|
||||
this.pos.proxy.scan_item_error_unrecognized(ean);
|
||||
if(this.barcode_product_error_popup && this.pos_widget.screen_selector.get_user_mode() !== 'cashier'){
|
||||
this.pos_widget.screen_selector.show_popup(this.barcode_product_error_popup);
|
||||
}
|
||||
}
|
||||
|
@ -186,6 +187,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
return true;
|
||||
}
|
||||
}
|
||||
this.pos.proxy.scan_item_unrecognized(ean);
|
||||
return false;
|
||||
},
|
||||
|
||||
|
@ -199,9 +201,11 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
if(users[i].ean13 === ean.ean){
|
||||
this.pos.get('selectedOrder').set_client(users[i]);
|
||||
this.pos_widget.username.refresh();
|
||||
this.pos.proxy.scan_item_success(ean);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
this.pos.proxy.scan_item_unrecognized(ean);
|
||||
return false;
|
||||
//TODO start the transaction
|
||||
},
|
||||
|
@ -209,6 +213,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
// what happens when a discount barcode is scanned : the default behavior
|
||||
// is to set the discount on the last order.
|
||||
barcode_discount_action: function(ean){
|
||||
this.pos.proxy.scan_item_success(ean);
|
||||
var last_orderline = this.pos.get('selectedOrder').getLastOrderline();
|
||||
if(last_orderline){
|
||||
last_orderline.set_discount(ean.value)
|
||||
|
@ -241,6 +246,8 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
// this method shows the screen and sets up all the widget related to this screen. Extend this method
|
||||
// if you want to alter the behavior of the screen.
|
||||
show: function(){
|
||||
var self = this;
|
||||
|
||||
this.hidden = false;
|
||||
if(this.$element){
|
||||
this.$element.show();
|
||||
|
@ -251,14 +258,22 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
}else{
|
||||
this.hide_action_bar();
|
||||
}
|
||||
|
||||
// we add the help button by default. we do this because the buttons are cleared on each refresh so that
|
||||
// the button stay local to each screen
|
||||
this.pos_widget.left_action_bar.add_new_button({
|
||||
label: 'help',
|
||||
icon: '/point_of_sale/static/src/img/icons/png48/help.png',
|
||||
click: function(){ self.help_button_action(); },
|
||||
});
|
||||
|
||||
var self = this;
|
||||
var cashier_mode = this.pos_widget.screen_selector.get_user_mode() === 'cashier';
|
||||
|
||||
this.pos_widget.set_numpad_visible(this.show_numpad && cashier_mode);
|
||||
this.pos_widget.set_leftpane_visible(this.show_leftpane);
|
||||
this.pos_widget.set_left_action_bar_visible(this.show_leftpane && !cashier_mode);
|
||||
this.pos_widget.set_cashier_controls_visible(cashier_mode);
|
||||
/*this.pos_widget.action_bar.set_element_visible('help-button', !cashier_mode, function(){ self.help_button_action(); });*/
|
||||
|
||||
if(cashier_mode && this.pos.use_selfcheckout){
|
||||
this.pos_widget.client_button.show();
|
||||
|
@ -287,9 +302,8 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
if(this.pos.barcode_reader){
|
||||
this.pos.barcode_reader.reset_action_callbacks();
|
||||
}
|
||||
if(this.pos_widget.action_bar){
|
||||
this.pos_widget.action_bar.destroy_buttons();
|
||||
}
|
||||
this.pos_widget.action_bar.destroy_buttons();
|
||||
this.pos_widget.left_action_bar.destroy_buttons();
|
||||
},
|
||||
|
||||
// this methods hides the screen. It's not a good place to put your cleanup stuff as it is called on the
|
||||
|
@ -559,12 +573,17 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
|
||||
barcode_client_action: function(ean){
|
||||
this._super(ean);
|
||||
this.pos_widget.screen_selector.set_current_screen(self.next_screen);
|
||||
this.pos_widget.screen_selector.set_current_screen(this.next_screen);
|
||||
},
|
||||
|
||||
show: function(){
|
||||
this._super();
|
||||
var self = this;
|
||||
$('.goodbye-message').css({opacity:1}).show();
|
||||
setTimeout(function(){
|
||||
console.log('kill');
|
||||
$('.goodbye-message').animate({opacity:0},500,'swing',function(){$('.goodbye-message').hide();});
|
||||
},3000);
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -731,18 +750,23 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
validateCurrentOrder: function() {
|
||||
var self = this;
|
||||
var currentOrder = this.pos.get('selectedOrder');
|
||||
|
||||
this.validate_button.$element.attr('disabled','disabled'); //FIXME is the css actually using this attr ?
|
||||
if(this.busy){
|
||||
return;
|
||||
}else{
|
||||
this.busy = true;
|
||||
}
|
||||
this.validate_button.$element.addClass('disabled');
|
||||
|
||||
this.pos.push_order(currentOrder.exportAsJSON())
|
||||
.then(function() {
|
||||
self.validate_button.$element.removeAttr('disabled');
|
||||
if(self.pos.use_proxy_printer){
|
||||
self.pos.proxy.print_receipt(currentOrder.export_for_printing());
|
||||
self.pos.get('selectedOrder').destroy(); //finish order and go back to scan screen
|
||||
}else{
|
||||
self.pos_widget.screen_selector.set_current_screen(self.next_screen);
|
||||
}
|
||||
self.validate_button.$element.removeClass('disabled');
|
||||
self.busy = false;
|
||||
});
|
||||
},
|
||||
bindPaymentLineEvents: function() {
|
||||
|
|
|
@ -112,7 +112,7 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
template:'OrderWidget',
|
||||
init: function(parent, options) {
|
||||
this._super(parent,options);
|
||||
this.compact = options.compact !== undefined ? options.compact : true;
|
||||
this.display_mode = options.display_mode || 'numpad'; // 'maximized' | 'actionbar' | 'numpad'
|
||||
this.set_numpad_state(options.numpadState);
|
||||
this.pos.bind('change:selectedOrder', this.change_selected_order, this);
|
||||
this.bind_orderline_events();
|
||||
|
@ -165,9 +165,12 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
var self = this;
|
||||
this._super();
|
||||
|
||||
if(!this.compact){
|
||||
console.log('not compact');
|
||||
if(this.display_mode === 'maximized'){
|
||||
$('.point-of-sale .order-container').css({'bottom':'0px'});
|
||||
}else if(this.display_mode === 'actionbar'){
|
||||
$('.point-of-sale .order-container').css({'bottom':'105px'});
|
||||
}else if(this.display_mode !== 'numpad'){
|
||||
console.error('ERROR: OrderWidget renderElement(): wrong display_mode:',this.display_mode);
|
||||
}
|
||||
|
||||
var $content = this.$('.orderlines');
|
||||
|
@ -212,10 +215,9 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
var total = order ? order.getTotal() : 0;
|
||||
this.$('.summary .value.total').html(this.format_currency(total));
|
||||
},
|
||||
set_compact: function(compact){
|
||||
console.log('set_compact',compact);
|
||||
if(this.compact !== compact){
|
||||
this.compact = compact;
|
||||
set_display_mode: function(mode){
|
||||
if(this.display_mode !== mode){
|
||||
this.display_mode = mode;
|
||||
this.renderElement();
|
||||
}
|
||||
},
|
||||
|
@ -368,7 +370,7 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
add_new_button: function(button_options){
|
||||
var button = new module.ActionButtonWidget(this,button_options);
|
||||
this.button_list.push(button);
|
||||
button.appendTo($('.pos-actionbar-button-list'));
|
||||
button.appendTo(this.$('.pos-actionbar-button-list'));
|
||||
return button;
|
||||
},
|
||||
show:function(){
|
||||
|
@ -671,14 +673,15 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
this.pos_widget = this; //So that pos_widget's childs have pos_widget set automatically
|
||||
|
||||
this.numpad_visible = true;
|
||||
this.left_action_bar_visible = true;
|
||||
this.leftpane_visible = true;
|
||||
this.leftpane_width = '440px';
|
||||
this.cashier_controls_visible = true;
|
||||
var degree = 0;
|
||||
|
||||
/*
|
||||
//Epileptic mode
|
||||
setInterval(function(){
|
||||
$('body').css({'-webkit-filter':'sepia('+Math.round(Math.random())+') hue-rotate('+Math.random()*360+'deg) blur('+Math.random()*5+'px)' });
|
||||
$('body').css({'-webkit-filter':'hue-rotate('+Math.random()*360+'deg)' });
|
||||
},100);
|
||||
*/
|
||||
|
||||
|
@ -718,9 +721,14 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
self.screen_selector.show_popup('error', 'Sorry, we could not find any PoS Configuration for this session');
|
||||
}
|
||||
|
||||
self.$('.loader').animate({opacity:0},3000,'swing',function(){$('.loader').hide();});
|
||||
self.$('.loader').animate({opacity:0},3000,'swing',function(){self.$('.loader').hide();});
|
||||
self.$('.loader img').hide();
|
||||
|
||||
if(jQuery.deparam(jQuery.param.querystring()).debug !== undefined){
|
||||
window.pos = self.pos;
|
||||
window.pos_widget = self.pos_widget;
|
||||
}
|
||||
|
||||
},function(){ // error when loading models data from the backend
|
||||
self.$('.loader img').hide();
|
||||
return new instance.web.Model("ir.model.data").get_func("search_read")([['name', '=', 'action_pos_session_opening']], ['res_id'])
|
||||
|
@ -733,7 +741,6 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
}, self));
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
// This method instantiates all the screens, widgets, etc. If you want to add new screens change the
|
||||
// startup screen, etc, override this method.
|
||||
|
@ -788,6 +795,9 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
this.action_bar = new module.ActionBarWidget(this);
|
||||
this.action_bar.appendTo($(".point-of-sale #rightpane"));
|
||||
|
||||
this.left_action_bar = new module.ActionBarWidget(this);
|
||||
this.left_action_bar.appendTo($(".point-of-sale #leftpane"));
|
||||
|
||||
this.paypad = new module.PaypadWidget(this, {});
|
||||
this.paypad.replace($('#placeholder-PaypadWidget'));
|
||||
|
||||
|
@ -895,16 +905,35 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
if(visible !== this.numpad_visible){
|
||||
this.numpad_visible = visible;
|
||||
if(visible){
|
||||
this.set_left_action_bar_visible(false);
|
||||
this.numpad.show();
|
||||
this.paypad.show();
|
||||
this.order_widget.set_compact(true);
|
||||
this.order_widget.set_display_mode('numpad');
|
||||
}else{
|
||||
this.numpad.hide();
|
||||
this.paypad.hide();
|
||||
this.order_widget.set_compact(false);
|
||||
if(this.order_widget.display_mode === 'numpad'){
|
||||
this.order_widget.set_display_mode('maximized');
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
set_left_action_bar_visible: function(visible){
|
||||
if(visible !== this.left_action_bar_visible){
|
||||
this.left_action_bar_visible = visible;
|
||||
if(visible){
|
||||
this.set_numpad_visible(false);
|
||||
this.left_action_bar.show();
|
||||
this.order_widget.set_display_mode('actionbar');
|
||||
}else{
|
||||
this.left_action_bar.hide();
|
||||
if(this.order_widget.display_mode === 'actionbar'){
|
||||
this.order_widget.set_display_mode('maximized');
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
//shows or hide the leftpane (contains the list of orderlines, the numpad, the paypad, etc.)
|
||||
set_leftpane_visible: function(visible){
|
||||
if(visible !== this.leftpane_visible){
|
||||
|
|
|
@ -237,7 +237,7 @@
|
|||
<t t-if="widget.currency.position == 'after'" t-esc="widget.currency.symbol"/>
|
||||
</span>
|
||||
</div>
|
||||
<div class="infoline">
|
||||
<div class="infoline" >
|
||||
<span class='left-block'>
|
||||
Change:
|
||||
</span>
|
||||
|
@ -269,6 +269,9 @@
|
|||
<img src="/point_of_sale/static/src/img/scan.png" />
|
||||
<p> Please scan an item or your member card </p>
|
||||
</div>
|
||||
<div class="goodbye-message">
|
||||
<p>Thank you for shopping with us.</p>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue