From 822450cbb0b5529db76825e7fbce9724e6bb8ce4 Mon Sep 17 00:00:00 2001 From: Ivan Yelizariev Date: Tue, 3 Jan 2017 13:32:02 +0500 Subject: [PATCH 01/15] [CI] use 3 sec timeout by default; tune switch_to_order --- pos_multi_session/external_tests/tests/inject.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pos_multi_session/external_tests/tests/inject.js b/pos_multi_session/external_tests/tests/inject.js index 3d0c9ab024..8e722a9697 100644 --- a/pos_multi_session/external_tests/tests/inject.js +++ b/pos_multi_session/external_tests/tests/inject.js @@ -71,7 +71,11 @@ window.mstest = { $('.order-sequence').each(function(){ var order_num = $.trim($(this).html()).split("\n"); if (parseInt(order_num[2]) == order.order_num){ - $(this).click(); + if (!$(this).parent().hasClass('selected')){ + // click only on inactive tab. + // Otherwise Customer Selection screen will be opened + $(this).click(); + } return false; } }); @@ -117,7 +121,7 @@ window.mstest = { setTimeout(function(){ callback(); mstest.is_wait = false; - }, timeout || 1000); + }, timeout || 3000); }, }; From 08ef97c1b1927ae045478464c42538e63b9d506a Mon Sep 17 00:00:00 2001 From: Ivan Yelizariev Date: Tue, 3 Jan 2017 16:52:52 +0500 Subject: [PATCH 02/15] [CI] add ability to create screenshots --- pos_multi_session/.gitignore | 1 + pos_multi_session/external_tests/phantomtest.js | 12 ++++++++++++ pos_multi_session/external_tests/tests/test_sync.py | 1 + 3 files changed, 14 insertions(+) create mode 100644 pos_multi_session/.gitignore diff --git a/pos_multi_session/.gitignore b/pos_multi_session/.gitignore new file mode 100644 index 0000000000..e33609d251 --- /dev/null +++ b/pos_multi_session/.gitignore @@ -0,0 +1 @@ +*.png diff --git a/pos_multi_session/external_tests/phantomtest.js b/pos_multi_session/external_tests/phantomtest.js index 94751b347e..b860a59342 100644 --- a/pos_multi_session/external_tests/phantomtest.js +++ b/pos_multi_session/external_tests/phantomtest.js @@ -19,6 +19,7 @@ Modified phantomtest.js from odoo ( https://github.com/odoo/odoo/blob/8.0/opener [{"session": "session1", "extra": "connection_on" | "connection_off" | "connection_slow" + "screenshot": screenshot_name, "code": "console.log('ok')", "ready": false, # wait before calling next command "timeout": 60000, # code execution timeout @@ -28,6 +29,11 @@ Modified phantomtest.js from odoo ( https://github.com/odoo/odoo/blob/8.0/opener * to communicate between commands, variable ``share`` can be used. It's saved right after execution finish. It's not save in async code (e.g. inside setTimeout function) +* screenshot: + + * make screenshot before execution of the code + * filename is SESSION-SCREENSHOT-NUM.png + */ var system = require('system'); @@ -250,9 +256,15 @@ function PhantomTest() { sname = command.session; page = self.pages[sname]; extra = command.extra; + screenshot = command.screenshot; code = command.code || 'true'; ready = command.ready || 'true'; + if (screenshot){ + console.log('Make screenshot', screenshot); + page.render(sname + '-' + screenshot + '-' + i + '.png'); + } + console.log("PhantomTest.runCommands: executing: " + code); (function(){ var commandNum = i; diff --git a/pos_multi_session/external_tests/tests/test_sync.py b/pos_multi_session/external_tests/tests/test_sync.py index 57cc95197e..93e60d3584 100644 --- a/pos_multi_session/external_tests/tests/test_sync.py +++ b/pos_multi_session/external_tests/tests/test_sync.py @@ -157,6 +157,7 @@ def test_20_offline_update_order(self): }, # ok {"session": "demo", + "screenshot": "test-20-final", "code": "console.log('ok');", }, ], 120) From 0c001bd487a26983cdd9ae8bafef3307cde501f8 Mon Sep 17 00:00:00 2001 From: Ivan Yelizariev Date: Tue, 3 Jan 2017 16:53:29 +0500 Subject: [PATCH 03/15] [DOC][CI] how to run tests manually in normal browser --- pos_multi_session/external_tests/README.rst | 26 +++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/pos_multi_session/external_tests/README.rst b/pos_multi_session/external_tests/README.rst index 2ef57366f5..f28969730c 100644 --- a/pos_multi_session/external_tests/README.rst +++ b/pos_multi_session/external_tests/README.rst @@ -36,3 +36,29 @@ Odoo server * use database with demo data * use ``--db-filter`` it equal to database name * use ``--workers=0`` + +Run tests in browser +-------------------- + +You can try repeat test in real browser, though it's not very convenient + +* open odoo with localhost:8069 +* open POS interface +* copy-paste code from ``pos_multi_session/external_tests/tests/inject.js`` +* line-by-line copy-paste test js code from ``pos_multi_session/external_tests/tests/test_sync.py``, e.g. + + * in admin window:: + + console.log('test_10_new_order'); + mstest.remove_all_orders(); + + * in demo window:: + + mstest.remove_all_orders(); + + * in admin window:: + + mstest.fill_order(); + + * etc. + From 708d65938b7484d9cdbccf17b07f4ed4ebc15639 Mon Sep 17 00:00:00 2001 From: Ivan Yelizariev Date: Tue, 3 Jan 2017 17:46:38 +0500 Subject: [PATCH 04/15] [CI] add test_31_queue; add more debug logs --- .../external_tests/tests/test_sync.py | 77 +++++++++++++++++++ .../static/src/js/pos_multi_session.js | 13 +++- 2 files changed, 89 insertions(+), 1 deletion(-) diff --git a/pos_multi_session/external_tests/tests/test_sync.py b/pos_multi_session/external_tests/tests/test_sync.py index 93e60d3584..efcf2af477 100644 --- a/pos_multi_session/external_tests/tests/test_sync.py +++ b/pos_multi_session/external_tests/tests/test_sync.py @@ -380,3 +380,80 @@ def test_30_slow(self): "code": "console.log('ok');", }, ], 120) + + def test_31_queue(self): + """Single POS send two update request. + It would raise error 'sync conflicts', if there are no queue for sending updates. For example + * Order has revision_ID equal to 10 + * We send first update + * We send second update + * First request is reached the server. Server sets revision_ID equal to 11 + * Second request is reached the server. Server return revision_error, because in request revision_ID is 10, while server has revision_ID 11 + """ + + # current postpone timer for sending updates is 1000 ms + # connection_slow delay response to 3000 ms + + self.phantom_js_multi({ + # use default settings for sessions (see ./common.py) + "admin": {}, + }, [ + # admin removes orders + {"session": "admin", + "code": """ + console.log('test_31_slow'); + mstest.remove_all_orders(); + """, + }, + # admin creates order + {"session": "admin", + "code": """ + mstest.fill_order(); + mstest.print_order(); + mstest.wait(function(){ + }) + """, + }, + + # response for admin requests are delayed for 3 seconds + {"session": "admin", + "extra": "connection_slow", + "code": """ + console.log("admin requests are delayed") + """, + }, + # admin updates order + {"session": "admin", + "code": """ + console.log('Admin updates Order') + mstest.fill_order(); + console.log('Admin waits to send update request') + mstest.wait(function(){ + }, 1500) + """, + }, + # admin updates order again + {"session": "admin", + "code": """ + console.log('Admin updates Order again') + mstest.fill_order(); + """, + }, + # admin waits and receives error if queue doesn't work + {"session": "admin", + "code": """ + mstest.wait(function(){ + }, 10000) + """, + "timeout": 20000, + }, + # connection is on + {"session": "admin", + "extra": "connection_on", + }, + # ok + {"session": "admin", + "screenshot": "test-31-final", + "code": "console.log('ok');", + }, + ], 120) diff --git a/pos_multi_session/static/src/js/pos_multi_session.js b/pos_multi_session/static/src/js/pos_multi_session.js index ff686e03d5..d3da590b2a 100644 --- a/pos_multi_session/static/src/js/pos_multi_session.js +++ b/pos_multi_session/static/src/js/pos_multi_session.js @@ -410,9 +410,12 @@ openerp.pos_multi_session = function(instance){ update: function(data){ return this.send({action: 'update_order', data: data}); }, + _debug_send_number: 0, send: function(message){ + var current_send_number = 0; if (this.pos.debug){ - console.log('MS', this.pos.config.name, 'send:', JSON.stringify(message)); + current_send_number = this._debug_send_number++; + console.log('MS', this.pos.config.name, 'send #' + current_send_number +' :', JSON.stringify(message)); } var self = this; var connection_status = new $.Deferred(); @@ -424,6 +427,9 @@ openerp.pos_multi_session = function(instance){ }); }; send_it().fail(function (error, e) { + if (self.pos.debug){ + console.log('MS', self.pos.config.name, 'failed request #'+current_send_number+':', error); + } if(error.message === 'XmlHttpRequestError ') { self.client_online = false; e.preventDefault(); @@ -438,6 +444,10 @@ openerp.pos_multi_session = function(instance){ self.request_sync_all(); } }).done(function(res){ + if (self.pos.debug){ + console.log('MS', self.pos.config.name, 'response #'+current_send_number+':', JSON.stringify(res)); + } + var server_orders_uid = []; self.client_online = true; if (res.action == "update_revision_ID") { @@ -446,6 +456,7 @@ openerp.pos_multi_session = function(instance){ connection_status.resolve(); if (res.action == "revision_error") { var warning_message = _t('There is a conflict during synchronization, try your action again'); + console.log('error', warning_message); self.warning(warning_message); self.request_sync_all(); } From f3808d41cbb8d6e13cd0fd0607c730169dadca0f Mon Sep 17 00:00:00 2001 From: Ivan Yelizariev Date: Tue, 3 Jan 2017 17:59:12 +0500 Subject: [PATCH 05/15] [CI] try to use trusty on travis to fix error with PIL File "/home/travis/odoo-8.0/openerp/addons/base/res/res_partner.py", line 325, in _get_default_image image = tools.image_colorize(image) File "/home/travis/odoo-8.0/openerp/tools/image.py", line 186, in image_colorize image.paste(color) File "/home/travis/.local/lib/python2.7/site-packages/PIL/Image.py", line 1319, in paste "cannot determine region size; use 4-item box" ParseError: "cannot determine region size; use 4-item box" while parsing /home/travis/odoo-8.0/addons/auth_signup/auth_signup_data.xml:6, near Template User portaltemplate _usertemplate 2017-01-03 12:51:45,475 5491 INFO openerp_template openerp.service.server: Initiating shutdown --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index a5fe02e362..1060d08968 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,7 @@ language: python python: - "2.7" +dist: trusty sudo: false cache: pip From 2212cbe8660a134020fbbbe3b75af68eecf787c2 Mon Sep 17 00:00:00 2001 From: Ivan Yelizariev Date: Wed, 4 Jan 2017 10:58:35 +0500 Subject: [PATCH 06/15] [CI] * don't raise error "revision_error" in test_30 (#208) * improve debug logs * check for revision_error in other tests * add session name in log "runCommands: executing" * print warning text in logs on showing warning_message --- pos_multi_session/external_tests/phantomtest.js | 2 +- pos_multi_session/external_tests/tests/inject.js | 6 +++++- pos_multi_session/external_tests/tests/test_sync.py | 9 +++++++-- pos_multi_session/static/src/js/pos_multi_session.js | 4 ++-- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/pos_multi_session/external_tests/phantomtest.js b/pos_multi_session/external_tests/phantomtest.js index b860a59342..37d54421aa 100644 --- a/pos_multi_session/external_tests/phantomtest.js +++ b/pos_multi_session/external_tests/phantomtest.js @@ -265,7 +265,7 @@ function PhantomTest() { page.render(sname + '-' + screenshot + '-' + i + '.png'); } - console.log("PhantomTest.runCommands: executing: " + code); + console.log("PhantomTest.runCommands: executing as "+sname+ ": " + code); (function(){ var commandNum = i; timer = setTimeout(function () { diff --git a/pos_multi_session/external_tests/tests/inject.js b/pos_multi_session/external_tests/tests/inject.js index 8e722a9697..4808fbf60c 100644 --- a/pos_multi_session/external_tests/tests/inject.js +++ b/pos_multi_session/external_tests/tests/inject.js @@ -123,5 +123,9 @@ window.mstest = { mstest.is_wait = false; }, timeout || 3000); }, - + check_revision_error: function(){ + warning_message = 'There is a conflict during synchronization, try your action again'; + if ($('.modal .in').text() == warning_message) + console.log('error', warning_message); + }, }; diff --git a/pos_multi_session/external_tests/tests/test_sync.py b/pos_multi_session/external_tests/tests/test_sync.py index efcf2af477..f7f93637df 100644 --- a/pos_multi_session/external_tests/tests/test_sync.py +++ b/pos_multi_session/external_tests/tests/test_sync.py @@ -144,6 +144,9 @@ def test_20_offline_update_order(self): "code": """ mstest.fill_order(); share.order = mstest.get_order(); + mstest.wait(function(){ + mstest.check_revision_error(); + }, 5000) """, }, # check sync on demo @@ -151,7 +154,7 @@ def test_20_offline_update_order(self): "code": """ mstest.wait(function(){ mstest.find_order(share.order); - }, 20000) + }, 10000) """, "timeout": 25000, }, @@ -172,7 +175,7 @@ def test_21_offline_remove_order(self): # admin removes orders {"session": "admin", "code": """ - console.log('test_20_offline'); + console.log('test_21_offline_remove_order'); mstest.remove_all_orders(); """, }, @@ -234,6 +237,7 @@ def test_21_offline_remove_order(self): # demo creates new order (to start reconnection process) {"session": "demo", "code": """ + console.log('demo creates new order (to start reconnection process)') mstest.new_order(); mstest.fill_order(); mstest.wait(function(){ @@ -443,6 +447,7 @@ def test_31_queue(self): {"session": "admin", "code": """ mstest.wait(function(){ + mstest.check_revision_error(); }, 10000) """, "timeout": 20000, diff --git a/pos_multi_session/static/src/js/pos_multi_session.js b/pos_multi_session/static/src/js/pos_multi_session.js index d3da590b2a..1acaef5572 100644 --- a/pos_multi_session/static/src/js/pos_multi_session.js +++ b/pos_multi_session/static/src/js/pos_multi_session.js @@ -428,7 +428,7 @@ openerp.pos_multi_session = function(instance){ }; send_it().fail(function (error, e) { if (self.pos.debug){ - console.log('MS', self.pos.config.name, 'failed request #'+current_send_number+':', error); + console.log('MS', self.pos.config.name, 'failed request #'+current_send_number+':', error.message); } if(error.message === 'XmlHttpRequestError ') { self.client_online = false; @@ -456,7 +456,6 @@ openerp.pos_multi_session = function(instance){ connection_status.resolve(); if (res.action == "revision_error") { var warning_message = _t('There is a conflict during synchronization, try your action again'); - console.log('error', warning_message); self.warning(warning_message); self.request_sync_all(); } @@ -499,6 +498,7 @@ openerp.pos_multi_session = function(instance){ self.send_offline_orders(); }, warning: function(warning_message){ + console.info('warning', warning_message); var self = this; new instance.web.Dialog(this, { title: _t("Warning"), From af2cbcc06676ca71187d01ecf1ac1093e2a9d7e0 Mon Sep 17 00:00:00 2001 From: Dinar Date: Wed, 1 Feb 2017 18:03:34 +0500 Subject: [PATCH 07/15] [ADD] added new common module pos_longpolling for POS (#213) --- pos_longpolling/README.rst | 29 +++++++ pos_longpolling/__init__.py | 2 + pos_longpolling/__manifest__.py | 34 ++++++++ pos_longpolling/doc/changelog.rst | 4 + pos_longpolling/doc/index.rst | 25 ++++++ pos_longpolling/models/__init__.py | 2 + .../models/pos_longpolling_models.py | 15 ++++ .../static/src/js/pos_longpolling.js | 87 +++++++++++++++++++ .../views/pos_longpolling_template.xml | 10 +++ 9 files changed, 208 insertions(+) create mode 100644 pos_longpolling/README.rst create mode 100644 pos_longpolling/__init__.py create mode 100644 pos_longpolling/__manifest__.py create mode 100644 pos_longpolling/doc/changelog.rst create mode 100644 pos_longpolling/doc/index.rst create mode 100644 pos_longpolling/models/__init__.py create mode 100644 pos_longpolling/models/pos_longpolling_models.py create mode 100644 pos_longpolling/static/src/js/pos_longpolling.js create mode 100644 pos_longpolling/views/pos_longpolling_template.xml diff --git a/pos_longpolling/README.rst b/pos_longpolling/README.rst new file mode 100644 index 0000000000..d7213ef4a3 --- /dev/null +++ b/pos_longpolling/README.rst @@ -0,0 +1,29 @@ +================= + POS Longpolling +================= + +Technical module implement instant updates in POS + +Credits +======= + +Contributors +------------ +* gabbasov@it-projects.info + +Sponsors +-------- +* `IT-Projects LLC `__ + +Further information +=================== + +Demo: http://runbot.it-projects.info/demo/pos-addons/10.0 + +HTML Description: https://apps.odoo.com/apps/modules/10.0/pos_longpolling/ + +Usage instructions: ``__ + +Changelog: ``__ + +Tested on Odoo 10.0 6a7c05112bf0c07ffa7dadfe76be08f3121fd4c8 diff --git a/pos_longpolling/__init__.py b/pos_longpolling/__init__.py new file mode 100644 index 0000000000..a0fdc10fe1 --- /dev/null +++ b/pos_longpolling/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +from . import models diff --git a/pos_longpolling/__manifest__.py b/pos_longpolling/__manifest__.py new file mode 100644 index 0000000000..ecfefde8f5 --- /dev/null +++ b/pos_longpolling/__manifest__.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +{ + "name": """POS Longpolling""", + "summary": """Technical module implement instant updates in POS""", + "category": "Point of Sale", + "images": [], + "version": "1.0.0", + "application": False, + + "author": "IT-Projects LLC, Dinar Gabbasov", + "support": "apps@it-projects.info", + "website": "https://twitter.com/gabbasov_dinar", + "license": "LGPL-3", + # "price": 0.00, + # "currency": "EUR", + + "depends": [ + "bus", + "point_of_sale", + ], + "external_dependencies": {"python": [], "bin": []}, + "data": [ + "views/pos_longpolling_template.xml", + ], + 'qweb': [], + "demo": [], + + "post_load": None, + "pre_init_hook": None, + "post_init_hook": None, + + "auto_install": False, + "installable": True, +} diff --git a/pos_longpolling/doc/changelog.rst b/pos_longpolling/doc/changelog.rst new file mode 100644 index 0000000000..9ee2b48b8e --- /dev/null +++ b/pos_longpolling/doc/changelog.rst @@ -0,0 +1,4 @@ +`1.0.0` +------- + +- Init version diff --git a/pos_longpolling/doc/index.rst b/pos_longpolling/doc/index.rst new file mode 100644 index 0000000000..251d360eb7 --- /dev/null +++ b/pos_longpolling/doc/index.rst @@ -0,0 +1,25 @@ +================= + POS Longpolling +================= + +Longpolling +=========== + +Check following resources about activating longpolling: + +* Official doc: https://www.odoo.com/documentation/8.0/setup/deploy.html#builtin-server +* Non-official doc: https://odoo-development.readthedocs.io/en/latest/admin/longpolling.html + +In short, you need to start server with non-zero ``workers`` parameter::: + + openerp-server --workers=2 ... + +and configure nginx: :: + + location /longpolling { + proxy_pass http://127.0.0.1:8072; + } + location / { + proxy_pass http://127.0.0.1:8069; + } + diff --git a/pos_longpolling/models/__init__.py b/pos_longpolling/models/__init__.py new file mode 100644 index 0000000000..b8c8f25918 --- /dev/null +++ b/pos_longpolling/models/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +from . import pos_longpolling_models diff --git a/pos_longpolling/models/pos_longpolling_models.py b/pos_longpolling/models/pos_longpolling_models.py new file mode 100644 index 0000000000..11fd1a04a5 --- /dev/null +++ b/pos_longpolling/models/pos_longpolling_models.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +from odoo import api, models + + +class PosConfig(models.Model): + _inherit = 'pos.config' + + @api.multi + def _send_to_channel(self, channel_name, message): + notifications = [] + for ps in self.env['pos.session'].search([('state', '!=', 'closed'), ('id', 'in', self.ids)]): + channel = '["%s","%s","%s"]' % (self._cr.dbname, channel_name, ps.config_id.id) + notifications.append([channel, message]) + self.env['bus.bus'].sendmany(notifications) + return 1 diff --git a/pos_longpolling/static/src/js/pos_longpolling.js b/pos_longpolling/static/src/js/pos_longpolling.js new file mode 100644 index 0000000000..aff4f95522 --- /dev/null +++ b/pos_longpolling/static/src/js/pos_longpolling.js @@ -0,0 +1,87 @@ +odoo.define('pos_longpolling', function(require){ + var exports = {}; + + var session = require('web.session'); + var core = require('web.core'); + var models = require('point_of_sale.models'); + var bus = require('bus.bus'); + var chrome = require('point_of_sale.chrome'); + + var _t = core._t; + + // prevent bus to be started by chat_manager.js + bus.bus.activated = true; // fake value to ignore start_polling call + + var PosModelSuper = models.PosModel; + models.PosModel = models.PosModel.extend({ + initialize: function(){ + var self = this; + PosModelSuper.prototype.initialize.apply(this, arguments); + this.channels = {}; + this.lonpolling_activated = false; + this.bus = bus.bus; + this.ready.then(function () { + self.start_longpolling(); + }); + }, + start_longpolling: function(){ + var self = this; + this.bus.last = this.db.load('bus_last', 0); + this.bus.on("notification", this, this.on_notification); + this.bus.stop_polling(); + _.each(self.channels, function(value, key){ + self.init_channel(key); + }); + this.bus.start_polling(); + this.lonpolling_activated = true; + }, + add_channel: function(channel_name, callback) { + this.channels[channel_name] = callback; + if (this.lonpolling_activated) { + this.init_channel(channel_name) + } + }, + get_full_channel_name: function(channel_name){ + return JSON.stringify([session.db,channel_name,String(this.config.id)]); + }, + init_channel: function(channel_name){ + var channel = this.get_full_channel_name(channel_name); + this.bus.add_channel(channel); + }, + remove_channel: function(channel_name) { + if (channel_name in this.channels) { + delete this.channels[channel_name]; + var channel = this.get_full_channel_name(channel_name); + this.bus.delete_channel(channel); + } + }, + on_notification: function(notification) { + for (var i = 0; i < notification.length; i++) { + var channel = notification[i][0]; + var message = notification[i][1]; + this.on_notification_do(channel, message); + } + this.db.save('bus_last', this.bus.last); + }, + on_notification_do: function (channel, message) { + var self = this; + var channel = JSON.parse(channel); + if(Array.isArray(channel) && (channel[1] in self.channels)){ + try{ + var callback = self.channels[channel[1]]; + if (callback) { + if (self.debug){ + console.log('POS LONGPOLLING', self.config.name, channel[1], JSON.stringify(message)); + } + callback(message); + } + }catch(err){ + this.chrome.gui.show_popup('error',{ + 'title': _t('Error'), + 'body': err, + }); + } + } + } + }); +}); diff --git a/pos_longpolling/views/pos_longpolling_template.xml b/pos_longpolling/views/pos_longpolling_template.xml new file mode 100644 index 0000000000..a4d3b3b1f2 --- /dev/null +++ b/pos_longpolling/views/pos_longpolling_template.xml @@ -0,0 +1,10 @@ + + + + + + From a5d0e247fb024598a51b7656fbde66663956c107 Mon Sep 17 00:00:00 2001 From: Ivan Yelizariev Date: Fri, 3 Feb 2017 14:17:41 +0500 Subject: [PATCH 08/15] [FIX] pos_longpolling: fix domain to check closed session [IMP] add logs [REF] _get_full_channel_name in python [IMP] add_channel -- allow to pass thisArg --- pos_longpolling/models/pos_longpolling_models.py | 16 +++++++++++++--- pos_longpolling/static/src/js/pos_longpolling.js | 7 +++++-- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/pos_longpolling/models/pos_longpolling_models.py b/pos_longpolling/models/pos_longpolling_models.py index 11fd1a04a5..ddae040199 100644 --- a/pos_longpolling/models/pos_longpolling_models.py +++ b/pos_longpolling/models/pos_longpolling_models.py @@ -1,6 +1,9 @@ # -*- coding: utf-8 -*- +import logging from odoo import api, models +_logger = logging.getLogger(__name__) + class PosConfig(models.Model): _inherit = 'pos.config' @@ -8,8 +11,15 @@ class PosConfig(models.Model): @api.multi def _send_to_channel(self, channel_name, message): notifications = [] - for ps in self.env['pos.session'].search([('state', '!=', 'closed'), ('id', 'in', self.ids)]): - channel = '["%s","%s","%s"]' % (self._cr.dbname, channel_name, ps.config_id.id) + for ps in self.env['pos.session'].search([('state', '!=', 'closed'), ('config_id', 'in', self.ids)]): + channel = ps.config_id._get_full_channel_name(channel_name) notifications.append([channel, message]) - self.env['bus.bus'].sendmany(notifications) + if notifications: + self.env['bus.bus'].sendmany(notifications) + _logger.debug('POS notifications for %s: %s', self.ids, notifications) return 1 + + @api.multi + def _get_full_channel_name(self, channel_name): + self.ensure_one() + return '["%s","%s","%s"]' % (self._cr.dbname, channel_name, self.id) diff --git a/pos_longpolling/static/src/js/pos_longpolling.js b/pos_longpolling/static/src/js/pos_longpolling.js index aff4f95522..d8dca26ad9 100644 --- a/pos_longpolling/static/src/js/pos_longpolling.js +++ b/pos_longpolling/static/src/js/pos_longpolling.js @@ -35,10 +35,13 @@ odoo.define('pos_longpolling', function(require){ this.bus.start_polling(); this.lonpolling_activated = true; }, - add_channel: function(channel_name, callback) { + add_channel: function(channel_name, callback, thisArg) { + if (thisArg){ + callback = _.bind(callback, thisArg); + } this.channels[channel_name] = callback; if (this.lonpolling_activated) { - this.init_channel(channel_name) + this.init_channel(channel_name); } }, get_full_channel_name: function(channel_name){ From 3396bc13e49418be6de0abe47ac08d22f11292e1 Mon Sep 17 00:00:00 2001 From: GabbasovDinar Date: Wed, 8 Feb 2017 13:04:37 +0500 Subject: [PATCH 09/15] [BACKPORT] fixes porting errors in 10.0 to 8.0 --- pos_longpolling/README.rst | 6 ++-- .../{__manifest__.py => __openerp__.py} | 2 +- .../models/pos_longpolling_models.py | 2 +- .../static/src/js/pos_longpolling.js | 34 ++++++++----------- .../views/pos_longpolling_template.xml | 6 ++-- 5 files changed, 23 insertions(+), 27 deletions(-) rename pos_longpolling/{__manifest__.py => __openerp__.py} (96%) diff --git a/pos_longpolling/README.rst b/pos_longpolling/README.rst index d7213ef4a3..16347231b4 100644 --- a/pos_longpolling/README.rst +++ b/pos_longpolling/README.rst @@ -18,12 +18,12 @@ Sponsors Further information =================== -Demo: http://runbot.it-projects.info/demo/pos-addons/10.0 +Demo: http://runbot.it-projects.info/demo/pos-addons/8.0 -HTML Description: https://apps.odoo.com/apps/modules/10.0/pos_longpolling/ +HTML Description: https://apps.odoo.com/apps/modules/8.0/pos_longpolling/ Usage instructions: ``__ Changelog: ``__ -Tested on Odoo 10.0 6a7c05112bf0c07ffa7dadfe76be08f3121fd4c8 +Tested on Odoo 8.0 8ce1e5134037dfe6cfbd756813e9baa31a221958 diff --git a/pos_longpolling/__manifest__.py b/pos_longpolling/__openerp__.py similarity index 96% rename from pos_longpolling/__manifest__.py rename to pos_longpolling/__openerp__.py index ecfefde8f5..23652fec2b 100644 --- a/pos_longpolling/__manifest__.py +++ b/pos_longpolling/__openerp__.py @@ -10,7 +10,7 @@ "author": "IT-Projects LLC, Dinar Gabbasov", "support": "apps@it-projects.info", "website": "https://twitter.com/gabbasov_dinar", - "license": "LGPL-3", + "license": "GPL-3", # "price": 0.00, # "currency": "EUR", diff --git a/pos_longpolling/models/pos_longpolling_models.py b/pos_longpolling/models/pos_longpolling_models.py index ddae040199..5808f97432 100644 --- a/pos_longpolling/models/pos_longpolling_models.py +++ b/pos_longpolling/models/pos_longpolling_models.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- import logging -from odoo import api, models +from openerp import api, models _logger = logging.getLogger(__name__) diff --git a/pos_longpolling/static/src/js/pos_longpolling.js b/pos_longpolling/static/src/js/pos_longpolling.js index d8dca26ad9..8fe877e730 100644 --- a/pos_longpolling/static/src/js/pos_longpolling.js +++ b/pos_longpolling/static/src/js/pos_longpolling.js @@ -1,25 +1,18 @@ -odoo.define('pos_longpolling', function(require){ - var exports = {}; - - var session = require('web.session'); - var core = require('web.core'); - var models = require('point_of_sale.models'); - var bus = require('bus.bus'); - var chrome = require('point_of_sale.chrome'); - - var _t = core._t; +openerp.pos_longpolling = function(instance){ + var module = instance.point_of_sale; + var _t = instance.web._t; // prevent bus to be started by chat_manager.js - bus.bus.activated = true; // fake value to ignore start_polling call + openerp.bus.bus.activated = true; // fake value to ignore start_polling call - var PosModelSuper = models.PosModel; - models.PosModel = models.PosModel.extend({ + var PosModelSuper = module.PosModel; + module.PosModel = module.PosModel.extend({ initialize: function(){ var self = this; PosModelSuper.prototype.initialize.apply(this, arguments); this.channels = {}; this.lonpolling_activated = false; - this.bus = bus.bus; + this.bus = openerp.bus.bus; this.ready.then(function () { self.start_longpolling(); }); @@ -45,7 +38,7 @@ odoo.define('pos_longpolling', function(require){ } }, get_full_channel_name: function(channel_name){ - return JSON.stringify([session.db,channel_name,String(this.config.id)]); + return JSON.stringify([openerp.session.db,channel_name,String(this.config.id)]); }, init_channel: function(channel_name){ var channel = this.get_full_channel_name(channel_name); @@ -59,6 +52,9 @@ odoo.define('pos_longpolling', function(require){ } }, on_notification: function(notification) { + if (typeof notification[0][0] === 'string') { + notification = [notification]; + } for (var i = 0; i < notification.length; i++) { var channel = notification[i][0]; var message = notification[i][1]; @@ -79,12 +75,12 @@ odoo.define('pos_longpolling', function(require){ callback(message); } }catch(err){ - this.chrome.gui.show_popup('error',{ - 'title': _t('Error'), - 'body': err, + self.pos_widget.screen_selector.show_popup('error',{ + message: _t('Error'), + comment: err, }); } } } }); -}); +}; diff --git a/pos_longpolling/views/pos_longpolling_template.xml b/pos_longpolling/views/pos_longpolling_template.xml index a4d3b3b1f2..03503b3dc1 100644 --- a/pos_longpolling/views/pos_longpolling_template.xml +++ b/pos_longpolling/views/pos_longpolling_template.xml @@ -1,10 +1,10 @@ - + -