---
title: SAIF.Business.Policy.Affiliate business rules
summary: Enumerated business rules for SAIF.Business.Policy.Affiliate.
status: draft
owner: Technical Writer
last_reviewed: 2026-07-31
library: SAIF.Business.Policy.Affiliate
reference_type: package
---

# SAIF.Business.Policy.Affiliate business rules

This page captures the rules enforced by `SAIF.Business.Policy.Affiliate` and the inherited BOF behavior it relies on.

## BR-AFF-001: Missing-key retrieval returns a default object

| Field | Value |
| --- | --- |
| **Statement** | Retrieval of a non-existent affiliate, interested party, preferred worker, or exemption returns a default-initialized object instead of raising an error. |
| **Trigger** | A keyed retrieve operation completes without a matching row. |
| **Enforcement** | `AfterRetrieve` checks for a row before calling `Fill`. |
| **Outcome** | Callers receive an object whose key and data fields remain at their initial values. |
| **Confidence** | Verified |
| **Source** | `Business\SAIF.Business.Policy.Affiliate\clsAffiliate.vb`

---

## BR-AFF-002: Affiliate display names omit empty parts

| Field | Value |
| --- | --- |
| **Statement** | Affiliate display names are built as last name, first name, middle initial, and suffix, omitting any empty component and its separator. |
| **Trigger** | The `Name` property is read on `clsAffiliate`. |
| **Enforcement** | `clsAffiliate.Name` appends only non-empty values in presentation order. |
| **Outcome** | Consumers receive a compact display name without extra punctuation or spacing. |
| **Confidence** | Verified |
| **Source** | `Business\SAIF.Business.Policy.Affiliate\clsAffiliate.vb`

---

## BR-AFF-003: Interested-party queries require type code 1

| Field | Value |
| --- | --- |
| **Statement** | Interested-party retrievals only return `BUSINESS_AFFILIATE` rows whose `AFFILIATE_TYPE_CODE` is `1`. |
| **Trigger** | An interested party or interested-party collection is retrieved. |
| **Enforcement** | Interested-party SQL injects the type predicate in its `WHERE` clause. |
| **Outcome** | Only interested-party associations are materialized. |
| **Confidence** | Verified |
| **Source** | `Business\SAIF.Business.Policy.Affiliate\clsInterestedParty.vb`

---

## BR-AFF-004: Affiliate associations join to people by SSN

| Field | Value |
| --- | --- |
| **Statement** | Policy-affiliate retrievals always join association rows to the underlying affiliate person record by SSN. |
| **Trigger** | Any interested-party or preferred-worker retrieve runs. |
| **Enforcement** | Shared SQL fragments join `BA.AFFILIATE_SSN` to `A.AFFILIATE_SSN`. |
| **Outcome** | Association objects are hydrated together with their nested `clsAffiliate` instance. |
| **Confidence** | Verified |
| **Source** | `Business\SAIF.Business.Policy.Affiliate\clsPolicyAffiliateBase.vb`

---

## BR-AFF-005: Association windows use overlap semantics

| Field | Value |
| --- | --- |
| **Statement** | Collection retrievals include an association when its effective date is before the requested end date and its cancel date is after the requested start date, treating null cancel dates as open-ended. |
| **Trigger** | An interested-party or preferred-worker collection is retrieved with a date window. |
| **Enforcement** | Collection SQL uses `BA.AFFILIATE_EFF_DATE < :EndDate` plus `nvl(BA.AFFILIATE_CANCEL_DATE, :StartDate + 1) > :StartDate`. |
| **Outcome** | Returned collections contain only associations that overlap the requested window. |
| **Confidence** | Verified |
| **Source** | `Business\SAIF.Business.Policy.Affiliate\clsInterestedPartyCollection.vb`

---

## BR-AFF-006: Association lists sort by person name

| Field | Value |
| --- | --- |
| **Statement** | Interested-party and preferred-worker collections sort rows by last name, first name, middle initial, and suffix. |
| **Trigger** | A collection retrieve completes. |
| **Enforcement** | Collection SQL appends an `order by` clause on affiliate-name columns. |
| **Outcome** | Callers receive deterministic alphabetical ordering. |
| **Confidence** | Verified |
| **Source** | `Business\SAIF.Business.Policy.Affiliate\clsInterestedPartyCollection.vb`

---

## BR-AFF-007: Transactional loads reuse shared code collections

