# -*- coding: utf-8 -*- # This file is part of the cashbook-module from m-ds for Tryton. # The COPYRIGHT file at the top level of this repository contains the # full copyright notices and license terms. from trytond.model import MultiValueMixin, ValueMixin, fields, Unique from trytond.transaction import Transaction from trytond.pool import Pool from sql import With, Literal from sql.functions import Function class ArrayAgg(Function): """input values, including nulls, concatenated into an array. """ __slots__ = () _function = 'ARRAY_AGG' # end ArrayAgg class ArrayAppend(Function): """ sql: array_append """ __slots__ = () _function = 'ARRAY_APPEND' # end ArrayApppend class ArrayToString(Function): """ sql: array_to_string """ __slots__ = () _function = 'ARRAY_TO_STRING' # end ArrayToString class AnyInArray(Function): """ sql: array_to_string """ __slots__ = () _function = 'ANY' def __str__(self): return self._function + '(' + ', '.join( map(self._format, self.args)) + '::int[])' # end AnyInArray class Array(Function): """ sql: array-type """ __slots__ = () _function = 'ARRAY' def __str__(self): return self._function + '[' + ', '.join( map(self._format, self.args)) + ']' # end Array def sub_ids_hierarchical(model_name): """ get table with id and sub-ids """ Model2 = Pool().get(model_name) tab_mod = Model2.__table__() tab_mod2 = Model2.__table__() lines = With('parent', 'id', recursive=True) lines.query = tab_mod.select( tab_mod.id, tab_mod.id, ) | tab_mod2.join(lines, condition=lines.id==tab_mod2.parent, ).select( lines.parent, tab_mod2.id, ) lines.query.all_ = True query = lines.select( lines.parent, ArrayAgg(lines.id).as_('subids'), group_by=[lines.parent], with_ = [lines]) return query def order_name_hierarchical(model_name, tables): """ order by pos a recursive sorting """ Model2 = Pool().get(model_name) tab_mod = Model2.__table__() tab_mod2 = Model2.__table__() table, _ = tables[None] lines = With('id', 'name', 'name_path', recursive=True) lines.query = tab_mod.select( tab_mod.id, tab_mod.name, Array(tab_mod.name), where = tab_mod.parent==None, ) lines.query |= tab_mod2.join(lines, condition=lines.id==tab_mod2.parent, ).select( tab_mod2.id, tab_mod2.name, ArrayAppend(lines.name_path, tab_mod2.name), ) lines.query.all_ = True query = lines.select( ArrayToString(lines.name_path, '/').as_('rec_name'), where = table.id==lines.id, with_ = [lines]) return [query] class UserValueMixin(ValueMixin): iduser = fields.Many2One(model_name='res.user', string="User", select=True, ondelete='CASCADE', required=True) @classmethod def __setup__(cls): super(UserValueMixin, cls).__setup__() tab_val = cls.__table__() cls._sql_constraints.extend([ ('val_uniq', Unique(tab_val, tab_val.iduser), 'cashbook.msg_setting_already_exists'), ]) # end UserValueMixin class UserMultiValueMixin(MultiValueMixin): def updt_multivalue_pattern(self, pattern): """ add values to pattern """ pattern.setdefault('iduser', Transaction().user) return pattern def get_multivalue(self, name, **pattern): Value = self.multivalue_model(name) if issubclass(Value, UserValueMixin): pattern = self.updt_multivalue_pattern(pattern) return super(UserMultiValueMixin, self).get_multivalue(name, **pattern) def set_multivalue(self, name, value, **pattern): Value = self.multivalue_model(name) if issubclass(Value, UserValueMixin): pattern = self.updt_multivalue_pattern(pattern) return super(UserMultiValueMixin, self).set_multivalue(name, value, **pattern) # end UserMultiValueMixin