---
title: Resolve policy-header associations
summary: Resolves policy-header associations using the configurable association type code table.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-07-31
library: SAIF.Business.View.Policy
reference_type: package
operation_id: OP-05
trigger: A caller requests policy-header associations for a policy
---

# Resolve policy-header associations

This is the current, data-driven replacement for the older hard-coded affiliation classification. Rather than encoding association families in .NET, the library loads a code table whose rows say what each association type is called, how it should be grouped and sorted, which security group governs it, and which stored procedure supplies its members. Adding an association type therefore becomes a data change rather than a code change.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-05 |
| **Trigger** | A caller requests policy-header associations for a policy |
| **Inputs** | `IDataPortalInfo` and a policy number |
| **Outputs** | A sequence of `IPolicyHeaderAssociation` values with attached period date ranges |
| **Primary components** | `clsPolicyHeaderAssociationFactory`, `clsAssociationTypeFactory`, `clsAssociationTypeCode` |
| **Entry point** | `Business/SAIF.Business.View.Policy/Associations/clsAssociationTypeCode.vb` |

## Steps

1. Load the association type code table in full and cache the resulting collection ([SQL-003](../sql/SQL-003-association-type-code-table.md), [ASSOCIATION_TYPE_CODE](../database-tables.md#association-type-code)).
   - Each row supplies the code, description, category, sort order, security group name, source procedure name, and the default-policy-header flag.
2. Group the loaded types by association category and resolve one source stored procedure per group ([BR-017](../business-rules.md#br-017-association-rows-without-a-matching-type-code-are-discarded)).
   - All types in a category must name the same source procedure; a category whose types disagree raises rather than choosing one.
3. Execute the resolved source procedure for the policy, passing the policy number and reading the result cursor ([SQL-029](../sql/SQL-029-non-typed-associations.md)).
   - The procedure name is a data value, so the executed body cannot be identified from source.**
   - Each row yields an association type code, policy number, is-parent flag, policy name, agent number, agency sequence number, and status description.
4. Match each row to a loaded type by comparing the category-prefixed association type code, and drop rows that match none ([BR-015](../business-rules.md#br-015-unrecognized-relationship-codes-are-classified-as-not-specified), [BR-017](../business-rules.md#br-017-association-rows-without-a-matching-type-code-are-discarded)).
5. Attach a coverage date range to each associated policy by reading the most recent issued period ([SQL-028](../sql/SQL-028-association-period-dates.md)).
   - A period counts as issued when it has a printed `P401` endorsement ([ENDORSEMENT](../database-tables.md#endorsement)) or a non-WCIS status of `E` ([POLICY_PERIOD_NON_WCIS](../database-tables.md#policy-period-non-wcis)), evaluated against [POLICY_PERIOD_ALL](../database-tables.md#policy-period-all).
   - The policy-number list is written into the statement text rather than bound as parameters, which differs from every other statement in this library.
   - Dates default per association family when none can be resolved ([BR-014](../business-rules.md#br-014-association-date-defaults-differ-per-association-family-and-detail-load-failures-are-non-fatal)).
6. Return the assembled header associations in the sort order carried by the code table.
   - Two superseded paths remain in the source for callers that have not migrated: affiliate-type classification ([SQL-013](../sql/SQL-013-policy-affiliate-type.md)) and parent-policy resolution ([SQL-019](../sql/SQL-019-parent-policy.md)), both marked obsolete.

## Process flow

The following diagram visualizes this operation's control flow.

```mermaid
flowchart TD
    Start([Header associations requested]) --> L[(Load ASSOCIATION_TYPE_CODE)]
    L --> G[Group types by category]
    G --> R{One source procedure<br>per category?}
    R -->|No| Err([Raise])
    R -->|Yes| X[(Execute the source procedure)]
    X --> M{Row matches a<br>known type code?}
    M -->|No| Drop[Discard the row]
    M -->|Yes| Keep[Keep the association]
    Keep --> P[(Attach issued period dates)]
    P --> Ok([Header association list])
    Drop --> Ok
```

## Failure and edge-case behavior

- A category whose types name different source procedures raises rather than picking one ([BR-017](../business-rules.md#br-017-association-rows-without-a-matching-type-code-are-discarded)).
- Rows whose code matches no loaded type are dropped silently, so a missing code table row hides associations without an error ([BR-015](../business-rules.md#br-015-unrecognized-relationship-codes-are-classified-as-not-specified)).
- The executed source procedure is a data value, so its behaviour cannot be verified from this repository.**

> **Note:** Statements marked with `†` are derived from dependency library
> documentation via the Legends CLI. Statements marked with `*` were inferred
> from code structure or contextual evidence. Statements marked with `**` could
> not be confirmed; treat as unknown until verified.

## Related documentation

- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)
- [SQL catalog](../sql/index.md)
- [Database tables](../database-tables.md)
- [Procedures](../procedures/index.md)
- [Security and authorization](../security-authorization.md)
- [API reference](../api/index.md)

## Sources

- `Business/SAIF.Business.View.Policy/Associations/clsAssociationTypeCode.vb`
- `Business/SAIF.Business.View.Policy/Associations/clsAssociationTypeCodeCollection.vb`
- `Business/SAIF.Business.View.Policy/Associations/clsPolicyHeaderAssociationFactory.vb`
- `Business/SAIF.Business.View.Policy/Associations/clsAssociationTypeFactory.vb`
