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

# DocumentService

Implements `Core.Contracts.Policies.Certificates.Document.IDocumentService`, building the XML payloads and PDF streams for certificate documents, batch certificate reports, and renewal/OSC summary-list reports. It resolves policy data through `ICertificateInformationService`, resolves policyholder delivery preferences through `ICertificatePreferenceService`, generates PDFs via the utility `SAIF.Core.Services.Documents.IDocumentService.GeneratePdf`, and — for batch printing runs — persists `XPrintControl`/`XDocument` imaging-tracking records through `IUnitOfWork` so each generated document can be located and reprinted later.

## Purpose
- Produces the policyholder-copy PDF stream and single-certificate PDF stream for a certificate, and the renewal/OSC summary-list PDF stream for a set of certificates.
- Assembles the `CertificateDocumentRequest` (certificate, policy, period, marketing contact, cancel date, insured secondary name) that document XML generation is built from, choosing OSC vs. standard policy/period/marketing-contact resolution based on `Certificate.CertificateType`.
- Builds the certificate-holder-copy and policyholder-copy document XML fragments (mailing address block, employer liability limits, agency/producer info, cancellation flags) from a `CertificateDocumentRequest`.
- Resolves the correct marketing contact (agency vs. SAIF employee) for standard and OSC policies, and resolves a certificate's effective cancel date from its policy period's actual or pending cancellation date.
- Builds the full batch certificate-report XML (grouped by certificate holder and by policy) and renewal/OSC summary-report XML, registering `XPrintControl`/`XDocument` imaging-tracking rows via `IUnitOfWork` when running as part of a batch print.
- Builds the `ImageConfig` used to route a generated PDF into the imaging system for a given policy, document date, and OSC/SAIF document type.

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

## Public members
| Member | Signature | Purpose |
| --- | --- | --- |
| MAILTO_POLICYHOLDER_TITLE | `public const string MAILTO_POLICYHOLDER_TITLE = "Mail to:"` | Fixed label used as the mailing-address title when the policyholder is the addressee. |
| MAILTO_CERTHOLDER_TITLE | `public const string MAILTO_CERTHOLDER_TITLE = "Certificate holder:"` | Fixed label used as the mailing-address title when the certificate holder is the addressee. |
| SAIF_NAME | `public const string SAIF_NAME = "SAIF Corporation"` | Fixed company name used as a fallback marketing-contact company name. |
| DocumentService (constructor) | `public DocumentService(IUnitOfWork unitOfWork, IDocumentService utilDocumentService, ICertificateInformationService certificateInformationService, ICertificatePreferenceService certificatePreferenceService)` | Wires the unit of work, the utility PDF-generation/imaging document service, the certificate information service, and the certificate preference service, null-checking all four via `Enforce.ArgumentNotNull`. |
| GetCertificatePolicyHolderStream | `public Stream GetCertificatePolicyHolderStream(CertificateBatchPrintArguments batchPrintArguments, IList<Certificate> certificates)` | Builds the policyholder-copy report XML for the given certificates and renders it to a PDF `MemoryStream`; returns an empty stream if no certificates are ready to include. |
| GetCertificateDocumentStream | `public Stream GetCertificateDocumentStream(Certificate certificate, bool isPolicyholderCopy = false)` | Builds the document request and XML for a single certificate (certificate-holder or policyholder copy) and renders it to a PDF `MemoryStream`. |
| GetSummaryReportStream | `public Stream GetSummaryReportStream(IList<Certificate> certificates, Boolean isRenewalReport)` | Builds the renewal/OSC summary-list XML for the given certificates (outside batch-printing mode) and renders it to a PDF `MemoryStream`. |
| GetCertificateDocumentRequest | `public CertificateDocumentRequest GetCertificateDocumentRequest(Certificate certificate)` | Loads the certificate's policy via `ICertificateInformationService.GetPolicy`, resolves the applicable period and marketing contact (OSC period/contact for `OtherStates` certificates, otherwise the matching policy period and standard marketing contact), resolves the cancel date, and assembles the resulting `CertificateDocumentRequest`. |
| GetCertificateDocumentXmlForCertHolder | `public static XElement GetCertificateDocumentXmlForCertHolder(CertificateDocumentRequest certificateDocumentRequest)` | Builds the certificate document XML fragment addressed to the certificate holder (mailing address resolved for the certificate-holder copy). |
| GetCertificateDocumentXmlForPolicyHolder | `public static XElement GetCertificateDocumentXmlForPolicyHolder(CertificateDocumentRequest certificateDocumentRequest)` | Builds the certificate document XML fragment addressed to the policyholder (mailing address resolved for the policyholder copy). |
| GetCertificateMarketingContact | `public static IMarketingContact GetCertificateMarketingContact(Policy policy)` | Returns the policy's agency marketing contact, falling back to the employee marketing contact if there is no agency contact or its name is literally "SAIF". |
| GetOscCertificateMarketingContact | `public static IMarketingContact GetOscCertificateMarketingContact(Policy policy, OtherStatesPolicy oscPolicy)` | Returns the OSC policy's agency marketing contact, falling back to the parent policy's employee marketing contact if there is no OSC agency contact or its name is literally "SAIF". |
| GetCertificateMailingAddressInfo | `public static CertificateMailingAddressInfo GetCertificateMailingAddressInfo(Certificate certificate, Policy policy, bool isPolicyHolderCopy)` | Builds the two-block mailing-address structure (title/name/address pairs) for a certificate document: for the policyholder copy it fills both the policyholder block and (for non-Bid certificates) a secondary certificate-holder block; for the certificate-holder copy it fills only the certificate-holder block (again skipped for Bid certificates), upper-casing all address text and stripping a bare "OR" address via `CleanseAddress`. |
| GetInsuredSecondName | `public static string GetInsuredSecondName(Certificate certificate, Policy policy)` | Returns the certificate's DBA name if set, otherwise the policy's main DBA name, otherwise the policy's short name if it differs from its legal name; otherwise an empty string. |
| GetCertificateCancelDate | `public static string GetCertificateCancelDate(PeriodBase policyPeriod)` | Returns the period's actual cancel date formatted as `MM/dd/yyyy` if set, otherwise its pending cancel date similarly formatted, otherwise an empty string. |
| GetCertificateBatchReportXml | `public XDocument GetCertificateBatchReportXml(CertificateBatchPrintArguments batchPrintArguments, IList<Certificate> certsReadyToPrint)` | Registers a shared `XPrintControl` record, then builds and concatenates the certificate-holder-grouped and policy-grouped batch report XML sections, registering an `XDocument` imaging record (and updating its `FileName` to `{Id}.pdf`) for each generated certificate. |
| GetCertificateSummaryReport | `public XDocument GetCertificateSummaryReport(CertificateBatchPrintArguments arguments, IList<Certificate> certificateSummaryList, Boolean isRenewalReport, Boolean isBatchPrinting)` | Builds the renewal/OSC summary-list report XML, split into a SAIF-standard section and an OSC section per distinct policy number; when `isBatchPrinting` is true it registers `XPrintControl`/`XDocument` imaging records and computes an `ImageConfig` per policy, otherwise it renders the report without persisting imaging metadata. |
| GetImageConfig | `public ImageConfig GetImageConfig(long policyNumber, DateTime documentDate, Boolean isOsc, string imageCommentText, string createUser)` | Loads the policy and builds an `ImageConfig` (policy image file code, "CERT" category, "OSC" or "SAIF" document type, 458-day document-date offset, single page) used to route a generated document into the imaging system. |

