odoo/openerp/addons/base/tests/test_base.py

381 lines
24 KiB
Python
Raw Normal View History

import unittest2
import openerp.tests.common as common
from openerp.osv.orm import except_orm
class test_base(common.TransactionCase):
def setUp(self):
super(test_base,self).setUp()
self.res_partner = self.registry('res.partner')
self.res_users = self.registry('res.users')
# samples use effective TLDs from the Mozilla public suffix
# list at http://publicsuffix.org
self.samples = [
('"Raoul Grosbedon" <raoul@chirurgiens-dentistes.fr> ', 'Raoul Grosbedon', 'raoul@chirurgiens-dentistes.fr'),
('ryu+giga-Sushi@aizubange.fukushima.jp', '', 'ryu+giga-Sushi@aizubange.fukushima.jp'),
('Raoul chirurgiens-dentistes.fr', 'Raoul chirurgiens-dentistes.fr', ''),
(" Raoul O'hara <!@historicalsociety.museum>", "Raoul O'hara", '!@historicalsociety.museum')
]
def test_00_res_partner_name_create(self):
cr, uid = self.cr, self.uid
parse = self.res_partner._parse_partner_name
for text, name, mail in self.samples:
self.assertEqual((name,mail), parse(text), 'Partner name parsing failed')
partner_id, dummy = self.res_partner.name_create(cr, uid, text)
partner = self.res_partner.browse(cr, uid, partner_id)
self.assertEqual(name or mail, partner.name, 'Partner name incorrect')
self.assertEqual(mail or False, partner.email, 'Partner email incorrect')
def test_10_res_partner_find_or_create(self):
cr,uid = self.cr, self.uid
email = self.samples[0][0]
partner_id, dummy = self.res_partner.name_create(cr, uid, email)
found_id = self.res_partner.find_or_create(cr, uid, email)
self.assertEqual(partner_id, found_id, 'find_or_create failed')
new_id = self.res_partner.find_or_create(cr, uid, self.samples[1][0])
self.assertTrue(new_id > partner_id, 'find_or_create failed - should have created new one')
new_id2 = self.res_partner.find_or_create(cr, uid, self.samples[2][0])
self.assertTrue(new_id2 > new_id, 'find_or_create failed - should have created new one again')
def test_15_res_partner_name_search(self):
cr,uid = self.cr, self.uid
for name, active in [
('"A Raoul Grosbedon" <raoul@chirurgiens-dentistes.fr>', False),
('B Raoul chirurgiens-dentistes.fr', True),
("C Raoul O'hara <!@historicalsociety.museum>", True),
('ryu+giga-Sushi@aizubange.fukushima.jp', True),
]:
partner_id, dummy = self.res_partner.name_create(cr, uid, name, context={'default_active': active})
partners = self.res_partner.name_search(cr, uid, 'Raoul')
self.assertEqual(len(partners), 2, 'Incorrect search number result for name_search')
partners = self.res_partner.name_search(cr, uid, 'Raoul', limit=1)
self.assertEqual(len(partners), 1, 'Incorrect search number result for name_search with a limit')
self.assertEqual(partners[0][1], 'B Raoul chirurgiens-dentistes.fr', 'Incorrect partner returned, should be the first active')
[FIX] res.partner: autosync of commercial fields and address fields + correct views accordingly + basic tests * Commercial fields (bug 1160365) Fix autosync of accounting/invoicing-related fields on contacts, just as if they were actually modeled as fields.related to the parent commercial entity. This starts with the addition of the new functional field `commercial_id`, to locate the commercial entity for any partner. The commercial entity is defined as the first ancestor (starting at the partner itself) that is either marked `is_company` or has no parent. [This is Part A of the solution on bug 1160365]. Then, whenever a partner is created or modified: - if it is a commercial entity, the commercial fields are synced downstream to all its descendants, stopping at company boundaries. - if is is not a commercial entity, the commercial fields are synced from its parent commercial entity. The list of fields to sync is determined by calling the new res.partner method `_commercial_fields()` which can be easily extended by any module that adds commercial fields on res.partner. A utility method `open_commercial_entity()` was added to res.partner to make it easy to include a button for editing the parent commercial entity, to be displayed instead of now-hidden commercial fields. [This is part B of the solution on bug 1160365] The res.partner.address_get() method (used to find child partners of certain types, e.g. "invoice") was udpated to take the new "commercial entity" notion into account: it will now look for matches in children but also parents and siblings that are part of the same "commercial entity". The default partner `type` is now "contact" to reflect the new model ; "default" is inappropriate because it is a wildcard and would stop the type lookup early. [This composes parts C and D of the solution on bug 1160365] Note: This fix comes with a matching addons fix to implement module-specific extensions of part B, as well as part E of the solution. * Address fields (bug 1160425) Corrected autosync of address fields is also included in the same branch, because those two mechanisms are closely related and share some parts of the implementation. The `use_parent_address` field now defaults to False (except in the mini-kanban view of contacts on a partner form), and the autosync of address fields has been modified to only work downstream and never update a parent company if a child contact is modified. Instead, the address fields are now displayed readonly on contacts that use the parent address, with a button to edit the parent address (new method open_parent(), similar to open_commercial_entity() but opening the direct parent). To make the initial creation of a contact + company pair, a special case was added: when a new contact is created for a company that has no other contact and no address, the address of the contact is assumed to be that of the company so it is moved to the company, then the `use_parent_address` flag is enabled on the contact, and the `is_company` flag on the company. This covers a use case where contact and company are created on-the-fly when creating a new document. Many logical flaws in the autosync of address fields have been corrected and are now covered by unit tests. * Misc related fixes - checking `is_company` does not reset the parent_id field anymore, to allow for multi-level structures. The field is still hidden automatically because having an empty "Company" field on the form view of a company is quite suprising), but this UI behavior is easily customized; - the `email`, `phone`, `fax`, `mobile`, `lang`, etc. that were sometimes synced when changing parent company are now properly left alone; - the `use_parent_address` field is now always visible next to the parent_id field when a parent is set lp bug: https://launchpad.net/bugs/1160425 fixed lp bug: https://launchpad.net/bugs/1160365 fixed bzr revid: odo@openerp.com-20130408013742-tm8w0w0nmunanokk
2013-04-08 01:37:42 +00:00
def test_20_res_partner_address_sync(self):
cr, uid = self.cr, self.uid
ghoststep = self.res_partner.browse(cr, uid, self.res_partner.create(cr, uid,
{'name': 'GhostStep',
'is_company': True,
'street': 'Main Street, 10',
'phone': '123456789',
'email': 'info@ghoststep.com',
'vat': 'BE0477472701',
'type': 'default'}))
[FIX] res.partner: autosync of commercial fields and address fields + correct views accordingly + basic tests * Commercial fields (bug 1160365) Fix autosync of accounting/invoicing-related fields on contacts, just as if they were actually modeled as fields.related to the parent commercial entity. This starts with the addition of the new functional field `commercial_id`, to locate the commercial entity for any partner. The commercial entity is defined as the first ancestor (starting at the partner itself) that is either marked `is_company` or has no parent. [This is Part A of the solution on bug 1160365]. Then, whenever a partner is created or modified: - if it is a commercial entity, the commercial fields are synced downstream to all its descendants, stopping at company boundaries. - if is is not a commercial entity, the commercial fields are synced from its parent commercial entity. The list of fields to sync is determined by calling the new res.partner method `_commercial_fields()` which can be easily extended by any module that adds commercial fields on res.partner. A utility method `open_commercial_entity()` was added to res.partner to make it easy to include a button for editing the parent commercial entity, to be displayed instead of now-hidden commercial fields. [This is part B of the solution on bug 1160365] The res.partner.address_get() method (used to find child partners of certain types, e.g. "invoice") was udpated to take the new "commercial entity" notion into account: it will now look for matches in children but also parents and siblings that are part of the same "commercial entity". The default partner `type` is now "contact" to reflect the new model ; "default" is inappropriate because it is a wildcard and would stop the type lookup early. [This composes parts C and D of the solution on bug 1160365] Note: This fix comes with a matching addons fix to implement module-specific extensions of part B, as well as part E of the solution. * Address fields (bug 1160425) Corrected autosync of address fields is also included in the same branch, because those two mechanisms are closely related and share some parts of the implementation. The `use_parent_address` field now defaults to False (except in the mini-kanban view of contacts on a partner form), and the autosync of address fields has been modified to only work downstream and never update a parent company if a child contact is modified. Instead, the address fields are now displayed readonly on contacts that use the parent address, with a button to edit the parent address (new method open_parent(), similar to open_commercial_entity() but opening the direct parent). To make the initial creation of a contact + company pair, a special case was added: when a new contact is created for a company that has no other contact and no address, the address of the contact is assumed to be that of the company so it is moved to the company, then the `use_parent_address` flag is enabled on the contact, and the `is_company` flag on the company. This covers a use case where contact and company are created on-the-fly when creating a new document. Many logical flaws in the autosync of address fields have been corrected and are now covered by unit tests. * Misc related fixes - checking `is_company` does not reset the parent_id field anymore, to allow for multi-level structures. The field is still hidden automatically because having an empty "Company" field on the form view of a company is quite suprising), but this UI behavior is easily customized; - the `email`, `phone`, `fax`, `mobile`, `lang`, etc. that were sometimes synced when changing parent company are now properly left alone; - the `use_parent_address` field is now always visible next to the parent_id field when a parent is set lp bug: https://launchpad.net/bugs/1160425 fixed lp bug: https://launchpad.net/bugs/1160365 fixed bzr revid: odo@openerp.com-20130408013742-tm8w0w0nmunanokk
2013-04-08 01:37:42 +00:00
p1 = self.res_partner.browse(cr, uid, self.res_partner.name_create(cr, uid, 'Denis Bladesmith <denis.bladesmith@ghoststep.com>')[0])
self.assertEqual(p1.type, 'contact', 'Default type must be "contact"')
[FIX] res.partner: autosync of commercial fields and address fields + correct views accordingly + basic tests * Commercial fields (bug 1160365) Fix autosync of accounting/invoicing-related fields on contacts, just as if they were actually modeled as fields.related to the parent commercial entity. This starts with the addition of the new functional field `commercial_id`, to locate the commercial entity for any partner. The commercial entity is defined as the first ancestor (starting at the partner itself) that is either marked `is_company` or has no parent. [This is Part A of the solution on bug 1160365]. Then, whenever a partner is created or modified: - if it is a commercial entity, the commercial fields are synced downstream to all its descendants, stopping at company boundaries. - if is is not a commercial entity, the commercial fields are synced from its parent commercial entity. The list of fields to sync is determined by calling the new res.partner method `_commercial_fields()` which can be easily extended by any module that adds commercial fields on res.partner. A utility method `open_commercial_entity()` was added to res.partner to make it easy to include a button for editing the parent commercial entity, to be displayed instead of now-hidden commercial fields. [This is part B of the solution on bug 1160365] The res.partner.address_get() method (used to find child partners of certain types, e.g. "invoice") was udpated to take the new "commercial entity" notion into account: it will now look for matches in children but also parents and siblings that are part of the same "commercial entity". The default partner `type` is now "contact" to reflect the new model ; "default" is inappropriate because it is a wildcard and would stop the type lookup early. [This composes parts C and D of the solution on bug 1160365] Note: This fix comes with a matching addons fix to implement module-specific extensions of part B, as well as part E of the solution. * Address fields (bug 1160425) Corrected autosync of address fields is also included in the same branch, because those two mechanisms are closely related and share some parts of the implementation. The `use_parent_address` field now defaults to False (except in the mini-kanban view of contacts on a partner form), and the autosync of address fields has been modified to only work downstream and never update a parent company if a child contact is modified. Instead, the address fields are now displayed readonly on contacts that use the parent address, with a button to edit the parent address (new method open_parent(), similar to open_commercial_entity() but opening the direct parent). To make the initial creation of a contact + company pair, a special case was added: when a new contact is created for a company that has no other contact and no address, the address of the contact is assumed to be that of the company so it is moved to the company, then the `use_parent_address` flag is enabled on the contact, and the `is_company` flag on the company. This covers a use case where contact and company are created on-the-fly when creating a new document. Many logical flaws in the autosync of address fields have been corrected and are now covered by unit tests. * Misc related fixes - checking `is_company` does not reset the parent_id field anymore, to allow for multi-level structures. The field is still hidden automatically because having an empty "Company" field on the form view of a company is quite suprising), but this UI behavior is easily customized; - the `email`, `phone`, `fax`, `mobile`, `lang`, etc. that were sometimes synced when changing parent company are now properly left alone; - the `use_parent_address` field is now always visible next to the parent_id field when a parent is set lp bug: https://launchpad.net/bugs/1160425 fixed lp bug: https://launchpad.net/bugs/1160365 fixed bzr revid: odo@openerp.com-20130408013742-tm8w0w0nmunanokk
2013-04-08 01:37:42 +00:00
p1phone = '123456789#34'
p1.write({'phone': p1phone,
'parent_id': ghoststep.id,
'use_parent_address': True})
p1.refresh()
self.assertEqual(p1.street, ghoststep.street, 'Address fields must be synced')
self.assertEqual(p1.phone, p1phone, 'Phone should be preserved after address sync')
self.assertEqual(p1.type, 'contact', 'Type should be preserved after address sync')
[FIX] res.partner: autosync of commercial fields and address fields + correct views accordingly + basic tests * Commercial fields (bug 1160365) Fix autosync of accounting/invoicing-related fields on contacts, just as if they were actually modeled as fields.related to the parent commercial entity. This starts with the addition of the new functional field `commercial_id`, to locate the commercial entity for any partner. The commercial entity is defined as the first ancestor (starting at the partner itself) that is either marked `is_company` or has no parent. [This is Part A of the solution on bug 1160365]. Then, whenever a partner is created or modified: - if it is a commercial entity, the commercial fields are synced downstream to all its descendants, stopping at company boundaries. - if is is not a commercial entity, the commercial fields are synced from its parent commercial entity. The list of fields to sync is determined by calling the new res.partner method `_commercial_fields()` which can be easily extended by any module that adds commercial fields on res.partner. A utility method `open_commercial_entity()` was added to res.partner to make it easy to include a button for editing the parent commercial entity, to be displayed instead of now-hidden commercial fields. [This is part B of the solution on bug 1160365] The res.partner.address_get() method (used to find child partners of certain types, e.g. "invoice") was udpated to take the new "commercial entity" notion into account: it will now look for matches in children but also parents and siblings that are part of the same "commercial entity". The default partner `type` is now "contact" to reflect the new model ; "default" is inappropriate because it is a wildcard and would stop the type lookup early. [This composes parts C and D of the solution on bug 1160365] Note: This fix comes with a matching addons fix to implement module-specific extensions of part B, as well as part E of the solution. * Address fields (bug 1160425) Corrected autosync of address fields is also included in the same branch, because those two mechanisms are closely related and share some parts of the implementation. The `use_parent_address` field now defaults to False (except in the mini-kanban view of contacts on a partner form), and the autosync of address fields has been modified to only work downstream and never update a parent company if a child contact is modified. Instead, the address fields are now displayed readonly on contacts that use the parent address, with a button to edit the parent address (new method open_parent(), similar to open_commercial_entity() but opening the direct parent). To make the initial creation of a contact + company pair, a special case was added: when a new contact is created for a company that has no other contact and no address, the address of the contact is assumed to be that of the company so it is moved to the company, then the `use_parent_address` flag is enabled on the contact, and the `is_company` flag on the company. This covers a use case where contact and company are created on-the-fly when creating a new document. Many logical flaws in the autosync of address fields have been corrected and are now covered by unit tests. * Misc related fixes - checking `is_company` does not reset the parent_id field anymore, to allow for multi-level structures. The field is still hidden automatically because having an empty "Company" field on the form view of a company is quite suprising), but this UI behavior is easily customized; - the `email`, `phone`, `fax`, `mobile`, `lang`, etc. that were sometimes synced when changing parent company are now properly left alone; - the `use_parent_address` field is now always visible next to the parent_id field when a parent is set lp bug: https://launchpad.net/bugs/1160425 fixed lp bug: https://launchpad.net/bugs/1160365 fixed bzr revid: odo@openerp.com-20130408013742-tm8w0w0nmunanokk
2013-04-08 01:37:42 +00:00
self.assertEqual(p1.email, 'denis.bladesmith@ghoststep.com', 'Email should be preserved after sync')
# turn off sync
p1street = 'Different street, 42'
p1.write({'street': p1street,
'use_parent_address': False})
p1.refresh(), ghoststep.refresh()
self.assertEqual(p1.street, p1street, 'Address fields must not be synced after turning sync off')
self.assertNotEqual(ghoststep.street, p1street, 'Parent address must never be touched')
# turn on sync again
p1.write({'use_parent_address': True})
p1.refresh()
self.assertEqual(p1.street, ghoststep.street, 'Address fields must be synced again')
self.assertEqual(p1.phone, p1phone, 'Phone should be preserved after address sync')
self.assertEqual(p1.type, 'contact', 'Type should be preserved after address sync')
self.assertEqual(p1.email, 'denis.bladesmith@ghoststep.com', 'Email should be preserved after sync')
# Modify parent, sync to children
[FIX] res.partner: autosync of commercial fields and address fields + correct views accordingly + basic tests * Commercial fields (bug 1160365) Fix autosync of accounting/invoicing-related fields on contacts, just as if they were actually modeled as fields.related to the parent commercial entity. This starts with the addition of the new functional field `commercial_id`, to locate the commercial entity for any partner. The commercial entity is defined as the first ancestor (starting at the partner itself) that is either marked `is_company` or has no parent. [This is Part A of the solution on bug 1160365]. Then, whenever a partner is created or modified: - if it is a commercial entity, the commercial fields are synced downstream to all its descendants, stopping at company boundaries. - if is is not a commercial entity, the commercial fields are synced from its parent commercial entity. The list of fields to sync is determined by calling the new res.partner method `_commercial_fields()` which can be easily extended by any module that adds commercial fields on res.partner. A utility method `open_commercial_entity()` was added to res.partner to make it easy to include a button for editing the parent commercial entity, to be displayed instead of now-hidden commercial fields. [This is part B of the solution on bug 1160365] The res.partner.address_get() method (used to find child partners of certain types, e.g. "invoice") was udpated to take the new "commercial entity" notion into account: it will now look for matches in children but also parents and siblings that are part of the same "commercial entity". The default partner `type` is now "contact" to reflect the new model ; "default" is inappropriate because it is a wildcard and would stop the type lookup early. [This composes parts C and D of the solution on bug 1160365] Note: This fix comes with a matching addons fix to implement module-specific extensions of part B, as well as part E of the solution. * Address fields (bug 1160425) Corrected autosync of address fields is also included in the same branch, because those two mechanisms are closely related and share some parts of the implementation. The `use_parent_address` field now defaults to False (except in the mini-kanban view of contacts on a partner form), and the autosync of address fields has been modified to only work downstream and never update a parent company if a child contact is modified. Instead, the address fields are now displayed readonly on contacts that use the parent address, with a button to edit the parent address (new method open_parent(), similar to open_commercial_entity() but opening the direct parent). To make the initial creation of a contact + company pair, a special case was added: when a new contact is created for a company that has no other contact and no address, the address of the contact is assumed to be that of the company so it is moved to the company, then the `use_parent_address` flag is enabled on the contact, and the `is_company` flag on the company. This covers a use case where contact and company are created on-the-fly when creating a new document. Many logical flaws in the autosync of address fields have been corrected and are now covered by unit tests. * Misc related fixes - checking `is_company` does not reset the parent_id field anymore, to allow for multi-level structures. The field is still hidden automatically because having an empty "Company" field on the form view of a company is quite suprising), but this UI behavior is easily customized; - the `email`, `phone`, `fax`, `mobile`, `lang`, etc. that were sometimes synced when changing parent company are now properly left alone; - the `use_parent_address` field is now always visible next to the parent_id field when a parent is set lp bug: https://launchpad.net/bugs/1160425 fixed lp bug: https://launchpad.net/bugs/1160365 fixed bzr revid: odo@openerp.com-20130408013742-tm8w0w0nmunanokk
2013-04-08 01:37:42 +00:00
ghoststreet = 'South Street, 25'
ghoststep.write({'street': ghoststreet})
p1.refresh()
self.assertEqual(p1.street, ghoststreet, 'Address fields must be synced automatically')
self.assertEqual(p1.phone, p1phone, 'Phone should not be synced')
self.assertEqual(p1.email, 'denis.bladesmith@ghoststep.com', 'Email should be preserved after sync')
p1street = 'My Street, 11'
p1.write({'street': p1street})
ghoststep.refresh()
self.assertEqual(ghoststep.street, ghoststreet, 'Touching contact should never alter parent')
def test_30_res_partner_first_contact_sync(self):
""" Test initial creation of company/contact pair where contact address gets copied to
company """
cr, uid = self.cr, self.uid
ironshield = self.res_partner.browse(cr, uid, self.res_partner.name_create(cr, uid, 'IronShield')[0])
self.assertFalse(ironshield.is_company, 'Partners are not companies by default')
self.assertFalse(ironshield.use_parent_address, 'use_parent_address defaults to False')
self.assertEqual(ironshield.type, 'contact', 'Default type must be "contact"')
ironshield.write({'type': 'default'}) # force default type to double-check sync
[FIX] res.partner: autosync of commercial fields and address fields + correct views accordingly + basic tests * Commercial fields (bug 1160365) Fix autosync of accounting/invoicing-related fields on contacts, just as if they were actually modeled as fields.related to the parent commercial entity. This starts with the addition of the new functional field `commercial_id`, to locate the commercial entity for any partner. The commercial entity is defined as the first ancestor (starting at the partner itself) that is either marked `is_company` or has no parent. [This is Part A of the solution on bug 1160365]. Then, whenever a partner is created or modified: - if it is a commercial entity, the commercial fields are synced downstream to all its descendants, stopping at company boundaries. - if is is not a commercial entity, the commercial fields are synced from its parent commercial entity. The list of fields to sync is determined by calling the new res.partner method `_commercial_fields()` which can be easily extended by any module that adds commercial fields on res.partner. A utility method `open_commercial_entity()` was added to res.partner to make it easy to include a button for editing the parent commercial entity, to be displayed instead of now-hidden commercial fields. [This is part B of the solution on bug 1160365] The res.partner.address_get() method (used to find child partners of certain types, e.g. "invoice") was udpated to take the new "commercial entity" notion into account: it will now look for matches in children but also parents and siblings that are part of the same "commercial entity". The default partner `type` is now "contact" to reflect the new model ; "default" is inappropriate because it is a wildcard and would stop the type lookup early. [This composes parts C and D of the solution on bug 1160365] Note: This fix comes with a matching addons fix to implement module-specific extensions of part B, as well as part E of the solution. * Address fields (bug 1160425) Corrected autosync of address fields is also included in the same branch, because those two mechanisms are closely related and share some parts of the implementation. The `use_parent_address` field now defaults to False (except in the mini-kanban view of contacts on a partner form), and the autosync of address fields has been modified to only work downstream and never update a parent company if a child contact is modified. Instead, the address fields are now displayed readonly on contacts that use the parent address, with a button to edit the parent address (new method open_parent(), similar to open_commercial_entity() but opening the direct parent). To make the initial creation of a contact + company pair, a special case was added: when a new contact is created for a company that has no other contact and no address, the address of the contact is assumed to be that of the company so it is moved to the company, then the `use_parent_address` flag is enabled on the contact, and the `is_company` flag on the company. This covers a use case where contact and company are created on-the-fly when creating a new document. Many logical flaws in the autosync of address fields have been corrected and are now covered by unit tests. * Misc related fixes - checking `is_company` does not reset the parent_id field anymore, to allow for multi-level structures. The field is still hidden automatically because having an empty "Company" field on the form view of a company is quite suprising), but this UI behavior is easily customized; - the `email`, `phone`, `fax`, `mobile`, `lang`, etc. that were sometimes synced when changing parent company are now properly left alone; - the `use_parent_address` field is now always visible next to the parent_id field when a parent is set lp bug: https://launchpad.net/bugs/1160425 fixed lp bug: https://launchpad.net/bugs/1160365 fixed bzr revid: odo@openerp.com-20130408013742-tm8w0w0nmunanokk
2013-04-08 01:37:42 +00:00
p1 = self.res_partner.browse(cr, uid, self.res_partner.create(cr, uid,
{'name': 'Isen Hardearth',
'street': 'Strongarm Avenue, 12',
'parent_id': ironshield.id}))
self.assertEquals(p1.type, 'contact', 'Default type must be "contact", not the copied parent type')
[FIX] res.partner: autosync of commercial fields and address fields + correct views accordingly + basic tests * Commercial fields (bug 1160365) Fix autosync of accounting/invoicing-related fields on contacts, just as if they were actually modeled as fields.related to the parent commercial entity. This starts with the addition of the new functional field `commercial_id`, to locate the commercial entity for any partner. The commercial entity is defined as the first ancestor (starting at the partner itself) that is either marked `is_company` or has no parent. [This is Part A of the solution on bug 1160365]. Then, whenever a partner is created or modified: - if it is a commercial entity, the commercial fields are synced downstream to all its descendants, stopping at company boundaries. - if is is not a commercial entity, the commercial fields are synced from its parent commercial entity. The list of fields to sync is determined by calling the new res.partner method `_commercial_fields()` which can be easily extended by any module that adds commercial fields on res.partner. A utility method `open_commercial_entity()` was added to res.partner to make it easy to include a button for editing the parent commercial entity, to be displayed instead of now-hidden commercial fields. [This is part B of the solution on bug 1160365] The res.partner.address_get() method (used to find child partners of certain types, e.g. "invoice") was udpated to take the new "commercial entity" notion into account: it will now look for matches in children but also parents and siblings that are part of the same "commercial entity". The default partner `type` is now "contact" to reflect the new model ; "default" is inappropriate because it is a wildcard and would stop the type lookup early. [This composes parts C and D of the solution on bug 1160365] Note: This fix comes with a matching addons fix to implement module-specific extensions of part B, as well as part E of the solution. * Address fields (bug 1160425) Corrected autosync of address fields is also included in the same branch, because those two mechanisms are closely related and share some parts of the implementation. The `use_parent_address` field now defaults to False (except in the mini-kanban view of contacts on a partner form), and the autosync of address fields has been modified to only work downstream and never update a parent company if a child contact is modified. Instead, the address fields are now displayed readonly on contacts that use the parent address, with a button to edit the parent address (new method open_parent(), similar to open_commercial_entity() but opening the direct parent). To make the initial creation of a contact + company pair, a special case was added: when a new contact is created for a company that has no other contact and no address, the address of the contact is assumed to be that of the company so it is moved to the company, then the `use_parent_address` flag is enabled on the contact, and the `is_company` flag on the company. This covers a use case where contact and company are created on-the-fly when creating a new document. Many logical flaws in the autosync of address fields have been corrected and are now covered by unit tests. * Misc related fixes - checking `is_company` does not reset the parent_id field anymore, to allow for multi-level structures. The field is still hidden automatically because having an empty "Company" field on the form view of a company is quite suprising), but this UI behavior is easily customized; - the `email`, `phone`, `fax`, `mobile`, `lang`, etc. that were sometimes synced when changing parent company are now properly left alone; - the `use_parent_address` field is now always visible next to the parent_id field when a parent is set lp bug: https://launchpad.net/bugs/1160425 fixed lp bug: https://launchpad.net/bugs/1160365 fixed bzr revid: odo@openerp.com-20130408013742-tm8w0w0nmunanokk
2013-04-08 01:37:42 +00:00
ironshield.refresh()
self.assertEqual(ironshield.street, p1.street, 'Address fields should be copied to company')
self.assertTrue(ironshield.is_company, 'Company flag should be turned on after first contact creation')
def test_40_res_partner_address_getc(self):
""" Test address_get address resolution mechanism: it should first go down through descendants,
stopping when encountering another is_copmany entity, then go up, stopping again at the first
is_company entity or the root ancestor and if nothing matches, it should use the provided partner
itself """
[FIX] res.partner: autosync of commercial fields and address fields + correct views accordingly + basic tests * Commercial fields (bug 1160365) Fix autosync of accounting/invoicing-related fields on contacts, just as if they were actually modeled as fields.related to the parent commercial entity. This starts with the addition of the new functional field `commercial_id`, to locate the commercial entity for any partner. The commercial entity is defined as the first ancestor (starting at the partner itself) that is either marked `is_company` or has no parent. [This is Part A of the solution on bug 1160365]. Then, whenever a partner is created or modified: - if it is a commercial entity, the commercial fields are synced downstream to all its descendants, stopping at company boundaries. - if is is not a commercial entity, the commercial fields are synced from its parent commercial entity. The list of fields to sync is determined by calling the new res.partner method `_commercial_fields()` which can be easily extended by any module that adds commercial fields on res.partner. A utility method `open_commercial_entity()` was added to res.partner to make it easy to include a button for editing the parent commercial entity, to be displayed instead of now-hidden commercial fields. [This is part B of the solution on bug 1160365] The res.partner.address_get() method (used to find child partners of certain types, e.g. "invoice") was udpated to take the new "commercial entity" notion into account: it will now look for matches in children but also parents and siblings that are part of the same "commercial entity". The default partner `type` is now "contact" to reflect the new model ; "default" is inappropriate because it is a wildcard and would stop the type lookup early. [This composes parts C and D of the solution on bug 1160365] Note: This fix comes with a matching addons fix to implement module-specific extensions of part B, as well as part E of the solution. * Address fields (bug 1160425) Corrected autosync of address fields is also included in the same branch, because those two mechanisms are closely related and share some parts of the implementation. The `use_parent_address` field now defaults to False (except in the mini-kanban view of contacts on a partner form), and the autosync of address fields has been modified to only work downstream and never update a parent company if a child contact is modified. Instead, the address fields are now displayed readonly on contacts that use the parent address, with a button to edit the parent address (new method open_parent(), similar to open_commercial_entity() but opening the direct parent). To make the initial creation of a contact + company pair, a special case was added: when a new contact is created for a company that has no other contact and no address, the address of the contact is assumed to be that of the company so it is moved to the company, then the `use_parent_address` flag is enabled on the contact, and the `is_company` flag on the company. This covers a use case where contact and company are created on-the-fly when creating a new document. Many logical flaws in the autosync of address fields have been corrected and are now covered by unit tests. * Misc related fixes - checking `is_company` does not reset the parent_id field anymore, to allow for multi-level structures. The field is still hidden automatically because having an empty "Company" field on the form view of a company is quite suprising), but this UI behavior is easily customized; - the `email`, `phone`, `fax`, `mobile`, `lang`, etc. that were sometimes synced when changing parent company are now properly left alone; - the `use_parent_address` field is now always visible next to the parent_id field when a parent is set lp bug: https://launchpad.net/bugs/1160425 fixed lp bug: https://launchpad.net/bugs/1160365 fixed bzr revid: odo@openerp.com-20130408013742-tm8w0w0nmunanokk
2013-04-08 01:37:42 +00:00
cr, uid = self.cr, self.uid
elmtree = self.res_partner.browse(cr, uid, self.res_partner.name_create(cr, uid, 'Elmtree')[0])
branch1 = self.res_partner.browse(cr, uid, self.res_partner.create(cr, uid, {'name': 'Branch 1',
'parent_id': elmtree.id,
'is_company': True}))
leaf10 = self.res_partner.browse(cr, uid, self.res_partner.create(cr, uid, {'name': 'Leaf 10',
'parent_id': branch1.id,
'type': 'invoice'}))
branch11 = self.res_partner.browse(cr, uid, self.res_partner.create(cr, uid, {'name': 'Branch 11',
'parent_id': branch1.id,
'type': 'other'}))
leaf111 = self.res_partner.browse(cr, uid, self.res_partner.create(cr, uid, {'name': 'Leaf 111',
'parent_id': branch11.id,
'type': 'delivery'}))
branch11.write({'is_company': False}) # force is_company after creating 1rst child
branch2 = self.res_partner.browse(cr, uid, self.res_partner.create(cr, uid, {'name': 'Branch 2',
'parent_id': elmtree.id,
'is_company': True}))
leaf21 = self.res_partner.browse(cr, uid, self.res_partner.create(cr, uid, {'name': 'Leaf 21',
'parent_id': branch2.id,
'type': 'delivery'}))
leaf22 = self.res_partner.browse(cr, uid, self.res_partner.create(cr, uid, {'name': 'Leaf 22',
'parent_id': branch2.id}))
leaf23 = self.res_partner.browse(cr, uid, self.res_partner.create(cr, uid, {'name': 'Leaf 23',
'parent_id': branch2.id,
'type': 'default'}))
# go up, stop at branch1
self.assertEqual(self.res_partner.address_get(cr, uid, [leaf111.id], ['delivery', 'invoice', 'contact', 'other', 'default']),
{'delivery': leaf111.id,
'invoice': leaf10.id,
'contact': branch1.id,
'other': branch11.id,
'default': leaf111.id}, 'Invalid address resolution')
[FIX] res.partner: autosync of commercial fields and address fields + correct views accordingly + basic tests * Commercial fields (bug 1160365) Fix autosync of accounting/invoicing-related fields on contacts, just as if they were actually modeled as fields.related to the parent commercial entity. This starts with the addition of the new functional field `commercial_id`, to locate the commercial entity for any partner. The commercial entity is defined as the first ancestor (starting at the partner itself) that is either marked `is_company` or has no parent. [This is Part A of the solution on bug 1160365]. Then, whenever a partner is created or modified: - if it is a commercial entity, the commercial fields are synced downstream to all its descendants, stopping at company boundaries. - if is is not a commercial entity, the commercial fields are synced from its parent commercial entity. The list of fields to sync is determined by calling the new res.partner method `_commercial_fields()` which can be easily extended by any module that adds commercial fields on res.partner. A utility method `open_commercial_entity()` was added to res.partner to make it easy to include a button for editing the parent commercial entity, to be displayed instead of now-hidden commercial fields. [This is part B of the solution on bug 1160365] The res.partner.address_get() method (used to find child partners of certain types, e.g. "invoice") was udpated to take the new "commercial entity" notion into account: it will now look for matches in children but also parents and siblings that are part of the same "commercial entity". The default partner `type` is now "contact" to reflect the new model ; "default" is inappropriate because it is a wildcard and would stop the type lookup early. [This composes parts C and D of the solution on bug 1160365] Note: This fix comes with a matching addons fix to implement module-specific extensions of part B, as well as part E of the solution. * Address fields (bug 1160425) Corrected autosync of address fields is also included in the same branch, because those two mechanisms are closely related and share some parts of the implementation. The `use_parent_address` field now defaults to False (except in the mini-kanban view of contacts on a partner form), and the autosync of address fields has been modified to only work downstream and never update a parent company if a child contact is modified. Instead, the address fields are now displayed readonly on contacts that use the parent address, with a button to edit the parent address (new method open_parent(), similar to open_commercial_entity() but opening the direct parent). To make the initial creation of a contact + company pair, a special case was added: when a new contact is created for a company that has no other contact and no address, the address of the contact is assumed to be that of the company so it is moved to the company, then the `use_parent_address` flag is enabled on the contact, and the `is_company` flag on the company. This covers a use case where contact and company are created on-the-fly when creating a new document. Many logical flaws in the autosync of address fields have been corrected and are now covered by unit tests. * Misc related fixes - checking `is_company` does not reset the parent_id field anymore, to allow for multi-level structures. The field is still hidden automatically because having an empty "Company" field on the form view of a company is quite suprising), but this UI behavior is easily customized; - the `email`, `phone`, `fax`, `mobile`, `lang`, etc. that were sometimes synced when changing parent company are now properly left alone; - the `use_parent_address` field is now always visible next to the parent_id field when a parent is set lp bug: https://launchpad.net/bugs/1160425 fixed lp bug: https://launchpad.net/bugs/1160365 fixed bzr revid: odo@openerp.com-20130408013742-tm8w0w0nmunanokk
2013-04-08 01:37:42 +00:00
self.assertEqual(self.res_partner.address_get(cr, uid, [branch11.id], ['delivery', 'invoice', 'contact', 'other', 'default']),
{'delivery': leaf111.id,
'invoice': leaf10.id,
'contact': branch1.id,
'other': branch11.id,
'default': branch11.id}, 'Invalid address resolution')
[FIX] res.partner: autosync of commercial fields and address fields + correct views accordingly + basic tests * Commercial fields (bug 1160365) Fix autosync of accounting/invoicing-related fields on contacts, just as if they were actually modeled as fields.related to the parent commercial entity. This starts with the addition of the new functional field `commercial_id`, to locate the commercial entity for any partner. The commercial entity is defined as the first ancestor (starting at the partner itself) that is either marked `is_company` or has no parent. [This is Part A of the solution on bug 1160365]. Then, whenever a partner is created or modified: - if it is a commercial entity, the commercial fields are synced downstream to all its descendants, stopping at company boundaries. - if is is not a commercial entity, the commercial fields are synced from its parent commercial entity. The list of fields to sync is determined by calling the new res.partner method `_commercial_fields()` which can be easily extended by any module that adds commercial fields on res.partner. A utility method `open_commercial_entity()` was added to res.partner to make it easy to include a button for editing the parent commercial entity, to be displayed instead of now-hidden commercial fields. [This is part B of the solution on bug 1160365] The res.partner.address_get() method (used to find child partners of certain types, e.g. "invoice") was udpated to take the new "commercial entity" notion into account: it will now look for matches in children but also parents and siblings that are part of the same "commercial entity". The default partner `type` is now "contact" to reflect the new model ; "default" is inappropriate because it is a wildcard and would stop the type lookup early. [This composes parts C and D of the solution on bug 1160365] Note: This fix comes with a matching addons fix to implement module-specific extensions of part B, as well as part E of the solution. * Address fields (bug 1160425) Corrected autosync of address fields is also included in the same branch, because those two mechanisms are closely related and share some parts of the implementation. The `use_parent_address` field now defaults to False (except in the mini-kanban view of contacts on a partner form), and the autosync of address fields has been modified to only work downstream and never update a parent company if a child contact is modified. Instead, the address fields are now displayed readonly on contacts that use the parent address, with a button to edit the parent address (new method open_parent(), similar to open_commercial_entity() but opening the direct parent). To make the initial creation of a contact + company pair, a special case was added: when a new contact is created for a company that has no other contact and no address, the address of the contact is assumed to be that of the company so it is moved to the company, then the `use_parent_address` flag is enabled on the contact, and the `is_company` flag on the company. This covers a use case where contact and company are created on-the-fly when creating a new document. Many logical flaws in the autosync of address fields have been corrected and are now covered by unit tests. * Misc related fixes - checking `is_company` does not reset the parent_id field anymore, to allow for multi-level structures. The field is still hidden automatically because having an empty "Company" field on the form view of a company is quite suprising), but this UI behavior is easily customized; - the `email`, `phone`, `fax`, `mobile`, `lang`, etc. that were sometimes synced when changing parent company are now properly left alone; - the `use_parent_address` field is now always visible next to the parent_id field when a parent is set lp bug: https://launchpad.net/bugs/1160425 fixed lp bug: https://launchpad.net/bugs/1160365 fixed bzr revid: odo@openerp.com-20130408013742-tm8w0w0nmunanokk
2013-04-08 01:37:42 +00:00
# go down, stop at at all child companies
self.assertEqual(self.res_partner.address_get(cr, uid, [elmtree.id], ['delivery', 'invoice', 'contact', 'other', 'default']),
{'delivery': elmtree.id,
'invoice': elmtree.id,
'contact': elmtree.id,
'other': elmtree.id,
'default': elmtree.id}, 'Invalid address resolution')
# go down through children
self.assertEqual(self.res_partner.address_get(cr, uid, [branch1.id], ['delivery', 'invoice', 'contact', 'other', 'default']),
{'delivery': leaf111.id,
'invoice': leaf10.id,
'contact': branch1.id,
'other': branch11.id,
'default': branch1.id}, 'Invalid address resolution')
self.assertEqual(self.res_partner.address_get(cr, uid, [branch2.id], ['delivery', 'invoice', 'contact', 'other', 'default']),
{'delivery': leaf21.id,
'invoice': leaf23.id,
'contact': branch2.id,
'other': leaf23.id,
'default': leaf23.id}, 'Invalid address resolution')
# go up then down through siblings
self.assertEqual(self.res_partner.address_get(cr, uid, [leaf21.id], ['delivery', 'invoice', 'contact', 'other', 'default']),
{'delivery': leaf21.id,
'invoice': leaf23.id,
'contact': branch2.id,
'other': leaf23.id,
'default': leaf23.id
}, 'Invalid address resolution, should scan commercial entity ancestor and its descendants')
self.assertEqual(self.res_partner.address_get(cr, uid, [leaf22.id], ['delivery', 'invoice', 'contact', 'other', 'default']),
{'delivery': leaf21.id,
'invoice': leaf23.id,
'contact': leaf22.id,
'other': leaf23.id,
'default': leaf23.id}, 'Invalid address resolution, should scan commercial entity ancestor and its descendants')
self.assertEqual(self.res_partner.address_get(cr, uid, [leaf23.id], ['delivery', 'invoice', 'contact', 'other', 'default']),
{'delivery': leaf21.id,
'invoice': leaf23.id,
'contact': branch2.id,
'other': leaf23.id,
'default': leaf23.id}, 'Invalid address resolution, `default` should only override if no partner with specific type exists')
# empty adr_pref means only 'default'
self.assertEqual(self.res_partner.address_get(cr, uid, [elmtree.id], []),
{'default': elmtree.id}, 'Invalid address resolution, no default means commercial entity ancestor')
self.assertEqual(self.res_partner.address_get(cr, uid, [leaf111.id], []),
{'default': leaf111.id}, 'Invalid address resolution, no default means contact itself')
[FIX] res.partner: autosync of commercial fields and address fields + correct views accordingly + basic tests * Commercial fields (bug 1160365) Fix autosync of accounting/invoicing-related fields on contacts, just as if they were actually modeled as fields.related to the parent commercial entity. This starts with the addition of the new functional field `commercial_id`, to locate the commercial entity for any partner. The commercial entity is defined as the first ancestor (starting at the partner itself) that is either marked `is_company` or has no parent. [This is Part A of the solution on bug 1160365]. Then, whenever a partner is created or modified: - if it is a commercial entity, the commercial fields are synced downstream to all its descendants, stopping at company boundaries. - if is is not a commercial entity, the commercial fields are synced from its parent commercial entity. The list of fields to sync is determined by calling the new res.partner method `_commercial_fields()` which can be easily extended by any module that adds commercial fields on res.partner. A utility method `open_commercial_entity()` was added to res.partner to make it easy to include a button for editing the parent commercial entity, to be displayed instead of now-hidden commercial fields. [This is part B of the solution on bug 1160365] The res.partner.address_get() method (used to find child partners of certain types, e.g. "invoice") was udpated to take the new "commercial entity" notion into account: it will now look for matches in children but also parents and siblings that are part of the same "commercial entity". The default partner `type` is now "contact" to reflect the new model ; "default" is inappropriate because it is a wildcard and would stop the type lookup early. [This composes parts C and D of the solution on bug 1160365] Note: This fix comes with a matching addons fix to implement module-specific extensions of part B, as well as part E of the solution. * Address fields (bug 1160425) Corrected autosync of address fields is also included in the same branch, because those two mechanisms are closely related and share some parts of the implementation. The `use_parent_address` field now defaults to False (except in the mini-kanban view of contacts on a partner form), and the autosync of address fields has been modified to only work downstream and never update a parent company if a child contact is modified. Instead, the address fields are now displayed readonly on contacts that use the parent address, with a button to edit the parent address (new method open_parent(), similar to open_commercial_entity() but opening the direct parent). To make the initial creation of a contact + company pair, a special case was added: when a new contact is created for a company that has no other contact and no address, the address of the contact is assumed to be that of the company so it is moved to the company, then the `use_parent_address` flag is enabled on the contact, and the `is_company` flag on the company. This covers a use case where contact and company are created on-the-fly when creating a new document. Many logical flaws in the autosync of address fields have been corrected and are now covered by unit tests. * Misc related fixes - checking `is_company` does not reset the parent_id field anymore, to allow for multi-level structures. The field is still hidden automatically because having an empty "Company" field on the form view of a company is quite suprising), but this UI behavior is easily customized; - the `email`, `phone`, `fax`, `mobile`, `lang`, etc. that were sometimes synced when changing parent company are now properly left alone; - the `use_parent_address` field is now always visible next to the parent_id field when a parent is set lp bug: https://launchpad.net/bugs/1160425 fixed lp bug: https://launchpad.net/bugs/1160365 fixed bzr revid: odo@openerp.com-20130408013742-tm8w0w0nmunanokk
2013-04-08 01:37:42 +00:00
branch11.write({'type': 'default'})
self.assertEqual(self.res_partner.address_get(cr, uid, [leaf111.id], []),
{'default': branch11.id}, 'Invalid address resolution, branch11 should now be default')
def test_50_res_partner_commercial_sync(self):
cr, uid = self.cr, self.uid
p0 = self.res_partner.browse(cr, uid, self.res_partner.create(cr, uid,
{'name': 'Sigurd Sunknife',
'email': 'ssunknife@gmail.com'}))
sunhelm = self.res_partner.browse(cr, uid, self.res_partner.create(cr, uid,
{'name': 'Sunhelm',
'is_company': True,
'street': 'Rainbow Street, 13',
'phone': '1122334455',
'email': 'info@sunhelm.com',
'vat': 'BE0477472701',
'child_ids': [(4, p0.id),
(0, 0, {'name': 'Alrik Greenthorn',
'email': 'agr@sunhelm.com'})],
}))
p1 = self.res_partner.browse(cr, uid, self.res_partner.create(cr, uid,
{'name': 'Otto Blackwood',
'email': 'otto.blackwood@sunhelm.com',
'parent_id': sunhelm.id}))
p11 = self.res_partner.browse(cr, uid, self.res_partner.create(cr, uid,
{'name': 'Gini Graywool',
'email': 'ggr@sunhelm.com',
'parent_id': p1.id}))
p2 = self.res_partner.browse(cr, uid, self.res_partner.search(cr, uid,
[('email', '=', 'agr@sunhelm.com')])[0])
for p in (p0, p1, p11, p2):
p.refresh()
self.assertEquals(p.commercial_partner_id, sunhelm, 'Incorrect commercial entity resolution')
[FIX] res.partner: autosync of commercial fields and address fields + correct views accordingly + basic tests * Commercial fields (bug 1160365) Fix autosync of accounting/invoicing-related fields on contacts, just as if they were actually modeled as fields.related to the parent commercial entity. This starts with the addition of the new functional field `commercial_id`, to locate the commercial entity for any partner. The commercial entity is defined as the first ancestor (starting at the partner itself) that is either marked `is_company` or has no parent. [This is Part A of the solution on bug 1160365]. Then, whenever a partner is created or modified: - if it is a commercial entity, the commercial fields are synced downstream to all its descendants, stopping at company boundaries. - if is is not a commercial entity, the commercial fields are synced from its parent commercial entity. The list of fields to sync is determined by calling the new res.partner method `_commercial_fields()` which can be easily extended by any module that adds commercial fields on res.partner. A utility method `open_commercial_entity()` was added to res.partner to make it easy to include a button for editing the parent commercial entity, to be displayed instead of now-hidden commercial fields. [This is part B of the solution on bug 1160365] The res.partner.address_get() method (used to find child partners of certain types, e.g. "invoice") was udpated to take the new "commercial entity" notion into account: it will now look for matches in children but also parents and siblings that are part of the same "commercial entity". The default partner `type` is now "contact" to reflect the new model ; "default" is inappropriate because it is a wildcard and would stop the type lookup early. [This composes parts C and D of the solution on bug 1160365] Note: This fix comes with a matching addons fix to implement module-specific extensions of part B, as well as part E of the solution. * Address fields (bug 1160425) Corrected autosync of address fields is also included in the same branch, because those two mechanisms are closely related and share some parts of the implementation. The `use_parent_address` field now defaults to False (except in the mini-kanban view of contacts on a partner form), and the autosync of address fields has been modified to only work downstream and never update a parent company if a child contact is modified. Instead, the address fields are now displayed readonly on contacts that use the parent address, with a button to edit the parent address (new method open_parent(), similar to open_commercial_entity() but opening the direct parent). To make the initial creation of a contact + company pair, a special case was added: when a new contact is created for a company that has no other contact and no address, the address of the contact is assumed to be that of the company so it is moved to the company, then the `use_parent_address` flag is enabled on the contact, and the `is_company` flag on the company. This covers a use case where contact and company are created on-the-fly when creating a new document. Many logical flaws in the autosync of address fields have been corrected and are now covered by unit tests. * Misc related fixes - checking `is_company` does not reset the parent_id field anymore, to allow for multi-level structures. The field is still hidden automatically because having an empty "Company" field on the form view of a company is quite suprising), but this UI behavior is easily customized; - the `email`, `phone`, `fax`, `mobile`, `lang`, etc. that were sometimes synced when changing parent company are now properly left alone; - the `use_parent_address` field is now always visible next to the parent_id field when a parent is set lp bug: https://launchpad.net/bugs/1160425 fixed lp bug: https://launchpad.net/bugs/1160365 fixed bzr revid: odo@openerp.com-20130408013742-tm8w0w0nmunanokk
2013-04-08 01:37:42 +00:00
self.assertEquals(p.vat, sunhelm.vat, 'Commercial fields must be automatically synced')
sunhelmvat = 'BE0123456789'
sunhelm.write({'vat': sunhelmvat})
for p in (p0, p1, p11, p2):
p.refresh()
self.assertEquals(p.vat, sunhelmvat, 'Commercial fields must be automatically and recursively synced')
p1vat = 'BE0987654321'
p1.write({'vat': p1vat})
for p in (sunhelm, p0, p11, p2):
p.refresh()
self.assertEquals(p.vat, sunhelmvat, 'Sync to children should only work downstream and on commercial entities')
# promote p1 to commercial entity
vals = p1.onchange_type(is_company=True)['value']
p1.write(dict(vals, parent_id=sunhelm.id,
is_company=True,
name='Sunhelm Subsidiary'))
p1.refresh()
self.assertEquals(p1.vat, p1vat, 'Setting is_company should stop auto-sync of commercial fields')
self.assertEquals(p1.commercial_partner_id, p1, 'Incorrect commercial entity resolution after setting is_company')
[FIX] res.partner: autosync of commercial fields and address fields + correct views accordingly + basic tests * Commercial fields (bug 1160365) Fix autosync of accounting/invoicing-related fields on contacts, just as if they were actually modeled as fields.related to the parent commercial entity. This starts with the addition of the new functional field `commercial_id`, to locate the commercial entity for any partner. The commercial entity is defined as the first ancestor (starting at the partner itself) that is either marked `is_company` or has no parent. [This is Part A of the solution on bug 1160365]. Then, whenever a partner is created or modified: - if it is a commercial entity, the commercial fields are synced downstream to all its descendants, stopping at company boundaries. - if is is not a commercial entity, the commercial fields are synced from its parent commercial entity. The list of fields to sync is determined by calling the new res.partner method `_commercial_fields()` which can be easily extended by any module that adds commercial fields on res.partner. A utility method `open_commercial_entity()` was added to res.partner to make it easy to include a button for editing the parent commercial entity, to be displayed instead of now-hidden commercial fields. [This is part B of the solution on bug 1160365] The res.partner.address_get() method (used to find child partners of certain types, e.g. "invoice") was udpated to take the new "commercial entity" notion into account: it will now look for matches in children but also parents and siblings that are part of the same "commercial entity". The default partner `type` is now "contact" to reflect the new model ; "default" is inappropriate because it is a wildcard and would stop the type lookup early. [This composes parts C and D of the solution on bug 1160365] Note: This fix comes with a matching addons fix to implement module-specific extensions of part B, as well as part E of the solution. * Address fields (bug 1160425) Corrected autosync of address fields is also included in the same branch, because those two mechanisms are closely related and share some parts of the implementation. The `use_parent_address` field now defaults to False (except in the mini-kanban view of contacts on a partner form), and the autosync of address fields has been modified to only work downstream and never update a parent company if a child contact is modified. Instead, the address fields are now displayed readonly on contacts that use the parent address, with a button to edit the parent address (new method open_parent(), similar to open_commercial_entity() but opening the direct parent). To make the initial creation of a contact + company pair, a special case was added: when a new contact is created for a company that has no other contact and no address, the address of the contact is assumed to be that of the company so it is moved to the company, then the `use_parent_address` flag is enabled on the contact, and the `is_company` flag on the company. This covers a use case where contact and company are created on-the-fly when creating a new document. Many logical flaws in the autosync of address fields have been corrected and are now covered by unit tests. * Misc related fixes - checking `is_company` does not reset the parent_id field anymore, to allow for multi-level structures. The field is still hidden automatically because having an empty "Company" field on the form view of a company is quite suprising), but this UI behavior is easily customized; - the `email`, `phone`, `fax`, `mobile`, `lang`, etc. that were sometimes synced when changing parent company are now properly left alone; - the `use_parent_address` field is now always visible next to the parent_id field when a parent is set lp bug: https://launchpad.net/bugs/1160425 fixed lp bug: https://launchpad.net/bugs/1160365 fixed bzr revid: odo@openerp.com-20130408013742-tm8w0w0nmunanokk
2013-04-08 01:37:42 +00:00
# writing on parent should not touch child commercial entities
sunhelmvat2 = 'BE0112233445'
sunhelm.write({'vat': sunhelmvat2})
p1.refresh()
self.assertEquals(p1.vat, p1vat, 'Setting is_company should stop auto-sync of commercial fields')
p0.refresh()
self.assertEquals(p0.vat, sunhelmvat2, 'Commercial fields must be automatically synced')
def test_60_read_group(self):
cr, uid = self.cr, self.uid
for user_data in [
{'name': 'Alice', 'login': 'alice', 'color': 1, 'function': 'Friend'},
{'name': 'Bob', 'login': 'bob', 'color': 2, 'function': 'Friend'},
{'name': 'Eve', 'login': 'eve', 'color': 3, 'function': 'Eavesdropper'},
]:
self.res_users.create(cr, uid, user_data)
groups_data = self.res_users.read_group(cr, uid, domain=[('login', 'in', ('alice', 'bob', 'eve'))], fields=['name', 'color', 'function'], groupby='function')
self.assertEqual(len(groups_data), 2, "Incorrect number of results when grouping on a field")
for group_data in groups_data:
self.assertIn('color', group_data, "Aggregated data for the column 'color' is not present in read_group return values")
self.assertEqual(group_data['color'], 3, "Incorrect sum for aggregated data for the column 'color'")
class test_partner_recursion(common.TransactionCase):
def setUp(self):
super(test_partner_recursion,self).setUp()
self.res_partner = self.registry('res.partner')
cr, uid = self.cr, self.uid
self.p1 = self.res_partner.name_create(cr, uid, 'Elmtree')[0]
self.p2 = self.res_partner.create(cr, uid, {'name': 'Elmtree Child 1', 'parent_id': self.p1})
self.p3 = self.res_partner.create(cr, uid, {'name': 'Elmtree Grand-Child 1.1', 'parent_id': self.p2})
# split 101, 102, 103 tests to force SQL rollback between them
def test_101_res_partner_recursion(self):
cr, uid, p1, p3 = self.cr, self.uid, self.p1, self.p3
self.assertRaises(except_orm, self.res_partner.write, cr, uid, [p1], {'parent_id': p3})
def test_102_res_partner_recursion(self):
cr, uid, p2, p3 = self.cr, self.uid, self.p2, self.p3
self.assertRaises(except_orm, self.res_partner.write, cr, uid, [p2], {'parent_id': p3})
def test_103_res_partner_recursion(self):
cr, uid, p3 = self.cr, self.uid, self.p3
self.assertRaises(except_orm, self.res_partner.write, cr, uid, [p3], {'parent_id': p3})
def test_104_res_partner_recursion_indirect_cycle(self):
""" Indirect hacky write to create cycle in children """
cr, uid, p2, p3 = self.cr, self.uid, self.p2, self.p3
p3b = self.res_partner.create(cr, uid, {'name': 'Elmtree Grand-Child 1.2', 'parent_id': self.p2})
self.assertRaises(except_orm, self.res_partner.write, cr, uid, [p2],
{'child_ids': [(1, p3, {'parent_id': p3b}), (1, p3b, {'parent_id': p3})]})
def test_110_res_partner_recursion_multi_update(self):
""" multi-write on several partners in same hierarchy must not trigger a false cycle detection """
cr, uid, p1, p2, p3 = self.cr, self.uid, self.p1, self.p2, self.p3
self.assertTrue(self.res_partner.write(cr, uid, [p1,p2,p3], {'phone': '123456'}))
class test_translation(common.TransactionCase):
def setUp(self):
super(test_translation, self).setUp()
self.res_category = self.registry('res.partner.category')
self.ir_translation = self.registry('ir.translation')
cr, uid = self.cr, self.uid
self.registry('ir.translation').load_module_terms(cr, ['base'], ['fr_FR'])
self.cat_id = self.res_category.create(cr, uid, {'name': 'Customers'})
self.ir_translation.create(cr, uid, {'name': 'res.partner.category,name', 'module':'base',
'value': 'Clients', 'res_id': self.cat_id, 'lang':'fr_FR', 'state':'translated', 'type': 'model'})
def test_101_create_translated_record(self):
cr, uid = self.cr, self.uid
no_context_cat = self.res_category.browse(cr, uid, self.cat_id)
self.assertEqual(no_context_cat.name, 'Customers', "Error in basic name_get")
fr_context_cat = self.res_category.browse(cr, uid, self.cat_id, context={'lang':'fr_FR'})
self.assertEqual(fr_context_cat.name, 'Clients', "Translation not found")
def test_102_duplicate_record(self):
cr, uid = self.cr, self.uid
self.new_cat_id = self.res_category.copy(cr, uid, self.cat_id, context={'lang':'fr_FR'})
no_context_cat = self.res_category.browse(cr, uid, self.new_cat_id)
self.assertEqual(no_context_cat.name, 'Customers', "Duplication did not set untranslated value")
fr_context_cat = self.res_category.browse(cr, uid, self.new_cat_id, context={'lang':'fr_FR'})
self.assertEqual(fr_context_cat.name, 'Clients', "Did not found translation for initial value")
def test_103_duplicate_record_fr(self):
cr, uid = self.cr, self.uid
self.new_fr_cat_id = self.res_category.copy(cr, uid, self.cat_id, default={'name': 'Clients (copie)'}, context={'lang':'fr_FR'})
no_context_cat = self.res_category.browse(cr, uid, self.new_fr_cat_id)
self.assertEqual(no_context_cat.name, 'Customers', "Duplication erased original untranslated value")
fr_context_cat = self.res_category.browse(cr, uid, self.new_fr_cat_id, context={'lang':'fr_FR'})
self.assertEqual(fr_context_cat.name, 'Clients (copie)', "Did not used default value for translated value")
if __name__ == '__main__':
unittest2.main()