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.

280 lines
10 KiB

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