'iface_electronic_scale' : fields.boolean('Electronic Scale', help="Enables Electronic Scale integration"),
'iface_vkeyboard' : fields.boolean('Virtual KeyBoard', help="Enables an integrated Virtual Keyboard"),
'iface_print_via_proxy' : fields.boolean('Print via Proxy', help="Bypass browser printing and prints via the hardware proxy"),
+ 'iface_scan_via_proxy' : fields.boolean('Scan via Proxy', help="Enable barcode scanning with a remotely connected barcode scanner"),
'iface_invoicing': fields.boolean('Invoicing',help='Enables invoice generation from the Point of Sale'),
'iface_big_scrollbars': fields.boolean('Large Scrollbars',help='For imprecise industrial touchscreens'),
'receipt_header': fields.text('Receipt Header',help="A short text that will be inserted as a header in the printed receipt"),
'receipt_footer': fields.text('Receipt Footer',help="A short text that will be inserted as a footer in the printed receipt"),
- 'proxy_ip': fields.char('Hardware Proxy IP Address', size=45),
+ 'proxy_ip': fields.char('IP Address', help='The hostname or ip address of the hardware proxy, Will be autodetected if left empty', size=45),
'state' : fields.selection(POS_CONFIG_STATE, 'Status', required=True, readonly=True),
'sequence_id' : fields.many2one('ir.sequence', 'Order IDs Sequence', readonly=True,
<field name="cash_control" />
</tree>
</field>
- <group string="Settings" >
+ <group string="Features" >
<group>
- <field name="iface_self_checkout" />
<field name="iface_cashdrawer" />
- <field name="iface_payment_terminal" />
<field name="iface_invoicing" />
+ <field name="iface_electronic_scale" />
</group>
<group>
- <field name="iface_electronic_scale" />
<field name="iface_vkeyboard" />
<field name="iface_big_scrollbars" />
- <field name="proxy_ip" />
</group>
</group>
- <group string="Receipt" >
+ <group string="Hardware Proxy" >
+ <field name="proxy_ip" />
<field name="iface_print_via_proxy" />
+ <field name="iface_scan_via_proxy" />
+ </group>
+ <group string="Receipt" >
<field name="receipt_header" placeholder="A custom receipt header message"/>
<field name="receipt_footer" placeholder="A custom receipt header footage"/>
</group>
/* c) The notifications indicator */
-.pos .oe_pos_synch-notification{
+.pos .oe_status{
float:right;
color: rgba(255,255,255,0.4);
padding: 8px;
font-style: italic;
cursor:pointer;
}
-.pos .oe_pos_synch-notification.oe_inactive{
+.pos .oe_status.oe_inactive{
cursor: default;
}
-.pos .oe_pos_synch-notification .oe_status{
+.pos .oe_status .oe_icon{
display:inline-block;
cursor:pointer;
- width:16px; height:16px;
+ width:20px; height:16px;
color: white;
}
-.pos .oe_pos_synch-notification .oe_red{
+.pos .oe_icon.oe_red{
color: rgb(197, 52, 0);
}
-.pos .oe_pos_synch-notification .oe_green{
+.pos .oe_icon.oe_green{
color: rgb(94, 185, 55);
}
+.pos .oe_icon.oe_orange{
+ color: rgb(239, 153, 65);
+}
/* ********* Contains everything below the bar ********* */
// stops catching keyboard events
disconnect: function(){
$('body').off('keypress', this.handler)
+ },
+ disconnect_from_proxy: function(){
this.remote_scanning = false;
},
connect_to_proxy: function(){
if(!self.remote_scanning){
return;
}
+ self.pos.set('proxy_status','connected');
self.scan(barcode);
waitforbarcode();
},
function(){
setTimeout(waitforbarcode,5000);
+ self.pos.set('proxy_status','disconnected');
});
});
},
this.proxy = new module.ProxyDevice(); // used to communicate to the hardware devices via a local proxy
this.barcode_reader = new module.BarcodeReader({'pos': this, proxy:this.proxy}); // used to read barcodes
- this.barcode_reader.connect_to_proxy();
this.proxy_queue = new module.JobQueue(); // used to prevent parallels communications to the proxy
this.db = new module.PosDB(); // a local database used to search trough products and categories & store pending orders
this.debug = jQuery.deparam(jQuery.param.querystring()).debug !== undefined; //debug mode
'synch': { state:'connected', pending:0 },
'orders': new module.OrderCollection(),
'selectedOrder': null,
+ 'proxy_status': 'connecting',
});
this.bind('change:synch',function(pos,synch){
// when all the data has loaded, we compute some stuff, and declare the Pos ready to be used.
this.ready = this.load_server_data()
.then(function(){
- return self.connect_to_posbox();
+ if(self.config.use_proxy){
+ return self.connect_to_proxy();
+ }
});
},
// this.flush();
this.proxy.close();
this.barcode_reader.disconnect();
+ this.barcode_reader.disconnect_from_proxy();
},
- connect_to_posbox: function(){
+ connect_to_proxy: function(){
var self = this;
+ this.barcode_reader.disconnect_from_proxy();
this.pos_widget.loading_message(_t('Connecting to the PosBox'),0);
+ this.set('proxy_status', 'connecting');
this.pos_widget.loading_skip(function(){
self.proxy.stop_searching();
+ self.set('proxy_status', 'disconnected');
});
return this.proxy.find_proxy({
}).then(function(proxies){
if(proxies.length > 0){
self.proxy.connect(proxies[0]);
+ if(self.config.iface_scan_via_proxy){
+ self.barcode_reader.connect_to_proxy();
+ }
+ self.set('proxy_status', 'connected');
+ }else{
+ self.set('proxy_status', 'disconnected');
}
});
},
'pos.config',
['name','journal_ids','warehouse_id','journal_id','pricelist_id',
'iface_self_checkout', 'iface_led', 'iface_cashdrawer',
- 'iface_payment_terminal', 'iface_electronic_scale', 'iface_barscan', 'iface_vkeyboard',
- 'iface_print_via_proxy','iface_cashdrawer','iface_invoicing','iface_big_scrollbars',
+ 'iface_payment_terminal', 'iface_electronic_scale', 'iface_barscan',
+ 'iface_vkeyboard','iface_print_via_proxy','iface_scan_via_proxy',
+ 'iface_cashdrawer','iface_invoicing','iface_big_scrollbars',
'receipt_header','receipt_footer','proxy_ip',
'state','sequence_id','session_ids'],
[['id','=', self.pos_session.config_id[0]]]
);
}).then(function(configs){
self.config = configs[0];
+ self.config.use_proxy = self.config.iface_payment_terminal ||
+ self.config.iface_electronic_scale ||
+ self.config.iface_print_via_proxy ||
+ self.config.iface_scan_via_proxy ||
+ self.config.iface_cashdrawer;
return self.fetch('stock.warehouse',[],[['id','=', self.config.warehouse_id[0]]]);
}).then(function(shops){
// ---------- Main Point of Sale Widget ----------
- // this is used to notify the user that data is being synchronized on the network
- module.SynchNotificationWidget = module.PosBaseWidget.extend({
- template: "SynchNotificationWidget",
- init: function(parent, options){
- options = options || {};
- this._super(parent, options);
- },
- renderElement: function() {
+ module.StatusWidget = module.PosBaseWidget.extend({
+ status: ['connected','connecting','disconnected','warning'],
+ set_status: function(status,msg){
var self = this;
- this._super();
+ for(var i = 0; i < this.status.length; i++){
+ this.$('.js_'+this.status[i]).addClass('oe_hidden');
+ }
+ this.$('.js_'+status).removeClass('oe_hidden');
- var pending = this.pos.get('nbr_pending_orders');
- this.set_status(pending ? 'disconnected' : 'connected',pending);
+ if(msg){
+ this.$('.js_msg').removeClass('oe_hidden').html(msg);
+ }else{
+ this.$('.js_msg').addClass('oe_hidden').html('');
+ }
+ },
+ });
+ // this is used to notify the user that data is being synchronized on the network
+ module.SynchNotificationWidget = module.StatusWidget.extend({
+ template: 'SynchNotificationWidget',
+ start: function(){
+ var self = this;
+ this.pos.bind('change:synch', function(pos,synch){
+ self.set_status(synch.state, synch.pending);
+ });
this.$el.click(function(){
self.pos.flush();
});
},
- set_status: function(state,pending){
- var self = this;
- this.$('.js_connected, .js_connecting, .js_disconnected, .js_pending').addClass('oe_hidden');
- this.$('.js_pending').html(pending || '');
- if(state === 'connected'){
- this.$('.js_connected').removeClass('oe_hidden');
- }else if(state === 'disconnected'){
- this.$('.js_disconnected, .js_pending').removeClass('oe_hidden');
- }else if(state === 'connecting'){
- this.$('.js_connecting, .js_pending').removeClass('oe_hidden');
- }
- },
+ });
+
+ // this is used to notify the user if the pos is connected to the proxy
+ module.ProxyStatusWidget = module.StatusWidget.extend({
+ template: 'ProxyStatusWidget',
start: function(){
var self = this;
- this.pos.bind('change:synch', function(pos,synch){
- self.set_status(synch.state, synch.pending);
+
+ this.set_status(this.pos.get('proxy_status'),'');
+
+ this.pos.bind('change:proxy_status', function(pos,status){
+ self.set_status(status,'');
+ });
+
+ this.$el.click(function(){
+ self.pos.connect_to_proxy();
});
},
});
// -------- Misc ---------
+ this.close_button = new module.HeaderButtonWidget(this,{
+ label: _t('Close'),
+ action: function(){ self.close(); },
+ });
+ this.close_button.appendTo(this.$('.pos-rightheader'));
+
this.notification = new module.SynchNotificationWidget(this,{});
this.notification.appendTo(this.$('.pos-rightheader'));
+ if(this.pos.config.use_proxy){
+ this.proxy_status = new module.ProxyStatusWidget(this,{});
+ this.proxy_status.appendTo(this.$('.pos-rightheader'));
+ }
+
this.username = new module.UsernameWidget(this,{});
this.username.replace(this.$('.placeholder-UsernameWidget'));
});
this.onscreen_keyboard.replace(this.$('.placeholder-OnscreenKeyboardWidget'));
- this.close_button = new module.HeaderButtonWidget(this,{
- label: _t('Close'),
- action: function(){ self.close(); },
- });
- this.close_button.appendTo(this.$('.pos-rightheader'));
-
this.client_button = new module.HeaderButtonWidget(this,{
label: _t('Self-Checkout'),
action: function(){ self.screen_selector.set_user_mode('client'); },
</t>
<t t-name="SynchNotificationWidget">
- <div class="oe_pos_synch-notification">
- <span class='js_pending oe_hidden'>0</span>
- <div class="js_connected oe_status oe_green">
- <i class='fa fa-fw fa-circle'></i>
+ <div class="oe_status js_synch">
+ <span class='js_msg oe_hidden'>0</span>
+ <div class="js_connected oe_icon oe_green">
+ <i class='fa fa-fw fa-rss'></i>
</div>
- <div class="js_connecting oe_status oe_hidden">
+ <div class="js_connecting oe_icon oe_hidden">
<i class='fa fa-fw fa-spin fa-spinner'></i>
</div>
- <div class="js_disconnected oe_status oe_red oe_hidden">
- <i class='fa fa-fw fa-circle'></i>
+ <div class="js_disconnected oe_icon oe_red oe_hidden">
+ <i class='fa fa-fw fa-rss'></i>
+ </div>
+ </div>
+ </t>
+
+ <t t-name="ProxyStatusWidget">
+ <div class="oe_status js_proxy">
+ <span class='js_msg oe_hidden'></span>
+ <div class="js_connected oe_icon oe_green">
+ <i class='fa fa-fw fa-sitemap'></i>
+ </div>
+ <div class="js_connecting oe_icon oe_hidden">
+ <i class='fa fa-fw fa-spin fa-spinner'></i>
+ </div>
+ <div class="js_disconnected oe_icon oe_red oe_hidden">
+ <i class='fa fa-fw fa-sitemap'></i>
</div>
</div>
</t>