Audit bill comparison¶
clsAuditCompare.CompareBills is a standalone diagnostic utility, independent of the BillAuditEngine.AuditBill pipeline, that compares two clsBillAudit snapshots — typically a pre- and post-audit copy of the same bill — across header fields, status, audit totals, messages, adjustments, and audited-service lines, and reports every mismatch as a comparison error.
| Field | Value |
|---|---|
| Operation ID | OP-AA-06 |
| Trigger | Caller invokes clsAuditCompare.CompareBills(inAudit1, inAudit2, Optional ForceCompare As Boolean = False) |
| Inputs | Two clsBillAudit instances; optional ForceCompare flag to bypass the matching-BillID precondition |
| Outputs | Boolean match result (True when no compare errors were added); collection of comparison error messages describing each mismatched field |
| Primary components | clsAuditCompare.CompareBills, clsAuditCompare.CompareField |
| Entry point | Business\SAIF.Business.Claim.Bill.AutomatedAudit\AuditUtilities\clsAuditCompare.vb |
Steps¶
- Store inputs.
CompareBillsstores the two suppliedclsBillAuditobjects. - Check matching bill identity. Unless
ForceCompare = True, the two bills must share the sameBillID; otherwise add error"Bills do not have matching ID's - Compare Cancelled."and the comparison for identity stops here (other sections below still run against the given inputs). - Compare bill header properties. Compare
BillTotalAmount,StatementFromDate,StatementThruDate,ClaimID,DRGCode,ClaimNumber, andClaimCheckValueusingCompareField(see step 8 for field-specific comparison rules). - Compare latest status records. Select each bill's latest status row by
UpdateDatedescending and compareStatusCodeandResponsiblePartyID. If either bill has no status record, add error"Could not determine matching Status Records". - Compare audit-level properties. Compare
AuditReceiptDate,ChargeableCostFlag,PrintEobFlag,SpecialHandlingCode,TotalAllowedAmount,TotalChargedAmount, andTotalMcoAdminFeeAmount. - Compare audit messages. If the message counts differ, add a non-match result with message
"Comparison of Message Text and Category cancelled."Otherwise, sort both message collections by category/text and compareMessageTextandMessageCategorypairwise. - Compare adjustments. If the adjustment counts differ, add a non-match result with message
"Comparison of property elements cancelled."Otherwise, sort both adjustment collections byAuditServiceIDand code and compareAuditAdjustmentAmount,AuditAdjustmentCode, andAuditServiceIDpairwise. - Compare audited services. If the service counts differ, add a non-match result with message
"Property comparison has been cancelled for this service."Otherwise, compare a broad set of audited-service fields by matchingServiceID.CompareFieldapplies type-specific rules: MessageText— compares letters case-insensitively, then digits (excluding zeroes), then punctuation, with distinct mismatch messages:"Values do not have the same letters.","Values do not have the same digits.","Values do not have the same punctuation marks."- String fields such as
DRGCode,McoEligibilityStatusCode, service modifiers, andServiceCode— trimmed string comparison. - Decimal
*Amountfields — numeric comparison, displayed as currency in the mismatch message. DateTimefields — exact comparison.- All other fields — case-insensitive string comparison.
- On any exception while comparing a field, add error
"<Class>/<Key>-<Prop>: Could not be compared - <exception>"rather than allowing the exception to propagate. - Return overall result.
CompareBillsreturnsTrueonly if no comparison errors were added across steps 2–8.
Process flow¶
flowchart TD
Start([CompareBills invoked]) --> IDCheck{ForceCompare or<br>BillID matches?}
IDCheck -->|No| IDError[Add error:<br>IDs do not match]
IDCheck -->|Yes| Header[Compare bill header fields]
IDError --> Header
Header --> Status[Compare latest status records]
Status --> Audit[Compare audit-level totals/flags]
Audit --> Messages{Message counts match?}
Messages -->|No| MsgCancelled[Add: comparison cancelled]
Messages -->|Yes| MsgCompare[Compare sorted message pairs]
MsgCancelled --> Adjustments
MsgCompare --> Adjustments{Adjustment counts match?}
Adjustments -->|No| AdjCancelled[Add: comparison cancelled]
Adjustments -->|Yes| AdjCompare[Compare sorted adjustment pairs]
AdjCancelled --> Services
AdjCompare --> Services{Service counts match?}
Services -->|No| SvcCancelled[Add: comparison cancelled]
Services -->|Yes| SvcCompare[Compare matched service fields<br>via CompareField]
SvcCancelled --> Done
SvcCompare --> Done([Return True if no errors added])
Failure and edge-case behavior¶
- A count mismatch in messages, adjustments, or services cancels field-by-field comparison for that section entirely and reports a single cancellation message rather than identifying which specific rows differ.
ForceCompare = Trueallows comparing two bills with differentBillIDvalues; all subsequent sections still run against whatever data each bill contains, which can produce a large number of unrelated mismatches.- Exceptions during an individual field compare are caught and reported as comparison errors rather than aborting the whole comparison, so a single malformed field does not prevent the rest of the comparison from completing.
- This operation is not invoked anywhere in the
BillAuditEngine.AuditBillpipeline traced in Automated bill audit orchestration; it is a standalone tool for callers who need to verify audit results independently.* - Source contains a commented-out Oracle-vs-DB2
DispenseAsWrittenCodenormalization branch that is excluded from this operation's behavior as dead code.
Related documentation¶
Note: Statements marked with
*were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts.
Sources¶
Business\SAIF.Business.Claim.Bill.AutomatedAudit\AuditUtilities\clsAuditCompare.vb