Skip to content

Commit 143b88a

Browse files
committed
[T-8592][IMP] partner_private_information: Private tags visibility managed by group
1 parent 9bad174 commit 143b88a

12 files changed

Lines changed: 161 additions & 11 deletions

File tree

partner_private_information/README.rst

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,21 @@ Partner Private Information
2222

2323
|badge1| |badge2| |badge3|
2424

25-
This module allows us to add a new tab to the partners file with private
26-
information that only designated users can view.
25+
Adds a dedicated “Private Info” tab to Contacts, containing a second set
26+
of contact data — including phone, mobile, e‑mail, full address, and
27+
categories — that is only visible and exportable by authorised users.
28+
This allows separating general contact details from internal-use-only
29+
data.
30+
31+
Key Features
32+
33+
This module provides:
34+
35+
- A Private Info tab on the partner form view, visible only to users
36+
with the appropriate access.
37+
- Controlled by the group: Extra Rights / Show partner private info.
38+
- Access is enabled via the user form by checking the option “Show
39+
partner private info”.
2740

2841
**Table of contents**
2942

@@ -44,6 +57,9 @@ Usage
4457
To use this module, you need to:
4558

4659
1. In the contact's tab we find a tab called private information.
60+
2. Tags (partner categories) can be flagged as **Private**. When a
61+
category is marked as private, it will only be available for
62+
selection in the **Private Information** tab.
4763

4864
Bug Tracker
4965
===========

partner_private_information/__manifest__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@
1515
"data": [
1616
"security/partner_private_information_security.xml",
1717
"views/res_partner_view.xml",
18+
"views/res_partner_category_views.xml",
1819
],
1920
}

partner_private_information/models/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
33

44
from . import res_partner
5+
from . import res_partner_category

partner_private_information/models/res_partner.py

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
# Copyright 2024 Roger Sans <roger.sans@sygel.es>
22
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
3+
import re
34

4-
from odoo import api, fields, models
5+
from odoo import _, api, fields, models
6+
from odoo.exceptions import ValidationError
57

68

79
class ResPartner(models.Model):
@@ -77,3 +79,47 @@ def _address_fields(self):
7779
"private_country_id",
7880
]
7981
return res
82+
83+
@api.constrains("private_phone", "private_mobile", "private_email")
84+
def _check_internal_contact_info_format(self):
85+
phone_pattern = re.compile(r"^\+?[0-9\s\-]{7,20}$")
86+
email_pattern = re.compile(r"^[\w\.-]+@[\w\.-]+\.\w+$")
87+
88+
for record in self:
89+
if record.private_phone and not phone_pattern.match(record.private_phone):
90+
raise ValidationError(
91+
_(
92+
"Invalid format for Private Phone. Examples: "
93+
"'+34 912 345 678', '912-345-678'."
94+
)
95+
)
96+
if record.private_mobile and not phone_pattern.match(record.private_mobile):
97+
raise ValidationError(
98+
_(
99+
"Invalid format for Private Mobile. Examples: "
100+
"'+34 600 100 200', '601-602-603'."
101+
)
102+
)
103+
if record.private_email and not email_pattern.match(record.private_email):
104+
raise ValidationError(
105+
_(
106+
"Invalid format for Private Email."
107+
"Example: 'john.doe@example.com'."
108+
)
109+
)
110+
111+
@api.onchange("private_phone", "country_id", "company_id")
112+
def _onchange_private_phone_validation(self):
113+
if self.private_phone:
114+
self.private_phone = (
115+
self._phone_format(fname="private_phone", force_format="INTERNATIONAL")
116+
or self.private_phone
117+
)
118+
119+
@api.onchange("private_mobile", "country_id", "company_id")
120+
def _onchange_private_mobile_validation(self):
121+
if self.private_mobile:
122+
self.private_mobile = (
123+
self._phone_format(fname="private_mobile", force_format="INTERNATIONAL")
124+
or self.private_mobile
125+
)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from odoo import fields, models
2+
3+
4+
class ResPartnerCategory(models.Model):
5+
_inherit = "res.partner.category"
6+
7+
is_private = fields.Boolean(string="Private Category", default=False)
Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,9 @@
1-
This module allows us to add a new tab to the partners file with private information that only designated users can view.
1+
Adds a dedicated “Private Info” tab to Contacts, containing a second set of contact data — including phone, mobile, e‑mail, full address, and categories — that is only visible and exportable by authorised users. This allows separating general contact details from internal-use-only data.
2+
3+
Key Features
4+
5+
This module provides:
6+
7+
- A Private Info tab on the partner form view, visible only to users with the appropriate access.
8+
- Controlled by the group: Extra Rights / Show partner private info.
9+
- Access is enabled via the user form by checking the option “Show partner private info”.
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
To use this module, you need to:
22

