diff --git a/addons/web/static/src/views/kanban/kanban_model.js b/addons/web/static/src/views/kanban/kanban_model.js index 84608523fb1..3ce8822d669 100644 --- a/addons/web/static/src/views/kanban/kanban_model.js +++ b/addons/web/static/src/views/kanban/kanban_model.js @@ -336,6 +336,18 @@ export class KanbanDynamicGroupList extends DynamicGroupList { }); } + get sumFields() { + const { sumField } = this.model.progressAttributes; + return sumField ? [sumField.name] : []; + } + + /** + * @override + */ + get fieldNames() { + return [...super.fieldNames, ...this.sumFields]; + } + /** * After a reload, empty groups are expcted to disappear from the web_read_group. * However, if the parameters are the same (domain + groupBy), we want to @@ -357,24 +369,20 @@ export class KanbanDynamicGroupList extends DynamicGroupList { return; } - const { fieldName, sumField } = this.model.progressAttributes; - const fieldNames = []; const gbFieldName = this.groupByField.name; const promises = {}; if (withProgressBars) { const domain = Domain.or(groups.map((g) => g.groupDomain)).toList(); - fieldNames.push(fieldName); promises.readProgressBar = this._fetchProgressData(domain); } // If we have a sumField, the aggregates must be re-fetched - if (sumField) { + if (this.sumFields.length) { const domain = Domain.or(groups.map((g) => g.getProgressBarDomain())).toList(); - fieldNames.push(sumField.name); promises.webReadGroup = this.model.orm.webReadGroup( this.resModel, domain, - fieldNames, + this.sumFields, this.groupBy, { lazy: true } ); @@ -387,9 +395,7 @@ export class KanbanDynamicGroupList extends DynamicGroupList { const result = await promises.webReadGroup; const groupData = result.groups.map((group) => ({ ...group, - [gbFieldName]: Array.isArray(group[gbFieldName]) - ? group[gbFieldName][0] - : group[gbFieldName], + [gbFieldName]: this._getValueFromGroupData(group, this.firstGroupBy), })); for (const group of groups) { group.updateAggregates(groupData); @@ -485,16 +491,11 @@ export class KanbanDynamicGroupList extends DynamicGroupList { * @returns {Promise} */ async _fetchProgressData(domain) { - const { colors, fieldName, help, sumField } = this.model.progressAttributes; + const { colors, fieldName, help } = this.model.progressAttributes; return this.model.orm.call(this.resModel, "read_progress_bar", [], { domain, group_by: this.firstGroupBy, - progress_bar: { - colors, - field: fieldName, - help, - sum_field: sumField && sumField.name, - }, + progress_bar: { colors, field: fieldName, help }, context: this.context, }); } diff --git a/addons/web/static/src/views/relational_model.js b/addons/web/static/src/views/relational_model.js index 5ce8ba61668..cc3b98091ca 100644 --- a/addons/web/static/src/views/relational_model.js +++ b/addons/web/static/src/views/relational_model.js @@ -2297,6 +2297,26 @@ export class DynamicGroupList extends DynamicList { return group; } + /** + * @param {Object} groupData + * @param {string} fieldName + * @returns {any} + */ + _getValueFromGroupData(groupData, fieldName) { + const field = this.fields[fieldName.split(":")[0]]; + if (["date", "datetime"].includes(field.type)) { + const range = groupData.__range[fieldName]; + if (!range) { + return false; + } + const dateValue = this._parseServerValue(field, range.to); + return dateValue.minus({ [field.type === "date" ? "day" : "second"]: 1 }); + } else { + const value = this._parseServerValue(field, groupData[fieldName]); + return Array.isArray(value) ? value[0] : value; + } + } + async _loadGroups() { const firstGroupByName = this.firstGroupBy.split(":")[0]; const _orderBy = this.orderBy.filter( @@ -2332,14 +2352,7 @@ export class DynamicGroupList extends DynamicList { const value = data[key]; switch (key) { case this.firstGroupBy: { - if (value && ["date", "datetime"].includes(groupByField.type)) { - const dateString = data.__range[this.firstGroupBy].to; - const dateValue = this._parseServerValue(groupByField, dateString); - const granularity = groupByField.type === "date" ? "day" : "second"; - groupParams.value = dateValue.minus({ [granularity]: 1 }); - } else { - groupParams.value = Array.isArray(value) ? value[0] : value; - } + groupParams.value = this._getValueFromGroupData(data, key); if (groupByField.type === "selection") { groupParams.displayName = Object.fromEntries(groupByField.selection)[ groupParams.value diff --git a/addons/web/static/tests/views/kanban_view_tests.js b/addons/web/static/tests/views/kanban_view_tests.js index 1d21342c922..1ea59ca73e3 100644 --- a/addons/web/static/tests/views/kanban_view_tests.js +++ b/addons/web/static/tests/views/kanban_view_tests.js @@ -4666,6 +4666,82 @@ QUnit.module("Views", (hooks) => { } ); + QUnit.test("Move record in grouped by date, progress bars and sum field", async (assert) => { + serverData.models.partner.records[0].date = "2017-01-08"; + serverData.models.partner.records[1].date = "2017-01-09"; + serverData.models.partner.records[2].date = "2017-02-08"; + serverData.models.partner.records[3].date = "2017-02-10"; + + await makeView({ + type: "kanban", + resModel: "partner", + serverData, + arch: /* xml */ ` + + + + +
+ +
+
+
+ `, + groupBy: ["date:month"], + }); + + assert.containsN(target, ".o_kanban_group", 2); + assert.containsN( + target, + ".o_kanban_group:first-child .o_kanban_record", + 2, + "1st column should contain 2 records of January month" + ); + assert.containsN( + target, + ".o_kanban_group:nth-child(2) .o_kanban_record", + 2, + "2nd column should contain 2 records of February month" + ); + + assert.deepEqual( + getProgressBars(0).map((pb) => pb.style.width), + ["50%", "50%"] + ); + assert.deepEqual( + getProgressBars(1).map((pb) => pb.style.width), + ["50%", "50%"] + ); + assert.deepEqual(getCounters(), ["19", "13"]); + + await dragAndDrop( + ".o_kanban_group:first-child .o_kanban_record", + ".o_kanban_group:nth-child(2)" + ); + + assert.containsOnce( + target, + ".o_kanban_group:first-child .o_kanban_record", + "Should only have one record remaining" + ); + assert.containsN( + target, + ".o_kanban_group:nth-child(2) .o_kanban_record", + 3, + "Should now have 3 records" + ); + + assert.deepEqual( + getProgressBars(0).map((pb) => pb.style.width), + ["100%"] + ); + assert.deepEqual( + getProgressBars(1).map((pb) => pb.style.width), + ["33.3333%", "33.3333%", "33.3333%"] // abridged to e-4 + ); + assert.deepEqual(getCounters(), ["9", "23"]); + }); + QUnit.test( "completely prevent drag and drop if records_draggable set to false", async (assert) => {