diff --git a/spp_registry_name_suffix/__init__.py b/spp_registry_name_suffix/__init__.py new file mode 100644 index 00000000..0650744f --- /dev/null +++ b/spp_registry_name_suffix/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/spp_registry_name_suffix/__manifest__.py b/spp_registry_name_suffix/__manifest__.py new file mode 100644 index 00000000..f644d5f4 --- /dev/null +++ b/spp_registry_name_suffix/__manifest__.py @@ -0,0 +1,28 @@ +# Part of OpenSPP. See LICENSE file for full copyright and licensing details. +{ + "name": "OpenSPP Registry Name Suffix", + "summary": "Adds a configurable suffix field (Jr., Sr., III, etc.) to Individual registrant names in OpenSPP.", + "category": "OpenSPP", + "version": "17.0.1.4.1", + "sequence": 1, + "author": "OpenSPP.org", + "website": "https://github.com/OpenSPP/openspp-modules", + "license": "LGPL-3", + "development_status": "Beta", + "maintainers": ["jeremi", "gonzalesedwin1123"], + "depends": [ + "g2p_registry_individual", + ], + "data": [ + "security/ir.model.access.csv", + "views/name_suffix_views.xml", + "views/res_partner_views.xml", + "data/name_suffix_data.xml", + ], + "assets": {}, + "demo": [], + "images": [], + "application": False, + "installable": True, + "auto_install": False, +} diff --git a/spp_registry_name_suffix/data/name_suffix_data.xml b/spp_registry_name_suffix/data/name_suffix_data.xml new file mode 100644 index 00000000..6077580a --- /dev/null +++ b/spp_registry_name_suffix/data/name_suffix_data.xml @@ -0,0 +1,171 @@ + + + + + + Jr. + JR + 10 + + Junior - typically used for a son named after his father + + + + Sr. + SR + 20 + + Senior - typically used for a father when a son has the same name + + + + Jra. + JRA + 25 + + JRA + + + + I + I + 30 + + The First + + + + II + II + 40 + + The Second + + + + III + III + 50 + + The Third + + + + IV + IV + 60 + + The Fourth + + + + V + V + 70 + + The Fifth + + + + VI + VI + 71 + + The Sixth + + + + VII + VII + 72 + + The Seventh + + + + VIII + VIII + 73 + + The Eighth + + + + IX + IX + 74 + + The Ninth + + + + X + X + 75 + + The Tenth + + + + XI + XI + 76 + + The Eleventh + + + + XII + XII + 77 + + The Twelfth + + + + XIII + XIII + 78 + + The Thirteenth + + + + XIV + XIV + 79 + + The Fourteenth + + + + XV + XV + 80 + + The Fifteenth + + + + + PhD + PHD + 100 + Doctor of Philosophy + + + + MD + MD + 110 + Doctor of Medicine + + + + Esq. + ESQ + 120 + Esquire - typically used for attorneys + + + diff --git a/spp_registry_name_suffix/models/__init__.py b/spp_registry_name_suffix/models/__init__.py new file mode 100644 index 00000000..607fd527 --- /dev/null +++ b/spp_registry_name_suffix/models/__init__.py @@ -0,0 +1,2 @@ +from . import name_suffix +from . import res_partner diff --git a/spp_registry_name_suffix/models/name_suffix.py b/spp_registry_name_suffix/models/name_suffix.py new file mode 100644 index 00000000..75b8d3ae --- /dev/null +++ b/spp_registry_name_suffix/models/name_suffix.py @@ -0,0 +1,62 @@ +from odoo import fields, models + + +class SPPNameSuffix(models.Model): + _name = "spp.name.suffix" + _description = "Name Suffix" + _order = "sequence, name" + + name = fields.Char( + string="Suffix", + required=True, + help="The suffix value (e.g., Jr., Sr., III, PhD)", + ) + code = fields.Char( + string="Code", + required=True, + help="Short code for the suffix", + ) + sequence = fields.Integer( + string="Sequence", + default=10, + help="Used to order suffixes in dropdown lists", + ) + active = fields.Boolean( + string="Active", + default=True, + help="If unchecked, the suffix will not be available for selection", + ) + description = fields.Text( + string="Description", + help="Additional description or usage notes for this suffix", + ) + is_generational = fields.Boolean( + string="Generational Suffix", + default=False, + help="Check this for generational suffixes (Jr., Sr., I, II, III, etc.). " + "Only one generational suffix can be used per individual.", + ) + + _sql_constraints = [ + ( + "name_uniq", + "unique(name)", + "Suffix name must be unique!", + ), + ( + "code_uniq", + "unique(code)", + "Suffix code must be unique!", + ), + ] + + def name_get(self): + """Display suffix name with code if different.""" + result = [] + for record in self: + if record.code and record.code != record.name: + name = f"{record.name} ({record.code})" + else: + name = record.name + result.append((record.id, name)) + return result diff --git a/spp_registry_name_suffix/models/res_partner.py b/spp_registry_name_suffix/models/res_partner.py new file mode 100644 index 00000000..4ae404f2 --- /dev/null +++ b/spp_registry_name_suffix/models/res_partner.py @@ -0,0 +1,44 @@ +from odoo import _, api, fields, models +from odoo.exceptions import ValidationError + + +class ResPartner(models.Model): + _inherit = "res.partner" + + suffix_ids = fields.Many2many( + comodel_name="spp.name.suffix", + relation="res_partner_name_suffix_rel", + column1="partner_id", + column2="suffix_id", + string="Suffixes", + help="Name suffixes", + ) + + @api.constrains("suffix_ids") + def _check_generational_suffix_conflict(self): + """Validate that only one generational suffix is selected.""" + for record in self: + if not record.suffix_ids: + continue + generational_suffixes = record.suffix_ids.filtered(lambda s: s.is_generational) + if len(generational_suffixes) > 1: + suffix_names = ", ".join(generational_suffixes.mapped("name")) + raise ValidationError( + _( + "Only one generational suffix can be used at a time. " + "The following are generational suffixes: %(suffixes)s", + suffixes=suffix_names, + ) + ) + + @api.onchange("is_group", "family_name", "given_name", "addl_name", "suffix_ids") + def name_change(self): + """Extend name change to include suffixes for individuals.""" + super().name_change() + if not self.is_group and self.suffix_ids and self.name: + # Join all suffixes in sequence order, separated by comma + suffixes_str = ", ".join(self.suffix_ids.sorted("sequence").mapped(lambda s: s.name.upper())) + suffix_part = f", {suffixes_str}" + # Only append suffixes if not already present (avoid double-append) + if not self.name.endswith(suffix_part): + self.name = f"{self.name}{suffix_part}" diff --git a/spp_registry_name_suffix/pyproject.toml b/spp_registry_name_suffix/pyproject.toml new file mode 100644 index 00000000..4231d0cc --- /dev/null +++ b/spp_registry_name_suffix/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/spp_registry_name_suffix/readme/DESCRIPTION.md b/spp_registry_name_suffix/readme/DESCRIPTION.md new file mode 100644 index 00000000..049cff0a --- /dev/null +++ b/spp_registry_name_suffix/readme/DESCRIPTION.md @@ -0,0 +1,59 @@ +# OpenSPP Registry Name Suffix + +The `spp_registry_name_suffix` module adds a configurable suffix field to Individual registrant names in OpenSPP, enabling proper recording of name suffixes such as Jr., Sr., III, IV, PhD, MD, etc. + +## Purpose + +This module enhances individual registrant data by: + +* **Providing configurable suffixes**: Administrators can manage available suffixes through the Registry Configuration menu. +* **Adding suffix support**: Record name suffixes using a standardized Many2one field reference. +* **Extending name generation**: Automatically includes the suffix in the generated full name. +* **Maintaining data integrity**: The suffix is stored as a reference to a configurable suffix record. + +## Features + +### Suffix Configuration +A new "Name Suffixes" menu is available under Registry > Configuration, allowing administrators to: +- Create, edit, and archive name suffixes +- Define suffix codes for data integration +- Set display order using sequence numbers +- Add descriptions for suffix usage guidance + +### Pre-configured Suffixes +The module comes with commonly used suffixes: +- **Generational**: Jr., Sr., I, II, III, IV, V +- **Academic/Professional**: PhD, MD, Esq. + +### Individual Registrant Integration +The suffix field appears on the Individual registrant form after the "Additional Name" field. It uses a dropdown selection with the following features: +- Quick search by suffix name or code +- No inline creation (to maintain data quality) +- Optional display in the registrant list view + +### Automatic Name Generation +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: +`FAMILY_NAME, GIVEN_NAME ADDL_NAME, SUFFIX` + +For example: "SMITH, JOHN MICHAEL, JR." + +## Dependencies + +This module depends on: +- **g2p_registry_individual**: Provides the individual registrant views, model, and the base `name_change` method. + +## Configuration + +1. Navigate to Registry > Configuration > Name Suffixes +2. Create additional suffixes as needed for your implementation +3. Set the sequence to control display order in dropdowns + +## Usage + +1. Navigate to an Individual registrant form +2. Select a suffix from the "Suffix" dropdown field +3. The full name will automatically update to include the suffix + +## References + +- OpenG2P Registry Individual: https://github.com/OpenSPP/openg2p-registry/tree/17.0-develop-openspp/g2p_registry_individual diff --git a/spp_registry_name_suffix/security/ir.model.access.csv b/spp_registry_name_suffix/security/ir.model.access.csv new file mode 100644 index 00000000..35b546d4 --- /dev/null +++ b/spp_registry_name_suffix/security/ir.model.access.csv @@ -0,0 +1,4 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink + +spp_name_suffix_registrar,SPP Name Suffix Registrar Access,spp_registry_name_suffix.model_spp_name_suffix,g2p_registry_base.group_g2p_registrar,1,1,1,1 +spp_name_suffix_admin,SPP Name Suffix Admin Access,spp_registry_name_suffix.model_spp_name_suffix,g2p_registry_base.group_g2p_admin,1,1,1,1 diff --git a/spp_registry_name_suffix/static/description/icon.png b/spp_registry_name_suffix/static/description/icon.png new file mode 100644 index 00000000..c7dbdaaf Binary files /dev/null and b/spp_registry_name_suffix/static/description/icon.png differ diff --git a/spp_registry_name_suffix/static/description/index.html b/spp_registry_name_suffix/static/description/index.html new file mode 100644 index 00000000..5868206a --- /dev/null +++ b/spp_registry_name_suffix/static/description/index.html @@ -0,0 +1,450 @@ + + + + + +OpenSPP: Registry Name Suffix + + + +
+

