---
title: Worker injured body part management
summary: Maintains the list of body parts injured on a claim, enforcing exactly one primary body part and mirroring that primary selection onto the claim header.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-07-30
library: SAIF.Business.Claim
reference_type: package
operation_id: OP-BC-12
trigger: A claim-maintenance caller retrieves the injured body part collection for a claim, adds or edits entries, and saves
---

# Worker injured body part management

Every accepted claim identifies the body parts the worker injured, the side of the body affected, and the nature of each injury. Exactly one of those entries is the primary body part, which drives reporting and reserving, and the primary selection is mirrored onto the claim header so downstream consumers do not have to walk the detail rows. This operation manages that collection: adding entries with client-assigned sub-numbers, enforcing the primary-body-part rules across the whole collection, persisting each entry, and cascading the primary selection to the claim.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-BC-12 |
| **Trigger** | `clsWorkerInjuredBodyPartCollection.GetWorkerInjuredBodyPartCol(dataPortalInfo, claimID)`, then `NewWorkerInjuredBodyPart(claimID)` for additions, then `Save()` |
| **Inputs** | `ClaimID`; body part code; body side code (blank, both, left, or right); injury nature code; primary flag; `UpdateNum` |
| **Outputs** | Persisted `CL_WORKER_INJURED_BODY_PART` rows; the claim header's primary body part, side, and injury nature columns; error messages `InsertError`, `UpdateError`, `DeleteError`, and collection rule failures |
| **Primary components** | `clsWorkerInjuredBodyPartCollection` (`BeforeRetrieve`, `AfterRetrieve`, `NewWorkerInjuredBodyPart`, `PrimaryValid`, `OnlyOnePrimary`), `clsWorkerInjuredBodyPart` (`Create`, `AfterInsert`, `AfterUpdate`, `AfterDelete`, `UpdateClaimBodyPart`) |
| **Entry point** | `Business\SAIF.Business.Claim\clsWorkerInjuredBodyPartCollection.vb` |

## Steps

1. **Retrieve the claim's body parts.** `GetWorkerInjuredBodyPartCol` selects every injured body part row for the claim, ordered so that the primary flag sorts first, which puts the primary entry at the head of the collection ([SQL-027](../sql/SQL-027-saif-business-claim.md), [CL_WORKER_INJURED_BODY_PART](../database-tables.md#cl_worker_injured_body_part)).
2. **Hydrate and prime the collection.** `AfterRetrieve` builds one item per row, propagates the collection's validation flag onto each item, and tracks the highest primary key sub-number seen so new entries can continue the numbering.
3. **Add a new entry.** `NewWorkerInjuredBodyPart` increments the tracked sub-number on the client and creates an item for the claim; the item's create path is purely in-memory because its create and retrieve statements are empty by design.
   - The new item defaults the body part code and injury nature code to the numeric-zero character, the body side code to blank, and the primary flag to `N`.
