---
title: Claim unit maintenance
summary: Creates, retrieves, updates, and deletes a claim unit record tying a claim to a policy unit for Unit Stat reporting, including default-flag seeding and the claim-unit collection retrieve.
status: draft
owner: SAIF
last_reviewed: 2026-07-30
library: SAIF.Business.UnitStat
reference_type: package
operation_id: OP-US-02
trigger: Caller creates a new claim unit under a policy unit, or retrieves an existing claim unit or claim-unit collection by policy unit sequence number
---

# Claim unit maintenance

A claim unit links a claim to a policy unit for Unit Stat reporting purposes, carrying the loss/exposure detail and reporting flags for that claim within the unit. This operation covers `clsClaimUnit`'s create/retrieve/update/delete lifecycle and `clsClaimUnitCollection`'s retrieval of all claim units for a policy unit.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-US-02 |
| **Trigger** | `clsClaimUnit.NewClaimUnit` / `GetClaimUnit`, followed by property edits and `Save()`, or `clsClaimUnitCollection.GetClaimUnits` |
| **Inputs** | Policy unit sequence number, claim ID, loss/exposure amounts, value code, reporting flags |
| **Outputs** | Persisted `US_CLAIM_UNIT` row; populated `clsClaimUnit` or `clsClaimUnitCollection` |
| **Primary components** | `clsClaimUnit.Create`, `clsClaimUnit.BeforeInsert/AfterInsert`, `clsClaimUnit.BeforeUpdate/AfterUpdate`, `clsClaimUnit.BeforeDelete/AfterDelete`, `clsClaimUnit.BeforeRetrieve/AfterRetrieve`, `clsClaimUnitCollection.BeforeRetrieve/AfterRetrieve` |
| **Entry point** | `Business\SAIF.Business.UnitStat\clsClaimUnit.vb`, `Business\SAIF.Business.UnitStat\clsClaimUnitCollection.vb` |

## Steps