OpenSPP: Registry Name Suffix

+ +

Beta License: LGPL-3 OpenSPP/openspp-modules

+
+

OpenSPP: Registry Name Suffix

+

This module adds a configurable suffix field to Individual registrant names in OpenSPP, enabling proper recording of name suffixes such as Jr., Sr., III, IV, PhD, MD, etc.

+
+

Purpose

+

The OpenSPP Registry Name Suffix module provides:

+
    +
  • Configurable Suffixes: Administrators can manage available suffixes through the Registry Configuration menu.
  • +
  • Suffix Support: Record name suffixes using a standardized Many2one field reference.
  • +
  • Extended Name Generation: Automatically includes the suffix in the computed full name.
  • +
  • Data Integrity: The suffix is stored as a reference to a configurable suffix record.
  • +
+
+
+

Features

+
+

Suffix Configuration

+

A new "Name Suffixes" menu is available under Registry > Configuration, allowing administrators to:

+
    +
  • Create, edit, and archive name suffixes
  • +
  • Define suffix codes for data integration
  • +
  • Set display order using sequence numbers
  • +
  • Add descriptions for suffix usage guidance
  • +
+
+
+

Pre-configured Suffixes

+

The module comes with commonly used suffixes:

+
    +
  • Generational: Jr., Sr., I, II, III, IV, V
  • +
  • Academic/Professional: PhD, MD, Esq.
  • +
