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.

180 lines
6.6 KiB

  1. # -*- coding: utf-8 -*-
  2. ##############################################################################
  3. #
  4. # OpenERP, Open Source Management Solution
  5. # This module copyright (C) 2014 Therp BV (<http://therp.nl>).
  6. #
  7. # This program is free software: you can redistribute it and/or modify
  8. # it under the terms of the GNU Affero General Public License as
  9. # published by the Free Software Foundation, either version 3 of the
  10. # License, or (at your option) any later version.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU Affero General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU Affero General Public License
  18. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. #
  20. ##############################################################################
  21. from openerp import osv, models, fields, api
  22. from openerp.tools import drop_view_if_exists
  23. from .res_partner_relation_type_selection import \
  24. ResPartnerRelationTypeSelection
  25. from . import get_partner_type, PADDING
  26. class ResPartnerRelationAll(models.AbstractModel):
  27. _auto = False
  28. _log_access = False
  29. _name = 'res.partner.relation.all'
  30. _overlays = 'res.partner.relation'
  31. _description = 'All (non-inverse + inverse) relations between partners'
  32. _additional_view_fields = []
  33. '''append to this list if you added fields to res_partner_relation that
  34. you need in this model and related fields are not adequate (ie for sorting)
  35. You must use the same name as in res_partner_relation.
  36. Don't overwrite this list in your declaration but append in _auto_init:
  37. def _auto_init(self, cr, context=None):
  38. self._additional_view_fields.append('my_field')
  39. return super(ResPartnerRelationAll, self)._auto_init(
  40. cr, context=context)
  41. _columns = {
  42. 'my_field': ....
  43. }
  44. '''
  45. def _auto_init(self, cr, context=None):
  46. drop_view_if_exists(cr, self._table)
  47. additional_view_fields = ','.join(self._additional_view_fields)
  48. additional_view_fields = (',' + additional_view_fields)\
  49. if additional_view_fields else ''
  50. cr.execute(
  51. '''create or replace view %(table)s as
  52. select
  53. id * %(padding)d as id,
  54. id as relation_id,
  55. type_id,
  56. cast('a' as char(1)) as record_type,
  57. left_contact_type as contact_type,
  58. left_partner_id as this_partner_id,
  59. right_partner_id as other_partner_id,
  60. date_start,
  61. date_end,
  62. active,
  63. type_id * %(padding)d as type_selection_id
  64. %(additional_view_fields)s
  65. from %(underlying_table)s
  66. union select
  67. id * %(padding)d + 1,
  68. id,
  69. type_id,
  70. cast('b' as char(1)),
  71. right_contact_type,
  72. right_partner_id,
  73. left_partner_id,
  74. date_start,
  75. date_end,
  76. active,
  77. type_id * %(padding)d + 1
  78. %(additional_view_fields)s
  79. from %(underlying_table)s''' % {
  80. 'table': self._table,
  81. 'padding': PADDING,
  82. 'additional_view_fields': additional_view_fields,
  83. 'underlying_table': 'res_partner_relation',
  84. }
  85. )
  86. return super(ResPartnerRelationAll, self)._auto_init(
  87. cr, context=context)
  88. @api.one
  89. def get_underlying_object(self):
  90. """Get the record on which this record is overlaid"""
  91. return self.env[self._overlays].browse(self.id / PADDING)
  92. contact_type = fields.Selection(
  93. lambda s: s.env['res.partner.relation.type']._get_partner_types(),
  94. 'Partner Type',
  95. default=lambda self: self._get_default_contact_type()
  96. )
  97. _columns = {
  98. 'record_type': osv.fields.selection(
  99. ResPartnerRelationTypeSelection._RECORD_TYPES, 'Record type',
  100. readonly=True),
  101. 'relation_id': osv.fields.many2one(
  102. 'res.partner.relation', 'Relation', readonly=True),
  103. 'type_id': osv.fields.many2one(
  104. 'res.partner.relation.type', 'Relation type', readonly=True),
  105. 'type_selection_id': osv.fields.many2one(
  106. 'res.partner.relation.type.selection', 'Relation type',
  107. ),
  108. 'this_partner_id': osv.fields.many2one(
  109. 'res.partner', 'Current partner', readonly=True),
  110. 'other_partner_id': osv.fields.many2one(
  111. 'res.partner', 'Other partner'),
  112. 'date_start': osv.fields.date('Starting date'),
  113. 'date_end': osv.fields.date('Ending date'),
  114. }
  115. active = fields.Boolean('Active', default=True)
  116. def _get_default_contact_type(self):
  117. partner_id = self._context.get('default_this_partner_id')
  118. if partner_id:
  119. partner = self.env['res.partner'].browse(partner_id)
  120. return get_partner_type(partner)
  121. return False
  122. def name_get(self, cr, uid, ids, context=None):
  123. return dict([
  124. (this.id, '%s %s %s' % (
  125. this.this_partner_id.name,
  126. this.type_selection_id.name_get()[0][1],
  127. this.other_partner_id.name,
  128. ))
  129. for this in self.browse(cr, uid, ids, context=context)])
  130. @api.one
  131. def write(self, vals):
  132. """divert non-problematic writes to underlying table"""
  133. underlying_objs = self.get_underlying_object()
  134. vals = {
  135. key: val
  136. for key, val in vals.iteritems()
  137. if not self._columns[key].readonly
  138. }
  139. vals['type_selection_id'] = vals.get(
  140. 'type_selection_id',
  141. underlying_objs.type_selection_id.id
  142. )
  143. return underlying_objs.write(vals)
  144. @api.model
  145. def create(self, vals):
  146. """divert non-problematic creates to underlying table
  147. Create a res.partner.relation but return the converted id
  148. """
  149. vals = {
  150. key: val
  151. for key, val in vals.iteritems()
  152. if not self._columns[key].readonly
  153. }
  154. vals['type_selection_id'] = vals.get(
  155. 'type_selection_id',
  156. False,
  157. )
  158. res = self.env[self._overlays].create(vals)
  159. return self.browse(res.id * PADDING)
  160. @api.one
  161. def unlink(self):
  162. """divert non-problematic creates to underlying table"""
  163. return self.get_underlying_object().unlink()