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.

237 lines
7.9 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. def _get_underlying_object(self):
  125. """Get the record on which this record is overlaid"""
  126. return self.env[self._overlays].browse(self.id / PADDING)
  127. def _get_default_contact_type(self):
  128. partner_id = self._context.get('default_this_partner_id')
  129. if partner_id:
  130. partner = self.env['res.partner'].browse(partner_id)
  131. return get_partner_type(partner)
  132. return False
  133. @api.multi
  134. def name_get(self):
  135. return {
  136. this.id: '%s %s %s' % (
  137. this.this_partner_id.name,
  138. this.type_selection_id.name_get()[0][1],
  139. this.other_partner_id.name,
  140. )
  141. for this in self
  142. }
  143. @api.onchange('type_selection_id')
  144. def onchange_type_selection_id(self):
  145. """Add domain on other_partner_id according to category_other and
  146. contact_type_other"""
  147. domain = []
  148. if self.type_selection_id.contact_type_other:
  149. domain.append(
  150. ('is_company', '=',
  151. self.type_selection_id.contact_type_other == 'c'))
  152. if self.type_selection_id.partner_category_other:
  153. domain.append(
  154. ('category_id', 'in',
  155. self.type_selection_id.partner_category_other.ids))
  156. return {
  157. 'domain': {
  158. 'other_partner_id': domain,
  159. }
  160. }
  161. @api.onchange('this_partner_id')
  162. def onchange_this_partner_id(self):
  163. if not self.this_partner_id:
  164. return {'domain': {'type_selection_id': []}}
  165. return {
  166. 'domain': {
  167. 'type_selection_id': [
  168. '|',
  169. ('contact_type_this', '=', False),
  170. ('contact_type_this', '=',
  171. 'c' if self.this_partner_id else 'p'),
  172. '|',
  173. ('partner_category_this', '=', False),
  174. ('partner_category_this', 'in',
  175. self.this_partner_id.category_id.ids),
  176. ],
  177. },
  178. }
  179. @api.one
  180. def write(self, vals):
  181. """divert non-problematic writes to underlying table"""
  182. underlying_objs = self._get_underlying_object()
  183. vals = {
  184. key: val
  185. for key, val in vals.iteritems()
  186. if not self._columns[key].readonly
  187. }
  188. vals['type_selection_id'] = vals.get(
  189. 'type_selection_id',
  190. underlying_objs.type_selection_id.id
  191. )
  192. return underlying_objs.write(vals)
  193. @api.model
  194. def create(self, vals):
  195. """divert non-problematic creates to underlying table
  196. Create a res.partner.relation but return the converted id
  197. """
  198. vals = {
  199. key: val
  200. for key, val in vals.iteritems()
  201. if not self._columns[key].readonly
  202. }
  203. vals['type_selection_id'] = vals.get(
  204. 'type_selection_id',
  205. False,
  206. )
  207. res = self.env[self._overlays].create(vals)
  208. return self.browse(res.id * PADDING)
  209. @api.one
  210. def unlink(self):
  211. """divert non-problematic creates to underlying table"""
  212. return self._get_underlying_object().unlink()