---
title: Maintain recovery case
summary: Creates, retrieves, and updates the third-party recovery case header, including status-driven task and letter generation.
status: draft
owner: SAIF
last_reviewed: 2026-07-30
library: SAIF.Business.Claim.ThirdParty
reference_type: package
operation_id: OP-TP-01
trigger: clsThirdPartyCase.GetThirdPartyCase / NewThirdPartyCase followed by property edits and Save()
---

# Maintain recovery case

`clsThirdPartyCase` anchors the third-party recovery aggregate for a claim. A caller retrieves or creates a case, edits adjuster, closure, statute, and cause-of-action fields, and calls `Save()`, which persists the header, cascades saves to the firm and companion-claim child collections, and then derives follow-up tasks and print flags from the status transition that just occurred.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-TP-01 |
| **Trigger** | `clsThirdPartyCase.NewThirdPartyCase` (create) or `GetThirdPartyCase` (retrieve by `CaseSeqNum`/`ClaimID`), followed by property edits and `Save()` |
| **Inputs** | `ClaimID`, `CaseSeqNum`, adjuster code, status code, closure code, cause-of-action code, statute date, suit-filed date, subsequent-intervening-cause date/code, plaintiff/co-counsel firm sequence numbers |
| **Outputs** | Persisted `THRDPARTY_CASE` row; generated `THRDPARTY_TASK` rows for adjuster review, deferred-case review, and unit-stat prediction due dates; `PrintClosureLetter` / `PrintNoPursueLetter` / `PrintSaifAssumesLetter` flags; UW open/close email flags; rows-affected contention error |
| **Primary components** | `clsThirdPartyCase.Save`, `clsThirdPartyCase.ManageTasks`, `clsThirdPartyCase.ManageLetters`, `clsThirdPartyCase.AddBusinessRules` |
| **Entry point** | `Business\SAIF.Business.Claim.ThirdParty\clsThirdPartyCase.vb` |

## Steps

