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.

175 lines
6.8 KiB

  1. # -*- coding: UTF-8 -*-
  2. '''
  3. Created on 23 may 2014
  4. @author: Ronald Portier, Therp
  5. rportier@therp.nl
  6. http://www.therp.nl
  7. For the model defined here _auto is set to False to prevent creating a
  8. database file. All i/o operations are overridden to use a sql SELECT that
  9. takes data from res_partner_connection_type where each type is included in the
  10. result set twice, so it appears that the connection type and the inverse
  11. type are separate records..
  12. The original function _auto_init is still called because this function
  13. normally (if _auto == True) not only creates the db tables, but it also takes
  14. care of registering all fields in ir_model_fields. This is needed to make
  15. the field labels translatable.
  16. example content for last lines of _statement:
  17. select id, record_type,
  18. customer_id, customer_name, customer_city, customer_zip, customer_street,
  19. caller_id, caller_name, caller_phone, caller_fax, caller_email
  20. from FULL_LIST as ResPartnerRelationTypeSelection where record_type = 'c'
  21. ORDER BY ResPartnerRelationTypeSelection.customer_name asc,
  22. ResPartnerRelationTypeSelection.caller_name asc;
  23. '''
  24. from openerp import api
  25. from openerp.osv import fields
  26. from openerp.osv import orm
  27. from openerp.tools import drop_view_if_exists
  28. from .res_partner_relation_type import ResPartnerRelationType
  29. from . import PADDING
  30. class ResPartnerRelationTypeSelection(orm.Model):
  31. '''Virtual relation types'''
  32. _RECORD_TYPES = [
  33. ('a', 'Type'),
  34. ('b', 'Inverse type'),
  35. ]
  36. _auto = False # Do not try to create table in _auto_init(..)
  37. _log_access = False
  38. @api.multi
  39. def get_type_from_selection_id(self):
  40. """Selection id ic computed from id of underlying type and the
  41. kind of record. This function does the inverse computation to give
  42. back the original type id, and about the record type."""
  43. type_id = self.id / PADDING
  44. is_reverse = (self.id % PADDING) > 0
  45. return type_id, is_reverse
  46. def _auto_init(self, cr, context=None):
  47. drop_view_if_exists(cr, self._table)
  48. # TODO: we lose field value's translations here.
  49. # probably we need to patch ir_translation.get_source for that
  50. # to get res_partner_relation_type's translations
  51. cr.execute(
  52. '''create or replace view %(table)s as
  53. select
  54. id * %(padding)d as id,
  55. id as type_id,
  56. cast('a' as char(1)) as record_type,
  57. name as name,
  58. contact_type_left as contact_type_this,
  59. contact_type_right as contact_type_other,
  60. partner_category_left as partner_category_this,
  61. partner_category_right as partner_category_other
  62. from %(underlying_table)s
  63. union select
  64. id * %(padding)d + 1,
  65. id,
  66. cast('b' as char(1)),
  67. name_inverse,
  68. contact_type_right,
  69. contact_type_left,
  70. partner_category_right,
  71. partner_category_left
  72. from %(underlying_table)s''' % {
  73. 'table': self._table,
  74. 'padding': PADDING,
  75. 'underlying_table': 'res_partner_relation_type',
  76. })
  77. return super(ResPartnerRelationTypeSelection, self)._auto_init(
  78. cr, context=context)
  79. def _search_partner_category_this(self, cr, uid, obj, field_name, args,
  80. context=None):
  81. category_ids = []
  82. for arg in args:
  83. if isinstance(arg, tuple) and arg[0] == field_name\
  84. and (arg[1] == '=' or arg[1] == 'in'):
  85. # TODO don't we have an api function to eval that?
  86. for delta in arg[2]:
  87. if delta[0] == 6:
  88. category_ids.extend(delta[2])
  89. if category_ids:
  90. return [
  91. '|',
  92. ('partner_category_this', '=', False),
  93. ('partner_category_this', 'in', category_ids),
  94. ]
  95. else:
  96. return [('partner_category_this', '=', False)]
  97. _name = 'res.partner.relation.type.selection'
  98. _description = 'All relation types'
  99. _foreign_keys = []
  100. _columns = {
  101. 'record_type': fields.selection(_RECORD_TYPES, 'Record type', size=16),
  102. 'type_id': fields.many2one(
  103. 'res.partner.relation.type', 'Type'),
  104. 'name': fields.char('Name', size=64),
  105. 'contact_type_this': fields.selection(
  106. ResPartnerRelationType._get_partner_types.im_func,
  107. 'Current record\'s partner type'),
  108. 'contact_type_other': fields.selection(
  109. ResPartnerRelationType._get_partner_types.im_func,
  110. 'Other record\'s partner type'),
  111. 'partner_category_this': fields.many2one(
  112. 'res.partner.category', 'Current record\'s category'),
  113. 'partner_category_other': fields.many2one(
  114. 'res.partner.category', 'Other record\'s category'),
  115. # search field to handle many2many deltas from the client
  116. 'search_partner_category_this': fields.function(
  117. lambda self, cr, uid, ids, context=None: dict(
  118. [(i, False) for i in ids]),
  119. fnct_search=_search_partner_category_this,
  120. type='many2many', obj='res.partner.category',
  121. string='Current record\'s category'),
  122. }
  123. _order = 'name asc'
  124. def name_get(self, cr, uid, ids, context=None):
  125. 'translate name using translations from res.partner.relation.type'
  126. result = super(ResPartnerRelationTypeSelection, self).name_get(
  127. cr, uid, ids, context=context)
  128. ir_translation = self.pool['ir.translation']
  129. return [
  130. (i, ir_translation._get_source(
  131. cr, uid,
  132. 'res.partner.relation.type,name_inverse'
  133. if self.get_type_from_selection_id(cr, uid, i)[1]
  134. else 'res.partner.relation.type,name',
  135. 'model', context.get('lang'), name))
  136. for i, name in result]
  137. def name_search(self, cr, uid, name='', args=None, operator='ilike',
  138. context=None, limit=100):
  139. 'search for translated names in res.partner.relation.type'
  140. res_partner_relation_type = self.pool['res.partner.relation.type']
  141. relation_ids = res_partner_relation_type.search(
  142. cr, uid, [('name', operator, name)],
  143. context=context)
  144. inverse_relation_ids = res_partner_relation_type.search(
  145. cr, uid, [('name_inverse', operator, name)],
  146. context=context)
  147. all_ids = self.search(
  148. cr, uid,
  149. [
  150. ('id', 'in',
  151. map(lambda x: x * PADDING, relation_ids) +
  152. map(lambda x: x * PADDING + 1, inverse_relation_ids)),
  153. ] + (args or []),
  154. context=context, limit=limit)
  155. return self.name_get(cr, uid, all_ids, context=context)