Skip to content

Commit 181e72b

Browse files
[UPD] spp_registry_name_suffix: add name suffix support for individuals
- Add spp.name.suffix model for configurable suffixes (Jr., Sr., III, PhD, etc.) - Extend res.partner with suffix_id field and name_change method - Add configuration menu under Registry > Configuration > Name Suffixes - Include default suffix data and unit tests
1 parent 542893b commit 181e72b

File tree

5 files changed

+78
-87
lines changed

5 files changed

+78
-87
lines changed

spp_registry_name_suffix/__manifest__.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,14 @@
33
"name": "OpenSPP Registry Name Suffix",
44
"summary": "Adds a configurable suffix field (Jr., Sr., III, etc.) to Individual registrant names in OpenSPP.",
55
"category": "OpenSPP",
6-
"version": "17.0.1.4.0",
6+
"version": "17.0.1.4.1",
77
"sequence": 1,
88
"author": "OpenSPP.org",
99
"website": "https://github.com/OpenSPP/openspp-modules",
1010
"license": "LGPL-3",
1111
"development_status": "Beta",
1212
"maintainers": ["jeremi", "gonzalesedwin1123"],
1313
"depends": [
14-
"spp_registrant_import",
1514
"g2p_registry_individual",
1615
],
1716
"data": [

spp_registry_name_suffix/data/name_suffix_data.xml

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -51,26 +51,4 @@
5151
<field name="description">The Fifth</field>
5252
</record>
5353

54-
<!-- Academic/Professional Suffixes -->
55-
<record id="suffix_phd" model="spp.name.suffix">
56-
<field name="name">PhD</field>
57-
<field name="code">PHD</field>
58-
<field name="sequence">100</field>
59-
<field name="description">Doctor of Philosophy</field>
60-
</record>
61-
62-
<record id="suffix_md" model="spp.name.suffix">
63-
<field name="name">MD</field>
64-
<field name="code">MD</field>
65-
<field name="sequence">110</field>
66-
<field name="description">Doctor of Medicine</field>
67-
</record>
68-
69-
<record id="suffix_esq" model="spp.name.suffix">
70-
<field name="name">Esq.</field>
71-
<field name="code">ESQ</field>
72-
<field name="sequence">120</field>
73-
<field name="description">Esquire - typically used for attorneys</field>
74-
</record>
75-
7654
</odoo>

spp_registry_name_suffix/models/res_partner.py

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,9 @@ class ResPartner(models.Model):
1111
help="Name suffix such as Jr., Sr., III, IV, PhD, MD, etc.",
1212
)
1313

14-
@api.depends(
15-
"is_registrant",
16-
"is_group",
17-
"family_name",
18-
"given_name",
19-
"addl_name",
20-
"suffix_id",
21-
)
22-
def _compute_name(self):
23-
"""Extend name computation to include suffix for individuals."""
24-
super()._compute_name()
25-
for rec in self:
26-
if not rec.is_registrant or rec.is_group:
27-
continue
28-
if rec.suffix_id:
29-
rec.name = f"{rec.name}, {rec.suffix_id.name.upper()}"
14+
@api.onchange("is_group", "family_name", "given_name", "addl_name", "suffix_id")
15+
def name_change(self):
16+
"""Extend name change to include suffix for individuals."""
17+
super().name_change()
18+
if not self.is_group and self.suffix_id:
19+
self.name = f"{self.name}, {self.suffix_id.name.upper()}"

spp_registry_name_suffix/readme/DESCRIPTION.md

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ This module enhances individual registrant data by:
88

99
* **Providing configurable suffixes**: Administrators can manage available suffixes through the Registry Configuration menu.
1010
* **Adding suffix support**: Record name suffixes using a standardized Many2one field reference.
11-
* **Extending name generation**: Automatically includes the suffix in the computed full name.
11+
* **Extending name generation**: Automatically includes the suffix in the generated full name.
1212
* **Maintaining data integrity**: The suffix is stored as a reference to a configurable suffix record.
1313

1414
## Features
@@ -32,16 +32,15 @@ The suffix field appears on the Individual registrant form after the "Additional
3232
- Optional display in the registrant list view
3333

3434
### Automatic Name Generation
35-
The suffix is automatically appended to the registrant's computed name in the format:
36-
`FAMILY_NAME, GIVEN_NAME, ADDL_NAME, SUFFIX`
35+
The suffix is automatically appended to the registrant's name when using the form. The module extends the `name_change` method from `g2p_registry_individual` to include the suffix in the generated name format:
36+
`FAMILY_NAME, GIVEN_NAME ADDL_NAME, SUFFIX`
3737

38-
For example: "SMITH, JOHN, MICHAEL, JR."
38+
For example: "SMITH, JOHN MICHAEL, JR."
3939

4040
## Dependencies
4141

4242
This module depends on:
43-
- **spp_registrant_import**: Provides the base name computation logic for registrants.
44-
- **g2p_registry_individual**: Provides the individual registrant views and model.
43+
- **g2p_registry_individual**: Provides the individual registrant views, model, and the base `name_change` method.
4544

4645
## Configuration
4746

@@ -58,4 +57,3 @@ This module depends on:
5857
## References
5958

6059
- OpenG2P Registry Individual: https://github.com/OpenSPP/openg2p-registry/tree/17.0-develop-openspp/g2p_registry_individual
61-

spp_registry_name_suffix/tests/test_name_suffix.py

Lines changed: 66 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from odoo.exceptions import ValidationError
44
from odoo.tests import tagged
5-
from odoo.tests.common import TransactionCase
5+
from odoo.tests.common import Form, TransactionCase
66

77

