Browse Source

[MIG] partner_multi_relation. Actual 13.0 migration.

14.0
Ronald Portier 4 years ago
committed by Raf Ven
parent
commit
f7d89cf108
  1. 2
      partner_multi_relation/__init__.py
  2. 4
      partner_multi_relation/__manifest__.py
  3. 13
      partner_multi_relation/data/demo.xml
  4. 2
      partner_multi_relation/models/res_partner.py
  5. 1
      partner_multi_relation/models/res_partner_relation.py
  6. 17
      partner_multi_relation/models/res_partner_relation_all.py
  7. 4
      partner_multi_relation/models/res_partner_relation_type.py
  8. 2
      partner_multi_relation/models/res_partner_relation_type_selection.py
  9. 1
      partner_multi_relation/readme/CONTRIBUTORS.rst
  10. 2
      partner_multi_relation/tests/__init__.py
  11. 6
      partner_multi_relation/tests/test_partner_relation.py
  12. 19
      partner_multi_relation/tests/test_partner_relation_all.py
  13. 2
      partner_multi_relation/tests/test_partner_relation_common.py
  14. 2
      partner_multi_relation/tests/test_partner_search.py
  15. 3
      partner_multi_relation/views/res_partner.xml
  16. 15
      partner_multi_relation/views/res_partner_relation_all.xml

2
partner_multi_relation/__init__.py

@ -1,2 +1,2 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from . import models from . import models

4
partner_multi_relation/__manifest__.py

@ -1,5 +1,5 @@
# Copyright 2013-2017 Therp BV <http://therp.nl>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
# Copyright 2013-2020 Therp BV <http://therp.nl>.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
{ {
"name": "Partner Relations", "name": "Partner Relations",
"version": "13.0.1.0.0", "version": "13.0.1.0.0",

13
partner_multi_relation/data/demo.xml

@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<odoo> <odoo>
<!-- Added partner categories and partners to this file, because it <!-- Added partner categories and partners to this file, because it
turned out to be a bad idea to rely on demo data in base module,
that can change from release to release. Only dependency on
countries remain. They are less likely to change/disappear.
-->
turned out to be a bad idea to rely on demo data in base module,
that can change from release to release. Only dependency on
countries remain. They are less likely to change/disappear.
-->
<!-- Partner relation types --> <!-- Partner relation types -->
<record id="rel_type_assistant" model="res.partner.relation.type"> <record id="rel_type_assistant" model="res.partner.relation.type">
<field name="name">Is assistant of</field> <field name="name">Is assistant of</field>
@ -48,8 +48,6 @@
name="category_id" name="category_id"
eval="[(6, 0, [ref('res_partner_category_pmr_11'), ref('res_partner_category_pmr_4')])]" eval="[(6, 0, [ref('res_partner_category_pmr_11'), ref('res_partner_category_pmr_4')])]"
/> />
<field name="supplier">1</field>
<field name="customer">1</field>
<field name="is_company">1</field> <field name="is_company">1</field>
<field name="city">Le Bourget du Lac</field> <field name="city">Le Bourget du Lac</field>
<field name="zip">73377</field> <field name="zip">73377</field>
@ -65,7 +63,6 @@
name="category_id" name="category_id"
eval="[(6, 0, [ref('res_partner_category_pmr_4'), ref('res_partner_category_pmr_11')])]" eval="[(6, 0, [ref('res_partner_category_pmr_4'), ref('res_partner_category_pmr_11')])]"
/> />
<field name="supplier">1</field>
<field name="is_company">1</field> <field name="is_company">1</field>
<field name="city">Champs sur Marne</field> <field name="city">Champs sur Marne</field>
<field name="zip">77420</field> <field name="zip">77420</field>
@ -78,8 +75,6 @@
<record id="res_partner_pmr_super" model="res.partner"> <record id="res_partner_pmr_super" model="res.partner">
<field name="name">Super Washing Powder Company</field> <field name="name">Super Washing Powder Company</field>
<field name="category_id" eval="[(6,0,[ref('res_partner_category_pmr_5')])]" /> <field name="category_id" eval="[(6,0,[ref('res_partner_category_pmr_5')])]" />
<field name="supplier">1</field>
<field eval="1" name="customer" />
<field name="is_company">1</field> <field name="is_company">1</field>
<field name="street">3rd Floor, Room 3-C,</field> <field name="street">3rd Floor, Room 3-C,</field>
<field <field

2
partner_multi_relation/models/res_partner.py

@ -169,7 +169,6 @@ class ResPartner(models.Model):
count=count, count=count,
) )
@api.multi
def get_partner_type(self): def get_partner_type(self):
"""Get partner type for relation. """Get partner type for relation.
:return: 'c' for company or 'p' for person :return: 'c' for company or 'p' for person
@ -178,7 +177,6 @@ class ResPartner(models.Model):
self.ensure_one() self.ensure_one()
return "c" if self.is_company else "p" return "c" if self.is_company else "p"
@api.multi
def action_view_relations(self): def action_view_relations(self):
for contact in self: for contact in self:
relation_model = self.env["res.partner.relation.all"] relation_model = self.env["res.partner.relation.all"]

