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

MDClarity · task primitive

CheckVisitGFEComplianceBatch

Overview

CheckVisitGFEComplianceBatchTask calculates Good Faith Estimate (GFE) compliance status for all visits in the VisitBatch table. It determines whether visits requiring GFEs have had compliant estimates sent on time, calculates due dates based on federal regulations, and identifies visits that need GFE letter resends due to changes after the initial letter was sent.

Use this task when: You need to audit GFE compliance for a batch of visits, identify visits requiring GFE letter resends due to changes, or prepare compliance data before running AutoSendLetters tasks.

Don't use this task when: Processing individual visit compliance in real-time (use VisitGFEComplianceCalculator directly), working with visits not in the batch table, or when GFE functionality is not enabled for the customer.


Parameters

Parameter Type Required Default Description
None - - - This task has no configurable parameters. It processes all visits in the VisitBatch table using the customer's GFEConfig settings.

Note: The task behavior is controlled by:


Execution Flow

flowchart TD
    A[Start CheckVisitGFEComplianceBatch] --> B[Clear VisitGFEComplianceBatch table]
    B --> C[Get all visits from VisitBatch]
    C --> D[Load related data for all visits]
    D --> E[Create dictionaries: VisitChangeEvents, PatientLetterSendEvents, PatientLetters]

    E --> F{Any visits in batch?}
    F -->|No| Z[Exit - No compliance records created]
    F -->|Yes| G[Loop through each visit]

    G --> H[Create VisitGFECalculationItem for visit]
    H --> I[Get most recent GFE-specific VisitChangeEvent]
    I --> J[Get GFE letters for visit]
    J --> K[Filter to letters created after most recent change]
    K --> L[Get compliant send events with no errors]

    L --> M[Calculate compliance for visit]
    M --> N{Does visit require GFE?}

    N -->|No - Less than 3 business days notice| O[Set IsGFERequired=false, IsGFECompliant=true]
    N -->|No - Not configured in GFEConfig| O
    N -->|Yes| P[Calculate GFE due date]

    P --> Q{Letters sent before due date?}
    Q -->|Yes, after last change| R[Set IsGFECompliant=true, IsResendRequired=false]
    Q -->|No or not after last change| S{GFE letters exist?}

    S -->|Yes| T[Set IsGFECompliant=false, IsResendRequired=true]
    S -->|No| U[Set IsGFECompliant=false, IsResendRequired=false]

    O --> V[Add to calculated compliances list]
    R --> V
    T --> V
    U --> V

    V --> W{More visits?}
    W -->|Yes| G
    W -->|No| X[Bulk save all VisitGFECompliances to batch table]
    X --> Y[End]

    style B fill:#ffe1e1
    style M fill:#e1f5ff
    style X fill:#e1f5ff

Processing Algorithm

The task uses federal GFE regulations to determine compliance:

GFE Requirement Rules

A visit requires a GFE if ALL of the following are true:

  1. Advance notice: Visit scheduled 3+ business days after creation (using SourceCreatedOn or CreatedOn)
  2. Configuration match: Visit's insurance and/or visit type matches customer's GFEConfig.Insurances and GFEConfig.VisitTypes
    • If both lists are empty: ALL visits require GFE
    • If only insurances configured: Match on insurance only
    • If only visit types configured: Match on visit type only
    • If both configured: Must match both insurance AND visit type

Due Date Calculation

Business days between creation and scheduled time:
- 3-9 business days: Due date = Creation date + 1 business day
- 10+ business days: Due date = Creation date + 3 business days
- Less than 3 business days: No GFE required

Federal holidays are excluded from business day calculations using FederalHolidayCalendar.

Compliance Determination

IsGFECompliant = true IF:
  - Visit does not require GFE, OR
  - At least one PatientLetterSendEvent exists where:
    * SendEvent.CreatedOn <= DueDate
    * Letter.IsGoodFaithEstimate = true
    * Letter was created after most recent GFE-specific change
    * SendEvent has no errors (LetterSendErrors.Count = 0)

IsResendRequired = true IF:
  - Visit requires GFE, AND
  - GFE letters exist for the visit, AND
  - No compliant send events exist before due date

GFE-Specific Visit Changes

Only these change types trigger GFE resend requirements:

Other changes (like PatientNameChanged) do NOT require GFE resends.

Example Execution

Scenario: Visit created on July 18, scheduled for October 18

  1. Business days calculation: 10+ business days between creation and scheduled time
  2. Due date: July 18 + 3 business days = July 21
  3. Letter sent: July 20 with successful send event
  4. Result: IsGFECompliant = true, IsResendRequired = false

Scenario: Same visit, but charges changed on July 22

  1. Most recent change: July 22 (ChargesChanged)
  2. Existing letter: Created July 18 (before change)
  3. Compliant send events: None after July 22
  4. Result: IsGFECompliant = false, IsResendRequired = true, VisitChangeEventKey = "VCE-XYZ"

Usage Examples

Example 1: Basic compliance calculation

// No parameters needed - processes entire VisitBatch
var task = new CheckVisitGFEComplianceBatchTask();
task.Execute(dataStore);

// Results are written to VisitGFEComplianceBatch table
// Query to see compliance results:
// SELECT * FROM VisitGFEComplianceBatch WHERE IsGFECompliant = 0

Example 2: Part of a visit processing pipeline

