---
title: Claim-person name management
summary: Maintains claim-person name history rows, generates the phonetic name code before persistence, and enforces primary/void flag consistency.
status: draft
owner: SAIF
last_reviewed: 2026-07-30
library: SAIF.Business.Claim.Person
reference_type: package
operation_id: OP-PER-02
trigger: Caller retrieves a person's name-history collection, adds or edits a name row, and saves the collection.
---

# Claim-person name management

Claim-person name management loads the full name-history collection for a claim person, lets the caller add a new name row or edit an existing one, generates a phonetic name code for search indexing before every insert, and validates required fields and flag consistency before persisting inserts, updates, and deletes. The collection also enforces that exactly one name row is marked primary.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-PER-02 |
| **Trigger** | Caller retrieves name history for a person, edits one or more name rows, and calls `Save()` on the collection |
| **Inputs** | `PersonID`; row fields `FirstName`, `LastName`, `MiddleName`, `NameExtensionCode`, `PrimaryFlag`, `VoidFlag`; acting user from `DataPortalInfo.UserID` |
| **Outputs** | In-memory `clsClaimPersonNameCollection`; persisted inserts, updates, or deletes in `CL_CLAIM_PERSON_NAME_HISTORY`; broken rules and DB-contention messages |
| **Primary components** | `clsClaimPersonNameCollection.GetClaimPersonNameCol`, `clsClaimPersonNameCollection.NewClaimPersonName`, `clsClaimPersonName.BeforeInsert`, `clsClaimPersonName.BeforeUpdate`, `clsClaimPersonName.BeforeDelete`, `clsClaimPersonName.GetPhoneticNameCode` |
| **Entry point** | `Business\SAIF.Business.Claim.Person\clsClaimPersonNameCollection.vb` |

## Steps

1. **Retrieve the person's full name history.** `GetClaimPersonNameCol` issues the collection read query for the given `PersonID`, loads each row into `clsClaimPersonName`, and tracks the highest `PrimaryKeySubNum` seen so far ([SQL-009](../sql/sql-009-select.md), [CL_CLAIM_PERSON_NAME_HISTORY](../database-tables.md#cl_claim_person_name_history)).
2. **Create a new name row when requested.** `NewClaimPersonName` increments the cached maximum sub-number, creates a child row through `clsClaimPersonName.NewClaimPersonName` for the current `PersonID`, and adds it to the managed collection. `Create()` seeds blank name fields, a blank phonetic name code, `PrimaryFlag = "N"`, and `VoidFlag = "N"` as defaults.
3. **Validate required fields and flag values on each dirty row.** The row rules require a non-blank last name, require `PrimaryFlag` to be `Y` or `N`, require `VoidFlag` to be `Y` or `N`, and reject a row that is both primary and void ([BR-PER-028](../business-rules.md#br-per-028-claim-person-name-last-name-is-required), [BR-PER-029](../business-rules.md#br-per-029-claim-person-name-primary-flag-must-be-y-or-n), [BR-PER-030](../business-rules.md#br-per-030-claim-person-name-void-flag-must-be-y-or-n), [BR-PER-031](../business-rules.md#br-per-031-a-primary-claim-person-name-may-not-be-void)).
4. **Validate the collection-wide primary selection.** When the collection is dirty and non-empty, the collection-level rule counts primary rows and rejects the change unless exactly one row is marked primary ([BR-PER-032](../business-rules.md#br-per-032-only-one-claim-person-name-can-be-primary)).
5. **Generate the phonetic name code before insert.** `PhoneticNameCode`'s getter calls the shared `GetPhoneticNameCode` helper, which issues a scalar Oracle call to the phonetic-name package using the row's last, first, and middle names, and returns the derived code for persistence ([BR-PER-002](../business-rules.md#br-per-002-phonetic-name-generation-is-required-for-name-maintenance), [SQL-008](../sql/sql-008-select.md), [DUAL](../database-tables.md#dual)).
6. **Insert a new name-history row.** `BeforeInsert` builds the insert request with first, last, and middle names, upper-case variants, name-extension code, primary and void flags, the phonetic name code, and the acting user, binding all key values ([SQL-002](../sql/sql-002-insert.md), [CL_CLAIM_PERSON_NAME_HISTORY](../database-tables.md#cl_claim_person_name_history)).
   - On failure: if the insert affects zero rows, `AfterInsert` adds the standard DB-contention error message; otherwise it marks the row old.
7. **Update an existing name-history row.** `BeforeUpdate` updates only `PrimaryFlag`, `VoidFlag`, and update metadata for the row identified by `PersonID` and `PrimaryKeySubNum` ([SQL-017](../sql/sql-017-update.md), [CL_CLAIM_PERSON_NAME_HISTORY](../database-tables.md#cl_claim_person_name_history)).
   - On failure: if the update affects zero rows, `AfterUpdate` adds the DB-contention error message.
8. **Delete a name-history row.** `BeforeDelete` deletes the row identified by `PersonID` and `PrimaryKeySubNum` ([SQL-021](../sql/sql-021-delete.md), [CL_CLAIM_PERSON_NAME_HISTORY](../database-tables.md#cl_claim_person_name_history)).
   - On failure: if the delete does not affect exactly one row, the standard DB-contention error message is added.
9. **Save the managed collection.** `clsClaimPersonNameCollection.Save` calls `ApplyEdit()` before delegating to `MyBase.Save()`, so pending in-progress edits on the active row are committed before the collection-level save runs.

## Process flow

The following diagram visualizes this operation's control flow.

```mermaid
flowchart TD
    Start([Load name history for one person]) --> Read[Retrieve name-history rows]
    Read --> Change{Add or edit a row?}
    Change -->|Add| NewRow[Assign next sub-number<br>and initialize defaults]
    Change -->|Edit| Validate[Validate row and collection]
    NewRow --> Validate
    Validate --> Valid{Validation passes?}
    Valid -->|No| Fail([Broken rules returned])
    Valid -->|Yes| Phonetic[Generate phonetic name code]
    Phonetic --> Save[Insert, update, or delete row]
    Save --> Rows{Expected rows affected?}
    Rows -->|No| Contention([Add DB-contention message])
    Rows -->|Yes| Done([Save completes])
```

## Failure and edge-case behavior

- `PhoneticNameCode`'s getter has a side effect: every read issues a live Oracle call rather than returning a cached value, so repeated reads repeat the database round trip.
- A row that is both primary and void is rejected by validation, so a caller cannot silently void the primary name.
- The class defines `UpdateClaimPersonSQL` (an update against `CL_CLAIM_PERSON.PRIMARY_LAST_NAME`/`PRIMARY_FIRST_NAME`/`PRIMARY_MIDDLE_NAME`/`PRIMARY_NAME_EXTENSION_CODE`, [SQL-016](../sql/sql-016-update.md)), but no caller in this source set invokes it during name-history save — the primary name fields on `CL_CLAIM_PERSON` are not kept in sync by this class.*
- `IsValid` on the individual name row short-circuits to `True` when the row is not dirty, so unmodified rows are never re-validated.

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)
- [SQL catalog](../sql/index.md)
- [Database tables](../database-tables.md)

> **Note:** Statements marked with `*` were inferred from code structure, naming conventions, or
> contextual evidence where direct confirmation was not available in source artifacts.

## Sources
- `Business\SAIF.Business.Claim.Person\clsClaimPersonName.vb`
- `Business\SAIF.Business.Claim.Person\clsClaimPersonNameCollection.vb`
