diff --git a/addons/web/static/src/js/views/calendar/calendar_controller.js b/addons/web/static/src/js/views/calendar/calendar_controller.js
index 6ec90393b7a..a4124405e2b 100644
--- a/addons/web/static/src/js/views/calendar/calendar_controller.js
+++ b/addons/web/static/src/js/views/calendar/calendar_controller.js
@@ -246,7 +246,22 @@ var CalendarController = AbstractController.extend({
* @private
* @param {OdooEvent} event
*/
- _onChangeFilter: function (event) {
+ _onChangeFilter: async function (event) {
+ if (event.data.value !== "all" && event.target.filter_field) {
+ const domain = [['user_id', '=', this.getSession().uid], [event.target.write_field, '=', parseInt(event.data.value)]];
+ const contact = await this._rpc({
+ model: event.target.write_model,
+ method: 'search',
+ args: [domain],
+ });
+ let val = {};
+ val[event.target.filter_field] = event.data.active;
+ await this._rpc({
+ model: event.target.write_model,
+ method: 'write',
+ args: [contact, val],
+ });
+ }
if (this.model.changeFilter(event.data) && !event.data.no_reload) {
this.reload();
}
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 cb0eeec5143..26c490f4c6c 100644
--- a/addons/web/static/src/js/views/calendar/calendar_model.js
+++ b/addons/web/static/src/js/views/calendar/calendar_model.js
@@ -537,11 +537,15 @@ return AbstractModel.extend({
}
var field = this.fields[filter.fieldName];
+ var fields = [filter.write_field];
+ if (filter.filter_field) {
+ fields.push(filter.filter_field);
+ }
return this._rpc({
model: filter.write_model,
method: 'search_read',
domain: [["user_id", "=", session.uid]],
- fields: [filter.write_field],
+ fields: fields,
})
.then(function (res) {
var records = _.map(res, function (record) {
@@ -554,7 +558,7 @@ return AbstractModel.extend({
'id': record.id,
'value': value,
'label': formater(_value, field),
- 'active': f && f.active,
+ 'active': (f && f.active) || (filter.filter_field && record[filter.filter_field]),
};
});
records.sort(function (f1,f2) {
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 fed9a705d11..ef556066085 100644
--- a/addons/web/static/src/js/views/calendar/calendar_renderer.js
+++ b/addons/web/static/src/js/views/calendar/calendar_renderer.js
@@ -46,6 +46,7 @@ var SidebarFilter = Widget.extend(FieldManagerMixin, {
this.fieldName = options.fieldName;
this.write_model = options.write_model;
this.write_field = options.write_field;
+ this.filter_field = options.filter_field;
this.avatar_field = options.avatar_field;
this.avatar_model = options.avatar_model;
this.filters = options.filters;
@@ -161,10 +162,12 @@ return AbstractRenderer.extend({
template: "CalendarView",
config: {
CalendarPopover: CalendarPopover,
+ eventTemplate: 'calendar-box',
},
custom_events: _.extend({}, AbstractRenderer.prototype.custom_events || {}, {
edit_event: '_onEditEvent',
delete_event: '_onDeleteEvent',
+ render_event: '_renderEvents',
}),
/**
@@ -356,7 +359,7 @@ return AbstractRenderer.extend({
if (_.isEmpty(qweb_context.record)) {
return '';
} else {
- return qweb.render("calendar-box", qweb_context);
+ return qweb.render(this.config.eventTemplate, qweb_context);
}
},
/**
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 8894d0760e5..7ac7e1730c9 100644
--- a/addons/web/static/src/js/views/calendar/calendar_view.js
+++ b/addons/web/static/src/js/views/calendar/calendar_view.js
@@ -112,6 +112,7 @@ var CalendarView = AbstractView.extend({
};
filters[fieldName].write_model = child.attrs.write_model;
filters[fieldName].write_field = child.attrs.write_field; // can't use a x2many fields
+ filters[fieldName].filter_field = child.attrs.filter_field;
modelFilters.push(fields[fieldName].relation);
}
diff --git a/addons/web/static/tests/views/calendar_tests.js b/addons/web/static/tests/views/calendar_tests.js
index 9f99431ae43..60994d3f713 100644
--- a/addons/web/static/tests/views/calendar_tests.js
+++ b/addons/web/static/tests/views/calendar_tests.js
@@ -116,11 +116,12 @@ QUnit.module('Views', {
id: {string: "ID", type: "integer"},
user_id: {string: "user", type: "many2one", relation: 'user'},
partner_id: {string: "partner", type: "many2one", relation: 'partner'},
+ partner_checked: {string: "checked", type: "boolean"}
},
records: [
- {id: 1, user_id: session.uid, partner_id: 1},
- {id: 2, user_id: session.uid, partner_id: 2},
- {id: 3, user_id: 4, partner_id: 3}
+ {id: 1, user_id: session.uid, partner_id: 1, partner_checked: true},
+ {id: 2, user_id: session.uid, partner_id: 2, partner_checked: true},
+ {id: 3, user_id: 4, partner_id: 3, partner_checked: true}
]
},
};
@@ -2140,6 +2141,40 @@ QUnit.module('Views', {
assert.strictEqual($('#ui-datepicker-div:empty').length, 0, "should have a clean body");
});
+ QUnit.test('check filters with filter_field specified', async function (assert) {
+ assert.expect(5);
+
+ const calendar = await createCalendarView({
+ View: CalendarView,
+ model: 'event',
+ data: this.data,
+ arch: `
+
+
+ `,
+ });
+
+ assert.containsOnce(calendar, '.o_calendar_filter_item[data-id="2"] input:checked',
+ "checkbox should be checked");
+ await testUtils.dom.click(calendar.$('.o_calendar_filter_item[data-id="2"] input'));
+ assert.containsNone(calendar, '.o_calendar_filter_item[data-id="2"] input:checked',
+ "checkbox should not be checked");
+ assert.strictEqual(this.data.filter_partner.records.find(r => r.id === 2).partner_checked, false,
+ "the status of this filter should now be false");
+ await calendar.reload();
+ assert.containsNone(calendar, '.o_calendar_filter_item[data-id="2"] input:checked',
+ "checkbox should not be checked after the reload");
+ assert.strictEqual(this.data.filter_partner.records.find(r => r.id === 2).partner_checked, false,
+ "the status of this filter should still be false after the reload");
+ calendar.destroy();
+ });
+
QUnit.test('"all" filter', async function (assert) {
assert.expect(8);
diff --git a/doc/reference/views.rst b/doc/reference/views.rst
index 935c426bc72..4acbe4259af 100644
--- a/doc/reference/views.rst
+++ b/doc/reference/views.rst
@@ -454,10 +454,11 @@ calendar view are:
* ``avatar_field``
only for x2many field, to display the avatar instead of the display_name
in the cards
- * ``write_model`` and ``write_field``
+ * ``write_model`` and ``write_field`` and ``filter_field``
you can add a filter and save the result in the defined model, the
- filter is added in the sidebar
+ filter is added in the sidebar. The ``filter_field`` is optionnal and allows
+ you to specify the field that will hold the status of the filter.
* ``filter`` and ``color``
use "True" to add this field in filter in the sidebar. You can specify
diff --git a/odoo/addons/base/rng/common.rng b/odoo/addons/base/rng/common.rng
index e2f2b05d39a..9c6d842d343 100644
--- a/odoo/addons/base/rng/common.rng
+++ b/odoo/addons/base/rng/common.rng
@@ -265,6 +265,7 @@
+