Initial import from Docker volume
This commit is contained in:
105
model/multivalue.py
Executable file
105
model/multivalue.py
Executable file
@@ -0,0 +1,105 @@
|
||||
# This file is part of Tryton. The COPYRIGHT file at the toplevel of this
|
||||
# repository contains the full copyright notices and license terms.
|
||||
from trytond.pool import Pool
|
||||
|
||||
from .fields import MultiValue
|
||||
from .match import MatchMixin
|
||||
from .model import Model
|
||||
|
||||
|
||||
class MultiValueMixin(object):
|
||||
__slots__ = ()
|
||||
|
||||
@classmethod
|
||||
def multivalue_model(cls, field):
|
||||
pool = Pool()
|
||||
Value = pool.get('%s.%s' % (cls.__name__, field))
|
||||
assert issubclass(Value, ValueMixin), (
|
||||
"%s is not a subclass of ValueMixin" % Value)
|
||||
return Value
|
||||
|
||||
def multivalue_records(self, field):
|
||||
Value = self.multivalue_model(field)
|
||||
for fname, field in self._fields.items():
|
||||
if (field._type == 'one2many'
|
||||
and field.model_name == Value.__name__
|
||||
and not field.filter):
|
||||
return getattr(self, fname)
|
||||
return Value.search([])
|
||||
|
||||
def multivalue_record(self, field, **pattern):
|
||||
Value = self.multivalue_model(field)
|
||||
for fname, field in Value._fields.items():
|
||||
if (field._type == 'many2one'
|
||||
and field.model_name == self.__name__):
|
||||
pattern = pattern.copy()
|
||||
pattern[fname] = self
|
||||
break
|
||||
record = Value(**pattern)
|
||||
for oname, ofield in self._fields.items():
|
||||
if (oname != field
|
||||
and isinstance(ofield, MultiValue)
|
||||
and self.multivalue_model(oname) == Value):
|
||||
func = getattr(self, 'default_%s' % oname, None)
|
||||
if func:
|
||||
setattr(record, oname, func(**pattern))
|
||||
return record
|
||||
|
||||
def __values(self, field, pattern, match_none=True):
|
||||
return [v for v in self.multivalue_records(field)
|
||||
if v.match(pattern, match_none=match_none)]
|
||||
|
||||
def get_multivalue(self, name, **pattern):
|
||||
Value = self.multivalue_model(name)
|
||||
pattern = filter_pattern(pattern, Value)
|
||||
values = self.__values(name, pattern, match_none=False)
|
||||
if not values:
|
||||
value = Value(**pattern)
|
||||
func = getattr(self, 'default_%s' % name, lambda **kw: None)
|
||||
setattr(value, name, func(**pattern))
|
||||
else:
|
||||
value = values[0]
|
||||
return getattr(value, name)
|
||||
|
||||
def _multivalue_getter(self, name):
|
||||
Value = self.multivalue_model(name)
|
||||
value = self.get_multivalue(name)
|
||||
if isinstance(value, Model):
|
||||
if Value._fields[name]._type == 'reference':
|
||||
return str(value)
|
||||
return value.id
|
||||
elif isinstance(value, (list, tuple)):
|
||||
return tuple(r.id if isinstance(r, Model) else r for r in value)
|
||||
else:
|
||||
return value
|
||||
|
||||
def set_multivalue(self, name, value, save=True, **pattern):
|
||||
Value = self.multivalue_model(name)
|
||||
pattern = filter_pattern(pattern, Value)
|
||||
values = self.__values(name, pattern, match_none=True)
|
||||
if not values:
|
||||
values = [self.multivalue_record(name, **pattern)]
|
||||
for record in values:
|
||||
setattr(record, name, value)
|
||||
if save:
|
||||
Value.save(values)
|
||||
else:
|
||||
return values
|
||||
|
||||
@classmethod
|
||||
def _multivalue_setter(cls, records, name, val):
|
||||
Value = cls.multivalue_model(name)
|
||||
to_save = []
|
||||
for record in records:
|
||||
to_save.extend(record.set_multivalue(name, val, save=False))
|
||||
Value.save(to_save)
|
||||
|
||||
|
||||
class ValueMixin(MatchMixin):
|
||||
|
||||
def match(self, pattern, match_none=True):
|
||||
return super(ValueMixin, self).match(pattern, match_none=match_none)
|
||||
|
||||
|
||||
def filter_pattern(pattern, Value):
|
||||
return {f: v for f, v in pattern.items() if f in Value._fields}
|
||||
Reference in New Issue
Block a user