From 8cf2adf5e314203debbec78edd7b163b40248348 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Thu, 30 Jan 2014 11:30:51 +0100 Subject: [PATCH 1/6] [IMP] point_of_sale: hold receipts until the printer is back online bzr revid: fva@openerp.com-20140130103051-htsx7ts111axhhub --- addons/point_of_sale/static/src/js/devices.js | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/addons/point_of_sale/static/src/js/devices.js b/addons/point_of_sale/static/src/js/devices.js index 57b23afd49f..bb13503d903 100644 --- a/addons/point_of_sale/static/src/js/devices.js +++ b/addons/point_of_sale/static/src/js/devices.js @@ -102,6 +102,8 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal }; this.custom_payment_status = this.default_payment_status; + this.receipt_queue = []; + this.notifications = {}; this.bypass_proxy = false; @@ -113,6 +115,13 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal this.set_connection_status('disconnected'); + this.on('change:status',this,function(eh,status){ + status = status.newValue; + if(status.status === 'connected'){ + self.print_receipt(); + } + }); + window.hw_proxy = this; }, set_connection_status: function(status,drivers){ @@ -502,7 +511,23 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal * } */ print_receipt: function(receipt){ - return this.message('print_receipt',{receipt: receipt}); + var self = this; + if(receipt){ + this.receipt_queue.push(receipt); + } + var aborted = false; + function send_printing_job(){ + if (self.receipt_queue.length > 0){ + var r = self.receipt_queue.shift(); + self.message('print_receipt',{ receipt: r },{ timeout: 5000 }) + .then(function(){ + send_printing_job(); + },function(){ + self.receipt_queue.unshift(r) + }); + } + } + send_printing_job(); }, // asks the proxy to log some information, as with the debug.log you can provide several arguments. From 20fc20a3f2ac2141643720160551af20d3949586 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Thu, 30 Jan 2014 12:45:35 +0100 Subject: [PATCH 2/6] [IMP] http allow auth=none without db outside of web bzr revid: al@openerp.com-20140130114535-0keldqr1eln8swm8 --- openerp/http.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/http.py b/openerp/http.py index 7069cbdeefe..09a0a8d1d57 100644 --- a/openerp/http.py +++ b/openerp/http.py @@ -865,7 +865,7 @@ class Root(object): self.load_addons() _logger.info("Generating nondb routing") - self.nodb_routing_map = routing_map(['', "web"], True) + self.nodb_routing_map = routing_map([''] + openerp.conf.server_wide_modules, True) def __call__(self, environ, start_response): """ Handle a WSGI request From 9cce88ab6a399881b9d1774a717a030c7e575913 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Thu, 30 Jan 2014 13:17:45 +0100 Subject: [PATCH 3/6] [ADD] Cross-Origin Resource Sharing support as http.route() argument bzr revid: fme@openerp.com-20140130121745-zjuuves1yhydydpx --- openerp/http.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/openerp/http.py b/openerp/http.py index 09a0a8d1d57..35cf8f39a7c 100644 --- a/openerp/http.py +++ b/openerp/http.py @@ -207,7 +207,7 @@ class WebRequest(object): warnings.warn('please use request.registry and request.cr directly', DeprecationWarning) yield (self.registry, self.cr) -def route(route, type="http", auth="user", methods=None): +def route(route, type="http", auth="user", methods=None, cors=None): """ Decorator marking the decorated method as being a handler for requests. The method must be part of a subclass of ``Controller``. @@ -225,6 +225,7 @@ def route(route, type="http", auth="user", methods=None): authentication modules. There request code will not have any facilities to access the database nor have any configuration indicating the current database nor the current user. :param methods: A sequence of http methods this route applies to. If not specified, all methods are allowed. + :param cors: The Access-Control-Allow-Origin cors directive value. """ assert type in ["http", "json"] def decorator(f): @@ -234,6 +235,7 @@ def route(route, type="http", auth="user", methods=None): f.routes = [route] f.methods = methods f.exposed = type + f.cors = cors if getattr(f, "auth", None) is None: f.auth = auth return f @@ -955,6 +957,12 @@ class Root(object): if not explicit_session and hasattr(response, 'set_cookie'): response.set_cookie('session_id', httprequest.session.sid, max_age=90 * 24 * 60 * 60) + # Support for Cross-Origin Resource Sharing + if request.func.cors: + response.headers.set('Access-Control-Allow-Origin', request.func.cors) + if request.func.methods: + response.headers.set('Access-Control-Allow-Methods', ','.join(request.func.methods)) + return response def dispatch(self, environ, start_response): From b63b03abd0c8109faa32803d2ae32663e1b64133 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Thu, 30 Jan 2014 13:26:54 +0100 Subject: [PATCH 4/6] [IMP] better handling of methods for CORS bzr revid: fme@openerp.com-20140130122654-2p481p5hwn033mi7 --- openerp/http.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/openerp/http.py b/openerp/http.py index 35cf8f39a7c..717582e2ec5 100644 --- a/openerp/http.py +++ b/openerp/http.py @@ -960,8 +960,12 @@ class Root(object): # Support for Cross-Origin Resource Sharing if request.func.cors: response.headers.set('Access-Control-Allow-Origin', request.func.cors) - if request.func.methods: - response.headers.set('Access-Control-Allow-Methods', ','.join(request.func.methods)) + methods = 'GET, POST' + if request.func_request_type == 'json': + methods = 'POST' + elif request.func.methods: + methods = ', '.join(request.func.methods) + response.headers.set('Access-Control-Allow-Methods', methods) return response From 9ce7c7d561ba3f2aff9f2eafda1c8dffd05e8b1f Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Thu, 30 Jan 2014 13:27:52 +0100 Subject: [PATCH 5/6] [IMP] Use CORS in pos (only two routes) bzr revid: fme@openerp.com-20140130122752-kfgo7u0q0crn3tbr --- addons/hw_proxy/controllers/main.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/addons/hw_proxy/controllers/main.py b/addons/hw_proxy/controllers/main.py index adb59a072b3..e6c19e322d6 100644 --- a/addons/hw_proxy/controllers/main.py +++ b/addons/hw_proxy/controllers/main.py @@ -33,16 +33,11 @@ class Proxy(http.Controller): statuses[driver] = drivers[driver].get_status() return statuses - @http.route('/hw_proxy/hello', type='http', auth='none') + @http.route('/hw_proxy/hello', type='http', auth='none', cors='*') def hello(self): - return request.make_response('ping', { - 'Cache-Control': 'no-cache', - 'Content-Type': 'text/html; charset=utf-8', - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Methods': 'GET', - }) + return "ping" - @http.route('/hw_proxy/handshake', type='json', auth='none') + @http.route('/hw_proxy/handshake', type='json', auth='none', cors='*') def handshake(self): return True From d5031cbee897f8fe6fa111a3cfe4f6510aff9e92 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Thu, 30 Jan 2014 13:46:06 +0100 Subject: [PATCH 6/6] [ADD] POS: added cors argument to all routes bzr revid: fme@openerp.com-20140130124606-wetmhcjqqvvkv5dy --- addons/hw_escpos/controllers/main.py | 4 +-- addons/hw_proxy/controllers/main.py | 44 +++++++++++++-------------- addons/hw_scanner/controllers/main.py | 4 +-- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/addons/hw_escpos/controllers/main.py b/addons/hw_escpos/controllers/main.py index 5b42e97b442..b4312fb94a8 100644 --- a/addons/hw_escpos/controllers/main.py +++ b/addons/hw_escpos/controllers/main.py @@ -259,12 +259,12 @@ hw_proxy.drivers['escpos'] = driver class EscposProxy(hw_proxy.Proxy): - @http.route('/hw_proxy/open_cashbox', type='json', auth='none') + @http.route('/hw_proxy/open_cashbox', type='json', auth='none', cors='*') def open_cashbox(self): _logger.info('ESC/POS: OPEN CASHBOX') driver.push_task('cashbox') - @http.route('/hw_proxy/print_receipt', type='json', auth='none') + @http.route('/hw_proxy/print_receipt', type='json', auth='none', cors='*') def print_receipt(self, receipt): _logger.info('ESC/POS: PRINT RECEIPT') driver.push_task('receipt',receipt) diff --git a/addons/hw_proxy/controllers/main.py b/addons/hw_proxy/controllers/main.py index e6c19e322d6..5293abd1f25 100644 --- a/addons/hw_proxy/controllers/main.py +++ b/addons/hw_proxy/controllers/main.py @@ -41,7 +41,7 @@ class Proxy(http.Controller): def handshake(self): return True - @http.route('/hw_proxy/status', type='http', auth='none') + @http.route('/hw_proxy/status', type='http', auth='none', cors='*') def status_http(self): resp = '\n\n

