Table of Contents

Populate Exit for Referral

Replicate exit activities from parent referrals to their child referrals, and link exit data back to referral records.

Overview

The Populate Exit for Referral operation finds exit activities (mag_exit) on parent referrals that have child referrals without exits, then:

  1. Links the exit back to the parent referral (if not already linked)
  2. Creates a new exit activity for each child referral that is missing one
  3. Updates each child referral with exit date, reason, and a reference to its new exit

This is an idempotent operation — re-running it will skip parent referrals and child referrals that have already been processed.

When to Use This Operation

Use This Operation When

  • After creating child referrals via --RecreateAdditionalReferrals where parent referrals were already exited
  • Parent referrals have exit activities but their child referrals don't
  • After data migration where exits need to be replicated to child referrals

Don't Use This Operation When

  • No child referrals exist (no mag_masterreferral relationships) — the query will find 0 records
  • Exit activities don't have mag_inboundreferral populated
  • All child referrals already have exits linked via mag_exitedby

Quick Start

Example 1: Preview Exit Population

Always run with --PreviewMode first. This queries the data and reports what would happen without making changes:

dotnet run --project WT.Navigator.CLI -- datamanipulation `
  --PopulateExitForReferral `
  -e https://myorg.crm6.dynamics.com `
  --ClientId a1b2c3d4-e5f6-7890-1234-567890abcdef `
  --Secret YourClientSecretHere `
  --PreviewMode

Expected Output:

Starting parallel population of exit for referrals...
Counting total parent exit records to process...
Found 42 parent exit records to process
Preview mode active - limiting to 100 records for faster preview
...
PREVIEW: Exit 12345678-1234-1234-1234-123456789012
  Parent referral: 23456789-2345-2345-2345-234567890123 | Needs update: False | Exit date: 2024-11-01 | Exit reason: 809730001
  Child referrals without exit: 2
    -> Child referral aaa... | Individual: Jane Smith
    -> Child referral bbb... | Individual: John Smith Jr
...
═══════════════════════════════════════════════════════════════
  PREVIEW SUMMARY - No changes were made
═══════════════════════════════════════════════════════════════
  Parent exit records scanned:           42
  Parent referrals needing update:       3
  Child exit records to create:          87
  Child referrals to update:             87
  Total Dataverse writes (estimated):    177
═══════════════════════════════════════════════════════════════
  Time taken: 12.3 seconds
  Run without --preview to execute these changes.
═══════════════════════════════════════════════════════════════
Note

Preview mode is limited to 100 parent exit records for speed. The counts shown are for that sample — actual totals may be higher.

Example 2: Execute Exit Population

After verifying the preview, run without --PreviewMode:

dotnet run --project WT.Navigator.CLI -- datamanipulation `
  --PopulateExitForReferral `
  -e https://myorg.crm6.dynamics.com `
  --ClientId a1b2c3d4-e5f6-7890-1234-567890abcdef `
  --Secret YourClientSecretHere

Expected Output:

Starting parallel population of exit for referrals...
Found 42 parent exit records to process
Creating pool of 50 service clients...
Progress: 20/42 (47.6%)
Progress: 42/42 (100.0%)
Populate exit for referral completed: 42/42 parent exit records processed in 34.2 seconds

How It Works

Record Selection Query

The operation finds mag_exit records that match all of these criteria:

  1. mag_inboundreferral is not null (exit is linked to a referral)
  2. The linked referral has at least one child referral (via mag_masterreferral)
  3. That child referral's mag_exitedby is null (child has no exit yet)
Important

The query targets exits where child referrals lack exits — not where the parent referral lacks mag_exitedby. A parent referral that was already linked to its exit will still be processed if its children haven't been exited.

Processing Steps (per parent exit)

  1. Resolve exit reason: If mag_newexitreason is set on the exit, retrieves the mapped mag_wtnexitreason value from mag_exitreasonmapping

  2. Check parent referral: Retrieves the parent referral's mag_exitedby field

    • If null → updates the parent referral with mag_exitedby, mag_exitdate, and mag_exitreason
    • If already set → skips the parent update (idempotent)
  3. Find unexited child referrals: Queries mag_referral where mag_masterreferral = parent AND mag_exitedby IS NULL

  4. For each child referral, creates a new mag_exit record and updates the child referral:

    Child exit creation:

    Field Source
    All business fields Cloned from parent exit (see exclusions below)
    mag_familygroupmember Child referral's mag_individualid
    mag_inboundreferral Child referral
    mag_familygroup Child individual's mag_whanauid
    mag_name / mag_summary "Exit Activity"
    mag_relationships JSON built from child's individual + referral IDs
    mag_planactivitysummary Cleared (null)

    Child referral update:

    Field Value
    mag_exitedby Reference to newly created mag_exit
    mag_exitdate Parent exit's mag_dischargedon (if set)
    mag_exitreason Mapped exit reason (if resolved)

Fields Excluded from Clone

When creating child exits, these fields are not copied from the parent exit:

Category Fields
Primary key mag_exitid
System audit createdby, createdon, modifiedby, modifiedon, createdonbehalfby, modifiedonbehalfby
Ownership owningbusinessunit, owningteam, owninguser
State statecode, statuscode
Auto-number mag_exitnumber
Migration mag_sourceguid, importsequencenumber, overriddencreatedon, timezoneruleversionnumber, utcconversiontimezonecode
Email activities mag_emailnoticetogp, mag_emailnoticetoreferrer
UI placeholders mag_auditpcfplaceholder, mag_pcfplaceholder, mag_autotextplaceholder, mag_pochelptextholder, mag_currentlegalstatusdisplay
Set explicitly mag_familygroupmember, mag_inboundreferral, mag_summary, mag_name, mag_planactivitysummary, mag_relationships

All other fields (exit reason, dates, clinical fields, PRIMHD, custom fields, activity groups, etc.) are carried across from the parent exit.

mag_relationships JSON Format

The operation builds this JSON structure for each exit activity:

{
  "Individual": [{"Id": "12345678-1234-1234-1234-123456789012"}],
  "Outcome": [],
  "Referral": [{"Id": "23456789-2345-2345-2345-234567890123"}]
}

Parameters

Required Parameters

--PopulateExitForReferral

Flag (-x) to enable the operation.

--EnvironmentUrl (-e)

The URL of your Dataverse environment.

-e https://myorg.crm6.dynamics.com

--ClientId

The Azure AD application (client) ID. Defaults to the standard SPN if omitted.

Optional Parameters

--Secret

The client secret. If omitted, uses the default secret from configuration.

--PreviewMode (-p)

Run in preview mode. Queries data and reports counts but makes no changes. Limited to 100 parent exit records.

Tip

Always run with --PreviewMode first to verify the count of exits to be created.

Real-World Scenarios

Scenario 1: Complete Exit Process After Creating Child Referrals

Situation: You ran --RecreateAdditionalReferrals and created child referrals. Some parent referrals were already exited, but the new child referrals have no exits.

# Step 1: Preview to verify counts
dotnet run --project WT.Navigator.CLI -- datamanipulation `
  --PopulateExitForReferral `
  -e https://prod.crm6.dynamics.com `
  --ClientId a1b2c3d4-e5f6-7890-1234-567890abcdef `
  -s $env:DATAVERSE_SECRET `
  --PreviewMode

