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.

333 lines
14 KiB

  1. # Copyright 2016-2017 Therp BV
  2. # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
  3. from datetime import date
  4. from odoo.exceptions import ValidationError
  5. from .test_partner_relation_common import TestPartnerRelationCommon
  6. class TestPartnerRelation(TestPartnerRelationCommon):
  7. def setUp(self):
  8. super(TestPartnerRelation, self).setUp()
  9. # Create a new relation type which will not have valid relations:
  10. category_nobody = self.category_model.create({"name": "Nobody"})
  11. (
  12. self.type_nobody,
  13. self.selection_nobody,
  14. self.selection_nobody_inverse,
  15. ) = self._create_relation_type_selection(
  16. {
  17. "name": "has relation with nobody",
  18. "name_inverse": "nobody has relation with",
  19. "contact_type_left": "c",
  20. "contact_type_right": "p",
  21. "partner_category_left": category_nobody.id,
  22. "partner_category_right": category_nobody.id,
  23. }
  24. )
  25. def _get_empty_relation(self):
  26. """Get empty relation record for onchange tests."""
  27. # Need English, because we will compare text
  28. return self.relation_all_model.with_context(lang="en_US").new({})
  29. def test_get_partner_types(self):
  30. """Partner types should contain at least 'c' and 'p'."""
  31. partner_types = self.selection_model.get_partner_types()
  32. type_codes = [ptype[0] for ptype in partner_types]
  33. self.assertTrue("c" in type_codes)
  34. self.assertTrue("p" in type_codes)
  35. def test_create_with_active_id(self):
  36. """Test creation with this_partner_id from active_id."""
  37. # Check wether we can create connection from company to person,
  38. # taking the particular company from the active records:
  39. relation = self.relation_all_model.with_context(
  40. active_id=self.partner_02_company.id, active_ids=self.partner_02_company.ids
  41. ).create(
  42. {
  43. "other_partner_id": self.partner_01_person.id,
  44. "type_selection_id": self.selection_company2person.id,
  45. }
  46. )
  47. self.assertTrue(relation)
  48. self.assertEqual(relation.this_partner_id, self.partner_02_company)
  49. # Partner should have one relation now:
  50. relation.invalidate_cache(None, relation.ids)
  51. self.partner_01_person.flush()
  52. self.assertEqual(self.partner_01_person.relation_count, 1)
  53. # Test create without type_selection_id:
  54. with self.assertRaises(ValidationError):
  55. self.relation_all_model.create(
  56. {
  57. "this_partner_id": self.partner_02_company.id,
  58. "other_partner_id": self.partner_01_person.id,
  59. }
  60. )
  61. def test_display_name(self):
  62. """Test display name"""
  63. relation = self._create_company2person_relation()
  64. self.assertEqual(
  65. relation.display_name,
  66. "%s %s %s"
  67. % (
  68. relation.this_partner_id.name,
  69. relation.type_selection_id.name,
  70. relation.other_partner_id.name,
  71. ),
  72. )
  73. def test_regular_write(self):
  74. """Test write with valid data."""
  75. relation = self._create_company2person_relation()
  76. relation.write({"date_start": "2014-09-01"})
  77. self.assertEqual(relation.date_start, date(2014, 9, 1))
  78. def test_write_incompatible_dates(self):
  79. """Test write with date_end before date_start."""
  80. relation = self._create_company2person_relation()
  81. with self.assertRaises(ValidationError):
  82. relation.write({"date_start": "2016-09-01", "date_end": "2016-08-01"})
  83. def test_validate_overlapping_01(self):
  84. """Test create overlapping with no start / end dates."""
  85. relation = self._create_company2person_relation()
  86. with self.assertRaises(ValidationError):
  87. # New relation with no start / end should give error
  88. self.relation_all_model.create(
  89. {
  90. "this_partner_id": relation.this_partner_id.id,
  91. "type_selection_id": relation.type_selection_id.id,
  92. "other_partner_id": relation.other_partner_id.id,
  93. }
  94. )
  95. def test_validate_overlapping_02(self):
  96. """Test create overlapping with start / end dates."""
  97. relation = self.relation_all_model.create(
  98. {
  99. "this_partner_id": self.partner_02_company.id,
  100. "type_selection_id": self.selection_company2person.id,
  101. "other_partner_id": self.partner_01_person.id,
  102. "date_start": "2015-09-01",
  103. "date_end": "2016-08-31",
  104. }
  105. )
  106. # New relation with overlapping start / end should give error
  107. with self.assertRaises(ValidationError):
  108. self.relation_all_model.create(
  109. {
  110. "this_partner_id": relation.this_partner_id.id,
  111. "type_selection_id": relation.type_selection_id.id,
  112. "other_partner_id": relation.other_partner_id.id,
  113. "date_start": "2016-08-01",
  114. "date_end": "2017-07-30",
  115. }
  116. )
  117. def test_validate_overlapping_03(self):
  118. """Test create not overlapping."""
  119. relation = self.relation_all_model.create(
  120. {
  121. "this_partner_id": self.partner_02_company.id,
  122. "type_selection_id": self.selection_company2person.id,
  123. "other_partner_id": self.partner_01_person.id,
  124. "date_start": "2015-09-01",
  125. "date_end": "2016-08-31",
  126. }
  127. )
  128. relation_another_record = self.relation_all_model.create(
  129. {
  130. "this_partner_id": relation.this_partner_id.id,
  131. "type_selection_id": relation.type_selection_id.id,
  132. "other_partner_id": relation.other_partner_id.id,
  133. "date_start": "2016-09-01",
  134. "date_end": "2017-08-31",
  135. }
  136. )
  137. self.assertTrue(relation_another_record)
  138. def test_inverse_record(self):
  139. """Test creation of inverse record."""
  140. relation = self._create_company2person_relation()
  141. inverse_relation = self.relation_all_model.search(
  142. [
  143. ("this_partner_id", "=", relation.other_partner_id.id),
  144. ("other_partner_id", "=", relation.this_partner_id.id),
  145. ]
  146. )
  147. self.assertEqual(len(inverse_relation), 1)
  148. self.assertEqual(
  149. inverse_relation.type_selection_id.name, self.selection_person2company.name
  150. )
  151. def test_inverse_creation(self):
  152. """Test creation of record through inverse selection."""
  153. relation = self.relation_all_model.create(
  154. {
  155. "this_partner_id": self.partner_01_person.id,
  156. "type_selection_id": self.selection_person2company.id,
  157. "other_partner_id": self.partner_02_company.id,
  158. }
  159. )
  160. # Check wether display name is what we should expect:
  161. self.assertEqual(
  162. relation.display_name,
  163. "%s %s %s"
  164. % (
  165. self.partner_01_person.name,
  166. self.selection_person2company.name,
  167. self.partner_02_company.name,
  168. ),
  169. )
  170. def test_inverse_creation_type_id(self):
  171. """Test creation of record through inverse selection with type_id."""
  172. relation = self.relation_all_model.create(
  173. {
  174. "this_partner_id": self.partner_01_person.id,
  175. "type_id": self.selection_person2company.type_id.id,
  176. "is_inverse": True,
  177. "other_partner_id": self.partner_02_company.id,
  178. }
  179. )
  180. # Check wether display name is what we should expect:
  181. self.assertEqual(
  182. relation.display_name,
  183. "%s %s %s"
  184. % (
  185. self.partner_01_person.name,
  186. self.selection_person2company.name,
  187. self.partner_02_company.name,
  188. ),
  189. )
  190. def test_unlink(self):
  191. """Unlinking derived relation should unlink base relation."""
  192. # Check wether underlying record is removed when record is removed:
  193. relation = self._create_company2person_relation()
  194. base_model = self.env[relation.res_model]
  195. base_relation = base_model.browse([relation.res_id])
  196. relation.unlink()
  197. self.assertFalse(base_relation.exists())
  198. # Check unlinking record sets with both derived relation records
  199. self.assertTrue(self.relation_all_model.search([]).unlink())
  200. def test_on_change_type_selection(self):
  201. """Test on_change_type_selection."""
  202. # 1. Test call with empty relation
  203. relation_empty = self._get_empty_relation()
  204. result = relation_empty.onchange_type_selection_id()
  205. self.assertTrue("domain" in result)
  206. self.assertFalse("warning" in result)
  207. self.assertTrue("this_partner_id" in result["domain"])
  208. self.assertFalse(result["domain"]["this_partner_id"])
  209. self.assertTrue("other_partner_id" in result["domain"])
  210. self.assertFalse(result["domain"]["other_partner_id"])
  211. # 2. Test call with company 2 person relation
  212. relation = self._create_company2person_relation()
  213. domain = relation.onchange_type_selection_id()["domain"]
  214. self.assertTrue(("is_company", "=", False) in domain["other_partner_id"])
  215. # 3. Test with relation needing categories,
  216. # take active partner from active_id:
  217. relation_ngo_volunteer = self.relation_all_model.with_context(
  218. active_id=self.partner_03_ngo.id
  219. ).create(
  220. {
  221. "type_selection_id": self.selection_ngo2volunteer.id,
  222. "other_partner_id": self.partner_04_volunteer.id,
  223. }
  224. )
  225. domain = relation_ngo_volunteer.onchange_type_selection_id()["domain"]
  226. self.assertTrue(
  227. ("category_id", "in", [self.category_01_ngo.id])
  228. in domain["this_partner_id"]
  229. )
  230. self.assertTrue(
  231. ("category_id", "in", [self.category_02_volunteer.id])
  232. in domain["other_partner_id"]
  233. )
  234. # 4. Test with invalid or impossible combinations
  235. relation_nobody = self._get_empty_relation()
  236. relation_nobody.type_selection_id = self.selection_nobody
  237. warning = relation_nobody.onchange_type_selection_id()["warning"]
  238. self.assertTrue("message" in warning)
  239. self.assertTrue("No this partner available" in warning["message"])
  240. relation_nobody.this_partner_id = self.partner_02_company
  241. warning = relation_nobody.onchange_type_selection_id()["warning"]
  242. self.assertTrue("message" in warning)
  243. self.assertTrue("incompatible" in warning["message"])
  244. # Allow left partner and check message for other partner:
  245. self.type_nobody.write({"partner_category_left": False})
  246. self.type_nobody.flush()
  247. self.selection_nobody.invalidate_cache(ids=self.selection_nobody.ids)
  248. warning = relation_nobody.onchange_type_selection_id()["warning"]
  249. self.assertTrue("message" in warning)
  250. self.assertTrue("No other partner available" in warning["message"])
  251. def test_on_change_partner_id(self):
  252. """Test on_change_partner_id."""
  253. # 1. Test call with empty relation
  254. relation_empty = self._get_empty_relation()
  255. result = relation_empty.onchange_partner_id()
  256. self.assertTrue("domain" in result)
  257. self.assertFalse("warning" in result)
  258. self.assertTrue("type_selection_id" in result["domain"])
  259. self.assertFalse(result["domain"]["type_selection_id"])
  260. # 2. Test call with company 2 person relation
  261. relation = self._create_company2person_relation()
  262. domain = relation.onchange_partner_id()["domain"]
  263. self.assertTrue(("contact_type_this", "=", "c") in domain["type_selection_id"])
  264. # 3. Test with invalid or impossible combinations
  265. relation_nobody = self._get_empty_relation()
  266. relation_nobody.this_partner_id = self.partner_02_company
  267. relation_nobody.type_selection_id = self.selection_nobody
  268. warning = relation_nobody.onchange_partner_id()["warning"]
  269. self.assertTrue("message" in warning)
  270. self.assertTrue("incompatible" in warning["message"])
  271. def test_write(self):
  272. """Test write. Special attention for changing type."""
  273. relation_company2person = self._create_company2person_relation()
  274. company_partner = relation_company2person.this_partner_id
  275. # First get another worker:
  276. partner_extra_person = self.partner_model.create(
  277. {"name": "A new worker", "is_company": False, "ref": "NW01"}
  278. )
  279. relation_company2person.write({"other_partner_id": partner_extra_person.id})
  280. self.assertEqual(
  281. relation_company2person.other_partner_id.name, partner_extra_person.name
  282. )
  283. # We will also change to a type going from person to company:
  284. (
  285. type_worker2company,
  286. selection_worker2company,
  287. selection_company2worker,
  288. ) = self._create_relation_type_selection(
  289. {
  290. "name": "works for",
  291. "name_inverse": "has worker",
  292. "contact_type_left": "p",
  293. "contact_type_right": "c",
  294. }
  295. )
  296. relation_company2person.write(
  297. {
  298. "this_partner_id": partner_extra_person.id,
  299. "type_selection_id": selection_worker2company.id,
  300. "other_partner_id": company_partner.id,
  301. }
  302. )
  303. self.assertEqual(
  304. relation_company2person.this_partner_id.id, partner_extra_person.id
  305. )
  306. self.assertEqual(
  307. relation_company2person.type_selection_id.id, selection_worker2company.id
  308. )
  309. self.assertEqual(
  310. relation_company2person.other_partner_id.id, company_partner.id
  311. )