88
@tagged("post_install", "-at_install")
@@ -61,44 +61,50 @@ def test_02_suffix_uniqueness(self):
6161
}
6262
)
6363

64-
def test_03_name_with_suffix(self):
65-
"""Test that suffix is appended to the computed name."""
66-
individual = self.env["res.partner"].create(
67-
{
68-
"family_name": "Doe",
69-
"given_name": "John",
70-
"suffix_id": self.suffix_jr.id,
71-
"is_registrant": True,
72-
"is_group": False,
73-
}
64+
def test_03_name_with_suffix_using_form(self):
65+
"""Test that suffix is appended to the name using form simulation."""
66+
with Form(self.env["res.partner"]) as partner_form:
67+
partner_form.is_registrant = True
68+
partner_form.is_group = False
69+
partner_form.family_name = "Doe"
70+
partner_form.given_name = "John"
71+
partner_form.suffix_id = self.suffix_jr
72+
individual = partner_form.save()
73+
self.assertEqual(
74+
individual.name,
75+
"DOE, JOHN, JR.",
76+
"Name should include suffix",
7477
)
75-
self.assertEqual(individual.name, "DOE, JOHN, JR.", "Name should include suffix")
7678

77-
def test_04_name_without_suffix(self):
78-
"""Test that name is computed correctly without suffix."""
79-
individual = self.env["res.partner"].create(
80-
{
81-
"family_name": "Doe",
82-
"given_name": "Jane",
83-
"is_registrant": True,
84-
"is_group": False,
85-
}
79+
def test_04_name_without_suffix_using_form(self):
80+
"""Test that name is generated correctly without suffix."""
81+
with Form(self.env["res.partner"]) as partner_form:
82+
partner_form.is_registrant = True
83+
partner_form.is_group = False
84+
partner_form.family_name = "Doe"
85+
partner_form.given_name = "Jane"
86+
individual = partner_form.save()
87+
self.assertEqual(
88+
individual.name,
89+
"DOE, JANE",
90+
"Name should not have trailing comma when no suffix",
8691
)
87-
self.assertEqual(individual.name, "DOE, JANE", "Name should not have trailing comma when no suffix")
8892

89-
def test_05_name_with_all_fields(self):
93+
def test_05_name_with_all_fields_using_form(self):
9094
"""Test name with all fields including addl_name and suffix."""
91-
individual = self.env["res.partner"].create(
92-
{
93-
"family_name": "Smith",
94-
"given_name": "Robert",
95-
"addl_name": "James",
96-
"suffix_id": self.suffix_phd.id,
97-
"is_registrant": True,
98-
"is_group": False,
99-
}
95+
with Form(self.env["res.partner"]) as partner_form:
96+
partner_form.is_registrant = True
97+
partner_form.is_group = False
98+
partner_form.family_name = "Smith"
99+
partner_form.given_name = "Robert"
100+
partner_form.addl_name = "James"
101+
partner_form.suffix_id = self.suffix_phd
102+
individual = partner_form.save()
103+
self.assertEqual(
104+
individual.name,
105+
"SMITH, ROBERT JAMES, PHD",
106+
"Name should include all parts including suffix",
100107
)
101-
self.assertEqual(individual.name, "SMITH, ROBERT, JAMES, PHD", "Name should include all parts including suffix")
102108

103109
def test_06_group_name_unaffected(self):
104110
"""Test that group name is not affected by suffix logic."""
@@ -110,10 +116,16 @@ def test_06_group_name_unaffected(self):
110116
"is_group": True,
111117
}
112118
)
113-
self.assertEqual(group.name, "Test Group", "Group name should not include suffix")
119+
# Call name_change to simulate form behavior
120+
group.name_change()
121+
self.assertEqual(
122+
group.name,
123+
"Test Group",
124+
"Group name should not include suffix",
125+
)
114126

115-
def test_07_suffix_update_triggers_name_recompute(self):
116-
"""Test that updating suffix triggers name recomputation."""
127+
def test_07_name_change_method_direct_call(self):
128+
"""Test name_change method called directly."""
117129
individual = self.env["res.partner"].create(
118130
{
119131
"family_name": "Johnson",
@@ -122,10 +134,18 @@ def test_07_suffix_update_triggers_name_recompute(self):
122134
"is_group": False,
123135
}
124136
)
137+
# Call name_change to generate name
138+
individual.name_change()
125139
self.assertEqual(individual.name, "JOHNSON, MICHAEL")
126140

127-
individual.write({"suffix_id": self.suffix_phd.id})
128-
self.assertEqual(individual.name, "JOHNSON, MICHAEL, PHD", "Name should update when suffix is added")
141+
# Add suffix and call name_change again
142+
individual.suffix_id = self.suffix_phd.id
143+
individual.name_change()
144+
self.assertEqual(
145+
individual.name,
146+
"JOHNSON, MICHAEL, PHD",
147+
"Name should update when suffix is added",
148+
)
129149

130150
def test_08_suffix_removal(self):
131151
"""Test that removing suffix updates the name correctly."""
@@ -138,7 +158,13 @@ def test_08_suffix_removal(self):
138158
"is_group": False,
139159
}
140160
)
161+
individual.name_change()
141162
self.assertEqual(individual.name, "WILLIAMS, SARAH, JR.")
142163

143-
individual.write({"suffix_id": False})
144-
self.assertEqual(individual.name, "WILLIAMS, SARAH", "Name should update when suffix is removed")
164+
individual.suffix_id = False
165+
individual.name_change()
166+
self.assertEqual(
167+
individual.name,
168+
"WILLIAMS, SARAH",
169+
"Name should update when suffix is removed",
170+
)

0 commit comments

Comments
 (0)