# Step 2: Review the log file
$logFile = Get-ChildItem "ParallelProcessing_PopulateExitForReferral_*" | Sort-Object LastWriteTime -Descending | Select-Object -First 1
Get-Content $logFile.FullName | Select-String "PREVIEW SUMMARY" -Context 0,10

# Step 3: If counts match expectations, run for real
dotnet run --project WT.Navigator.CLI -- datamanipulation `
  --PopulateExitForReferral `
  -e https://prod.crm6.dynamics.com `
  --ClientId a1b2c3d4-e5f6-7890-1234-567890abcdef `
  -s $env:DATAVERSE_SECRET

Expected Outcome:

  • Parent referrals have mag_exitedby, mag_exitdate, mag_exitreason populated (if they weren't already)
  • Each child referral has its own exit activity
  • Child exits have correct individual, family group, and referral links
  • Re-running the operation finds 0 records (all children now have exits)

Scenario 2: Fix Missing Exits After Data Migration

Situation: After migration, parent referrals have exit activities but child referrals don't.

dotnet run --project WT.Navigator.CLI -- datamanipulation `
  --PopulateExitForReferral `
  -e https://prod.crm6.dynamics.com `
  --ClientId a1b2c3d4-e5f6-7890-1234-567890abcdef `
  --Secret $env:DATAVERSE_SECRET

This is safe to run multiple times — it will only create exits for child referrals that still need them.

Performance & Scalability

Processing Configuration

Setting Value
Max concurrent threads 50
Records per batch 10 parent exits
Retrieve page size 5,000
Preview mode record limit 100 parent exits

Typical Performance

Parent Exits Avg Children/Parent Estimated Time
50 2 10–20 seconds
500 2 60–120 seconds
5,000 2 10–20 minutes
Note

Each child referral requires 3 Dataverse operations (retrieve individual, create exit, update referral). Performance depends on network latency, Dataverse throttling, and any plugins/workflows triggered by the creates/updates.

Troubleshooting

"No parent exit records found"

The query returned 0 records. This means one of:

  1. No exit activities exist with mag_inboundreferral — exits aren't linked to referrals
  2. No child referrals exist — no mag_masterreferral relationships (run --RecreateAdditionalReferrals first)
  3. All child referrals already have exits — operation has already been run, or exits were created through normal use

Verify with Advanced Find or SQL:

-- Check exits linked to referrals
SELECT COUNT(*) FROM mag_exit WHERE mag_inboundreferral IS NOT NULL

-- Check child referrals without exits
SELECT COUNT(*) FROM mag_referral
WHERE mag_masterreferral IS NOT NULL AND mag_exitedby IS NULL

"Error processing exit: ..."

Individual exit processing errors are logged but don't stop the operation. Common causes:

  • Plugin errors — a workflow or plugin on mag_exit create or mag_referral update failed
  • Privilege errors — the SPN doesn't have Create on mag_exit or Update on mag_referral
  • Missing individual — the child referral's mag_individualid references a deleted contact

Output & Logs

Log File Location

Log files are written to the working directory:

ParallelProcessing_PopulateExitForReferral_2026-02-17_14-30-22-123.log

Idempotency

The operation is safe to re-run:

  • Parent referrals already linked to their exit are skipped
  • Child referrals that already have mag_exitedby set are not queried
  • Parent exits with no remaining unexited children won't appear in the query at all

See Also