+
+
+

Individual Registrant Integration

+

The suffix field appears on the Individual registrant form after the "Additional Name" field. It uses a dropdown selection with the following features:

+
    +
  • Quick search by suffix name or code
  • +
  • No inline creation (to maintain data quality)
  • +
  • Optional display in the registrant list view
  • +
+
+
+

Automatic Name Generation

+

The suffix is automatically appended to the registrant's computed name in the format: +FAMILY_NAME, GIVEN_NAME, ADDL_NAME, SUFFIX

+

For example: "SMITH, JOHN, MICHAEL, JR."

+
+
+
+

Dependencies

+

This module depends on:

+
    +
  • g2p_registry_individual: Provides the individual registrant views, model, and the base name_change method.
  • +
+
+
+

Configuration

+
    +
  1. Navigate to Registry > Configuration > Name Suffixes
  2. +
  3. Create additional suffixes as needed for your implementation
  4. +
  5. Set the sequence to control display order in dropdowns
  6. +
+
+
+

Usage

+
    +
  1. Navigate to an Individual registrant form
  2. +
  3. Select a suffix from the "Suffix" dropdown field
  4. +
  5. The full name will automatically update to include the suffix
  6. +
+
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • OpenSPP.org
  • +
+
+
+

Maintainers

+

Current maintainers:

