Legacy Pipeline Atlas worker-1snapshot 2026-07-15

MDClarity · task primitive

BatchProcessAccountData

Overview

BatchProcessAccountDataTask calculates estimates for patient accounts by iterating through all combinations of specified facilities, insurances, and bill types. It processes real patient account data with actual charges to generate or update account estimates in the AccountEstimate and AccountEstimateCharge tables.

Use this task when: You need to recalculate account estimates across multiple facilities, insurance types, or bill types simultaneously, such as after pricing configuration changes or contract updates.

Don't use this task when:


Parameters

Parameter Type Required Default Description
FacilityChoice FacilityChoice Yes new FacilityChoice() Specifies which facilities to process. Can use AllFacilities = true, IndividualFacilities list, or FacilityGroups list.
InsuranceSet List<string> No Empty list (all insurances) List of insurance keys to process. If empty, processes accounts for all insurances (represented as single null entry).
BillTypeSet List<string> No Empty list (all bill types) List of bill type keys to process. If empty, processes accounts for all bill types (represented as single null entry).
MinServiceDate DateTime? No null Minimum service date filter for accounts to process. Null means no lower bound.
MaxServiceDate DateTime? No null Maximum service date filter for accounts to process. Null means no upper bound.
ScenarioInsurance string No null Optional insurance key for scenario-based "what-if" calculations. When set, calculates estimates as if accounts used this insurance instead of their actual insurance.
Incremental bool No true When true, only processes accounts without existing estimates (faster). When false, reprocesses all matching accounts regardless of existing estimates.
UpdateDimensions bool No false When true, updates dimension tables during processing. Set to true when dimension data may have changed.

Execution Flow

flowchart TD
    A[Start BatchProcessAccountDataTask] --> B{InsuranceSet empty?}
    B -->|Yes| C[Add null to InsuranceSet<br/>all insurances]
    B -->|No| D{BillTypeSet empty?}
    C --> D

    D -->|Yes| E[Add null to BillTypeSet<br/>all bill types]
    D -->|No| F[Get facilities from FacilityChoice]
    E --> F

    F --> G[Initialize error counter]
    G --> H[Loop: For each facility]

    H --> I[Loop: For each insurance]
    I --> J[Loop: For each bill type]

    J --> K[Create ProcessAccountDataTask<br/>with current combination]
    K --> L[Build SQL query with filters:<br/>facility, insurance, bill type,<br/>date range, incremental]

    L --> M[Execute ProcessAccountData]
    M --> N[Process accounts in batches]

    N --> O{More bill types?}
    O -->|Yes| J
    O -->|No| P{More insurances?}

    P -->|Yes| I
    P -->|No| Q{More facilities?}

    Q -->|Yes| H
    Q -->|No| R{errorCount > 0?}

    R -->|Yes| S[Log aggregated error message]
    R -->|No| T[Complete successfully]
    S --> T

    style K fill:#e1f5ff
    style M fill:#e1f5ff
    style N fill:#fff4e1
    style S fill:#ffe1e1

Processing Algorithm

The task uses a triple-nested loop to process all combinations of facilities, insurances, and bill types:

Total Iterations = Facilities × Insurances × Bill Types

For each combination:
  1. Build SQL query to select matching accounts
  2. Apply incremental filter (skip accounts with existing estimates if Incremental = true)
  3. Process accounts in batches (batch size: determined by AccountProcessor)
  4. Calculate estimates for each account using pricing engine
  5. Save results to AccountEstimate and AccountEstimateCharge tables
  6. Aggregate errors across all iterations

Example Execution

Scenario: Process accounts for 3 facilities, 2 insurances, 2 bill types

Facilities: ["FAC001", "FAC002", "FAC003"]
Insurances: ["INS-MEDICARE", "INS-BCBS"]
BillTypes: ["131", "141"]

Total Iterations: 3 × 2 × 2 = 12 separate processing runs

Each iteration processes:
  - Accounts matching: specific facility + specific insurance + specific bill type
  - With service dates in range (if MinServiceDate/MaxServiceDate set)
  - Excluding accounts with estimates (if Incremental = true)

Usage Examples

Example 1: Reprocess all accounts for specific facilities

var task = new BatchProcessAccountDataTask
{
    FacilityChoice = new FacilityChoice
    {
        IndividualFacilities = new List<string> { "FAC001", "FAC002" }
    },
    Incremental = false,  // Reprocess everything, ignore existing estimates
    UpdateDimensions = true  // Update dimensions during processing
};

