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.

212 lines
7.0 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 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. my_field = fields...
  42. '''
  43. this_partner_id = fields.Many2one(
  44. 'res.partner',
  45. string='Current Partner',
  46. required=True,
  47. )
  48. other_partner_id = fields.Many2one(
  49. 'res.partner',
  50. string='Other Partner',
  51. required=True,
  52. )
  53. type_id = fields.Many2one(
  54. 'res.partner.relation.type',
  55. string='Relation Type',
  56. required=True,
  57. )
  58. type_selection_id = fields.Many2one(
  59. 'res.partner.relation.type.selection',
  60. string='Relation Type',
  61. required=True,
  62. )
  63. relation_id = fields.Many2one(
  64. 'res.partner.relation',
  65. 'Relation',
  66. readonly=True,
  67. )
  68. record_type = fields.Selection(
  69. ResPartnerRelationTypeSelection._RECORD_TYPES,
  70. 'Record Type',
  71. readonly=True,
  72. )
  73. contact_type = fields.Selection(
  74. lambda s: s.env['res.partner.relation.type']._get_partner_types(),
  75. 'Partner Type',
  76. default=lambda self: self._get_default_contact_type()
  77. )
  78. date_start = fields.Date('Starting date')
  79. date_end = fields.Date('Ending date')
  80. active = fields.Boolean('Active', default=True)
  81. def _auto_init(self, cr, context=None):
  82. drop_view_if_exists(cr, self._table)
  83. additional_view_fields = ','.join(self._additional_view_fields)
  84. additional_view_fields = (',' + additional_view_fields)\
  85. if additional_view_fields else ''
  86. cr.execute(
  87. '''create or replace view %(table)s as
  88. select
  89. id * %(padding)d as id,
  90. id as relation_id,
  91. type_id,
  92. cast('a' as char(1)) as record_type,
  93. left_contact_type as contact_type,
  94. left_partner_id as this_partner_id,
  95. right_partner_id as other_partner_id,
  96. date_start,
  97. date_end,
  98. active,
  99. type_id * %(padding)d as type_selection_id
  100. %(additional_view_fields)s
  101. from %(underlying_table)s
  102. union select
  103. id * %(padding)d + 1,
  104. id,
  105. type_id,
  106. cast('b' as char(1)),
  107. right_contact_type,
  108. right_partner_id,
  109. left_partner_id,
  110. date_start,
  111. date_end,
  112. active,
  113. type_id * %(padding)d + 1
  114. %(additional_view_fields)s
  115. from %(underlying_table)s''' % {
  116. 'table': self._table,
  117. 'padding': PADDING,
  118. 'additional_view_fields': additional_view_fields,
  119. 'underlying_table': 'res_partner_relation',
  120. }
  121. )
  122. return super(ResPartnerRelationAll, self)._auto_init(
  123. cr, context=context)
  124. @api.one
  125. def get_underlying_object(self):
  126. """Get the record on which this record is overlaid"""
  127. return self.env[self._overlays].browse(self.id / PADDING)
  128. def _get_default_contact_type(self):
  129. partner_id = self._context.get('default_this_partner_id')
  130. if partner_id:
  131. partner = self.env['res.partner'].browse(partner_id)
  132. return get_partner_type(partner)
  133. return False
  134. @api.multi
  135. def name_get(self):
  136. return {
  137. this.id: '%s %s %s' % (
  138. this.this_partner_id.name,
  139. this.type_selection_id.name_get()[0][1],
  140. this.other_partner_id.name,
  141. )
  142. for this in self
  143. }
  144. @api.onchange('type_selection_id')
  145. def onchange_type_selection_id(self):
  146. """Add domain on other_partner_id according to category_other"""
  147. if not self.type_selection_id.partner_category_other:
  148. return {'domain': []}
  149. is_company = self.type_selection_id.partner_category_other == 'c'
  150. return {
  151. 'domain': {
  152. 'other_partner_id': [('is_company', '=', is_company)],
  153. }
  154. }
  155. @api.one
  156. def write(self, vals):
  157. """divert non-problematic writes to underlying table"""
  158. underlying_objs = self.get_underlying_object()
  159. vals = {
  160. key: val
  161. for key, val in vals.iteritems()
  162. if not self._columns[key].readonly
  163. }
  164. vals['type_selection_id'] = vals.get(
  165. 'type_selection_id',
  166. underlying_objs.type_selection_id.id
  167. )
  168. return underlying_objs.write(vals)
  169. @api.model
  170. def create(self, vals):
  171. """divert non-problematic creates to underlying table
  172. Create a res.partner.relation but return the converted id
  173. """
  174. vals = {
  175. key: val
  176. for key, val in vals.iteritems()
  177. if not self._columns[key].readonly
  178. }
  179. vals['type_selection_id'] = vals.get(
  180. 'type_selection_id',
  181. False,
  182. )
  183. res = self.env[self._overlays].create(vals)
  184. return self.browse(res.id * PADDING)
  185. @api.one
  186. def unlink(self):
  187. """divert non-problematic creates to underlying table"""
  188. return self.get_underlying_object().unlink()