SubpoenaSaveService¶
Owns the create/update/approve/disapprove/delete lifecycle for a subpoena and its recipients, translating between the contract Subpoena model and the SAIF.Data.Model.Legal.Subpoenas.Subpoena entity graph. It checks the requesting employee's initiate/approve authority limits via IBillServiceHelper.UserAuthorityLevel before auto-approving a subpoena, computes issue dates via IBillServiceHelper.GetNextIssueDate/IWorkCalendarService.NextWorkDay, and validates the incoming model with IValidationService before any persistence occurs.
Purpose¶
- Approves a subpoena automatically when the requesting employee's initiate or approve authority limit covers the highest recipient paid amount, then saves it.
- Reverts a subpoena to in-progress status and saves it (disapproval).
- Deletes a subpoena outright when found.
- Validates and persists a subpoena (new or existing), including optimistic-concurrency checking via
UpdateNumber, opposing-counsel address validation, recipient synchronization (add/update/remove, including witness legal-person and address upsert), and issue-date computation — all inside a single transaction.
Context¶
- Namespace:
SAIF.Services.Legal.Subpoenas - Assembly/package:
SAIF.Services(packaged inside theSAIF.SAIFCode.CoreNuGet package).
Public members¶
| Member | Signature | Purpose |
|---|---|---|
| SubpoenaSaveService (constructor) | public SubpoenaSaveService(IUnitOfWork unitOfWork, IUserProfileService userProfileService, IValidationService validationService, IBillServiceHelper billServiceHelper, IWorkCalendarService workCalendarService) |
Wires the unit of work, current-user profile (captured as an uppercased static _currentUser), the validation service, the authority-limit/issue-date helper, and the work-calendar service; null-checks all five collaborators. |
| ApproveSubpoena | public long ApproveSubpoena(Subpoena subpoena, IMessageContainer messageContainer) |
Defaults the subpoena to in-progress status if unset, then — if the current employee's initiate or approve authority limit is at least the highest recipient PaidAmount — marks it approved, sets ApprovedByEmployeeId/ApprovedDate to the current employee/today, and delegates to SaveSubpoena to validate and persist; otherwise saves it unapproved. Returns the persisted subpoena's ID, or 0 on validation failure. |
| DisapproveSubpoena | public bool DisapproveSubpoena(Subpoena subpoena, IMessageContainer messageContainer) |
Sets the subpoena's status to in-progress and saves it via SaveSubpoena, returning true only if the save produced a nonzero ID. |
| DeleteSubpoena | public bool DeleteSubpoena(long subpoenaId, IMessageContainer messageContainer) |
Looks up the subpoena by ID and, if found, deletes it inside a transaction and returns true; returns false if no matching subpoena exists. |
| SaveSubpoena | public long SaveSubpoena(Subpoena subpoena, IMessageContainer messageContainer) |
Defaults status (in-progress) and type (medical records) when unset, validates the subpoena (unless already paid) via ValidateSubpoena/IValidationService — returning 0 and adding errors to messageContainer on failure — then within a transaction: rejects with an optimistic-concurrency error if UpdateNumber is stale, rejects if the linked legal case's opposing-counsel firm has no address, copies all subpoena fields onto the data entity (computing issue date via IBillServiceHelper/IWorkCalendarService for approvals and witness types), synchronizes recipients (add/update/remove, including legal-person and address upsert for witness recipients), adds the entity if new, commits, and returns its ID. |
Behavioral notes¶
ApproveSubpoena's auto-approval decision compares the recipient's maximumPaidAmountagainst the current employee's initiate and approve authority limits (IBillServiceHelper.UserAuthorityLevel); if neither limit covers it, the subpoena is saved without approval.SaveSubpoenaskips its ownValidateSubpoenacall entirely when the subpoena's current status isPaidCode, allowing paid subpoenas to be re-saved (e.g., recipient corrections) without full re-validation.*- Recipient synchronization (
SaveRecipients) removes data recipients no longer present in the incoming model, then for each incoming recipient short-circuits (continue) unless it is new orHasRecipientChangeddetects a material difference, avoiding unnecessary update-user/date stamping. - Witness recipients'
LegalPerson/LegalPersonAddressrecords are created viaCreateNewLegalPersonfor brand-new recipients or people, and updated in place viaUpdateLegalPersonotherwise; provider-type recipients instead resolveProviderLocation/RegisteredAgentLocationby ID. - Issue date defaults to
IBillServiceHelper.GetNextIssueDate("LS")for every new/updated subpoena, but is recomputed (and pushed forward two work days viaIWorkCalendarService.NextWorkDayfor witness-type subpoenas) whenever the status transitions to approved. _currentUseris astaticfield assigned from the constructor's injectedIUserProfileService, so it reflects whichever instance was constructed most recently within the process rather than being strictly per-instance state.*
Constraints and usage notes¶
ApproveSubpoena,DisapproveSubpoena,DeleteSubpoena, andSaveSubpoenaall throw viaEnforce.ArgumentNotNullifmessageContainerisnull;ApproveSubpoenaandSaveSubpoenaadditionally throw ifsubpoenaisnull.DisapproveSubpoenacarries aCA1062suppression acknowledging it does not null-checksubpoenaitself.SpecialDeliveryTextis truncated to at most 1000 characters before being stored.SaveSubpoenarolls back (without committing) and returns0both on staleUpdateNumberand on a missing opposing-counsel address, leaving the caller to surface the addedmessageContainererrors.
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/SubpoenaSaveService.cs