1
partner_multi_relation/models/res_partner_relation.py

@ -82,7 +82,6 @@ class ResPartnerRelation(models.Model):
""" """
self._check_partner("right") self._check_partner("right")
@api.multi
def _check_partner(self, side): def _check_partner(self, side):
"""Check partner for required company or person, and for category """Check partner for required company or person, and for category

17
partner_multi_relation/models/res_partner_relation_all.py

@ -44,8 +44,8 @@ SELECT
FROM res_partner_relation rel""" FROM res_partner_relation rel"""
class ResPartnerRelationAll(models.AbstractModel):
"""Abstract model to show each relation from two sides."""
class ResPartnerRelationAll(models.Model):
"""Model to show each relation from two sides."""
_auto = False _auto = False
_log_access = False _log_access = False
@ -190,7 +190,6 @@ CREATE OR REPLACE VIEW %%(table)s AS
""" """
return "" return ""
@api.model_cr_context
def _auto_init(self): def _auto_init(self):
cr = self._cr cr = self._cr
drop_view_if_exists(cr, self._table) drop_view_if_exists(cr, self._table)
@ -215,7 +214,6 @@ CREATE OR REPLACE VIEW %%(table)s AS
("other_partner_id", operator, value), ("other_partner_id", operator, value),
] ]
@api.multi
def name_get(self): def name_get(self):
return { return {
this.id: "%s %s %s" this.id: "%s %s %s"
@ -383,14 +381,12 @@ CREATE OR REPLACE VIEW %%(table)s AS
del vals[key] del vals[key]
return vals return vals
@api.multi
def get_base_resource(self): def get_base_resource(self):
"""Get base resource from res_model and res_id.""" """Get base resource from res_model and res_id."""
self.ensure_one() self.ensure_one()
base_model = self.env[self.res_model] base_model = self.env[self.res_model]
return base_model.browse([self.res_id]) return base_model.browse([self.res_id])
@api.multi
def write_resource(self, base_resource, vals): def write_resource(self, base_resource, vals):
"""write handled by base resource.""" """write handled by base resource."""
self.ensure_one() self.ensure_one()
@ -399,6 +395,7 @@ CREATE OR REPLACE VIEW %%(table)s AS
relation_model = self.env["res.partner.relation"] relation_model = self.env["res.partner.relation"]
assert self.res_model == relation_model._name assert self.res_model == relation_model._name
base_resource.write(vals) base_resource.write(vals)
base_resource.flush()
@api.model @api.model
def _get_type_selection_from_vals(self, vals): def _get_type_selection_from_vals(self, vals):
@ -416,10 +413,8 @@ CREATE OR REPLACE VIEW %%(table)s AS
or False or False
) )
@api.multi
def write(self, vals): def write(self, vals):
"""For model 'res.partner.relation' call write on underlying model.
"""
"""For model 'res.partner.relation' call write on underlying model."""
new_type_selection = self._get_type_selection_from_vals(vals) new_type_selection = self._get_type_selection_from_vals(vals)
for rec in self: for rec in self:
type_selection = new_type_selection or rec.type_selection_id type_selection = new_type_selection or rec.type_selection_id
@ -428,7 +423,7 @@ CREATE OR REPLACE VIEW %%(table)s AS
rec.write_resource(base_resource, vals) rec.write_resource(base_resource, vals)
# Invalidate cache to make res.partner.relation.all reflect changes # Invalidate cache to make res.partner.relation.all reflect changes
# in underlying res.partner.relation: # in underlying res.partner.relation:
self.env.clear()
self.invalidate_cache(None, self.ids)
return True return True
@api.model @api.model
@ -464,7 +459,6 @@ CREATE OR REPLACE VIEW %%(table)s AS
res_id = self._compute_id(base_resource, type_selection) res_id = self._compute_id(base_resource, type_selection)
return self.browse(res_id) return self.browse(res_id)
@api.multi
def unlink_resource(self, base_resource): def unlink_resource(self, base_resource):
"""Delegate unlink to underlying model.""" """Delegate unlink to underlying model."""
self.ensure_one() self.ensure_one()
@ -474,7 +468,6 @@ CREATE OR REPLACE VIEW %%(table)s AS
assert self.res_model == relation_model._name assert self.res_model == relation_model._name
base_resource.unlink() base_resource.unlink()
@api.multi
def unlink(self): def unlink(self):
"""For model 'res.partner.relation' call unlink on underlying model. """For model 'res.partner.relation' call unlink on underlying model.
""" """

