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

# SubpoenaService

Supplies the read-side data and reference lists behind the subpoena UI: the pending-subpoena inbox (merged from the local `Subpoena` entity and Guidewire's `ICCClaimApiService` claim data), mileage/payment calculations for witness fees, a single subpoena's full detail view, code-table lookups (statuses, types, mailing options, hearing locations, registered agents, process servers), the current employee's authority limits, and the set of employees eligible to initiate a subpoena. It hides conflicted-worker claimant names from users lacking the `"LNConflict"` authorization and calculates driving mileage via `IGoogleMapsApiServiceProxy`.

## Purpose
- Builds the subpoena inbox (all non-paid, non-ready-to-pay subpoenas) enriched with claimant name, conflict status, and a formatted witness list, masking claimant names as "Confidential" for users without conflict-view access.
- Calculates witness mileage and payment amount either from two addresses (via Google Maps driving distance, doubled for round trip) or from a supplied mileage figure, applying the current mileage rate and flat payment amount.
- Retrieves a single subpoena's full detail (merged from the data entity and the Guidewire claim), enriching each recipient with a formatted provider/registered-agent address.
- Builds the subpoena-approval-request email content.
- Exposes reference/code-table lists: subpoena statuses, subpoena types, mailing/special-handling options, Oregon business policy locations for a policy, hearing locations, registered agents (with formatted addresses), and process servers.
- Determines whether the current user can enter subpoenas and the current user's initiate/approve payment authority limits and default/minimum compliance dates.

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

## Public members
| Member | Signature | Purpose |
| --- | --- | --- |
| SubpoenaService (constructor) | `public SubpoenaService(IUnitOfWork unitOfWork, IUserProfileService userProfileService, ILocationQueryProvider locationQueryProvider, ProviderContract.IProviderInformationService providerInformationService, IEnvironmentService environmentService, IBillServiceHelper billServiceHelper, IGoogleMapsApiServiceProxy googleMapsService, ICCClaimApiService claimApiService)` | Wires the unit of work, current-user profile (captures uppercased user ID and the `"LNConflict"` authorization flag), location query provider, provider address lookups, environment configuration, authority-limit/issue-date helper, Google Maps distance proxy, and Claim Center claim API client. |
| GetInboxItems | `public IEnumerable<SubpoenaInboxItem> GetInboxItems()` | Returns every subpoena not yet paid or ready-to-pay as a `SubpoenaInboxItem`, merged with its Guidewire claim data, with claimant names masked to `"Confidential"` for users lacking conflict access, requester display name resolved from `Employee`, and a newline-joined witness list built from each recipient's provider or legal-person name — ordered by subpoena ID. |
| GetCalculatedSubpoenaPayment(string, string) | `public SubpoenaPaymentCalculationResults GetCalculatedSubpoenaPayment(string fromLocation, string toLocation)` | Computes round-trip mileage between two encoded, `<br>`-delimited address strings via `IGoogleMapsApiServiceProxy`, retrying with a truncated `fromLocation` on failure until only the last address segment remains, then derives mileage cost and total paid amount (flat fee + mileage cost, or `0` if no mileage); sets an error message if mileage could not be calculated. |
| GetCalculatedSubpoenaPayment(decimal) | `public SubpoenaPaymentCalculationResults GetCalculatedSubpoenaPayment(decimal miles)` | Derives mileage cost and total paid amount directly from a supplied mileage figure (clamped to a minimum of `0`), applying the current mileage rate and flat payment amount. |
| GetSubpoena | `public Subpoena GetSubpoena(long subpoenaId, IMessageContainer messageContainer)` | Loads the subpoena by ID, merges in Guidewire claim data, resolves each recipient's formatted provider/registered-agent address, and returns it; adds a "Subpoena not found" error and returns a new empty `Subpoena` if no match exists. |
| GetApprovalEmail | `public ApprovalEmail GetApprovalEmail(long id, string caseNumber, string claimantName)` | Builds an `ApprovalEmail` addressed to the fixed legal-approvers distribution list, with a subject naming the case/claimant and a body linking to the subpoena's entry screen. |
| ListOfSubpoenaStatus | `public IList<SubpoenaStatus> ListOfSubpoenaStatus { get; }` | All configured subpoena status codes, mapped to their contract representation. |
| ListOfSubpoenaTypes | `public IList<SubpoenaType> ListOfSubpoenaTypes { get; }` | All configured subpoena type codes, mapped to their contract representation. |
| ListOfMailingOptions | `public IList<SubpoenaSpecialHandling> ListOfMailingOptions { get; }` | All configured subpoena special-handling (mailing) options, mapped to their contract representation. |
| ListOfPolicyLocations | `public IList<Core.Contracts.Locations.Location> ListOfPolicyLocations(long policyNumber)` | Returns the Oregon business locations for the given policy number, ordered by location name, with each location's display name augmented to include its address line and city. |
| InitiateEmployeeList | `public IList<LegalEmployee> InitiateEmployeeList()` | Returns employees currently holding an unexpired subpoena-payment initiate authority limit, ordered by last name, flagging whichever entry matches the current user as `IsSelectedUser`. |
| ListOfHearingLocations | `public IList<HearingLocation> ListOfHearingLocations { get; }` | All non-expired hearing locations excluding the federal (`"FED"`) code, mapped to contract objects and ordered by full location name then location name. |
| ListOfRegisteredAgents | `public IList<RegisteredAgent> ListOfRegisteredAgents { get; }` | All registered agents, each enriched with a formatted address built from its linked provider location's business name and first address. |
| ListOfProcessServers | `public IList<ProcessServer> ListOfProcessServers { get; }` | All process servers, each with its business name populated from the linked provider location. |
| CanEnterSubpoenas | `public bool CanEnterSubpoenas()` | Returns whether the current user holds the `"LNSubpoenaUpdate"` authorization. |
| CurrentUserPaymentLimit | `public decimal CurrentUserPaymentLimit()` | Returns the current user's subpoena-payment initiate authority limit via `IBillServiceHelper.UserAuthorityLevel`. |
| CurrentUserApprovalLimit | `public decimal CurrentUserApprovalLimit()` | Returns the current user's subpoena-payment approve authority limit via `IBillServiceHelper.UserAuthorityLevel`. |
| DefaultComplianceDate | `public DateTime DefaultComplianceDate { get; }` | The suggested subpoena compliance date: the next "LS" issue date plus 14 days. |
| MinimumComplianceDate | `public DateTime MinimumComplianceDate { get; }` | The earliest allowable subpoena compliance date: the next "LS" issue date plus 7 days. |

## Behavioral notes
- Carries a `CA1506:AvoidExcessiveClassCoupling` class-level suppression, reflecting its dependency on location, provider, environment, authority-helper, Google Maps, and Claim Center collaborators.*
- A static constructor calls `SubpoenaMappingHelper.MapSubpoenaService()`, registering the AutoMapper mappings this service relies on, once per process.
- `CreateSubpoena`/`CreateSubpoenaInboxItem` both call `_claimApiService.GetClaim(...).GetAwaiter().GetResult()`, synchronously blocking on the asynchronous Claim Center claim lookup rather than exposing an async API.*
- `GetCalculatedSubpoenaPayment(string, string)` carries a `CA1031:DoNotCatchGeneralExceptionTypes` suppression because it deliberately catches any exception from the Google Maps call to drive its retry/fallback loop.
- Mileage cost is always `decimal.Round(miles * mileageRate, 2)`; total paid amount is `0` whenever calculated mileage units are `0`, on the assumption that no travel means no witness fee is owed.*

## Constraints and usage notes
- `GetCalculatedSubpoenaPayment(string, string)` throws via `Enforce.ArgumentNotNull` if `fromLocation` is `null`.
- `GetSubpoena` and other `IMessageContainer`-accepting methods throw via `Enforce.ArgumentNotNull` if `messageContainer` is `null`.
- `ListOfPolicyLocations` returns an empty list immediately (skipping the display-name formatting loop) when the query provider returns no locations.

> **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/Legal/Subpoenas/SubpoenaService.cs`
