15 changed files with 712 additions and 0 deletions
-
50partner_multi_relation_hierarchy/README.rst
-
4partner_multi_relation_hierarchy/__init__.py
-
21partner_multi_relation_hierarchy/__manifest__.py
-
149partner_multi_relation_hierarchy/i18n/nl.po
-
148partner_multi_relation_hierarchy/i18n/partner_multi_relation_hierarchy.pot
-
7partner_multi_relation_hierarchy/models/__init__.py
-
39partner_multi_relation_hierarchy/models/res_partner.py
-
44partner_multi_relation_hierarchy/models/res_partner_relation.py
-
102partner_multi_relation_hierarchy/models/res_partner_relation_hierarchy.py
-
22partner_multi_relation_hierarchy/models/res_partner_relation_type.py
-
2partner_multi_relation_hierarchy/security/ir.model.access.csv
-
4partner_multi_relation_hierarchy/tests/__init__.py
-
68partner_multi_relation_hierarchy/tests/test_partner_hierarchy.py
-
35partner_multi_relation_hierarchy/views/res_partner.xml
-
17partner_multi_relation_hierarchy/views/res_partner_relation_type.xml
@ -0,0 +1,50 @@ |
|||||
|
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg |
||||
|
:alt: License |
||||
|
|
||||
|
Partner Multi Relation Hierarchy |
||||
|
================================ |
||||
|
|
||||
|
This module extends the concept of relations between partners with the concept |
||||
|
of an hierarchy. |
||||
|
|
||||
|
For istance a company belonging to a larger concern would have the concern 'above' it. |
||||
|
|
||||
|
Or a person might belong to a local organisation, that in turn might belong to a |
||||
|
provincial organisation, which might belong to a nation organisation. |
||||
|
|
||||
|
It will not be excluded that a partner might be connected to several hierarchies. |
||||
|
|
||||
|
The hierarchical 'chains' will be made visible on the partner. |
||||
|
|
||||
|
More info |
||||
|
--------- |
||||
|
|
||||
|
For further information, please visit: |
||||
|
|
||||
|
* https://www.odoo.com/forum/help-1 |
||||
|
|
||||
|
Known issues / Roadmap |
||||
|
====================== |
||||
|
|
||||
|
Credits |
||||
|
======= |
||||
|
|
||||
|
Contributors |
||||
|
------------ |
||||
|
|
||||
|
* Ronald Portier <ronald@therp.nl> |
||||
|
|
||||
|
Maintainer |
||||
|
---------- |
||||
|
|
||||
|
.. image:: http://odoo-community.org/logo.png |
||||
|
:alt: Odoo Community Association |
||||
|
:target: http://odoo-community.org |
||||
|
|
||||
|
This module is maintained by the OCA. |
||||
|
|
||||
|
OCA, or the Odoo Community Association, is a nonprofit organization whose |
||||
|
mission is to support the collaborative development of Odoo features and |
||||
|
promote its widespread use. |
||||
|
|
||||
|
To contribute to this module, please visit https://github.com/oca/partner-contact |
@ -0,0 +1,4 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright 2017 Therp BV <https://therp.nl> |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
from . import models |
@ -0,0 +1,21 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright 2017 Therp BV <https://therp.nl> |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
{ |
||||
|
"name": "Partner relation hierarchy", |
||||
|
"version": "10.0.0.1.0", |
||||
|
"author": "Therp BV,Odoo Community Association (OCA)", |
||||
|
"complexity": "normal", |
||||
|
"category": "Customer Relationship Management", |
||||
|
"license": "AGPL-3", |
||||
|
"depends": [ |
||||
|
"partner_multi_relation", |
||||
|
], |
||||
|
"data": [ |
||||
|
'views/res_partner.xml', |
||||
|
'views/res_partner_relation_type.xml', |
||||
|
'security/ir.model.access.csv', |
||||
|
], |
||||
|
"auto_install": False, |
||||
|
"installable": True, |
||||
|
} |
@ -0,0 +1,149 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * partner_multi_relation_hierarchy |
||||
|
# |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: Odoo Server 10.0\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2017-11-01 09:31+0000\n" |
||||
|
"PO-Revision-Date: 2017-11-01 09:31+0000\n" |
||||
|
"Last-Translator: Ronald Portier <ronald@therp.nl>, 2017\n" |
||||
|
"Language-Team: Dutch (https://www.transifex.com/oca/teams/23907/nl/)\n" |
||||
|
"MIME-Version: 1.0\n" |
||||
|
"Content-Type: text/plain; charset=UTF-8\n" |
||||
|
"Content-Transfer-Encoding: \n" |
||||
|
"Language: nl\n" |
||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model.fields,help:partner_multi_relation_hierarchy.field_res_partner_relation_hierarchy_hierarchy_display |
||||
|
msgid "Compact representation of hierarchy" |
||||
|
msgstr "Compacte weergave van de hiërarchie" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model.fields,field_description:partner_multi_relation_hierarchy.field_res_partner_relation_hierarchy_display_name |
||||
|
msgid "Display Name" |
||||
|
msgstr "Naam voor weergave" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model.fields,field_description:partner_multi_relation_hierarchy.field_res_partner_has_partner_above |
||||
|
#: model:ir.model.fields,field_description:partner_multi_relation_hierarchy.field_res_users_has_partner_above |
||||
|
msgid "Has partner above" |
||||
|
msgstr "Heeft relatie boven zich" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model.fields,field_description:partner_multi_relation_hierarchy.field_res_partner_relation_hierarchy_hierarchy_display |
||||
|
#: model:ir.ui.view,arch_db:partner_multi_relation_hierarchy.view_partner_form |
||||
|
msgid "Hierarchy" |
||||
|
msgstr "Hiërarchie" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model.fields,field_description:partner_multi_relation_hierarchy.field_res_partner_relation_hierarchy_id |
||||
|
msgid "ID" |
||||
|
msgstr "ID" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model.fields,field_description:partner_multi_relation_hierarchy.field_res_partner_relation_hierarchy___last_update |
||||
|
msgid "Last Modified on" |
||||
|
msgstr "Laatst gewijzigd" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model.fields,field_description:partner_multi_relation_hierarchy.field_res_partner_relation_hierarchy_level |
||||
|
msgid "Level" |
||||
|
msgstr "Niveau" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model.fields,help:partner_multi_relation_hierarchy.field_res_partner_relation_hierarchy_level |
||||
|
msgid "Number of levels that partner above is higher up" |
||||
|
msgstr "Niveau verschil met bovenliggende partner" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model,name:partner_multi_relation_hierarchy.model_res_partner |
||||
|
#: model:ir.model.fields,field_description:partner_multi_relation_hierarchy.field_res_partner_relation_hierarchy_partner_id |
||||
|
msgid "Partner" |
||||
|
msgstr "Relatie" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model,name:partner_multi_relation_hierarchy.model_res_partner_relation_type |
||||
|
msgid "Partner Relation Type" |
||||
|
msgstr "Type connectie" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model.fields,field_description:partner_multi_relation_hierarchy.field_res_partner_relation_hierarchy_partner_above_id |
||||
|
msgid "Partner above" |
||||
|
msgstr "Bovenliggende relatie" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model.fields,field_description:partner_multi_relation_hierarchy.field_res_partner_relation_hierarchy_partner_below_id |
||||
|
msgid "Partner below" |
||||
|
msgstr "Onderliggende relatie" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model.fields,help:partner_multi_relation_hierarchy.field_res_partner_relation_hierarchy_partner_below_id |
||||
|
msgid "Partner immediately below partner above in the hierarchy" |
||||
|
msgstr "Direct bovenliggende relatie in de hiërarchie" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model,name:partner_multi_relation_hierarchy.model_res_partner_relation |
||||
|
msgid "Partner relation" |
||||
|
msgstr "Connectie" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model.fields,help:partner_multi_relation_hierarchy.field_res_partner_relation_hierarchy_partner_above_id |
||||
|
msgid "Partner somewhere above in the hierarchy" |
||||
|
msgstr "Relatie één of meer plaatsen hoger in de hiërarchie" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model.fields,field_description:partner_multi_relation_hierarchy.field_res_partner_partner_above_ids_4248 |
||||
|
#: model:ir.model.fields,field_description:partner_multi_relation_hierarchy.field_res_users_partner_above_ids |
||||
|
msgid "Partners above in hierarchy" |
||||
|
msgstr "Bovenliggende partners in de hiërarchie" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model.fields,field_description:partner_multi_relation_hierarchy.field_res_partner_relation_type_hierarchy |
||||
|
msgid "Partners equal, right above, or left above" |
||||
|
msgstr "Relaties gelijkwaardig, rechts hoger of links hoger" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model,name:partner_multi_relation_hierarchy.model_res_partner_relation_hierarchy |
||||
|
msgid "Partners with all their partnes above" |
||||
|
msgstr "Relaties met al hun bovenliggende relaties" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model.fields,help:partner_multi_relation_hierarchy.field_res_partner_relation_type_hierarchy |
||||
|
msgid "Select wether the relation between the partners can be considered hierarchical. And if so which side is considered 'above'." |
||||
|
msgstr "Geef aan of de connectie tussen de relaties een hiërarchie aangeeft. Zo ja geef aan welke kant beschouwd wordt als 'bovenliggend'" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model.fields,help:partner_multi_relation_hierarchy.field_res_partner_relation_hierarchy_partner_id |
||||
|
msgid "The partner at the base of the hierarchy" |
||||
|
msgstr "De relatie aan de basis van de hiërarchie" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: code:addons/partner_multi_relation_hierarchy/models/res_partner_relation.py:43 |
||||
|
#, python-format |
||||
|
msgid "There is already a hierarchical relation between these partners: %s" |
||||
|
msgstr "Er bestaat reeds een hiërarchische relatie tussen deze partners." |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model.fields,field_description:partner_multi_relation_hierarchy.field_res_partner_partner_above_hierarchy |
||||
|
#: model:ir.model.fields,field_description:partner_multi_relation_hierarchy.field_res_users_partner_above_hierarchy |
||||
|
msgid "Upper level partners" |
||||
|
msgstr "Bovenliggende relaties" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: selection:res.partner.relation.type,hierarchy:0 |
||||
|
msgid "equal" |
||||
|
msgstr "gelijk" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: selection:res.partner.relation.type,hierarchy:0 |
||||
|
msgid "left_above_right" |
||||
|
msgstr "links boven rechts" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: selection:res.partner.relation.type,hierarchy:0 |
||||
|
msgid "right_above_left" |
||||
|
msgstr "rechts boven links" |
||||
|
|
@ -0,0 +1,148 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * partner_multi_relation_hierarchy |
||||
|
# |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: Odoo Server 10.0\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2017-11-01 09:31+0000\n" |
||||
|
"PO-Revision-Date: 2017-11-01 09:31+0000\n" |
||||
|
"Last-Translator: <>\n" |
||||
|
"Language-Team: \n" |
||||
|
"MIME-Version: 1.0\n" |
||||
|
"Content-Type: text/plain; charset=UTF-8\n" |
||||
|
"Content-Transfer-Encoding: \n" |
||||
|
"Plural-Forms: \n" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model.fields,help:partner_multi_relation_hierarchy.field_res_partner_relation_hierarchy_hierarchy_display |
||||
|
msgid "Compact representation of hierarchy" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model.fields,field_description:partner_multi_relation_hierarchy.field_res_partner_relation_hierarchy_display_name |
||||
|
msgid "Display Name" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model.fields,field_description:partner_multi_relation_hierarchy.field_res_partner_has_partner_above |
||||
|
#: model:ir.model.fields,field_description:partner_multi_relation_hierarchy.field_res_users_has_partner_above |
||||
|
msgid "Has partner above" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model.fields,field_description:partner_multi_relation_hierarchy.field_res_partner_relation_hierarchy_hierarchy_display |
||||
|
#: model:ir.ui.view,arch_db:partner_multi_relation_hierarchy.view_partner_form |
||||
|
msgid "Hierarchy" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model.fields,field_description:partner_multi_relation_hierarchy.field_res_partner_relation_hierarchy_id |
||||
|
msgid "ID" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model.fields,field_description:partner_multi_relation_hierarchy.field_res_partner_relation_hierarchy___last_update |
||||
|
msgid "Last Modified on" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model.fields,field_description:partner_multi_relation_hierarchy.field_res_partner_relation_hierarchy_level |
||||
|
msgid "Level" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model.fields,help:partner_multi_relation_hierarchy.field_res_partner_relation_hierarchy_level |
||||
|
msgid "Number of levels that partner above is higher up" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model,name:partner_multi_relation_hierarchy.model_res_partner |
||||
|
#: model:ir.model.fields,field_description:partner_multi_relation_hierarchy.field_res_partner_relation_hierarchy_partner_id |
||||
|
msgid "Partner" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model,name:partner_multi_relation_hierarchy.model_res_partner_relation_type |
||||
|
msgid "Partner Relation Type" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model.fields,field_description:partner_multi_relation_hierarchy.field_res_partner_relation_hierarchy_partner_above_id |
||||
|
msgid "Partner above" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model.fields,field_description:partner_multi_relation_hierarchy.field_res_partner_relation_hierarchy_partner_below_id |
||||
|
msgid "Partner below" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model.fields,help:partner_multi_relation_hierarchy.field_res_partner_relation_hierarchy_partner_below_id |
||||
|
msgid "Partner immediately below partner above in the hierarchy" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model,name:partner_multi_relation_hierarchy.model_res_partner_relation |
||||
|
msgid "Partner relation" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model.fields,help:partner_multi_relation_hierarchy.field_res_partner_relation_hierarchy_partner_above_id |
||||
|
msgid "Partner somewhere above in the hierarchy" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model.fields,field_description:partner_multi_relation_hierarchy.field_res_partner_partner_above_ids_4248 |
||||
|
#: model:ir.model.fields,field_description:partner_multi_relation_hierarchy.field_res_users_partner_above_ids |
||||
|
msgid "Partners above in hierarchy" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model.fields,field_description:partner_multi_relation_hierarchy.field_res_partner_relation_type_hierarchy |
||||
|
msgid "Partners equal, right above, or left above" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model,name:partner_multi_relation_hierarchy.model_res_partner_relation_hierarchy |
||||
|
msgid "Partners with all their partnes above" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model.fields,help:partner_multi_relation_hierarchy.field_res_partner_relation_type_hierarchy |
||||
|
msgid "Select wether the relation between the partners can be considered hierarchical. And if so which side is considered 'above'." |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model.fields,help:partner_multi_relation_hierarchy.field_res_partner_relation_hierarchy_partner_id |
||||
|
msgid "The partner at the base of the hierarchy" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: code:addons/partner_multi_relation_hierarchy/models/res_partner_relation.py:43 |
||||
|
#, python-format |
||||
|
msgid "There is already a hierarchical relation between these partners: %s" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: model:ir.model.fields,field_description:partner_multi_relation_hierarchy.field_res_partner_partner_above_hierarchy |
||||
|
#: model:ir.model.fields,field_description:partner_multi_relation_hierarchy.field_res_users_partner_above_hierarchy |
||||
|
msgid "Upper level partners" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: selection:res.partner.relation.type,hierarchy:0 |
||||
|
msgid "equal" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: selection:res.partner.relation.type,hierarchy:0 |
||||
|
msgid "left_above_right" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: partner_multi_relation_hierarchy |
||||
|
#: selection:res.partner.relation.type,hierarchy:0 |
||||
|
msgid "right_above_left" |
||||
|
msgstr "" |
||||
|
|
@ -0,0 +1,7 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright 2017 Therp BV <https://therp.nl> |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
from . import res_partner_relation_type |
||||
|
from . import res_partner_relation_hierarchy |
||||
|
from . import res_partner |
||||
|
from . import res_partner_relation |
@ -0,0 +1,39 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright 2017-2018 Therp BV <https://therp.nl>. |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
from odoo import api, fields, models |
||||
|
|
||||
|
|
||||
|
class ResPartner(models.Model): |
||||
|
_inherit = 'res.partner' |
||||
|
|
||||
|
@api.multi |
||||
|
def _compute_partners_above(self): |
||||
|
"""Check partners up in the hierarchy if any.""" |
||||
|
for this in self: |
||||
|
this.partner_above_hierarchy = \ |
||||
|
this.partner_above_ids and \ |
||||
|
this.partner_above_ids[0].hierarchy_display or '' |
||||
|
this.has_partner_above = bool(this.partner_above_ids) |
||||
|
|
||||
|
partner_above_ids = fields.One2many( |
||||
|
comodel_name='res.partner.relation.hierarchy', |
||||
|
inverse_name='partner_id', |
||||
|
string='Partners above in hierarchy', |
||||
|
readonly=True) |
||||
|
partner_above_hierarchy = fields.Char( |
||||
|
string="Upper level partners", |
||||
|
compute='_compute_partners_above', |
||||
|
readonly=True) |
||||
|
has_partner_above = fields.Boolean( |
||||
|
compute='_compute_partners_above', |
||||
|
readonly=True) |
||||
|
|
||||
|
@api.multi |
||||
|
def is_above(self, other_partner): |
||||
|
"""Check whether this partner is above other_partner.""" |
||||
|
self.ensure_one() |
||||
|
for partner_above in other_partner.partner_above_ids: |
||||
|
if self.id == partner_above.partner_above_id.id: |
||||
|
return True |
||||
|
return False |
@ -0,0 +1,44 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright 2017-2018 Therp BV <https://therp.nl>. |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
from odoo import _, api, models |
||||
|
from odoo.exceptions import ValidationError |
||||
|
|
||||
|
|
||||
|
class ResPartnerRelation(models.Model): |
||||
|
_inherit = 'res.partner.relation' |
||||
|
|
||||
|
@api.model |
||||
|
def create(self, vals): |
||||
|
"""Prevent contradictory links in hierarchy. |
||||
|
|
||||
|
We should not do this in a constraint, as those are only checked |
||||
|
after creation has already been done, and other modules might |
||||
|
fail when they process in invalid hierarchy when triggered on |
||||
|
create. |
||||
|
|
||||
|
TODO: Prevent this also on write. |
||||
|
""" |
||||
|
context = self.env.context |
||||
|
if 'left_partner_id' not in vals and context.get('active_id'): |
||||
|
vals['left_partner_id'] = context.get('active_id') |
||||
|
# Check if we have needed left partner, type and right |
||||
|
# partner. If not leave error handling to super |
||||
|
if not {'left_partner_id', 'type_id', 'right_partner_id'} <= set(vals): |
||||
|
return super(ResPartnerRelation, self).create(vals) |
||||
|
type_model = self.env['res.partner.relation.type'] |
||||
|
type_id = type_model.browse(vals['type_id']) |
||||
|
hierarchy = type_id.hierarchy |
||||
|
# If relation is not for a hierarchy, just return super |
||||
|
if hierarchy == 'equal': |
||||
|
return super(ResPartnerRelation, self).create(vals) |
||||
|
partner_model = self.env['res.partner'] |
||||
|
left_partner = partner_model.browse(vals['left_partner_id']) |
||||
|
right_partner = partner_model.browse(vals['right_partner_id']) |
||||
|
if ((hierarchy == 'left' and right_partner.is_above(left_partner)) or |
||||
|
(hierarchy == 'right' and |
||||
|
left_partner.is_above(right_partner))): |
||||
|
raise ValidationError( |
||||
|
_("Not allowed to create an inconsistent hierarchy")) |
||||
|
# Everything is OK, call super |
||||
|
return super(ResPartnerRelation, self).create(vals) |
@ -0,0 +1,102 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright 2017 Therp BV <https://therp.nl> |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
"""Abstract model to show each relation from two sides.""" |
||||
|
from psycopg2.extensions import AsIs |
||||
|
|
||||
|
from openerp import api, fields, models |
||||
|
from openerp.tools import drop_view_if_exists |
||||
|
|
||||
|
|
||||
|
class ResPartnerRelationHierarchy(models.AbstractModel): |
||||
|
"""Abstract model to show each relation from two sides.""" |
||||
|
_auto = False |
||||
|
_log_access = False |
||||
|
_name = 'res.partner.relation.hierarchy' |
||||
|
_description = 'Partners with all their partnes above' |
||||
|
_order = 'partner_id, level desc, partner_above_id' |
||||
|
|
||||
|
partner_id = fields.Many2one( |
||||
|
comodel_name='res.partner', |
||||
|
string='Partner', |
||||
|
required=True, |
||||
|
readonly=True, |
||||
|
help="The partner at the base of the hierarchy") |
||||
|
partner_above_id = fields.Many2one( |
||||
|
comodel_name='res.partner', |
||||
|
string='Partner above', |
||||
|
required=True, |
||||
|
readonly=True, |
||||
|
help="Partner somewhere above in the hierarchy") |
||||
|
partner_below_id = fields.Many2one( |
||||
|
comodel_name='res.partner', |
||||
|
string='Partner below', |
||||
|
required=True, |
||||
|
readonly=True, |
||||
|
help="Partner immediately below partner above in the hierarchy") |
||||
|
level = fields.Integer( |
||||
|
string='Level', |
||||
|
required=True, |
||||
|
readonly=True, |
||||
|
help="Number of levels that partner above is higher up") |
||||
|
hierarchy_display = fields.Char( |
||||
|
string='Hierarchy', |
||||
|
required=True, |
||||
|
readonly=True, |
||||
|
help="Compact representation of hierarchy") |
||||
|
|
||||
|
@api.model_cr_context |
||||
|
def _auto_init(self): |
||||
|
"""Create hierarchy view only taking into account active relations. |
||||
|
""" |
||||
|
cr = self._cr |
||||
|
drop_view_if_exists(cr, self._table) |
||||
|
cr.execute( |
||||
|
"""\ |
||||
|
CREATE OR REPLACE VIEW %(table)s AS |
||||
|
WITH RECURSIVE hierarchy_relations AS ( |
||||
|
SELECT |
||||
|
left_partner_id as partner_above_id, |
||||
|
type_id, |
||||
|
right_partner_id as partner_below_id, |
||||
|
op.name as partner_above_name |
||||
|
FROM res_partner_relation rpr |
||||
|
JOIN res_partner_relation_type rt ON rpr.type_id = rt.id |
||||
|
JOIN res_partner op ON left_partner_id = op.id |
||||
|
WHERE rt.hierarchy = 'left' |
||||
|
AND (rpr.date_start is NULL OR rpr.date_start <= CURRENT_DATE) |
||||
|
AND (rpr.date_end is NULL OR rpr.date_end > CURRENT_DATE) |
||||
|
UNION |
||||
|
SELECT right_partner_id, type_id, left_partner_id, op.name |
||||
|
FROM res_partner_relation rpr |
||||
|
JOIN res_partner_relation_type rt ON rpr.type_id = rt.id |
||||
|
JOIN res_partner op ON right_partner_id = op.id |
||||
|
WHERE rt.hierarchy = 'right' |
||||
|
AND (rpr.date_start is NULL OR rpr.date_start <= CURRENT_DATE) |
||||
|
AND (rpr.date_end is NULL OR rpr.date_end > CURRENT_DATE) |
||||
|
), |
||||
|
hierarchy_tree( |
||||
|
partner_id, partner_above_id, partner_below_id, level, hierarchy_display, |
||||
|
path, cycle |
||||
|
) AS ( |
||||
|
SELECT |
||||
|
partner_below_id as partner_id, partner_above_id, partner_below_id, |
||||
|
1 as level, partner_above_name as hierarchy_display, |
||||
|
ARRAY[partner_below_id], false |
||||
|
FROM hierarchy_relations hr |
||||
|
UNION ALL |
||||
|
SELECT htree.partner_id, hr.partner_above_id, hr.partner_below_id, |
||||
|
htree.level + 1, |
||||
|
hr.partner_above_name || '/' || htree.hierarchy_display, |
||||
|
htree.path || hr.partner_below_id, |
||||
|
hr.partner_below_id = ANY(htree.path) |
||||
|
FROM hierarchy_relations hr, hierarchy_tree htree |
||||
|
WHERE hr.partner_below_id = htree.partner_above_id |
||||
|
AND NOT cycle |
||||
|
) |
||||
|
SELECT |
||||
|
row_number() over (order by partner_id, level, partner_above_id) as id, * |
||||
|
FROM hierarchy_tree ht |
||||
|
""", |
||||
|
{'table': AsIs(self._table)}) |
||||
|
return super(ResPartnerRelationHierarchy, self)._auto_init() |
@ -0,0 +1,22 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright 2017 Therp BV <https://therp.nl> |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
from openerp import fields, models |
||||
|
|
||||
|
|
||||
|
HIERARCHY_SELECTION = [ |
||||
|
('left', 'left_above_right'), |
||||
|
('equal', 'equal'), |
||||
|
('right', 'right_above_left')] |
||||
|
|
||||
|
|
||||
|
class ResPartnerRelationType(models.Model): |
||||
|
_inherit = 'res.partner.relation.type' |
||||
|
|
||||
|
hierarchy = fields.Selection( |
||||
|
selection=HIERARCHY_SELECTION, |
||||
|
string='Partners equal, right above, or left above', |
||||
|
default='equal', |
||||
|
help="Select wether the relation between the partners" |
||||
|
" can be considered hierarchical. And if so" |
||||
|
" which side is considered 'above'.") |
@ -0,0 +1,2 @@ |
|||||
|
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink |
||||
|
read_res_partner_relation_hierarchy,access_res_partner_relation_hierarchy,model_res_partner_relation_hierarchy,,1,0,0,0 |
@ -0,0 +1,4 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright 2017 Therp BV |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
from . import test_partner_hierarchy |
@ -0,0 +1,68 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright 2017 Therp BV |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
from openerp.exceptions import ValidationError |
||||
|
from openerp.tests import common |
||||
|
|
||||
|
|
||||
|
class TestPartnerHierarchy(common.TransactionCase): |
||||
|
|
||||
|
def test_hierarchy(self): |
||||
|
"""Test hierarchy. |
||||
|
|
||||
|
Create a hierarchical relation type. Then create a hierarchy |
||||
|
of three levels. |
||||
|
Check the computation of the display name. |
||||
|
Check that no circular hierarchy can be created. |
||||
|
""" |
||||
|
partner_model = self.env['res.partner'] |
||||
|
type_model = self.env['res.partner.relation.type'] |
||||
|
relation_model = self.env['res.partner.relation'] |
||||
|
partner_multinational = partner_model.create({ |
||||
|
'name': 'Big Important Multinational', |
||||
|
'is_company': True, |
||||
|
'ref': 'COM001'}) |
||||
|
partner_national = partner_model.create({ |
||||
|
'name': 'National Company', |
||||
|
'is_company': True, |
||||
|
'ref': 'COM002'}) |
||||
|
partner_local = partner_model.create({ |
||||
|
'name': 'Small local company', |
||||
|
'is_company': True, |
||||
|
'ref': 'COM003'}) |
||||
|
# Create a hierarchical relation type between companies: |
||||
|
type_company2branch = type_model.create({ |
||||
|
'name': 'has daughter company', |
||||
|
'name_inverse': 'has parent company', |
||||
|
'contact_type_left': 'c', |
||||
|
'contact_type_right': 'c', |
||||
|
'hierarchy': 'left'}) |
||||
|
# Let the local company belong to the national company: |
||||
|
relation_model.create({ |
||||
|
'left_partner_id': partner_national.id, |
||||
|
'type_id': type_company2branch.id, |
||||
|
'right_partner_id': partner_local.id}) |
||||
|
self.assertTrue(partner_local.has_partner_above) |
||||
|
# We should be able to find the national company as being above |
||||
|
# the local company. |
||||
|
self.assertEqual(len(partner_local.partner_above_ids[0]), 1) |
||||
|
self.assertEqual( |
||||
|
partner_local.partner_above_ids[0].partner_above_id, |
||||
|
partner_national) |
||||
|
# Let the national company belong to the multinational company: |
||||
|
relation_model.create({ |
||||
|
'left_partner_id': partner_multinational.id, |
||||
|
'type_id': type_company2branch.id, |
||||
|
'right_partner_id': partner_national.id}) |
||||
|
self.env.invalidate_all() |
||||
|
self.assertFalse(partner_multinational.has_partner_above) |
||||
|
self.assertTrue(partner_multinational.is_above(partner_local)) |
||||
|
self.assertEqual( |
||||
|
partner_local.partner_above_hierarchy, |
||||
|
'/'.join([partner_multinational.name, partner_national.name])) |
||||
|
# Check error when trying to create inconsistent hierarchy: |
||||
|
with self.assertRaises(ValidationError): |
||||
|
relation_model.create({ |
||||
|
'left_partner_id': partner_local.id, |
||||
|
'type_id': type_company2branch.id, |
||||
|
'right_partner_id': partner_multinational.id}) |
@ -0,0 +1,35 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<odoo> |
||||
|
|
||||
|
<record id="view_partner_form" model="ir.ui.view"> |
||||
|
<field name="name">view.partner.form</field> |
||||
|
<field name="inherit_id" ref="base.view_partner_form" /> |
||||
|
<field name="model">res.partner</field> |
||||
|
<field type="xml" name="arch"> |
||||
|
<xpath expr="//div" position="after"> |
||||
|
<field name="has_partner_above" invisible="1" /> |
||||
|
<group |
||||
|
colspan="6" col="8" |
||||
|
attrs="{'invisible': [('has_partner_above','=',False)]}" |
||||
|
> |
||||
|
<field name="partner_above_hierarchy" colspan="7" /> |
||||
|
</group> |
||||
|
</xpath> |
||||
|
<xpath expr="//page[@name='internal_notes']" position="after"> |
||||
|
<page name="hierarchy_page" |
||||
|
string="Hierarchy" |
||||
|
attrs="{'invisible': [('has_partner_above','=',False)]}"> |
||||
|
<group name="hierarchy_group"> |
||||
|
<field name="partner_above_ids" nolabel="1"> |
||||
|
<tree> |
||||
|
<field name="hierarchy_display"/> |
||||
|
<field name="level"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</group> |
||||
|
</page> |
||||
|
</xpath> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,17 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<odoo> |
||||
|
|
||||
|
<record id="form_res_partner_relation_type" model="ir.ui.view"> |
||||
|
<field name="model">res.partner.relation.type</field> |
||||
|
<field |
||||
|
name="inherit_id" |
||||
|
ref="partner_multi_relation.form_res_partner_relation_type" |
||||
|
/> |
||||
|
<field type="xml" name="arch"> |
||||
|
<field name="allow_self" position="before" > |
||||
|
<field name="hierarchy" /> |
||||
|
</field> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue