diff options
| author | David Monjoie <dmo@odoo.com> | 2017-06-27 16:14:55 +0200 |
|---|---|---|
| committer | David Monjoie <dmo@odoo.com> | 2017-07-03 08:15:24 +0200 |
| commit | 405681fa8b0a68108291f1aab19a961c458babfa (patch) | |
| tree | 771b8b36add8125e77e25251c38818261b2bbe82 | |
| parent | 0f7f3fc2f1c78cfaaaef435c1189ac79fe330b15 (diff) | |
[FIX] web,google_calendar: fix google calendar sync
5 files changed, 244 insertions, 68 deletions
diff --git a/addons/google_calendar/static/src/js/google_calendar.js b/addons/google_calendar/static/src/js/google_calendar.js index 240b5568c0b..dbb7a308540 100644 --- a/addons/google_calendar/static/src/js/google_calendar.js +++ b/addons/google_calendar/static/src/js/google_calendar.js @@ -5,97 +5,143 @@ var core = require('web.core'); var Dialog = require('web.Dialog'); var framework = require('web.framework'); var CalendarRenderer = require('web.CalendarRenderer'); +var CalendarController = require('web.CalendarController'); var _t = core._t; -CalendarRenderer.include({ - events: _.extend({}, CalendarRenderer.prototype.events, { - 'click .o_google_sync_button': function () { - this.syncCalendar(this.fields_view); - } +CalendarController.include({ + custom_events: _.extend({}, CalendarController.prototype.custom_events, { + syncCalendar: '_onSyncCalendar', }), - syncCalendar: function() { + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + + /** + * Try to sync the calendar with Google Calendar. According to the result + * from Google API, this function may require an action of the user by the + * mean of a dialog. + * + * @private + * @returns {OdooEvent} event + */ + _onSyncCalendar: function (event) { var self = this; var context = this.getSession().user_context; - this.$google_button.prop('disabled', true); - this.trigger_up('perform_rpc', { + this._rpc({ route: '/google_calendar/sync_data', - args: { - model: this.state.model, + params: { + model: this.modelName, fromurl: window.location.href, local_context: context, - }, - on_success: function (o) { - if (o.status === "need_auth") { - Dialog.alert(self, _t("You will be redirected to Google to authorize access to your calendar!"), { + } + }).then(function (o) { + if (o.status === "need_auth") { + Dialog.alert(self, _t("You will be redirected to Google to authorize access to your calendar!"), { + confirm_callback: function() { + framework.redirect(o.url); + }, + title: _t('Redirection'), + }); + } else if (o.status === "need_config_from_admin") { + if (!_.isUndefined(o.action) && parseInt(o.action)) { + Dialog.confirm(self, _t("The Google Synchronization needs to be configured before you can use it, do you want to do it now?"), { confirm_callback: function() { - framework.redirect(o.url); + self.do_action(o.action); }, - title: _t('Redirection'), + title: _t('Configuration'), }); - } else if (o.status === "need_config_from_admin") { - if (!_.isUndefined(o.action) && parseInt(o.action)) { - Dialog.confirm(self, _t("The Google Synchronization needs to be configured before you can use it, do you want to do it now?"), { - confirm_callback: function() { - self.do_action(o.action); - }, - title: _t('Configuration'), - }); - } else { - Dialog.alert(self, _t("An administrator needs to configure Google Synchronization before you can use it!"), { - title: _t('Configuration'), - }); - } - } else if (o.status === "need_refresh") { - self.$calendar.fullCalendar('refetchEvents'); - } else if (o.status === "need_reset") { - var confirm_text1 = _t("The account you are trying to synchronize (%s) is not the same as the last one used (%s)!"); - var confirm_text2 = _t("In order to do this, you first need to disconnect all existing events from the old account."); - var confirm_text3 = _t("Do you want to do this now?"); - var text = _.str.sprintf(confirm_text1 + "\n" + confirm_text2 + "\n\n" + confirm_text3, o.info.new_name, o.info.old_name); - Dialog.confirm(self, text, { - confirm_callback: function() { - self._rpc({ - route: '/google_calendar/remove_references', - params: { - model: self.state.model, - local_context: context, - }, - }) - .done(function(o) { - if (o.status === "OK") { - Dialog.alert(self, _t("All events have been disconnected from your previous account. You can now restart the synchronization"), { - title: _t('Event disconnection success'), - }); - } else if (o.status === "KO") { - Dialog.alert(self, _t("An error occured while disconnecting events from your previous account. Please retry or contact your administrator."), { - title: _t('Event disconnection error'), - }); - } // else NOP - }); - }, - title: _t('Accounts'), + } else { + Dialog.alert(self, _t("An administrator needs to configure Google Synchronization before you can use it!"), { + title: _t('Configuration'), }); } - - self.$google_button.prop('disabled', false); - }, + } else if (o.status === "need_refresh") { + self.reload(); + } else if (o.status === "need_reset") { + var confirmText1 = _t("The account you are trying to synchronize (%s) is not the same as the last one used (%s)!"); + var confirmText2 = _t("In order to do this, you first need to disconnect all existing events from the old account."); + var confirmText3 = _t("Do you want to do this now?"); + var text = _.str.sprintf(confirmText1 + "\n" + confirmText2 + "\n\n" + confirmText3, o.info.new_name, o.info.old_name); + Dialog.confirm(self, text, { + confirm_callback: function() { + self._rpc({ + route: '/google_calendar/remove_references', + params: { + model: self.state.model, + local_context: context, + }, + }) + .done(function(o) { + if (o.status === "OK") { + Dialog.alert(self, _t("All events have been disconnected from your previous account. You can now restart the synchronization"), { + title: _t('Event disconnection success'), + }); + } else if (o.status === "KO") { + Dialog.alert(self, _t("An error occured while disconnecting events from your previous account. Please retry or contact your administrator."), { + title: _t('Event disconnection error'), + }); + } // else NOP + }); + }, + title: _t('Accounts'), + }); + } + }).always(function () { + event.data.on_always(); }); - }, - initSidebar: function() { + } +}); + +CalendarRenderer.include({ + events: _.extend({}, CalendarRenderer.prototype.events, { + 'click .o_google_sync_button': '_onSyncCalendar', + }), + + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + + /** + * Adds the Sync with Google button in the sidebar + * + * @private + */ + _initSidebar: function () { var self = this; - this._super(); - this.$google_button = $(); - if (this.state.model === "calendar.event") { - this.$google_button = $('<button/>', {type: 'button', html: _t("Sync with <b>Google</b>")}) + this._super.apply(this, arguments); + this.$googleButton = $(); + if (this.model === "calendar.event") { + this.$googleButton = $('<button/>', {type: 'button', html: _t("Sync with <b>Google</b>")}) .addClass('o_google_sync_button oe_button btn btn-sm btn-default') .prepend($('<img/>', { src: "/google_calendar/static/src/img/calendar_32.png", })) - .appendTo(self.$('.o_calendar_sidebar')); + .appendTo(self.$sidebar); } }, + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + + /** + * Requests to sync the calendar with Google Calendar + * + * @private + */ + _onSyncCalendar: function () { + var self = this; + var context = this.getSession().user_context; + this.$googleButton.prop('disabled', true); + this.trigger_up('syncCalendar', { + on_always: function () { + self.$googleButton.prop('disabled', false); + }, + }); + }, }); }); diff --git a/addons/google_calendar/static/tests/google_calendar_tests.js b/addons/google_calendar/static/tests/google_calendar_tests.js new file mode 100644 index 00000000000..08176dde839 --- /dev/null +++ b/addons/google_calendar/static/tests/google_calendar_tests.js @@ -0,0 +1,122 @@ +odoo.define('google_calendar.calendar_tests', function (require) { +"use strict"; + +var CalendarView = require('web.CalendarView'); +var testUtils = require('web.test_utils'); + +var createView = testUtils.createView; + +var initialDate = new Date("2016-12-12T08:00:00Z"); + + +QUnit.module('Google Calendar', { + beforeEach: function () { + this.data = { + 'calendar.event': { + fields: { + id: {string: "ID", type: "integer"}, + user_id: {string: "user", type: "many2one", relation: 'user'}, + partner_id: {string: "user", type: "many2one", relation: 'partner', related: 'user_id.partner_id'}, + name: {string: "name", type: "char"}, + start_date: {string: "start date", type: "date"}, + stop_date: {string: "stop date", type: "date"}, + start: {string: "start datetime", type: "datetime"}, + stop: {string: "stop datetime", type: "datetime"}, + allday: {string: "allday", type: "boolean"}, + partner_ids: {string: "attendees", type: "one2many", relation: 'partner'}, + type: {string: "type", type: "integer"}, + }, + records: [ + {id: 5, user_id: 4, partner_id: 4, name: "event 1", start: "2016-12-13 15:55:05", stop: "2016-12-15 18:55:05", allday: false, partner_ids: [], type: 2}, + {id: 6, user_id: 4, partner_id: 4, name: "event 2", start: "2016-12-18 08:00:00", stop: "2016-12-18 09:00:00", allday: false, partner_ids: [], type: 3} + ], + check_access_rights: function () { + return $.when(true); + } + }, + user: { + fields: { + id: {string: "ID", type: "integer"}, + display_name: {string: "Displayed name", type: "char"}, + partner_id: {string: "partner", type: "many2one", relation: 'partner'}, + image: {string: "image", type: "integer"}, + }, + records: [ + {id: 4, display_name: "user 4", partner_id: 4}, + ] + }, + partner: { + fields: { + id: {string: "ID", type: "integer"}, + display_name: {string: "Displayed name", type: "char"}, + image: {string: "image", type: "integer"}, + }, + records: [ + {id: 4, display_name: "partner 4", image: 'DDD'} + ] + }, + filter_partner: { + fields: { + id: {string: "ID", type: "integer"}, + user_id: {string: "user", type: "many2one", relation: 'user'}, + partner_id: {string: "partner", type: "many2one", relation: 'partner'}, + }, + records: [ + {id: 3, user_id: 4, partner_id: 4} + ] + }, + }; + } +}, function () { + + QUnit.test('sync google calendar', function (assert) { + assert.expect(6); + + var calendar = createView({ + View: CalendarView, + model: 'calendar.event', + data: this.data, + arch: + '<calendar class="o_calendar_test" '+ + 'date_start="start" '+ + 'date_stop="stop" '+ + 'mode="month">'+ + '<field name="name"/>'+ + '</calendar>', + viewOptions: { + initialDate: initialDate, + }, + mockRPC: function (route, args) { + if (route === '/google_calendar/sync_data') { + assert.step(route); + this.data['calendar.event'].records.push( + {id: 7, user_id: 4, partner_id: 4, name: "event from google calendar", start: "2016-12-28 15:55:05", stop: "2016-12-29 18:55:05", allday: false, partner_ids: [], type: 2} + ); + return $.when({status: 'need_refresh'}); + } else if (route === '/google_calendar/static/src/img/calendar_32.png') { + return $.when(); + } else if (route === '/web/dataset/call_kw/calendar.event/search_read') { + assert.step(route); + } + return this._super.apply(this, arguments); + }, + }); + + assert.strictEqual(calendar.$('.fc-event').length, 2, "should display 2 events on the month"); + + var $sidebar = calendar.$('.o_calendar_sidebar'); + + calendar.$('.o_google_sync_button').click(); + + assert.verifySteps([ + '/web/dataset/call_kw/calendar.event/search_read', + '/google_calendar/sync_data', + '/web/dataset/call_kw/calendar.event/search_read', + ], 'should do a search_read before and after the call to sync_data'); + + assert.strictEqual(calendar.$('.fc-event').length, 3, "should now display 3 events on the month"); + + calendar.destroy(); + }); +}); +}); diff --git a/addons/google_calendar/views/google_calendar_templates.xml b/addons/google_calendar/views/google_calendar_templates.xml index 6f8924e4af8..4ff9df7f453 100644 --- a/addons/google_calendar/views/google_calendar_templates.xml +++ b/addons/google_calendar/views/google_calendar_templates.xml @@ -6,4 +6,10 @@ <script type="text/javascript" src="/google_calendar/static/src/js/google_calendar.js"></script> </xpath> </template> + + <template id="qunit_suite" name="google_calendar_tests" inherit_id="web.qunit_suite"> + <xpath expr="//t[@t-set='head']" position="inside"> + <script type="text/javascript" src="/google_calendar/static/tests/google_calendar_tests.js"></script> + </xpath> + </template> </odoo> diff --git a/addons/web/static/src/js/views/calendar/calendar_renderer.js b/addons/web/static/src/js/views/calendar/calendar_renderer.js index 23d63aa9044..a4930c87d37 100644 --- a/addons/web/static/src/js/views/calendar/calendar_renderer.js +++ b/addons/web/static/src/js/views/calendar/calendar_renderer.js @@ -164,6 +164,7 @@ return AbstractRenderer.extend({ init: function (parent, state, params) { this._super.apply(this, arguments); this.displayFields = params.displayFields; + this.model = params.model; this.filters = []; this.color_map = {}; diff --git a/addons/web/static/src/js/views/calendar/calendar_view.js b/addons/web/static/src/js/views/calendar/calendar_view.js index 135224fb0cc..71a6c30b756 100644 --- a/addons/web/static/src/js/views/calendar/calendar_view.js +++ b/addons/web/static/src/js/views/calendar/calendar_view.js @@ -119,6 +119,7 @@ var CalendarView = AbstractView.extend({ this.rendererParams.displayFields = displayFields; this.rendererParams.eventTemplate = _.findWhere(arch.children, {'tag': 'templates'}); + this.rendererParams.model = viewInfo.model; this.loadParams.fieldNames = _.uniq(fieldNames); this.loadParams.mapping = mapping; |
