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.

238 lines
9.0 KiB

  1. # -*- coding: utf-8 -*-
  2. '''Extend res.partner model'''
  3. ##############################################################################
  4. #
  5. # OpenERP, Open Source Management Solution
  6. # This module copyright (C) 2013 Therp BV (<http://therp.nl>).
  7. #
  8. # This program is free software: you can redistribute it and/or modify
  9. # it under the terms of the GNU Affero General Public License as
  10. # published by the Free Software Foundation, either version 3 of the
  11. # License, or (at your option) any later version.
  12. #
  13. # This program is distributed in the hope that it will be useful,
  14. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. # GNU Affero General Public License for more details.
  17. #
  18. # You should have received a copy of the GNU Affero General Public License
  19. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. #
  21. ##############################################################################
  22. import time
  23. from openerp.osv import orm, fields
  24. from openerp.osv.expression import is_leaf
  25. from openerp.tools import DEFAULT_SERVER_DATE_FORMAT
  26. class ResPartner(orm.Model):
  27. _inherit = 'res.partner'
  28. def _get_relation_ids(
  29. self, cr, uid, ids, dummy_name, dummy_arg, context=None):
  30. if context is None:
  31. context = {}
  32. # TODO: do a permission test on returned ids
  33. cr.execute(
  34. '''select id, left_partner_id, right_partner_id
  35. from res_partner_relation
  36. where (left_partner_id in %s or right_partner_id in %s)''' +
  37. ' order by ' + self.pool['res.partner.relation']._order,
  38. (tuple(ids), tuple(ids))
  39. )
  40. result = dict([(i, []) for i in ids])
  41. for row in cr.fetchall():
  42. if row[1] in result:
  43. result[row[1]].append(row[0])
  44. if row[2] in result:
  45. result[row[2]].append(row[0])
  46. return result
  47. def _set_relation_ids(
  48. self, cr, uid, ids, dummy_name, field_value, dummy_arg,
  49. context=None):
  50. if context is None:
  51. context = {}
  52. relation_obj = self.pool.get('res.partner.relation')
  53. context2 = self._update_context(context, ids)
  54. for value in field_value:
  55. if value[0] == 0:
  56. relation_obj.create(cr, uid, value[2], context=context2)
  57. if value[0] == 1:
  58. relation_obj.write(
  59. cr, uid, value[1], value[2], context=context2)
  60. if value[0] == 2:
  61. relation_obj.unlink(cr, uid, value[1], context=context2)
  62. def _search_relation_id(
  63. self, cr, uid, dummy_obj, name, args, context=None):
  64. result = []
  65. for arg in args:
  66. if isinstance(arg, tuple) and arg[0] == name:
  67. if arg[1] != '=':
  68. continue
  69. type_id, is_inverse = self\
  70. .pool['res.partner.relation.type.selection']\
  71. .get_type_from_selection_id(cr, uid, arg[2])
  72. result.extend([
  73. '&',
  74. ('relation_all_ids.type_id', '=', type_id),
  75. ('relation_all_ids.record_type', '=',
  76. 'b' if is_inverse else 'a')
  77. ])
  78. return result
  79. def _search_relation_date(self, cr, uid, obj, name, args, context=None):
  80. result = []
  81. for arg in args:
  82. if isinstance(arg, tuple) and arg[0] == name:
  83. # TODO: handle {<,>}{,=}
  84. if arg[1] != '=':
  85. continue
  86. result.extend([
  87. '&',
  88. '|',
  89. ('relation_all_ids.date_start', '=', False),
  90. ('relation_all_ids.date_start', '<=', arg[2]),
  91. '|',
  92. ('relation_all_ids.date_end', '=', False),
  93. ('relation_all_ids.date_end', '>=', arg[2]),
  94. ])
  95. return result
  96. def _search_related_partner_id(
  97. self, cr, uid, dummy_obj, name, args, context=None):
  98. result = []
  99. for arg in args:
  100. if isinstance(arg, tuple) and arg[0] == name:
  101. result.append(
  102. (
  103. 'relation_all_ids.other_partner_id',
  104. arg[1],
  105. arg[2],
  106. ))
  107. return result
  108. def _search_related_partner_category_id(
  109. self, cr, uid, dummy_obj, name, args, context=None):
  110. result = []
  111. for arg in args:
  112. if isinstance(arg, tuple) and arg[0] == name:
  113. result.append(
  114. (
  115. 'relation_all_ids.other_partner_id.category_id',
  116. arg[1],
  117. arg[2],
  118. ))
  119. return result
  120. _columns = {
  121. 'relation_ids': fields.function(
  122. lambda self, *args, **kwargs: self._get_relation_ids(
  123. *args, **kwargs),
  124. fnct_inv=_set_relation_ids,
  125. type='one2many', obj='res.partner.relation',
  126. string='Relations',
  127. selectable=False,
  128. ),
  129. 'relation_all_ids': fields.one2many(
  130. 'res.partner.relation.all', 'this_partner_id',
  131. string='All relations with current partner',
  132. auto_join=True,
  133. selectable=False,
  134. ),
  135. 'search_relation_id': fields.function(
  136. lambda self, cr, uid, ids, *args: dict([
  137. (i, False) for i in ids]),
  138. fnct_search=_search_relation_id,
  139. string='Has relation of type',
  140. type='many2one', obj='res.partner.relation.type.selection'
  141. ),
  142. 'search_relation_partner_id': fields.function(
  143. lambda self, cr, uid, ids, *args: dict([
  144. (i, False) for i in ids]),
  145. fnct_search=_search_related_partner_id,
  146. string='Has relation with',
  147. type='many2one', obj='res.partner'
  148. ),
  149. 'search_relation_date': fields.function(
  150. lambda self, cr, uid, ids, *args: dict([
  151. (i, False) for i in ids]),
  152. fnct_search=_search_relation_date,
  153. string='Relation valid', type='date'
  154. ),
  155. 'search_relation_partner_category_id': fields.function(
  156. lambda self, cr, uid, ids, *args: dict([
  157. (i, False) for i in ids]),
  158. fnct_search=_search_related_partner_category_id,
  159. string='Has relation with a partner in category',
  160. type='many2one', obj='res.partner.category'
  161. ),
  162. }
  163. def copy_data(self, cr, uid, id, default=None, context=None):
  164. if default is None:
  165. default = {}
  166. default.setdefault('relation_ids', [])
  167. default.setdefault('relation_all_ids', [])
  168. return super(ResPartner, self).copy_data(cr, uid, id, default=default,
  169. context=context)
  170. def search(self, cr, uid, args, offset=0, limit=None, order=None,
  171. context=None, count=False):
  172. if context is None:
  173. context = {}
  174. # inject searching for current relation date if we search for relation
  175. # properties and no explicit date was given
  176. date_args = []
  177. for arg in args:
  178. if is_leaf(arg) and arg[0].startswith('search_relation'):
  179. if arg[0] == 'search_relation_date':
  180. date_args = []
  181. break
  182. if not date_args:
  183. date_args = [
  184. ('search_relation_date', '=', time.strftime(
  185. DEFAULT_SERVER_DATE_FORMAT))]
  186. # because of auto_join, we have to do the active test by hand
  187. active_args = []
  188. if context.get('active_test', True):
  189. for arg in args:
  190. if is_leaf(arg) and\
  191. arg[0].startswith('search_relation'):
  192. active_args = [('relation_all_ids.active', '=', True)]
  193. break
  194. return super(ResPartner, self).search(
  195. cr, uid, args + date_args + active_args, offset=offset,
  196. limit=limit, order=order, context=context, count=count)
  197. def read(
  198. self, cr, uid, ids, fields=None, context=None,
  199. load='_classic_read'):
  200. return super(ResPartner, self).read(
  201. cr, uid, ids, fields=fields,
  202. context=self._update_context(context, ids))
  203. def write(self, cr, uid, ids, vals, context=None):
  204. return super(ResPartner, self).write(
  205. cr, uid, ids, vals, context=self._update_context(context, ids))
  206. def _update_context(self, context, ids):
  207. if context is None:
  208. context = {}
  209. ids = ids if isinstance(ids, list) else [ids] if ids else []
  210. result = context.copy()
  211. result.setdefault('active_id', ids[0] if ids else None)
  212. result.setdefault('active_ids', ids)
  213. result.setdefault('active_model', self._name)
  214. return result