4
partner_multi_relation/models/res_partner_relation_type.py

@ -83,7 +83,6 @@ class ResPartnerRelationType(models.Model):
elif not relation.date_end or relation.date_end > today: elif not relation.date_end or relation.date_end > today:
relation.write({"date_end": today}) relation.write({"date_end": today})
@api.multi
def check_existing(self, vals): def check_existing(self, vals):
"""Check wether records exist that do not fit new criteria.""" """Check wether records exist that do not fit new criteria."""
relation_model = self.env["res.partner.relation"] relation_model = self.env["res.partner.relation"]
@ -207,7 +206,6 @@ class ResPartnerRelationType(models.Model):
end_relation_types = self.filtered(lambda t: t.handle_invalid_onchange == "end") end_relation_types = self.filtered(lambda t: t.handle_invalid_onchange == "end")
end_relation_types._end_active_reflexive_relations() end_relation_types._end_active_reflexive_relations()
@api.multi
def _update_right_vals(self, vals): def _update_right_vals(self, vals):
"""Make sure that on symmetric relations, right vals follow left vals. """Make sure that on symmetric relations, right vals follow left vals.
@ -231,7 +229,6 @@ class ResPartnerRelationType(models.Model):
self._update_right_vals(vals) self._update_right_vals(vals)
return super(ResPartnerRelationType, self).create(vals) return super(ResPartnerRelationType, self).create(vals)
@api.multi
def write(self, vals): def write(self, vals):
"""Handle existing relations if conditions change.""" """Handle existing relations if conditions change."""
self.check_existing(vals) self.check_existing(vals)
@ -248,7 +245,6 @@ class ResPartnerRelationType(models.Model):
return True return True
@api.multi
def unlink(self): def unlink(self):
"""Allow delete of relation type, even when connections exist. """Allow delete of relation type, even when connections exist.

2
partner_multi_relation/models/res_partner_relation_type_selection.py

