Skip to content

BillEntryService

Drives the manual and auto-feed bill intake workflow: pulling the next scanned bill image/task off the imaging queue via IClaimBillEntryRepository and IImagingClient, building a new CbpBill record pre-filled with worker/claim data resolved through IClaimInformationService, IClaimQueryProvider, and ICCClaimApiService, and validating and persisting bill edits through IUnitOfWork/IValidationService. It also resolves provider location and rendering-provider lookups (via IProviderQueryProvider) for the bill entry UI, and applies conflict-of-interest filtering to the responsible-party inbox using ClaimUserSecurityAccess built from the current user's IUserProfileService profile.

Purpose

  • Retrieves the next queued bill image/claim-bill task for entry, skipping duplicate images already recorded against a bill and logging or warning when an image cannot be located depending on environment.
  • Creates, saves, and submits bills, applying optimistic-concurrency checks and re-deriving worker/claim/provider data on relevant field changes.
  • Advances a bill's status history with a new CbpBillStatus entry, stamped with the acting or default responsible party.
  • Filters a responsible party's bill inbox to exclude bills for workers flagged as a conflict of interest, unless the current user has conflict access.
  • Resolves billing/rendering provider locations and their active addresses for bill entry provider lookups.
  • Exposes bill type, bill status, and note category/type reference tables for bill entry forms.

Context

  • Namespace: SAIF.Services.Claims.Bills
  • Assembly/package: SAIF.Services (packaged inside the SAIF.SAIFCode.Core NuGet package)

Public members

Member Signature Purpose
BillEntryService (constructor) public BillEntryService(IUnitOfWork uow, IUserProfileService uprof, IValidationService val, IClaimBillEntryRepository repo, IImagingClient imagingClient, IBillService billService, IEnvironmentService environmentService, ILogService logService, INoteService noteService, IClaimInformationService claimInformationService, IProviderQueryProvider providerQueryProvider, IClaimQueryProvider claimQueryProvider, ICCClaimApiService ccclaimApiService) Wires all repository, imaging, claim, provider, note, logging, and environment dependencies used by the service, throws if uow is null, and pre-computes the current user ID for update stamping.
GetNewBill public Bill GetNewBill(IMessageContainer messageContainer) Creates and immediately saves a new blank standard-type bill, returning the persisted result.
GetNextClaimBillFromQueue public Bill GetNextClaimBillFromQueue(bool hasConflictAccess, IMessageContainer messageContainer) Pulls the next non-duplicate bill task from the imaging queue, retrieves its image, and builds a new bill record from it; returns an empty Bill with a warning when the queue is empty, retries automatically (in production) or returns a partially built record with a warning (outside production) when the associated image cannot be found.
GetClaimBillQueueRemainingCount public long GetClaimBillQueueRemainingCount() Returns the count of active, non-deleted auto-feed queue tasks assigned to the {CBPAPP} task user.
GetBill public Bill GetBill(long billId, IMessageContainer messageContainer) Retrieves a bill by ID and, if it has an associated image, resolves and attaches its image URL; adds an error if the bill does not exist or a warning if it has no linked image.
GetBillNotes public IList<Note> GetBillNotes(long id, IMessageContainer messageContainer) Returns the bill's notes excluding provider-contact-type notes; adds an error and returns an empty list if the bill does not exist.
GetNoteCategories public IEnumerable<NoteCategoryCode> GetNoteCategories() Returns the audit note category code reference list sourced from INoteService.
GetNoteTypes public IEnumerable<NoteTypeCode> GetNoteTypes() Returns the audit note type code reference list sourced from INoteService.
SaveBill public Bill SaveBill(Bill bill, IMessageContainer messageContainer, bool saveOnSubmit = false) Validates and persists a bill, creating a new CbpBill if it does not yet exist or updating the existing record; rejects the save with a concurrency error if the persisted UpdateNumber no longer matches the caller's, and applies submit-time date normalization when saveOnSubmit is true.
SubmitBill public Bill SubmitBill(Bill bill, IMessageContainer messageContainer) Validates submission-specific business rules (claim number present, billing provider present unless bill type "W", at least one service line, received date within the last 9 years and not in the future) before delegating to SaveBill with saveOnSubmit: true; returns an empty Bill if any rule fails.
UpdateBillStatus public Bill UpdateBillStatus(long billId, string recipientId, string billStatusCode) Appends a new status history entry to the bill for the given status code and responsible party (defaulting to the current user), commits it, and returns the refreshed bill; throws InvalidDataException if the status code is not recognized.
GetBillTypeCodes public IList<CbpBillTypeCode> GetBillTypeCodes() Returns all bill type codes ordered by description.
GetBillStatusCodes public IList<CbpBillStatusCode> GetBillStatusCodes() Returns all bill status codes ordered by description.
GetInboxBillsByResponsiblePartyId public BillEntryInboxResult GetInboxBillsByResponsiblePartyId(string responsiblePartyId) Returns the bills currently assigned to the given responsible party, filtering out bills for workers flagged as a conflict of interest unless the current user has conflict access, and reports whether any results were security-filtered.
GetProviderLocations public IEnumerable<BillEntryProviderLocation> GetProviderLocations(string tin) Resolves the provider matching the given tax ID and returns its locations that have an active physical address, including formatted physical/payment addresses and primary service description; throws NoMatchingDataException if the tin is empty or no matching provider is found.
GetRenderingProviders public IEnumerable<BillEntryProviderLocation> GetRenderingProviders(long providerLocationId) Returns the given provider location plus its non-business working-provider relationships as of today, each with formatted address, primary service, and expiration status; throws NoMatchingDataException if the location does not exist.

Behavioral notes

  • A static constructor registers AutoMapper mappings once per app domain via BillMappingHelper.MapBillService(), BillMappingHelper.MapForSearchQuery(), and ProviderMappingHelper.MapCodeTables()/MapTables().
  • GetNextClaimBillFromQueue recurses on itself when an image lookup fails in production, after logging the exception via ILogService, effectively retrying the next queue item automatically.*
  • Mutating operations (SaveBill, UpdateBillStatus, and the private bill-build helper) wrap changes in unitOfWork.Begin()/unitOfWork.Commit(); SaveBill calls unitOfWork.Dispose() instead of committing on a concurrency conflict.
  • SaveBill compares the incoming and persisted bill via CollectionComparer<Bill>.GetChanges to decide whether to re-derive bill type/provider/date-dependent fields, and a TODO comment in source notes this change-detection is currently always reporting changes due to lossy DB↔UI↔DB mapping.*
  • Changing a bill's BillTypeCode clears type-specific service fields (diagnosis pointer codes for non-standard bills, secondary service/provider codes for non-outpatient bills) and resets each service's location code based on the new bill type.
  • ClaimUserSecurityAccess, built from the current user's profile, governs whether conflict-of-interest bills are visible in GetInboxBillsByResponsiblePartyId.*

Constraints and usage notes

  • SaveBill requires both bill and messageContainer to be non-null and throws via Enforce.ArgumentNotNull otherwise.
  • SubmitBill enforces a hard 9-year lower bound and a not-in-the-future upper bound on the mail room received date, in addition to requiring at least one bill service line and (for non-"W" bill types) a billing provider.
  • GetProviderLocations and GetRenderingProviders only report an address as "active" when its ExpirationDate is null or in the future.

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/Claims/Bills/BillEntryService.cs