Hardware Proxy Status

\n' statuses = self.get_status() @@ -70,39 +70,39 @@ class Proxy(http.Controller): 'Access-Control-Allow-Methods': 'GET', }) - @http.route('/hw_proxy/status_json', type='json', auth='none') + @http.route('/hw_proxy/status_json', type='json', auth='none', cors='*') def status_json(self): return self.get_status() - @http.route('/hw_proxy/scan_item_success', type='json', auth='none') + @http.route('/hw_proxy/scan_item_success', type='json', auth='none', cors='*') def scan_item_success(self, ean): """ A product has been scanned with success """ print 'scan_item_success: ' + str(ean) - @http.route('/hw_proxy/scan_item_error_unrecognized', type='json', auth='none') + @http.route('/hw_proxy/scan_item_error_unrecognized', type='json', auth='none', cors='*') def scan_item_error_unrecognized(self, ean): """ A product has been scanned without success """ print 'scan_item_error_unrecognized: ' + str(ean) - @http.route('/hw_proxy/help_needed', type='json', auth='none') + @http.route('/hw_proxy/help_needed', type='json', auth='none', cors='*') def help_needed(self): """ The user wants an help (ex: light is on) """ print "help_needed" - @http.route('/hw_proxy/help_canceled', type='json', auth='none') + @http.route('/hw_proxy/help_canceled', type='json', auth='none', cors='*') def help_canceled(self): """ The user stops the help request """ print "help_canceled" - @http.route('/hw_proxy/weighting_start', type='json', auth='none') + @http.route('/hw_proxy/weighting_start', type='json', auth='none', cors='*') def weighting_start(self): if self.scale == 'closed': print "Opening (Fake) Connection to Scale..." @@ -113,7 +113,7 @@ class Proxy(http.Controller): else: print "WARNING: Scale already Connected !!!" - @http.route('/hw_proxy/weighting_read_kg', type='json', auth='none') + @http.route('/hw_proxy/weighting_read_kg', type='json', auth='none', cors='*') def weighting_read_kg(self): if self.scale == 'open': print "Reading Scale..." @@ -125,7 +125,7 @@ class Proxy(http.Controller): print "WARNING: Reading closed scale !!!" return 0.0 - @http.route('/hw_proxy/weighting_end', type='json', auth='none') + @http.route('/hw_proxy/weighting_end', type='json', auth='none', cors='*') def weighting_end(self): if self.scale == 'open': print "Closing Connection to Scale ..." @@ -136,7 +136,7 @@ class Proxy(http.Controller): else: print "WARNING: Scale already Closed !!!" - @http.route('/hw_proxy/payment_request', type='json', auth='none') + @http.route('/hw_proxy/payment_request', type='json', auth='none', cors='*') def payment_request(self, price): """ The PoS will activate the method payment @@ -144,55 +144,55 @@ class Proxy(http.Controller): print "payment_request: price:"+str(price) return 'ok' - @http.route('/hw_proxy/payment_status', type='json', auth='none') + @http.route('/hw_proxy/payment_status', type='json', auth='none', cors='*') def payment_status(self): print "payment_status" return { 'status':'waiting' } - @http.route('/hw_proxy/payment_cancel', type='json', auth='none') + @http.route('/hw_proxy/payment_cancel', type='json', auth='none', cors='*') def payment_cancel(self): print "payment_cancel" - @http.route('/hw_proxy/transaction_start', type='json', auth='none') + @http.route('/hw_proxy/transaction_start', type='json', auth='none', cors='*') def transaction_start(self): print 'transaction_start' - @http.route('/hw_proxy/transaction_end', type='json', auth='none') + @http.route('/hw_proxy/transaction_end', type='json', auth='none', cors='*') def transaction_end(self): print 'transaction_end' - @http.route('/hw_proxy/cashier_mode_activated', type='json', auth='none') + @http.route('/hw_proxy/cashier_mode_activated', type='json', auth='none', cors='*') def cashier_mode_activated(self): print 'cashier_mode_activated' - @http.route('/hw_proxy/cashier_mode_deactivated', type='json', auth='none') + @http.route('/hw_proxy/cashier_mode_deactivated', type='json', auth='none', cors='*') def cashier_mode_deactivated(self): print 'cashier_mode_deactivated' - @http.route('/hw_proxy/open_cashbox', type='json', auth='none') + @http.route('/hw_proxy/open_cashbox', type='json', auth='none', cors='*') def open_cashbox(self): print 'open_cashbox' - @http.route('/hw_proxy/print_receipt', type='json', auth='none') + @http.route('/hw_proxy/print_receipt', type='json', auth='none', cors='*') def print_receipt(self, receipt): print 'print_receipt' + str(receipt) - @http.route('/hw_proxy/is_scanner_connected', type='json', auth='none') + @http.route('/hw_proxy/is_scanner_connected', type='json', auth='none', cors='*') def print_receipt(self, receipt): print 'is_scanner_connected?' return False - @http.route('/hw_proxy/scanner', type='json', auth='none') + @http.route('/hw_proxy/scanner', type='json', auth='none', cors='*') def print_receipt(self, receipt): print 'scanner' time.sleep(10) return '' - @http.route('/hw_proxy/log', type='json', auth='none') + @http.route('/hw_proxy/log', type='json', auth='none', cors='*') def log(self, arguments): _logger.info(' '.join(str(v) for v in arguments)) - @http.route('/hw_proxy/print_pdf_invoice', type='json', auth='none') + @http.route('/hw_proxy/print_pdf_invoice', type='json', auth='none', cors='*') def print_pdf_invoice(self, pdfinvoice): print 'print_pdf_invoice' + str(pdfinvoice) diff --git a/addons/hw_scanner/controllers/main.py b/addons/hw_scanner/controllers/main.py index 664606954c3..105856a3e28 100644 --- a/addons/hw_scanner/controllers/main.py +++ b/addons/hw_scanner/controllers/main.py @@ -124,7 +124,7 @@ class Scanner(Thread): self.set_status('error',str(e)) return None - @http.route('/hw_proxy/Vis_scanner_connected', type='json', auth='none') + @http.route('/hw_proxy/Vis_scanner_connected', type='json', auth='none', cors='*') def is_scanner_connected(self): return self.get_device() != None @@ -207,7 +207,7 @@ s = Scanner() hw_proxy.drivers['scanner'] = s class ScannerDriver(hw_proxy.Proxy): - @http.route('/hw_proxy/scanner', type='json', auth='none') + @http.route('/hw_proxy/scanner', type='json', auth='none', cors='*') def scanner(self): if not s.isAlive(): s.start()