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.

151 lines
4.8 KiB

  1. # -*- coding: utf-8 -*-
  2. # Copyright 2013-2017 Therp BV <http://therp.nl>
  3. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
  4. """
  5. For the model defined here _auto is set to False to prevent creating a
  6. database file. The model is based on a SQL view based on
  7. res_partner_relation_type where each type is included in the
  8. result set twice, so it appears that the connection type and the inverse
  9. type are separate records..
  10. The original function _auto_init is still called because this function
  11. normally (if _auto == True) not only creates the db tables, but it also takes
  12. care of registering all fields in ir_model_fields. This is needed to make
  13. the field labels translatable.
  14. """
  15. from psycopg2.extensions import AsIs
  16. from openerp import api, fields, models
  17. from openerp.tools import drop_view_if_exists
  18. class ResPartnerRelationTypeSelection(models.Model):
  19. """Virtual relation types"""
  20. _name = 'res.partner.relation.type.selection'
  21. _description = 'All relation types'
  22. _auto = False # Do not try to create table in _auto_init(..)
  23. _foreign_keys = []
  24. _log_access = False
  25. _order = 'name asc'
  26. @api.model
  27. def get_partner_types(self):
  28. """Partner types are defined by model res.partner.relation.type."""
  29. # pylint: disable=no-self-use
  30. rprt_model = self.env['res.partner.relation.type']
  31. return rprt_model.get_partner_types()
  32. type_id = fields.Many2one(
  33. comodel_name='res.partner.relation.type',
  34. string='Type',
  35. )
  36. name = fields.Char('Name')
  37. contact_type_this = fields.Selection(
  38. selection='get_partner_types',
  39. string='Current record\'s partner type',
  40. )
  41. is_inverse = fields.Boolean(
  42. string="Is reverse type?",
  43. help="Inverse relations are from right to left partner.",
  44. )
  45. contact_type_other = fields.Selection(
  46. selection='get_partner_types',
  47. string='Other record\'s partner type',
  48. )
  49. partner_category_this = fields.Many2one(
  50. comodel_name='res.partner.category',
  51. string='Current record\'s category',
  52. )
  53. partner_category_other = fields.Many2one(
  54. comodel_name='res.partner.category',
  55. string='Other record\'s category',
  56. )
  57. allow_self = fields.Boolean(
  58. string='Reflexive',
  59. )
  60. is_symmetric = fields.Boolean(
  61. string='Symmetric',
  62. )
  63. def _get_additional_view_fields(self):
  64. """Allow inherit models to add fields to view.
  65. If fields are added, the resulting string must have each field
  66. prepended by a comma, like so:
  67. return ', typ.allow_self, typ.left_partner_category'
  68. """
  69. return ''
  70. def _get_additional_tables(self):
  71. """Allow inherit models to add tables (JOIN's) to view.
  72. Example:
  73. return 'JOIN type_extention ext ON (bas.type_id = ext.id)'
  74. """
  75. return ''
  76. @api.model_cr_context
  77. def _auto_init(self):
  78. cr = self._cr
  79. drop_view_if_exists(cr, self._table)
  80. cr.execute(
  81. """\
  82. CREATE OR REPLACE VIEW %(table)s AS
  83. WITH selection_type AS (
  84. SELECT
  85. id * 2 AS id,
  86. id AS type_id,
  87. name AS name,
  88. False AS is_inverse,
  89. contact_type_left AS contact_type_this,
  90. contact_type_right AS contact_type_other,
  91. partner_category_left AS partner_category_this,
  92. partner_category_right AS partner_category_other
  93. FROM %(underlying_table)s
  94. UNION SELECT
  95. (id * 2) + 1,
  96. id,
  97. name_inverse,
  98. True,
  99. contact_type_right,
  100. contact_type_left,
  101. partner_category_right,
  102. partner_category_left
  103. FROM %(underlying_table)s
  104. WHERE not is_symmetric
  105. )
  106. SELECT
  107. bas.*,
  108. typ.allow_self,
  109. typ.is_symmetric
  110. %(additional_view_fields)s
  111. FROM selection_type bas
  112. JOIN res_partner_relation_type typ ON (bas.type_id = typ.id)
  113. %(additional_tables)s
  114. """,
  115. {'table': AsIs(self._table),
  116. 'underlying_table': AsIs('res_partner_relation_type'),
  117. 'additional_view_fields':
  118. AsIs(self._get_additional_view_fields()),
  119. 'additional_tables':
  120. AsIs(self._get_additional_tables())})
  121. return super(ResPartnerRelationTypeSelection, self)._auto_init()
  122. @api.multi
  123. def name_get(self):
  124. """Get name or name_inverse from underlying model."""
  125. return [
  126. (this.id,
  127. this.is_inverse and this.type_id.name_inverse or
  128. this.type_id.display_name)
  129. for this in self]
  130. @api.model
  131. def name_search(self, name='', args=None, operator='ilike', limit=100):
  132. """Search for name or inverse name in underlying model."""
  133. # pylint: disable=no-value-for-parameter
  134. return self.search(
  135. ['|',
  136. ('type_id.name', operator, name),
  137. ('type_id.name_inverse', operator, name)] + (args or []),
  138. limit=limit).name_get()