---
title: Manage liens and settlements
summary: Persists recovery liens, lien categories, settlements, and settlement detail rows, enforcing settlement-total-to-detail-total reconciliation.
status: draft
owner: SAIF
last_reviewed: 2026-07-30
library: SAIF.Business.Claim.ThirdParty
reference_type: package
operation_id: OP-TP-04
trigger: clsThrdpartyLien / clsThrdpartyLienCategory / clsThrdpartySettlement / clsThrdpartySettlementDetail retrieval or creation followed by Save()
---

# Manage liens and settlements

Liens (`clsThrdpartyLien`), lien categories (`clsThrdpartyLienCategory`), settlements (`clsThrdpartySettlement`), and settlement detail rows (`clsThrdpartySettlementDetail`) together model how recovery money is claimed against and distributed. Settlement validation is the most rule-rich of the four, reconciling the settlement total against the sum of its detail rows before allowing a save.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-TP-04 |
| **Trigger** | Retrieval or creation of a lien, lien category, settlement, or settlement detail object, followed by property edits and `Save()` |
| **Inputs** | `CaseSeqNum`, lien date/amount, lien category fields, settlement amount/code/date, settlement detail category amount/code |
| **Outputs** | Persisted `THRDPARTY_LIEN`, `THRDPARTY_LIEN_CATEGORY`, and settlement/settlement-detail rows scoped to `THRDPARTY_CASE` |
| **Primary components** | `clsThrdpartyLien.AddBusinessRules`, `clsThrdpartySettlement.AddBusinessRules`, `clsThrdpartySettlementDetail.AddBusinessRules` |
| **Entry point** | `Business\SAIF.Business.Claim.ThirdParty\clsThrdpartyLien.vb` |

## Steps