4. **Enforce the primary body part rules.** Before the collection can be saved, two collection-level rules run:
   - A primary body part must be designated somewhere in the collection; this check is gated on the collection's validation flag so callers that suppress validation can bypass it ([BR-006](../business-rules.md#br-006-primary-body-part-must-be-designated)).
   - No more than one entry may carry the primary flag; this check is always enforced ([BR-007](../business-rules.md#br-007-only-one-body-part-may-be-marked-as-primary)).
5. **Insert an entry.** Saving a new item inserts the claim identifier, primary key sub-number, body part code, body side code, injury nature code, primary flag, `SYSDATE`, update number, and update user ([SQL-008](../sql/SQL-008-saif-business-claim.md), [CL_WORKER_INJURED_BODY_PART](../database-tables.md#cl_worker_injured_body_part)).
   - If exactly one row is not affected: add `InsertError` carrying the framework database contention message ([BR-008](../business-rules.md#br-008-updatedelete-row-count-must-equal-1)).
6. **Update an entry.** Saving an existing item writes the body part code, body side code, injury nature code, primary flag, `SYSDATE`, an incremented update number, and the update user, keyed on the claim identifier, primary key sub-number, and prior update number ([SQL-038](../sql/SQL-038-saif-business-claim.md), [CL_WORKER_INJURED_BODY_PART](../database-tables.md#cl_worker_injured_body_part)).
   - If exactly one row is not affected: add `UpdateError` carrying the framework database contention message ([BR-008](../business-rules.md#br-008-updatedelete-row-count-must-equal-1)).
7. **Mirror the primary selection onto the claim.** After a successful insert or update, and only when the item is dirty and carries the primary flag, `UpdateClaimBodyPart` runs its own portal request that writes the primary body part code, primary body side code, and primary injury nature code onto the claim header row together with `SYSDATE`, an incremented update number, and the update user ([BR-013](../business-rules.md#br-013-the-primary-injured-body-part-is-mirrored-onto-the-claim-header)). The claim header table belongs to another claim library and this statement is not represented in this library's SQL catalog.*
   - When the caller asks for the fields to be cleared instead, the same statement writes the numeric-zero character into the code columns and a blank into the side column.
   - The item is then marked old.
8. **Delete an entry.** Deleting removes the row by claim identifier, primary key sub-number, and prior update number ([SQL-047](../sql/SQL-047-saif-business-claim.md), [CL_WORKER_INJURED_BODY_PART](../database-tables.md#cl_worker_injured_body_part)).
   - If the affected row count is `0`: add `DeleteError` carrying the framework database contention message ([BR-008](../business-rules.md#br-008-updatedelete-row-count-must-equal-1)).

## Process flow

The following diagram visualizes this operation's control flow.

```mermaid
flowchart TD
	Start([Caller retrieves the injured<br>body parts for a claim]) --> Get[Select rows ordered with<br>the primary flag first]
	Get --> Hyd[Build items and track the<br>highest sub-number]
	Hyd --> Edit{Caller adds an entry?}
	Edit -->|Yes| New[Increment the sub-number<br>and create an in-memory item]
	Edit -->|No| Rules
	New --> Rules{Exactly one primary<br>body part designated?}
	Rules -->|No| RuleErr([Collection rule messages surface;<br>save is refused])
	Rules -->|Yes| Write{New item?}
	Write -->|Yes| Ins[Insert the body part row]
	Write -->|No| Upd[Update the body part row]
	Ins --> Rows{Rows affected = 1?}
	Upd --> Rows
	Rows -->|No| Err([Add Insert or Update error])
	Rows -->|Yes| Prim{Item is dirty<br>and primary?}
	Prim -->|No| Done([Row persisted])
	Prim -->|Yes| Claim[Write primary body part, side<br>and nature onto the claim header]
	Claim --> Done
```

## Failure and edge-case behavior

- The claim header update is executed directly through a portal request with no rows-affected check, so a failed cascade leaves the claim header out of step with the detail rows and reports nothing to the caller.
- Sub-numbers are assigned on the client from the highest value seen in the retrieved collection, so two concurrent sessions adding entries to the same claim can generate the same sub-number.
- The primary-body-part presence rule is gated on a validation flag propagated from the collection, so a caller that clears the flag can save a claim with no primary body part designated.
- The delete path has no success branch, so a successful delete leaves the item's state unchanged rather than marking it removed.*
- The helper that would reject an invalid injury nature always reports valid, so injury nature codes are effectively unvalidated by this library.
- Named injury-nature constants exist for hearing loss, heart attack, mental disorder, amputation, and COVID-19; the COVID-19 constant is declared but never referenced in this library.
- Clearing the primary fields writes placeholder values rather than nulls, so consumers of the claim header must treat the numeric-zero character and a blank side as "no primary body part".*

## 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\clsWorkerInjuredBodyPart.vb`
- `Business\SAIF.Business.Claim\clsWorkerInjuredBodyPartCollection.vb`
