/usr/lib/python2.7/dist-packages/trytond/model/fields/property.py is in tryton-server 3.8.3-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 | # 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 sql import Cast, Literal, Null
from sql.functions import Substring, Position
from .function import Function
from .field import Field, SQL_OPERATORS
from .numeric import Numeric
from .integer import Integer
from .float import Float
from ...transaction import Transaction
from ...pool import Pool
class Property(Function):
'''
Define a property field that is stored in ir.property (any).
'''
def __init__(self, field):
'''
:param field: The field of the function.
'''
super(Property, self).__init__(field, True, True, True)
__init__.__doc__ += Field.__init__.__doc__
def __copy__(self):
return Property(copy.copy(self._field))
def __deepcopy__(self, memo):
return Property(copy.deepcopy(self._field))
def get(self, ids, model, name, values=None):
'''
Retreive the property.
: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
'''
with Transaction().set_context(_check_access=False):
pool = Pool()
Property = pool.get('ir.property')
return Property.get(name, model.__name__, ids)
def set(self, Model, name, ids, value, *args):
'''
Set the property.
'''
with Transaction().set_context(_check_access=False):
pool = Pool()
Property = pool.get('ir.property')
args = iter((ids, value) + args)
for ids, value in zip(args, args):
if value is not None:
prop_value = '%s,%s' % (getattr(self, 'model_name', ''),
str(value))
else:
prop_value = None
# TODO change set API to use sequence of records, value
Property.set(name, Model.__name__, ids, prop_value)
def convert_domain(self, domain, tables, Model):
pool = Pool()
Rule = pool.get('ir.rule')
Property = pool.get('ir.property')
IrModel = pool.get('ir.model')
Field = pool.get('ir.model.field')
cursor = Transaction().cursor
name, operator, value = domain
sql_type = self._field.sql_type().base
property_cond = Rule.query_get('ir.property')
property_ = Property.__table__()
model_field = Field.__table__()
model = IrModel.__table__()
# Fetch res ids that comply with the domain
join = property_.join(model_field,
condition=model_field.id == property_.field)
join = join.join(model,
condition=model.id == model_field.model)
cond = ((model.model == Model.__name__)
& (model_field.name == name))
if property_cond:
cond &= property_.id.in_(property_cond)
cursor.execute(*join.select(
Cast(Substring(property_.res,
Position(',', property_.res) + Literal(1)),
Model.id.sql_type().base),
property_.id,
where=cond & self.get_condition(sql_type, domain, property_)))
props = cursor.fetchall()
default = None
for prop in props:
if not prop[0]:
default = prop[1]
break
if (not default
or ((value is False or value is None)
and operator in ['=', '!='])
or (operator in ['not like', 'not ilike', 'not in', '!='])):
dom_operator = 'in' # default operator
if (((value is False or value is None) and operator == '=')
or ((value is not False and value is not None)
and operator in [
'not like', 'not ilike', 'not in', '!='])):
dom_operator = 'not in'
return [('id', dom_operator, [x[0] for x in props])]
# Fetch the res ids that doesn't use the default value
cursor.execute(*property_.select(
Cast(Substring(property_.res,
Position(',', property_.res) + Literal(1)),
Model.id.sql_type().base),
where=property_cond & (property_.res != Null)))
fetchall = cursor.fetchall()
if not fetchall:
return [('id', 'in', [x[0] for x in props])]
else:
other_ids = [x[0] for x in cursor.fetchall()]
res_ids = Model.search(['OR',
('id', 'in', [x[0] for x in props]),
('id', 'not in', other_ids)
])
return [('id', 'in', res_ids)]
@staticmethod
def get_condition(sql_type, clause, table):
operator = clause[1]
value = clause[2]
sql_types = [
Numeric('numeric').sql_type().base,
Integer('integer').sql_type().base,
Float('float').sql_type().base,
]
if sql_type in sql_types and value:
if isinstance(value, (list, tuple)):
value = [Cast(v, sql_type) for v in value]
else:
value = Cast(value, sql_type)
if value is None:
value = False
column = Cast(Substring(table.value,
Position(',', table.value) + Literal(1)),
sql_type)
Operator = SQL_OPERATORS[operator]
# All negative clauses will be negated later
if operator in ('in', 'not in'):
return column.in_(value)
elif ((value is False or value is None)
and operator in ('=', '!=')):
return column != Null
elif operator == 'not like':
return column.like(value)
elif operator == 'not ilike':
return column.ilike(value)
elif operator == '!=':
return column == value
return Operator(column, value)
|