diff --git a/addons/partner_autocomplete/static/src/js/partner_autocomplete_core.js b/addons/partner_autocomplete/static/src/js/partner_autocomplete_core.js
index 74d32c74acc..08d0a9a5149 100644
--- a/addons/partner_autocomplete/static/src/js/partner_autocomplete_core.js
+++ b/addons/partner_autocomplete/static/src/js/partner_autocomplete_core.js
@@ -23,51 +23,51 @@ var PartnerAutocompleteMixin = {
* Get list of companies via Autocomplete API
*
* @param {string} value
- * @returns {Deferred}
+ * @returns {Promise}
* @private
*/
_autocomplete: function (value) {
+ var self = this;
value = value.trim();
- var def = $.Deferred(),
- isVAT = this._isVAT(value),
- odooSuggestions = [],
- clearbitSuggestions = [];
+ var isVAT = this._isVAT(value);
+ var odooSuggestions = [];
+ var clearbitSuggestions = [];
+ return new Promise(function (resolve, reject) {
+ var odooPromise = self._getOdooSuggestions(value, isVAT).then(function (suggestions){
+ odooSuggestions = suggestions;
+ });
- var odooPromise = this._getOdooSuggestions(value, isVAT).then(function (suggestions){
- odooSuggestions = suggestions;
+ // Only get Clearbit suggestions if not a VAT number
+ var clearbitPromise = isVAT ? false : self._getClearbitSuggestions(value).then(function (suggestions){
+ clearbitSuggestions = suggestions;
+ });
+
+ var concatResults = function () {
+ // Add Clearbit result with Odoo result (with unique domain)
+ if (clearbitSuggestions && clearbitSuggestions.length) {
+ var websites = odooSuggestions.map(function (suggestion) {
+ return suggestion.website;
+ });
+ clearbitSuggestions.forEach(function (suggestion) {
+ if (websites.indexOf(suggestion.domain) < 0) {
+ websites.push(suggestion.domain);
+ odooSuggestions.push(suggestion);
+ }
+ });
+ }
+
+ odooSuggestions = _.filter(odooSuggestions, function (suggestion) {
+ return !suggestion.ignored;
+ });
+ _.each(odooSuggestions, function(suggestion){
+ delete suggestion.ignored;
+ });
+ return resolve(odooSuggestions);
+ };
+
+ self._whenAll([odooPromise, clearbitPromise]).then(concatResults, concatResults);
});
- // Only get Clearbit suggestions if not a VAT number
- var clearbitPromise = isVAT ? false : this._getClearbitSuggestions(value).then(function (suggestions){
- clearbitSuggestions = suggestions;
- });
-
- var concatResults = function () {
- // Add Clearbit result with Odoo result (with unique domain)
- if (clearbitSuggestions && clearbitSuggestions.length) {
- var websites = odooSuggestions.map(function (suggestion) {
- return suggestion.website;
- });
- clearbitSuggestions.forEach(function (suggestion) {
- if (websites.indexOf(suggestion.domain) < 0) {
- websites.push(suggestion.domain);
- odooSuggestions.push(suggestion);
- }
- });
- }
-
- odooSuggestions = _.filter(odooSuggestions, function (suggestion) {
- return !suggestion.ignored;
- });
- _.each(odooSuggestions, function(suggestion){
- delete suggestion.ignored;
- });
- return def.resolve(odooSuggestions);
- };
-
- this._whenAll([odooPromise, clearbitPromise]).then(concatResults, concatResults);
-
- return def;
},
/**
@@ -77,7 +77,7 @@ var PartnerAutocompleteMixin = {
* @param {string} company.website
* @param {string} company.partner_gid
* @param {string} company.vat
- * @returns {Deferred}
+ * @returns {Promise}
* @private
*/
_enrichCompany: function (company) {
@@ -92,7 +92,7 @@ var PartnerAutocompleteMixin = {
* Get the company logo as Base 64 image from url
*
* @param {string} url
- * @returns {Deferred}
+ * @returns {Promise}
* @private
*/
_getCompanyLogo: function (url) {
@@ -106,7 +106,7 @@ var PartnerAutocompleteMixin = {
* Get enriched data + logo before populating partner form
*
* @param {Object} company
- * @returns {Deferred}
+ * @returns {Promise}
*/
_getCreateData: function (company) {
var self = this;
@@ -123,40 +123,38 @@ var PartnerAutocompleteMixin = {
});
};
- var def = $.Deferred();
+ return new Promise(function (resolve) {
+ // Fetch additional company info via Autocomplete Enrichment API
+ var enrichPromise = self._enrichCompany(company);
- // Fetch additional company info via Autocomplete Enrichment API
- var enrichPromise = this._enrichCompany(company);
+ // Get logo
+ var logoPromise = company.logo ? self._getCompanyLogo(company.logo) : false;
+ self._whenAll([enrichPromise, logoPromise]).then(function (result) {
+ var company_data = result[0];
+ var logo_data = result[1];
- // Get logo
- var logoPromise = company.logo ? this._getCompanyLogo(company.logo) : false;
+ if (company_data.error && company_data.error_message === 'Insufficient Credit') {
+ self._notifyNoCredits();
+ company_data = company;
+ }
- this._whenAll([enrichPromise, logoPromise]).always(function (company_data, logo_data){
- if (Array.isArray(company_data)) company_data = company_data[0];
- else company_data = {};
+ if (_.isEmpty(company_data)) {
+ company_data = company;
+ }
- if (Array.isArray(logo_data)) logo_data = logo_data[0];
- else logo_data = '';
+ // Delete attribute to avoid "Field_changed" errors
+ removeUselessFields(company_data);
- if (company_data.error && company_data.error_message === 'Insufficient Credit'){
- self._notifyNoCredits();
- company_data = company;
- }
-
- if (_.isEmpty(company_data)) company_data = company;
-
- // Delete attribute to avoid "Field_changed" errors
- removeUselessFields(company_data);
-
- // Assign VAT coming from parent VIES VAT query
- if (company.vat) company_data.vat = company.vat;
- def.resolve({
- company: company_data,
- logo: logo_data
+ // Assign VAT coming from parent VIES VAT query
+ if (company.vat) {
+ company_data.vat = company.vat;
+ }
+ resolve({
+ company: company_data,
+ logo: logo_data
+ });
});
});
-
- return def;
},
/**
@@ -186,35 +184,35 @@ var PartnerAutocompleteMixin = {
//--------------------------------------------------------------------------
/**
- * Returns a deferred which will be resolved with the base64 data of the
+ * Returns a promise which will be resolved with the base64 data of the
* image fetched from the given url.
*
* @private
* @param {string} url : the url where to find the image to fetch
- * @returns {Deferred}
+ * @returns {Promise}
*/
_getBase64Image: function (url) {
- var def = $.Deferred();
- var xhr = new XMLHttpRequest();
- xhr.onload = function () {
- var reader = new FileReader();
- reader.onloadend = function () {
- def.resolve(reader.result);
+ return new Promise(function (resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.onload = function () {
+ var reader = new FileReader();
+ reader.onloadend = function () {
+ resolve(reader.result);
+ };
+ reader.readAsDataURL(xhr.response);
};
- reader.readAsDataURL(xhr.response);
- };
- xhr.open('GET', url);
- xhr.responseType = 'blob';
- xhr.onerror = def.reject.bind(def);
- xhr.send();
- return def;
+ xhr.open('GET', url);
+ xhr.responseType = 'blob';
+ xhr.onerror = reject;
+ xhr.send();
+ });
},
/**
* Use Clearbit Autocomplete API to return suggestions
*
* @param {string} value
- * @returns {Deferred}
+ * @returns {Promise}
* @private
*/
_getClearbitSuggestions: function (value) {
@@ -242,7 +240,7 @@ var PartnerAutocompleteMixin = {
*
* @param {string} value
* @param {boolean} isVAT
- * @returns {Deferred}
+ * @returns {Promise}
* @private
*/
_getOdooSuggestions: function (value, isVAT) {
@@ -298,72 +296,26 @@ var PartnerAutocompleteMixin = {
/**
* Utility to wait for multiple promises
- * $.when will reject all promises whenever a promise is rejected
+ * Promise.all will reject all promises whenever a promise is rejected
* This utility will continue
- * Source : https://gist.github.com/fearphage/4341799
*
- * @param array
- * @returns {*}
+ * @param {Promise[]} promises
+ * @returns {Promise}
* @private
*/
- _whenAll: function (array) {
- var slice = [].slice;
-
- var
- resolveValues = arguments.length === 1 && $.isArray(array)
- ? array
- : slice.call(arguments)
- , length = resolveValues.length
- , remaining = length
- , deferred = $.Deferred()
- , i = 0
- , failed = 0
- , rejectContexts = Array(length)
- , rejectValues = Array(length)
- , resolveContexts = Array(length)
- , value
- ;
-
- function updateFunc(index, contexts, values) {
- return function () {
- !(values === resolveValues) && failed++;
- deferred.notifyWith(
- contexts[index] = this
- , values[index] = slice.call(arguments)
- );
- if (!(--remaining)) {
- deferred[(!failed ? 'resolve' : 'reject') + 'With'](contexts, values);
- }
- };
- }
-
- for (; i < length; i++) {
- if ((value = resolveValues[i]) && $.isFunction(value.promise)) {
- value.promise()
- .done(updateFunc(i, resolveContexts, resolveValues))
- .fail(updateFunc(i, rejectContexts, rejectValues))
- ;
- }
- else {
- deferred.notifyWith(this, value);
- --remaining;
- }
- }
-
- if (!remaining) {
- deferred.resolveWith(resolveContexts, resolveValues);
- }
-
- return deferred.promise();
+ _whenAll: function (promises) {
+ return Promise.all(promises.map(function (p) {
+ return Promise.resolve(p);
+ }));
},
/**
- * @private
- * @returns {$.Promise}
+ * @private
+ * @returns {Promise}
*/
_notifyNoCredits: function () {
var self = this;
- this._rpc({
+ return this._rpc({
model: 'iap.account',
method: 'get_credits_url',
args: ['partner_autocomplete'],
diff --git a/addons/partner_autocomplete/static/src/js/partner_autocomplete_fieldchar.js b/addons/partner_autocomplete/static/src/js/partner_autocomplete_fieldchar.js
index 3a6374de5fc..efac26ca098 100644
--- a/addons/partner_autocomplete/static/src/js/partner_autocomplete_fieldchar.js
+++ b/addons/partner_autocomplete/static/src/js/partner_autocomplete_fieldchar.js
@@ -135,14 +135,15 @@ var FieldAutocomplete = FieldChar.extend(AutocompleteMixin, {
self.trigger_up('field_changed', {
dataPointID: self.dataPointID,
changes: data.company,
+ onSuccess: function () {
+ // update the input's value directly
+ if (self.onlyVAT)
+ self.$input.val(self._formatValue(company.vat));
+ else
+ self.$input.val(self._formatValue(company.name));
+ },
});
});
-
- // update the input's value directly
- if (this.onlyVAT)
- this.$input.val(this._formatValue(company.vat));
- else
- this.$input.val(this._formatValue(company.name));
this._removeDropdown();
},
diff --git a/addons/partner_autocomplete/static/src/js/partner_autocomplete_many2one.js b/addons/partner_autocomplete/static/src/js/partner_autocomplete_many2one.js
index 5a3334e8094..a594373f720 100644
--- a/addons/partner_autocomplete/static/src/js/partner_autocomplete_many2one.js
+++ b/addons/partner_autocomplete/static/src/js/partner_autocomplete_many2one.js
@@ -35,7 +35,7 @@ var PartnerField = FieldMany2One.extend(AutocompleteMixin, {
* Action : create popup form with pre-filled values from Autocomplete
*
* @param {Object} company
- * @returns {Deferred}
+ * @returns {Promise}
* @private
*/
_createPartner: function (company) {
@@ -78,7 +78,7 @@ var PartnerField = FieldMany2One.extend(AutocompleteMixin, {
*/
_modifyAutompleteRendering: function (){
var api = this.$input.data('ui-autocomplete');
- // FIXME: bugfix to prevent traceback in mobile apps due to override
+ // FIXME: bugfix to prevent traceback in mobile apps due to override
// of Many2one widget with native implementation.
if (!api) {
return;
@@ -114,40 +114,38 @@ var PartnerField = FieldMany2One.extend(AutocompleteMixin, {
*
* @override
* @param search_val {string}
- * @returns {Deferred}
+ * @returns {Promise}
* @private
*/
_searchSuggestions: function (search_val) {
- var def = $.Deferred();
+ var self = this;
+ return new Promise(function (resolve, reject) {
+ if (self._isOnline()) {
- if (this._isOnline()) {
- var self = this;
+ self._autocomplete(search_val).then(function (suggestions) {
+ var choices = [];
+ if (suggestions && suggestions.length) {
+ _.each(suggestions, function (suggestion) {
+ var label = ' ';
+ label += _.str.sprintf('%s, %s', suggestion.label, suggestion.description);
- self._autocomplete(search_val).then(function (suggestions) {
- var choices = [];
- if (suggestions && suggestions.length) {
- _.each(suggestions, function (suggestion) {
- var label = ' ';
- label += _.str.sprintf('%s, %s', suggestion.label, suggestion.description);
-
- choices.push({
- label: label,
- action: function () {
- self._createPartner(suggestion);
- },
- logo: suggestion.logo,
- classname: 'o_partner_autocomplete_dropdown_item',
+ choices.push({
+ label: label,
+ action: function () {
+ self._createPartner(suggestion);
+ },
+ logo: suggestion.logo,
+ classname: 'o_partner_autocomplete_dropdown_item',
+ });
});
- });
- }
+ }
- def.resolve(choices);
- });
- } else {
- def.resolve([]);
- }
-
- return def;
+ resolve(choices);
+ });
+ } else {
+ resolve([]);
+ }
+ });
},
});
diff --git a/addons/partner_autocomplete/static/tests/partner_autocomplete_tests.js b/addons/partner_autocomplete/static/tests/partner_autocomplete_tests.js
index bae95b395a5..0f5a7fb7d1c 100644
--- a/addons/partner_autocomplete/static/tests/partner_autocomplete_tests.js
+++ b/addons/partner_autocomplete/static/tests/partner_autocomplete_tests.js
@@ -8,7 +8,7 @@ odoo.define('partner_autocomplete.tests', function (require) {
var PartnerField = require('partner.autocomplete.many2one');
var NotificationService = require('web.NotificationService');
- var createView = testUtils.createAsyncView;
+ var createView = testUtils.createView;
function _compareResultFields(assert, form, fields, createData) {
var type, formatted, $fieldInput;
@@ -54,7 +54,7 @@ odoo.define('partner_autocomplete.tests', function (require) {
_.each(fieldsToPatch, function (fieldToPatch) {
testUtils.mock.patch(fieldToPatch, {
_getBase64Image: function (url) {
- return $.when(url === "odoo.com/logo.png" ? "odoobase64" : "");
+ return Promise.resolve(url === "odoo.com/logo.png" ? "odoobase64" : "");
},
_isOnline: function () {
return true;
@@ -67,7 +67,7 @@ odoo.define('partner_autocomplete.tests', function (require) {
return def;
},
_enrichCompany: function (company) {
- return $.when(enrichData);
+ return Promise.resolve(enrichData);
},
_getOdooSuggestions: function (value, isVAT) {
var results = _.filter(suggestions, function (suggestion) {
@@ -75,7 +75,7 @@ odoo.define('partner_autocomplete.tests', function (require) {
if (isVAT) return (suggestion.vat.toLowerCase().indexOf(value) >= 0);
else return (suggestion.name.toLowerCase().indexOf(value) >= 0);
});
- return $.when(results);
+ return Promise.resolve(results);
},
_getClearbitSuggestions: function (value) {
return this._getOdooSuggestions(value);
@@ -185,11 +185,10 @@ odoo.define('partner_autocomplete.tests', function (require) {
});
- QUnit.test("Partner autocomplete : Company type = Company / Name search", function (assert) {
- assert.expect(21);
- var done = assert.async();
+ QUnit.test("Partner autocomplete : Company type = Company / Name search", async function (assert) {
+ assert.expect(18);
var fields = this.data['res.partner'].fields;
- createView({
+ var form = await createView({
View: FormView,
model: 'res.partner',
data: this.data,
@@ -209,34 +208,31 @@ odoo.define('partner_autocomplete.tests', function (require) {
'' +
'' +
'',
- mockRPC: function (route, args) {
- if (args.method) {
- assert.step(args.method);
- }
+ mockRPC: function (route) {
if (route === "/web/static/src/img/placeholder.png"
|| route === "odoo.com/logo.png"
|| route === "data:image/png;base64,odoobase64") { // land here as it is not valid base64 content
- return $.when();
+ return Promise.resolve();
}
return this._super.apply(this, arguments);
},
- }).then(function (form){
+ });
// Set company type to Company
var $company_type = form.$("select[name='company_type']");
- testUtils.fields.editSelect($company_type, '"company"');
+ await testUtils.fields.editSelect($company_type, '"company"');
// Check input exists
var $input = form.$(".o_field_partner_autocomplete > input:visible");
assert.strictEqual($input.length, 1, "there should be an for the field");
// Change input val and assert changes
- testUtils.fields.editInput($input, "odoo")
-
+ await testUtils.fields.editInput($input, "odoo");
+ await testUtils.nextTick();
var $dropdown = form.$(".o_field_partner_autocomplete .dropdown-menu:visible");
assert.strictEqual($dropdown.length, 1, "there should be an opened dropdown");
- assert.strictEqual($dropdown.children().length, 1, "there should be only one proposition");
+ assert.strictEqual($dropdown.children().length, 1, "there should be only ne proposition");
- testUtils.dom.click($dropdown.find("a").first());
+ await testUtils.dom.click($dropdown.find("a").first());
$input = form.$(".o_field_partner_autocomplete > input");
assert.strictEqual($input.val(), "Odoo", "Input value should have been updated to \"Odoo\"");
assert.strictEqual(form.$("input.o_field_widget").val(), "odoo.com", "website value should have been updated to \"odoo.com\"");
@@ -244,31 +240,29 @@ odoo.define('partner_autocomplete.tests', function (require) {
_compareResultFields(assert, form, fields, createData);
// Try suggestion with bullshit query
- testUtils.fields.editInput($input, "ZZZZZZZZZZZZZZZZZZZZZZ")
+ await testUtils.fields.editInput($input, "ZZZZZZZZZZZZZZZZZZZZZZ");
$dropdown = form.$(".o_field_partner_autocomplete .dropdown-menu:visible");
assert.strictEqual($dropdown.length, 0, "there should be no opened dropdown when no result");
// Try autocomplete again
- testUtils.fields.editInput($input, "odoo")
+ await testUtils.fields.editInput($input, "odoo");
+ await testUtils.nextTick();
$dropdown = form.$(".o_field_partner_autocomplete .dropdown-menu:visible");
assert.strictEqual($dropdown.length, 1, "there should be an opened dropdown when typing odoo letters again");
// Test if dropdown closes on focusout
$input.trigger("focusout");
+ await testUtils.nextTick();
$dropdown = form.$(".o_field_partner_autocomplete .dropdown-menu:visible");
assert.strictEqual($dropdown.length, 0, "unfocusing the input should close the dropdown");
form.destroy();
-
- done();
- });
});
- QUnit.test("Partner autocomplete : Company type = Company / VAT search", function (assert) {
- assert.expect(32);
- var done = assert.async();
+ QUnit.test("Partner autocomplete : Company type = Company / VAT search", async function (assert) {
+ assert.expect(29);
var fields = this.data['res.partner'].fields;
- createView({
+ var form = await createView({
View: FormView,
model: 'res.partner',
data: this.data,
@@ -288,21 +282,18 @@ odoo.define('partner_autocomplete.tests', function (require) {
'' +
'' +
'',
- mockRPC: function (route, args) {
- if (args.method) {
- assert.step(args.method);
- }
+ mockRPC: function (route) {
if (route === "/web/static/src/img/placeholder.png"
|| route === "odoo.com/logo.png"
|| route === "data:image/png;base64,odoobase64") { // land here as it is not valid base64 content
- return $.when();
+ return Promise.resolve();
}
return this._super.apply(this, arguments);
},
- }).then(function (form){
+ });
// Set company type to Company
var $company_type = form.$("select[name='company_type']");
- testUtils.fields.editSelect($company_type, '"company"');
+ await testUtils.fields.editSelect($company_type, '"company"');
// Check input exists
@@ -310,33 +301,33 @@ odoo.define('partner_autocomplete.tests', function (require) {
assert.strictEqual($input.length, 1, "there should be an for the field");
// Set incomplete VAT and assert changes
- testUtils.fields.editInput($input, "BE047747270")
+ await testUtils.fields.editInput($input, "BE047747270")
var $dropdown = form.$(".o_field_partner_autocomplete .dropdown-menu:visible");
assert.strictEqual($dropdown.length, 0, "there should be no opened dropdown no results with incomplete VAT number");
// Set complete VAT and assert changes
// First suggestion (only vat result)
- testUtils.fields.editInput($input, "BE0477472701")
+ await testUtils.fields.editInput($input, "BE0477472701")
$dropdown = form.$(".o_field_partner_autocomplete .dropdown-menu:visible");
assert.strictEqual($dropdown.length, 1, "there should be an opened dropdown");
assert.strictEqual($dropdown.children().length, 1, "there should be one proposition for complete VAT number");
- testUtils.dom.click($dropdown.find("a").first());
+ await testUtils.dom.click($dropdown.find("a").first());
$input = form.$(".o_field_partner_autocomplete > input");
assert.strictEqual($input.val(), "Odoo", "Input value should have been updated to \"Odoo\"");
_compareResultFields(assert, form, fields, createData);
-
+ await testUtils.nextTick();
// Set complete VAT and assert changes
// Second suggestion (only vat + clearbit result)
- testUtils.fields.editInput($input, "BE0477472701")
+ await testUtils.fields.editInput($input, "BE0477472701")
$dropdown = form.$(".o_field_partner_autocomplete .dropdown-menu:visible");
assert.strictEqual($dropdown.length, 1, "there should be an opened dropdown");
assert.strictEqual($dropdown.children().length, 1, "there should be one proposition for complete VAT number");
- testUtils.dom.click($dropdown.find("a").first());
+ await testUtils.dom.click($dropdown.find("a").first());
$input = form.$(".o_field_partner_autocomplete > input");
assert.strictEqual($input.val(), "Odoo", "Input value should have been updated to \"Odoo\"");
@@ -350,8 +341,6 @@ odoo.define('partner_autocomplete.tests', function (require) {
form.destroy();
- done();
- });
});
QUnit.test("Partner autocomplete : render Many2one", function (assert) {
@@ -390,16 +379,15 @@ odoo.define('partner_autocomplete.tests', function (require) {
});
});
- QUnit.test("Partner autocomplete : Notify not enough credits", function (assert) {
+ QUnit.test("Partner autocomplete : Notify not enough credits", async function (assert) {
assert.expect(1);
- var done = assert.async();
enrichData = {
error: true,
error_message: 'Insufficient Credit',
};
- createView({
+ var form = await createView({
View: FormView,
model: 'res.partner',
data: this.data,
@@ -413,26 +401,24 @@ odoo.define('partner_autocomplete.tests', function (require) {
},
mockRPC: function (route, args) {
if (args.method === "get_credits_url"){
- return $.when('credits_url');
+ return Promise.resolve('credits_url');
}
return this._super.apply(this, arguments);
},
- }).then(function (form){
+ });
// Set company type to Company
var $company_type = form.$("select[name='company_type']");
- testUtils.fields.editSelect($company_type, '"company"');
+ await testUtils.fields.editSelect($company_type, '"company"');
var $input = form.$(".o_field_partner_autocomplete > input:visible");
- testUtils.fields.editInput($input, "BE0477472701");
+ await testUtils.fields.editInput($input, "BE0477472701");
var $dropdown = form.$(".o_field_partner_autocomplete .dropdown-menu:visible");
- testUtils.dom.click($dropdown.find("a").first());
+ await testUtils.dom.click($dropdown.find("a").first());
var $notify = $(".o_partner_autocomplete_test_notify");
assert.isVisible($notify, "there should be an 'Insufficient Credit' notification");
form.destroy();
- done();
- });
});
});