2009-02-03 18:58:25 +01:00
|
|
|
#This file is part of Tryton. The COPYRIGHT file at the top level of
|
|
|
|
|
#this repository contains the full copyright notices and license terms.
|
|
|
|
|
|
2010-03-11 16:42:50 +01:00
|
|
|
import inspect
|
|
|
|
|
import copy
|
2009-02-03 18:58:25 +01:00
|
|
|
from trytond.model.fields.field import Field
|
2010-01-20 10:55:19 +01:00
|
|
|
from trytond.model.fields.float import digits_validate
|
|
|
|
|
from trytond.model.fields.one2many import add_remove_validate
|
|
|
|
|
from trytond.pyson import PYSON
|
2009-02-03 18:58:25 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
class Function(Field):
|
2009-03-01 13:37:31 +01:00
|
|
|
'''
|
2009-09-13 15:37:11 +02:00
|
|
|
Define function field (any).
|
2009-03-01 13:37:31 +01:00
|
|
|
'''
|
2009-02-03 18:58:25 +01:00
|
|
|
|
2011-01-07 10:58:43 +01:00
|
|
|
def __init__(self, field, getter, setter=None, searcher=None,
|
|
|
|
|
loading='lazy'):
|
2009-03-01 13:37:31 +01:00
|
|
|
'''
|
2010-03-11 16:42:50 +01:00
|
|
|
:param field: The field of the function.
|
|
|
|
|
:param getter: The name of the function for getting values.
|
|
|
|
|
:param setter: The name of the function to set value.
|
|
|
|
|
:param searcher: The name of the function to search.
|
2011-01-07 10:58:43 +01:00
|
|
|
:param loading: Define how the field must be loaded:
|
|
|
|
|
``lazy`` or ``eager``.
|
2009-03-01 13:37:31 +01:00
|
|
|
'''
|
2010-03-11 16:42:50 +01:00
|
|
|
assert isinstance(field, Field)
|
|
|
|
|
self._field = field
|
|
|
|
|
self._type = field._type
|
|
|
|
|
self.getter = getter
|
|
|
|
|
self.setter = setter
|
|
|
|
|
if not self.setter:
|
|
|
|
|
self._field.readonly = True
|
|
|
|
|
self.searcher = searcher
|
2011-01-07 10:58:43 +01:00
|
|
|
assert loading in ('lazy', 'eager'), 'loading must be "lazy" or "eager"'
|
|
|
|
|
self.loading = loading
|
2010-01-20 10:55:19 +01:00
|
|
|
|
2009-03-01 13:37:31 +01:00
|
|
|
__init__.__doc__ += Field.__init__.__doc__
|
2009-02-03 18:58:25 +01:00
|
|
|
|
2010-03-11 16:42:50 +01:00
|
|
|
def __copy__(self):
|
|
|
|
|
return Function(copy.copy(self._field), self.getter,
|
|
|
|
|
setter=self.setter, searcher=self.searcher)
|
2010-01-20 10:55:19 +01:00
|
|
|
|
2010-03-11 16:42:50 +01:00
|
|
|
def __getattr__(self, name):
|
|
|
|
|
return getattr(self._field, name)
|
2010-01-20 10:55:19 +01:00
|
|
|
|
2010-03-11 16:42:50 +01:00
|
|
|
def __getitem__(self, name):
|
|
|
|
|
return self._field[name]
|
2010-01-20 10:55:19 +01:00
|
|
|
|
2010-03-11 16:42:50 +01:00
|
|
|
def __setattr__(self, name, value):
|
|
|
|
|
if name in ('_field', '_type', 'getter', 'setter', 'searcher'):
|
|
|
|
|
return object.__setattr__(self, name, value)
|
|
|
|
|
return setattr(self._field, name, value)
|
2010-01-20 10:55:19 +01:00
|
|
|
|
2010-08-19 22:01:12 +02:00
|
|
|
def search(self, model, name, clause):
|
2009-03-01 13:37:31 +01:00
|
|
|
'''
|
2010-03-11 16:42:50 +01:00
|
|
|
Call the searcher.
|
2009-03-01 13:37:31 +01:00
|
|
|
|
|
|
|
|
:param model: The model.
|
2010-01-26 12:15:35 +01:00
|
|
|
:param name: The name of the field.
|
2010-03-23 11:22:31 +01:00
|
|
|
:param clause: The search domain clause. See ModelStorage.search
|
|
|
|
|
:return: a list of domain clause.
|
2009-03-01 13:37:31 +01:00
|
|
|
'''
|
2010-03-11 16:42:50 +01:00
|
|
|
if not self.searcher:
|
2010-08-19 22:01:12 +02:00
|
|
|
model.raise_user_error('search_function_missing', name)
|
|
|
|
|
return getattr(model, self.searcher)(name, tuple(clause))
|
2009-02-03 18:58:25 +01:00
|
|
|
|
2010-08-19 22:01:12 +02:00
|
|
|
def get(self, ids, model, name, values=None):
|
2009-03-01 13:37:31 +01:00
|
|
|
'''
|
2010-03-11 16:42:50 +01:00
|
|
|
Call the getter.
|
2009-03-01 13:37:31 +01:00
|
|
|
If the function has ``names`` in the function definition then
|
|
|
|
|
it will call it with a list of name.
|
|
|
|
|
|
|
|
|
|
:param ids: A list of ids.
|
|
|
|
|
:param model: The model.
|
|
|
|
|
:param name: The name of the field or a list of name field.
|
|
|
|
|
:param values:
|
|
|
|
|
:return: a dictionary with ids as key and values as value or
|
|
|
|
|
a dictionary with name as key and a dictionary as value if
|
|
|
|
|
name is a list of field name.
|
|
|
|
|
'''
|
2009-02-03 18:58:25 +01:00
|
|
|
if isinstance(name, list):
|
|
|
|
|
names = name
|
|
|
|
|
# Test is the function works with a list of names
|
2010-03-11 16:42:50 +01:00
|
|
|
if 'names' in inspect.getargspec(getattr(model, self.getter))[0]:
|
2010-08-19 22:01:12 +02:00
|
|
|
return getattr(model, self.getter)(ids, names)
|
2009-02-03 18:58:25 +01:00
|
|
|
res = {}
|
|
|
|
|
for name in names:
|
2010-08-19 22:01:12 +02:00
|
|
|
res[name] = getattr(model, self.getter)(ids, name)
|
2009-02-03 18:58:25 +01:00
|
|
|
return res
|
|
|
|
|
else:
|
|
|
|
|
# Test is the function works with a list of names
|
2010-03-11 16:42:50 +01:00
|
|
|
if 'names' in inspect.getargspec(getattr(model, self.getter))[0]:
|
2009-02-03 18:58:25 +01:00
|
|
|
name = [name]
|
2010-08-19 22:01:12 +02:00
|
|
|
return getattr(model, self.getter)(ids, name)
|
2009-02-03 18:58:25 +01:00
|
|
|
|
|
|
|
|
|
2010-08-19 22:01:12 +02:00
|
|
|
def set(self, ids, model, name, value):
|
2009-03-01 13:37:31 +01:00
|
|
|
'''
|
2010-03-11 16:42:50 +01:00
|
|
|
Call the setter.
|
2009-03-01 13:37:31 +01:00
|
|
|
|
2010-03-11 16:42:50 +01:00
|
|
|
:param ids: A list of ids.
|
2009-03-01 13:37:31 +01:00
|
|
|
:param model: The model.
|
|
|
|
|
:param name: The name of the field.
|
|
|
|
|
:param value: The value to set.
|
|
|
|
|
'''
|
2010-03-11 16:42:50 +01:00
|
|
|
if self.setter:
|
2010-08-19 22:01:12 +02:00
|
|
|
getattr(model, self.setter)(ids, name, value)
|