Initial import from Docker volume
This commit is contained in:
111
model/fields/multiselection.py
Executable file
111
model/fields/multiselection.py
Executable file
@@ -0,0 +1,111 @@
|
||||
# This file is part of Tryton. The COPYRIGHT file at the toplevel of this
|
||||
# repository contains the full copyright notices and license terms.
|
||||
import json
|
||||
from functools import partial
|
||||
|
||||
from sql import Literal, operators
|
||||
|
||||
from trytond.rpc import RPC
|
||||
from trytond.transaction import Transaction
|
||||
|
||||
from .field import Field, domain_method
|
||||
from .selection import SelectionMixin
|
||||
|
||||
# Use canonical form
|
||||
dumps = partial(json.dumps, separators=(',', ':'), sort_keys=True)
|
||||
|
||||
|
||||
class MultiSelection(SelectionMixin, Field):
|
||||
"Define a multi-selection field."
|
||||
_type = 'multiselection'
|
||||
_sql_type = 'VARCHAR'
|
||||
_py_type = tuple
|
||||
|
||||
def __init__(self, selection, string='', sort=True, translate=True,
|
||||
help='', help_selection=None, required=False, readonly=False,
|
||||
domain=None, states=None, on_change=None,
|
||||
on_change_with=None, depends=None, context=None, loading='eager'):
|
||||
"""
|
||||
:param selection: A list or a function name that returns a list.
|
||||
The list must be a list of tuples. First member is the value
|
||||
to store and the second is the value to display.
|
||||
:param sort: A boolean to sort or not the selections.
|
||||
"""
|
||||
super().__init__(string=string, help=help,
|
||||
required=required, readonly=readonly, domain=domain, states=states,
|
||||
on_change=on_change, on_change_with=on_change_with,
|
||||
depends=depends, context=context, loading=loading)
|
||||
if hasattr(selection, 'copy'):
|
||||
self.selection = selection.copy()
|
||||
else:
|
||||
self.selection = selection
|
||||
self.selection_change_with = set()
|
||||
self.sort = sort
|
||||
self.translate_selection = translate
|
||||
self.help_selection = help_selection
|
||||
__init__.__doc__ += Field.__init__.__doc__
|
||||
|
||||
def set_rpc(self, model):
|
||||
super().set_rpc(model)
|
||||
if not isinstance(self.selection, (list, tuple)):
|
||||
assert hasattr(model, self.selection), \
|
||||
'Missing %s on model %s' % (self.selection, model.__name__)
|
||||
instantiate = 0 if self.selection_change_with else None
|
||||
cache = dict(days=1) if instantiate is None else None
|
||||
model.__rpc__.setdefault(
|
||||
self.selection, RPC(instantiate=instantiate, cache=cache))
|
||||
|
||||
def get(self, ids, model, name, values=None):
|
||||
lists = {id: () for id in ids}
|
||||
for value in values or []:
|
||||
data = value[name]
|
||||
if data:
|
||||
# If stored as JSON conversion is done on backend
|
||||
if isinstance(data, str):
|
||||
data = json.loads(data)
|
||||
lists[value['id']] = tuple(data)
|
||||
return lists
|
||||
|
||||
def sql_format(self, value):
|
||||
value = super().sql_format(value)
|
||||
if isinstance(value, (list, tuple)):
|
||||
value = dumps(sorted(set(value)))
|
||||
return value
|
||||
|
||||
def _domain_column(self, operator, column):
|
||||
database = Transaction().database
|
||||
return database.json_get(super()._domain_column(operator, column))
|
||||
|
||||
def _domain_value(self, operator, value):
|
||||
database = Transaction().database
|
||||
domain_value = super()._domain_value(operator, value)
|
||||
if value is not None:
|
||||
domain_value = database.json_get(domain_value)
|
||||
return domain_value
|
||||
|
||||
@domain_method
|
||||
def convert_domain(self, domain, tables, Model):
|
||||
name, operator, value = domain[:3]
|
||||
if operator not in {'in', 'not in'}:
|
||||
return super().convert_domain(domain, tables, Model)
|
||||
database = Transaction().database
|
||||
table, _ = tables[None]
|
||||
raw_column = self.sql_column(table)
|
||||
if isinstance(value, str):
|
||||
try:
|
||||
expression = database.json_key_exists(raw_column, value)
|
||||
except NotImplementedError:
|
||||
expression = operators.Like(
|
||||
raw_column, '%' + dumps(value) + '%')
|
||||
else:
|
||||
try:
|
||||
expression = database.json_any_keys_exist(
|
||||
raw_column, list(value))
|
||||
except NotImplementedError:
|
||||
expression = Literal(False)
|
||||
for item in value:
|
||||
expression |= operators.Like(
|
||||
raw_column, '%' + dumps(item) + '%')
|
||||
if operator == 'not in':
|
||||
expression = operators.Not(expression)
|
||||
return expression
|
||||
Reference in New Issue
Block a user