summaryrefslogtreecommitdiff
path: root/addons/partner_autocomplete/static
diff options
context:
space:
mode:
authorAntoine Prieels (ANP) <anp@odoo.com>2018-11-21 11:53:01 +0000
committerAntoine Prieels (ANP) <anp@odoo.com>2018-11-28 10:32:20 +0000
commit8b930c648d15b8b873d4ee4a8042f95825d28896 (patch)
treefa5be1336f53e754cb8f3818bffe645b420366e8 /addons/partner_autocomplete/static
parentfea93a9dd6154961f4dcdb652bc580ec0d6a83ef (diff)
[IMP] partner_autocomplete: Notify when user out of credits
closes odoo/odoo#29309
Diffstat (limited to 'addons/partner_autocomplete/static')
-rw-r--r--addons/partner_autocomplete/static/src/js/partner_autocomplete_core.js66
-rw-r--r--addons/partner_autocomplete/static/src/js/partner_autocomplete_fieldchar.js10
-rw-r--r--addons/partner_autocomplete/static/src/js/partner_autocomplete_many2one.js12
-rw-r--r--addons/partner_autocomplete/static/src/xml/partner_autocomplete.xml7
-rw-r--r--addons/partner_autocomplete/static/tests/partner_autocomplete_tests.js154
5 files changed, 179 insertions, 70 deletions
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 a5f4188615b..c36d2f1a29c 100644
--- a/addons/partner_autocomplete/static/src/js/partner_autocomplete_core.js
+++ b/addons/partner_autocomplete/static/src/js/partner_autocomplete_core.js
@@ -1,14 +1,20 @@
-odoo.define('partner.autocomplete.core', function (require) {
+odoo.define('partner.autocomplete.Mixin', function (require) {
'use strict';
-var rpc = require('web.rpc');
var concurrency = require('web.concurrency');
-return {
+var core = require('web.core');
+var Qweb = core.qweb;
+var _t = core._t;
+
+/**
+ * This mixin only works with classes having EventDispatcherMixin in 'web.mixins'
+ */
+var PartnerAutocompleteMixin = {
_dropPreviousOdoo: new concurrency.DropPrevious(),
_dropPreviousClearbit: new concurrency.DropPrevious(),
_timeout : 1000, // Timeout for Clearbit autocomplete in ms
-
+
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
@@ -20,7 +26,7 @@ return {
* @returns {Deferred}
* @private
*/
- autocomplete: function (value) {
+ _autocomplete: function (value) {
value = value.trim();
var def = $.Deferred(),
isVAT = this._isVAT(value),
@@ -62,11 +68,14 @@ return {
* Get enrichment data
*
* @param {Object} company
+ * @param {string} company.website
+ * @param {string} company.partner_gid
+ * @param {string} company.vat
* @returns {Deferred}
* @private
*/
- enrichCompany: function (company) {
- return rpc.query({
+ _enrichCompany: function (company) {
+ return this._rpc({
model: 'res.partner',
method: 'enrich_company',
args: [company.website, company.partner_gid, company.vat],
@@ -80,7 +89,7 @@ return {
* @returns {Deferred}
* @private
*/
- getCompanyLogo: function (url) {
+ _getCompanyLogo: function (url) {
return this._getBase64Image(url).then(function (base64Image) {
// base64Image equals "data:" if image not available on given url
return base64Image ? base64Image.replace(/^data:image[^;]*;base64,?/, '') : false;
@@ -93,7 +102,9 @@ return {
* @param {Object} company
* @returns {Deferred}
*/
- getCreateData: function (company) {
+ _getCreateData: function (company) {
+ var self = this;
+
var removeUselessFields = function (company) {
var fields = 'label,description,domain,logo,legal_name'.split(',');
fields.forEach(function (field) {
@@ -109,10 +120,10 @@ return {
var def = $.Deferred();
// Fetch additional company info via Autocomplete Enrichment API
- var enrichPromise = this.enrichCompany(company);
+ var enrichPromise = this._enrichCompany(company);
// Get logo
- var logoPromise = company.logo ? this.getCompanyLogo(company.logo) : false;
+ var logoPromise = company.logo ? this._getCompanyLogo(company.logo) : false;
this._whenAll([enrichPromise, logoPromise]).always(function (company_data, logo_data){
if (Array.isArray(company_data)) company_data = company_data[0];
@@ -121,6 +132,11 @@ return {
if (Array.isArray(logo_data)) logo_data = logo_data[0];
else logo_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
@@ -142,7 +158,7 @@ return {
*
* @returns {boolean}
*/
- isOnline: function () {
+ _isOnline: function () {
return navigator && navigator.onLine;
},
@@ -154,7 +170,7 @@ return {
* @returns {boolean}
* @private
*/
- validateSearchTerm: function (search_val, onlyVAT) {
+ _validateSearchTerm: function (search_val, onlyVAT) {
if (onlyVAT) return this._isVAT(search_val);
else return search_val && search_val.length > 2;
},
@@ -226,7 +242,7 @@ return {
_getOdooSuggestions: function (value, isVAT) {
var method = isVAT ? 'read_by_vat' : 'autocomplete';
- var def = rpc.query({
+ var def = this._rpc({
model: 'res.partner',
method: method,
args: [value],
@@ -334,5 +350,27 @@ return {
return deferred.promise();
},
+
+ /**
+ * @private
+ * @returns {$.Promise}
+ */
+ _notifyNoCredits: function () {
+ var self = this;
+ this._rpc({
+ model: 'iap.account',
+ method: 'get_credits_url',
+ args: ['partner_autocomplete'],
+ }).then(function (url) {
+ var title = _t('Not enough credits for Partner Autocomplete');
+ var content = Qweb.render('partner_autocomplete.insufficient_credit_notification', {
+ credits_url: url
+ });
+ self.do_notify(title, content, false, 'o_partner_autocomplete_no_credits_notify');
+ });
+ },
};
+
+return PartnerAutocompleteMixin;
+
});
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 b1843ec8de1..3a6374de5fc 100644
--- a/addons/partner_autocomplete/static/src/js/partner_autocomplete_fieldchar.js
+++ b/addons/partner_autocomplete/static/src/js/partner_autocomplete_fieldchar.js
@@ -4,7 +4,7 @@ odoo.define('partner.autocomplete.fieldchar', function (require) {
var basic_fields = require('web.basic_fields');
var core = require('web.core');
var field_registry = require('web.field_registry');
-var Autocomplete = require('partner.autocomplete.core');
+var AutocompleteMixin = require('partner.autocomplete.Mixin');
var QWeb = core.qweb;
@@ -15,7 +15,7 @@ var FieldChar = basic_fields.FieldChar;
* name on a res.partner view (indeed, it is designed to change the "name",
* "website" and "image" fields of records of this model).
*/
-var FieldAutocomplete = FieldChar.extend({
+var FieldAutocomplete = FieldChar.extend(AutocompleteMixin, {
className: 'o_field_partner_autocomplete',
debounceSuggestions: 400,
resetOnAnyFieldChange: true,
@@ -112,7 +112,7 @@ var FieldAutocomplete = FieldChar.extend({
*/
_selectCompany: function (company) {
var self = this;
- Autocomplete.getCreateData(company).then(function (data) {
+ this._getCreateData(company).then(function (data) {
if (data.logo) {
var logoField = self.model === 'res.partner' ? 'image' : 'logo';
data.company[logoField] = data.logo;
@@ -190,8 +190,8 @@ var FieldAutocomplete = FieldChar.extend({
*/
_suggestCompanies: function (value) {
var self = this;
- if (Autocomplete.validateSearchTerm(value, this.onlyVAT) && Autocomplete.isOnline()) {
- return Autocomplete.autocomplete(value).then(function (suggestions) {
+ if (this._validateSearchTerm(value, this.onlyVAT) && this._isOnline()) {
+ return this._autocomplete(value).then(function (suggestions) {
if (suggestions && suggestions.length) {
self.suggestions = suggestions;
self._showDropdown();
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 83f2ce9ce0b..5a3334e8094 100644
--- a/addons/partner_autocomplete/static/src/js/partner_autocomplete_many2one.js
+++ b/addons/partner_autocomplete/static/src/js/partner_autocomplete_many2one.js
@@ -3,12 +3,12 @@ odoo.define('partner.autocomplete.many2one', function (require) {
var FieldMany2One = require('web.relational_fields').FieldMany2One;
var core = require('web.core');
-var Autocomplete = require('partner.autocomplete.core');
+var AutocompleteMixin = require('partner.autocomplete.Mixin');
var field_registry = require('web.field_registry');
var _t = core._t;
-var PartnerField = FieldMany2One.extend({
+var PartnerField = FieldMany2One.extend(AutocompleteMixin, {
jsLibs: [
'/partner_autocomplete/static/lib/jsvat.js'
],
@@ -21,7 +21,7 @@ var PartnerField = FieldMany2One.extend({
this._addAutocompleteSource(this._searchSuggestions, {
placeholder: _t('Searching Autocomplete...'),
order: 20,
- validation: Autocomplete.validateSearchTerm,
+ validation: this._validateSearchTerm,
});
this.additionalContext['show_vat'] = true;
@@ -42,7 +42,7 @@ var PartnerField = FieldMany2One.extend({
var self = this;
self.$('input').val('');
- return Autocomplete.getCreateData(company).then(function (data){
+ return self._getCreateData(company).then(function (data){
var context = {
'default_is_company': true
};
@@ -120,10 +120,10 @@ var PartnerField = FieldMany2One.extend({
_searchSuggestions: function (search_val) {
var def = $.Deferred();
- if (Autocomplete.isOnline()) {
+ if (this._isOnline()) {
var self = this;
- Autocomplete.autocomplete(search_val).then(function (suggestions) {
+ self._autocomplete(search_val).then(function (suggestions) {
var choices = [];
if (suggestions && suggestions.length) {
_.each(suggestions, function (suggestion) {
diff --git a/addons/partner_autocomplete/static/src/xml/partner_autocomplete.xml b/addons/partner_autocomplete/static/src/xml/partner_autocomplete.xml
index c85969882ad..6020e9537cc 100644
--- a/addons/partner_autocomplete/static/src/xml/partner_autocomplete.xml
+++ b/addons/partner_autocomplete/static/src/xml/partner_autocomplete.xml
@@ -13,4 +13,11 @@
</a>
</t>
</div>
+
+ <!--
+ @param {string} credits_url
+ -->
+ <div t-name="partner_autocomplete.insufficient_credit_notification" class="">
+ <a class="btn btn-link" t-att-href="credits_url"><i class="fa fa-arrow-right"/> Buy more credits</a>
+ </div>
</templates>
diff --git a/addons/partner_autocomplete/static/tests/partner_autocomplete_tests.js b/addons/partner_autocomplete/static/tests/partner_autocomplete_tests.js
index 52dcde5370f..bae95b395a5 100644
--- a/addons/partner_autocomplete/static/tests/partner_autocomplete_tests.js
+++ b/addons/partner_autocomplete/static/tests/partner_autocomplete_tests.js
@@ -4,9 +4,9 @@ odoo.define('partner_autocomplete.tests', function (require) {
var FormView = require('web.FormView');
var concurrency = require('web.concurrency');
var testUtils = require("web.test_utils");
- var AutocompleteCore = require('partner.autocomplete.core');
var AutocompleteField = require('partner.autocomplete.fieldchar');
var PartnerField = require('partner.autocomplete.many2one');
+ var NotificationService = require('web.NotificationService');
var createView = testUtils.createAsyncView;
@@ -36,13 +36,67 @@ odoo.define('partner_autocomplete.tests', function (require) {
});
}
+ var suggestions = [{
+ name: "Odoo",
+ website: "odoo.com",
+ domain: "odoo.com",
+ logo: "odoo.com/logo.png",
+ vat: "BE0477472701"
+ }];
+
+ var enrichData = {};
+
+ var createData = {};
+
QUnit.module('partner_autocomplete', {
before: function () {
- var suggestions = [
- {name: "Odoo", website: "odoo.com", domain: "odoo.com", logo: "odoo.com/logo.png", vat: "BE0477472701"}
- ];
+ var fieldsToPatch = [PartnerField, AutocompleteField];
+ _.each(fieldsToPatch, function (fieldToPatch) {
+ testUtils.mock.patch(fieldToPatch, {
+ _getBase64Image: function (url) {
+ return $.when(url === "odoo.com/logo.png" ? "odoobase64" : "");
+ },
+ _isOnline: function () {
+ return true;
+ },
+ _getCreateData: function (company) {
+ var def = this._super.apply(this, arguments);
+ def.then(function (data) {
+ createData = data.company;
+ });
+ return def;
+ },
+ _enrichCompany: function (company) {
+ return $.when(enrichData);
+ },
+ _getOdooSuggestions: function (value, isVAT) {
+ var results = _.filter(suggestions, function (suggestion) {
+ value = value ? value.toLowerCase() : '';
+ if (isVAT) return (suggestion.vat.toLowerCase().indexOf(value) >= 0);
+ else return (suggestion.name.toLowerCase().indexOf(value) >= 0);
+ });
+ return $.when(results);
+ },
+ _getClearbitSuggestions: function (value) {
+ return this._getOdooSuggestions(value);
+ },
+ do_notify: function (title, message, sticky, className) {
+ return this.call('notification', 'notify', {
+ title: title,
+ message: message,
+ sticky: true,
+ className: 'o_partner_autocomplete_test_notify'
+ });
+ },
+ });
+ });
- var enrich_data = {
+ testUtils.mock.patch(AutocompleteField, {
+ debounceSuggestions: 0,
+ });
+ },
+ beforeEach: function () {
+ enrichData = {
country_id: 20,
state_id: false,
partner_gid: 1,
@@ -56,42 +110,6 @@ odoo.define('partner_autocomplete.tests', function (require) {
vat: "BE0477472701",
};
- testUtils.mock.patch(AutocompleteCore, {
- _getBase64Image: function (url) {
- return $.when(url === "odoo.com/logo.png" ? "odoobase64" : "");
- },
- isOnline: function () {
- return true;
- },
- getCreateData: function (company) {
- var self = this;
- var def = this._super.apply(this, arguments);
- def.then(function (data) {
- self._createData = data.company;
- });
- return def;
- },
- enrichCompany: function (company) {
- return $.when(enrich_data);
- },
- _getOdooSuggestions(value, isVAT) {
- var results = _.filter(suggestions, function (suggestion) {
- value = value ? value.toLowerCase() : '';
- if (isVAT) return (suggestion.vat.toLowerCase().indexOf(value) >= 0);
- else return (suggestion.name.toLowerCase().indexOf(value) >= 0);
- });
- return $.when(results);
- },
- _getClearbitSuggestions(value) {
- return this._getOdooSuggestions(value);
- },
- });
-
- testUtils.mock.patch(AutocompleteField, {
- debounceSuggestions: 0,
- });
- },
- beforeEach: function () {
this.data = {
'res.partner': {
fields: {
@@ -128,7 +146,7 @@ odoo.define('partner_autocomplete.tests', function (require) {
},
after: function () {
testUtils.mock.unpatch(AutocompleteField);
- testUtils.mock.unpatch(AutocompleteCore);
+ testUtils.mock.unpatch(PartnerField);
},
});
@@ -223,7 +241,7 @@ odoo.define('partner_autocomplete.tests', function (require) {
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\"");
- _compareResultFields(assert, form, fields, AutocompleteCore._createData);
+ _compareResultFields(assert, form, fields, createData);
// Try suggestion with bullshit query
testUtils.fields.editInput($input, "ZZZZZZZZZZZZZZZZZZZZZZ")
@@ -309,7 +327,7 @@ odoo.define('partner_autocomplete.tests', function (require) {
$input = form.$(".o_field_partner_autocomplete > input");
assert.strictEqual($input.val(), "Odoo", "Input value should have been updated to \"Odoo\"");
- _compareResultFields(assert, form, fields, AutocompleteCore._createData);
+ _compareResultFields(assert, form, fields, createData);
// Set complete VAT and assert changes
// Second suggestion (only vat + clearbit result)
@@ -323,7 +341,7 @@ odoo.define('partner_autocomplete.tests', function (require) {
$input = form.$(".o_field_partner_autocomplete > input");
assert.strictEqual($input.val(), "Odoo", "Input value should have been updated to \"Odoo\"");
- _compareResultFields(assert, form, fields, AutocompleteCore._createData);
+ _compareResultFields(assert, form, fields, createData);
// Test if dropdown closes on focusout
$input.trigger("focusout");
@@ -371,4 +389,50 @@ odoo.define('partner_autocomplete.tests', function (require) {
});
});
});
+
+ QUnit.test("Partner autocomplete : Notify not enough credits", function (assert) {
+ assert.expect(1);
+ var done = assert.async();
+
+ enrichData = {
+ error: true,
+ error_message: 'Insufficient Credit',
+ };
+
+ createView({
+ View: FormView,
+ model: 'res.partner',
+ data: this.data,
+ arch:
+ '<form>' +
+ '<field name="company_type"/>' +
+ '<field name="name" widget="field_partner_autocomplete"/>' +
+ '</form>',
+ services: {
+ notification: NotificationService,
+ },
+ mockRPC: function (route, args) {
+ if (args.method === "get_credits_url"){
+ return $.when('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"');
+
+ var $input = form.$(".o_field_partner_autocomplete > input:visible");
+ testUtils.fields.editInput($input, "BE0477472701");
+
+ var $dropdown = form.$(".o_field_partner_autocomplete .dropdown-menu:visible");
+ 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();
+ });
+ });
});