New interface for Function/Property fields
Function field takes an other field in parameters set/get function on Fields take a list of ids
This commit is contained in:
@@ -1,3 +1,7 @@
|
||||
* set/get function on Fields take a list of ids
|
||||
* New interface for Function/Property fields
|
||||
Take a Field as first argument instead of many separate arguments
|
||||
Remove static arguments
|
||||
* Fix Float and Numeric for lost of precision
|
||||
* Add decimal digits validation on fields
|
||||
* Improve unittests to run trytond from tests
|
||||
|
||||
@@ -549,26 +549,6 @@ The framework is able to check, if ``names`` (instead of ``name``) is used in
|
||||
the method definition, hence adapting the way the method is called.
|
||||
|
||||
|
||||
Another way to tackle Function implementation is to pass a dictionary to the
|
||||
``args`` argument on the field definition. It will be forwarded to the function
|
||||
call:
|
||||
|
||||
.. highlight:: python
|
||||
|
||||
::
|
||||
|
||||
state = fields.Function(
|
||||
'get_state', type='selection', string='Total Service',
|
||||
args={'key':'value'},
|
||||
selection=[('draft','Draft'),('done','Done')],
|
||||
)
|
||||
|
||||
def get_state(self, cursor, user, ids, names, arg, context=None):
|
||||
# [...]
|
||||
if arg.get('key'):
|
||||
pass # do something with 'value'
|
||||
|
||||
|
||||
Search on Function fields
|
||||
+++++++++++++++++++++++++
|
||||
|
||||
|
||||
+19
-21
@@ -216,15 +216,14 @@ class ActionReport(ModelSQL, ModelView):
|
||||
report_name = fields.Char('Internal Name', required=True)
|
||||
report = fields.Char('Path')
|
||||
report_content_data = fields.Binary('Content')
|
||||
report_content = fields.Function('get_report_content',
|
||||
fnct_inv='report_content_inv', type='binary',
|
||||
string='Content')
|
||||
report_content = fields.Function(fields.Binary('Content'),
|
||||
'get_report_content', setter='set_report_content')
|
||||
action = fields.Many2One('ir.action', 'Action', required=True,
|
||||
ondelete='CASCADE')
|
||||
style = fields.Property(type='char', string='Style',
|
||||
help='Define the style to apply on the report.')
|
||||
style_content = fields.Function('get_style_content',
|
||||
type='binary', string='Style')
|
||||
style = fields.Property(fields.Char('Style',
|
||||
help='Define the style to apply on the report.'))
|
||||
style_content = fields.Function(fields.Binary('Style'),
|
||||
'get_style_content')
|
||||
direct_print = fields.Boolean('Direct Print')
|
||||
extension = fields.Selection(
|
||||
[('odt', 'ODT Document'),
|
||||
@@ -281,7 +280,7 @@ class ActionReport(ModelSQL, ModelView):
|
||||
def default_module(self, cursor, user, context=None):
|
||||
return context and context.get('module', '') or ''
|
||||
|
||||
def get_report_content(self, cursor, user, ids, name, arg, context=None):
|
||||
def get_report_content(self, cursor, user, ids, name, context=None):
|
||||
res = {}
|
||||
for report in self.browse(cursor, user, ids, context=context):
|
||||
data = report[name + '_data']
|
||||
@@ -295,11 +294,12 @@ class ActionReport(ModelSQL, ModelView):
|
||||
res[report.id] = data
|
||||
return res
|
||||
|
||||
def report_content_inv(self, cursor, user, obj_id, name, value, arg,
|
||||
def set_report_content(self, cursor, user, ids, name, value,
|
||||
context=None):
|
||||
self.write(cursor, user, obj_id, {name+'_data': value}, context=context)
|
||||
self.write(cursor, user, ids, {'%s_data' % name: value},
|
||||
context=context)
|
||||
|
||||
def get_style_content(self, cursor, user, ids, name, arg, context=None):
|
||||
def get_style_content(self, cursor, user, ids, name, context=None):
|
||||
res = {}
|
||||
for report in self.browse(cursor, user, ids, context=context):
|
||||
try:
|
||||
@@ -396,8 +396,7 @@ class ActionActWindow(ModelSQL, ModelView):
|
||||
], string='Type of view')
|
||||
act_window_views = fields.One2Many('ir.action.act_window.view',
|
||||
'act_window', 'Views')
|
||||
views = fields.Function('views_get_fnc', type='binary',
|
||||
string='Views')
|
||||
views = fields.Function(fields.Binary('Views'), 'get_views')
|
||||
limit = fields.Integer('Limit',
|
||||
help='Default limit for the list view')
|
||||
auto_refresh = fields.Integer('Auto-Refresh',
|
||||
@@ -408,12 +407,11 @@ class ActionActWindow(ModelSQL, ModelView):
|
||||
help='Use the action name as window name')
|
||||
search_value = fields.Char('Search Criteria',
|
||||
help='Default search criteria for the list view')
|
||||
pyson_domain = fields.Function('get_pyson', type='string',
|
||||
string='PySON Domain')
|
||||
pyson_context = fields.Function('get_pyson', type='string',
|
||||
string='PySON Context')
|
||||
pyson_search_value = fields.Function('get_pyson', type='string',
|
||||
string='PySON Search Criteria')
|
||||
pyson_domain = fields.Function(fields.Char('PySON Domain'), 'get_pyson')
|
||||
pyson_context = fields.Function(fields.Char('PySON Context'),
|
||||
'get_pyson')
|
||||
pyson_search_value = fields.Function(fields.Char(
|
||||
'PySON Search Criteria'), 'get_pyson')
|
||||
|
||||
def __init__(self):
|
||||
super(ActionActWindow, self).__init__()
|
||||
@@ -504,14 +502,14 @@ class ActionActWindow(ModelSQL, ModelView):
|
||||
return False
|
||||
return True
|
||||
|
||||
def views_get_fnc(self, cursor, user, ids, name, arg, context=None):
|
||||
def get_views(self, cursor, user, ids, name, context=None):
|
||||
res = {}
|
||||
for act in self.browse(cursor, user, ids, context=context):
|
||||
res[act.id] = [(view.view.id, view.view.type) \
|
||||
for view in act.act_window_views]
|
||||
return res
|
||||
|
||||
def get_pyson(self, cursor, user, ids, name, arg, context=None):
|
||||
def get_pyson(self, cursor, user, ids, name, context=None):
|
||||
res = {}
|
||||
encoder = PYSONEncoder()
|
||||
field = name[6:]
|
||||
|
||||
@@ -16,16 +16,15 @@ class Attachment(ModelSQL, ModelView):
|
||||
_name = 'ir.attachment'
|
||||
_description = __doc__
|
||||
name = fields.Char('Attachment Name', required=True)
|
||||
datas = fields.Function('get_datas', fnct_inv='set_datas',
|
||||
type='binary', string='Datas')
|
||||
datas = fields.Function(fields.Binary('Datas'), 'get_datas',
|
||||
setter='set_datas')
|
||||
description = fields.Text('Description')
|
||||
res_model = fields.Char('Resource Model', readonly=True)
|
||||
res_id = fields.Integer('Resource ID', readonly=True)
|
||||
link = fields.Char('Link')
|
||||
digest = fields.Char('Digest', size=32)
|
||||
collision = fields.Integer('Collision')
|
||||
datas_size = fields.Function('get_datas', type='integer',
|
||||
string='Datas size')
|
||||
datas_size = fields.Function(fields.Integer('Datas size'), 'get_datas')
|
||||
|
||||
def __init__(self):
|
||||
super(Attachment, self).__init__()
|
||||
@@ -38,7 +37,7 @@ class Attachment(ModelSQL, ModelView):
|
||||
def default_collision(self, cursor, user, context=None):
|
||||
return 0
|
||||
|
||||
def get_datas(self, cursor, user, ids, name, arg, context=None):
|
||||
def get_datas(self, cursor, user, ids, name, context=None):
|
||||
res = {}
|
||||
db_name = cursor.dbname
|
||||
for attachment in self.browse(cursor, user, ids, context=context):
|
||||
@@ -64,7 +63,7 @@ class Attachment(ModelSQL, ModelView):
|
||||
res[attachment.id] = value
|
||||
return res
|
||||
|
||||
def set_datas(self, cursor, user, obj_id, name, value, args, context=None):
|
||||
def set_datas(self, cursor, user, ids, name, value, context=None):
|
||||
if value is False or value is None:
|
||||
return
|
||||
db_name = cursor.dbname
|
||||
@@ -113,10 +112,10 @@ class Attachment(ModelSQL, ModelView):
|
||||
file_p = open(filename, 'wb')
|
||||
file_p.write(data)
|
||||
file_p.close()
|
||||
cursor.execute('UPDATE ir_attachment ' \
|
||||
'SET digest = %s, ' \
|
||||
'collision = %s ' \
|
||||
'WHERE id = %s', (digest, collision, obj_id))
|
||||
self.write(cursor, user, ids, {
|
||||
'digest': digest,
|
||||
'collision': collision,
|
||||
}, context=context)
|
||||
|
||||
def check_access(self, cursor, user, ids, mode='read', context=None):
|
||||
model_access_obj = self.pool.get('ir.model.access')
|
||||
|
||||
+11
-13
@@ -133,7 +133,7 @@ class Module(ModelSQL, ModelView):
|
||||
description = fields.Text("Description", readonly=True, translate=True)
|
||||
author = fields.Char("Author", readonly=True)
|
||||
website = fields.Char("Website", readonly=True)
|
||||
version = fields.Function('get_version', string='Version', type='char')
|
||||
version = fields.Function(fields.Char('Version'), 'get_version')
|
||||
dependencies = fields.One2Many('ir.module.module.dependency',
|
||||
'module', 'Dependencies', readonly=True)
|
||||
state = fields.Selection([
|
||||
@@ -186,8 +186,7 @@ class Module(ModelSQL, ModelView):
|
||||
return {}
|
||||
return info
|
||||
|
||||
def get_version(self, cursor, user, ids, name, arg,
|
||||
context=None):
|
||||
def get_version(self, cursor, user, ids, name, context=None):
|
||||
res = {}
|
||||
for module in self.browse(cursor, user, ids, context=context):
|
||||
res[module.id] = Module.get_module_info(
|
||||
@@ -465,15 +464,14 @@ class ModuleDependency(ModelSQL, ModelView):
|
||||
name = fields.Char('Name')
|
||||
module = fields.Many2One('ir.module.module', 'Module', select=1,
|
||||
ondelete='CASCADE', required=True)
|
||||
state = fields.Function('get_state', type='selection',
|
||||
selection=[
|
||||
('uninstalled','Not Installed'),
|
||||
('installed','Installed'),
|
||||
('to upgrade','To be upgraded'),
|
||||
('to remove','To be removed'),
|
||||
('to install','To be installed'),
|
||||
('unknown', 'Unknown'),
|
||||
], string='State', readonly=True)
|
||||
state = fields.Function(fields.Selection([
|
||||
('uninstalled','Not Installed'),
|
||||
('installed','Installed'),
|
||||
('to upgrade','To be upgraded'),
|
||||
('to remove','To be removed'),
|
||||
('to install','To be installed'),
|
||||
('unknown', 'Unknown'),
|
||||
], 'State', readonly=True), 'get_state')
|
||||
|
||||
def __init__(self):
|
||||
super(ModuleDependency, self).__init__()
|
||||
@@ -482,7 +480,7 @@ class ModuleDependency(ModelSQL, ModelView):
|
||||
'Dependency must be unique by module!'),
|
||||
]
|
||||
|
||||
def get_state(self, cursor, user, ids, name, args, context=None):
|
||||
def get_state(self, cursor, user, ids, name, context=None):
|
||||
result = {}
|
||||
module_obj = self.pool.get('ir.module.module')
|
||||
for dependency in self.browse(cursor, user, ids):
|
||||
|
||||
@@ -147,14 +147,14 @@ class Property(ModelSQL, ModelView):
|
||||
'field': field_id,
|
||||
}
|
||||
|
||||
def set(self, cursor, user, name, model, res_id, val, context=None):
|
||||
def set(self, cursor, user, name, model, ids, val, context=None):
|
||||
"""
|
||||
Set property value for res_id
|
||||
Set property value for ids
|
||||
:param cursor: the database cursor
|
||||
:param user: the user id
|
||||
:param names: property name
|
||||
:param model: object name
|
||||
:param res_id: a record ids
|
||||
:param ids: a list of ids
|
||||
:param val: the value
|
||||
:param context: the context
|
||||
:return: the id of the record created
|
||||
@@ -177,7 +177,7 @@ class Property(ModelSQL, ModelView):
|
||||
|
||||
property_ids = self.search(cursor, user, [
|
||||
('field', '=', field_id),
|
||||
('res', '=', model + ',' + str(res_id)),
|
||||
('res', 'in', [model + ',' + str(res_id) for res_id in ids]),
|
||||
], order=[], context=context)
|
||||
self.delete(cursor, 0, property_ids, context=ctx)
|
||||
|
||||
@@ -208,9 +208,10 @@ class Property(ModelSQL, ModelView):
|
||||
|
||||
res = False
|
||||
if (val != default_val):
|
||||
vals = self._set_values(cursor, user, name, model, res_id, val,
|
||||
field_id, context=context)
|
||||
res = self.create(cursor, 0, vals, context=ctx)
|
||||
for res_id in ids:
|
||||
vals = self._set_values(cursor, user, name, model, res_id, val,
|
||||
field_id, context=context)
|
||||
res = self.create(cursor, 0, vals, context=ctx)
|
||||
return res
|
||||
|
||||
Property()
|
||||
|
||||
@@ -53,8 +53,8 @@ class Translation(ModelSQL, ModelView, Cacheable):
|
||||
value = fields.Text('Translation Value')
|
||||
module = fields.Char('Module', readonly=True)
|
||||
fuzzy = fields.Boolean('Fuzzy')
|
||||
model = fields.Function('get_model', fnct_search='model_search',
|
||||
type='char', string='Model')
|
||||
model = fields.Function(fields.Char('Model'), 'get_model',
|
||||
searcher='search_model')
|
||||
|
||||
def __init__(self):
|
||||
super(Translation, self).__init__()
|
||||
@@ -75,13 +75,13 @@ class Translation(ModelSQL, ModelView, Cacheable):
|
||||
def default_fuzzy(self, cursor, user, context=None):
|
||||
return False
|
||||
|
||||
def get_model(self, cursor, user, ids, name, arg, context=None):
|
||||
def get_model(self, cursor, user, ids, name, context=None):
|
||||
res = {}
|
||||
for translation in self.browse(cursor, user, ids, context=context):
|
||||
res[translation.id] = translation.name.split(',')[0]
|
||||
return res
|
||||
|
||||
def model_search(self, cursor, user, name, args, context=None):
|
||||
def search_model(self, cursor, user, name, args, context=None):
|
||||
args2 = []
|
||||
i = 0
|
||||
while i < len(args):
|
||||
|
||||
+26
-23
@@ -82,17 +82,16 @@ class UIMenu(ModelSQL, ModelView):
|
||||
parent = fields.Many2One('ir.ui.menu', 'Parent Menu', select=1)
|
||||
groups = fields.Many2Many('ir.ui.menu-res.group',
|
||||
'menu_id', 'gid', 'Groups')
|
||||
complete_name = fields.Function('get_full_name',
|
||||
string='Complete Name', type='char', order_field='name')
|
||||
complete_name = fields.Function(fields.Char('Complete Name',
|
||||
order_field='name'), 'get_full_name')
|
||||
icon = fields.Selection(ICONS, 'Icon', translate=False)
|
||||
action = fields.Function('get_action', fnct_inv='action_inv',
|
||||
type='reference', string='Action',
|
||||
selection=[
|
||||
('ir.action.report', 'ir.action.report'),
|
||||
('ir.action.act_window', 'ir.action.act_window'),
|
||||
('ir.action.wizard', 'ir.action.wizard'),
|
||||
('ir.action.url', 'ir.action.url'),
|
||||
])
|
||||
action = fields.Function(fields.Reference('Action',
|
||||
selection=[
|
||||
('ir.action.report', 'ir.action.report'),
|
||||
('ir.action.act_window', 'ir.action.act_window'),
|
||||
('ir.action.wizard', 'ir.action.wizard'),
|
||||
('ir.action.url', 'ir.action.url'),
|
||||
]), 'get_action', setter='set_action')
|
||||
active = fields.Boolean('Active')
|
||||
|
||||
def __init__(self):
|
||||
@@ -108,7 +107,7 @@ class UIMenu(ModelSQL, ModelView):
|
||||
def default_active(self, cursor, user, context=None):
|
||||
return True
|
||||
|
||||
def get_full_name(self, cursor, user, ids, name, args, context):
|
||||
def get_full_name(self, cursor, user, ids, name, context):
|
||||
res = {}
|
||||
for menu in self.browse(cursor, user, ids, context=context):
|
||||
res[menu.id] = self._get_one_full_name(menu)
|
||||
@@ -146,7 +145,7 @@ class UIMenu(ModelSQL, ModelView):
|
||||
res = check_menu(res)
|
||||
return res
|
||||
|
||||
def get_action(self, cursor, user, ids, name, arg, context=None):
|
||||
def get_action(self, cursor, user, ids, name, context=None):
|
||||
action_keyword_obj = self.pool.get('ir.action.keyword')
|
||||
|
||||
if context is None:
|
||||
@@ -176,8 +175,7 @@ class UIMenu(ModelSQL, ModelView):
|
||||
res[model_id] = action_keyword.action.type + ',' + str(action_id)
|
||||
return res
|
||||
|
||||
def action_inv(self, cursor, user, menu_id, name, value, arg,
|
||||
context=None):
|
||||
def set_action(self, cursor, user, ids, name, value, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
if not value:
|
||||
@@ -186,10 +184,14 @@ class UIMenu(ModelSQL, ModelView):
|
||||
if '_timestamp' in ctx:
|
||||
del ctx['_timestamp']
|
||||
action_keyword_obj = self.pool.get('ir.action.keyword')
|
||||
action_keyword_ids = action_keyword_obj.search(cursor, user, [
|
||||
('keyword', '=', 'tree_open'),
|
||||
('model', '=', self._name + ',' + str(menu_id)),
|
||||
], context=context)
|
||||
action_keyword_ids = []
|
||||
for i in range(0, len(ids), cursor.IN_MAX):
|
||||
sub_ids = ids[i:i + cursor.IN_MAX]
|
||||
action_keyword_ids += action_keyword_obj.search(cursor, user, [
|
||||
('keyword', '=', 'tree_open'),
|
||||
('model', 'in', [self._name + ',' + str(menu_id)
|
||||
for menu_id in sub_ids]),
|
||||
], context=context)
|
||||
if action_keyword_ids:
|
||||
action_keyword_obj.delete(cursor, user, action_keyword_ids,
|
||||
context=ctx)
|
||||
@@ -199,10 +201,11 @@ class UIMenu(ModelSQL, ModelView):
|
||||
action_obj = self.pool.get(action_type)
|
||||
action = action_obj.browse(cursor, user, int(action_id),
|
||||
context=context)
|
||||
action_keyword_obj.create(cursor, user, {
|
||||
'keyword': 'tree_open',
|
||||
'model': self._name + ',' + str(menu_id),
|
||||
'action': action.action.id,
|
||||
}, context=ctx)
|
||||
for menu_id in ids:
|
||||
action_keyword_obj.create(cursor, user, {
|
||||
'keyword': 'tree_open',
|
||||
'model': self._name + ',' + str(menu_id),
|
||||
'action': action.action.id,
|
||||
}, context=ctx)
|
||||
|
||||
UIMenu()
|
||||
|
||||
@@ -1,93 +1,55 @@
|
||||
#This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
#this repository contains the full copyright notices and license terms.
|
||||
|
||||
import inspect
|
||||
import copy
|
||||
from trytond.model.fields.field import Field
|
||||
from trytond.model.fields.float import digits_validate
|
||||
from trytond.model.fields.one2many import add_remove_validate
|
||||
from trytond.pyson import PYSON
|
||||
import inspect
|
||||
|
||||
|
||||
class Function(Field):
|
||||
'''
|
||||
Define function field (any).
|
||||
'''
|
||||
_type = 'float'
|
||||
|
||||
def __init__(self, fnct, arg=None, fnct_inv='', fnct_inv_arg=None,
|
||||
type='float', fnct_search='', model_name=None, selection=None,
|
||||
digits=None, relation=None, add_remove=None, datetime_field=None,
|
||||
string='', help='', required=False, readonly=False, domain=None,
|
||||
states=None, priority=0, change_default=False, translate=False,
|
||||
select=0, on_change=None, on_change_with=None, depends=None,
|
||||
order_field=None, context=None):
|
||||
def __init__(self, field, getter, setter=None, searcher=None):
|
||||
'''
|
||||
:param fnct: The name of the function.
|
||||
:param arg: Argument for the function.
|
||||
:param fnct_inv: The name of the function to write.
|
||||
:param fnct_inv_arg: Argument for the function to write.
|
||||
:param type: The type of field.
|
||||
:param fnct_search: The name of the function to search.
|
||||
:param model_name: See Many2One.
|
||||
:param selection: See Selection.
|
||||
:param digits: See Float.
|
||||
:param relation: Like model_name.
|
||||
:param add_remove: See Many2One.
|
||||
:param datetime_field: The name of the field that contains the datetime
|
||||
value to read the target records.
|
||||
: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.
|
||||
'''
|
||||
if datetime_field:
|
||||
if depends:
|
||||
depends.append(datetime_field)
|
||||
else:
|
||||
depends = [datetime_field]
|
||||
super(Function, self).__init__(string=string, help=help,
|
||||
required=required, readonly=readonly, domain=domain,
|
||||
states=states, priority=priority, change_default=change_default,
|
||||
translate=translate, select=select, on_change=on_change,
|
||||
on_change_with=on_change_with, depends=depends,
|
||||
order_field=order_field, context=context)
|
||||
self.model_name = model_name
|
||||
self.fnct = fnct
|
||||
self.arg = arg
|
||||
self.fnct_inv = fnct_inv
|
||||
self.fnct_inv_arg = fnct_inv_arg
|
||||
if not self.fnct_inv:
|
||||
self.readonly = True
|
||||
self._type = type
|
||||
self.fnct_search = fnct_search
|
||||
self.selection = selection
|
||||
self.__digits = None
|
||||
self.digits = digits
|
||||
if relation:
|
||||
self.model_name = relation
|
||||
self.__add_remove = None
|
||||
self.add_remove = add_remove
|
||||
self.datetime_field = datetime_field
|
||||
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
|
||||
|
||||
__init__.__doc__ += Field.__init__.__doc__
|
||||
|
||||
def _get_digits(self):
|
||||
return self.__digits
|
||||
def __copy__(self):
|
||||
return Function(copy.copy(self._field), self.getter,
|
||||
setter=self.setter, searcher=self.searcher)
|
||||
|
||||
def _set_digits(self, value):
|
||||
digits_validate(value)
|
||||
self.__digits = value
|
||||
def __getattr__(self, name):
|
||||
return getattr(self._field, name)
|
||||
|
||||
digits = property(_get_digits, _set_digits)
|
||||
def __getitem__(self, name):
|
||||
return self._field[name]
|
||||
|
||||
def _get_add_remove(self):
|
||||
return self.__add_remove
|
||||
|
||||
def _set_add_remove(self, value):
|
||||
add_remove_validate(value)
|
||||
self.__add_remove = value
|
||||
|
||||
add_remove = property(_get_add_remove, _set_add_remove)
|
||||
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)
|
||||
|
||||
def search(self, cursor, user, model, name, args, context=None):
|
||||
'''
|
||||
Call the fnct_search.
|
||||
Call the searcher.
|
||||
|
||||
:param cursor: The database cursor.
|
||||
:param user: The user id.
|
||||
@@ -97,15 +59,15 @@ class Function(Field):
|
||||
:param context: The context.
|
||||
:return: New list of domain.
|
||||
'''
|
||||
if not self.fnct_search:
|
||||
if not self.searcher:
|
||||
model.raise_user_error(cursor, 'search_function_missing',
|
||||
name, context=context)
|
||||
return getattr(model, self.fnct_search)(cursor, user, name, args,
|
||||
return getattr(model, self.searcher)(cursor, user, name, args,
|
||||
context=context)
|
||||
|
||||
def get(self, cursor, user, ids, model, name, values=None, context=None):
|
||||
'''
|
||||
Call the fnct.
|
||||
Call the getter.
|
||||
If the function has ``names`` in the function definition then
|
||||
it will call it with a list of name.
|
||||
|
||||
@@ -123,34 +85,34 @@ class Function(Field):
|
||||
if isinstance(name, list):
|
||||
names = name
|
||||
# Test is the function works with a list of names
|
||||
if 'names' in inspect.getargspec(getattr(model, self.fnct))[0]:
|
||||
return getattr(model, self.fnct)(cursor, user, ids, names,
|
||||
self.arg, context=context)
|
||||
if 'names' in inspect.getargspec(getattr(model, self.getter))[0]:
|
||||
return getattr(model, self.getter)(cursor, user, ids, names,
|
||||
context=context)
|
||||
res = {}
|
||||
for name in names:
|
||||
res[name] = getattr(model, self.fnct)(cursor, user, ids, name,
|
||||
self.arg, context=context)
|
||||
res[name] = getattr(model, self.getter)(cursor, user, ids,
|
||||
name, context=context)
|
||||
return res
|
||||
else:
|
||||
# Test is the function works with a list of names
|
||||
if 'names' in inspect.getargspec(getattr(model, self.fnct))[0]:
|
||||
if 'names' in inspect.getargspec(getattr(model, self.getter))[0]:
|
||||
name = [name]
|
||||
return getattr(model, self.fnct)(cursor, user, ids, name, self.arg,
|
||||
return getattr(model, self.getter)(cursor, user, ids, name,
|
||||
context=context)
|
||||
|
||||
|
||||
def set(self, cursor, user, record_id, model, name, value, context=None):
|
||||
def set(self, cursor, user, ids, model, name, value, context=None):
|
||||
'''
|
||||
Call the fnct_inv.
|
||||
Call the setter.
|
||||
|
||||
:param cursor: The database cursor.
|
||||
:param user: The user id.
|
||||
:param record_id: The record id.
|
||||
:param ids: A list of ids.
|
||||
:param model: The model.
|
||||
:param name: The name of the field.
|
||||
:param value: The value to set.
|
||||
:param context: The context.
|
||||
'''
|
||||
if self.fnct_inv:
|
||||
getattr(model, self.fnct_inv)(cursor, user, record_id, name, value,
|
||||
self.fnct_inv_arg, context=context)
|
||||
if self.setter:
|
||||
getattr(model, self.setter)(cursor, user, ids, name, value,
|
||||
context=context)
|
||||
|
||||
@@ -82,13 +82,13 @@ class Many2Many(Field):
|
||||
res[relation[self.origin]].append(relation[self.target])
|
||||
return res
|
||||
|
||||
def set(self, cursor, user, record_id, model, name, values, context=None):
|
||||
def set(self, cursor, user, ids, model, name, values, context=None):
|
||||
'''
|
||||
Set the values.
|
||||
|
||||
:param cursor: The database cursor
|
||||
:param user: The user id
|
||||
:param record_id: The record id
|
||||
:param ids: A list of ids
|
||||
:param model: A string with the name of the model
|
||||
:param name: A string with the name of the field
|
||||
:param values: A list of tuples:
|
||||
@@ -107,75 +107,77 @@ class Many2Many(Field):
|
||||
target_obj = self.get_target(model.pool)
|
||||
for act in values:
|
||||
if act[0] == 'create':
|
||||
relation_obj.create(cursor, user, {
|
||||
self.origin: record_id,
|
||||
self.target: target_obj.create(cursor, user, act[1],
|
||||
context=context),
|
||||
}, context=context)
|
||||
for record_id in ids:
|
||||
relation_obj.create(cursor, user, {
|
||||
self.origin: record_id,
|
||||
self.target: target_obj.create(cursor, user, act[1],
|
||||
context=context),
|
||||
}, context=context)
|
||||
elif act[0] == 'write':
|
||||
target_obj.write(cursor, user, act[1] , act[2], context=context)
|
||||
elif act[0] == 'delete':
|
||||
target_obj.delete(cursor, user, act[1], context=context)
|
||||
elif act[0] == 'unlink':
|
||||
if isinstance(act[1], (int, long)):
|
||||
ids = [act[1]]
|
||||
target_ids = [act[1]]
|
||||
else:
|
||||
ids = list(act[1])
|
||||
if not ids:
|
||||
target_ids = list(act[1])
|
||||
if not target_ids:
|
||||
continue
|
||||
relation_ids = []
|
||||
for i in range(0, len(ids), cursor.IN_MAX):
|
||||
sub_ids = ids[i:i + cursor.IN_MAX]
|
||||
for i in range(0, len(target_ids), cursor.IN_MAX):
|
||||
sub_ids = target_ids[i:i + cursor.IN_MAX]
|
||||
relation_ids += relation_obj.search(cursor, user, [
|
||||
(self.origin, '=', record_id),
|
||||
(self.origin, 'in', ids),
|
||||
(self.target, 'in', sub_ids),
|
||||
], context=context)
|
||||
relation_obj.delete(cursor, user, relation_ids, context=context)
|
||||
elif act[0] == 'add':
|
||||
if isinstance(act[1], (int, long)):
|
||||
ids = [act[1]]
|
||||
target_ids = [act[1]]
|
||||
else:
|
||||
ids = list(act[1])
|
||||
if not ids:
|
||||
target_ids = list(act[1])
|
||||
if not target_ids:
|
||||
continue
|
||||
existing_ids = []
|
||||
for i in range(0, len(ids), cursor.IN_MAX):
|
||||
sub_ids = ids[i:i + cursor.IN_MAX]
|
||||
for i in range(0, len(target_ids), cursor.IN_MAX):
|
||||
sub_ids = target_ids[i:i + cursor.IN_MAX]
|
||||
relation_ids = relation_obj.search(cursor, user, [
|
||||
(self.origin, '=', record_id),
|
||||
(self.origin, 'in', ids),
|
||||
(self.target, 'in', sub_ids),
|
||||
], context=context)
|
||||
for relation in relation_obj.browse(cursor, user,
|
||||
relation_ids, context=context):
|
||||
existing_ids.append(relation[self.target].id)
|
||||
new_ids = [x for x in ids if x not in existing_ids]
|
||||
for new_id in new_ids:
|
||||
relation_obj.create(cursor, user, {
|
||||
self.origin: record_id,
|
||||
self.target: new_id,
|
||||
}, context=context)
|
||||
for new_id in (x for x in target_ids if x not in existing_ids):
|
||||
for record_id in ids:
|
||||
relation_obj.create(cursor, user, {
|
||||
self.origin: record_id,
|
||||
self.target: new_id,
|
||||
}, context=context)
|
||||
elif act[0] == 'unlink_all':
|
||||
ids = relation_obj.search(cursor, user, [
|
||||
(self.origin, '=', record_id),
|
||||
target_ids = relation_obj.search(cursor, user, [
|
||||
(self.origin, 'in', ids),
|
||||
(self.target + '.id', '!=', False),
|
||||
], context=context)
|
||||
relation_obj.delete(cursor, user, ids, context=context)
|
||||
relation_obj.delete(cursor, user, target_ids, context=context)
|
||||
elif act[0] == 'set':
|
||||
if not act[1]:
|
||||
ids = []
|
||||
target_ids = []
|
||||
else:
|
||||
ids = list(act[1])
|
||||
ids2 = relation_obj.search(cursor, user, [
|
||||
(self.origin, '=', record_id),
|
||||
target_ids = list(act[1])
|
||||
target_ids2 = relation_obj.search(cursor, user, [
|
||||
(self.origin, 'in', ids),
|
||||
(self.target + '.id', '!=', False),
|
||||
], context=context)
|
||||
relation_obj.delete(cursor, user, ids2, context=context)
|
||||
relation_obj.delete(cursor, user, target_ids2, context=context)
|
||||
|
||||
for new_id in ids:
|
||||
relation_obj.create(cursor, user, {
|
||||
self.origin: record_id,
|
||||
self.target: new_id,
|
||||
}, context=context)
|
||||
for new_id in target_ids:
|
||||
for record_id in ids:
|
||||
relation_obj.create(cursor, user, {
|
||||
self.origin: record_id,
|
||||
self.target: new_id,
|
||||
}, context=context)
|
||||
else:
|
||||
raise Exception('Bad arguments')
|
||||
|
||||
|
||||
@@ -106,13 +106,13 @@ class One2Many(Field):
|
||||
val.sort(lambda x, y: cmp(index_of_ids2[x], index_of_ids2[y]))
|
||||
return res
|
||||
|
||||
def set(self, cursor, user, record_id, model, name, values, context=None):
|
||||
def set(self, cursor, user, ids, model, name, values, context=None):
|
||||
'''
|
||||
Set the values.
|
||||
|
||||
:param cursor: The database cursor
|
||||
:param user: The user id
|
||||
:param record_id: The record id
|
||||
:param ids: A list of ids
|
||||
:param model: A string with the name of the model
|
||||
:param name: A string with the name of the field
|
||||
:param values: A list of tuples:
|
||||
@@ -131,64 +131,66 @@ class One2Many(Field):
|
||||
model = model.pool.get(self.model_name)
|
||||
for act in values:
|
||||
if act[0] == 'create':
|
||||
act[1][self.field] = record_id
|
||||
model.create(cursor, user, act[1], context=context)
|
||||
for record_id in ids:
|
||||
act[1][self.field] = record_id
|
||||
model.create(cursor, user, act[1], context=context)
|
||||
elif act[0] == 'write':
|
||||
act[2][self.field] = record_id
|
||||
model.write(cursor, user, act[1] , act[2], context=context)
|
||||
elif act[0] == 'delete':
|
||||
model.delete(cursor, user, act[1], context=context)
|
||||
elif act[0] == 'delete_all':
|
||||
ids = model.search(cursor, user, [
|
||||
(self.field, '=', record_id),
|
||||
target_ids = model.search(cursor, user, [
|
||||
(self.field, 'in', ids),
|
||||
], context=context)
|
||||
model.delete(cursor, user, ids, context=context)
|
||||
model.delete(cursor, user, target_ids, context=context)
|
||||
elif act[0] == 'unlink':
|
||||
if isinstance(act[1], (int, long)):
|
||||
ids = [act[1]]
|
||||
target_ids = [act[1]]
|
||||
else:
|
||||
ids = list(act[1])
|
||||
if not ids:
|
||||
target_ids = list(act[1])
|
||||
if not target_ids:
|
||||
continue
|
||||
ids = model.search(cursor, user, [
|
||||
(self.field, '=', record_id),
|
||||
('id', 'in', ids),
|
||||
target_ids = model.search(cursor, user, [
|
||||
(self.field, 'in', ids),
|
||||
('id', 'in', target_ids),
|
||||
], context=context)
|
||||
model.write(cursor, user, ids, {
|
||||
model.write(cursor, user, target_ids, {
|
||||
self.field: False,
|
||||
}, context=context)
|
||||
elif act[0] == 'add':
|
||||
if isinstance(act[1], (int, long)):
|
||||
ids = [act[1]]
|
||||
target_ids = [act[1]]
|
||||
else:
|
||||
ids = list(act[1])
|
||||
if not ids:
|
||||
target_ids = list(act[1])
|
||||
if not target_ids:
|
||||
continue
|
||||
ids = model.write(cursor, user, ids, {
|
||||
self.field: record_id,
|
||||
}, context=context)
|
||||
for record_id in ids:
|
||||
model.write(cursor, user, target_ids, {
|
||||
self.field: record_id,
|
||||
}, context=context)
|
||||
elif act[0] == 'unlink_all':
|
||||
ids = model.search(cursor, user, [
|
||||
(self.field, '=', record_id),
|
||||
target_ids = model.search(cursor, user, [
|
||||
(self.field, 'in', ids),
|
||||
], context=context)
|
||||
model.write(cursor, user, ids, {
|
||||
model.write(cursor, user, target_ids, {
|
||||
self.field: False,
|
||||
}, context=context)
|
||||
elif act[0] == 'set':
|
||||
if not act[1]:
|
||||
ids = [0]
|
||||
target_ids = [0]
|
||||
else:
|
||||
ids = list(act[1])
|
||||
ids2 = model.search(cursor, user, [
|
||||
(self.field, '=', record_id),
|
||||
('id', 'not in', ids),
|
||||
], context=context)
|
||||
model.write(cursor, user, ids2, {
|
||||
self.field: False,
|
||||
}, context=context)
|
||||
if act[1]:
|
||||
model.write(cursor, user, ids, {
|
||||
self.field: record_id,
|
||||
target_ids = list(act[1])
|
||||
for record_id in ids:
|
||||
target_ids2 = model.search(cursor, user, [
|
||||
(self.field, '=', record_id),
|
||||
('id', 'not in', target_ids),
|
||||
], context=context)
|
||||
model.write(cursor, user, target_ids2, {
|
||||
self.field: False,
|
||||
}, context=context)
|
||||
if act[1]:
|
||||
model.write(cursor, user, target_ids, {
|
||||
self.field: record_id,
|
||||
}, context=context)
|
||||
else:
|
||||
raise Exception('Bad arguments')
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
#this repository contains the full copyright notices and license terms.
|
||||
|
||||
import copy
|
||||
from trytond.model.fields.function import Function
|
||||
from trytond.model.fields.field import Field
|
||||
from trytond import backend
|
||||
@@ -11,32 +12,17 @@ class Property(Function):
|
||||
Define a property field that is stored in ir.property (any).
|
||||
'''
|
||||
|
||||
def __init__(self, type='float', model_name=None, selection=None,
|
||||
digits=None, relation=None, add_remove=None, string='', help='',
|
||||
required=False, readonly=False, domain=None, states=None,
|
||||
priority=0, change_default=False, translate=False, select=0,
|
||||
on_change=None, on_change_with=None, depends=None,
|
||||
order_field=None, context=None):
|
||||
def __init__(self, field):
|
||||
'''
|
||||
:param type: The type of the field.
|
||||
:param fnct_search: The name of the search function.
|
||||
:param model_name: See Many2One.
|
||||
:param selection: See Selection.
|
||||
:param digits: See Float.
|
||||
:param relation: Like model_name.
|
||||
:param add_remove: See Many2One.
|
||||
:param field: The field of the function.
|
||||
'''
|
||||
super(Property, self).__init__('', type=type, model_name=model_name,
|
||||
selection=selection, digits=digits, relation=relation,
|
||||
add_remove=add_remove, string=string, help=help,
|
||||
required=required, readonly=readonly, domain=domain,
|
||||
states=states, priority=priority, change_default=change_default,
|
||||
translate=translate, select=select, on_change=on_change,
|
||||
on_change_with=on_change_with, depends=depends,
|
||||
order_field=order_field, context=context)
|
||||
self.readonly = False
|
||||
super(Property, self).__init__(field, True, True, True)
|
||||
|
||||
__init__.__doc__ += Field.__init__.__doc__
|
||||
|
||||
def __copy__(self):
|
||||
return Property(copy.copy(self._field))
|
||||
|
||||
def get(self, cursor, user, ids, model, name, values=None, context=None):
|
||||
'''
|
||||
Retreive the property.
|
||||
@@ -56,21 +42,21 @@ class Property(Function):
|
||||
return res
|
||||
|
||||
|
||||
def set(self, cursor, user, record_id, model, name, value, context=None):
|
||||
def set(self, cursor, user, ids, model, name, value, context=None):
|
||||
'''
|
||||
Set the property.
|
||||
|
||||
:param cursor: The database cursor.
|
||||
:param user: The user id.
|
||||
:param record_id: The record id.
|
||||
:param ids: A list of ids.
|
||||
:param model: The model.
|
||||
:param name: The name of the field.
|
||||
:param value: The value to set.
|
||||
:param context: The context.
|
||||
'''
|
||||
property_obj = model.pool.get('ir.property')
|
||||
return property_obj.set(cursor, user, name, model._name, record_id,
|
||||
(value and (self.model_name or '') + ',' + str(value)) or
|
||||
return property_obj.set(cursor, user, name, model._name, ids,
|
||||
(value and getattr(self, 'model_name', '') + ',' + str(value)) or
|
||||
False, context=context)
|
||||
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ class Reference(Field):
|
||||
on_change_with=on_change_with, depends=depends,
|
||||
order_field=order_field, context=context)
|
||||
self.selection = selection or None
|
||||
|
||||
__init__.__doc__ += Field.__init__.__doc__
|
||||
|
||||
def get(self, cursor, user, ids, model, name, values=None, context=None):
|
||||
|
||||
+11
-12
@@ -407,7 +407,7 @@ class ModelSQL(ModelStorage):
|
||||
upd_todo.sort(lambda x, y: self._columns[x].priority - \
|
||||
self._columns[y].priority)
|
||||
for field in upd_todo:
|
||||
self._columns[field].set(cursor, user, id_new, self, field,
|
||||
self._columns[field].set(cursor, user, [id_new], self, field,
|
||||
values[field], context=context)
|
||||
|
||||
if self._history:
|
||||
@@ -601,8 +601,8 @@ class ModelSQL(ModelStorage):
|
||||
func_fields = {}
|
||||
for field in fields_post:
|
||||
if isinstance(self._columns[field], fields.Function):
|
||||
key = (self._columns[field].fnct, self._columns[field].arg,
|
||||
self._columns[field].datetime_field)
|
||||
key = (self._columns[field].getter,
|
||||
getattr(self._columns[field], 'datetime_field', None))
|
||||
func_fields.setdefault(key, [])
|
||||
func_fields[key].append(field)
|
||||
continue
|
||||
@@ -622,10 +622,10 @@ class ModelSQL(ModelStorage):
|
||||
values=res, context=context)
|
||||
for record in res:
|
||||
record[field] = res2[record['id']]
|
||||
for i in func_fields:
|
||||
field_list = func_fields[i]
|
||||
for key in func_fields:
|
||||
field_list = func_fields[key]
|
||||
field = field_list[0]
|
||||
datetime_field = i[2]
|
||||
_, datetime_field = key
|
||||
if datetime_field:
|
||||
ctx = context.copy()
|
||||
for record in res:
|
||||
@@ -636,8 +636,8 @@ class ModelSQL(ModelStorage):
|
||||
for field in res2:
|
||||
record[field] = res2[field][record['id']]
|
||||
continue
|
||||
res2 = self._columns[field].get(cursor, user, ids, self, field_list,
|
||||
values=res, context=context)
|
||||
res2 = self._columns[field].get(cursor, user, ids, self,
|
||||
field_list, values=res, context=context)
|
||||
for field in res2:
|
||||
for record in res:
|
||||
record[field] = res2[field][record['id']]
|
||||
@@ -923,13 +923,12 @@ class ModelSQL(ModelStorage):
|
||||
context.get('language') or 'en_US', ids,
|
||||
values[field])
|
||||
|
||||
# call the 'set' method of fields which are not classic_write
|
||||
# call the 'set' method of fields
|
||||
upd_todo.sort(lambda x, y: self._columns[x].priority - \
|
||||
self._columns[y].priority)
|
||||
for field in upd_todo:
|
||||
for select_id in ids:
|
||||
self._columns[field].set(cursor, user, select_id, self, field,
|
||||
values[field], context=context)
|
||||
self._columns[field].set(cursor, user, ids, self, field,
|
||||
values[field], context=context)
|
||||
|
||||
if self._history:
|
||||
columns = ['"' + str(x) + '"' for x in self._columns
|
||||
|
||||
@@ -43,8 +43,8 @@ class ModelStorage(Model):
|
||||
create_date = fields.DateTime('Create Date', readonly=True)
|
||||
write_uid = fields.Many2One('res.user', 'Write User', readonly=True)
|
||||
write_date = fields.DateTime('Write Date', readonly=True)
|
||||
rec_name = fields.Function('get_rec_name', type='char', string='Name',
|
||||
fnct_search='search_rec_name')
|
||||
rec_name = fields.Function(fields.Char('Name'), 'get_rec_name',
|
||||
searcher='search_rec_name')
|
||||
|
||||
def __init__(self):
|
||||
super(ModelStorage, self).__init__()
|
||||
@@ -437,7 +437,7 @@ class ModelStorage(Model):
|
||||
return domain
|
||||
return process(domain)
|
||||
|
||||
def get_rec_name(self, cursor, user, ids, name, arg, context=None):
|
||||
def get_rec_name(self, cursor, user, ids, name, context=None):
|
||||
'''
|
||||
Return a dictionary with id as key and rec_name as value.
|
||||
It is used by the Function field rec_name.
|
||||
@@ -446,7 +446,6 @@ class ModelStorage(Model):
|
||||
:param user: the user id
|
||||
:param ids: a list of ids
|
||||
:param name: the name of the Function field
|
||||
:param arg: the argument of the Function field
|
||||
:param context: the context
|
||||
:return: a dictionary
|
||||
'''
|
||||
|
||||
+3
-4
@@ -158,11 +158,10 @@ SequenceTypeGroup()
|
||||
|
||||
class Sequence(ModelSQL, ModelView):
|
||||
_name = 'ir.sequence'
|
||||
groups = fields.Function('get_groups', type='many2many',
|
||||
relation='res.group', string='User Groups',
|
||||
fnct_search='search_groups')
|
||||
groups = fields.Function(fields.Many2Many('res.group', None, None,
|
||||
'User Groups'), 'get_groups', searcher='search_groups')
|
||||
|
||||
def get_groups(self, cursor, user, ids, name, arg, context=None):
|
||||
def get_groups(self, cursor, user, ids, name, context=None):
|
||||
sequence_type_obj = self.pool.get('ir.sequence.type')
|
||||
sequences= self.browse(cursor, user, ids, context=context)
|
||||
code2seq = {}
|
||||
|
||||
@@ -56,8 +56,8 @@ class Request(ModelSQL, ModelView):
|
||||
True,
|
||||
Not(Equal(Eval('act_from', 0), Eval('_user', 0)))),
|
||||
})
|
||||
number_references = fields.Function('get_number_references', type='integer',
|
||||
string="Number of References", on_change_with=['references'])
|
||||
number_references = fields.Function(fields.Integer('Number of References',
|
||||
on_change_with=['references']), 'get_number_references')
|
||||
state = fields.Selection(_STATES, 'State', required=True, readonly=True)
|
||||
history = fields.One2Many('res.request.history', 'request',
|
||||
'History', readonly=True)
|
||||
@@ -92,8 +92,7 @@ class Request(ModelSQL, ModelView):
|
||||
return len(vals['references'])
|
||||
return 0
|
||||
|
||||
def get_number_references(self, cursor, user, ids, name, arg,
|
||||
context=None):
|
||||
def get_number_references(self, cursor, user, ids, name, context=None):
|
||||
res = {}
|
||||
for request in self.browse(cursor, user, ids, context=context):
|
||||
if request.references:
|
||||
|
||||
+8
-9
@@ -37,15 +37,14 @@ class User(ModelSQL, ModelView):
|
||||
domain=[('global_p', '!=', True), ('default_p', '!=', True)])
|
||||
language = fields.Many2One('ir.lang', 'Language',
|
||||
domain=['OR', ('translatable', '=', True), ('code', '=', 'en_US')])
|
||||
language_direction = fields.Function('get_language_direction', type='char',
|
||||
string='Language Direction')
|
||||
language_direction = fields.Function(fields.Char('Language Direction'),
|
||||
'get_language_direction')
|
||||
timezone = fields.Selection('timezones', 'Timezone')
|
||||
email = fields.Char('Email')
|
||||
status_bar = fields.Function('get_status_bar', type='char',
|
||||
string="Status Bar")
|
||||
status_bar = fields.Function(fields.Char('Status Bar'), 'get_status_bar')
|
||||
warnings = fields.One2Many('res.user.warning', 'user', 'Warnings')
|
||||
connections = fields.Function('get_connections', type='integer',
|
||||
string='Connections')
|
||||
connections = fields.Function(fields.Integer('Connections'),
|
||||
'get_connections')
|
||||
|
||||
def __init__(self):
|
||||
super(User, self).__init__()
|
||||
@@ -100,7 +99,7 @@ class User(ModelSQL, ModelView):
|
||||
def default_action(self, cursor, user, context=None):
|
||||
return self.default_menu(cursor, user, context=context)
|
||||
|
||||
def get_language_direction(self, cursor, user, ids, name, arg, context=None):
|
||||
def get_language_direction(self, cursor, user, ids, name, context=None):
|
||||
res = {}
|
||||
lang_obj = self.pool.get('ir.lang')
|
||||
default_direction = lang_obj.default_direction(cursor, user, context=context)
|
||||
@@ -111,13 +110,13 @@ class User(ModelSQL, ModelView):
|
||||
res[user.id] = default_direction
|
||||
return res
|
||||
|
||||
def get_status_bar(self, cursor, user_id, ids, name, arg, context=None):
|
||||
def get_status_bar(self, cursor, user_id, ids, name, context=None):
|
||||
res = {}
|
||||
for user in self.browse(cursor, user_id, ids, context=context):
|
||||
res[user.id] = user.name
|
||||
return res
|
||||
|
||||
def get_connections(self, cursor, user, ids, name, arg, context=None):
|
||||
def get_connections(self, cursor, user, ids, name, context=None):
|
||||
res = {}
|
||||
for user_id in ids:
|
||||
res[user_id] = get_connections(cursor.database_name, user_id)
|
||||
|
||||
Reference in New Issue
Block a user