| Field | Value |
| --- | --- |
| **Statement** | Interested-party children reuse collection-scoped code tables while a transaction is pending instead of loading them per child. |
| **Trigger** | `clsInterestedPartyCollection.AfterRetrieve` runs inside a pending transaction. |
| **Enforcement** | The collection passes cached title and insured-code collections into each child `Load` call. |
| **Outcome** | Nested code-table lookups are avoided inside the transaction. |
| **Confidence** | Verified |
| **Source** | `Business\SAIF.Business.Policy.Affiliate\clsInterestedPartyCollection.vb`

---

## BR-AFF-008: Interested-party active filters honor effective and cancel dates

| Field | Value |
| --- | --- |
| **Statement** | An interested party is active as of a date when its effective date is on or before that date and its cancel date is either null or later than that date. |
| **Trigger** | `InterestdParyExtensions.Active` is applied. |
| **Enforcement** | The extension filters by `EffectiveDate` and `CancelDate`. |
| **Outcome** | Consumers can derive the in-force interested-party subset for a date. |
| **Confidence** | Verified |
| **Source** | `Business\SAIF.Business.Policy.Affiliate\clsInterestedPartyCollection.vb`

---

## BR-AFF-009: Preferred-worker queries require type code 2

| Field | Value |
| --- | --- |
| **Statement** | Preferred-worker retrievals only return `BUSINESS_AFFILIATE` rows whose `AFFILIATE_TYPE_CODE` is `2`. |
| **Trigger** | A preferred worker or preferred-worker collection is retrieved. |
| **Enforcement** | Preferred-worker SQL injects the type predicate in its `WHERE` clause. |
| **Outcome** | Only preferred-worker associations are materialized. |
| **Confidence** | Verified |
| **Source** | `Business\SAIF.Business.Policy.Affiliate\clsPolicyPreferredWorker.vb`

---

## BR-AFF-010: Eligibility rows must cover both effective and cancel dates

| Field | Value |
| --- | --- |
| **Statement** | A preferred-worker eligibility row qualifies only when its window contains the association effective date and also contains the association cancel date, defaulting a missing cancel date to `12/31/9999`. |
| **Trigger** | Lazy eligibility loading executes for a preferred worker. |
| **Enforcement** | `GetPreferredWorkerData` filters on both dates with `nvl` and Oracle date literals. |
| **Outcome** | Only a fully covering eligibility row can populate preferred-worker details. |
| **Confidence** | Verified |
| **Source** | `Business\SAIF.Business.Policy.Affiliate\clsPolicyPreferredWorker.vb`

---

## BR-AFF-011: Earliest qualifying eligibility row wins

| Field | Value |
| --- | --- |
| **Statement** | When multiple preferred-worker eligibility rows qualify, the earliest eligibility-effective row is selected. |
| **Trigger** | More than one `PREFERRED_WORKER` row matches the lazy lookup. |
| **Enforcement** | The inner query orders by eligibility-effective date and the outer query applies `rownum = 1`. |
| **Outcome** | A single deterministic eligibility row is loaded. |
| **Confidence** | Verified |
| **Source** | `Business\SAIF.Business.Policy.Affiliate\clsPolicyPreferredWorker.vb`

---

## BR-AFF-012: Missing eligibility returns sentinel values

| Field | Value |
| --- | --- |
| **Statement** | When no preferred-worker eligibility row matches, the preferred-worker identifier and contract type become empty strings and both eligibility dates become `Date.MinValue`. |
| **Trigger** | The lazy eligibility query returns no rows. |
| **Enforcement** | `GetPreferredWorkerData` assigns sentinel values before returning. |
| **Outcome** | Later property reads see a stable empty eligibility state without repeating the query. |
| **Confidence** | Verified |
| **Source** | `Business\SAIF.Business.Policy.Affiliate\clsPolicyPreferredWorker.vb`

---

## BR-AFF-013: Affiliate SSN identifies single-officer exemptions

| Field | Value |
| --- | --- |
| **Statement** | A corporate officer exemption applies to a single named officer only when `AffiliateSSN` is populated. |
| **Trigger** | `IsSingleCorporateOfficerExemption` is evaluated. |
| **Enforcement** | `clsCorporateOfficerExemption` checks whether `AffiliateSSN` is null. |
| **Outcome** | Consumers can distinguish person-specific exemptions from policy-level exemptions. |
| **Confidence** | Verified |
| **Source** | `Business\SAIF.Business.Policy.Affiliate\clsCorporateOfficerExemption.vb`

