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.

217 lines
9.7 KiB

  1. # -*- coding: utf-8 -*-
  2. # Copyright 2014-2017 Therp BV <https://therp.nl>
  3. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
  4. from lxml import etree
  5. from odoo.exceptions import ValidationError
  6. from odoo.tests import common
  7. class FakeTab():
  8. def __init__(self, id, name):
  9. self.id = id
  10. self.name = name
  11. class TestPartnerTabs(common.SingleTransactionCase):
  12. post_install = True
  13. def test_create_tab(self):
  14. tab_model = self.env['res.partner.tab']
  15. partner_model = self.env['res.partner']
  16. new_tab = tab_model.create({
  17. 'code': 'executive',
  18. 'name': 'Executive members',
  19. 'contact_type': 'c'})
  20. self.assertTrue(bool(new_tab))
  21. # There should now be a field in res_partner for the new tab.
  22. fieldname = partner_model._get_tab_fieldname(new_tab)
  23. self.assertTrue(fieldname in partner_model._fields)
  24. # The form view for partner should now also contain the tab,
  25. # if the view contains tabs in the first place.
  26. view_partner_form = self.env.ref('base.view_partner_form')
  27. view = partner_model.with_context().fields_view_get(
  28. view_id=view_partner_form.id, view_type='form')
  29. tree = etree.fromstring(view['arch'])
  30. field = tree.xpath('//field[@name="id"]')
  31. self.assertTrue(field, 'Id field does not exist.')
  32. # And we should have a field for the tab:
  33. field = tree.xpath('//field[@name="%s"]' % fieldname)
  34. self.assertTrue(
  35. field,
  36. 'Tab field %s does not exist in %s.' %
  37. (fieldname, etree.tostring(tree)))
  38. # There should be no effect on the tree view:
  39. view = partner_model.with_context().fields_view_get(view_type='tree')
  40. tree = etree.fromstring(view['arch'])
  41. field = tree.xpath('//field[@name="%s"]' % fieldname)
  42. self.assertFalse(
  43. field,
  44. 'Tab field %s should not exist in %s.' %
  45. (fieldname, etree.tostring(tree)))
  46. def test_tab_modifications(self):
  47. category_model = self.env['res.partner.category']
  48. tab_model = self.env['res.partner.tab']
  49. type_model = self.env['res.partner.relation.type']
  50. category_government = category_model.create({'name': 'Government'})
  51. executive_tab = tab_model.create({
  52. 'code': 'executive',
  53. 'name': 'Executive members'})
  54. self.assertTrue(bool(executive_tab))
  55. type_has_chairperson = type_model.create({
  56. 'name': 'has chairperson',
  57. 'name_inverse': 'is chairperson for',
  58. 'contact_type_right': 'p',
  59. 'tab_left_id': executive_tab.id})
  60. self.assertTrue(bool(type_has_chairperson))
  61. # If we change tab now to be only valid on company partners
  62. # the tab_left_id field should be cleared from the type:
  63. executive_tab.write({
  64. 'contact_type': 'c',
  65. 'partner_category_id': category_government.id})
  66. self.assertFalse(type_has_chairperson.tab_left_id.id)
  67. # Trying to set the tab back on type should be impossible:
  68. with self.assertRaises(ValidationError):
  69. type_has_chairperson.write({'tab_left_id': executive_tab.id})
  70. # We should be able to change tab, if also changing contact type
  71. # and category:
  72. type_has_chairperson.write({
  73. 'partner_category_left': category_government.id,
  74. 'contact_type_left': 'c',
  75. 'tab_left_id': executive_tab.id})
  76. self.assertEqual(
  77. type_has_chairperson.tab_left_id.id,
  78. executive_tab.id)
  79. # Unlinking the tab should reset the tab name on relations:
  80. executive_tab.unlink()
  81. self.assertEqual(
  82. type_has_chairperson.tab_left_id.id,
  83. False)
  84. def test_relation_type_modifications(self):
  85. category_model = self.env['res.partner.category']
  86. tab_model = self.env['res.partner.tab']
  87. type_model = self.env['res.partner.relation.type']
  88. category_government = category_model.create({'name': 'Government'})
  89. category_positions = category_model.create({'name': 'Positions'})
  90. executive_tab = tab_model.create({
  91. 'code': 'executive',
  92. 'name': 'Executive members',
  93. 'contact_type': 'c',
  94. 'partner_category_id': category_government.id})
  95. self.assertTrue(bool(executive_tab))
  96. positions_tab = tab_model.create({
  97. 'code': 'positions',
  98. 'name': 'Positions held',
  99. 'contact_type': 'p',
  100. 'partner_category_id': category_positions.id})
  101. self.assertTrue(bool(executive_tab))
  102. type_has_chairperson = type_model.create({
  103. 'name': 'has chairperson',
  104. 'name_inverse': 'is chairperson for',
  105. 'partner_category_left': category_government.id,
  106. 'contact_type_left': 'c',
  107. 'tab_left_id': executive_tab.id,
  108. 'partner_category_right': category_positions.id,
  109. 'contact_type_right': 'p',
  110. 'tab_right_id': positions_tab.id})
  111. self.assertTrue(bool(type_has_chairperson))
  112. # Trying to clear either category should raise ValidationError:
  113. with self.assertRaises(ValidationError):
  114. type_has_chairperson.write({'partner_category_left': False})
  115. with self.assertRaises(ValidationError):
  116. type_has_chairperson.write({'partner_category_right': False})
  117. # Trying to clear either contact type should raise ValidationError:
  118. with self.assertRaises(ValidationError):
  119. type_has_chairperson.write({'contact_type_left': False})
  120. with self.assertRaises(ValidationError):
  121. type_has_chairperson.write({'contact_type_right': False})
  122. def test_relations(self):
  123. """Test relations shown on tab."""
  124. tab_model = self.env['res.partner.tab']
  125. type_model = self.env['res.partner.relation.type']
  126. partner_model = self.env['res.partner']
  127. relation_model = self.env['res.partner.relation']
  128. relation_all_model = self.env['res.partner.relation.all']
  129. executive_tab = tab_model.create({
  130. 'code': 'executive',
  131. 'name': 'Executive members'})
  132. self.assertTrue(bool(executive_tab))
  133. type_has_chairperson = type_model.create({
  134. 'name': 'has chairperson',
  135. 'name_inverse': 'is chairperson for',
  136. 'contact_type_right': 'p',
  137. 'tab_left_id': executive_tab.id})
  138. self.assertTrue(bool(type_has_chairperson))
  139. big_company = partner_model.create({
  140. 'name': 'Big company',
  141. 'is_company': True,
  142. 'ref': 'BIG'})
  143. self.assertTrue(bool(big_company))
  144. important_person = partner_model.create({
  145. 'name': 'Bart Simpson',
  146. 'is_company': False,
  147. 'ref': 'BS'})
  148. self.assertTrue(bool(important_person))
  149. relation_company_chair = relation_model.create({
  150. 'left_partner_id': big_company.id,
  151. 'type_id': type_has_chairperson.id,
  152. 'right_partner_id': important_person.id})
  153. self.assertTrue(bool(relation_company_chair))
  154. # Now we should be able to find the relation with the tab_id:
  155. relation_all_company_chair = relation_all_model.search([
  156. ('tab_id', '=', executive_tab.id)], limit=1)
  157. self.assertTrue(bool(relation_all_company_chair))
  158. self.assertEqual(
  159. relation_company_chair.left_partner_id.id,
  160. relation_all_company_chair.this_partner_id.id)
  161. # We should find the company on the partner through tab field:
  162. fieldname = partner_model._get_tab_fieldname(executive_tab)
  163. self.assertTrue(fieldname in partner_model._fields)
  164. executive_partners = big_company[fieldname]
  165. self.assertEqual(len(executive_partners), 1)
  166. self.assertEqual(
  167. executive_partners.other_partner_id.id,
  168. important_person.id)
  169. # When adding a new relation on a tab, type must be for tab.
  170. onchange_result = executive_partners.with_context(
  171. default_tab_id=executive_tab.id
  172. ).onchange_partner_id()
  173. self.assertTrue(onchange_result)
  174. self.assertIn('domain', onchange_result)
  175. self.assertIn('type_selection_id', onchange_result['domain'])
  176. self.assertEqual(
  177. onchange_result['domain']['type_selection_id'][-1],
  178. ('tab_id', '=', executive_tab.id))
  179. def test_update_tabs(self):
  180. """Test the function that will create tabs during module loading."""
  181. tab_model = self.env['res.partner.tab']
  182. partner_model = self.env['res.partner']
  183. executive_tab = tab_model.create({
  184. 'code': 'executive',
  185. 'name': 'Executive members'})
  186. self.assertTrue(bool(executive_tab))
  187. tabfield_executive_name = partner_model._get_tab_fieldname(
  188. executive_tab)
  189. # Create some fake tab fields (should be removed).
  190. tab_123 = FakeTab(123, 'First tab')
  191. tab_456 = FakeTab(456, 'Second tab')
  192. # Add "tab fields"
  193. partner_model._add_tab_field(tab_123)
  194. tabfield_123_name = partner_model._get_tab_fieldname(tab_123)
  195. self.assertEqual(
  196. partner_model._fields[tabfield_123_name].string, tab_123.name)
  197. partner_model._add_tab_field(tab_456)
  198. tabfield_456_name = partner_model._get_tab_fieldname(tab_456)
  199. self.assertEqual(
  200. partner_model._fields[tabfield_456_name].string, tab_456.name)
  201. # Now call hook method
  202. partner_model._register_hook()
  203. self.assertFalse(tabfield_123_name in partner_model._fields)
  204. self.assertFalse(tabfield_456_name in partner_model._fields)
  205. self.assertTrue(tabfield_executive_name in partner_model._fields)