---
title: Claim adjustment — void, combine, transfer, restore
summary: Executes exactly one of the four claim-adjustment actions through the PK82140_CLAIM_ADJUSTMENTS Oracle package after action-specific validation.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-07-30
library: SAIF.Business.Claim.Maintenance
reference_type: package
operation_id: OP-CM-03
trigger: Caller selects an AdjustmentAction, populates the matching context objects, and calls Save()
---

# Claim adjustment — void, combine, transfer, restore

Claim adjustment is a single business object with four mutually exclusive modes. The caller selects one adjustment action, populates the context that action needs, lets the action-specific rule set validate the request, and then calls `Save()`, which dispatches to the matching Oracle stored function in `PK82140_CLAIM_ADJUSTMENTS`. Void, combine, and restore each issue one call; transfer loops over a collection of claims and stops at the first failure.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-CM-03 |
| **Trigger** | Caller sets `AdjustmentAction` (or the `SetAdjustmentProperty` shortcut `V`, `C`, `T`, `R`), populates the associated context objects, and calls `Save()` after confirming `IsValid` |
| **Inputs** | Adjustment action selector; current claim (`ClaimID`, `ClaimUpdateNum`, `WorkerID`, `ClaimStatus`); combine claim number and resolved claim for combine; transfer-to worker and claim collection for transfer; the claim's own worker for restore; acting user from the data-portal info |
| **Outputs** | Boolean success (`ErrorCount = 0`); rows-affected return value from each stored function; broken rules, error messages, and warnings; persisted state changes executed inside the Oracle package |
| **Primary components** | `clsClaimAdjustment.Save`, `clsClaimAdjustment.IsValid`, `clsClaimAdjustment.AddBusinessRules`, `clsClaimAdjustment.RetrieveWorker`, `clsClaimAdjustment.NearbyClaimExists` |
| **Entry point** | `Business\SAIF.Business.Claim.Maintenance\clsClaimAdjustment.vb` |

## Steps