---

## BR-AFF-014: IsActiveCorporateOfficer requires an expiration date

| Field | Value |
| --- | --- |
| **Statement** | `IsActiveCorporateOfficer` returns true only when the exemption has a non-null expiration date. |
| **Trigger** | `IsActiveCorporateOfficer` is evaluated. |
| **Enforcement** | `clsCorporateOfficerExemption.IsActiveCorporateOfficer` returns `Not IsExpirationDateNull()`. |
| **Outcome** | Open-ended exemptions report false while dated exemptions report true. |
| **Confidence** | Verified |
| **Source** | `Business\SAIF.Business.Policy.Affiliate\clsCorporateOfficerExemption.vb`

---

## BR-AFF-015: Corporate officer details are loaded only for single-officer exemptions

| Field | Value |
| --- | --- |
| **Statement** | The related affiliate person record is loaded only when an exemption names a specific officer. |
| **Trigger** | The `CorporateOfficer` property is read on `clsCorporateOfficerExemption`. |
| **Enforcement** | The property calls `clsAffiliate.GetAffiliate` only when `IsSingleCorporateOfficerExemption` is true. |
| **Outcome** | Policy-level exemptions avoid an unnecessary affiliate lookup. |
| **Confidence** | Verified |
| **Source** | `Business\SAIF.Business.Policy.Affiliate\clsCorporateOfficerExemption.vb`

---

## BR-AFF-016: Code descriptions come from framework code collections

| Field | Value |
| --- | --- |
| **Statement** | Affiliate title, insured-code, and exemption-reason descriptions are resolved from framework-managed code tables. |
| **Trigger** | A description property or code-collection property is read. |
| **Enforcement** | The library calls `clsCodeCollection.GetCodeCollection` for `AFFILIATE_TITLE_CODE`, `INSURED_CODE`, or `EXEMPT_REASON_CODE`. |
| **Outcome** | Callers receive the current description text for stored code values. |
| **Confidence** | Verified |
| **Source** | `Business\SAIF.Business.Policy.Affiliate\clsInterestedParty.vb`

---

## BR-AFF-017: Policy-affiliate identity is a three-part key

| Field | Value |
| --- | --- |
| **Statement** | Policy-affiliate equality is based on policy number, affiliate ID, and effective date. |
| **Trigger** | Equality checks, collection lookups, and removals compare two associations. |
| **Enforcement** | `clsPolicyAffiliateBase.Equals` and collection helper methods compare the three key fields. |
| **Outcome** | Membership tests and removals operate on the persisted association identity. |
| **Confidence** | Verified |
| **Source** | `Business\SAIF.Business.Policy.Affiliate\clsPolicyAffiliateBase.vb`

---

## BR-AFF-018: The library exposes retrieve-only data access

| Field | Value |
| --- | --- |
| **Statement** | Every criteria class throws when callers request create, insert, update, or delete SQL. |
| **Trigger** | Any persistence path is attempted through a criteria object. |
| **Enforcement** | Mutating SQL properties raise `ApplicationException(BOC.Messages.InvalidSQLProperty)`. |
| **Outcome** | Objects can be edited in memory but not persisted by this library. |
| **Confidence** | Verified |
| **Source** | `Business\SAIF.Business.Policy.Affiliate\clsPolicyAffiliateBase.vb`

---

## BR-AFF-019: Flag columns convert through framework boolean helpers

| Field | Value |
| --- | --- |
| **Statement** | Interested-party boolean flags are interpreted through the framework `ToBoolean` extension instead of local literal comparisons. |
| **Trigger** | `IsDirector`, `IsOwner`, or `IsOfficerOfNotice` is evaluated. |
| **Enforcement** | The properties call `ToBoolean` on the stored flag value. |
| **Outcome** | Flag interpretation stays aligned with BOF framework conventions. |
| **Confidence** | Verified |
| **Source** | `Business\SAIF.Business.Policy.Affiliate\clsInterestedParty.vb`

---

## BR-AFF-020: Stale cached affiliate objects are reloaded on access

| Field | Value |
| --- | --- |
| **Statement** | The cached nested affiliate is discarded and reloaded if its SSN no longer matches the association `AffiliateID`. |
| **Trigger** | The `Affiliate` property is read on a policy-affiliate object. |
| **Enforcement** | `clsPolicyAffiliateBase.Affiliate` re-fetches with `clsAffiliate.GetAffiliate` when the cached child no longer matches the key. |
| **Outcome** | Association objects keep their nested person object aligned with the current key. |
| **Confidence** | Verified |
| **Source** | `Business\SAIF.Business.Policy.Affiliate\clsPolicyAffiliateBase.vb`