+

jeremi gonzalesedwin1123

+

This module is part of the OpenSPP/openspp-modules project on GitHub.

+

You are welcome to contribute.

+
+
+
+ + + diff --git a/spp_registry_name_suffix/tests/__init__.py b/spp_registry_name_suffix/tests/__init__.py new file mode 100644 index 00000000..25566a92 --- /dev/null +++ b/spp_registry_name_suffix/tests/__init__.py @@ -0,0 +1 @@ +from . import test_name_suffix diff --git a/spp_registry_name_suffix/tests/test_name_suffix.py b/spp_registry_name_suffix/tests/test_name_suffix.py new file mode 100644 index 00000000..f07a7d19 --- /dev/null +++ b/spp_registry_name_suffix/tests/test_name_suffix.py @@ -0,0 +1,328 @@ +from odoo.exceptions import ValidationError +from odoo.tests import tagged +from odoo.tests.common import TransactionCase + + +@tagged("post_install", "-at_install") +class TestNameSuffix(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.env = cls.env( + context=dict( + cls.env.context, + test_queue_job_no_delay=True, + ) + ) + + # Use existing suffixes from data file + cls.suffix_jr = cls.env.ref("spp_registry_name_suffix.suffix_jr") + cls.suffix_sr = cls.env.ref("spp_registry_name_suffix.suffix_sr") + cls.suffix_iii = cls.env.ref("spp_registry_name_suffix.suffix_iii") + cls.suffix_phd = cls.env.ref("spp_registry_name_suffix.suffix_phd") + + def test_01_suffix_model_creation(self): + """Test that suffix model can be created correctly.""" + suffix = self.env["spp.name.suffix"].create( + { + "name": "Test Suffix", + "code": "TEST", + } + ) + self.assertTrue(suffix.active) + self.assertEqual(suffix.sequence, 10) # Default + + def test_02_suffix_data_loaded(self): + """Test that default suffix data is loaded correctly.""" + self.assertEqual(self.suffix_jr.name, "Jr.") + self.assertEqual(self.suffix_jr.code, "JR") + self.assertEqual(self.suffix_phd.name, "PhD") + self.assertEqual(self.suffix_phd.code, "PHD") + + def test_03_name_with_single_suffix(self): + """Test that a single suffix is appended to the computed name.""" + individual = self.env["res.partner"].create( + { + "name": "Temp", # Required by res_partner_check_name constraint + "family_name": "Doe", + "given_name": "John", + "suffix_ids": [(6, 0, [self.suffix_jr.id])], + "is_registrant": True, + "is_group": False, + } + ) + # Call name_change to generate name (simulates form onchange) + individual.name_change() + self.assertEqual( + individual.name, + "DOE, JOHN, JR.", + "Name should include suffix", + ) + + def test_04_name_without_suffix(self): + """Test that name is computed correctly without suffix.""" + individual = self.env["res.partner"].create( + { + "name": "Temp", # Required by res_partner_check_name constraint + "family_name": "Doe", + "given_name": "Jane", + "is_registrant": True, + "is_group": False, + } + ) + individual.name_change() + self.assertEqual( + individual.name, + "DOE, JANE", + "Name should not have trailing comma when no suffix", + ) + + def test_05_name_with_multiple_suffixes(self): + """Test name with multiple suffixes (e.g., Jr. and PhD).""" + individual = self.env["res.partner"].create( + { + "name": "Temp", # Required by res_partner_check_name constraint + "family_name": "Smith", + "given_name": "Robert", + "suffix_ids": [(6, 0, [self.suffix_jr.id, self.suffix_phd.id])], + "is_registrant": True, + "is_group": False, + } + ) + individual.name_change() + # Jr. has sequence 10, PhD has sequence 100, so Jr. comes first + self.assertEqual( + individual.name, + "SMITH, ROBERT, JR., PHD", + "Name should include multiple suffixes in sequence order", + ) + + def test_06_name_with_all_fields_and_multiple_suffixes(self): + """Test name with all fields including addl_name and multiple suffixes.""" + individual = self.env["res.partner"].create( + { + "name": "Temp", # Required by res_partner_check_name constraint + "family_name": "Williams", + "given_name": "James", + "addl_name": "Edward", + "suffix_ids": [(6, 0, [self.suffix_jr.id, self.suffix_phd.id])], + "is_registrant": True, + "is_group": False, + } + ) + individual.name_change() + self.assertEqual( + individual.name, + "WILLIAMS, JAMES EDWARD, JR., PHD", + "Name should include all parts including multiple suffixes", + ) + + def test_07_group_name_unaffected(self): + """Test that group name is not affected by suffix logic.""" + group = self.env["res.partner"].create( + { + "name": "Test Group", + "suffix_ids": [(6, 0, [self.suffix_jr.id])], + "is_registrant": True, + "is_group": True, + } + ) + # Call name_change to simulate form behavior + group.name_change() + self.assertEqual( + group.name, + "Test Group", + "Group name should not include suffix", + ) + + def test_08_suffix_update_triggers_name_change(self): + """Test that updating suffixes and calling name_change updates name.""" + individual = self.env["res.partner"].create( + { + "name": "Temp", # Required by res_partner_check_name constraint + "family_name": "Johnson", + "given_name": "Michael", + "is_registrant": True, + "is_group": False, + } + ) + # Call name_change to generate name + individual.name_change() + self.assertEqual(individual.name, "JOHNSON, MICHAEL") + + # Add suffix and call name_change again + individual.suffix_ids = [(6, 0, [self.suffix_phd.id])] + individual.name_change() + self.assertEqual( + individual.name, + "JOHNSON, MICHAEL, PHD", + "Name should update when suffix is added", + ) + + def test_09_suffix_removal(self): + """Test that removing suffixes updates the name correctly.""" + individual = self.env["res.partner"].create( + { + "name": "Temp", # Required by res_partner_check_name constraint + "family_name": "Williams", + "given_name": "Sarah", + "suffix_ids": [(6, 0, [self.suffix_jr.id])], + "is_registrant": True, + "is_group": False, + } + ) + individual.name_change() + self.assertEqual(individual.name, "WILLIAMS, SARAH, JR.") + + individual.suffix_ids = [(5, 0, 0)] # Clear all suffixes + individual.name_change() + self.assertEqual( + individual.name, + "WILLIAMS, SARAH", + "Name should update when suffixes are removed", + ) + + def test_10_suffix_sequence_ordering(self): + """Test that suffixes are ordered by sequence field.""" + # PhD has sequence 100, Jr. has sequence 10 + # Even if we add PhD first, Jr. should appear first in the name + individual = self.env["res.partner"].create( + { + "name": "Temp", + "family_name": "Brown", + "given_name": "David", + "suffix_ids": [(6, 0, [self.suffix_phd.id, self.suffix_jr.id])], + "is_registrant": True, + "is_group": False, + } + ) + individual.name_change() + self.assertEqual( + individual.name, + "BROWN, DAVID, JR., PHD", + "Suffixes should be ordered by sequence regardless of selection order", + ) + + def test_11_name_get_with_different_code(self): + """Test name_get when code differs from name.""" + # suffix_jr has name="Jr." and code="JR" (different) + result = self.suffix_jr.name_get() + self.assertEqual(len(result), 1) + self.assertEqual(result[0][0], self.suffix_jr.id) + self.assertEqual( + result[0][1], + "Jr. (JR)", + "name_get should show name with code in parentheses", + ) + + def test_12_name_get_with_same_code(self): + """Test name_get when code equals name.""" + # Create a suffix where name and code are the same + suffix_same = self.env["spp.name.suffix"].create( + { + "name": "SAME", + "code": "SAME", + } + ) + result = suffix_same.name_get() + self.assertEqual(len(result), 1) + self.assertEqual(result[0][0], suffix_same.id) + self.assertEqual( + result[0][1], + "SAME", + "name_get should show only name when code equals name", + ) + + def test_13_name_get_multiple_records(self): + """Test name_get with multiple records.""" + # Get multiple suffixes at once + suffixes = self.suffix_jr | self.suffix_phd + result = suffixes.name_get() + self.assertEqual(len(result), 2) + # Check that all record IDs are in the result + result_ids = [r[0] for r in result] + self.assertIn(self.suffix_jr.id, result_ids) + self.assertIn(self.suffix_phd.id, result_ids) + + def test_14_is_generational_set_on_generational_suffixes(self): + """Test that generational suffixes have is_generational flag set.""" + self.assertTrue( + self.suffix_jr.is_generational, + "Jr. should be marked as generational", + ) + self.assertTrue( + self.suffix_sr.is_generational, + "Sr. should be marked as generational", + ) + self.assertTrue( + self.suffix_iii.is_generational, + "III should be marked as generational", + ) + self.assertFalse( + self.suffix_phd.is_generational, + "PhD should not be marked as generational", + ) + + def test_15_generational_suffix_conflict_prevented(self): + """Test that two generational suffixes cannot be selected together.""" + individual = self.env["res.partner"].create( + { + "name": "Temp", + "family_name": "Doe", + "given_name": "John", + "is_registrant": True, + "is_group": False, + } + ) + # Try to add both Jr. and Sr. (both generational) + with self.assertRaises(ValidationError) as context: + individual.write({"suffix_ids": [(6, 0, [self.suffix_jr.id, self.suffix_sr.id])]}) + self.assertIn("generational", str(context.exception).lower()) + + def test_16_generational_with_non_generational_allowed(self): + """Test that generational + non-generational suffixes can be combined.""" + # Jr. (generational) + PhD (non-generational) should work + individual = self.env["res.partner"].create( + { + "name": "Temp", + "family_name": "Smith", + "given_name": "Jane", + "suffix_ids": [(6, 0, [self.suffix_jr.id, self.suffix_phd.id])], + "is_registrant": True, + "is_group": False, + } + ) + self.assertEqual(len(individual.suffix_ids), 2) + individual.name_change() + self.assertEqual(individual.name, "SMITH, JANE, JR., PHD") + + def test_17_roman_numerals_conflict(self): + """Test that two roman numeral suffixes cannot be selected together.""" + individual = self.env["res.partner"].create( + { + "name": "Temp", + "family_name": "King", + "given_name": "Henry", + "is_registrant": True, + "is_group": False, + } + ) + suffix_iv = self.env.ref("spp_registry_name_suffix.suffix_iv") + # Try to add both III and IV (both generational) + with self.assertRaises(ValidationError): + individual.write({"suffix_ids": [(6, 0, [self.suffix_iii.id, suffix_iv.id])]}) + + def test_18_jr_and_roman_numeral_conflict(self): + """Test that Jr. and roman numerals cannot be selected together.""" + individual = self.env["res.partner"].create( + { + "name": "Temp", + "family_name": "Windsor", + "given_name": "Charles", + "is_registrant": True, + "is_group": False, + } + ) + # Try to add Jr. and III (both generational) + with self.assertRaises(ValidationError): + individual.write({"suffix_ids": [(6, 0, [self.suffix_jr.id, self.suffix_iii.id])]}) diff --git a/spp_registry_name_suffix/views/name_suffix_views.xml b/spp_registry_name_suffix/views/name_suffix_views.xml new file mode 100644 index 00000000..0b6384c5 --- /dev/null +++ b/spp_registry_name_suffix/views/name_suffix_views.xml @@ -0,0 +1,90 @@ + + + + + + spp.name.suffix.tree + spp.name.suffix + + + + + + + + + + + + + + spp.name.suffix.form + spp.name.suffix + +
+ + + + + + + + + + + + + + + +
+
+
+ + + + spp.name.suffix.search + spp.name.suffix + + + + + + + + + + + + + + Name Suffixes + spp.name.suffix + tree,form + + +

+ Create your first name suffix +

+

+ Name suffixes like Jr., Sr., III, PhD, MD can be configured here + and then selected on individual registrant records. +

+
+
+ + + + +
diff --git a/spp_registry_name_suffix/views/res_partner_views.xml b/spp_registry_name_suffix/views/res_partner_views.xml new file mode 100644 index 00000000..821c5412 --- /dev/null +++ b/spp_registry_name_suffix/views/res_partner_views.xml @@ -0,0 +1,34 @@ + + + + + + + res.partner.view.form.inherit.name.suffix + res.partner + + + + + + + + + + + res.partner.view.tree.inherit.name.suffix + res.partner + + + + + + + + +