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

# CalculateInterestService

Implements `ICalculateInterestService`, running the batch interest-calculation process for Collections cases: it retrieves eligible case interest records via `ICollectionsRepository`, applies the calculated interest to each case's outstanding balance through `IUnitOfWork`, records an `"INT"` interest transaction per case, and emails a generated PDF report using `IDocumentService`. It also depends on `IUserProfileService` to attribute updates to the running user.

## Purpose
- Retrieves cases eligible for interest charges for a given run date via `ICollectionsRepository.GetInterest`.
- Optionally (unless in report-only mode) posts an interest transaction and updates each case's current balance within a single unit-of-work transaction.
- Builds and emails a PDF "Interest Calculation Report" summarizing the interest charged per case.

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

## Public members
| Member | Signature | Purpose |
| --- | --- | --- |
| CalculateInterestService(...) | `public CalculateInterestService(IUserProfileService profile, IUnitOfWork unitOfWork, ICollectionsRepository collectionsRepo, IDocumentService documentService)` | Wires in the profile, unit-of-work, collections repository, and document-service collaborators, enforcing that the repository, unit of work, and document service are non-null. |
| CalculateInterest | `public bool CalculateInterest(DateTime runDate, string caseId, bool reportOnlyMode, ILogWriter controlLog, ILogWriter interestReport, string emailList)` | Loads interest-eligible cases for `runDate`/`caseId`, emails a PDF interest report to `emailList`, and — unless `reportOnlyMode` is true — increases each case's current balance by the calculated interest and posts a corresponding `"INT"` transaction inside one committed unit-of-work transaction; always returns `true`. |

## Behavioral notes
- Wraps the balance updates and transaction inserts in a single `_unitOfWork.Begin()`/`Commit()` pair when `reportOnlyMode` is false, so either all cases in the run are updated or (on failure) none are committed*.
- Always generates and emails the interest report via `_documentService.GenerateDocument`/`EmailService.SendEmail`, even in report-only mode, so the report reflects calculated interest whether or not it was posted.
- Sends the report to every address in `emailList` (comma-separated) with the fixed `@saif.com` domain appended, and hardcodes the sender address `Helpdesk@saif.com`.
- Each posted interest transaction uses a fixed `"INT"`/`"Interest Charge"` transaction code, is marked `IsSystemGenerated = true`, and is attributed to the currently logged-in user via `_profileService.GetCurrentUser().UserId`.

> **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/Collections/CalculateInterestService.cs