---

## Inherited business rules

### From `clsBusinessBase` (`SAIF.Framework.Core`)

## INH-AFF-001: BOF base classes surface broken-rule state

| Field | Value |
| --- | --- |
| **Statement** | BOF business objects surface broken-rule state through the framework rules manager and `IDataErrorInfo`. This behavior is inherited from `clsBusinessBase` in `SAIF.Framework.Core`. |
| **Trigger** | A BOF-derived business object evaluates or exposes its validation state. |
| **Enforcement** | `clsBusinessBase` owns a `clsRulesManager` that tracks failed rules as `clsBrokenRule` entries, and implements the `IDataErrorInfo` `Error`/`Item` members to expose that broken-rule state to data-binding consumers. |
| **Outcome** | UI and service consumers can read validation errors through `IDataErrorInfo` without re-implementing rule plumbing or querying the rules engine directly. |
| **Confidence** | Verified — confirmed against the `SAIF.Framework.Core` business-rules documentation via the Legends CLI. |
| **Origin** | `SAIF.Framework.Core` — `clsBusinessBase` |
| **Source** | `SAIF.Framework.Core` business-rules documentation, BR-002 "Broken-rule tracking and surfacing" (citing `SAIF.Framework.Core\V1\BusinessRules\clsRulesManager.vb` and `SAIF.Framework.Core\V1\BaseItems\clsBusinessBase.vb`), retrieved via the Legends CLI. |

---

### From `clsBusinessCollectionBase` (`SAIF.Framework.Core`)

## INH-AFF-002: BOF collections expose traversal and validation surfaces

| Field | Value |
| --- | --- |
| **Statement** | BOF collections expose a collection-level `IDataErrorInfo` validation surface through the shared framework base class, and are inferred to provide current-item traversal following the same BOF collection conventions.* This behavior is inherited from `clsBusinessCollectionBase` in `SAIF.Framework.Core`. |
| **Trigger** | A collection consumer traverses items or reads collection-level validation state. |
| **Enforcement** | `clsBusinessCollectionBase` implements the `IDataErrorInfo` `Error`/`Item` members, surfacing broken-rule state to derived collections; current-item traversal members are assumed present based on standard BOF collection conventions.* |
| **Outcome** | Interested-party and preferred-worker collections inherit consistent `IDataErrorInfo` validation semantics, and are inferred to inherit consistent current-item traversal semantics.* |
| **Confidence** | Partially verified — the `IDataErrorInfo` validation surface is confirmed against the `SAIF.Framework.Core` business-rules documentation via the Legends CLI; current-item traversal behavior is inferred from BOF naming conventions and was not directly confirmed in that documentation. |
| **Origin** | `SAIF.Framework.Core` — `clsBusinessCollectionBase` |
| **Source** | `SAIF.Framework.Core` business-rules documentation, BR-002 "Broken-rule tracking and surfacing" (citing `SAIF.Framework.Core\V1\BusinessRules\clsRulesManager.vb` and `SAIF.Framework.Core\V1\BaseItems\clsBusinessBase.vb`), retrieved via the Legends CLI. |

## Related documentation
- [Index](index.md)
- [Overview](overview.md)
- [Architecture](architecture.md)
- [Dependencies](dependencies.md)
- [Operations and processes](operations-processes.md)
- [Database tables](database-tables.md)
- [SQL catalog](sql/index.md)
- [API reference](api/index.md)
- [Configuration](configuration.md)

> **Note:** Statements marked with * were inferred from code structure, naming conventions, or
> contextual evidence where direct confirmation was not available in source artifacts. Statements
> marked with ** could not be confirmed; treat as unknown until verified.

## Sources
- `Business\SAIF.Business.Policy.Affiliate\clsAffiliate.vb`
- `Business\SAIF.Business.Policy.Affiliate\clsPolicyAffiliateBase.vb`
- `Business\SAIF.Business.Policy.Affiliate\clsInterestedParty.vb`
- `Business\SAIF.Business.Policy.Affiliate\clsInterestedPartyCollection.vb`
- `Business\SAIF.Business.Policy.Affiliate\clsPolicyPreferredWorker.vb`
- `Business\SAIF.Business.Policy.Affiliate\clsCorporateOfficerExemption.vb`
