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.

261 lines
11 KiB

  1. # Copyright 2016-2017 Therp BV
  2. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
  3. from datetime import date
  4. from dateutil.relativedelta import relativedelta
  5. from openerp import fields
  6. from openerp.exceptions import ValidationError
  7. from .test_partner_relation_common import TestPartnerRelationCommon
  8. class TestPartnerRelation(TestPartnerRelationCommon):
  9. post_install = True
  10. def test_selection_name_search(self):
  11. """Test wether we can find type selection on reverse name."""
  12. selection_types = self.selection_model.name_search(
  13. name=self.selection_person2company.name)
  14. self.assertTrue(selection_types)
  15. self.assertTrue(
  16. (self.selection_person2company.id,
  17. self.selection_person2company.name) in selection_types)
  18. def test_self_allowed(self):
  19. """Test creation of relation to same partner when type allows."""
  20. type_allow = self.type_model.create({
  21. 'name': 'allow',
  22. 'name_inverse': 'allow_inverse',
  23. 'contact_type_left': 'p',
  24. 'contact_type_right': 'p',
  25. 'allow_self': True})
  26. self.assertTrue(type_allow)
  27. reflexive_relation = self.relation_model.create({
  28. 'type_id': type_allow.id,
  29. 'left_partner_id': self.partner_01_person.id,
  30. 'right_partner_id': self.partner_01_person.id})
  31. self.assertTrue(reflexive_relation)
  32. def test_self_disallowed(self):
  33. """Test creating relation to same partner when disallowed.
  34. Attempt to create a relation of a partner to the same partner should
  35. raise an error when the type of relation explicitly disallows this.
  36. """
  37. type_disallow = self.type_model.create({
  38. 'name': 'disallow',
  39. 'name_inverse': 'disallow_inverse',
  40. 'contact_type_left': 'p',
  41. 'contact_type_right': 'p',
  42. 'allow_self': False})
  43. self.assertTrue(type_disallow)
  44. with self.assertRaises(ValidationError):
  45. self.relation_model.create({
  46. 'type_id': type_disallow.id,
  47. 'left_partner_id': self.partner_01_person.id,
  48. 'right_partner_id': self.partner_01_person.id})
  49. def test_self_default(self):
  50. """Test default not to allow relation with same partner.
  51. Attempt to create a relation of a partner to the same partner
  52. raise an error when the type of relation does not explicitly allow
  53. this.
  54. """
  55. type_default = self.type_model.create({
  56. 'name': 'default',
  57. 'name_inverse': 'default_inverse',
  58. 'contact_type_left': 'p',
  59. 'contact_type_right': 'p'})
  60. self.assertTrue(type_default)
  61. with self.assertRaises(ValidationError):
  62. self.relation_model.create({
  63. 'type_id': type_default.id,
  64. 'left_partner_id': self.partner_01_person.id,
  65. 'right_partner_id': self.partner_01_person.id})
  66. def test_self_mixed(self):
  67. """Test creation of relation with wrong types.
  68. Trying to create a relation between partners with an inappropiate
  69. type should raise an error.
  70. """
  71. with self.assertRaises(ValidationError):
  72. self.relation_model.create({
  73. 'type_id': self.type_company2person.id,
  74. 'left_partner_id': self.partner_01_person.id,
  75. 'right_partner_id': self.partner_02_company.id})
  76. def test_symmetric(self):
  77. """Test creating symmetric relation."""
  78. # Start out with non symmetric relation:
  79. type_symmetric = self.type_model.create({
  80. 'name': 'not yet symmetric',
  81. 'name_inverse': 'the other side of not symmetric',
  82. 'is_symmetric': False,
  83. 'contact_type_left': False,
  84. 'contact_type_right': 'p'})
  85. # not yet symmetric relation should result in two records in
  86. # selection:
  87. selection_symmetric = self.selection_model.search([
  88. ('type_id', '=', type_symmetric.id)])
  89. self.assertEqual(len(selection_symmetric), 2)
  90. # Now change to symmetric and test name and inverse name:
  91. with self.env.do_in_draft():
  92. type_symmetric.write({
  93. 'name': 'sym',
  94. 'is_symmetric': True})
  95. self.assertEqual(type_symmetric.is_symmetric, True)
  96. self.assertEqual(
  97. type_symmetric.name_inverse,
  98. type_symmetric.name)
  99. self.assertEqual(
  100. type_symmetric.contact_type_right,
  101. type_symmetric.contact_type_left)
  102. # now update the database:
  103. type_symmetric.write({
  104. 'name': type_symmetric.name,
  105. 'is_symmetric': type_symmetric.is_symmetric,
  106. 'name_inverse': type_symmetric.name_inverse,
  107. 'contact_type_right': type_symmetric.contact_type_right})
  108. # symmetric relation should result in only one record in
  109. # selection:
  110. selection_symmetric = self.selection_model.search([
  111. ('type_id', '=', type_symmetric.id)])
  112. self.assertEqual(len(selection_symmetric), 1)
  113. relation = self.relation_all_model.create({
  114. 'type_selection_id': selection_symmetric.id,
  115. 'this_partner_id': self.partner_02_company.id,
  116. 'other_partner_id': self.partner_01_person.id})
  117. partners = self.partner_model.search([
  118. ('search_relation_type_id', '=', relation.type_selection_id.id)])
  119. self.assertTrue(self.partner_01_person in partners)
  120. self.assertTrue(self.partner_02_company in partners)
  121. def test_category_domain(self):
  122. """Test check on category in relations."""
  123. # Check on left side:
  124. with self.assertRaises(ValidationError):
  125. self.relation_model.create({
  126. 'type_id': self.type_ngo2volunteer.id,
  127. 'left_partner_id': self.partner_02_company.id,
  128. 'right_partner_id': self.partner_04_volunteer.id})
  129. # Check on right side:
  130. with self.assertRaises(ValidationError):
  131. self.relation_model.create({
  132. 'type_id': self.type_ngo2volunteer.id,
  133. 'left_partner_id': self.partner_03_ngo.id,
  134. 'right_partner_id': self.partner_01_person.id})
  135. def test_relation_type_change(self):
  136. """Test change in relation type conditions."""
  137. # First create a relation type having no particular conditions.
  138. (type_school2student,
  139. school2student,
  140. school2student_inverse) = \
  141. self._create_relation_type_selection({
  142. 'name': 'school has student',
  143. 'name_inverse': 'studies at school'})
  144. # Second create relations based on those conditions.
  145. partner_school = self.partner_model.create({
  146. 'name': 'Test School',
  147. 'is_company': True,
  148. 'ref': 'TS'})
  149. partner_bart = self.partner_model.create({
  150. 'name': 'Bart Simpson',
  151. 'is_company': False,
  152. 'ref': 'BS'})
  153. partner_lisa = self.partner_model.create({
  154. 'name': 'Lisa Simpson',
  155. 'is_company': False,
  156. 'ref': 'LS'})
  157. relation_school2bart = self.relation_all_model.create({
  158. 'this_partner_id': partner_school.id,
  159. 'type_selection_id': school2student.id,
  160. 'other_partner_id': partner_bart.id})
  161. self.assertTrue(relation_school2bart)
  162. relation_school2lisa = self.relation_all_model.create({
  163. 'this_partner_id': partner_school.id,
  164. 'type_selection_id': school2student.id,
  165. 'other_partner_id': partner_lisa.id})
  166. self.assertTrue(relation_school2lisa)
  167. relation_bart2lisa = self.relation_all_model.create({
  168. 'this_partner_id': partner_bart.id,
  169. 'type_selection_id': school2student.id,
  170. 'other_partner_id': partner_lisa.id})
  171. self.assertTrue(relation_bart2lisa)
  172. # Third creata a category and make it a condition for the
  173. # relation type.
  174. # - Test restriction
  175. # - Test ignore
  176. category_student = self.category_model.create({'name': 'Student'})
  177. with self.assertRaises(ValidationError):
  178. type_school2student.write({
  179. 'partner_category_right': category_student.id})
  180. self.assertFalse(type_school2student.partner_category_right.id)
  181. type_school2student.write({
  182. 'handle_invalid_onchange': 'ignore',
  183. 'partner_category_right': category_student.id})
  184. self.assertEqual(
  185. type_school2student.partner_category_right.id,
  186. category_student.id)
  187. # Fourth make company type a condition for left partner
  188. # - Test ending
  189. # - Test deletion
  190. partner_bart.write({
  191. 'category_id': [(4, category_student.id)]})
  192. partner_lisa.write({
  193. 'category_id': [(4, category_student.id)]})
  194. # Future student to be deleted by end action:
  195. partner_homer = self.partner_model.create({
  196. 'name': 'Homer Simpson',
  197. 'is_company': False,
  198. 'ref': 'HS',
  199. 'category_id': [(4, category_student.id)]})
  200. relation_lisa2homer = self.relation_all_model.create({
  201. 'this_partner_id': partner_lisa.id,
  202. 'type_selection_id': school2student.id,
  203. 'other_partner_id': partner_homer.id,
  204. 'date_start': fields.Date.to_string(
  205. date.today() + relativedelta(months=+6))})
  206. self.assertTrue(relation_lisa2homer)
  207. type_school2student.write({
  208. 'handle_invalid_onchange': 'end',
  209. 'contact_type_left': 'c'})
  210. self.assertEqual(
  211. relation_bart2lisa.date_end,
  212. fields.Date.today())
  213. self.assertFalse(relation_lisa2homer.exists())
  214. type_school2student.write({
  215. 'handle_invalid_onchange': 'delete',
  216. 'contact_type_left': 'c',
  217. 'contact_type_right': 'p'})
  218. self.assertFalse(relation_bart2lisa.exists())
  219. def test_relation_type_unlink(self):
  220. """Test delete of relation type, including deleting relations."""
  221. # First create a relation type having restrict particular conditions.
  222. type_model = self.env['res.partner.relation.type']
  223. relation_model = self.env['res.partner.relation']
  224. partner_model = self.env['res.partner']
  225. type_school2student = type_model.create({
  226. 'name': 'school has student',
  227. 'name_inverse': 'studies at school',
  228. 'handle_invalid_onchange': 'delete'})
  229. # Second create relation based on those conditions.
  230. partner_school = partner_model.create({
  231. 'name': 'Test School',
  232. 'is_company': True,
  233. 'ref': 'TS'})
  234. partner_bart = partner_model.create({
  235. 'name': 'Bart Simpson',
  236. 'is_company': False,
  237. 'ref': 'BS'})
  238. relation_school2bart = relation_model.create({
  239. 'left_partner_id': partner_school.id,
  240. 'type_id': type_school2student.id,
  241. 'right_partner_id': partner_bart.id})
  242. # Delete type. Relations with type should also cease to exist:
  243. type_school2student.unlink()
  244. self.assertFalse(relation_school2bart.exists())