1. **Create.** `NewClaimUnit(dataPortal, claimID, policyUnitSeqNum)` invokes `Create()`, which seeds `ClaimID` from the criteria but, rather than using the criteria's `PolicyUnitSeqNum` (already supplied by the caller), allocates a brand-new value from the `US_POLICY_UNIT_SEQ` sequence into `m_PolicyUnitSeqNum`* — this appears to be an unintended divergence from the pattern used elsewhere in the library (see Failure and edge-case behavior below).
2. **New-object defaults.** `ValueCode`, `ReportedFatalFlag`, `ReportedClosedFlag`, and `PreferredWorkerFlag` are all seeded to `'N'` by member-variable initializers, so every new claim unit starts in these states unless explicitly overridden before save: `ValueCode` → `'N'` ([BR-US-028](../business-rules.md#br-us-028-valuecode-for-claim-units-defaults-to-n)), `ReportedFatalFlag` and `ReportedClosedFlag` → `'N'` ([BR-US-029](../business-rules.md#br-us-029-reportedfatalflag-and-reportedclosedflag-for-claim-units-default-to-n)), `PreferredWorkerFlag` → `'N'` ([BR-US-030](../business-rules.md#br-us-030-preferredworkerflag-for-claim-units-defaults-to-n)).
3. **Insert.** `BeforeInsert` stamps `UpdateUser`/`UpdateDate`, resets `UpdateNumber` to 0, and binds every column for the parameterized insert ([SQL-003](../sql/SQL-003-us-claim-unit-insert.md), [US_CLAIM_UNIT](../database-tables.md#us-claim-unit)). `AfterInsert` checks rows affected:
   - If `RowsAffected <> 1`: adds `InsertError` with the literal "Insert Failed" message.
   - Otherwise: `MarkOld()`.
4. **Retrieve single claim unit.** `Criteria.RetrieveSQL` dispatches on `RetrieveType`, exposed through two public factory overloads:
   - `GetClaimUnit(dataPortal, claimID)` — retrieves the active claim unit by claim ID alone, filtering `ACTIVE_UNIT_FLAG = 'Y'` ([SQL-012](../sql/SQL-012-us-claim-unit-active-row-by-claim.md)).
   - `GetClaimUnit(dataPortal, claimID, policyUnitSeqNum)` — retrieves by the composite claim ID and policy unit sequence number, regardless of active status ([SQL-013](../sql/SQL-013-us-claim-unit-row-by-claim-and-policy-unit.md)).
   - `AfterRetrieve` fills the object when a row is found and always calls `MarkOld()`.
5. **Retrieve claim-unit collection.** `clsClaimUnitCollection.GetClaimUnits(policyUnitSeqNum)` selects every `US_CLAIM_UNIT` row for the policy unit ([SQL-016](../sql/SQL-016-us-claim-unit-collection-by-policy-unit.md)), including inactive/previously-removed claim units — per an explicit source comment, this collection intentionally returns all rows rather than filtering to an active subset.
6. **Update.** `BeforeUpdate` increments `UpdateNumber`, restamps `UpdateUser`/`UpdateDate`, and rebinds every column ([SQL-028](../sql/SQL-028-us-claim-unit-update.md), [US_CLAIM_UNIT](../database-tables.md#us-claim-unit)). `AfterUpdate` checks rows affected:
   - If `RowsAffected <> 1`: adds `UpdateError` with `clsConstants.Messages.DBContentionError` ([BR-US-020](../business-rules.md#br-us-020-database-contention-on-update-or-delete-is-detected-by-checking-rowsaffected-1)).
   - Otherwise: `MarkOld()`.
7. **Delete.** `BeforeDelete` binds `ClaimID` and `PolicyUnitSeqNum` to the delete-by-composite-key statement ([SQL-034](../sql/SQL-034-us-claim-unit-delete.md)). `AfterDelete` checks rows affected:
   - If `RowsAffected <> 1`: adds `DeleteError` with `clsConstants.Messages.DBContentionError` ([BR-US-020](../business-rules.md#br-us-020-database-contention-on-update-or-delete-is-detected-by-checking-rowsaffected-1)).
   - Otherwise: `MarkNew()`.
8. **Parent linkage.** A claim unit is always retrieved and persisted as a child of a policy unit's `ClaimUnits` collection (see [Policy unit CRUD](policy-unit-crud.md)); it is not saved as a standalone root object in normal use.

## Process flow

```mermaid
flowchart TD
	Start([Caller creates or retrieves<br>a claim unit]) --> Which{Create, retrieve one,<br>retrieve collection,<br>update, or delete?}
	Which -->|Create| SeqBug[Allocate new PolicyUnitSeqNum<br>from sequence, ignoring criteria value]
	SeqBug --> Defaults[Apply flag defaults:<br>ValueCode=N, ReportedFatalFlag=N,<br>ReportedClosedFlag=N, PreferredWorkerFlag=N]
	Defaults --> Insert[Insert US_CLAIM_UNIT row]
	Insert --> InsRows{RowsAffected = 1?}
	InsRows -->|No| InsErr([InsertError: Insert Failed])
	InsRows -->|Yes| MarkOldA([MarkOld])
	Which -->|Retrieve one| RetOne[Select by PolicyUnitSeqNum<br>and ClaimID]
	RetOne --> FillOne[Fill object if found;<br>MarkOld regardless]
	Which -->|Retrieve collection| RetAll[Select all rows<br>for PolicyUnitSeqNum<br>includes inactive units]
	Which -->|Update| Upd[Rebind all columns;<br>restamp UpdateUser/UpdateDate]
	Upd --> UpdRows{RowsAffected = 1?}
	UpdRows -->|No| Contention([UpdateError: DB contention])
	UpdRows -->|Yes| MarkOldB([MarkOld])
	Which -->|Delete| Del[Delete by PolicyUnitSeqNum<br>and ClaimID]
	Del --> DelRows{RowsAffected = 1?}
	DelRows -->|No| ContentionDel([DeleteError: DB contention])
	DelRows -->|Yes| MarkNewA([MarkNew])
```

## Failure and edge-case behavior

- `Create()` allocates a brand-new `US_POLICY_UNIT_SEQ` value into the claim unit's `PolicyUnitSeqNum` instead of using the value supplied via `NewClaimUnit(...)`'s criteria; this looks like an unintended bug rather than deliberate behavior, since it would associate the new claim unit with the wrong policy unit if the allocated sequence differs from the intended parent.*
- `clsClaimUnitCollection.GetClaimUnits` returns all claim units for a policy unit, including inactive ones, by explicit design (per source comment) — callers must filter by activity status themselves if only active claim units are wanted.
- Insert failures use the literal "Insert Failed" message, distinct from the shared `DBContentionError` message used for update/delete failures.

## 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. Statements
> marked with `**` could not be confirmed; treat as unknown until verified.

## Sources

- `Business\SAIF.Business.UnitStat\clsClaimUnit.vb`
- `Business\SAIF.Business.UnitStat\clsClaimUnitCollection.vb`
