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