1. **Create or retrieve the case.** `Create()` seeds defaults (`CauseOfActionCode = "NOTD"`, `ThrdpartyStatusCode = "PEND"`, `ThrdpartyTypeCode = "UND"`, `StatuteDate = DOI + 2 years`) for a new case; `GetThirdPartyCase` retrieves an existing case by `CaseSeqNum`/`ClaimID` ([SQL-049](../sql/sql-049-pk82033_thirdparty-thrdparty_case_select.md), [THRDPARTY_CASE](../database-tables.md#thrdparty_case)).
2. **Validate the case (`IsValid`).** In addition to the base validation, the firm collection, task collection, and companion-claim collection are each checked if they have been read, and their broken rules are propagated to the case:
   - Adjuster code is required ([BR-009](../business-rules.md#br-009-third-party-case-adjuster-code-is-required)).
   - Closure code is required once the status is set to `CLOSE` ([BR-010](../business-rules.md#br-010-case-closure-requires-a-closure-code)).
   - Subsequent-intervening-cause date and suit-filed date must fall strictly between the date of injury and today ([BR-011](../business-rules.md#br-011-subsequent-intervening-cause-and-suit-filed-dates-must-fall-between-doi-and-today)).
   - Statute date is required and must not precede the date of injury ([BR-012](../business-rules.md#br-012-statute-date-is-required-and-must-follow-the-date-of-injury)).
   - Statute date month/day should match the DOI month/day, otherwise a warning is raised ([BR-013](../business-rules.md#br-013-statute-date-monthday-should-match-doi-warning)).
3. **Save firm assignments.** If the firm collection has been loaded, `Save()` first captures whether the plaintiff or co-counsel firm sequence number was cleared, saves the firm collection ([SQL-025](../sql/sql-025-pk82033_thirdparty-thrdparty_firm_insert.md), [SQL-080](../sql/sql-080-pk82033_thirdparty-thrdparty_firm_update.md), [THRDPARTY_FIRM](../database-tables.md#thrdparty_firm)), and re-derives the plaintiff/co-counsel sequence numbers from the saved collection by matching `FirmType` against `clsThirdPartyConstants.PLAINTIFF_FIRM` / `COCOUNSEL_FIRM`.
   - On failure: if the firm collection reports errors, `Save()` returns `False` immediately without persisting the case header.
4. **Save the companion-claim collection**, if it has been loaded, before the header save.
5. **Persist the case header** through `MyBase.Save()`, which dispatches to `BeforeInsert`/`AfterInsert` or `BeforeUpdate`/`AfterUpdate` depending on whether the case is new:
   - Insert calls the package with claim ID, adjuster/status/closure/type codes, cause-of-action and SIC codes, cocounsel/plaintiff firm sequence numbers, and statute date, and obtains the new `CaseSeqNum` from a preceding scalar sequence read ([SQL-022](../sql/sql-022-pk82033_thirdparty-thrdparty_case_insert.md), [THRDPARTY_CASE](../database-tables.md#thrdparty_case)).
   - Update binds the full set of editable header fields plus the key `CaseSeqNum`/`UpdateSeqNum`/`ClaimID` ([SQL-076](../sql/sql-076-pk82033_thirdparty-thrdparty_case_update.md), [THRDPARTY_CASE](../database-tables.md#thrdparty_case)).
   - On a rows-affected value other than `1`: `AfterInsert`/`AfterUpdate` adds an `InsertError`/`UpdateError` message and the header save is treated as failed.
6. **Clean up transient firm removals.** After the base save, if the plaintiff or co-counsel firm was cleared during this call, the case removes that firm from the in-memory collection and re-saves the firm collection to reflect the removal.
7. **Derive follow-up tasks (`ManageTasks`), only when the save succeeded and the case is not deleted:**
   - If the status changed to `DEFER`: delete any existing `NOTIC` task ([SQL-090](../sql/sql-090-pk82033_thirdparty-thrdparty_delete.md) family via `DeleteTaskSQL`, [THRDPARTY_TASK](../database-tables.md#thrdparty_task)) and create an `ADJ` task due in 30 days ("Review Deferred Case").
   - If the status changed to `OPEN`: delete any `NOTIC` task, set the underwriter-open-email flag, create an `ADJ` task due in 70 days ("Review Open Case"), and — if the claim's unit-stat due date falls within a ±60-day window of today — create an additional `ADJ` task for the unit-stat prediction due date, delegating the due-date lookup to `clsClaimData.GetData(...).UnitStatDueDate`.
     > **Origin**: The claim's unit-stat due date is retrieved from `clsClaimData` in `SAIF.Business.Claim`, which is documented in the previous format; see [Operations and processes](../../saif-business-claim/operations-processes.md) in that library's documentation set.
   - If the status changed to `CLOSE`: delete all tasks for the case ([SQL-090](../sql/sql-090-pk82033_thirdparty-thrdparty_delete.md) family via `DeleteAllTasksSQL`) and set the underwriter-close-email flag.
   - If the closure code changed to `SET` (settled): flag that a claim-adjuster task is needed (`NeedsClaimAdjusterTask`), for the caller to act on.
   - Each generated task is created through `clsThirdpartyTask.NewThirdpartyTask` and saved individually; if the new task is not savable, its error messages are folded into the case's own error collection under keys `TaskError1`, `TaskError2`, etc.
8. **Derive print flags (`ManageLetters`), only when the save succeeded and the case is not deleted:**
   - If the cause-of-action code was just set to `SAIFA` (SAIF assumes): set `PrintSaifAssumesLetter`.
   - If the status transitioned from `OPEN` to `CLOSE`: set `PrintNoPursueLetter` when the closure code is one of `PRPS`, `CA`, `N3PL`, `RPR`, and set `PrintClosureLetter` when the closure code is one of `PRPS`, `CA`, `DEFV`, `N3PL`, `RPR`, `COLL`.
9. **Mark the object clean** (`MarkOld()`) and return the overall save result (`ErrorCount = 0` from the base save).

## Process flow

The following diagram visualizes the maintain-recovery-case control flow from validation through status-driven follow-up.

```mermaid
flowchart TD
	Start([Caller retrieves or creates case]) --> Edit[Caller edits adjuster,<br>status, closure, statute fields]
	Edit --> Validate{IsValid?<br>rules + child collections}
	Validate -->|No| Fail([Broken rules returned;<br>no package call])
	Validate -->|Yes| Firms[Save firm collection<br>if loaded]
	Firms --> FirmErr{Firm errors?}
	FirmErr -->|Yes| Fail2([Save returns False;<br>header not persisted])
	FirmErr -->|No| Companion[Save companion-claim<br>collection if loaded]
	Companion --> HeaderSave[Insert or update<br>THRDPARTY_CASE via package]
	HeaderSave --> Rows{RowsAffected = 1?}
	Rows -->|No| Contention([InsertError/UpdateError added])
	Rows -->|Yes| Cleanup[Remove cleared plaintiff/<br>cocounsel firm; re-save firms]
	Cleanup --> Status{Status or closure<br>code changed?}
	Status -->|DEFER| Defer[Delete NOTIC task;<br>create 30-day review task]
	Status -->|OPEN| Open[Delete NOTIC task;<br>create 70-day review task;<br>conditional unit-stat task]
	Status -->|CLOSE| Close[Delete all tasks;<br>flag UW close email]
	Status -->|SET closure| Settled[Flag claim-adjuster<br>task needed]
	Status -->|No change| Letters[Evaluate print-letter flags]
	Defer --> Letters
	Open --> Letters
	Close --> Letters
	Settled --> Letters
	Letters --> Done([Save returns ErrorCount = 0])
```

## Failure and edge-case behavior

- A rows-affected value other than `1` on insert or update is the primary failure mode and surfaces as `InsertError`/`UpdateError` rather than an exception ([BR-005](../business-rules.md#br-005-recovery-save-operations-require-one-affected-row)).
- If the firm collection save reports errors, `Save()` returns `False` immediately and never attempts the header insert/update — the case header and firm collection are not left in a fully consistent saved state if only some firms failed.*
- Task creation failures inside `ManageTasks` do not stop the case save (the case has already been persisted by this point); they only add `TaskError<n>` messages to the case's error collection for the caller to inspect after `Save()` returns.
- The unit-stat prediction task is only created within a ±60-day window of the claim's unit-stat due date; outside that window no task is generated even though the case just opened.
- `ManageTasks` and `ManageLetters` run only when `ErrorCount = 0` and the case is not deleted, so a failed save never triggers task/letter side effects.

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

## Related documentation

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

## Sources

- `Business\SAIF.Business.Claim.ThirdParty\clsThirdPartyCase.vb`
- `Business\SAIF.Business.Claim.ThirdParty\clsThirdpartyTask.vb`