@ -73,7 +73,6 @@ class ResPartnerRelationTypeSelection(models.Model):
""" """
return "" return ""
@api.model_cr_context
def _auto_init(self): def _auto_init(self):
cr = self._cr cr = self._cr
drop_view_if_exists(cr, self._table) drop_view_if_exists(cr, self._table)
@ -121,7 +120,6 @@ CREATE OR REPLACE VIEW %(table)s AS
) )
return super(ResPartnerRelationTypeSelection, self)._auto_init() return super(ResPartnerRelationTypeSelection, self)._auto_init()
@api.multi
def name_get(self): def name_get(self):
"""Get name or name_inverse from underlying model.""" """Get name or name_inverse from underlying model."""
return [ return [

1
partner_multi_relation/readme/CONTRIBUTORS.rst

@ -5,3 +5,4 @@
* Bruno Joliveau <bruno.joliveau@savoirfairelinux.com> * Bruno Joliveau <bruno.joliveau@savoirfairelinux.com>
* Adriana Ierfino <adriana.ierfino@savoirfairelinux.com> * Adriana Ierfino <adriana.ierfino@savoirfairelinux.com>
* Numigi (tm) and all its contributors (https://bit.ly/numigiens) * Numigi (tm) and all its contributors (https://bit.ly/numigiens)
* Radovan Skolnik <radovan@skolnik.info>, KEMA SK s.r.o. (https://www.kema.sk)

2
partner_multi_relation/tests/__init__.py

@ -1,4 +1,4 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from . import test_partner_relation_common from . import test_partner_relation_common
from . import test_partner_relation from . import test_partner_relation
from . import test_partner_relation_all from . import test_partner_relation_all

6
partner_multi_relation/tests/test_partner_relation.py

@ -1,5 +1,5 @@
# Copyright 2016-2017 Therp BV # Copyright 2016-2017 Therp BV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from datetime import date, datetime, timedelta from datetime import date, datetime, timedelta
from dateutil.relativedelta import relativedelta from dateutil.relativedelta import relativedelta
@ -271,8 +271,7 @@ class TestPartnerRelation(TestPartnerRelationCommon):
) )
self.assertEqual(len(selection_symmetric), 2) self.assertEqual(len(selection_symmetric), 2)
# Now change to symmetric and test name and inverse name: # Now change to symmetric and test name and inverse name:
with self.env.do_in_draft():
type_symmetric.write({"name": "sym", "is_symmetric": True})
type_symmetric.write({"name": "sym", "is_symmetric": True})
self.assertEqual(type_symmetric.is_symmetric, True) self.assertEqual(type_symmetric.is_symmetric, True)
self.assertEqual(type_symmetric.name_inverse, type_symmetric.name) self.assertEqual(type_symmetric.name_inverse, type_symmetric.name)
self.assertEqual( self.assertEqual(
@ -287,6 +286,7 @@ class TestPartnerRelation(TestPartnerRelationCommon):
"contact_type_right": type_symmetric.contact_type_right, "contact_type_right": type_symmetric.contact_type_right,
} }
) )
type_symmetric.flush()
# symmetric relation should result in only one record in # symmetric relation should result in only one record in
# selection: # selection:
selection_symmetric = self.selection_model.search( selection_symmetric = self.selection_model.search(

19
partner_multi_relation/tests/test_partner_relation_all.py

@ -1,5 +1,5 @@
# Copyright 2016-2017 Therp BV # Copyright 2016-2017 Therp BV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from datetime import date from datetime import date
@ -56,6 +56,8 @@ class TestPartnerRelation(TestPartnerRelationCommon):
self.assertTrue(relation) self.assertTrue(relation)
self.assertEqual(relation.this_partner_id, self.partner_02_company) self.assertEqual(relation.this_partner_id, self.partner_02_company)
# Partner should have one relation now: # Partner should have one relation now:
relation.invalidate_cache(None, relation.ids)
self.partner_01_person.flush()
self.assertEqual(self.partner_01_person.relation_count, 1) self.assertEqual(self.partner_01_person.relation_count, 1)
# Test create without type_selection_id: # Test create without type_selection_id:
with self.assertRaises(ValidationError): with self.assertRaises(ValidationError):
@ -79,11 +81,10 @@ class TestPartnerRelation(TestPartnerRelationCommon):
), ),
) )
def test__regular_write(self):
def test_regular_write(self):
"""Test write with valid data.""" """Test write with valid data."""
relation = self._create_company2person_relation() relation = self._create_company2person_relation()
relation.write({"date_start": "2014-09-01"}) relation.write({"date_start": "2014-09-01"})
relation.invalidate_cache(ids=relation.ids)
self.assertEqual(relation.date_start, date(2014, 9, 1)) self.assertEqual(relation.date_start, date(2014, 9, 1))
def test_write_incompatible_dates(self): def test_write_incompatible_dates(self):
@ -252,18 +253,17 @@ class TestPartnerRelation(TestPartnerRelationCommon):
) )
# 4. Test with invalid or impossible combinations # 4. Test with invalid or impossible combinations
relation_nobody = self._get_empty_relation() relation_nobody = self._get_empty_relation()
with self.env.do_in_draft():
relation_nobody.type_selection_id = self.selection_nobody
relation_nobody.type_selection_id = self.selection_nobody
warning = relation_nobody.onchange_type_selection_id()["warning"] warning = relation_nobody.onchange_type_selection_id()["warning"]
self.assertTrue("message" in warning) self.assertTrue("message" in warning)
self.assertTrue("No this partner available" in warning["message"]) self.assertTrue("No this partner available" in warning["message"])
with self.env.do_in_draft():
relation_nobody.this_partner_id = self.partner_02_company
relation_nobody.this_partner_id = self.partner_02_company
warning = relation_nobody.onchange_type_selection_id()["warning"] warning = relation_nobody.onchange_type_selection_id()["warning"]
self.assertTrue("message" in warning) self.assertTrue("message" in warning)
self.assertTrue("incompatible" in warning["message"]) self.assertTrue("incompatible" in warning["message"])
# Allow left partner and check message for other partner: # Allow left partner and check message for other partner:
self.type_nobody.write({"partner_category_left": False}) self.type_nobody.write({"partner_category_left": False})
self.type_nobody.flush()
self.selection_nobody.invalidate_cache(ids=self.selection_nobody.ids) self.selection_nobody.invalidate_cache(ids=self.selection_nobody.ids)
warning = relation_nobody.onchange_type_selection_id()["warning"] warning = relation_nobody.onchange_type_selection_id()["warning"]
self.assertTrue("message" in warning) self.assertTrue("message" in warning)
@ -284,9 +284,8 @@ class TestPartnerRelation(TestPartnerRelationCommon):
self.assertTrue(("contact_type_this", "=", "c") in domain["type_selection_id"]) self.assertTrue(("contact_type_this", "=", "c") in domain["type_selection_id"])
# 3. Test with invalid or impossible combinations # 3. Test with invalid or impossible combinations
relation_nobody = self._get_empty_relation() relation_nobody = self._get_empty_relation()
with self.env.do_in_draft():
relation_nobody.this_partner_id = self.partner_02_company
relation_nobody.type_selection_id = self.selection_nobody
relation_nobody.this_partner_id = self.partner_02_company
relation_nobody.type_selection_id = self.selection_nobody
warning = relation_nobody.onchange_partner_id()["warning"] warning = relation_nobody.onchange_partner_id()["warning"]
self.assertTrue("message" in warning) self.assertTrue("message" in warning)
self.assertTrue("incompatible" in warning["message"]) self.assertTrue("incompatible" in warning["message"])

