---
title: Audit service and adjustment retrieval
summary: Retrieves the audited service lines for a medical bill and, per service, the audit adjustments applied to it, resolving each adjustment's descriptive code through the adjustment code lookup.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-07-30
library: SAIF.Business.Claim.MedicalBill
reference_type: package
operation_id: OP-MB-03
trigger: Reading clsMedicalBill.AuditServices (lazy), then reading clsAuditService.ServiceAdjustments (lazy) per returned service
---

# Audit service and adjustment retrieval

This operation covers the parent-child pair of `clsAuditServiceCollection`/`clsAuditService` and `clsServiceAdjustmentCollection`/`clsServiceAdjustment`, both retrieved through the same `PK82396_MEDICAL_BILLS` package. Audit services are the individual billed service lines that were audited for a bill; each audited service line can carry zero or more adjustments explaining how its allowed amount was derived. Because a service's adjustments cannot be understood without the audited-service context that produced them, and because both are read-only stored-procedure retrievals scoped to the same bill, they are documented together.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-MB-03 |
| **Trigger** | `clsMedicalBill.AuditServices` (lazy read, unless `SuppressAuditDetail` is set); `clsAuditService.ServiceAdjustments` (lazy read per service) |
| **Inputs** | `BillID` (audit services); `AuditSeqNum` and `BillID` (service adjustments) |
| **Outputs** | Populated `clsAuditServiceCollection` of `clsAuditService` items, each with charge/allowed/MCO-admin-fee amounts and an `IsIMEService` flag; populated `clsServiceAdjustmentCollection` of `clsServiceAdjustment` items per service, each resolving its adjustment code description |
| **Primary components** | `clsAuditServiceCollection.GetAuditServices`, `clsAuditServiceCollection.BeforeRetrieve`, `clsAuditService.ServiceAdjustments`, `clsAuditService.IsIMEService`, `clsServiceAdjustmentCollection.GetServiceAdjustments`, `clsServiceAdjustmentCollection.BeforeRetrieve`, `clsServiceAdjustment.AdjustmentCodeObject` |
| **Entry point** | `Business\SAIF.Business.Claim.MedicalBill\clsAuditServiceCollection.vb`, `Business\SAIF.Business.Claim.MedicalBill\clsServiceAdjustmentCollection.vb` |

## Steps

1. **Lazy trigger from the parent bill.** Reading `clsMedicalBill.AuditServices` retrieves the collection only on first access and only when `SuppressAuditDetail` is false ([BR-MB-020](../business-rules.md#br-mb-020-audit-and-eob-detail-retrieval-is-suppressed-for-bulk-print-views)); the result is cached on the bill instance for subsequent reads.
2. **Retrieve audited services.** `clsAuditServiceCollection.GetAuditServices(dpi, billID)` calls `PK82396_MEDICAL_BILLS.GetAuditServices` ([SQL-006](../sql/SQL-006.md), [CBP_AUDITED_SERVICE](../database-tables.md#cbp_audited_service), [CBP_SERVICE_DESCRIPTION](../database-tables.md#cbp_service_description), [CBP_NATIONAL_DRUG](../database-tables.md#cbp_national_drug)) and loads one `clsAuditService` per returned row via `Fill`/`Load`.
   - Service description resolution prefers the bill-specific service description text and falls back to the national-drug generic name for drug-coded services, both joined with effective-date filtering ([BR-PROC-002](../business-rules.md#br-proc-002-service-descriptions-prefer-bill-service-description-text-and-fall-back-to-generic-drug-na)).
3. **Derive the IME flag.** `clsAuditService.IsIMEService` returns true when the resolved `ServiceDescription` starts with `"IME"`; this is a computed convenience property, not separately persisted.
4. **Lazy trigger for adjustments.** Reading `clsAuditService.ServiceAdjustments` retrieves the child collection only on first access, using the service's own `AuditSeqNum` and `BillID`.
5. **Retrieve service adjustments.** `clsServiceAdjustmentCollection.GetServiceAdjustments(dpi, auditSeqNum, billID)` calls `PK82396_MEDICAL_BILLS.GetServiceAdjustments` ([SQL-013](../sql/SQL-013.md), [CBP_AUDITED_SERVICE_ADJUSTMENT](../database-tables.md#cbp_audited_service_adjustment)) and loads one `clsServiceAdjustment` per returned row.
   - Adjustments are returned in a fixed sort order — code `FT` first, code `PA` last, all other codes in between — enforced by a `CASE` expression in the procedure query ([BR-PROC-001](../business-rules.md#br-proc-001-service-adjustments-are-sorted-so-code-ft-appears-first-pa-appears-last-and-all-othe)).
6. **Resolve the adjustment's descriptive code (lazy).** Reading `clsServiceAdjustment.AdjustmentCodeObject` lazily resolves the adjustment's code description by delegating to the [Adjustment code lookup](adjustment-code-lookup.md) operation, using the raw `AdjustmentCode` value stored on the adjustment row; `AdjustmentCode` itself is a pass-through of `AdjustmentCodeObject.Code`.
7. **Aggregate totals on the parent bill.** `clsMedicalBill.TotalAdjustmentAmt` sums `AdjustmentAmount` across every service and every adjustment (when `SuppressAuditDetail` is false), and `clsAuditService.PaidAmt` computes `AllowedAmt - McoAdminFee` per service line.

## Process flow

The following diagram visualizes this operation's control flow.

```mermaid
flowchart TD
	Start([Bill.AuditServices read]) --> Suppress{SuppressAuditDetail?}
	Suppress -->|Yes| Skip([Returns Nothing;<br>no retrieval issued])
	Suppress -->|No| Retrieve[GetAuditServices via<br>PK82396_MEDICAL_BILLS]
	Retrieve --> Services[Populate clsAuditService items<br>with resolved descriptions]
	Services --> IME[Compute IsIMEService per item]
	IME --> AdjTrigger{ServiceAdjustments read?}
	AdjTrigger -->|Yes| AdjRetrieve[GetServiceAdjustments via<br>PK82396_MEDICAL_BILLS, sorted FT/others/PA]
	AdjTrigger -->|No| Done
	AdjRetrieve --> CodeLookup[Resolve AdjustmentCodeObject<br>per adjustment]
	CodeLookup --> Done([Aggregate totals available<br>on parent bill])
```

## Failure and edge-case behavior

- Both collections are read-only stored-procedure retrievals; there is no persist/save path on either object.
- `AuditServices` and `ServiceAdjustments` are each cached after first load, so subsequent reads within the same object lifetime do not re-issue the retrieval even if underlying data changes.
- Bulk-print suppression (`SuppressAuditDetail`) silently skips this entire operation for affected bills rather than raising an error, which can make aggregate totals across a suppressed collection understate actual adjustments.

## Related documentation

- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)
- [SQL catalog](../sql/index.md)
- [Database tables](../database-tables.md)

## Sources

- `Business\SAIF.Business.Claim.MedicalBill\clsAuditServiceCollection.vb`
- `Business\SAIF.Business.Claim.MedicalBill\clsAuditService.vb`
- `Business\SAIF.Business.Claim.MedicalBill\clsServiceAdjustmentCollection.vb`
- `Business\SAIF.Business.Claim.MedicalBill\clsServiceAdjustment.vb`