Example 2: Incremental processing for specific insurance and bill type

var task = new BatchProcessAccountDataTask
{
    FacilityChoice = new FacilityChoice
    {
        AllFacilities = true  // Process all facilities
    },
    InsuranceSet = new List<string> { "INS-MEDICARE" },
    BillTypeSet = new List<string> { "131" },
    Incremental = true,  // Only process accounts without existing estimates
    MinServiceDate = new DateTime(2024, 1, 1),
    MaxServiceDate = new DateTime(2024, 12, 31)
};

Example 3: Scenario analysis with "what-if" insurance

var task = new BatchProcessAccountDataTask
{
    FacilityChoice = new FacilityChoice
    {
        IndividualFacilities = new List<string> { "FAC001" }
    },
    ScenarioInsurance = "INS-BCBS",  // Calculate estimates as if using BCBS insurance
    Incremental = false
};

Example 4: Process recent accounts across facility groups

var task = new BatchProcessAccountDataTask
{
    FacilityChoice = new FacilityChoice
    {
        FacilityGroups = new List<string> { "HOSPITAL-GROUP-1", "CLINIC-GROUP-A" }
    },
    MinServiceDate = DateTime.Now.AddMonths(-3),  // Last 3 months
    Incremental = true
};

Example 5: Full reprocessing after pricing update

var task = new BatchProcessAccountDataTask
{
    FacilityChoice = new FacilityChoice
    {
        AllFacilities = true
    },
    InsuranceSet = new List<string> { "INS-MEDICARE", "INS-MEDICAID" },
    Incremental = false,  // Reprocess all, even with existing estimates
    UpdateDimensions = true,  // Ensure dimension tables are current
    MinServiceDate = new DateTime(2024, 1, 1)
};

Related Tasks Comparison

Task Use Case Granularity Custom SQL Batch Mode
BatchProcessAccountData Bulk account recalculation across multiple facilities/insurances/bill types Nested loops (facilities × insurances × bill types) No Yes (nested iteration)
ProcessAccountData Single facility/insurance/bill type combination Single combination No No
ProcessAccountDataFromQuery Custom SQL-driven account selection Query-defined Yes No
LoadAccountData Import account data from external sources File/table import Yes Import only (no calculation)

When to choose:


Performance Considerations

Database Impact

Optimization Tips

Scenario Recommendation Rationale
First-time processing Incremental = true Skips accounts with existing estimates, much faster
After pricing changes Incremental = false Ensures all estimates reflect new pricing
Large account volumes Limit facilities or use date filters Reduces total iteration count and processing time
Scenario testing Use ScenarioInsurance with single facility Enables "what-if" analysis without affecting production estimates
Scheduled nightly jobs Incremental = true with recent date range Processes only new/changed accounts efficiently

Expected Performance


Error Handling

The task uses error aggregation rather than fail-fast behavior:

// Errors are counted but don't stop processing
int errorCount = 0;
foreach (facility, insurance, billType combination) {
    errorCount += ProcessAccountData(combination);  // Returns error count
}

if (errorCount > 0) {
    // Log single aggregated error after all iterations complete
    LogException($"Total of {errorCount} errors when batch processing account data.");
}

Important:


Common Pitfalls

Issue Problem Solution
Empty InsuranceSet/BillTypeSet treated as "all" Setting empty lists doesn't mean "skip" - it means "process all" Explicitly set lists to null or omit the parameter if you want default behavior. Understand that empty = add single null entry = all.
Incremental mode skips updates Incremental = true won't update existing estimates even if pricing changed Set Incremental = false when reprocessing after pricing/config changes
Massive iteration counts All facilities × all insurances × all bill types can be hundreds of iterations Use specific facility/insurance lists or date filters to reduce scope
Dimension tables out of date Estimates use stale dimension data Set UpdateDimensions = true when dimension data may have changed
Scenario insurance confusion ScenarioInsurance overrides actual account insurance for calculations Only use for "what-if" analysis; remove for normal processing
Date filters miss accounts MinServiceDate/MaxServiceDate filter on service date, not account creation date Ensure date range covers the accounts you intend to process
Mixed bill type accounts Accounts with multiple bill types may be processed in multiple iterations This is expected - accounts appear in results for each matching bill type

Code References