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.

215 lines
7.2 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. underlying_objs = underlying_objs and underlying_objs[0]
  160. vals = {
  161. key: val
  162. for key, val in vals.iteritems()
  163. if not self._columns[key].readonly
  164. }
  165. vals['type_selection_id'] = vals.get(
  166. 'type_selection_id',
  167. underlying_objs.type_selection_id.id
  168. )
  169. return underlying_objs.write(vals)
  170. @api.model
  171. def create(self, vals):
  172. """divert non-problematic creates to underlying table
  173. Create a res.partner.relation but return the converted id
  174. """
  175. vals = {
  176. key: val
  177. for key, val in vals.iteritems()
  178. if not self._columns[key].readonly
  179. }
  180. vals['type_selection_id'] = vals.get(
  181. 'type_selection_id',
  182. False,
  183. )
  184. res = self.env[self._overlays].create(vals)
  185. return self.browse(res.id * PADDING)
  186. @api.one
  187. def unlink(self):
  188. """divert non-problematic creates to underlying table"""
  189. underlying_objs = self.get_underlying_object()
  190. underlying_objs = underlying_objs and underlying_objs[0]
  191. return underlying_objs.unlink()