---
title: PolicyDocumentsService
summary: API reference for PolicyDocumentsService.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-09-24
library: SAIF.Services
reference_type: package
---

# PolicyDocumentsService

Implements `IPolicyDocumentsService`, the primary read/write API for policy output documents: retrieving policy metadata and viewable/held document lists for agencies and policyholders, adding, replacing, deleting, holding, and marking documents viewed/deleted, and resolving packaged document packets. It depends on `IUnitOfWork` for repository access and transactions, `IUserProfileService` for the current user, `IPolicyAssociationService` for related-policy lookups, `IOutputDocumentQueryProvider` and `IPolicyQueryProvider`/`IImageQueryProvider` for reference data, `IPolicySecurityService` for authorization filtering, and `IPolicyOutputDocumentRepository` for document persistence; its static constructor registers a large set of AutoMapper maps between data models and output-document contracts.

## Purpose
- Returns policy summary information (including validated associated/related policies) for a policy number, masking real names for demo users.
- Retrieves agency-viewable, policyholder-viewable, held/pending, payroll-report, and agency-inbox document lists, expanding multi-document packets via `PacketManager`.
- Adds new manually-scanned documents or packets, replaces or deletes existing documents (guarding against concurrent updates via update-number checks), and applies hold/unhold and agency-delete/undelete state changes.
- Resolves an image or a packet's constituent documents for viewing, and marks agency documents as viewed.

## Context
- Namespace: `SAIF.Services.OutputDocuments`
- Assembly/package: `SAIF.Services` (packaged inside the `SAIF.SAIFCode.Core` NuGet package)