## Behavioral notes
- `GetCertificateDocumentStream`, `GetCertificatePolicyHolderStream`, and `GetSummaryReportStream` all delegate final PDF rendering to the injected utility `IDocumentService.GeneratePdf`, using the fixed package names `Policy_OLCA_CertificateOfInsurance` (certificate documents) and `Policy_Certificates_List` (summary lists).
- `GetCertificatePolicyHolderStream` returns an empty `MemoryStream` (rather than attempting PDF generation) when the generated XML contains no `Certificates` descendant element, avoiding rendering an empty report.
- `GetCertificateBatchReportXml` and `GetCertificateSummaryReport` both persist `XPrintControl`/`XDocument` rows via `unitOfWork.GetRepository<...>().Add(...)` as a side effect of XML generation when running in batch/imaging mode — XML building and print-tracking persistence are not separated.*
- `GetCertificateMailingAddressInfo` special-cases Bid certificates (`Certificate.CertificateTypes.Bid`): the certificate-holder mailing block is left blank for Bid certificates in both the policyholder-copy and certificate-holder-copy branches.
- `CleanseAddress` (private) blanks out an address whose trimmed, upper-cased value is exactly `"OR"`, treating a bare state abbreviation as a missing address.
- The type mixes instance methods (which depend on injected collaborators and `IUnitOfWork`) with `static` methods (pure XML/string-building helpers with no collaborator dependency), so a subset of its public surface can be invoked without an instance.

## Constraints and usage notes
- All four constructor parameters are null-checked via `Enforce.ArgumentNotNull`, so this type cannot be constructed with any null collaborator.
- Several public members are `static` (`GetCertificateDocumentXmlForCertHolder`, `GetCertificateDocumentXmlForPolicyHolder`, `GetCertificateMarketingContact`, `GetOscCertificateMarketingContact`, `GetCertificateMailingAddressInfo`, `GetInsuredSecondName`, `GetCertificateCancelDate`) and can be called without an instance of `DocumentService`, while imaging-tracking-persisting members (`GetCertificateBatchReportXml`, `GetCertificateSummaryReport`) require an instance bound to a live `IUnitOfWork`.
- `GetCertificateSummaryReport` and `GetCertificateBatchReportXml` assume `unitOfWork` is actively participating in a transaction managed by the caller when `isBatchPrinting`/registration behavior applies persisted `XPrintControl`/`XDocument` rows; this type does not call `Begin()`/`Commit()` itself.*

> **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/Policies/Certificates/DocumentService.cs`