3-
1. In the contact's tab we find a tab called private information.
3+
1. In the contact's tab we find a tab called private information.
4+
2. Tags (partner categories) can be flagged as **Private**. When a category is marked as private, it will only be available for selection in the **Private Information** tab.

partner_private_information/security/partner_private_information_security.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,19 @@
88
eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"
99
/>
1010
</record>
11+
<record id="rule_hide_private_categories" model="ir.rule">
12+
<field name="name">Hide Private Categories</field>
13+
<field name="model_id" ref="base.model_res_partner_category" />
14+
<field name="domain_force">[('is_private', '=', False)]</field>
15+
<field name="groups" eval="[(4, ref('base.group_user'))]" />
16+
</record>
17+
<record id="rule_show_all_categories" model="ir.rule">
18+
<field name="name">Show All Categories</field>
19+
<field name="model_id" ref="base.model_res_partner_category" />
20+
<field
21+
name="groups"
22+
eval="[(4, ref('partner_private_information.group_partner_private_info'))]"
23+
/>
24+
<field name="domain_force">[(1, '=', 1)]</field>
25+
</record>
1126
</odoo>

partner_private_information/static/description/index.html

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -370,8 +370,20 @@ <h1 class="title">Partner Private Information</h1>
370370
!! source digest: sha256:350d438ab706b5aabc16f6a4874de7ebb9c81819627fedc573aaf77f4c6b7fe6
371371
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
372372
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/sygel-technology/sy-partner-contact/tree/18.0/partner_private_information"><img alt="sygel-technology/sy-partner-contact" src="https://img.shields.io/badge/github-sygel--technology%2Fsy--partner--contact-lightgray.png?logo=github" /></a></p>
373-
<p>This module allows us to add a new tab to the partners file with private
374-
information that only designated users can view.</p>
373+
<p>Adds a dedicated “Private Info” tab to Contacts, containing a second set
374+
of contact data — including phone, mobile, e‑mail, full address, and
375+
categories — that is only visible and exportable by authorised users.
376+
This allows separating general contact details from internal-use-only
377+
data.</p>
378+
<p>Key Features</p>
379+
<p>This module provides:</p>
380+
<ul class="simple">
381+
<li>A Private Info tab on the partner form view, visible only to users
382+
with the appropriate access.</li>
383+
<li>Controlled by the group: Extra Rights / Show partner private info.</li>
384+
<li>Access is enabled via the user form by checking the option “Show
385+
partner private info”.</li>
386+
</ul>
375387
<p><strong>Table of contents</strong></p>
376388
<div class="contents local topic" id="contents">
377389
<ul class="simple">
@@ -399,6 +411,9 @@ <h1><a class="toc-backref" href="#toc-entry-2">Usage</a></h1>
399411
<p>To use this module, you need to:</p>
400412
<ol class="arabic simple">
401413
<li>In the contact’s tab we find a tab called private information.</li>
414+
<li>Tags (partner categories) can be flagged as <strong>Private</strong>. When a
415+
category is marked as private, it will only be available for
416+
selection in the <strong>Private Information</strong> tab.</li>
402417
</ol>
403418
</div>
404419
<div class="section" id="bug-tracker">

partner_private_information/tests/test_partner_private_information.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from odoo.exceptions import AccessError
1+
from odoo.exceptions import AccessError, ValidationError
22
from odoo.tests.common import TransactionCase, new_test_user
33

44

@@ -39,8 +39,15 @@ def test_private_fields_hidden_from_unauthorized_user(self):
3939

4040
with self.assertRaises(AccessError):
4141
_ = partner.private_phone
42+
with self.assertRaises(AccessError):
4243
_ = partner.private_email
4344

4445
def test_private_fields_default_values(self):
4546
self.assertFalse(self.partner.private_phone)
4647
self.assertFalse(self.partner.private_email)
48+
49+
def test_invalid_private_phone_format(self):
50+
partner = self.partner.with_user(self.user_private)
51+
with self.assertRaises(ValidationError):
52+
partner.private_phone = "abc123"
53+
partner._check_internal_contact_info_format()

0 commit comments

Comments
 (0)