diff --git a/addons/web/static/src/js/views/calendar/calendar_model.js b/addons/web/static/src/js/views/calendar/calendar_model.js
index ed02983d957..e338ae55ece 100644
--- a/addons/web/static/src/js/views/calendar/calendar_model.js
+++ b/addons/web/static/src/js/views/calendar/calendar_model.js
@@ -45,20 +45,26 @@ return AbstractModel.extend({
if (event.allDay || end.diff(start) % 86400000 === 0) {
event.allDay = true;
- if (this.scale === 'month') {
+ if (this.data.scale === 'month') {
+ // In month, FullCalendar gives the end day as the
+ // next day at midnight (instead of 23h59).
+ end.add(-1, 'days');
if (event.r_start) {
start.hours(event.r_start.hours())
.minutes(event.r_start.minutes())
.seconds(event.r_start.seconds())
.utc();
- end.add(-1, 'days')
- .hours(event.r_end.hours())
+ end.hours(event.r_end.hours())
.minutes(event.r_end.minutes())
.seconds(event.r_end.seconds())
.utc();
- } else {
+ } else if (this.mapping.all_day) {
start.utc();
end.utc();
+ } else {
+ // default hours in the user's timezone
+ start.hours(7).add(-this.getSession().getTZOffset(start), 'minutes');
+ end.hours(19).add(-this.getSession().getTZOffset(end), 'minutes');
}
} else if (this.mapping.all_day) {
start.startOf('day');
@@ -622,6 +628,10 @@ return AbstractModel.extend({
// r.start = date_start.format('YYYY-MM-DD');
// r.end = date_stop.format('YYYY-MM-DD');
} else if (this.data.scale === 'month' && this.fields[this.mapping.date_start].type !== 'date') {
+ // In month, FullCalendar gives the end day as the
+ // next day at midnight (instead of 23h59).
+ date_stop.add(1, 'days');
+
// allow to resize in month mode
r.reset_allday = r.allDay;
r.allDay = true;
diff --git a/addons/web/static/tests/views/calendar_tests.js b/addons/web/static/tests/views/calendar_tests.js
index 29e76182bb4..31891d6c28b 100644
--- a/addons/web/static/tests/views/calendar_tests.js
+++ b/addons/web/static/tests/views/calendar_tests.js
@@ -644,8 +644,8 @@ QUnit.module('Views', {
$view.remove();
});
- QUnit.test('create all day event', function (assert) {
- assert.expect(2);
+ QUnit.test('create all day event in week mode', function (assert) {
+ assert.expect(3);
this.data.event.records = [];
@@ -696,6 +696,8 @@ QUnit.module('Views', {
assert.strictEqual($newevent.text().replace(/[\s\n\r]+/g, ''), "newevent",
"should display the new event with time and title");
+ assert.strictEqual($newevent.parent().attr('colspan'), "2",
+ "should appear over two days.");
assert.deepEqual($newevent.data('fcSeg').event.record,
{
@@ -712,6 +714,82 @@ QUnit.module('Views', {
$view.remove();
});
+ QUnit.test('create event in month mode', function (assert) {
+ assert.expect(4);
+
+ this.data.event.records = [];
+
+ var calendar = createView({
+ View: CalendarView,
+ model: 'event',
+ data: this.data,
+ arch:
+ ''+
+ ''+
+ '',
+ archs: archs,
+ viewOptions: {
+ initialDate: initialDate,
+ },
+ session: {
+ getTZOffset: function () {
+ return 120;
+ },
+ },
+ mockRPC: function (route, args) {
+ if (args.method === "create") {
+ assert.deepEqual(args.args[0], {
+ "name": "new event",
+ "start": "2016-12-14 05:00:00",
+ "stop": "2016-12-15 17:00:00",
+ },
+ "should send the correct data to create events");
+ }
+ return this._super(route, args);
+ },
+ });
+
+ var $view = $('#qunit-fixture').contents();
+ $view.prependTo('body'); // => select with click position
+
+ var pos = calendar.$('.fc-bg td:eq(20)').offset();
+ try {
+ testUtils.triggerPositionalMouseEvent(pos.left+15, pos.top+15, "mousedown");
+ } catch (e) {
+ calendar.destroy();
+ $view.remove();
+ throw new Error('The test fails to simulate a click in the screen. Your screen is probably too small or your dev tools is open.');
+ }
+ pos = calendar.$('.fc-bg td:eq(21)').offset();
+ testUtils.triggerPositionalMouseEvent(pos.left+15, pos.top+15, "mousemove");
+ testUtils.triggerPositionalMouseEvent(pos.left+15, pos.top+15, "mouseup");
+
+ $('.modal input:first').val('new event').trigger('input');
+ $('.modal button.btn:contains(Create)').trigger('click');
+ var $newevent = calendar.$('.fc-event:contains(new event)');
+
+ assert.strictEqual($newevent.text().replace(/[\s\n\r]+/g, ''), "newevent",
+ "should display the new event with time and title");
+ assert.strictEqual($newevent.parent().attr('colspan'), "2",
+ "should appear over two days.");
+
+ assert.deepEqual($newevent.data('fcSeg').event.record, {
+ display_name: "new event",
+ start: fieldUtils.parse.datetime("2016-12-14 05:00:00", this.data.event.fields.start, {isUTC: true}),
+ stop: fieldUtils.parse.datetime("2016-12-15 17:00:00", this.data.event.fields.stop, {isUTC: true}),
+ name: "new event",
+ id: 1
+ }, "the new record should have the utc datetime (quickCreate)");
+
+ calendar.destroy();
+ $view.remove();
+ });
+
QUnit.test('use mini calendar', function (assert) {
assert.expect(12);
@@ -874,6 +952,62 @@ QUnit.module('Views', {
assert.strictEqual($('#ui-datepicker-div:empty').length, 0, "should have a clean body");
});
+ QUnit.test('create and edit event in month mode (all_day: false)', function (assert) {
+ assert.expect(2);
+
+ var calendar = createView({
+ View: CalendarView,
+ model: 'event',
+ data: this.data,
+ arch:
+ ''+
+ ''+
+ '',
+ archs: archs,
+ viewOptions: {
+ initialDate: initialDate,
+ },
+ session: {
+ getTZOffset: function () {
+ return -240;
+ },
+ },
+ });
+
+ // create a new event and edit it
+ var $cell = calendar.$('.fc-day-grid .fc-row:eq(4) .fc-day:eq(2)');
+ testUtils.triggerMouseEvent($cell, "mousedown");
+ testUtils.triggerMouseEvent($cell, "mouseup");
+ $('.modal-body input:first').val('coucou').trigger('input');
+
+ testUtils.intercept(calendar, 'do_action', function (event) {
+ assert.deepEqual(event.data.action,
+ {
+ type: "ir.actions.act_window",
+ res_model: "event",
+ views: [[false, "form"]],
+ target: "current",
+ context: {
+ "default_name": "coucou",
+ "default_start": "2016-12-27 11:00:00", // 7:00 + 4h
+ "default_stop": "2016-12-27 23:00:00", // 19:00 + 4h
+ }
+ },
+ "should open the form view with the context default values");
+ });
+
+ $('.modal button.btn:contains(Edit)').trigger('click');
+
+ calendar.destroy();
+ assert.strictEqual($('#ui-datepicker-div:empty').length, 0, "should have a clean body");
+ });
+
+
QUnit.test('readonly date_start field', function (assert) {
assert.expect(4);