## Public members
| Member | Signature | Purpose |
| --- | --- | --- |
| PolicyDocumentsService(...) | `public PolicyDocumentsService(IUnitOfWork uow, IUserProfileService userProfileService, IPolicyAssociationService associationService, IOutputDocumentQueryProvider outputDocumentQueryProvider, IPolicySecurityService policySecurityService, IPolicyQueryProvider policyQueryProvider, IImageQueryProvider imageQueryProvider, IPolicyOutputDocumentRepository policyOutputDocumentRepository)` | Validates every collaborator is non-null via `Enforce.ArgumentNotNull` and wires them in for use by the document operations. |
| GetDocumentDate | `public DateTime GetDocumentDate()` | Returns the current output-document processing/release date. |
| GetPolicy(policyNumber) | `public ContractOutputDocuments.Policy GetPolicy(long policyNumber)` | Returns policy summary information with no policy-association filtering (`associationType = "none"`). |
| GetPolicy(policyNumber, associationType) | `public ContractOutputDocuments.Policy GetPolicy(long policyNumber, string associationType)` | Returns the mapped policy along with security-filtered associated policies of the requested `AssociationTypes`, and replaces real policy/agency names with demo placeholders when the current user is a demo user. |
| GetCategories | `public IList<CodeTableListItem> GetCategories()` | Returns the active document category codes ordered by description. |
| GetPayrollReportDocuments | `public IEnumerable<PolicyDocument> GetPayrollReportDocuments(long reportId)` | Returns the individual output documents associated with a payroll report's packet sequence number. |
| GetPayrollReportPackets | `public IEnumerable<PolicyDocument> GetPayrollReportPackets(long reportId)` | Returns the payroll report's documents grouped into packets via `PacketManager.CreatePackets`. |
| GetAgencyViewableDocuments(policyNumber) | `public IEnumerable<PolicyDocument> GetAgencyViewableDocuments(long policyNumber)` | Returns all released, agency-viewable documents/packets for a policy. |
| GetAgencyViewableDocuments(policyNumber, documentCategory) | `public IEnumerable<PolicyDocument> GetAgencyViewableDocuments(long policyNumber, string documentCategory)` | Returns released, agency-viewable documents/packets for a policy filtered to a single document category. |
| GetPolicyholderViewableDocuments(policyNumber) | `public IEnumerable<PolicyDocument> GetPolicyholderViewableDocuments(long policyNumber)` | Returns released documents/packets for a policy further filtered to those flagged `IsPolicyholderViewable`. |
| GetPolicyholderViewableDocuments(policyNumber, documentCategory) | `public IEnumerable<PolicyDocument> GetPolicyholderViewableDocuments(long policyNumber, string documentCategory)` | Returns policyholder-viewable documents/packets for a policy filtered to a single document category. |
| GetHeldAndPendingDocuments | `public IEnumerable<PolicyDocument> GetHeldAndPendingDocuments(long policyNumber)` | Returns documents for a policy that are currently held or pending release. |
| GetDocumentsForAgency | `public IEnumerable<PolicyDocument> GetDocumentsForAgency(AgencyInboxFilter filter)` | Returns the agency inbox's documents/packets released within the filter's day range (optionally scoped to a producer), annotated with lease/wrap relationship descriptions and demo-user name masking, ordered by document date descending. |
| GetManualAddDocumentTypes | `public IEnumerable<ContractOutputDocuments.OutputDocumentTypeCode> GetManualAddDocumentTypes()` | Returns the document type codes eligible for manual document addition. |
| AddDocument | `public void AddDocument(ImageDocumentAdd imageDocumentAdd)` | Within a transaction, resolves the document/packet type code for the given policy and creates a new pending `PolicyOutputDocument`/`OutputDocument` pair referencing the supplied image; throws `ArgumentNullException` if the request is null. |
| AddPacket | `public void AddPacket(ImagePacketAdd imagePacketAdd)` | Within a transaction, resolves the packet's document type code and creates a new pending `PolicyOutputDocument`/`OutputDocument` pair for the packet's image; throws `ArgumentNullException` if the request or the resolved policy is null. |
| DeleteDocument | `public void DeleteDocument(DocumentDelete documentDelete)` | Marks the specified document deleted (setting its status, update date, and current user) after checking its update number matches, throwing `SaifValidationException` if another user updated it first. |
| HoldDocuments | `public void HoldDocuments(IEnumerable<DocumentHold> documents)` | Applies held/pending status changes to the supplied documents within a transaction; throws `SaifValidationException("There are no document holds to save.")` if none of the requested documents actually changed status. |
| ReplaceDocument | `public void ReplaceDocument(DocumentReplace replace)` | Within a transaction, if the existing document was updated by someone else since the client last read it, marks it deleted-for-image-replacement and throws `SaifValidationException`; otherwise marks the old document deleted and inserts a new document referencing the replacement image, updating any output-log entries that pointed at the old image. |
| GetImage | `public Image GetImage(long outputDocumentId)` | Returns the mapped image metadata for a document's underlying image, or `null` if the document has no image or the image cannot be found. |
| GetDocument | `public PolicyDocument GetDocument(DocumentRequest request)` | Returns the mapped policy document for the requested output-document ID, or `null` if it does not exist. |
| GetDocumentsForPacket | `public IEnumerable<PolicyDocument> GetDocumentsForPacket(long documentId, string packetId)` | Returns the documents belonging to a released packet, including any released child-policy documents when the requested document's policy has a relationship policy matching itself; throws `SaifValidationException` if the requested document has not been released. |
| MarkAgencyDocumentViewed | `public void MarkAgencyDocumentViewed(IEnumerable<long> documentIds)` | Within a transaction, sets `AgencyViewed = true` and records the update user/date for each specified document that exists. |
| MarkAgencyDocumentsDeleted | `public void MarkAgencyDocumentsDeleted(IEnumerable<DocumentAgencyDelete> documents)` | Within a transaction, sets the agency delete date (to now) and update user/date on each specified document. |
| MarkAgencyDocumentsUnDeleted | `public void MarkAgencyDocumentsUnDeleted(IEnumerable<DocumentAgencyDelete> documents)` | Within a transaction, clears the agency delete date and records the update user/date on each specified document. |

## Behavioral notes
- All mutating operations (`AddDocument`, `AddPacket`, `DeleteDocument`, `HoldDocuments`, `ReplaceDocument`, `MarkAgencyDocumentViewed`, `MarkAgencyDocumentsDeleted`, `MarkAgencyDocumentsUnDeleted`) wrap their work in `unitOfWork.Begin()`/`Commit()`, but only `ReplaceDocument`'s conflict path explicitly commits before throwing — most other paths rely on the ambient transaction to persist partial state if an unexpected exception occurs mid-method*.
- Optimistic-concurrency checks compare `PolicyOutputDocumentUpdateNumber`/`UpdateNumber` before deleting or replacing a document, raising `SaifValidationException("Error: Document updated by another user.")` on mismatch.
- `GetPolicy` and `GetDocumentsForAgency` both special-case demo users (`CurrentUser.IsDemoUser()`), replacing policy, legal, and agency names with fixed placeholder text so demo environments never expose real customer data.
- The static constructor registers dozens of AutoMapper class maps (policy, output document, image, agency/producer, category code) shared across the service's read methods; because these maps are static, they are configured once per process and shared by all instances.

> **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
- Services/SAIF.Services/OutputDocuments/PolicyDocumentsService.cs
