summaryrefslogtreecommitdiff
path: root/addons/base_iban/static/src
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/base_iban/static/src
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/base_iban/static/src')
-rw-r--r--addons/base_iban/static/src/js/iban_widget.js129
-rw-r--r--addons/base_iban/static/src/scss/iban_widget_view.scss16
-rw-r--r--addons/base_iban/static/src/tests/iban_widget_test.js65
3 files changed, 210 insertions, 0 deletions
diff --git a/addons/base_iban/static/src/js/iban_widget.js b/addons/base_iban/static/src/js/iban_widget.js
new file mode 100644
index 00000000..e56b78b1
--- /dev/null
+++ b/addons/base_iban/static/src/js/iban_widget.js
@@ -0,0 +1,129 @@
+odoo.define('base_iban.iban_widget', function (require) {
+"use strict";
+
+var basicFields = require('web.basic_fields');
+var core = require('web.core');
+var fieldRegistry = require('web.field_registry');
+
+var FieldChar = basicFields.FieldChar;
+
+var _t = core._t;
+/**
+ * IbanWidget is a widget to check if the iban number is valide.
+ * If the bank account is correct, it will show a green check pictogram
+ * next to number, if the number is not complient with IBAN format, a
+ * red cross will be show. This pictogram is computed every time the user
+ * changes the field (If user is typing, there is a debouce of 400ms).
+ */
+var IbanWidget = FieldChar.extend({
+ /**
+ * @constructor
+ */
+ init: function () {
+ this._super.apply(this, arguments);
+ this.ibanIsValid;
+ this._isValid = true;
+ this._compute_debounce = _.debounce(this._compute, 400);
+ },
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ * Compute if iban is valid
+ * @private
+ */
+ _compute: function () {
+ var self = this;
+ var content = this._getValue();
+
+ if (content.length === 0) {
+ this.ibanIsValid = true;
+ this.$el.last().filter('.o_iban').removeClass('fa-check text-success fa-times text-danger o_iban_fail');
+ this.$el.last().filter('.o_iban').attr('title', '');
+ } else if (content.length < 15) {
+ if (this.ibanIsValid !== false) {
+ this.ibanIsValid = false;
+ this._renderValid();
+ }
+ } else {
+ this._rpc({
+ model: 'res.partner.bank',
+ method: 'check_iban',
+ args: [[], content],
+ })
+ .then(function (result) {
+ if (result !== self.ibanIsValid) {
+ self.ibanIsValid = result;
+ self._renderValid();
+ }
+ });
+ }
+ },
+ /**
+ * @private
+ * @override
+ * @returns {Promise|undefined}
+ */
+ _renderEdit: function () {
+ var res = this._super.apply(this, arguments);
+ this._compute();
+ return res;
+ },
+ /**
+ * Render the pictogram next to account number.
+ * @private
+ */
+ _renderValid: function () {
+ var warningMessage = _t("Account isn't IBAN compliant.");
+
+ if (this.$el.filter('.o_iban').length === 0) {
+ var $span;
+ if (!this.ibanIsValid) {
+ $span = $('<span class="fa fa-times o_iban text-danger o_iban_fail"/>');
+ $span.attr('title', warningMessage);
+ } else {
+ $span = $('<span class="fa fa-check o_iban text-success"/>');
+ }
+ this.$el.addClass('o_iban_input_with_validator');
+ $span.insertAfter(this.$el);
+ this.$el = this.$el.add($span);
+ }
+
+ if (!this.ibanIsValid) {
+ this.$el.last().filter('.o_iban').removeClass('fa-check text-success').addClass('fa-times text-danger o_iban_fail');
+ this.$el.last().filter('.o_iban').attr('title', warningMessage);
+ } else {
+ this.$el.last().filter('.o_iban').removeClass('fa-times text-danger o_iban_fail').addClass('fa-check text-success');
+ this.$el.last().filter('.o_iban').attr('title', '');
+
+ }
+ },
+
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+
+ /**
+ * @override
+ * @private
+ */
+ _onChange: function () {
+ this._super.apply(this, arguments);
+ this._compute();
+ },
+ /**
+ * @override
+ * @private
+ */
+ _onInput: function () {
+ this._super.apply(this, arguments);
+ this._compute_debounce();
+ },
+});
+
+fieldRegistry.add('iban', IbanWidget);
+
+return IbanWidget;
+});
diff --git a/addons/base_iban/static/src/scss/iban_widget_view.scss b/addons/base_iban/static/src/scss/iban_widget_view.scss
new file mode 100644
index 00000000..a226960e
--- /dev/null
+++ b/addons/base_iban/static/src/scss/iban_widget_view.scss
@@ -0,0 +1,16 @@
+.o_form_view {
+
+ // Iban widget warning
+ .o_iban {
+ display: inline-flex;
+ margin-left: -15px;
+ margin-top: 5px;
+ }
+ .o_iban_fail {
+ cursor: help;
+ }
+ .o_iban_input_with_validator {
+ padding-right: 20px!important;
+ }
+
+}
diff --git a/addons/base_iban/static/src/tests/iban_widget_test.js b/addons/base_iban/static/src/tests/iban_widget_test.js
new file mode 100644
index 00000000..3fe954d7
--- /dev/null
+++ b/addons/base_iban/static/src/tests/iban_widget_test.js
@@ -0,0 +1,65 @@
+odoo.define('base_iban.iban_widget_tests', function (require) {
+"use strict";
+
+var FormView = require('web.FormView');
+var testUtils = require('web.test_utils');
+
+var createView = testUtils.createView;
+
+QUnit.module('fields', {
+ beforeEach: function () {
+ this.data = {
+ partner: {
+ fields: {
+ acc_number: {string: "acc_number", type: "char"},
+ },
+ records: [{
+ id: 1,
+ acc_number: "",
+ }]
+ },
+ };
+ // patch _.debounce to be fast and synchronous
+ this.underscoreDebounce = _.debounce;
+ _.debounce = _.identity;
+ },
+ afterEach: function () {
+ // unpatch _.debounce
+ _.debounce = this.underscoreDebounce;
+ }
+}, function () {
+
+ QUnit.module('IbanWidget');
+
+ QUnit.test('Iban widgets are correctly rendered', async function (assert) {
+ assert.expect(6);
+ var form = await createView({
+ View: FormView,
+ model: 'partner',
+ data: this.data,
+ arch: '<form><sheet><field name="acc_number" widget="iban"/></sheet></form>',
+ mockRPC: function (route, args) {
+ if (args.method === 'check_iban') {
+ console.log(args.args[1] === "BE00 0000 0000 0000 0000")
+ return Promise.resolve(args.args[1] === "BE00 0000 0000 0000 0000");
+ }
+ return this._super.apply(this, arguments);
+ },
+ });
+
+ await testUtils.fields.editAndTrigger(form.$('.o_field_widget'), "BE00", 'input');
+ assert.containsOnce(form, '.o_iban_fail', "Should be a False account, it's too short");
+ assert.containsOnce(form, '.fa-times', "Should have a cross pictogram");
+
+ await testUtils.fields.editAndTrigger(form.$('.o_field_widget'), "BE00 0000 0000 0000 0000", 'input');
+ assert.containsOnce(form, '.text-success', "Should have text-success");
+ assert.containsOnce(form, '.fa-check', "Should have a valid pictogram");
+
+ await testUtils.fields.editAndTrigger(form.$('.o_field_widget'), "BE00 xxxx xxxx xxxx xxxx", 'input');
+ assert.containsOnce(form, '.o_iban_fail', "Should be False account");
+ assert.containsOnce(form, '.fa-times', "Should have a cross pictogram");
+
+ form.destroy();
+ });
+});
+});