committed by
Holger Brunn
9 changed files with 565 additions and 411 deletions
-
3partner_relations/models/res_partner.py
-
25partner_relations/models/res_partner_relation.py
-
167partner_relations/models/res_partner_relation_all.py
-
93partner_relations/models/res_partner_relation_type.py
-
8partner_relations/tests/__init__.py
-
250partner_relations/tests/test_partner_relation.py
-
241partner_relations/tests/test_partner_relation_all.py
-
113partner_relations/tests/test_partner_relation_common.py
-
76partner_relations/tests/test_partner_search.py
@ -1 +1,7 @@ |
|||
from . import test_partner_relations |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright 2016 Therp BV |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
from . import test_partner_relation_common |
|||
from . import test_partner_relation |
|||
from . import test_partner_relation_all |
|||
from . import test_partner_search |
@ -0,0 +1,241 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright 2016 Therp BV |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
from openerp.exceptions import ValidationError |
|||
|
|||
from .test_partner_relation_common import TestPartnerRelationCommon |
|||
|
|||
|
|||
class TestPartnerRelation(TestPartnerRelationCommon): |
|||
|
|||
def setUp(self): |
|||
super(TestPartnerRelation, self).setUp() |
|||
|
|||
# Create a new relation type which will not have valid relations: |
|||
category_nobody = self.category_model.create({ |
|||
'name': 'Nobody', |
|||
}) |
|||
(self.type_nobody, |
|||
self.selection_nobody, |
|||
self.selection_nobody_inverse) = ( |
|||
self._create_relation_type_selection({ |
|||
'name': 'has relation with nobody', |
|||
'name_inverse': 'nobody has relation with', |
|||
'contact_type_left': 'c', |
|||
'contact_type_right': 'p', |
|||
'partner_category_left': category_nobody.id, |
|||
'partner_category_right': category_nobody.id, |
|||
}) |
|||
) |
|||
|
|||
def _get_empty_relation(self): |
|||
"""Get empty relation record for onchange tests.""" |
|||
# Need English, because we will compare text |
|||
return self.relation_all_model.with_context(lang='en_US').new({}) |
|||
|
|||
def test_create_with_active_id(self): |
|||
"""Test creation with this_partner_id from active_id.""" |
|||
# Check wether we can create connection from company to person, |
|||
# taking the particular company from the active records: |
|||
relation = self.relation_all_model.with_context( |
|||
active_id=self.partner_02_company.id, |
|||
active_ids=self.partner_02_company.ids, |
|||
).create({ |
|||
'other_partner_id': self.partner_01_person.id, |
|||
'type_selection_id': self.selection_company2person.id, |
|||
}) |
|||
self.assertTrue(relation) |
|||
self.assertEqual(relation.this_partner_id, self.partner_02_company) |
|||
# Partner should have one relation now: |
|||
self.assertEqual(self.partner_01_person.relation_count, 1) |
|||
|
|||
def test_display_name(self): |
|||
"""Test display name""" |
|||
relation = self._create_company2person_relation() |
|||
self.assertEqual( |
|||
relation.display_name, '%s %s %s' % ( |
|||
relation.this_partner_id.name, |
|||
relation.type_selection_id.name, |
|||
relation.other_partner_id.name, |
|||
) |
|||
) |
|||
|
|||
def test__regular_write(self): |
|||
"""Test write with valid data.""" |
|||
relation = self._create_company2person_relation() |
|||
relation.write({ |
|||
'date_start': '2014-09-01', |
|||
}) |
|||
relation.invalidate_cache(ids=relation.ids) |
|||
self.assertEqual(relation.date_start, '2014-09-01') |
|||
|
|||
def test_write_incompatible_dates(self): |
|||
"""Test write with date_end before date_start.""" |
|||
relation = self._create_company2person_relation() |
|||
with self.assertRaises(ValidationError): |
|||
relation.write({ |
|||
'date_start': '2016-09-01', |
|||
'date_end': '2016-08-01', |
|||
}) |
|||
|
|||
def test_validate_overlapping_01(self): |
|||
"""Test create overlapping with no start / end dates.""" |
|||
relation = self._create_company2person_relation() |
|||
with self.assertRaises(ValidationError): |
|||
# New relation with no start / end should give error |
|||
self.relation_all_model.create({ |
|||
'this_partner_id': relation.this_partner_id.id, |
|||
'type_selection_id': relation.type_selection_id.id, |
|||
'other_partner_id': relation.other_partner_id.id, |
|||
}) |
|||
|
|||
def test_validate_overlapping_02(self): |
|||
"""Test create overlapping with start / end dates.""" |
|||
relation = self.relation_all_model.create({ |
|||
'this_partner_id': self.partner_02_company.id, |
|||
'type_selection_id': self.selection_company2person.id, |
|||
'other_partner_id': self.partner_01_person.id, |
|||
'date_start': '2015-09-01', |
|||
'date_end': '2016-08-31', |
|||
}) |
|||
# New relation with overlapping start / end should give error |
|||
with self.assertRaises(ValidationError): |
|||
self.relation_all_model.create({ |
|||
'this_partner_id': relation.this_partner_id.id, |
|||
'type_selection_id': relation.type_selection_id.id, |
|||
'other_partner_id': relation.other_partner_id.id, |
|||
'date_start': '2016-08-01', |
|||
'date_end': '2017-07-30', |
|||
}) |
|||
|
|||
def test_validate_overlapping_03(self): |
|||
"""Test create not overlapping.""" |
|||
relation = self.relation_all_model.create({ |
|||
'this_partner_id': self.partner_02_company.id, |
|||
'type_selection_id': self.selection_company2person.id, |
|||
'other_partner_id': self.partner_01_person.id, |
|||
'date_start': '2015-09-01', |
|||
'date_end': '2016-08-31', |
|||
}) |
|||
relation_another_record = self.relation_all_model.create({ |
|||
'this_partner_id': relation.this_partner_id.id, |
|||
'type_selection_id': relation.type_selection_id.id, |
|||
'other_partner_id': relation.other_partner_id.id, |
|||
'date_start': '2016-09-01', |
|||
'date_end': '2017-08-31', |
|||
}) |
|||
self.assertTrue(relation_another_record) |
|||
|
|||
def test_inverse_record(self): |
|||
"""Test creation of inverse record.""" |
|||
relation = self._create_company2person_relation() |
|||
inverse_relation = self.relation_all_model.search([ |
|||
('this_partner_id', '=', relation.other_partner_id.id), |
|||
('other_partner_id', '=', relation.this_partner_id.id), |
|||
]) |
|||
self.assertEqual(len(inverse_relation), 1) |
|||
self.assertEqual( |
|||
inverse_relation.type_selection_id.name, |
|||
self.selection_person2company.name |
|||
) |
|||
|
|||
def test_inverse_creation(self): |
|||
"""Test creation of record through inverse selection.""" |
|||
relation = self.relation_all_model.create({ |
|||
'this_partner_id': self.partner_01_person.id, |
|||
'type_selection_id': self.selection_person2company.id, |
|||
'other_partner_id': self.partner_02_company.id, |
|||
}) |
|||
# Check wether display name is what we should expect: |
|||
self.assertEqual( |
|||
relation.display_name, '%s %s %s' % ( |
|||
self.partner_01_person.name, |
|||
self.selection_person2company.name, |
|||
self.partner_02_company.name, |
|||
) |
|||
) |
|||
|
|||
def test_unlink(self): |
|||
"""Unlinking derived relation should unlink base relation.""" |
|||
# Check wether underlying record is removed when record is removed: |
|||
relation = self._create_company2person_relation() |
|||
base_relation = relation.relation_id |
|||
relation.unlink() |
|||
self.assertFalse(base_relation.exists()) |
|||
|
|||
def test_on_change_type_selection(self): |
|||
"""Test on_change_type_selection.""" |
|||
# 1. Test call with empty relation |
|||
relation_empty = self._get_empty_relation() |
|||
result = relation_empty.onchange_type_selection_id() |
|||
self.assertTrue('domain' in result) |
|||
self.assertFalse('warning' in result) |
|||
self.assertTrue('this_partner_id' in result['domain']) |
|||
self.assertFalse(result['domain']['this_partner_id']) |
|||
self.assertTrue('other_partner_id' in result['domain']) |
|||
self.assertFalse(result['domain']['other_partner_id']) |
|||
# 2. Test call with company 2 person relation |
|||
relation = self._create_company2person_relation() |
|||
domain = relation.onchange_type_selection_id()['domain'] |
|||
self.assertTrue( |
|||
('is_company', '=', False) in domain['other_partner_id'] |
|||
) |
|||
# 3. Test with relation needing categories. |
|||
relation_ngo_volunteer = self.relation_all_model.create({ |
|||
'this_partner_id': self.partner_03_ngo.id, |
|||
'type_selection_id': self.selection_ngo2volunteer.id, |
|||
'other_partner_id': self.partner_04_volunteer.id, |
|||
}) |
|||
domain = relation_ngo_volunteer.onchange_type_selection_id()['domain'] |
|||
self.assertTrue( |
|||
('category_id', 'in', [self.category_01_ngo.id]) in |
|||
domain['this_partner_id'] |
|||
) |
|||
self.assertTrue( |
|||
('category_id', 'in', [self.category_02_volunteer.id]) in |
|||
domain['other_partner_id'] |
|||
) |
|||
# 4. Test with invalid or impossible combinations |
|||
relation_nobody = self._get_empty_relation() |
|||
with self.env.do_in_draft(): |
|||
relation_nobody.type_selection_id = self.selection_nobody |
|||
warning = relation_nobody.onchange_type_selection_id()['warning'] |
|||
self.assertTrue('message' in warning) |
|||
self.assertTrue('No this partner available' in warning['message']) |
|||
with self.env.do_in_draft(): |
|||
relation_nobody.this_partner_id = self.partner_02_company |
|||
warning = relation_nobody.onchange_type_selection_id()['warning'] |
|||
self.assertTrue('message' in warning) |
|||
self.assertTrue('incompatible' in warning['message']) |
|||
# Allow left partner and check message for other partner: |
|||
self.type_nobody.write({ |
|||
'partner_category_left': False, |
|||
}) |
|||
self.selection_nobody.invalidate_cache(ids=self.selection_nobody.ids) |
|||
warning = relation_nobody.onchange_type_selection_id()['warning'] |
|||
self.assertTrue('message' in warning) |
|||
self.assertTrue('No other partner available' in warning['message']) |
|||
|
|||
def test_on_change_partner_id(self): |
|||
"""Test on_change_partner_id.""" |
|||
# 1. Test call with empty relation |
|||
relation_empty = self._get_empty_relation() |
|||
result = relation_empty.onchange_partner_id() |
|||
self.assertTrue('domain' in result) |
|||
self.assertFalse('warning' in result) |
|||
self.assertTrue('type_selection_id' in result['domain']) |
|||
self.assertFalse(result['domain']['type_selection_id']) |
|||
# 2. Test call with company 2 person relation |
|||
relation = self._create_company2person_relation() |
|||
domain = relation.onchange_partner_id()['domain'] |
|||
self.assertTrue( |
|||
('contact_type_this', '=', 'c') in domain['type_selection_id'] |
|||
) |
|||
# 3. Test with invalid or impossible combinations |
|||
relation_nobody = self._get_empty_relation() |
|||
with self.env.do_in_draft(): |
|||
relation_nobody.this_partner_id = self.partner_02_company |
|||
relation_nobody.type_selection_id = self.selection_nobody |
|||
warning = relation_nobody.onchange_partner_id()['warning'] |
|||
self.assertTrue('message' in warning) |
|||
self.assertTrue('incompatible' in warning['message']) |
@ -0,0 +1,113 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright 2016 Therp BV |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
from openerp.tests import common |
|||
|
|||
|
|||
class TestPartnerRelationCommon(common.TransactionCase): |
|||
|
|||
def setUp(self): |
|||
super(TestPartnerRelationCommon, self).setUp() |
|||
|
|||
self.partner_model = self.env['res.partner'] |
|||
self.category_model = self.env['res.partner.category'] |
|||
self.type_model = self.env['res.partner.relation.type'] |
|||
self.selection_model = self.env['res.partner.relation.type.selection'] |
|||
self.relation_model = self.env['res.partner.relation'] |
|||
self.relation_all_model = self.env['res.partner.relation.all'] |
|||
self.partner_01_person = self.partner_model.create({ |
|||
'name': 'Test User 1', |
|||
'is_company': False, |
|||
'ref': 'PR01', |
|||
}) |
|||
self.partner_02_company = self.partner_model.create({ |
|||
'name': 'Test Company', |
|||
'is_company': True, |
|||
'ref': 'PR02', |
|||
}) |
|||
# Create partners with specific categories: |
|||
self.category_01_ngo = self.category_model.create({ |
|||
'name': 'NGO', |
|||
}) |
|||
self.partner_03_ngo = self.partner_model.create({ |
|||
'name': 'Test NGO', |
|||
'is_company': True, |
|||
'ref': 'PR03', |
|||
'category_id': [(4, self.category_01_ngo.id)], |
|||
}) |
|||
self.category_02_volunteer = self.category_model.create({ |
|||
'name': 'Volunteer', |
|||
}) |
|||
self.partner_04_volunteer = self.partner_model.create({ |
|||
'name': 'Test Volunteer', |
|||
'is_company': False, |
|||
'ref': 'PR04', |
|||
'category_id': [(4, self.category_02_volunteer.id)], |
|||
}) |
|||
# Create a new relation type withouth categories: |
|||
(self.type_company2person, |
|||
self.selection_company2person, |
|||
self.selection_person2company) = ( |
|||
self._create_relation_type_selection({ |
|||
'name': 'mixed', |
|||
'name_inverse': 'mixed_inverse', |
|||
'contact_type_left': 'c', |
|||
'contact_type_right': 'p', |
|||
}) |
|||
) |
|||
# Create a new relation type with categories: |
|||
(self.type_ngo2volunteer, |
|||
self.selection_ngo2volunteer, |
|||
self.selection_volunteer2ngo) = ( |
|||
self._create_relation_type_selection({ |
|||
'name': 'NGO has volunteer', |
|||
'name_inverse': 'volunteer works for NGO', |
|||
'contact_type_left': 'c', |
|||
'contact_type_right': 'p', |
|||
'partner_category_left': self.category_01_ngo.id, |
|||
'partner_category_right': self.category_02_volunteer.id, |
|||
}) |
|||
) |
|||
|
|||
def _create_relation_type_selection(self, vals): |
|||
"""Create relation type and return this with selection types.""" |
|||
assert 'name' in vals, ( |
|||
"Name missing in vals to create relation type. Vals: %s." |
|||
% vals |
|||
) |
|||
assert 'name' in vals, ( |
|||
"Name_inverse missing in vals to create relation type. Vals: %s." |
|||
% vals |
|||
) |
|||
new_type = self.type_model.create(vals) |
|||
self.assertTrue( |
|||
new_type, |
|||
msg="No relation type created with vals %s." % vals |
|||
) |
|||
selection_types = self.selection_model.search([ |
|||
('type_id', '=', new_type.id), |
|||
]) |
|||
for st in selection_types: |
|||
if st.is_inverse: |
|||
inverse_type_selection = st |
|||
else: |
|||
type_selection = st |
|||
self.assertTrue( |
|||
inverse_type_selection, |
|||
msg="Failed to find inverse type selection based on" |
|||
" relation type created with vals %s." % vals |
|||
) |
|||
self.assertTrue( |
|||
type_selection, |
|||
msg="Failed to find type selection based on" |
|||
" relation type created with vals %s." % vals |
|||
) |
|||
return (new_type, type_selection, inverse_type_selection) |
|||
|
|||
def _create_company2person_relation(self): |
|||
"""Utility function to get a relation from company 2 partner.""" |
|||
return self.relation_all_model.create({ |
|||
'type_selection_id': self.selection_company2person.id, |
|||
'this_partner_id': self.partner_02_company.id, |
|||
'other_partner_id': self.partner_01_person.id, |
|||
}) |
@ -0,0 +1,76 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright 2015 Camptocamp SA |
|||
# Copyright 2016 Therp BV |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
from openerp import fields |
|||
from openerp.exceptions import ValidationError |
|||
|
|||
from .test_partner_relation_common import TestPartnerRelationCommon |
|||
|
|||
|
|||
class TestPartnerSearch(TestPartnerRelationCommon): |
|||
|
|||
def test_search_relation_type(self): |
|||
"""Test searching on relation type.""" |
|||
relation = self._create_company2person_relation() |
|||
partners = self.partner_model.search([ |
|||
('search_relation_type_id', '=', relation.type_selection_id.id) |
|||
]) |
|||
self.assertTrue(self.partner_02_company in partners) |
|||
partners = self.partner_model.search([ |
|||
('search_relation_type_id', '!=', relation.type_selection_id.id) |
|||
]) |
|||
self.assertTrue(self.partner_01_person in partners) |
|||
partners = self.partner_model.search([ |
|||
('search_relation_type_id', '=', self.type_company2person.name) |
|||
]) |
|||
self.assertTrue(self.partner_01_person in partners) |
|||
self.assertTrue(self.partner_02_company in partners) |
|||
partners = self.partner_model.search([ |
|||
('search_relation_type_id', '=', 'unknown relation') |
|||
]) |
|||
self.assertFalse(partners) |
|||
# Check error with invalid search operator: |
|||
with self.assertRaises(ValidationError): |
|||
partners = self.partner_model.search([ |
|||
('search_relation_type_id', 'child_of', 'some parent') |
|||
]) |
|||
|
|||
def test_search_relation_partner(self): |
|||
"""Test searching on related partner.""" |
|||
self._create_company2person_relation() |
|||
partners = self.partner_model.search([ |
|||
('search_relation_partner_id', '=', self.partner_02_company.id), |
|||
]) |
|||
self.assertTrue(self.partner_01_person in partners) |
|||
|
|||
def test_search_relation_date(self): |
|||
"""Test searching on relations valid on a certain date.""" |
|||
self._create_company2person_relation() |
|||
partners = self.partner_model.search([ |
|||
('search_relation_date', '=', fields.Date.today()), |
|||
]) |
|||
self.assertTrue(self.partner_01_person in partners) |
|||
self.assertTrue(self.partner_02_company in partners) |
|||
|
|||
def test_search_any_partner(self): |
|||
"""Test searching for partner left or right.""" |
|||
self._create_company2person_relation() |
|||
both_relations = self.relation_all_model.search([ |
|||
('any_partner_id', '=', self.partner_02_company.id), |
|||
]) |
|||
self.assertEqual(len(both_relations), 2) |
|||
|
|||
def test_search_partner_category(self): |
|||
"""Test searching for partners related to partners having category.""" |
|||
relation_ngo_volunteer = self.relation_all_model.create({ |
|||
'this_partner_id': self.partner_03_ngo.id, |
|||
'type_selection_id': self.selection_ngo2volunteer.id, |
|||
'other_partner_id': self.partner_04_volunteer.id, |
|||
}) |
|||
self.assertTrue(relation_ngo_volunteer) |
|||
partners = self.partner_model.search([ |
|||
('search_relation_partner_category_id', '=', |
|||
self.category_02_volunteer.id) |
|||
]) |
|||
self.assertTrue(self.partner_03_ngo in partners) |
Write
Preview
Loading…
Cancel
Save
Reference in new issue