[FIX] web: kanban column counter when grouped by a date

Before this commit, if the kanban was grouped by a date field, and have
an aggregate, the column counter was always 0.

Now, the column counter has the correct value.

closes odoo/odoo#133114

X-original-commit: ea3809a480c29eafd6ab8433d5ae0e378b1d9967
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
Signed-off-by: Jorge Pinna Puissant (jpp) <jpp@odoo.com>
This commit is contained in:
Jorge Pinna Puissant
2023-08-25 18:49:30 +02:00
parent 35ce7b9991
commit 0fd1790fb5
4 changed files with 97 additions and 38 deletions
@@ -230,6 +230,7 @@ export class DynamicGroupList extends DynamicList {
[this.groupByField.name]: [id, groupName],
value: id,
displayName: groupName,
rawValue: [id, groupName],
};
const group = this._createGroupDatapoint(data);
@@ -408,7 +408,7 @@ export class RelationalModel extends Model {
groupData[config.groupBy[0]],
group.range
);
group.rawValue = groupData[groupByField.name];
group.rawValue = groupData[config.groupBy];
group.displayName = getDisplayNameFromGroupData(
groupByField,
groupData[config.groupBy[0]]
@@ -14,15 +14,7 @@ const FALSE = Symbol("False");
*/
function _findGroup(groups, groupByField, value) {
return (
groups.find((s) => {
if (Array.isArray(s[groupByField.name])) {
return s[groupByField.name][0] === value;
} else {
return s[groupByField.name] === value;
}
}) || {}
);
return groups.find((g) => g[groupByField.name] === value) || {};
}
function _createFilterDomain(fieldName, bars, value) {
@@ -50,12 +42,13 @@ class ProgressBarState {
getGroupInfo(group) {
if (!this._groupsInfo[group.id]) {
if (
!Object.keys(_findGroup(this._aggregateValues, group.groupByField, group.value))
.length
!Object.keys(
_findGroup(this._aggregateValues, group.groupByField, group.serverValue)
).length
) {
this._aggregateValues.push({
...group.aggregates,
[group.groupByField.name]: group.value,
[group.groupByField.name]: group.serverValue,
});
}
let groupValue = group.displayName || group.value;
@@ -90,14 +83,14 @@ class ProgressBarState {
});
// Update activeBars count and aggreagates
if (this.activeBars[group.value]) {
this.activeBars[group.value].count = bars.find(
(x) => x.value === this.activeBars[group.value].value
if (this.activeBars[group.serverValue]) {
this.activeBars[group.serverValue].count = bars.find(
(x) => x.value === this.activeBars[group.serverValue].value
).count;
if (this.activeBars[group.value].count === 0) {
if (this.activeBars[group.serverValue].count === 0) {
group.applyFilter(undefined).then(() => {
delete this.activeBars[group.value];
delete this.activeBars[group.serverValue];
group.model.notify();
});
}
@@ -105,10 +98,10 @@ class ProgressBarState {
if (this._aggregateFields.length) {
//recompute the aggregates is not necessary
//the web_read_group was already done with the correct domain (containing the applied filter)
this.activeBars[group.value].aggregates = _findGroup(
this.activeBars[group.serverValue].aggregates = _findGroup(
this._aggregateValues,
group.groupByField,
group.value
group.serverValue
);
}
}
@@ -116,7 +109,7 @@ class ProgressBarState {
const self = this;
const progressBar = {
get activeBar() {
return self.activeBars[group.value]?.value || null;
return self.activeBars[group.serverValue]?.value || null;
},
bars,
};
@@ -129,20 +122,20 @@ class ProgressBarState {
getAggregateValue(group, aggregateField) {
const title = aggregateField ? aggregateField.string : _t("Count");
let value = 0;
if (!this.activeBars[group.value]) {
if (!this.activeBars[group.serverValue]) {
value = group.count;
if (aggregateField) {
value =
_findGroup(this._aggregateValues, group.groupByField, group.value)[
_findGroup(this._aggregateValues, group.groupByField, group.serverValue)[
aggregateField.name
] || 0;
}
} else {
value = this.activeBars[group.value].count;
value = this.activeBars[group.serverValue].count;
if (aggregateField) {
value =
(this.activeBars[group.value]?.aggregates &&
this.activeBars[group.value]?.aggregates[aggregateField.name]) ||
(this.activeBars[group.serverValue]?.aggregates &&
this.activeBars[group.serverValue]?.aggregates[aggregateField.name]) ||
0;
}
}
@@ -153,11 +146,11 @@ class ProgressBarState {
const group = this.model.root.groups.find((group) => group.id === groupId);
const progressBar = this.getGroupInfo(group);
const nextActiveBar = {};
if (bar.value && this.activeBars[group.value]?.value !== bar.value) {
if (bar.value && this.activeBars[group.serverValue]?.value !== bar.value) {
nextActiveBar.value = bar.value;
} else {
group.applyFilter(undefined).then(() => {
delete this.activeBars[group.value];
delete this.activeBars[group.serverValue];
group.model.notify();
});
return;
@@ -181,7 +174,7 @@ class ProgressBarState {
proms.push(this._updateAggregateGroup(group, bars, nextActiveBar));
}
await Promise.all(proms);
this.activeBars[group.value] = nextActiveBar;
this.activeBars[group.serverValue] = nextActiveBar;
}
_updateAggregateGroup(group, bars, activeBar) {
@@ -201,10 +194,10 @@ class ProgressBarState {
.webReadGroup(resModel, domain, fields, groupBy, kwargs)
.then((res) => {
if (res.length) {
const resGroup = _findGroup(res.groups, group.groupByField, group.value);
const resGroup = _findGroup(res.groups, group.groupByField, group.serverValue);
activeBar.aggregates = {
...resGroup,
[group.groupByField.name]: group.value,
[group.groupByField.name]: group.serverValue,
};
}
});
@@ -219,16 +212,16 @@ class ProgressBarState {
// If the selected bar is empty, remove the selection
for (const group of this.model.root.groups) {
if (this.activeBars[group.value] && group.list.count === 0) {
if (this.activeBars[group.serverValue] && group.list.count === 0) {
this.selectBar(group.id, { value: null });
}
}
}
updateAggreagteGroup(group) {
if (group && this.activeBars[group.value]) {
if (group && this.activeBars[group.serverValue]) {
const { bars } = this.getGroupInfo(group);
this._updateAggregateGroup(group, bars, this.activeBars[group.value]);
this._updateAggregateGroup(group, bars, this.activeBars[group.serverValue]);
}
}
@@ -244,7 +237,9 @@ class ProgressBarState {
groupBy,
kwargs
);
this._aggregateValues = res.groups;
this._aggregateValues = res.groups.map((r) => {
return { ...r, [firstGroupByName]: r[groupBy] };
});
}
async _updateProgressBar() {
@@ -282,9 +277,9 @@ class ProgressBarState {
? group.count - Object.values(counts).reduce((a, b) => a + b, 0)
: group.count;
if (this.activeBars[group.value]) {
this.activeBars[group.value].count = groupInfo.bars.find(
(x) => x.value === this.activeBars[group.value].value
if (this.activeBars[group.serverValue]) {
this.activeBars[group.serverValue].count = groupInfo.bars.find(
(x) => x.value === this.activeBars[group.serverValue].value
).count;
}
}
@@ -46,6 +46,7 @@ import { AnimatedNumber } from "@web/views/view_components/animated_number";
import { Component, onWillRender, xml } from "@odoo/owl";
import { SampleServer } from "@web/model/sample_server";
import { KanbanRenderer } from "@web/views/kanban/kanban_renderer";
const serviceRegistry = registry.category("services");
const viewWidgetRegistry = registry.category("view_widgets");
@@ -9897,6 +9898,68 @@ QUnit.module("Views", (hooks) => {
]);
});
QUnit.test(
"drag & drop records grouped by date with progressbar with aggregates",
async (assert) => {
serverData.models.partner.records[0].date = "2010-11-30";
serverData.models.partner.records[1].date = "2010-11-30";
serverData.models.partner.records[2].date = "2010-10-30";
serverData.models.partner.records[3].date = "2010-10-30";
// Usually kanban views grouped by a date, cannot drag and drop.
// There are some overrides that allow the drag and drop of dates (CRM forecast for instance).
// This patch is done to simulate these overrides.
patchWithCleanup(KanbanRenderer.prototype, {
isMovableField() {
return true;
},
});
await makeView({
type: "kanban",
resModel: "partner",
serverData,
arch: `
<kanban>
<progressbar field="foo" colors='{"yop": "success", "gnap": "warning", "blip": "danger"}' sum_field="int_field"/>
<templates>
<t t-name="kanban-box">
<div>
<field name="int_field"/>
</div>
</t>
</templates>
</kanban>`,
groupBy: ["date:month"],
async mockRPC(route, args) {
assert.step(args.method || route);
},
});
assert.deepEqual(getCounters(), ["13", "19"]);
await dragAndDrop(
".o_kanban_group:first-child .o_kanban_record",
".o_kanban_group:nth-child(2)"
);
assert.deepEqual(getCounters(), ["-4", "36"]);
assert.verifySteps([
"get_views",
"web_read_group",
"read_progress_bar",
"unity_web_search_read",
"unity_web_search_read",
"write",
"read_progress_bar",
"web_read_group",
"/web/dataset/resequence",
"read",
]);
}
);
QUnit.test("progress bar subgroup count recompute", async (assert) => {
await makeView({
type: "kanban",