---
title: Manage notes and tasks
summary: Persists free-form recovery notes and assigned follow-up tasks against a case, including last-task-delete protections for pending, deferred, and open cases.
status: draft
owner: SAIF
last_reviewed: 2026-07-30
library: SAIF.Business.Claim.ThirdParty
reference_type: package
operation_id: OP-TP-06
trigger: clsThirdpartyNote.NewThirdPartyNote / clsThirdpartyTask.NewThirdpartyTask followed by property edits and Save()
---

# Manage notes and tasks

Recovery notes (`clsThirdpartyNote`) are free-text case annotations; recovery tasks (`clsThirdpartyTask`) are assigned, due-dated follow-up items. Tasks carry the more elaborate rule set, including a multi-outcome check (`LastTaskDelete`) that blocks or warns before the last remaining task on a case can be removed, echoing the pending-case delete restriction already documented for tasks in general ([BR-004](../business-rules.md#br-004-pending-case-tasks-cannot-be-deleted-directly)).

| Field | Value |
| --- | --- |
| **Operation ID** | OP-TP-06 |
| **Trigger** | `clsThirdpartyNote.NewThirdPartyNote` / retrieval, and `clsThirdpartyTask.NewThirdpartyTask` / retrieval, each followed by property edits and `Save()` |
| **Inputs** | `CaseSeqNum`, note category code, note text; task code (category), task text, assigned-to user name, task due date, marked-for-delete flag |
| **Outputs** | Persisted `THRDPARTY_CASE`-scoped note rows and `THRDPARTY_TASK` rows; blocked or warned task deletions |
| **Primary components** | `clsThirdpartyNote.AddBusinessRules`, `clsThirdpartyTask.AddBusinessRules`, `clsThirdpartyTask.LastTaskDelete`, `clsThirdpartyTask.GetTaskDeleteCode` |
| **Entry point** | `Business\SAIF.Business.Claim.ThirdParty\clsThirdpartyTask.vb` |

## Steps

1. **Create or retrieve a note.** Retrieval reads notes by case ([SQL-059](../sql/sql-059-pk82033_thirdparty-thrdparty_note_select.md), [THRDPARTY_CASE](../database-tables.md#thrdparty_case)).
2. **Validate the note (`IsValid`):**
   - Note category code is required.
   - Note text is required.
   - Note text must not exceed 4000 characters.
   - All three checks are collectively enforced by the note's business rules ([BR-028](../business-rules.md#br-028-third-party-note-requires-a-category-and-note-text-limited-to-4000-characters)).
3. **Persist the note** via insert ([SQL-028](../sql/sql-028-pk82033_thirdparty-thrdparty_note_insert.md)) or update ([SQL-082](../sql/sql-082-pk82033_thirdparty-thrdparty_note_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.
4. **Create or retrieve a task.** Retrieval reads tasks by case and, optionally, task code ([SQL-045](../sql/sql-045-pk82033_thirdparty-selecttasks.md)/[SQL-046](../sql/sql-046-pk82033_thirdparty-selecttasksbycase.md), [THRDPARTY_TASK](../database-tables.md#thrdparty_task)).
5. **Validate the task (`IsValid`):**
   - Case sequence number must be non-zero, i.e. the owning case must exist ([BR-029](../business-rules.md#br-029-third-party-task-requires-a-case-category-assignee-and-task-text)).
   - Task code (category) is required ([BR-029](../business-rules.md#br-029-third-party-task-requires-a-case-category-assignee-and-task-text)).
   - Assigned-to user name is required ([BR-029](../business-rules.md#br-029-third-party-task-requires-a-case-category-assignee-and-task-text)).
   - Task text is required ([BR-029](../business-rules.md#br-029-third-party-task-requires-a-case-category-assignee-and-task-text)).
   - While the task is dirty and not marked for delete, the due date must fall between today and one year from today — already documented at the library level as [BR-003](../business-rules.md#br-003-third-party-task-due-dates-are-limited-to-a-one-year-window).
   - While the task is dirty and not deleted, a due date that does not fall on a working day triggers a warning that the date will be shifted to the next work day ([BR-030](../business-rules.md#br-030-task-due-dates-falling-on-a-non-work-day-are-automatically-shifted-to-the-next-work-day)).
6. **Evaluate the last-task-delete guard (`LastTaskDelete`), only when the task is marked for delete.** `GetTaskDeleteCode()` classifies the delete request against the case's remaining tasks and case status, and the rule branches on the returned code:
   - Code `1`: block the delete — pending-case tasks must be removed by deleting the case itself from the Review screen, matching the library-level rule already documented as [BR-004](../business-rules.md#br-004-pending-case-tasks-cannot-be-deleted-directly).
   - Code `2`: block the delete — deferred and open claims must retain at least one future task.
   - Code `3`: the first attempt raises a confirmation warning ("last task is being deleted... click save to confirm"); a second attempt, tracked via `m_LastTaskWarningGiven`, allows the delete to proceed.
   - Code `4`: allow the delete outright.
   - Any other code: block the delete with a generic "Task not found" error.
7. **Persist the task** via insert ([SQL-031](../sql/sql-031-pk82033_thirdparty-thrdparty_task_insert.md)), update ([SQL-085](../sql/sql-085-pk82033_thirdparty-thrdparty_task_update.md)), or delete ([SQL-097](../sql/sql-097-pk82033_thirdparty-thrdparty_task_delete.md)) against [THRDPARTY_TASK](../database-tables.md#thrdparty_task).
   - On a rows-affected value other than `1`: an insert/update/delete error message is added.

## Process flow

The following diagram visualizes task validation, focusing on the multi-outcome last-task-delete guard.

```mermaid
flowchart TD
	Start([Caller creates, edits, or<br>marks a task for delete]) --> Basic[Validate case, code,<br>assignee, text]
	Basic --> BasicOk{Valid?}
	BasicOk -->|No| Fail([Broken rules returned])
	BasicOk -->|Yes| DueDate{Dirty and<br>not marked for delete?}
	DueDate -->|Yes| Range[Validate due date within<br>one year window]
	DueDate -->|No| MarkDel{Marked for delete?}
	Range --> WorkDay[Warn if due date<br>is not a working day]
	WorkDay --> MarkDel
	MarkDel -->|No| Save[Insert or update THRDPARTY_TASK]
	MarkDel -->|Yes| Code{GetTaskDeleteCode}
	Code -->|1: pending case| BlockPending([Error: delete via<br>case Review screen])
	Code -->|2: deferred/open, no future task| BlockFuture([Error: must retain<br>a future task])
	Code -->|3: last task, first attempt| WarnConfirm([Warning: confirm delete])
	Code -->|3: last task, confirmed| Save
	Code -->|4: allowed| Save
	Code -->|else| BlockUnknown([Error: task not found])
	Save --> Rows{RowsAffected = 1?}
	Rows -->|No| Contention([Insert/Update/Delete error added])
	Rows -->|Yes| Done([Changes persisted])
```

## Failure and edge-case behavior

- The working-day warning (code path in step 5) does not itself move the due date in the rule function; the warning message states the date "has been changed," implying the shift happens elsewhere in the UI or caller flow rather than inside this rule.*
- The `LastTaskDelete` confirmation flow (code `3`) relies on in-memory state (`m_LastTaskWarningGiven`) to distinguish a first attempt from a confirmed retry, so it only works within a single object instance's lifetime — a fresh retrieval resets the confirmation state.*
- A rows-affected value other than `1` on any insert, update, or 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 validation has no length-based warning tier below the 4000-character hard limit — text at or under the limit is accepted regardless of length.

> **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\clsThirdpartyNote.vb`
- `Business\SAIF.Business.Claim.ThirdParty\clsThirdpartyNoteCollection.vb`
- `Business\SAIF.Business.Claim.ThirdParty\clsThirdpartyTask.vb`
- `Business\SAIF.Business.Claim.ThirdParty\clsThirdPartyTaskCollection.vb`
