Skip to content

Commit

Permalink
[IMP] mis_builder: take field context into account
Browse files Browse the repository at this point in the history
Prior to this commit only the action context was taken into account
when looking for the `mis_analytic_domain` key in the context.

This commit adds the support of the field context, where `self`
can be used in order to inject record data in the context.
  • Loading branch information
Laurent Stukkens committed Jan 17, 2024
1 parent b0692f8 commit ed9eec9
Showing 1 changed file with 65 additions and 4 deletions.
69 changes: 65 additions & 4 deletions mis_builder/static/src/components/mis_report_widget.esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@ import {Domain} from "@web/core/domain";
import {FilterMenu} from "@web/search/filter_menu/filter_menu";
import {SearchBar} from "@web/search/search_bar/search_bar";
import {SearchModel} from "@web/search/search_model";
import {evaluateExpr} from "@web/core/py_js/py";
import {parseDate} from "@web/core/l10n/dates";
import {registry} from "@web/core/registry";
import {useSetupAction} from "@web/webclient/actions/action_hook";

const misAnalyticDomainKey = "mis_analytic_domain";

export class MisReportWidget extends Component {
setup() {
super.setup();
Expand Down Expand Up @@ -121,15 +124,73 @@ export class MisReportWidget extends Component {
}
}

/**
* Get the record data in a form that is usable for the domain eval. All the
* `many2one` values are returned as id instead of a list (id, value).
*
* @returns {Object}
* @private
*/
_getRecordDataForDomainResolution() {
const recordData = {};
for (const [fieldName, value] of Object.entries(this.props.record.data)) {
if (this.props.record.fields[fieldName].type !== "one2many") {
if (this.props.record.fields[fieldName].type === "many2one") {
recordData[fieldName] = value[0];
continue;
}
recordData[fieldName] = value;
}
}
return recordData;
}

/**
* The domain built from both the context that is passed through the action
* and the one that is set on the field in the view. The last one being evaluated
* against the context populated with a self property populated with the record data.
*
* @returns {Domain}
*/
get miscAnalyticDomain() {
let domain = Domain.TRUE;
// Get the domain that is set on the action
const recordContext = this.props.record.context;
if (misAnalyticDomainKey in recordContext) {
const recordDomain = new Domain(recordContext[misAnalyticDomainKey]);
domain = Domain.and([domain, recordDomain]);
}
// Get the domain that is set on the field and evaluate it with both the context
// and the record data mounted on a self property.
if ("context" in this.props.record.activeFields[this.props.name]) {
const contextAttr = this.props.record.activeFields[this.props.name].context;
const evaluation_context = {
...recordContext,
self: this._getRecordDataForDomainResolution(),
};
const fieldContext = evaluateExpr(contextAttr, evaluation_context);
if (misAnalyticDomainKey in fieldContext) {
const fieldDomain = new Domain(fieldContext[misAnalyticDomainKey]);
domain = Domain.and([domain, fieldDomain]);
}
}
return domain;
}

get context() {
let ctx = this.props.record.context;
const misAnalyticDomain = this.miscAnalyticDomain;
if (misAnalyticDomain !== Domain.TRUE) {
ctx = {
...ctx,
[misAnalyticDomainKey]: misAnalyticDomain.toList(),
};
}
if (this.showSearchBar && this.searchModel.searchDomain) {
ctx = {
...ctx,
mis_analytic_domain: Domain.and([
new Domain(
this.props.record.context.mis_analytic_domain || Domain.TRUE
),
[misAnalyticDomainKey]: Domain.and([
new Domain(ctx[misAnalyticDomainKey] || Domain.TRUE),
new Domain(this.searchModel.searchDomain),
]).toList(),
};
Expand Down

0 comments on commit ed9eec9

Please sign in to comment.