1. **Select the adjustment type.** The caller assigns `AdjustmentAction` — Void, Combine, Transfer, or Restore. Because the action is a single enum field, only one flow can ever run per call ([BR-CM-007](../business-rules.md#br-cm-007-void-combine-transfer-restore-are-mutually-exclusive-adjustment-operations)).
2. **Initialize the object.** `Create()` seeds the current claim from the criteria and clears the combine claim and transfer collection for a fresh instance.
3. **Dispatch validation (`IsValid`).** The broken-rule collection is cleared and `CheckRules` is invoked with the rule-set key matching the selected action — the void rule set alone for Void, void plus combine for Combine, transfer-worker plus transfer-claim for Transfer, and restore for Restore — so only the relevant rules run ([BR-CM-007](../business-rules.md#br-cm-007-void-combine-transfer-restore-are-mutually-exclusive-adjustment-operations)).
4. **Return the validation verdict.** `IsValid` returns `ErrorCount = 0`. Callers are expected to check it before calling `Save()`; `Save()` does not call `IsValid` itself.*
5. **Set up the save.** `Save()` calls `AcceptChanges()`, obtains a fresh portal request and data request from the data-portal info, and branches on the selected action.
6. **Void — validate.** The void rule set requires an active claim status, no legal case for the claim, no incurred costs, and no released or unposted payment; each check delegates to a claim service and adds an error message when it fails.
   - Sub-step: the claim services resolve legal-case existence, incurred costs, and non-posted payments for the claim identifier and return booleans consumed directly by the rules.

   > **Origin**: The legal-case, incurred-cost, and payment existence checks are implemented by the claim service classes in `SAIF.Business.Claim` and executed on behalf of this operation. That library is documented in the previous format, so no per-operation page exists; see [Operations and processes](../../saif-business-claim/operations-processes.md) in the `SAIF.Business.Claim` documentation set.
7. **Void — execute.** The request is configured as a scalar stored-procedure call to `PK82140_CLAIM_ADJUSTMENTS.VoidClaim`, binding the claim identifier, current update number, acting user, and a rows-affected return parameter ([SQL-085](../sql/SQL-085.md), [CL_INJURY_CLAIM](../database-tables.md#cl_injury_claim)) ([BR-PROC-001](../business-rules.md#br-proc-001-claim-void-requests-must-provide-the-claim-identifier-current-update-number-and-acting-u)).
   - On a rows-affected value of `0`: add `UpdateError` with the DB contention message (step 14).
8. **Combine — resolve the target claim.** Setting `CombineClaimNum` immediately loads the target claim through the claim-data factory so the combine rules can inspect it.
   - Sub-step: the claim-data factory (`clsClaimData.GetData`) retrieves the claim identified by the given claim number and returns the populated claim data used by the combine validation in step 9.

   > **Origin**: The target-claim retrieval is implemented by `clsClaimData.GetData` in `SAIF.Business.Claim` and executed on behalf of this operation. That library is documented in the previous format, so no per-operation page exists; see [Operations and processes](../../saif-business-claim/operations-processes.md) in the `SAIF.Business.Claim` documentation set.
9. **Combine — validate.** The combine rule set requires the target claim to be found and valid, to have an active status, to belong to the same worker, and to carry the same policy number as the current claim.
10. **Combine — execute.** The request calls `PK82140_CLAIM_ADJUSTMENTS.CombineClaim`, binding the current claim, the combine claim, the update number, the acting user, and the rows-affected return parameter ([SQL-082](../sql/SQL-082.md), [CL_INJURY_CLAIM](../database-tables.md#cl_injury_claim)) ([BR-PROC-002](../business-rules.md#br-proc-002-claim-combine-requests-must-identify-both-the-source-claim-and-the-claim-to-combine-into)).
    - On a rows-affected value of `0`: add `UpdateError` with the DB contention message (step 14).
11. **Transfer — resolve the target worker and claims.** `RetrieveWorker` looks the worker up by worker identifier ([SQL-030](../sql/SQL-030.md), [CL_CLAIM_PERSON](../database-tables.md#cl_claim_person)) or by primary tax identifier ([SQL-031](../sql/SQL-031.md), [CL_CLAIM_PERSON](../database-tables.md#cl_claim_person)) and populates the worker structure; the caller populates the collection of claims to move.
12. **Transfer — validate.** The transfer rule sets require a target worker that differs from the current claim's worker and a worker identifier greater than zero. The per-claim rule then walks the transfer collection:
    - If a claim does not have an active status: add an error naming that claim.
    - If a support order exists for a claim: add an error naming that claim.
    - If another claim for the target worker falls within a fourteen-day window of the injury date: add a warning only, using an inline scalar query ([SQL-029](../sql/SQL-029.md), [CL_INJURY_CLAIM](../database-tables.md#cl_injury_claim)).
13. **Transfer — execute per claim.** `Save()` loops the transfer collection and, for each claim, calls `PK82140_CLAIM_ADJUSTMENTS.TransferClaim` with that claim's identifier and update number, the target worker, the acting user, and the rows-affected return parameter ([SQL-084](../sql/SQL-084.md), [CL_INJURY_CLAIM](../database-tables.md#cl_injury_claim)) ([BR-PROC-003](../business-rules.md#br-proc-003-claim-transfer-and-restore-flows-require-a-target-worker-identifier-in-addition-to-claim-v)).
    - If the rows-affected value for a claim is `0`: add `UpdateError` with the DB contention message and exit the loop immediately, leaving the remaining claims untransferred.
14. **Restore — validate and execute.** The restore rule set requires the current claim to be in void status — the inverse of the void precondition. The request then calls `PK82140_CLAIM_ADJUSTMENTS.RestoreClaim` with the claim identifier, the claim's own current worker, the update number, the acting user, and the rows-affected return parameter ([SQL-083](../sql/SQL-083.md), [CL_INJURY_CLAIM](../database-tables.md#cl_injury_claim)) ([BR-PROC-003](../business-rules.md#br-proc-003-claim-transfer-and-restore-flows-require-a-target-worker-identifier-in-addition-to-claim-v)).
    - On a rows-affected value of `0`: add `UpdateError` with the DB contention message.
15. **Shared post-processing.** For every action except Transfer, `Save()` reads the rows-affected parameter once after the single stored-function call and adds a DB contention error when it is `0`; Transfer is excluded because it already performed the check per iteration.
16. **Return the outcome.** `Save()` returns `ErrorCount = 0` as the overall success indicator.

## Process flow

The following diagram visualizes this operation's control flow across the four mutually exclusive adjustment actions.

```mermaid
flowchart TD
	Start([Caller sets AdjustmentAction<br>and context objects]) --> Which{Which adjustment action?}
	Which -->|Void| VRules[Validate: active status,<br>no legal case, no incurred costs,<br>no released payment]
	VRules --> VOk{Rules pass?}
	VOk -->|No| Fail([Broken rules returned;<br>no package call])
	VOk -->|Yes| VCall[Call VoidClaim]
	Which -->|Combine| CLoad[Load combine claim]
	CLoad --> CRules[Validate: found, active,<br>same worker, same policy]
	CRules --> COk{Rules pass?}
	COk -->|No| Fail
	COk -->|Yes| CCall[Call CombineClaim]
	Which -->|Transfer| TLoad[Retrieve target worker<br>and transfer claims]
	TLoad --> TRules[Validate: different worker,<br>worker entered, each claim active,<br>no support order; nearby claim warns]
	TRules --> TOk{Rules pass?}
	TOk -->|No| Fail
	TOk -->|Yes| TLoop[For each claim:<br>call TransferClaim]
	TLoop --> TRows{RowsAffected = 0?}
	TRows -->|Yes| TAbort([Contention error added;<br>loop exits, partial transfer])
	TRows -->|No| TNext{More claims?}
	TNext -->|Yes| TLoop
	TNext -->|No| Done([Save returns ErrorCount = 0])
	Which -->|Restore| RRules[Validate: claim is in void status]
	RRules --> ROk{Rules pass?}
	ROk -->|No| Fail
	ROk -->|Yes| RCall[Call RestoreClaim]
	VCall --> Rows{RowsAffected = 0?}
	CCall --> Rows
	RCall --> Rows
	Rows -->|Yes| Contention([DB contention error added])
	Rows -->|No| Done
```

## Failure and edge-case behavior

- Mutual exclusivity is structural: the single enum plus the branch in `Save()` and the rule-set dispatch in `IsValid` make it impossible to run two adjustment types in one call ([BR-CM-007](../business-rules.md#br-cm-007-void-combine-transfer-restore-are-mutually-exclusive-adjustment-operations)).
- If the adjustment action is left unset, no branch matches, no stored function runs, and the subsequent rows-affected read fails or returns a stale value; this path is not explicitly guarded.*
- A rows-affected value of `0` is treated uniformly as a DB contention error across all four actions, but only Transfer has remaining work to abort.
- The transfer per-claim rule adds error and warning messages directly instead of returning a boolean, so blocking depends entirely on whether errors were added; the fourteen-day nearby-claim check is explicitly a warning.
- The combine rule flags a missing or invalid target claim as an error but does not prevent `Save()` from dereferencing it later, so callers must respect `IsValid` before saving.*
- A duplicate transfer-worker rule function exists in source but is never registered, so it has no runtime effect.*
- The factory requires valid claim data to construct the criteria; without claim context the object cannot be created at all.

## 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.Maintenance\clsClaimAdjustment.vb`
