You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
196 lines
8.2 KiB
196 lines
8.2 KiB
###################################################################################
|
|
#
|
|
# Copyright (c) 2017-2019 MuK IT GmbH.
|
|
#
|
|
# This file is part of MuK Search Panel
|
|
# (see https://mukit.at).
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU Lesser General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU Lesser General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Lesser General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
###################################################################################
|
|
|
|
import logging
|
|
|
|
from odoo import _, api, fields, models
|
|
from odoo.exceptions import UserError
|
|
from odoo.osv import expression
|
|
from odoo.tools import lazy
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
class Base(models.AbstractModel):
|
|
|
|
_inherit = 'base'
|
|
|
|
#----------------------------------------------------------
|
|
# Functions
|
|
#----------------------------------------------------------
|
|
|
|
@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', group_by] if group_by else ['display_name']
|
|
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', group_by] if group_by else ['display_name']
|
|
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]
|
|
for value, label in selection:
|
|
filter_values.append({
|
|
'id': value,
|
|
'name': label,
|
|
'count': counters.get(value, 0),
|
|
})
|
|
|
|
return filter_values
|