You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

102 lines
4.5 KiB

  1. ###################################################################################
  2. #
  3. # Copyright (C) 2018 MuK IT GmbH
  4. #
  5. # This program is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU Affero General Public License as
  7. # published by the Free Software Foundation, either version 3 of the
  8. # License, or (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU Affero General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU Affero General Public License
  16. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. #
  18. ###################################################################################
  19. import logging
  20. from odoo import api, models, fields
  21. from odoo.osv import expression
  22. from odoo.addons.muk_utils.tools import utils
  23. _logger = logging.getLogger(__name__)
  24. class Base(models.AbstractModel):
  25. _inherit = 'base'
  26. #----------------------------------------------------------
  27. # Hierarchy Methods
  28. #----------------------------------------------------------
  29. @api.model
  30. def search_parents(self, domain=[], order=None):
  31. """ This method finds the top level elements of the hierarchy for a given search query.
  32. :param domain: a search domain <reference/orm/domains> (default: empty list)
  33. :param order: a string to define the sort order of the query (default: none)
  34. :returns: the top level elements for the given search query
  35. """
  36. return self.browse(self._search_parents(domain=domain, order=order))
  37. @api.model
  38. def search_read_parents(self, domain=[], fields=None, order=None):
  39. """ This method finds the top level elements of the hierarchy for a given search query.
  40. :param domain: a search domain <reference/orm/domains> (default: empty list)
  41. :param fields: a list of fields to read (default: all fields of the model)
  42. :param order: a string to define the sort order of the query (default: none)
  43. :returns: the top level elements for the given search query
  44. """
  45. records = self.search_parents(domain=domain, order=order)
  46. if not records:
  47. return []
  48. if fields and fields == ['id']:
  49. return [{'id': record.id} for record in records]
  50. result = records.read(fields)
  51. if len(result) <= 1:
  52. return result
  53. index = {vals['id']: vals for vals in result}
  54. return [index[record.id] for record in records if record.id in index]
  55. @api.model
  56. def _search_parents(self, domain=[], order=None):
  57. if not self._parent_store or self._parent_name not in self._fields:
  58. raise TypeError("Model %r does not exist in registry." % name)
  59. self.check_access_rights('read')
  60. if expression.is_false(self, domain):
  61. return []
  62. query = self._where_calc(domain)
  63. self._apply_ir_rules(query, 'read')
  64. from_clause, where_clause, where_clause_arguments = query.get_sql()
  65. parent_where = where_clause and (" WHERE %s" % where_clause) or ''
  66. parent_query = 'SELECT "%s".id FROM ' % self._table + from_clause + parent_where
  67. no_parent_clause ='"{table}"."{field}" IS NULL'.format(
  68. table=self._table,
  69. field=self._parent_name
  70. )
  71. no_access_clause ='"{table}"."{field}" NOT IN ({query})'.format(
  72. table=self._table,
  73. field=self._parent_name,
  74. query=parent_query
  75. )
  76. parent_clause = '({0} OR {1})'.format(
  77. no_parent_clause,
  78. no_access_clause
  79. )
  80. order_by = self._generate_order_by(order, query)
  81. from_clause, where_clause, where_clause_params = query.get_sql()
  82. where_str = (
  83. where_clause and
  84. (" WHERE %s AND %s" % (where_clause, parent_clause)) or
  85. (" WHERE %s" % parent_clause)
  86. )
  87. query_str = 'SELECT "%s".id FROM ' % self._table + from_clause + where_str + order_by
  88. complete_where_clause_params = where_clause_params + where_clause_arguments
  89. self._cr.execute(query_str, complete_where_clause_params)
  90. return utils.uniquify_list([x[0] for x in self._cr.fetchall()])