3
0
Fork 0
web_techsystech/web_view_searchpanel/models/base.py

199 lines
7.5 KiB
Python

# Copyright 2017-2019 MuK IT GmbH.
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
import logging
from odoo import _, api, models
from odoo.exceptions import UserError
from odoo.osv import expression
_logger = logging.getLogger(__name__)
class Base(models.AbstractModel):
_inherit = 'base'
@api.model
def search_panel_select_range(self, field_name, **kwargs):
"""
Return possible values of the field field_name (case select="one")
and the parent field (if any) used to hierarchize them.
:param field_name: the name of a many2one category field
:return: {
'parent_field': parent field on the comodel of field, or False
'values': array of dictionaries containing some info on the
records available on the comodel of the field 'field_name'.
The display name (and possibly parent_field) are fetched.
}
"""
field = self._fields[field_name]
supported_types = ['many2one']
if field.type not in supported_types:
raise UserError(_(
'Only types %(supported_types)s are supported for category'
'(found type %(field_type)s)'
) % ({
'supported_types': supported_types,
'field_type': field.type
}))
Comodel = self.env[field.comodel_name]
fields = ['display_name']
parent_name = (
Comodel._parent_name if Comodel._parent_name
in Comodel._fields else False
)
if parent_name:
fields.append(parent_name)
model_domain = expression.AND([
kwargs.get('search_domain', []),
kwargs.get('category_domain', []),
kwargs.get('filter_domain', []),
])
return {
'parent_field': parent_name,
'values': Comodel.with_context(
hierarchical_naming=False).search_read(model_domain, fields),
}
@api.model
def search_panel_select_multi_range(self, field_name, **kwargs):
"""
Return possible values of the field field_name (case select="multi"),
possibly with counters and groups.
:param field_name: the name of a filter field;
possible types are many2one, many2many, selection.
:param search_domain: base domain of search
:param category_domain: domain generated by categories
:param filter_domain: domain generated by filters
:param comodel_domain: domain of field values (if relational)
:param group_by: extra field to read on comodel, to group comodel
records
:param disable_counters: whether to count records by value
:return: a list of possible values, each being a dict with keys
'id' (value),
'name' (value label),
'count' (how many records with that value),
'group_id' (value of group),
'group_name' (label of group).
"""
field = self._fields[field_name]
supported_types = ['many2one', 'many2many', 'selection']
if field.type not in supported_types:
raise UserError(_(
'Only types %(supported_types)s are supported for '
'filter (found type %(field_type)s)'
) % ({
'supported_types': supported_types, 'field_type': field.type}))
Comodel = self.env.get(field.comodel_name)
model_domain = expression.AND([
kwargs.get('search_domain', []),
kwargs.get('category_domain', []),
kwargs.get('filter_domain', []),
[(field_name, '!=', False)],
])
comodel_domain = kwargs.get('comodel_domain', [])
disable_counters = kwargs.get('disable_counters', False)
group_by = kwargs.get('group_by', False)
if group_by:
# determine the labeling of values returned by the group_by field
group_by_field = Comodel._fields[group_by]
if group_by_field.type == 'many2one':
def group_id_name(value):
return value or (False, _("Not Set"))
elif group_by_field.type == 'selection':
desc = Comodel.fields_get([group_by])[group_by]
group_by_selection = dict(desc['selection'])
group_by_selection[False] = _("Not Set")
def group_id_name(value):
return value, group_by_selection[value]
else:
def group_id_name(value):
return (value, value) if value else (False, _("Not Set"))
# get filter_values
filter_values = []
if field.type == 'many2one':
counters = {}
if not disable_counters:
groups = self.read_group(
model_domain, [field_name], [field_name])
counters = {
group[field_name][0]: group[field_name + '_count']
for group in groups
}
# retrieve all possible values, and return them with their label
# and counter
field_names = ['display_name']
if group_by:
field_names.append(group_by)
records = Comodel.search_read(comodel_domain, field_names)
for record in records:
record_id = record['id']
values = {
'id': record_id,
'name': record['display_name'],
'count': counters.get(record_id, 0),
}
if group_by:
values['group_id'], values['group_name'] = group_id_name(
record[group_by])
filter_values.append(values)
elif field.type == 'many2many':
# retrieve all possible values, and return them with their label
# and counter
field_names = ['display_name']
if group_by:
field_names.append(group_by)
records = Comodel.search_read(comodel_domain, field_names)
for record in records:
record_id = record['id']
values = {
'id': record_id,
'name': record['display_name'],
'count': 0,
}
if not disable_counters:
count_domain = expression.AND([
model_domain, [(field_name, 'in', record_id)]])
values['count'] = self.search_count(count_domain)
if group_by:
values['group_id'], values['group_name'] = group_id_name(
record[group_by])
filter_values.append(values)
elif field.type == 'selection':
counters = {}
if not disable_counters:
groups = self.read_group(
model_domain, [field_name], [field_name])
counters = {
group[field_name]: group[field_name + '_count']
for group in groups
}
# retrieve all possible values, and return them with their label
# and counter
selection = self.fields_get([field_name])[field_name]['selection']
for value, label in selection:
filter_values.append({
'id': value,
'name': label,
'count': counters.get(value, 0),
})
return filter_values