---
title: Get eligible claim payees
summary: Assembles the in-memory collection of payees eligible for a claim payment, combining the worker and the worker's beneficiaries under age, disability, and award-eligibility rules.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-07-30
library: SAIF.Business.Payment
reference_type: package
operation_id: OP-PAY-01
trigger: Caller invokes clsEligPayeeClaimCollection.getEligClaimPayees with a worker ID
---

# Get eligible claim payees

Get eligible claim payees builds the list of people who may legitimately receive a claim payment: the injured worker (unless deceased) and any beneficiaries whose relationship and award-eligibility fields currently qualify them. The operation is entirely in-memory — it does not execute local SQL — and instead composes worker, beneficiary, and address data retrieved from `SAIF.Business.Claim.Person` before applying the eligibility rules directly in `clsEligPayeeClaimCollection`.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-PAY-01 |
| **Trigger** | Caller invokes `clsEligPayeeClaimCollection.getEligClaimPayees(inDataportal, inWorkerID, inIncludeForeignAddresses, inIncludeNonEligiblePayees, inClaimID)` |
| **Inputs** | `IDataPortalInfo`; `inWorkerID`; `inIncludeForeignAddresses`; optional `inIncludeNonEligiblePayees` (default `False`); optional `inClaimID` (default `0`) |
| **Outputs** | Populated `clsEligPayeeClaimCollection` containing a blank placeholder payee plus the worker and/or beneficiary payee records that qualify |
| **Primary components** | `clsEligPayeeClaimCollection.getEligClaimPayees`, `clsEligPayeeClaimCollection.SelectBeneficiaryAddress`, `clsEligPayeeClaimCollection.ValidAddressOrNothing`, `clsEligPayeeClaimCollection.GetAddressTypeFromAddress`, `clsEligPayeeClaim.NewEligPayeeClaim` |
| **Entry point** | `Business\SAIF.Business.Payment\clsEligPayeeClaimCollection.vb` |

## Steps

1. **Create an empty result collection.** `getEligClaimPayees` calls `NewEligClaimPayees(inDataportal)` to construct a fresh `clsEligPayeeClaimCollection` through the BOF `CreateObject` pathway; the collection's own `RetrieveSQL` stub is never exercised by this flow because the collection is built by hand rather than fetched ([SQL-002](../sql/SQL-002-saif-business-payment.md)).
2. **Retrieve the worker record.** The operation calls `clsWorker.GetWorker(inDataportal, inWorkerID)`.
   - `GetWorker` resolves the `CCClaimDataApi` retrieve route `V1/GeneralWorkerData/Worker/{0}` for controller `GeneralWorkerData` and calls the data-portal's API access layer.
   - The API response is mapped into a `clsWorker` profile (dates, flags, phones, names, tax ID, update metadata) when the HTTP status is `OK`; otherwise an error is added and the profile is left unpopulated.*

   > **Origin**: Worker retrieval and profile mapping are implemented by [`Worker profile management`](../../saif-business-claim-person/operations/worker-profile-management.md) (`SAIF.Business.Claim.Person`) and executed on behalf of this operation.
3. **Retrieve the worker's beneficiaries.** The operation calls `clsBeneficiaryCollection.GetBeneficiariesForWorker(inDataportal, l_Worker.WorkerID, inClaimID)`.
   - The collection's `BeforeRetrieve` formats the `CCClaimDataApi` route `v1/GeneralWorkerData/Contacts/{WorkerID}?onlyActiveClaim={OnlyActiveClaim}` and requests claim-contact data for the worker.
   - `AfterRetrieve` materializes each returned contact into a `clsBeneficiary`, copying birth/death dates, email, gender, phones, tax ID, dependent type, worker/person identifiers, termination date, active flag, name components, and update date, and loads a guardian object immediately when the contact already carries guardian data.

   > **Origin**: Beneficiary contact retrieval and mapping are implemented by [`Beneficiary management`](../../saif-business-claim-person/operations/beneficiary-management.md) (`SAIF.Business.Claim.Person`) and executed on behalf of this operation.
