Browse Source

[MIG] 10.0 partner_contact_in_several_companies (#347)

* [MIG] inital work to 10.0

* [FIX] restore computed field

- select=1 is not usable anymore ...

* [FIX] convert _fields_sync to new api

* [FIX] restore form . import statement

* [FIX] readme with last template.

* [FIX] import statement.

* [FIX] check all tests

* [FIX] Flake8 errors fixes

* [FIX] flake 8

* [FIX] wrong obj call self -> self.contact_id

* [FIX] typo

* [FIX] flake 8

* [FIX] add index on contact_type

* [fix] use in statement on test

* [FIX] update base action with new context

* [FIX] test fixes

* [FIX] test work

* [FIX] flake 8 over indent

* [FIX] fixes on lastest comments

- better readability
- remove <data></data> tags

* [FIX] model that same pattern for _fields_sync

- add test ensure_once()

* [FIX] remove last data xml tags

* [FIX] fix action test

* [FIX] typo in import statement

* [FIX] remove logger from tests

* [FIX] new flake8 compute method name for OCA

* [FIX] minor typo

* [FIX] partner_contact_in_several_companies: remove contributor key in manifest

* [FIX] partner_contact_in_several_companies: residual onchange on partner view

* Revert "[FIX] partner_contact_in_several_companies: remove contributor key in manifest"

This reverts commit 56e511a9a7.

* [FIX] partner_contact_personal_information_page: clean manifest and authors

* [FIX] partner_contact_in_several_companies: required = True not needed
14.0
Nicolas JEUDY 7 years ago
committed by Jacob Oldfield
parent
commit
3bb88fa669
  1. 23
      partner_contact_in_several_companies/README.rst
  2. 16
      partner_contact_in_several_companies/__manifest__.py
  3. 6
      partner_contact_in_several_companies/demo/ir_actions.xml
  4. 6
      partner_contact_in_several_companies/demo/res_partner.xml
  5. 2
      partner_contact_in_several_companies/models/ir_actions.py
  6. 39
      partner_contact_in_several_companies/models/res_partner.py
  7. 217
      partner_contact_in_several_companies/tests/test_partner_contact_in_several_companies.py
  8. 18
      partner_contact_in_several_companies/views/res_partner.xml

23
partner_contact_in_several_companies/README.rst

@ -32,7 +32,7 @@ For further information, please visit:
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas .. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot :alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/134/9.0
:target: https://runbot.odoo-community.org/runbot/134/10.0
Known issues / Roadmap Known issues / Roadmap
====================== ======================
@ -42,22 +42,24 @@ Known issues / Roadmap
Bug Tracker Bug Tracker
=========== ===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/
partner-contact/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed feedback `here <https://github.com/OCA/
partner-contact/issues/new?body=module:%20
partner_contact_in_serveral_companies%0Aversion:%20
9.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Bugs are tracked on `GitHub Issues
<https://github.com/OCA/partner-contact/issues>`_. In case of trouble, please
check there if your issue has already been reported. If you spotted it first,
help us smashing it by providing a detailed and welcomed feedback.
Credits Credits
======= =======
Images
------
* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_.
Contributors Contributors
------------ ------------
* Xavier ALT <xal@openerp.com> (original author)
* Xavier ALT <xal@odoo.com> (original author)
* El Hadji Dem <elhadji.dem@savoirfairelinux.com> * El Hadji Dem <elhadji.dem@savoirfairelinux.com>
* TheCloneMaster <the.clone.master@gmail.com> * TheCloneMaster <the.clone.master@gmail.com>
* Sandy Carter <bwrsandman@gmail.com> * Sandy Carter <bwrsandman@gmail.com>
@ -65,6 +67,7 @@ Contributors
* Sebastien Alix <sebastien.alix@osiell.com> * Sebastien Alix <sebastien.alix@osiell.com>
* Jairo Llopis <j.llopis@grupoesoc.es> * Jairo Llopis <j.llopis@grupoesoc.es>
* Richard deMeester <richard@willowit.com.au> * Richard deMeester <richard@willowit.com.au>
* Nicolas JEUDY <https://github.com/njeudy>
Maintainer Maintainer
---------- ----------

16
partner_contact_in_several_companies/__manifest__.py

@ -4,23 +4,13 @@
{ {
"name": "Contacts in several partners", "name": "Contacts in several partners",
"summary": "Allow to have one contact in several partners", "summary": "Allow to have one contact in several partners",
"version": "9.0.1.0.0",
"version": "10.0.1.0.0",
"category": "Customer Relationship Management", "category": "Customer Relationship Management",
"website": "https://odoo-community.org/", "website": "https://odoo-community.org/",
"author": "Odoo Community Association (OCA)",
"contributors": [
'Xavier ALT <xal@openerp.com>',
'El Hadji Dem <elhadji.dem@savoirfairelinux.com>',
'TheCloneMaster <the.clone.master@gmail.com>',
'Sandy Carter <bwrsandman@gmail.com>',
'Rudolf Schnapka <rs@techno-flex.de>',
'Sebastien Alix <sebastien.alix@osiell.com>',
'Jairo Llopis <j.llopis@grupoesoc.es>',
'Richard deMeester <richard@willowit.com.au>',
],
"author": "Odoo Community Association (OCA),Odoo SA",
"license": "AGPL-3", "license": "AGPL-3",
'application': False, 'application': False,
'installable': False,
'installable': True,
'auto_install': False, 'auto_install': False,
"depends": [ "depends": [
"base", "base",

6
partner_contact_in_several_companies/demo/ir_actions.xml

@ -1,7 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<odoo> <odoo>
<data>
<record id="action_partner_form" model="ir.actions.act_window"> <record id="action_partner_form" model="ir.actions.act_window">
<field name="name">All Customers in All Positions</field> <field name="name">All Customers in All Positions</field>
<field name="type">ir.actions.act_window</field> <field name="type">ir.actions.act_window</field>
@ -11,6 +9,4 @@
<field name="context">{"search_default_customer":1, 'search_show_all_positions': {'is_set': True, 'set_value': True}}</field> <field name="context">{"search_default_customer":1, 'search_show_all_positions': {'is_set': True, 'set_value': True}}</field>
<field name="search_view_id" ref="base.view_res_partner_filter"/> <field name="search_view_id" ref="base.view_res_partner_filter"/>
</record> </record>
</data>
</odoo>
</odoo>

6
partner_contact_in_several_companies/demo/res_partner.xml

@ -1,7 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<odoo> <odoo>
<data>
<record id="res_partner_main2_position_consultant" model="res.partner"> <record id="res_partner_main2_position_consultant" model="res.partner">
<field name="name">Roger Scott</field> <field name="name">Roger Scott</field>
<field name="function">Consultant</field> <field name="function">Consultant</field>
@ -21,6 +19,4 @@
<field name="parent_id" ref="base.main_partner"/> <field name="parent_id" ref="base.main_partner"/>
<field name="contact_id" ref="res_partner_contact1"/> <field name="contact_id" ref="res_partner_contact1"/>
</record> </record>
</data>
</odoo>
</odoo>

2
partner_contact_in_several_companies/models/ir_actions.py

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import models, api
from odoo import api, models
class IRActionsWindow(models.Model): class IRActionsWindow(models.Model):

39
partner_contact_in_several_companies/models/res_partner.py

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import fields, models, _, api
from openerp.osv import expression
from odoo import api, fields, models, _
from odoo.osv import expression
class ResPartner(models.Model): class ResPartner(models.Model):
@ -12,8 +12,9 @@ class ResPartner(models.Model):
[('standalone', _('Standalone Contact')), [('standalone', _('Standalone Contact')),
('attached', _('Attached to existing Contact')), ('attached', _('Attached to existing Contact')),
], ],
compute='_get_contact_type',
required=True, select=1, store=True,
compute='_compute_contact_type',
store=True,
index=True,
default='standalone') default='standalone')
contact_id = fields.Many2one('res.partner', string='Main Contact', contact_id = fields.Many2one('res.partner', string='Main Contact',
domain=[('is_company', '=', False), domain=[('is_company', '=', False),
@ -23,10 +24,11 @@ class ResPartner(models.Model):
other_contact_ids = fields.One2many('res.partner', 'contact_id', other_contact_ids = fields.One2many('res.partner', 'contact_id',
string='Others Positions') string='Others Positions')
@api.one
@api.multi
@api.depends('contact_id') @api.depends('contact_id')
def _get_contact_type(self):
self.contact_type = self.contact_id and 'attached' or 'standalone'
def _compute_contact_type(self):
for rec in self:
rec.contact_type = 'attached' if rec.contact_id else 'standalone'
def _basecontact_check_context(self, mode): def _basecontact_check_context(self, mode):
""" Remove 'search_show_all_positions' for non-search mode. """ Remove 'search_show_all_positions' for non-search mode.
@ -115,8 +117,7 @@ class ResPartner(models.Model):
self.ensure_one() self.ensure_one()
if self.contact_id: if self.contact_id:
contact_fields = self._contact_fields() contact_fields = self._contact_fields()
sync_vals = self._update_fields_values(self.contact_id,
contact_fields)
sync_vals = self.contact_id._update_fields_values(contact_fields)
self.write(sync_vals) self.write(sync_vals)
def update_contact(self, vals): def update_contact(self, vals):
@ -129,26 +130,26 @@ class ResPartner(models.Model):
if contact_vals: if contact_vals:
self.with_context(__update_contact_lock=True).write(contact_vals) self.with_context(__update_contact_lock=True).write(contact_vals)
@api.model
def _fields_sync(self, partner, update_values):
@api.multi
def _fields_sync(self, update_values):
"""Sync commercial fields and address fields from company and to """Sync commercial fields and address fields from company and to
children, contact fields from contact and to attached contact children, contact fields from contact and to attached contact
after create/update, just as if those were all modeled as after create/update, just as if those were all modeled as
fields.related to the parent fields.related to the parent
""" """
super(ResPartner, self)._fields_sync(partner, update_values)
self.ensure_one()
super(ResPartner, self)._fields_sync(update_values)
contact_fields = self._contact_fields() contact_fields = self._contact_fields()
# 1. From UPSTREAM: sync from parent contact # 1. From UPSTREAM: sync from parent contact
if update_values.get('contact_id'): if update_values.get('contact_id'):
partner._contact_sync_from_parent()
self._contact_sync_from_parent()
# 2. To DOWNSTREAM: sync contact fields to parent or related # 2. To DOWNSTREAM: sync contact fields to parent or related
elif any(field in contact_fields for field in update_values): elif any(field in contact_fields for field in update_values):
update_ids = [
c.id for c in partner.other_contact_ids if not c.is_company
]
if partner.contact_id:
update_ids.append(partner.contact_id.id)
self.browse(update_ids).update_contact(update_values)
update_ids = self.other_contact_ids.filtered(
lambda p: not p.is_company)
if self.contact_id:
update_ids |= self.contact_id
update_ids.update_contact(update_values)
@api.onchange('contact_id') @api.onchange('contact_id')
def _onchange_contact_id(self): def _onchange_contact_id(self):

217
partner_contact_in_several_companies/tests/test_partner_contact_in_several_companies.py

@ -1,7 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp.tests import common
from odoo.tests import common
class PartnerContactInSeveralCompaniesCase(common.TransactionCase): class PartnerContactInSeveralCompaniesCase(common.TransactionCase):
@ -9,254 +8,212 @@ class PartnerContactInSeveralCompaniesCase(common.TransactionCase):
def setUp(self): def setUp(self):
"""*****setUp*****""" """*****setUp*****"""
super(PartnerContactInSeveralCompaniesCase, self).setUp() super(PartnerContactInSeveralCompaniesCase, self).setUp()
cr, uid = self.cr, self.uid
ModelData = self.registry('ir.model.data')
self.partner = self.registry('res.partner')
self.action = self.registry('ir.actions.act_window')
self.partner = self.env['res.partner']
self.action = self.env['ir.actions.act_window']
current_module = 'partner_contact_in_several_companies'
# Get test records reference # Get test records reference
for attr, module, name in [
('main_partner_id', 'base', 'main_partner'),
('bob_contact_id',
'partner_contact_in_several_companies',
'res_partner_contact1'),
('bob_job1_id',
'partner_contact_in_several_companies',
'res_partner_contact1_work_position1'),
('roger_contact_id', 'base', 'res_partner_main2'),
('roger_job2_id',
'partner_contact_in_several_companies',
'res_partner_main2_position_consultant'),
('base_partner_action_id', 'base', 'action_partner_form'),
('custom_partner_action_id',
'partner_contact_in_several_companies',
'action_partner_form'),
]:
r = ModelData.get_object_reference(cr, uid, module, name)
setattr(self, attr, r[1] if r else False)
self.main_partner = self.env.ref('base.main_partner')
self.bob_contact = self.env.ref(
'%s.res_partner_contact1' % current_module)
self.bob_job1 = self.env.ref(
'%s.res_partner_contact1_work_position1' % current_module)
self.roger_contact = self.env.ref('base.res_partner_main2')
self.roger_job2 = self.env.ref(
'%s.res_partner_main2_position_consultant' % current_module)
def test_00_show_only_standalone_contact(self): def test_00_show_only_standalone_contact(self):
"""Check that only standalone contact are shown if context """Check that only standalone contact are shown if context
explicitly state to not display all positions explicitly state to not display all positions
""" """
cr, uid = self.cr, self.uid
ctx = {'search_show_all_positions': {'is_set': True, ctx = {'search_show_all_positions': {'is_set': True,
'set_value': False 'set_value': False
}} }}
partner_ids = self.partner.search(cr, uid, [], context=ctx)
partner_ids.sort()
self.assertTrue(self.bob_job1_id not in partner_ids)
self.assertTrue(self.roger_job2_id not in partner_ids)
partner_ids = self.partner.with_context(ctx).search([])
self.assertTrue(self.bob_job1 not in partner_ids)
self.assertTrue(self.roger_job2 not in partner_ids)
def test_01_show_all_positions(self): def test_01_show_all_positions(self):
"""Check that all contact are show if context is empty or """Check that all contact are show if context is empty or
explicitly state to display all positions or the "is_set" explicitly state to display all positions or the "is_set"
value has been set to False. value has been set to False.
""" """
cr, uid = self.cr, self.uid
partner_ids = self.partner.search(cr, uid, [], context=None)
self.assertTrue(self.bob_job1_id in partner_ids)
self.assertTrue(self.roger_job2_id in partner_ids)
partner_ids = self.partner.search([])
self.assertTrue(self.bob_job1 in partner_ids)
self.assertTrue(self.roger_job2 in partner_ids)
ctx = {'search_show_all_positions': {'is_set': False}} ctx = {'search_show_all_positions': {'is_set': False}}
partner_ids = self.partner.search(cr, uid, [], context=ctx)
self.assertTrue(self.bob_job1_id in partner_ids)
self.assertTrue(self.roger_job2_id in partner_ids)
partner_ids = self.partner.with_context(ctx).search([])
self.assertTrue(self.bob_job1 in partner_ids)
self.assertTrue(self.roger_job2 in partner_ids)
ctx = {'search_show_all_positions': {'is_set': True, ctx = {'search_show_all_positions': {'is_set': True,
'set_value': True 'set_value': True
}} }}
partner_ids = self.partner.search(cr, uid, [], context=ctx)
self.assertTrue(self.bob_job1_id in partner_ids)
self.assertTrue(self.roger_job2_id in partner_ids)
partner_ids = self.partner.with_context(ctx).search([])
self.assertTrue(self.bob_job1 in partner_ids)
self.assertTrue(self.roger_job2 in partner_ids)
def test_02_reading_other_contact_one2many_show_all_positions(self): def test_02_reading_other_contact_one2many_show_all_positions(self):
"""Check that readonly partner's ``other_contact_ids`` return """Check that readonly partner's ``other_contact_ids`` return
all values whatever the context all values whatever the context
""" """
cr, uid = self.cr, self.uid
def read_other_contacts(pid, context=None):
return self.partner.read(
cr, uid, [pid], ['other_contact_ids'],
context=context)[0]['other_contact_ids']
def read_contacts(pid, context=None):
return self.partner.read(
cr, uid, [pid], ['child_ids'], context=context)[0]['child_ids']
ctx = None
ctx = {}
self.assertEqual( self.assertEqual(
read_other_contacts(self.bob_contact_id, context=ctx),
[self.bob_job1_id],
self.bob_job1, self.bob_contact.with_context(ctx).other_contact_ids
) )
ctx = {'search_show_all_positions': {'is_set': False}} ctx = {'search_show_all_positions': {'is_set': False}}
self.assertEqual(read_other_contacts(
self.bob_contact_id, context=ctx),
[self.bob_job1_id],
self.assertEqual(
self.bob_job1, self.bob_contact.with_context(ctx).other_contact_ids
) )
ctx = {'search_show_all_positions': {'is_set': True, ctx = {'search_show_all_positions': {'is_set': True,
'set_value': False
'set_value': False,
}} }}
self.assertEqual(read_other_contacts(
self.bob_contact_id, context=ctx),
[self.bob_job1_id],
self.assertEqual(
self.bob_job1, self.bob_contact.with_context(ctx).other_contact_ids
) )
ctx = {'search_show_all_positions': {'is_set': True, ctx = {'search_show_all_positions': {'is_set': True,
'set_value': True
'set_value': True,
}} }}
self.assertEqual( self.assertEqual(
read_other_contacts(self.bob_contact_id, context=ctx),
[self.bob_job1_id],
self.bob_job1, self.bob_contact.with_context(ctx).other_contact_ids
) )
ctx = None
ctx = {}
self.assertIn( self.assertIn(
self.bob_job1_id,
read_contacts(self.main_partner_id, context=ctx),
)
self.bob_job1,
self.main_partner.with_context(ctx).child_ids)
ctx = {'search_show_all_positions': {'is_set': False}} ctx = {'search_show_all_positions': {'is_set': False}}
self.assertIn( self.assertIn(
self.bob_job1_id,
read_contacts(self.main_partner_id, context=ctx),
)
self.bob_job1,
self.main_partner.with_context(ctx).child_ids)
ctx = {'search_show_all_positions': {'is_set': True, ctx = {'search_show_all_positions': {'is_set': True,
'set_value': False
'set_value': False,
}} }}
self.assertIn( self.assertIn(
self.bob_job1_id,
read_contacts(self.main_partner_id, context=ctx),
)
self.bob_job1,
self.main_partner.with_context(ctx).child_ids)
ctx = {'search_show_all_positions': {'is_set': True, ctx = {'search_show_all_positions': {'is_set': True,
'set_value': True
'set_value': True,
}} }}
self.assertIn( self.assertIn(
self.bob_job1_id,
read_contacts(self.main_partner_id, context=ctx),
)
self.bob_job1,
self.main_partner.with_context(ctx).child_ids)
def test_03_search_match_attached_contacts(self): def test_03_search_match_attached_contacts(self):
"""Check that searching partner also return partners having """Check that searching partner also return partners having
attached contacts matching search criteria attached contacts matching search criteria
""" """
cr, uid = self.cr, self.uid
# Bob's contact has one other position which is related to # Bob's contact has one other position which is related to
# 'YourCompany' # 'YourCompany'
# so search for all contacts working for 'YourCompany' # so search for all contacts working for 'YourCompany'
# should contain Bob position. # should contain Bob position.
partner_ids = self.partner.search( partner_ids = self.partner.search(
cr, uid,
[('parent_id', 'ilike', 'YourCompany')],
context=None
)
self.assertIn(self.bob_job1_id, partner_ids, )
[('parent_id', 'ilike', 'YourCompany')])
self.assertTrue(self.bob_job1 in partner_ids)
# but when searching without 'all positions', # but when searching without 'all positions',
# we should get the position standalone contact instead. # we should get the position standalone contact instead.
ctx = {'search_show_all_positions': {'is_set': True, ctx = {'search_show_all_positions': {'is_set': True,
'set_value': False
'set_value': False,
}} }}
partner_ids = self.partner.search(
cr, uid,
[('parent_id', 'ilike', 'YourCompany')],
context=ctx
)
self.assertIn(self.bob_contact_id, partner_ids, )
partner_ids = self.partner.with_context(ctx).search(
[('parent_id', 'ilike', 'YourCompany')])
self.assertTrue(self.bob_contact in partner_ids)
def test_04_contact_creation(self): def test_04_contact_creation(self):
"""Check that we're begin to create a contact""" """Check that we're begin to create a contact"""
cr, uid = self.cr, self.uid
# Create a contact using only name # Create a contact using only name
new_contact_id = self.partner.create(cr, uid, {'name': 'Bob Egnops'})
new_contact = self.partner.create({'name': 'Bob Egnops'})
self.assertEqual( self.assertEqual(
self.partner.browse(cr, uid, new_contact_id).contact_type,
new_contact.contact_type,
'standalone', 'standalone',
) )
# Create a contact with only contact_id # Create a contact with only contact_id
new_contact_id = self.partner.create(
cr, uid, {'contact_id': self.bob_contact_id}
new_contact = self.partner.create(
{'contact_id': self.bob_contact.id}
) )
new_contact = self.partner.browse(cr, uid, new_contact_id)
self.assertEqual(new_contact.name, 'Bob Egnops')
self.assertEqual(new_contact.contact_type, 'attached')
self.assertEqual(new_contact.name, u'Bob Egnops')
self.assertEqual(new_contact.contact_type, u'attached')
# Create a contact with both contact_id and name; # Create a contact with both contact_id and name;
# contact's name should override provided value in that case # contact's name should override provided value in that case
new_contact_id = self.partner.create(
cr, uid, {'contact_id': self.bob_contact_id, 'name': 'Rob Egnops'}
new_contact = self.partner.create(
{'contact_id': self.bob_contact.id, 'name': 'Rob Egnops'}
) )
self.assertEqual( self.assertEqual(
self.partner.browse(cr, uid, new_contact_id).name,
'Bob Egnops'
new_contact.name,
u'Bob Egnops'
) )
# Reset contact to standalone # Reset contact to standalone
self.partner.write(cr, uid, [new_contact_id], {'contact_id': False})
new_contact.write({'contact_id': False})
self.assertEqual( self.assertEqual(
self.partner.browse(cr, uid, new_contact_id).contact_type,
'standalone',
new_contact.contact_type,
u'standalone',
) )
# Reset contact to attached, and ensure only it is unlinked (i.e. # Reset contact to attached, and ensure only it is unlinked (i.e.
# context is ignored). # context is ignored).
self.partner.write(cr, uid, [new_contact_id],
{'contact_id': self.bob_contact_id})
new_contact.write({'contact_id': self.bob_contact.id})
ctx = {'search_show_all_positions': {'is_set': True, ctx = {'search_show_all_positions': {'is_set': True,
'set_value': True 'set_value': True
}} }}
self.partner.unlink(cr, uid, [new_contact_id], context=ctx)
partner_ids = self.partner.search(
cr, uid, [('id', 'in', [new_contact_id, self.bob_contact_id])])
self.assertIn(self.bob_contact_id, partner_ids)
self.assertNotIn(new_contact_id, partner_ids)
new_contact.with_context(ctx).unlink()
partner_ids = self.partner.with_context(ctx).search(
[('id', 'in', [new_contact.id, self.bob_contact.id])])
self.assertIn(self.bob_contact, partner_ids)
self.assertNotIn(new_contact, partner_ids)
def test_05_contact_fields_sync(self): def test_05_contact_fields_sync(self):
"""Check that contact's fields are correctly synced between """Check that contact's fields are correctly synced between
parent contact or related contacts parent contact or related contacts
""" """
cr, uid = self.cr, self.uid
# Test DOWNSTREAM sync # Test DOWNSTREAM sync
self.partner.write(
cr, uid, [self.bob_contact_id], {'name': 'Rob Egnops'}
self.bob_contact.write(
{'name': 'Rob Egnops'}
) )
self.assertEqual( self.assertEqual(
self.partner.browse(cr, uid, self.bob_job1_id).name,
self.bob_job1.name,
'Rob Egnops', 'Rob Egnops',
) )
# Test UPSTREAM sync # Test UPSTREAM sync
self.partner.write(cr, uid, [self.bob_job1_id], {'name': 'Bob Egnops'})
self.bob_job1.write({'name': 'Bob Egnops'})
self.assertEqual( self.assertEqual(
self.partner.browse(cr, uid, self.bob_contact_id).name,
self.bob_contact.name,
'Bob Egnops', 'Bob Egnops',
) )
def test_06_ir_action(self): def test_06_ir_action(self):
"""Check ir_action context is auto updated. """Check ir_action context is auto updated.
""" """
cr, uid = self.cr, self.uid
new_context_val = "'search_show_all_positions': " \ new_context_val = "'search_show_all_positions': " \
"{'is_set': True, 'set_value': False},"
"{'is_set': True, 'set_value': False}"
details = self.env['ir.actions.act_window'].for_xml_id(
'base',
'action_partner_form')
details = self.action.read(
cr, uid, [self.base_partner_action_id]
)
self.assertIn( self.assertIn(
new_context_val, new_context_val,
details[0]['context'],
details['context'],
msg='Default actions not updated with new context' msg='Default actions not updated with new context'
) )
details = self.action.read(
cr, uid, [self.custom_partner_action_id]
)
details = self.env['ir.actions.act_window'].for_xml_id(
'partner_contact_in_several_companies',
'action_partner_form')
self.assertNotIn( self.assertNotIn(
new_context_val, new_context_val,
details[0]['context'],
details['context'],
msg='Custom actions incorrectly updated with new context' msg='Custom actions incorrectly updated with new context'
) )

18
partner_contact_in_several_companies/views/res_partner.xml

@ -1,7 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<data>
<record id="view_res_partner_filter_contact" model="ir.ui.view"> <record id="view_res_partner_filter_contact" model="ir.ui.view">
<field name="name">res.partner.select.contact</field> <field name="name">res.partner.select.contact</field>
<field name="model">res.partner</field> <field name="model">res.partner</field>
@ -75,7 +73,7 @@
</div> </div>
<div class="oe_kanban_details"> <div class="oe_kanban_details">
<field name="name"/> <field name="name"/>
<div t-if="record.function.raw_value"><field name="function"/></div>
<div t-if="record.function.raw_value"><field name="function"/> at <field name="parent_id"/></div>
<div t-if="record.email.raw_value"><field name="email"/></div> <div t-if="record.email.raw_value"><field name="email"/></div>
<div t-if="record.phone.raw_value">Phone: <field name="phone"/></div> <div t-if="record.phone.raw_value">Phone: <field name="phone"/></div>
<div t-if="record.mobile.raw_value">Mobile: <field name="mobile"/></div> <div t-if="record.mobile.raw_value">Mobile: <field name="mobile"/></div>
@ -97,7 +95,7 @@
<field name="street" placeholder="Street..." class="o_address_street"/> <field name="street" placeholder="Street..." class="o_address_street"/>
<field name="street2" placeholder="Street 2..." class="o_address_street"/> <field name="street2" placeholder="Street 2..." class="o_address_street"/>
<field name="city" placeholder="City" class="o_address_city"/> <field name="city" placeholder="City" class="o_address_city"/>
<field name="state_id" class="o_address_state" placeholder="State" options='{"no_open": True}' on_change="onchange_state(state_id)" context="{'country_id': country_id, 'zip': zip}"/>
<field name="state_id" class="o_address_state" placeholder="State" options='{"no_open": True}' context="{'country_id': country_id, 'zip': zip}"/>
<field name="zip" placeholder="ZIP" class="o_address_zip"/> <field name="zip" placeholder="ZIP" class="o_address_zip"/>
<field name="country_id" placeholder="Country" class="o_address_country" options='{"no_open": True, "no_create": True}'/> <field name="country_id" placeholder="Country" class="o_address_country" options='{"no_open": True, "no_create": True}'/>
</div> </div>
@ -123,12 +121,6 @@
</field> </field>
</page> </page>
</page> </page>
<xpath expr="//field[@name='category_id']" position="before">
<group>
<label for="contact_type" class="oe_edit_only"/>
<field name="contact_type" readonly="0" nolabel="1"/>
</group>
</xpath>
<xpath expr="//field[@name='child_ids']/form//field[@name='name']" position="before"> <xpath expr="//field[@name='child_ids']/form//field[@name='name']" position="before">
<field name='contact_type' readonly='0'/> <field name='contact_type' readonly='0'/>
<field name="contact_id" string="Contact" <field name="contact_id" string="Contact"
@ -145,7 +137,6 @@
<field name="model">res.partner</field> <field name="model">res.partner</field>
<field name="inherit_id" ref="partner_contact_personal_information_page.personal_information"/> <field name="inherit_id" ref="partner_contact_personal_information_page.personal_information"/>
<field name="arch" type="xml"> <field name="arch" type="xml">
<data>
<xpath expr="//page[@name='personal_information_page']/group[@name='personal_information_group']" <xpath expr="//page[@name='personal_information_page']/group[@name='personal_information_group']"
position='attributes'> position='attributes'>
<attribute name='attrs'>{'invisible': [('contact_id','!=',False)]}</attribute> <attribute name='attrs'>{'invisible': [('contact_id','!=',False)]}</attribute>
@ -161,7 +152,6 @@
options="{'always_reload': True}"/> options="{'always_reload': True}"/>
</p> </p>
</xpath> </xpath>
</data>
</field> </field>
</record> </record>
@ -187,6 +177,4 @@
</xpath> </xpath>
</field> </field>
</record> </record>
</data>
</odoo>
</odoo>
Loading…
Cancel
Save