Files
tryton/trytond/rpc.py
T
Cédric Krier fe674cef55 Enforce unique list of records on method calls
An option is added on RPC definition to enforce uniqueness of records
instantiated. The key methods ModeView.button and Workflow.transition have an
assert to detect error in development code.

issue6184
review36411002
2017-07-16 23:49:15 +02:00

67 lines
2.5 KiB
Python

# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from trytond.transaction import Transaction
__all__ = ['RPC']
class RPC(object):
'''Define RPC behavior
readonly: The transaction mode
instantiate: The position or the slice of the arguments to be instanciated
result: The function to transform the result
check_access: If access right must be checked
unique: Check instances are unique
'''
__slots__ = ('readonly', 'instantiate', 'result', 'check_access', 'unique')
def __init__(self, readonly=True, instantiate=None, result=None,
check_access=True, unique=True):
self.readonly = readonly
self.instantiate = instantiate
if result is None:
result = lambda r: r
self.result = result
self.check_access = check_access
self.unique = unique
def convert(self, obj, *args, **kwargs):
args = list(args)
kwargs = kwargs.copy()
if 'context' in kwargs:
context = kwargs.pop('context')
else:
context = args.pop()
timestamp = None
for key in context.keys():
if key == '_timestamp':
timestamp = context[key]
# Remove all private keyword but _datetime for history
if key.startswith('_') and key != '_datetime':
del context[key]
if self.instantiate is not None:
def instance(data):
with Transaction().set_context(context):
if isinstance(data, (int, long)):
return obj(data)
elif isinstance(data, dict):
return obj(**data)
else:
if self.unique and len(data) != len(set(data)):
raise ValueError("Duplicate ids")
return obj.browse(data)
if isinstance(self.instantiate, slice):
for i, data in enumerate(args[self.instantiate]):
start, _, step = self.instantiate.indices(len(args))
i = i * step + start
args[i] = instance(data)
else:
data = args[self.instantiate]
args[self.instantiate] = instance(data)
if self.check_access:
context['_check_access'] = True
return args, kwargs, context, timestamp