4. **Retrieve the worker's addresses.** The operation calls `clsClaimPersonAddressCollection.GetClaimPersonAddressCollection(inDataportal, l_Worker.WorkerID)`.
   - This calls `clsWorkerAddress.GetWorkerAddresses(DataPortalInfo, PersonID)`, which configures the `CCClaimDataApi` route `V1/GeneralWorkerData/WorkerAddresses/{0}` and returns the caller's home, mailing, and payment addresses.

   > **Origin**: Address retrieval and mapping are implemented by [`Claim-person address management`](../../saif-business-claim-person/operations/claim-person-address-management.md) (`SAIF.Business.Claim.Person`) and executed on behalf of this operation.
5. **Add a blank payee placeholder.** A sentinel `clsEligPayeeClaim` is constructed with `PersonID = 0`, `Name.First = "< No Payee Selected >"`, no address, and `AddressType = NoAddress`, and is always added first so UI callers can present a "no payee selected" option ([BR-PAY-01](../business-rules.md#br-pay-01-eligible-payee-record-requirement)).
6. **Evaluate worker eligibility.** If `l_Worker.DeathDate > Date.MinValue` and `inIncludeNonEligiblePayees = False`, the worker is skipped entirely — no worker payee record is added ([BR-PAY-03](../business-rules.md#br-pay-03-dead-worker-exclusion-from-eligible-payee-list)).
   - If the worker qualifies (alive, or `inIncludeNonEligiblePayees = True`), a `clsEligPayeeClaim` is created via `clsEligPayeeClaim.NewEligPayeeClaim(inDataportal, l_Worker.WorkerID)` ([SQL-001](../sql/SQL-001-saif-business-payment.md)).
7. **Select the worker's address.** The worker address prefers mailing, then home, then a "no address" fallback:
   - If the mailing address is empty, or is foreign and `inIncludeForeignAddresses = False`: fall back to the home address under the same emptiness/foreign test; if that also fails, set `Address.AddressLine1 = MSG_NO_ADDRESS_FOUND` and `AddressType = NoAddress`.
   - Otherwise use the most recent home address history entry, or the mailing address, and set `AddressType` to `Home` or `Mailing` accordingly, stamping `AddressUpdateDate` from the selected address history row.
8. **Populate worker payee fields.** Name, gender, email, phone, birth date, death date, tax ID, and `PersonID` are copied from the worker profile onto the payee record, and the worker payee is added to the result collection.
9. **Evaluate each beneficiary in turn.** For each `clsBeneficiary` returned in step 3:
   - If the beneficiary's `RelationshipToWorkerCode = "2"` (child): eligible if `BirthDate.AddYears(26) >= Today` ([BR-PAY-04](../business-rules.md#br-pay-04-child-under-26-eligible-as-beneficiary-payee)); otherwise eligible only if `InvalidCode = "Y"` and `AwardEligExpDate > Now` ([BR-PAY-05](../business-rules.md#br-pay-05-invaliddisabled-child-over-26-exception)).
   - If the beneficiary is not a child: eligible if `AwardEligExpDate > Now` ([BR-PAY-06](../business-rules.md#br-pay-06-non-child-beneficiary-eligible-until-award-expiry)).
   - Regardless of the checks above, if `inIncludeNonEligiblePayees = True`, the beneficiary is included unconditionally ([BR-PAY-07](../business-rules.md#br-pay-07-include-non-eligible-payees-override)).
   - If neither the eligibility check nor the override applies: skip the beneficiary — no payee record is added for it.
10. **Select the beneficiary's address for each included beneficiary.**
    - If the beneficiary has a `Guardian`, use the guardian's address and mark `AddressType = Primary`.
    - Otherwise call `SelectBeneficiaryAddress`, which returns the first non-empty address in the order mailing, home, payment; if none are populated, set `Address.AddressLine1 = MSG_NO_ADDRESS_FOUND` and `AddressType = NoAddress`.
11. **Populate beneficiary payee fields.** Name, gender, email, phone, birth/death dates, age, `InvalidChild`, tax ID, and `PersonID` are copied from the beneficiary onto the payee record, and the beneficiary payee is added to the result collection.
12. **Return the assembled collection.** Once the worker branch and the beneficiary loop have both completed, `getEligClaimPayees` returns the populated `clsEligPayeeClaimCollection` to the caller.

## Process flow

The following diagram visualizes this operation's control flow.

```mermaid
flowchart TD
	Start([getEligClaimPayees called]) --> GetWorker[Retrieve worker record]
	GetWorker --> GetBenes[Retrieve worker beneficiaries]
	GetBenes --> GetAddrs[Retrieve worker addresses]
	GetAddrs --> AddBlank[Add blank payee placeholder]
	AddBlank --> DeathCheck{Worker DeathDate set<br>and not includeNonEligible?}
	DeathCheck -->|Yes| SkipWorker[Skip worker]
	DeathCheck -->|No| WorkerAddr[Select worker address:<br>Mailing then Home then NoAddress]
	WorkerAddr --> AddWorker[Add worker payee record]
	SkipWorker --> BeneLoop[For each beneficiary]
	AddWorker --> BeneLoop
	BeneLoop --> IsChild{Relationship code = child?}
	IsChild -->|Yes, under 26| EligA[Eligible]
	IsChild -->|Yes, 26+| InvalidCheck{Invalid code Y and<br>award not expired?}
	InvalidCheck -->|Yes| EligB[Eligible]
	InvalidCheck -->|No| NotEligA[Not eligible]
	IsChild -->|No| AwardCheck{Award eligibility<br>date in future?}
	AwardCheck -->|Yes| EligC[Eligible]
	AwardCheck -->|No| NotEligB[Not eligible]
	EligA --> IncludeCheck
	EligB --> IncludeCheck
	EligC --> IncludeCheck
	NotEligA --> IncludeCheck{Eligible or<br>includeNonEligible override?}
	NotEligB --> IncludeCheck
	IncludeCheck -->|Yes| BeneAddr[Select beneficiary address:<br>Guardian then Mailing then Home then Payment]
	BeneAddr --> AddBene[Add beneficiary payee record]
	IncludeCheck -->|No| SkipBene[Skip beneficiary]
	AddBene --> More{More beneficiaries?}
	SkipBene --> More
	More -->|Yes| BeneLoop
	More -->|No| Done([Return populated collection])
```

## Failure and edge-case behavior

- If the worker record is not found — `l_Worker.WorkerID <> inWorkerID` after `GetWorker` — the entire method returns just the blank placeholder payee; neither the worker nor any beneficiary is added.
- When no valid address is found for a worker or beneficiary, `Address.AddressLine1` is set to `MSG_NO_ADDRESS_FOUND` and `AddressType` is set to `NoAddress`; the payee is still returned, only without a usable address.
- The `inIncludeForeignAddresses = False` foreign-address exclusion applies only in the worker mailing/home address selection branch (step 7); `SelectBeneficiaryAddress` (step 10) does not re-check the foreign flag before selecting an address.*
- `inIncludeNonEligiblePayees = True` (step 9) overrides both the worker death-date exclusion ([BR-PAY-03](../business-rules.md#br-pay-03-dead-worker-exclusion-from-eligible-payee-list)) and every beneficiary eligibility check ([BR-PAY-04](../business-rules.md#br-pay-04-child-under-26-eligible-as-beneficiary-payee), [BR-PAY-05](../business-rules.md#br-pay-05-invaliddisabled-child-over-26-exception), [BR-PAY-06](../business-rules.md#br-pay-06-non-child-beneficiary-eligible-until-award-expiry)), so a caller passing this flag should expect ineligible and deceased-worker payees in the result.
- The eligible-payee contract in [BR-PAY-01](../business-rules.md#br-pay-01-eligible-payee-record-requirement) is realized here in-memory: a payee is only present in the returned collection when this operation constructs a `clsEligPayeeClaim` record for it, so downstream payment code must treat collection membership as the eligibility signal.*

## 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.Payment\clsEligPayeeClaimCollection.vb`
- `Business\SAIF.Business.Payment\clsEligPayeeClaim.vb`