2
partner_multi_relation/tests/test_partner_relation_common.py

@ -1,5 +1,5 @@
# Copyright 2016 Therp BV # Copyright 2016 Therp BV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from odoo.tests import common from odoo.tests import common

2
partner_multi_relation/tests/test_partner_search.py

@ -1,6 +1,6 @@
# Copyright 2015 Camptocamp SA # Copyright 2015 Camptocamp SA
# Copyright 2016 Therp BV # Copyright 2016 Therp BV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from odoo import fields from odoo import fields
from odoo.exceptions import ValidationError from odoo.exceptions import ValidationError

3
partner_multi_relation/views/res_partner.xml

@ -33,9 +33,8 @@
<act_window <act_window
id="action_show_partner_multi_relation" id="action_show_partner_multi_relation"
name="Show partner's relations" name="Show partner's relations"
src_model="res.partner"
binding_model="res.partner"
res_model="res.partner.relation.all" res_model="res.partner.relation.all"
domain="[('this_partner_id', 'in', active_ids)]" domain="[('this_partner_id', 'in', active_ids)]"
key2="client_action_multi"
/> />
</odoo> </odoo>

15
partner_multi_relation/views/res_partner_relation_all.xml

@ -3,11 +3,7 @@
<record id="tree_res_partner_relation_all" model="ir.ui.view"> <record id="tree_res_partner_relation_all" model="ir.ui.view">
<field name="model">res.partner.relation.all</field> <field name="model">res.partner.relation.all</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree
string="Partner Relations"
colors="gray:not active; blue:date_start &gt; current_date"
editable="top"
>
<tree string="Partner Relations" editable="top">
<field <field
name="this_partner_id" name="this_partner_id"
required="True" required="True"
@ -75,17 +71,16 @@
<record id="action_res_partner_relation_all" model="ir.actions.act_window"> <record id="action_res_partner_relation_all" model="ir.actions.act_window">
<field name="name">Relations</field> <field name="name">Relations</field>
<field name="res_model">res.partner.relation.all</field> <field name="res_model">res.partner.relation.all</field>
<field name="view_type">form</field>
<field name="view_mode">tree</field> <field name="view_mode">tree</field>
<field name="view_id" ref="tree_res_partner_relation_all" /> <field name="view_id" ref="tree_res_partner_relation_all" />
<field name="search_view_id" ref="search_res_partner_relation_all" /> <field name="search_view_id" ref="search_res_partner_relation_all" />
<field name="context">{'active_test': 0}</field> <field name="context">{'active_test': 0}</field>
<field name="help" type="html"> <field name="help" type="html">
<p class="oe_view_nocontent_create"> <p class="oe_view_nocontent_create">
Record and track your partners' relations. Relations may
be linked to other partners with a type either directly
or inversely.
</p>
Record and track your partners' relations. Relations may
be linked to other partners with a type either directly
or inversely.
</p>
</field> </field>
</record> </record>
</odoo> </odoo>
Loading…
Cancel
Save