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

# CertificatePreferenceService

Manages per-policy certificate delivery preferences (delivery method, renewal notification type, email address, fax number) by reading and writing `CertData.CertificatePreference` records through `IUnitOfWork`, validating edits via `IValidationService`, and gating writes with an `IUserProfileService`-resolved current-user authorization check. It is consumed by `CertificateService.SetCertificateBatchPrintStatus` to decide certificate-holder/policyholder mail distribution status.

## Purpose
- Retrieves a single policy's certificate preference (mapped to the `CertificatePreference` contract, including converting the stored fax number into a `PhoneNumber`) or preferences for a batch of policy numbers.
- Creates a new certificate preference for a policy, or updates an existing one, both after validating the edit DTO and confirming the current user is authorized to update preferences.
- Reports whether a policy already has a stored preference, and whether the current user is authorized to save preferences at all.

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

## Public members
| Member | Signature | Purpose |
| --- | --- | --- |
| CertificatePreferenceService (constructor) | `public CertificatePreferenceService(IUnitOfWork unitOfWork, IValidationService validationService, IUserProfileService userProfileService)` | Wires the unit of work, validation service, and user-profile service used by every preference read/write operation. |
| GetPreference | `public CertificatePreference GetPreference(long policyNumber)` | Loads the policy's stored certificate preference and maps it to the `CertificatePreference` contract, or throws `CertificateServiceException` if none exists. |
| GetPreferences | `public IEnumerable<CertificatePreference> GetPreferences(List<long> policyNumberList)` | Returns the mapped certificate preferences for every policy number in the supplied list. |
| AddPreference | `public void AddPreference(long policyNumber, CertificatePreferenceEdit certificatePreferenceEdit)` | Validates the current user's authorization and the edit DTO, then creates and persists a new `CertData.CertificatePreference` for the policy with create/update user and timestamp set to the current user and time, committing the transaction. |
| SavePreference | `public void SavePreference(long policyNumber, CertificatePreferenceEdit certificatePreferenceEdit)` | Validates the current user's authorization and the edit DTO, then loads the policy's existing preference, applies the edit's field changes, updates the update-user/date, and commits the transaction. |
| HasPreference | `public bool HasPreference(long policyNumber)` | Returns whether any stored `CertificatePreference` record exists for the policy number. |
| HasSecurityToSavePreference | `public bool HasSecurityToSavePreference()` | Returns whether the current user holds the `Preference`, `PreferenceExternal`, or `"Certs"` authorization resource, i.e. can save preferences at all. |

## Behavioral notes
- A static constructor registers an AutoMapper mapping from `CertData.CertificatePreference` to `CertificatePreference`, resolving the `Fax` property from the stored `FaxNumber` string via `PhoneNumber`, once per process.
- `AddPreference` wraps its repository insert in `unitOfWork.Begin()`/`unitOfWork.Commit()`; `SavePreference` wraps its lookup-and-update in `unitOfWork.Begin()`/`unitOfWork.Commit()` as well.
- `GetPreferenceByPolicyNumber` catches `InvalidOperationException` from a `Single()` lookup and rethrows as `CertificateServiceException("Error: Preference not found.")`.
- `ValidateCertificatePreferenceEdit` throws `SaifValidationException` when `IValidationService.Validate` reports the edit DTO invalid.
- `ValidateUserCanUpdatePreference` throws `CertificateServiceException("Error: You are not authorized to update preferences")` when the current user lacks the `Preference`/`PreferenceExternal`/`"Certs"` authorization resource.
- `MapContractToDataObject` is `internal static`, converting the edit DTO's `DeliveryMethod` and `RenewalNotificationType` enums to their data-layer equivalents, copying the email address, and setting the fax number only when a non-null `Fax` value is supplied.*

## Constraints and usage notes
- All three constructor parameters (`unitOfWork`, `validationService`, `userProfileService`) are null-checked via `Enforce.ArgumentNotNull`.
- `AddPreference` sets `CreateUser`/`UpdateUser` to the current user's uppercased user ID, while `SavePreference` sets `UpdateUser` to the non-uppercased user ID — an inconsistency in casing between the two write paths.*
- Both `AddPreference` and `SavePreference` require the current user to pass `ValidateUserCanUpdatePreference` before any data is written, regardless of whether the caller already checked `HasSecurityToSavePreference`.*

> **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/CertificatePreferenceService.cs`
