From b131e9b0ef458e8cc00b0a2eb6c1b4d8dfe889a0 Mon Sep 17 00:00:00 2001 From: Akash Bhavsar Date: Mon, 26 Jun 2017 17:24:01 +0530 Subject: [PATCH] [FIX] barcodes: fix several issues when scanning barcodes Since the new views, most of the barcodes feature was broken. This commit re-enables the support of commands like 'edit', 'save', 'cancel', 'previous' and 'next'. Also changed javascript event handler to jquery event handler to make barcodes testable in phantomjs. --- .../barcodes/static/src/js/barcode_events.js | 22 ++-- .../barcodes/static/src/js/barcode_field.js | 2 +- .../static/src/js/barcode_form_view.js | 55 ++++++-- addons/barcodes/static/tests/barcode_tests.js | 121 ++++++++++++++++++ addons/barcodes/views/barcodes_templates.xml | 6 + addons/web/static/tests/helpers/test_utils.js | 15 +++ 6 files changed, 197 insertions(+), 24 deletions(-) create mode 100644 addons/barcodes/static/tests/barcode_tests.js diff --git a/addons/barcodes/static/src/js/barcode_events.js b/addons/barcodes/static/src/js/barcode_events.js index 04c03a41308..0f13c59fe66 100644 --- a/addons/barcodes/static/src/js/barcode_events.js +++ b/addons/barcodes/static/src/js/barcode_events.js @@ -77,13 +77,7 @@ var BarcodeEvents = core.Class.extend(mixins.PropertiesMixin, { 'bubbles': old_event.bubbles, 'cancelable': old_event.cancelable, }; - try { - new_event = new Event("keypress", params); - } catch(error) { - // For IE >= 9, use new CustomEvent(), instead of new Event() - new_event = new CustomEvent("keypress", params); - } - + new_event = $.Event('keypress', params); new_event.viewArg = old_event.viewArg; new_event.ctrl = old_event.ctrl; new_event.alt = old_event.alt; @@ -96,7 +90,7 @@ var BarcodeEvents = core.Class.extend(mixins.PropertiesMixin, { new_event.which = old_event.which; new_event.dispatched_by_barcode_reader = true; - old_event.target.dispatchEvent(new_event); + $(old_event.target).trigger(new_event); } } }, @@ -173,17 +167,17 @@ var BarcodeEvents = core.Class.extend(mixins.PropertiesMixin, { }, start: function(prevent_key_repeat){ - document.body.addEventListener('keypress', this.__handler, true); + $('body').bind("keypress", this.__handler); if (prevent_key_repeat === true) { - document.body.addEventListener('keydown', this.__keydown_handler, true); - document.body.addEventListener('keyup', this.__keyup_handler, true); + $('body').bind("keydown", this.__keydown_handler); + $('body').bind('keyup', this.__keyup_handler); } }, stop: function(){ - document.body.removeEventListener('keypress', this.__handler, true); - document.body.removeEventListener('keydown', this.__keydown_handler, true); - document.body.removeEventListener('keyup', this.__keyup_handler, true); + $('body').unbind("keypress", this.__handler); + $('body').unbind("keydown", this.__keydown_handler); + $('body').unbind('keyup', this.__keyup_handler); }, }); diff --git a/addons/barcodes/static/src/js/barcode_field.js b/addons/barcodes/static/src/js/barcode_field.js index aa31b4d8261..9b0f2391e3a 100644 --- a/addons/barcodes/static/src/js/barcode_field.js +++ b/addons/barcodes/static/src/js/barcode_field.js @@ -40,7 +40,7 @@ var FieldFloatScannable = basicFields.FieldFloat.extend({ */ _onKeypress: function (e) { /* only simulate a keypress if it has been previously prevented */ - if (e.originalEvent.dispatched_by_barcode_reader !== true) { + if (e.dispatched_by_barcode_reader !== true) { e.preventDefault(); this.$input.blur(); return; diff --git a/addons/barcodes/static/src/js/barcode_form_view.js b/addons/barcodes/static/src/js/barcode_form_view.js index 69a59fdaafa..37fa34dcf95 100644 --- a/addons/barcodes/static/src/js/barcode_form_view.js +++ b/addons/barcodes/static/src/js/barcode_form_view.js @@ -26,19 +26,21 @@ FormController.include({ this.activeBarcode = { form_view: { commands: { - 'O-CMD.NEW': 'createRecord', - 'O-CMD.EDIT': 'toEditMode', - 'O-CMD.CANCEL': 'discardChange', - 'O-CMD.SAVE': function () { return this.saveRecord({reload: true}); }, - // 'O-CMD.PAGER-PREV': - // 'O-CMD.PAGER-NEXT': - } - } + 'O-CMD.EDIT': this._onEdit.bind(this), + 'O-CMD.CANCEL': this._onDiscard.bind(this), + 'O-CMD.SAVE': this._onCommandSave.bind(this), + 'O-CMD.PAGER-PREV': this._onCommandPrevious.bind(this), + 'O-CMD.PAGER-NEXT': this._onCommandNext.bind(this), + }, + }, }; this.barcodeMutex = new concurrency.Mutex(); this._barcodeStartListening(); }, + /** + * @override + */ destroy: function () { this._barcodeStopListening(); this._super(); @@ -70,6 +72,8 @@ FormController.include({ } }, /** + * Returns true iff the given barcode matches the given record (candidate). + * * @private * @param {Object} candidate: record in the x2m * @param {string} barcode sent by the scanner (string generate from keypress series) @@ -128,7 +132,7 @@ FormController.include({ */ _getBarCodeRecord: function (record, barcode, activeBarcode) { var self = this; - if (!activeBarcode.fieldName) { + if (!activeBarcode.fieldName || !record.data[activeBarcode.fieldName]) { return; } return _.find(record.data[activeBarcode.fieldName].data, function (record) { @@ -237,6 +241,24 @@ FormController.include({ }); }); }, + /** + * @private + */ + _onCommandNext: function () { + return this.mutex.exec(function () {}).then(this.pager.next.bind(this.pager)); + }, + /** + * @private + */ + _onCommandPrevious: function () { + return this.mutex.exec(function () {}).then(this.pager.previous.bind(this.pager)); + }, + /** + * @private + */ + _onCommandSave: function () { + return this.saveRecord(); + }, /** * @private * @param {KeyEvent} event @@ -359,6 +381,21 @@ FormRenderer.include({ } return $button; }, + /** + * Add barcode event handler + * + * @override + * @private + * @param {Object} node + * @returns {jQueryElement} + */ + _renderTagButton: function (node) { + var $button = this._super.apply(this, arguments); + if (node.attrs.barcode_trigger) { + this._barcodeButtonHandler($button, node); + } + return $button; + } }); BarcodeEvents.ReservedBarcodePrefixes.push('O-BTN'); diff --git a/addons/barcodes/static/tests/barcode_tests.js b/addons/barcodes/static/tests/barcode_tests.js new file mode 100644 index 00000000000..09daebcd976 --- /dev/null +++ b/addons/barcodes/static/tests/barcode_tests.js @@ -0,0 +1,121 @@ +odoo.define('barcodes.tests', function (require) { +"use strict"; + +var testUtils = require('web.test_utils'); +var FormView = require('web.FormView'); + +var createView = testUtils.createView; +var triggerKeypressEvent = testUtils.triggerKeypressEvent; + +QUnit.module('Barcodes', { + beforeEach: function () { + this.data = { + product: { + fields: { + name: {string : "Product name", type: "char"}, + }, + records: [ + {id: 1, name: "iPad Mini"}, + {id: 2, name: "Mouse, Optical"}, + ], + }, + }; + } +}); + +QUnit.test('Button with barcode_trigger', function (assert) { + assert.expect(1); + + var form = createView({ + View: FormView, + model: 'product', + data: this.data, + arch: '
' + + '
' + + '
' + + '
', + res_id: 2, + intercepts: { + execute_action: function (event) { + assert.strictEqual(event.data.action_data.name, 'do_something', + "do_something method call verified"); + }, + }, + }); + + // O-BTN.doit + _.each(['O','-','B','T','N','.','d','o','i','t','Enter'], triggerKeypressEvent); + + form.destroy(); +}); + +QUnit.test('edit, save and cancel buttons', function (assert) { + assert.expect(6); + + var form = createView({ + View: FormView, + model: 'product', + data: this.data, + arch: '
', + mockRPC: function (route, args) { + if (args.method === 'write') { + assert.step('save'); + } + return this._super.apply(this, arguments); + }, + res_id: 1, + }); + + // O-CMD.EDIT + _.each(["O","-","C","M","D",".","E","D","I","T","Enter"], triggerKeypressEvent); + assert.strictEqual(form.$(".o_form_editable").length, 1, + "should have switched to 'edit' mode"); + // dummy change to check that it actually saves + form.$('.o_field_widget').val('test').trigger('input'); + // O-CMD.SAVE + _.each(["O","-","C","M","D",".","S","A","V","E","Enter"], triggerKeypressEvent); + assert.strictEqual(form.$(".o_form_readonly").length, 1, + "should have switched to 'readonly' mode"); + assert.verifySteps(['save'], 'should have saved'); + + // O-CMD.EDIT + _.each(["O","-","C","M","D",".","E","D","I","T","Enter"], triggerKeypressEvent); + // dummy change to check that it correctly discards + form.$('.o_field_widget').val('test').trigger('input'); + // O-CMD.CANCEL + _.each(["O","-","C","M","D",".","C","A","N","C","E","L","Enter"], triggerKeypressEvent); + assert.strictEqual(form.$(".o_form_readonly").length, 1, + "should have switched to 'readonly' mode"); + assert.verifySteps(['save'], 'should not have saved'); + + form.destroy(); +}); + +QUnit.test('pager buttons', function (assert) { + assert.expect(3); + + var form = createView({ + View: FormView, + model: 'product', + data: this.data, + arch: '
', + res_id: 1, + viewOptions: { + ids: [1, 2], + index: 0, + }, + }); + + assert.strictEqual(form.$('.o_field_widget').text(), 'iPad Mini'); + // O-CMD.PAGER-NEXT + _.each(["O","-","C","M","D",".","P","A","G","E","R","-","N","E","X","T","Enter"], triggerKeypressEvent); + assert.strictEqual(form.$('.o_field_widget').text(), 'Mouse, Optical'); + // O-CMD.PAGER-PREV + _.each(["O","-","C","M","D",".","P","A","G","E","R","-","P","R","E","V","Enter"], triggerKeypressEvent); + assert.strictEqual(form.$('.o_field_widget').text(), 'iPad Mini'); + + form.destroy(); +}); + +}); diff --git a/addons/barcodes/views/barcodes_templates.xml b/addons/barcodes/views/barcodes_templates.xml index 420a069a491..cb16a40c178 100644 --- a/addons/barcodes/views/barcodes_templates.xml +++ b/addons/barcodes/views/barcodes_templates.xml @@ -10,4 +10,10 @@ +