1. **Create or retrieve a lien.** Retrieval reads a lien by case and sequence ([SQL-058](../sql/sql-058-pk82033_thirdparty-thrdparty_lien_select_by_seq.md)/[SQL-057](../sql/sql-057-pk82033_thirdparty-thrdparty_lien_select.md), [THRDPARTY_LIEN](../database-tables.md#thrdparty_lien)).
2. **Validate the lien.** Lien date is required ([BR-021](../business-rules.md#br-021-lien-date-is-required)); an expense-amount-required rule exists in source but is commented out and is not registered, so it has no runtime effect.*
3. **Persist the lien** via insert ([SQL-003](../sql/sql-003-pk82033_thirdparty-thrdparty_lien_create.md)), update, or delete against [THRDPARTY_LIEN](../database-tables.md#thrdparty_lien).
   - On a rows-affected value other than `1`: an insert/update/delete error message is added.
4. **Create or retrieve a lien category.** Retrieval reads categories by case ([SQL-056](../sql/sql-056-pk82033_thirdparty-thrdparty_lien_cat_select.md), [THRDPARTY_LIEN_CATEGORY](../database-tables.md#thrdparty_lien_category)). No business rules are registered for lien categories in source — validation, if any, is enforced entirely at the package level.*
5. **Persist the lien category** via insert ([SQL-027](../sql/sql-027-pk82033_thirdparty-thrdparty_lien_category_insert.md)) or update ([SQL-081](../sql/sql-081-pk82033_thirdparty-thrdparty_lien_category_update.md)).
6. **Create or retrieve a settlement.** Retrieval reads a settlement by case and sequence ([SQL-066](../sql/sql-066-pk82033_thirdparty-thrdparty_settlement_select.md), [THRDPARTY_CASE](../database-tables.md#thrdparty_case)).
7. **Validate the settlement (`IsValid`):**
   - The settlement amount must equal the sum of its own settlement detail rows (`SettlementDtlTotal`) ([BR-022](../business-rules.md#br-022-settlement-total-must-equal-the-sum-of-settlement-detail-amounts-and-be-greater-than-zero)).
   - While the settlement is dirty, the settlement amount must be greater than zero ([BR-022](../business-rules.md#br-022-settlement-total-must-equal-the-sum-of-settlement-detail-amounts-and-be-greater-than-zero)).
   - While the settlement is dirty, a settlement type code is required ([BR-023](../business-rules.md#br-023-settlement-type-and-settlement-date-are-required-date-cannot-be-in-the-future-or-otherwise-unreasonable)).
   - Settlement date is required, cannot be in the future, and must be a reasonable date (delegated to shared `CommonBusinessRules.IsTTodayOrFutureDate` / `IsReasonableDate` checks) ([BR-023](../business-rules.md#br-023-settlement-type-and-settlement-date-are-required-date-cannot-be-in-the-future-or-otherwise-unreasonable)).
8. **Persist the settlement** via insert ([SQL-030](../sql/sql-030-pk82033_thirdparty-thrdparty_settlement_insert.md)) or update ([SQL-084](../sql/sql-084-pk82033_thirdparty-thrdparty_settlement_update.md)) against [THRDPARTY_CASE](../database-tables.md#thrdparty_case).
   - On a rows-affected value other than `1`: an insert/update error message is added.
9. **Create or retrieve settlement detail rows** scoped to a settlement ([SQL-065](../sql/sql-065-pk82033_thirdparty-thrdparty_settl_dtl_select.md)).
10. **Validate settlement detail rows:**
    - Category amount cannot be less than zero ([BR-024](../business-rules.md#br-024-settlement-detail-category-amount-cannot-be-negative-and-category-code-is-required)).
    - Fund category code is required ([BR-024](../business-rules.md#br-024-settlement-detail-category-amount-cannot-be-negative-and-category-code-is-required)).
11. **Persist settlement detail rows** via insert ([SQL-029](../sql/sql-029-pk82033_thirdparty-thrdparty_settl_dtl_insert.md)) or update ([SQL-083](../sql/sql-083-pk82033_thirdparty-thrdparty_settl_dtl_update.md)) against [THRDPARTY_CASE](../database-tables.md#thrdparty_case).
    - When a caller adds, edits, or deletes a settlement detail row, the settlement total validation in step 7 re-runs the next time the settlement's `IsValid` is checked, so a detail-total mismatch blocks the settlement save even if each individual detail row is itself valid.

## Process flow

The following diagram visualizes settlement-to-detail reconciliation, the most rule-driven path in this operation.

```mermaid
flowchart TD
	Start([Caller edits settlement<br>and detail rows]) --> DetailRules[Validate each detail row:<br>amount >= 0, category code required]
	DetailRules --> DetailOk{Detail rows valid?}
	DetailOk -->|No| Fail([Broken rules returned])
	DetailOk -->|Yes| Recalc[Recompute SettlementDtlTotal]
	Recalc --> SettleRules[Validate settlement:<br>amount = detail total,<br>amount > 0, type + date required]
	SettleRules --> SettleOk{Valid?}
	SettleOk -->|No| Fail
	SettleOk -->|Yes| Save[Insert or update settlement<br>and detail rows]
	Save --> Rows{RowsAffected = 1?}
	Rows -->|No| Contention([Insert/Update error added])
	Rows -->|Yes| Done([Changes persisted])
```

## Failure and edge-case behavior

- Because the settlement-total rule compares against the live detail total, editing a detail row after the settlement has already validated can invalidate the settlement on the next check without an explicit re-save trigger from the caller.*
- The lien's expense-amount-required rule is fully commented out in source and never registered — the corresponding validation described in the class's TODO comments does not run.*
- Lien categories have no BOF-level business rules registered; any category-level validation is enforced by the `PK82033_THIRDPARTY` package rather than the BOF class.*
- A rows-affected value other than `1` on any insert/update/delete is treated as a DB contention failure rather than an exception ([BR-005](../business-rules.md#br-005-recovery-save-operations-require-one-affected-row)).

> **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\clsThrdpartyLien.vb`
- `Business\SAIF.Business.Claim.ThirdParty\clsThrdpartyLienCategory.vb`
- `Business\SAIF.Business.Claim.ThirdParty\clsThrdpartySettlement.vb`
- `Business\SAIF.Business.Claim.ThirdParty\clsThrdpartySettlementDetail.vb`
- `Business\SAIF.Business.Claim.ThirdParty\clsThirdpartySettlDtlType.vb`
