diff --git a/muk_utils/__manifest__.py b/muk_utils/__manifest__.py
index 3d30ee0..3ce9ea6 100644
--- a/muk_utils/__manifest__.py
+++ b/muk_utils/__manifest__.py
@@ -1,51 +1,51 @@
-###################################################################################
-#
-# Copyright (C) 2018 MuK IT GmbH
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see .
-#
-###################################################################################
-{
- "name": "MuK Utils",
- "summary": """Utility Features""",
- "version": '12.0.1.4.11',
- "category": 'Extra Tools',
- "license": "AGPL-3",
- "author": "MuK IT",
- "website": "https://www.mukit.at",
- 'live_test_url': 'https://mukit.at/r/SgN',
- "contributors": [
- "Mathias Markl ",
- ],
- "depends": [
- "base_setup",
- ],
- "data": [
- "views/mixins_groups.xml",
- "views/res_config_settings_view.xml",
- ],
- "qweb": [
- "static/src/xml/*.xml",
- ],
- "images": [
- 'static/description/banner.png'
- ],
- "external_dependencies": {
- "python": [],
- "bin": [],
- },
- "application": False,
- "installable": True,
- "auto_install": False,
-}
+###################################################################################
+#
+# Copyright (C) 2018 MuK IT GmbH
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+{
+ "name": "MuK Utils",
+ "summary": """Utility Features""",
+ "version": '12.0.1.4.12',
+ "category": 'Extra Tools',
+ "license": "AGPL-3",
+ "author": "MuK IT",
+ "website": "https://www.mukit.at",
+ 'live_test_url': 'https://mukit.at/r/SgN',
+ "contributors": [
+ "Mathias Markl ",
+ ],
+ "depends": [
+ "base_setup",
+ ],
+ "data": [
+ "views/mixins_groups.xml",
+ "views/res_config_settings_view.xml",
+ ],
+ "qweb": [
+ "static/src/xml/*.xml",
+ ],
+ "images": [
+ 'static/description/banner.png'
+ ],
+ "external_dependencies": {
+ "python": [],
+ "bin": [],
+ },
+ "application": False,
+ "installable": True,
+ "auto_install": False,
+}
diff --git a/muk_utils/models/base.py b/muk_utils/models/base.py
index ffadc18..07f5751 100644
--- a/muk_utils/models/base.py
+++ b/muk_utils/models/base.py
@@ -42,7 +42,7 @@ class Base(models.AbstractModel):
def _build_search_childs_domain(self, parent_id, domain=[]):
self._check_parent_field()
parent_domain = [[self._parent_name, '=', parent_id]]
- return expression.AND(parent_domain, domain) if domain else parent_domain
+ return expression.AND([parent_domain, domain]) if domain else parent_domain
#----------------------------------------------------------
# Security
diff --git a/muk_utils/models/mixins_hierarchy.py b/muk_utils/models/mixins_hierarchy.py
index b3e68c0..b2b723b 100644
--- a/muk_utils/models/mixins_hierarchy.py
+++ b/muk_utils/models/mixins_hierarchy.py
@@ -1,128 +1,143 @@
-###################################################################################
-#
-# Copyright (C) 2017 MuK IT GmbH
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see .
-#
-###################################################################################
-
-import json
-import operator
-import functools
-import collections
-
-from odoo import models, fields, api
-
-class Hierarchy(models.AbstractModel):
-
- _name = 'muk_utils.mixins.hierarchy'
- _description = 'Hierarchy Mixin'
-
- _parent_store = True
- _parent_path_sudo = False
- _parent_path_store = False
-
- #----------------------------------------------------------
- # Database
- #----------------------------------------------------------
-
- parent_path = fields.Char(
- string="Parent Path",
- index=True)
-
- @api.model
- def _add_magic_fields(self):
- super(Hierarchy, self)._add_magic_fields()
- def add(name, field):
- if name not in self._fields:
- self._add_field(name, field)
- path_names_search = None
- if not self._parent_path_store:
- path_names_search = '_search_parent_path_names',
- add('parent_path_names', fields.Char(
- _module=self._module,
- compute='_compute_parent_path',
- compute_sudo=self._parent_path_sudo,
- store=self._parent_path_store,
- search=path_names_search,
- string="Path Names",
- readonly=True,
- automatic=True))
- add('parent_path_json', fields.Text(
- _module=self._module,
- compute='_compute_parent_path',
- compute_sudo=self._parent_path_sudo,
- store=self._parent_path_store,
- string="Path Json",
- readonly=True,
- automatic=True))
-
- #----------------------------------------------------------
- # Search
- #----------------------------------------------------------
-
- @api.model
- def _search_parent_path_names(self, operator, operand):
- domain = []
- for value in operand.split('/'):
- args = [(self._rec_name_fallback(), operator, value)]
- domain = expression.OR(args, domain) if domain else args
- return domain
-
- #----------------------------------------------------------
- # Read, View
- #----------------------------------------------------------
-
- @api.depends('parent_path')
- def _compute_parent_path(self):
- records = self.filtered(lambda record: record.parent_path)
- paths = [list(map(int, rec.parent_path.split('/')[:-1])) for rec in records]
- ids = paths and set(functools.reduce(operator.concat, paths)) or []
- data = dict(self.browse(ids)._filter_access('read').name_get())
- for record in records:
- path_names = [""]
- path_json = []
- for id in reversed(list(map(int, record.parent_path.split('/')[:-1]))):
- if id not in data:
- break
- path_names.append(data[id])
- path_json.append({
- 'model': record._name,
- 'name': data[id],
- 'id': id,
- })
- path_names.reverse()
- path_json.reverse()
- record.update({
- 'parent_path_names': '/'.join(path_names),
- 'parent_path_json': json.dumps(path_json),
- })
-
- #----------------------------------------------------------
- # Create, Update, Delete
- #----------------------------------------------------------
-
- @api.multi
- def write(self, vals):
- if self._parent_path_store and self._rec_name_fallback() in vals:
- with self.env.norecompute():
- res = super(Hierarchy, self).write(vals)
- domain = [('id', 'child_of', self.ids)]
- records = self.sudo().search(domain)
- records.modified(['parent_path'])
- if self.env.recompute and self.env.context.get('recompute', True):
- records.recompute()
- return res
- return super(Hierarchy, self).write(vals)
+###################################################################################
+#
+# Copyright (C) 2017 MuK IT GmbH
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+###################################################################################
+
+import json
+import operator
+import functools
+import collections
+
+from odoo import models, fields, api
+from odoo.osv import expression
+
+class Hierarchy(models.AbstractModel):
+
+ _name = 'muk_utils.mixins.hierarchy'
+ _description = 'Hierarchy Mixin'
+
+ _parent_store = True
+ _parent_path_sudo = False
+ _parent_path_store = False
+
+ #----------------------------------------------------------
+ # Database
+ #----------------------------------------------------------
+
+ parent_path = fields.Char(
+ string="Parent Path",
+ index=True)
+
+ @api.model
+ def _add_magic_fields(self):
+ super(Hierarchy, self)._add_magic_fields()
+ def add(name, field):
+ if name not in self._fields:
+ self._add_field(name, field)
+ path_names_search = None
+ if not self._parent_path_store:
+ path_names_search = '_search_parent_path_names'
+ add('parent_path_names', fields.Char(
+ _module=self._module,
+ compute='_compute_parent_paths',
+ compute_sudo=self._parent_path_sudo,
+ store=self._parent_path_store,
+ search=path_names_search,
+ string="Path Names",
+ readonly=True,
+ automatic=True))
+ add('parent_path_json', fields.Text(
+ _module=self._module,
+ compute='_compute_parent_paths',
+ compute_sudo=self._parent_path_sudo,
+ store=self._parent_path_store,
+ string="Path Json",
+ readonly=True,
+ automatic=True))
+
+ #----------------------------------------------------------
+ # Helper
+ #----------------------------------------------------------
+
+ def _get_depends_parent_paths(self):
+ depends = ['parent_path']
+ if self._rec_name:
+ depends += [self._rec_name]
+ elif 'name' in self._fields:
+ depends += ['name']
+ elif 'x_name' in self._fields:
+ depends += ['x_name']
+ return depends
+
+ #----------------------------------------------------------
+ # Search
+ #----------------------------------------------------------
+
+ @api.model
+ def _search_parent_path_names(self, operator, operand):
+ domain = []
+ for value in operand.split('/'):
+ args = [(self._rec_name_fallback(), operator, value)]
+ domain = expression.OR([args, domain]) if domain else args
+ return domain if domain else [(self._rec_name_fallback(), operator, "")]
+
+ #----------------------------------------------------------
+ # Read, View
+ #----------------------------------------------------------
+
+ @api.depends(lambda self: self._get_depends_parent_paths())
+ def _compute_parent_paths(self):
+ records = self.filtered(lambda record: record.parent_path)
+ paths = [list(map(int, rec.parent_path.split('/')[:-1])) for rec in records]
+ ids = paths and set(functools.reduce(operator.concat, paths)) or []
+ data = dict(self.browse(ids)._filter_access('read').name_get())
+ for record in records:
+ path_names = [""]
+ path_json = []
+ for id in reversed(list(map(int, record.parent_path.split('/')[:-1]))):
+ if id not in data:
+ break
+ path_names.append(data[id])
+ path_json.append({
+ 'model': record._name,
+ 'name': data[id],
+ 'id': id,
+ })
+ path_names.reverse()
+ path_json.reverse()
+ record.update({
+ 'parent_path_names': '/'.join(path_names),
+ 'parent_path_json': json.dumps(path_json),
+ })
+
+ #----------------------------------------------------------
+ # Create, Update, Delete
+ #----------------------------------------------------------
+
+ @api.multi
+ def write(self, vals):
+ if self._parent_path_store and self._rec_name_fallback() in vals:
+ with self.env.norecompute():
+ res = super(Hierarchy, self).write(vals)
+ domain = [('id', 'child_of', self.ids)]
+ records = self.sudo().search(domain)
+ records.modified(['parent_path'])
+ if self.env.recompute and self.env.context.get('recompute', True):
+ records.recompute()
+ return res
+ return super(Hierarchy, self).write(vals)
\ No newline at end of file