Skip to content

Commit

Permalink
[IMP] mis-builder: set analytic account constraint in the filter when…
Browse files Browse the repository at this point in the history
… displayed

This commit extracts, when the filters are displayed, the domain info
from the `mis_analytic_domain` context key or from the
analyticAccountIdField props and add it to the active filters.

The system prevents the user from removing the constraint.
  • Loading branch information
Laurent Stukkens committed Dec 27, 2023
1 parent dcc1903 commit 9a8add9
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 33 deletions.
1 change: 1 addition & 0 deletions mis_builder/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
],
"assets": {
"web.assets_backend": [
"mis_builder/static/src/components/search_model.esm.js",
"mis_builder/static/src/components/mis_report_widget.esm.js",
"mis_builder/static/src/components/mis_report_widget.xml",
"mis_builder/static/src/components/mis_report_widget.css",
Expand Down
77 changes: 44 additions & 33 deletions mis_builder/static/src/components/mis_report_widget.esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@
import {Component, onWillStart, useState, useSubEnv} from "@odoo/owl";
import {useBus, useService} from "@web/core/utils/hooks";
import {DatePicker} from "@web/core/datepicker/datepicker";
import {Domain} from "@web/core/domain";
import {FilterMenu} from "@web/search/filter_menu/filter_menu";
import {MisReportSearchModel} from "@mis_builder/components/search_model.esm";
import {SearchBar} from "@web/search/search_bar/search_bar";
import {SearchModel} from "@web/search/search_model";
import {parseDate} from "@web/core/l10n/dates";
import {registry} from "@web/core/registry";
import {standardFieldProps} from "@web/views/fields/standard_field_props";
Expand All @@ -23,7 +22,7 @@ export class MisReportWidget extends Component {
mis_report_data: {header: [], body: []},
pivot_date: null,
});
this.searchModel = new SearchModel(this.env, {
this.searchModel = new MisReportSearchModel(this.env, {
user: this.user,
orm: this.orm,
view: this.view,
Expand Down Expand Up @@ -63,6 +62,7 @@ export class MisReportWidget extends Component {
await this.searchModel.load({
resModel: this.source_aml_model_name,
searchViewId: this.widget_search_view_id,
analyticAccountId: this.analyticAccountId,
});
}

Expand Down Expand Up @@ -111,12 +111,10 @@ export class MisReportWidget extends Component {

get context() {
let ctx = this.props.record.context;
this.setMisAnalyticDomainContextKey(ctx);
if (this.showSearchBar && this.searchModel.searchDomain) {
ctx[this.misAnalyticDomainContextKey] = Domain.and([
ctx[this.misAnalyticDomainContextKey],
new Domain(this.searchModel.searchDomain),
]).toList();
ctx[this.misAnalyticDomainContextKey] = this.searchModel.searchDomain;
} else {
this._setMisAnalyticDomainContextKey(ctx);
}
if (this.showPivotDate && this.state.pivot_date) {
ctx = {
Expand Down Expand Up @@ -147,34 +145,47 @@ export class MisReportWidget extends Component {
);
}

setMisAnalyticDomainContextKey(context) {
get analyticAccountId() {
let analyticAccountId = this._getAnalyticAccountIdFromData();
if (
this.props.analytic_account_id_field &&
!(this.misAnalyticDomainContextKey in context)
!analyticAccountId &&
this.props.record.context &&
this.props.record.context.mis_analytic_domain
) {
let analyticAccountId = false;
const analyticAccountIdFieldType =
this.props.record.fields[this.props.analytic_account_id_field].type;
switch (analyticAccountIdFieldType) {
case "many2one":
analyticAccountId =
this.props.record.data[this.props.analytic_account_id_field][0];
break;
case "integer":
analyticAccountId =
this.props.record.data[this.props.analytic_account_id_field];
break;
default:
throw new Error(
```Unsupported field type for analytic_account_id: ${analyticAccountIdFieldType}```
);
}
if (analyticAccountId) {
context[this.misAnalyticDomainContextKey] = [
["analytic_account_id", "=", analyticAccountId],
];
}
analyticAccountId = this.props.record.context.mis_analytic_domain[0][2];
}
return analyticAccountId;
}

_getAnalyticAccountIdFromData() {
if (
!this.props.analyticAccountIdField ||
!(this.props.analyticAccountIdField in this.props.record.fields)
) {
return false;
}
const analyticAccountIdFieldType =
this.props.record.fields[this.props.analyticAccountIdField].type;
switch (analyticAccountIdFieldType) {
case "many2one":
return this.props.record.data[this.props.analyticAccountIdField][0];
case "integer":
return this.props.record.data[this.props.analyticAccountIdField];
default:
throw new Error(
```Unsupported field type for analytic_account_id: ${analyticAccountIdFieldType}```
);
}
}

_setMisAnalyticDomainContextKey(context) {
const analyticAccountId = this._getAnalyticAccountIdFromData();
if (!analyticAccountId) {
return;
}
context[this.misAnalyticDomainContextKey] = [
["analytic_account_id", "=", analyticAccountId],
];
}

async printPdf() {
Expand Down
105 changes: 105 additions & 0 deletions mis_builder/static/src/components/search_model.esm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/** @odoo-module **/

import {SearchModel} from "@web/search/search_model";
import {useService} from "@web/core/utils/hooks";

export class MisReportSearchModel extends SearchModel {
/**
* @override
*/
setup() {
this.notificationService = useService("notification");
super.setup(...arguments);
}

/**
* @override
*/
deactivateGroup(groupId) {
// Prevent removing the analytic account filter and let the user know.
let reactivateAnalyticAccountFilter = false;
if (this.analyticAccountSearchItem.groupId === groupId) {
if (
this.query.filter(
(query) => query.searchItemId === this.analyticAccountSearchItem.id
).length === 1
) {
this.notificationService.add(
this.env._t("The analytic account filter cannot be removed"),
{type: "info"}
);
return;
}
// As there are more than one filter on the analytic account, let
// super remove them and add it back after.
reactivateAnalyticAccountFilter = true;
}
super.deactivateGroup(groupId);
if (reactivateAnalyticAccountFilter) {
this._addAnalyticAccountFilter();
}
}

/**
* @override
*/
async load(config) {
// Store analytic account id in the SearchModel for reuse in other functions.
this.analyticAccountId = config.analyticAccountId;
const analyticAccountNamePromise = this._loadAnalyticAccountName();
await Promise.all([analyticAccountNamePromise, super.load(...arguments)]);
this._determineAnalyticAccountSearchItem();
this._addAnalyticAccountFilter();
}

/**
* Add the filter regarding the analytic account in the search model.
* @private
*/
_addAnalyticAccountFilter() {
if (!this.analyticAccountSearchItem || !this.analyticAccountName) {
return;
}
this.addAutoCompletionValues(this.analyticAccountSearchItem.id, {
label: this.analyticAccountName,
operator: "=",
value: this.analyticAccountId,
});
}

/**
* Find the searchItem that correspond to the analytic account field and store it
* under analyticAccountSearchItem.
* @private
*/
_determineAnalyticAccountSearchItem() {
// Store analytic account searchItem in the SearchModel for reuse in other functions.
for (const searchItem of Object.values(this.searchItems)) {
if (
searchItem.type === "field" &&
searchItem.fieldName === "analytic_account_id"
) {
this.analyticAccountSearchItem = searchItem;
break;
}
}
}

/**
* Load the analytic account name and store it under analyticAccountName.
* @returns {Promise<void>}
* @private
*/
async _loadAnalyticAccountName() {
if (!this.analyticAccountId) {
return;
}
const readResult = await this.orm.read(
"account.analytic.account",
[this.analyticAccountId],
["display_name"]
);
const analyticAccount = readResult[0];
this.analyticAccountName = analyticAccount.display_name;
}
}

0 comments on commit 9a8add9

Please sign in to comment.