[FIX] analytic: allow filtering based on analytic distribution
Currently, the field `analytic_distribution` does not appear in the filters, while it should (to be able to filter `account_move_line` for example). We added Json to the filterable fields. If not overriden, it will search on it like a String. We also have to add a non-stored field to be able to define a search function for `analytic_distribution`, to be able to search based on the keys of the json. closes odoo/odoo#121223 X-original-commit: 3d3e6847230d5cc9cd61a9bf83bef403a5b4b3ec Signed-off-by: William André (wan) <wan@odoo.com>
This commit is contained in:
committed by
Gauthier Wala (gawa)
parent
216fa84fbe
commit
dba7056c71
@@ -123,6 +123,12 @@ msgstr ""
|
||||
msgid "Analytic Distribution Models"
|
||||
msgstr ""
|
||||
|
||||
#. module: analytic
|
||||
#: model:ir.model.fields,field_description:analytic.field_account_analytic_distribution_model__analytic_distribution_search
|
||||
#: model:ir.model.fields,field_description:analytic.field_analytic_mixin__analytic_distribution_search
|
||||
msgid "Analytic Distribution Search"
|
||||
msgstr ""
|
||||
|
||||
#. module: analytic
|
||||
#. odoo-javascript
|
||||
#: code:addons/analytic/static/src/components/analytic_distribution/analytic_distribution.js:0
|
||||
@@ -577,6 +583,13 @@ msgstr ""
|
||||
msgid "One or more lines require a 100% analytic distribution."
|
||||
msgstr ""
|
||||
|
||||
#. module: analytic
|
||||
#. odoo-python
|
||||
#: code:addons/analytic/models/analytic_mixin.py:0
|
||||
#, python-format
|
||||
msgid "Operation not supported"
|
||||
msgstr ""
|
||||
|
||||
#. module: analytic
|
||||
#. odoo-javascript
|
||||
#: code:addons/analytic/static/src/components/analytic_distribution/analytic_distribution.js:0
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
from odoo import models, fields, api, _
|
||||
from odoo.tools.float_utils import float_round, float_compare
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
|
||||
class AnalyticMixin(models.AbstractModel):
|
||||
_name = 'analytic.mixin'
|
||||
@@ -13,6 +13,11 @@ class AnalyticMixin(models.AbstractModel):
|
||||
compute="_compute_analytic_distribution", store=True, copy=True, readonly=False,
|
||||
precompute=True
|
||||
)
|
||||
# Json non stored to be able to search on analytic_distribution.
|
||||
analytic_distribution_search = fields.Json(
|
||||
store=False,
|
||||
search="_search_analytic_distribution"
|
||||
)
|
||||
analytic_precision = fields.Integer(
|
||||
store=False,
|
||||
default=lambda self: self.env['decimal.precision'].precision_get("Percentage Analytic"),
|
||||
@@ -32,9 +37,38 @@ class AnalyticMixin(models.AbstractModel):
|
||||
self.env.cr.execute(query)
|
||||
super().init()
|
||||
|
||||
@api.model
|
||||
def fields_get(self, allfields=None, attributes=None):
|
||||
""" Hide analytic_distribution_search from filterable/searchable fields"""
|
||||
res = super().fields_get(allfields, attributes)
|
||||
if res.get('analytic_distribution_search'):
|
||||
res['analytic_distribution_search']['searchable'] = False
|
||||
return res
|
||||
|
||||
def _compute_analytic_distribution(self):
|
||||
pass
|
||||
|
||||
def _search_analytic_distribution(self, operator, value):
|
||||
if operator not in ['=', '!=', 'ilike', 'not ilike'] or not isinstance(value, (str, bool)):
|
||||
raise UserError(_('Operation not supported'))
|
||||
operator_name_search = '=' if operator in ('=', '!=') else 'ilike'
|
||||
account_ids = list(self.env['account.analytic.account']._name_search(name=value, operator=operator_name_search))
|
||||
|
||||
query = f"""
|
||||
SELECT id
|
||||
FROM {self._table}
|
||||
WHERE analytic_distribution ?| array[%s]
|
||||
"""
|
||||
operator_inselect = 'inselect' if operator in ('=', 'ilike') else 'not inselect'
|
||||
return [('id', operator_inselect, (query, [[str(account_id) for account_id in account_ids]]))]
|
||||
|
||||
@api.model
|
||||
def _search(self, domain, offset=0, limit=None, order=None, access_rights_uid=None):
|
||||
for arg in domain:
|
||||
if isinstance(arg, (list, tuple)) and arg[0] == 'analytic_distribution' and isinstance(arg[2], str):
|
||||
arg[0] = 'analytic_distribution_search'
|
||||
return super()._search(domain, offset, limit, order, access_rights_uid)
|
||||
|
||||
def write(self, vals):
|
||||
""" Format the analytic_distribution float value, so equality on analytic_distribution can be done """
|
||||
decimal_precision = self.env['decimal.precision'].precision_get('Percentage Analytic')
|
||||
|
||||
@@ -328,6 +328,16 @@ const PROPERTIES_RELATIONAL = {
|
||||
defaultValue: (fieldDef) => (fieldDef.type === "many2one" ? 1 : []),
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const JSON_FIELD = {
|
||||
operators: ["equal", "not_equal", "ilike", "not_ilike","set", "not_set"],
|
||||
editors: {
|
||||
default: makeEditor(Input),
|
||||
},
|
||||
defaultValue: () => "",
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
|
||||
export const FIELD_DESCRIPTIONS = {
|
||||
@@ -338,6 +348,7 @@ export const FIELD_DESCRIPTIONS = {
|
||||
float: NUMBER,
|
||||
html: TEXT,
|
||||
integer: NUMBER,
|
||||
json: JSON_FIELD,
|
||||
many2many: RELATIONAL,
|
||||
many2one: RELATIONAL,
|
||||
monetary: NUMBER,
|
||||
|
||||
@@ -82,6 +82,7 @@ QUnit.module("Components", (hooks) => {
|
||||
},
|
||||
datetime: { string: "Date Time", type: "datetime", searchable: true },
|
||||
int: { string: "Integer", type: "integer", searchable: true },
|
||||
json_field: { string: "Json Field", type: "json", searchable: true},
|
||||
},
|
||||
records: [
|
||||
{ id: 1, foo: "yop", bar: true, product_id: 37 },
|
||||
@@ -620,6 +621,17 @@ QUnit.module("Components", (hooks) => {
|
||||
assert.strictEqual(comp.domain, `[("state", "in", ["b"])]`);
|
||||
});
|
||||
|
||||
QUnit.test("json field with operator change from 'equal' to 'ilike'", async (assert) => {
|
||||
|
||||
await makeDomainSelector({ domain: `[['json_field', '=', "hey"]]` });
|
||||
assert.strictEqual(target.querySelector(".o_model_field_selector_chain_part").innerText, `Json Field`);
|
||||
assert.strictEqual(target.querySelector(".o_domain_leaf_operator_select").value, "equal"); // option "="
|
||||
assert.strictEqual(target.querySelector(".o_domain_leaf_value_input").value, `hey`);
|
||||
|
||||
await editSelect(target, ".o_domain_leaf_operator_select", "ilike");
|
||||
assert.strictEqual(target.querySelector(".o_domain_leaf_operator_select").value, "ilike"); // option "ilike"
|
||||
});
|
||||
|
||||
QUnit.test("parse -1", async (assert) => {
|
||||
class Parent extends Component {
|
||||
setup() {
|
||||
|
||||
Reference in New Issue
Block a user