// Step 1: Load visits into batch
var loadVisitsTask = new LoadVisitsTask { /* query configuration */ };
loadVisitsTask.Execute(dataStore);

// Step 2: Calculate compliance
var complianceTask = new CheckVisitGFEComplianceBatchTask();
complianceTask.Execute(dataStore);

// Step 3: Send letters to non-compliant visits
var autoSendTask = new AutoSendLettersTask();
autoSendTask.Execute(dataStore);

Example 3: Compliance auditing after visit changes

// After logging visit changes with LogVisitChangeEventsBatchTask,
// recalculate compliance to identify resend requirements
var changeEventsTask = new LogVisitChangeEventsBatchTask();
changeEventsTask.Execute(dataStore);

var complianceTask = new CheckVisitGFEComplianceBatchTask();
complianceTask.Execute(dataStore);

// Query visits requiring resends
string sql = @"
    SELECT v.Key, v.PatientName, v.ScheduledTime,
           gfe.DueDate, gfe.VisitChangeEventKey
    FROM VisitBatch v
    INNER JOIN VisitGFEComplianceBatch gfe ON v.Key = gfe.Key
    WHERE gfe.IsResendRequired = 1";

Example 4: Checking compliance before SyncBatch

// Calculate compliance for visits in batch
var complianceTask = new CheckVisitGFEComplianceBatchTask();
complianceTask.Execute(dataStore);

// Sync batch data to production tables
// (This promotes VisitGFEComplianceBatch → VisitGFECompliance)
var syncTask = new SyncBatchTask();
syncTask.Execute(dataStore);

Related Tasks Comparison

Task Use Case Data Source Writes To Real-Time
CheckVisitGFEComplianceBatch Batch compliance calculation for all visits in batch table VisitBatch VisitGFEComplianceBatch No (batch only)
LogVisitChangeEventsBatch Track changes to visits that may require GFE resends VisitBatch vs Visit comparison VisitChangeEventBatch No (batch only)
AutoSendLetters Generate and send GFE letters for compliant visits VisitBatch + AutoSendLetterConfig PatientLetter, PatientLetterSendEvent No (batch only)
AutoSendLettersForFutureVisits Generate GFE letters for future visits Visit table (future scheduled) PatientLetter, PatientLetterSendEvent No (scheduled task)
SyncBatch Promote batch compliance data to production VisitGFEComplianceBatch VisitGFECompliance No (batch only)

When to use which:


Performance Considerations

Database Impact

Tables Read:

Tables Written:

Query Patterns:

Optimization Tips

Scenario Recommendation Rationale
Large batch sizes (10K+ visits) Consider breaking into smaller batches or running during off-hours Memory usage grows with batch size; dictionaries hold all related data in memory
First-time GFE enablement Run for historical visits separately from daily processing Initial run processes all visits; subsequent runs only process new/changed visits
Frequent visit changes Run LogVisitChangeEventsBatch before this task Ensures most recent changes are captured for resend determination
Performance monitoring Track execution time and batch size Typical performance: 1,000 visits processed in < 5 seconds

Memory Considerations

The task loads all related data into memory dictionaries:

For a batch of 10,000 visits with average of 2 change events, 3 letters, and 3 send events each:

Concurrent Execution

Not Safe: Do not run multiple instances concurrently


Error Handling

The task uses a fail-fast approach:

public void Execute()
{
    // Truncates batch table
    visitGFEComplianceRepo.ClearVisitGFEComplianceBatch();

    // Get all data (throws on database errors)
    List<VisitGFECalculationItem> items =
        batchVisitGFECalculationItemFactory.GetForVisitBatch();

    // Calculate compliance for all visits
    List<VisitGFECompliance> compliances =
        visitGFEComplianceCalculator.CalculateVisitGFECompliances(items);

    // Bulk save (throws on database errors)
    visitGFEComplianceRepo.SaveManyBatch(compliances);
}

Error Behavior:

Important: The task does NOT:

Rollback Behavior:


Common Pitfalls

Issue Problem Solution
Empty VisitGFEComplianceBatch table VisitBatch table is empty or not populated Run LoadVisitsTask or SyncBatchTask to populate VisitBatch before running compliance check
All visits show IsGFERequired=false Customer.GFEConfig not configured Verify Customer.GFEConfig.Insurances and Customer.GFEConfig.VisitTypes are populated with appropriate values
Due dates are null Visit.ScheduledTime is null Ensure visits have scheduled times; visits without scheduled times cannot have due dates calculated
Compliance always false PatientLetterSendEvent records missing or have errors Check that AutoSendLetters task successfully sent letters; verify LetterSendErrors collection is empty
IsResendRequired not triggering VisitChangeEventBatch not populated Run LogVisitChangeEventsBatchTask before compliance task to capture visit changes
Wrong business day calculations Federal holidays not recognized Task uses FederalHolidayCalendar; verify holiday calendar is up to date for current year
Resend logic not considering changes GFE-specific change types not logged Only specific change types trigger resends (InsuranceChanged, ChargesChanged, etc.); verify change events include these types
Compliance data not in production SyncBatch not run after compliance task Run SyncBatchTask to promote VisitGFEComplianceBatch → VisitGFECompliance for production use
SourceCreatedOn vs CreatedOn confusion Visit creation date affects due date calculation Task prefers SourceCreatedOn (from source system) over CreatedOn (MDClarity import time) for due date calculation

Code References