CollectionsService¶
Implements ICollectionsService (extending ValidatingServiceBase), the primary orchestration service for the Legal Collections module: it manages case/request creation and lookup, debtors and their addresses, notes, activities, transactions, collection tasks, and case search, and generates the PDF summary/notes/tasks reports used by the collections UI. It depends on IValidationService for FluentValidation-based edits, IUnitOfWork for all persistence and transactions, ICollectionsRepository for collections-specific queries, IDocumentService for PDF/email generation, IUserProfileService for the current user, IWorkCalendarService to compute note edit windows, IWorkerDataApiClient to resolve worker names/SSNs from Guidewire, and ICCClaimApiService to resolve claim/worker details for claim-based cases. Its static constructor calls AutoMapperBootStrapper.Configure() once to register the AutoMapper maps used throughout the class.
Purpose¶
- Retrieves and summarizes collections cases (by ID or reference number), including PDF case-summary generation with activity, category-total, and transaction detail.
- Creates, updates, and deletes debtors and their associated mailing/physical locations, resolving addresses differently for policy, claim, third-party, and fraud/other case types.
- Manages case notes (create/save/delete/PDF export), enforcing an editable window computed via
IWorkCalendarService. - Validates and saves collections "requests" (new/edited cases), generating the appropriate debtor set for the case's collection code and mapping associated activities.
- Manages collection tasks (create/save/delete/list/PDF export) tied to a case's policy or claim.
- Manages transactions (create/save/delete), recomputing case balances and enforcing approval requirements based on transaction code.
- Performs cross-system worker/claim/policy searches by populating a temp table from the worker data API and delegating to
ICollectionsRepository.SearchCollections.
Context¶
- Namespace:
SAIF.Services.Collections - Assembly/package:
SAIF.Services(packaged inside theSAIF.SAIFCode.CoreNuGet package)
Public members¶
| Member | Signature | Purpose |
|---|---|---|
| UnitOfWork | protected readonly IUnitOfWork UnitOfWork |
Repository/transaction gateway used for essentially all persistence in this service. |
| ValidationService | protected readonly IValidationService ValidationService |
Runs FluentValidation rules against domain models before they are persisted, collecting errors into an IMessageContainer. |
| CollectionsRepo | protected readonly ICollectionsRepository CollectionsRepo |
Supplies collections-specific queries (category totals, addresses, name/SSN lookups, search, payment application). |
| DocumentService | protected readonly IDocumentService DocumentService |
Generates PDF case-summary, notes, and tasks reports. |
| UserProfileService | protected readonly IUserProfileService UserProfileService |
Resolves the current user for create/update attribution and authorization checks. |
| WorkCalendarService | protected readonly IWorkCalendarService WorkCalendarService |
Computes the next work day used to determine whether a note is still within its editable window. |
| CollectionsService(...) | public CollectionsService(IValidationService validationService, IUnitOfWork unitOfWork, ICollectionsRepository collectionsRepo, IDocumentService documentService, IUserProfileService userProfileService, IWorkCalendarService workCalendarService, IWorkerDataApiClient workerDataApiClient, ICCClaimApiService ccClaimApiService) |
Wires in all collaborators (enforcing non-null validation service and unit of work) needed to service case, debtor, note, request, task, transaction, and search operations. |
| GetActivities | public IEnumerable<Activity> GetActivities(long caseId) |
Returns all activity records recorded against a case. |
| GetActivityCodes | public IEnumerable<ActivityCode> GetActivityCodes() |
Returns the activity type reference list ordered by description, with a leading blank "--Select--" placeholder entry. |
| GetCaseById | public Case GetCaseById(long caseId) |
Returns the mapped case with its derived CaseType, or null if the case does not exist. |
| GetCaseSummaryById | public Case GetCaseSummaryById(long caseId) |
Returns the case populated with category totals, market type (for policy cases), county, and derived case type, for summary display. |
| GetCasesByReference | public IEnumerable<CaseHeader> GetCasesByReference(string referenceId) |
Returns case headers matching a (possibly check-digit-trimmed) reference number, resolving the debtor/worker display name — including a live Guidewire claim lookup for claim-related collection codes — and derived case type for each. |
| GetSummaryPdf | public byte[] GetSummaryPdf(long caseId) |
Builds the case-summary XML (header, activities, category totals, transactions) and returns the rendered "Corporate_Collections_Summary" PDF, or null if the case reference cannot be found. |
| GetDebtor | public Debtor GetDebtor(long id) |
Returns a single debtor mapped to its domain contract with contact info, name, and SSN populated, or an empty Debtor if not found. |
| GetDebtors | public ICollection<Debtor> GetDebtors(long caseId) |
Returns all debtors for a case with contact info populated, masking the SSN to the last four digits for users who are not authorized "update" users. |
| GetPolicyFormattedAddresses | public ICollection<DebtorAddress> GetPolicyFormattedAddresses(long policyNum) |
Returns every active location for a policy with a fully formatted address string. |
| GetDebtorName | public string GetDebtorName(long id) |
Returns the debtor's display name, falling back to a Guidewire worker lookup (last, first, middle) when no name is stored for a worker-linked debtor. |
| GetPrimaryDebtorName | public string GetPrimaryDebtorName(long id) |
Returns the case's primary debtor's display name, with the same Guidewire worker fallback as GetDebtorName. |
| GetDebtorSsn | public string GetDebtorSsn(long id) |
Returns the debtor's SSN, falling back to the Guidewire worker's tax ID when no SSN is stored for a worker-linked debtor. |
| GetPolicyLocations | public ICollection<Location> GetPolicyLocations(long policyNum) |
Returns all non-expired locations for a policy, ordered by address line 1. |
| GetPolicyMailingLocation | public Location GetPolicyMailingLocation(long policyNum) |
Returns the policy's non-expired location flagged with location code "POL" (the mailing address). |
| CreateDebtor | public Debtor CreateDebtor(long caseId, DebtorEdit debtorEdit, IMessageContainer messageContainer) |
Validates the new debtor, and if valid, creates a new manually entered address location plus a Debtor record in one transaction, refreshing the last-statement balance in a second transaction unless the debtor's statement is held. |
| DeleteDebtor | public bool DeleteDebtor(long id, IMessageContainer messageContainer) |
Deletes the debtor (and its dedicated location, if any) inside one transaction; returns false if the debtor does not exist. |
| SaveDebtor | public bool SaveDebtor(long id, long caseId, DebtorEdit debtorEdit, IMessageContainer messageContainer) |
Validates the edited debtor, and if valid, updates (or creates) the associated location and debtor record — refreshing the last-statement balance when the statement hold is being released — inside one transaction. |
| UpdateDebtors | public bool UpdateDebtors(long caseId, IEnumerable<DebtorEdit> debtorEditList, IMessageContainer messageContainer) |
Validates and updates the SSN, SOIL inclusion, statement-hold flag, and mailing address (nulled out when it matches the policy's default mailing location) for each debtor in the list, in one transaction; stops and returns false at the first invalid debtor. |
| GetNotes | public IEnumerable<Note> GetNotes(long caseId, NoteFilter filter) |
Returns notes for a case within the given date filter, newest first, each flagged CanEdit based on whether today is still within the work-calendar editable window. |
| GetNote | public Note GetNote(long noteId) |
Returns a single note with its CanEdit flag computed from the work-calendar editable window. |
| SaveNote | public bool SaveNote(long noteId, NoteEdit noteEdit, string appendText, IMessageContainer messageContainer) |
Validates the edited note, and if valid, updates its text (appending a timestamped "*ADDED ... by ..." annotation when append text is supplied) and commits the change. |
| CreateNote | public Note CreateNote(long caseId, NoteEdit noteEdit, IMessageContainer messageContainer) |
Validates and, if valid, creates a new note attributed to the current user and returns the persisted note (with CanEdit recomputed). |
| DeleteNote | public bool DeleteNote(long noteId, IMessageContainer messageContainer) |
Deletes the specified note inside one transaction; always returns true. |
| GetNotePdf | public byte[] GetNotePdf(long caseId, NoteFilter filter) |
Builds the filtered notes XML (with a date-range summary) and returns the rendered "Corporate_Collections_Notes" PDF. |
| GetRequestById | public Request GetRequestById(long caseId) |
Returns the case mapped to a Request contract, with market type (for policy cases) and county resolved, for edit/display purposes. |
| CreateRequest | public Request CreateRequest() |
Returns a new, empty Request mapped from a blank case, for use when initiating a new collections case. |
| ValidateContext | public bool ValidateContext(string caseType, string caseContext, out string contextName) |
For policy-type case codes, resolves and returns the policy name for a policy number; otherwise resolves and returns the worker's formatted name via ICCClaimApiService; returns false with an explanatory contextName message if the policy/claim cannot be found. |
| GetCollectionCodes | public IEnumerable<CollectionCode> GetCollectionCodes() |
Returns the collection-type reference list ordered by description. |
| GetJudgmentCodes | public IEnumerable<JudgmentCode> GetJudgmentCodes() |
Returns the judgment-type reference list ordered by description. |
| GetJudgmentYears | public IEnumerable<JudgmentYearsValue> GetJudgmentYears() |
Returns the allowed judgment-duration values ordered by number of years. |
| GetInterestCalcCodes | public IEnumerable<InterestCalcCode> GetInterestCalcCodes() |
Returns the interest-calculation-method reference list ordered by description. |
| GetInterestRates | public IEnumerable<InterestRateValue> GetInterestRates() |
Returns the allowed annual interest rates ordered by rate. |
| GetCountyCodes | public IEnumerable<County> GetCountyCodes() |
Returns Oregon county reference codes ordered by name, plus a synthetic "C7" / "Out of state" entry for Washington. |
| GetStatusCodes | public IEnumerable<StatusCode> GetStatusCodes() |
Returns the case-status reference list ordered by description. |
| GetStateCodes | public IEnumerable<StateCode> GetStateCodes() |
Returns the US state reference list ordered by code. |
| GetCreditReps | public IEnumerable<CreditRepUser> GetCreditReps() |
Returns active (non-expired) credit representative users ordered by employee last name. |
| SaveRequest | public bool SaveRequest(long caseId, Request request, ICollection<Activity> activities, IMessageContainer messages) |
Validates the request and its activities; if valid, updates (or, for caseId == 0, creates and generates debtors for) the case's core fields, reconciles its activities, and commits inside one transaction; fails with a concurrency error if the stored UpdateNum no longer matches the submitted request. |
| CreateActivity | public Activity CreateActivity(long caseId) |
Returns a new, empty Activity contract pre-populated with the given case ID. |
| DeleteActivity | public bool DeleteActivity(long activityId) |
Deletes the specified activity inside one transaction; returns false if the activity does not exist. |
| GetSearchResults | public async Task<IEnumerable<SearchResult>> GetSearchResults(SearchCriteria criteria) |
For non-policy-name searches, first stages matching Guidewire claim/worker data into a temp table, then (after normalizing and wildcard-formatting the criteria) delegates to ICollectionsRepository.SearchCollections, returning up to 300 results with debtor names backfilled where missing. |
| CreateTask | public CollectionTask CreateTask(CollectionTaskEdit taskEdit, IMessageContainer messageContainer) |
Validates the task edit, resolves the owning policy or claim for the case, and — if valid both before and after enrichment — creates the task (attributed to "SYSTEM") inside one transaction, returning the persisted task with its debtor name populated. |
| DeleteTask | public bool DeleteTask(long id, IMessageContainer messageContainer) |
Soft-deletes (IsDeleted = true) the specified task and increments its update number inside one transaction; always returns true. |
| GetTask | public CollectionTask GetTask(long id) |
Returns the task mapped to its domain contract with the case's primary debtor name populated. |
| GetTasks | public IEnumerable<CollectionTask> GetTasks(CollectionTaskCriteria criteria) |
Returns up to 300 non-deleted Collections-source tasks matching the date range/case/reference-number filters, ordered by due date descending, each with its debtor name resolved. |
| GetTasksForPdf | public byte[] GetTasksForPdf(CollectionTaskCriteria criteria) |
Builds the filtered tasks XML (with a date-range and filter summary) and returns the rendered "Corporate_Collections_Tasks" PDF. |
| SaveTask | public bool SaveTask(long id, CollectionTaskEdit collectionTaskEdit, IMessageContainer messageContainer) |
Validates the edited task's date/text, and if valid, updates and commits the change inside one transaction. |
| ValidateCollectionTaskCriteria | public bool ValidateCollectionTaskCriteria(ref CollectionTaskCriteria criteria, IMessageContainer messageContainer) |
Defaults an unset through-date to DateTime.MaxValue, or adds a validation error and returns false when the from-date is after the through-date. |
| GetTransactions | public ICollection<Transaction> GetTransactions(long caseId) |
Returns all transactions for a case, each flagged with whether it CanEdit (based on statement date, prior payment application, category, and system-generated status) and whether approval IsApprovalRequired. |
| GetTransaction | public Transaction GetTransaction(long id) |
Returns a single transaction mapped to its domain contract. |
| DeleteTransaction | public bool DeleteTransaction(long id) |
Deletes the transaction and reverses its amount from the case's current balance inside one transaction; returns false if the transaction does not exist. |
| SaveTransaction | public bool SaveTransaction(long transactionId, TransactionEdit transEdit, IMessageContainer messages) |
Validates the edited transaction; if the stored update number no longer matches, rolls back and fails with a concurrency error; otherwise (when editable) adjusts the case balance by the amount delta and commits the change inside one transaction. |
| InsertTransaction | public long InsertTransaction(TransactionEdit transEdit, IMessageContainer messages) |
Validates and, if valid, inserts a new transaction, adjusts the case's current balance up or down based on the transaction code's pay-down order, commits, then reapplies payments via CollectionsRepo.ApplyPayments; returns -1 if validation fails, otherwise the new transaction ID. |
| CheckForRequiredApproval | public bool CheckForRequiredApproval(TransactionCode tranCode) |
Returns whether the given transaction code is flagged as requiring approval in the transaction-code reference list. |
| GetTransactionCategoryCodes | public IEnumerable<TransactionCategoryCode> GetTransactionCategoryCodes() |
Returns the full transaction-category reference list. |
| GetTransactionCodes | public ICollection<TransactionCode> GetTransactionCodes() |
Returns the transaction-type reference list ordered by description, each flagged IsInterestAllowed based on its category's pay-down order. |
| GetWriteOffApprovalUsers | public ICollection<WriteOffApprovalUser> GetWriteOffApprovalUsers() |
Returns active (non-expired) write-off approval users ordered by employee last name. |
| IsUpdateUser | public bool IsUpdateUser() |
Returns whether the current user holds the "LegalColUpdate" security permission. |
Behavioral notes¶
- Wraps nearly every write operation (debtor, note, request, task, and transaction create/save/delete) in a
UnitOfWork.Begin()/Commit()pair, and rolls back on optimistic-concurrency failures detected by comparing a submittedUpdateNumto the stored value (SaveRequest,SaveTransaction). - Validates domain models before persisting via the private
ValidateAndAddErrorshelper, which delegates toValidationService.Validate(backed by the Collections FluentValidation validators) and appends any failures to the caller'sIMessageContainer. - Resolves debtor contact information differently per case type (
GetDebtorContactInfo): fraud/other and policy cases queryCollectionsRepo, claim cases callICCClaimApiService.GetWorkerAddress, and third-party cases callCollectionsRepo.GetThirdPartyAddress. GetDebtorsmasks the stored SSN to"xxx-xx-####"for any user who is not an authorized update user (perIsUpdateUser), enforcing field-level data protection.CreateTask/GetTask/GetTasksresolve and cache a per-case debtor name lookup (DebtorNameItem) to avoid re-querying per task row when listing multiple tasks for the same case.
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/CollectionsService.cs