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

# RctServicePlanService

Implements `IRctServicePlanService`, batch-processing a CSV-derived list of policy service-plan changes (module `RCT0011`): validating each policy number and service-plan code, expiring the policy's currently active service plan when the code changes, and inserting the new plan (or leaving it removed) while accumulating counts and messages describing what happened. It depends on `IUnitOfWork` for repository access and transactions and `IUserProfileService` (currently unused in favor of a hard-coded module-name stamp).

## Purpose
- Validates each incoming service-plan change against known policies and service-plan codes, recording per-row error messages for invalid entries.
- Expires a policy's active service plan when its code differs from the incoming change, then inserts the new plan unless the change indicates removal.
- Rolls back the entire batch transaction immediately if an individual service-plan change fails to process.
- Returns aggregate counts (processed, expired, inserted, ignored, errors) and associated messages for the batch run.

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

## Public members
| Member | Signature | Purpose |
| --- | --- | --- |
| RctServicePlanService(...) | `public RctServicePlanService(IUnitOfWork unitOfWork, IUserProfileService userProfileService)` | Validates both collaborators are non-null via `Enforce.ArgumentNotNull` and wires them in. |
| ProcessAllServicePlans | `public StringDictionary ProcessAllServicePlans(ReadOnlyCollection<RctCsvFile> rctServicePlanChangeList)` | Within a transaction, validates and applies each service-plan change in the supplied list (expiring/inserting/ignoring as appropriate), rolling back and returning immediately if any single change fails to process, and otherwise committing and returning a `StringDictionary` of processed/expired/inserted/ignored/error counts and messages. |

## Behavioral notes
- Service-plan removal is signaled by the literal code `"na"` (case-insensitive), which causes the active plan to be expired without a replacement being inserted.
- A policy number not found among valid policies, or a service-plan code not found among valid service-plan codes (and not the removal code), is recorded as an error and the row is skipped rather than throwing.
- `ExpireServicePlan` and `InsertServicePlan` stamp `CreateUser`/`UpdateUser` with the constant `"RCT0011"` module name instead of the injected `IUserProfileService`'s current user, and swallow any exception by returning `false` rather than propagating it*.
- The entire batch is wrapped in `_unitOfWork.Begin()`/`Commit()`, but a single failed row triggers an immediate `_unitOfWork.Rollback()` and early return, discarding all changes made earlier in the same batch.

> **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/Rct/RctServicePlanService.cs
