Public/Get-Patients.ps1

<#
    .SYNOPSIS
    Returns a selected subset of patients in a Salesforce org.

    .DESCRIPTION
    Queries for Salesforce patients and queires the associated CDR resources for those patients.

    .INPUTS
    None. You cannot pipe objects to Get-Patients.

    .OUTPUTS
    An array of PSCustomObjects with each object contains the following keys:
        - sfPatient - the salesforce patient object
        - cdrPatient - the FHIR resource from PDS or CDR

    .PARAMETER SelectCdrIds
    An array of CDR ids to retrieve.

    .PARAMETER Status
    Only return patients with this status. Defaults to "Active"
    Can pass $null for all patients regardless of status.

    .PARAMETER Prompt
    If specified will display an interactive UI to select one or more patients. Default is not not prompt.

    .EXAMPLE
    PS> $patients = Get-Patients -Prompt -Status $null

    .LINK
    Set-Config

    .NOTES
    Assumes config is initialized for org access.
#>

function Get-Patients {

    [CmdletBinding()]
    [OutputType([PSCustomObject[]])]
    param(
        [Parameter(Mandatory = $false, Position = 0, ValueFromPipeline)]
        [String[]]
        $SelectCdrIds,

        [Parameter(Mandatory = $false, Position = 1)]
        [ValidateSet("Pending - Activation", "Active", "Suspended", "Pending - Removal", "Removed", "All", "Deleted")]
        [String]
        $Status = "All",

        [Parameter(Mandatory = $false, Position = 2)]
        [Switch]
        $Prompt = $false,

        [Parameter(Mandatory = $false, Position = 3)]
        [String]
        $SfId
    )

    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
    }

    end {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete"
    }

    process {
        Write-Debug "[$($MyInvocation.MyCommand.Name)] PSBoundParameters: $($PSBoundParameters | Out-String)"
        $params = @{ Status = $Status }
        if ($PSBoundParameters.ContainsKey('SfId')) {
            $params.Add("Id", $SfId)
        }

        $sfPatients = Get-SfPatients @params
        if ($sfPatients.Count -gt 0) {
            $cdrIds = @($sfPatients | Select-Object phecc__CDRPID__c -ExpandProperty phecc__CDRPID__c)
            $bundle = Get-CdrPatients -Ids $cdrIds
            $cdrPatients = $bundle.entry | Select-Object resource

            $selected = & {
                if ($PSBoundParameters.ContainsKey('SelectCdrIds')) {
                    $cdrPatients | Where-Object { $SelectCdrIds.Contains($_.resource.Id) } | Select-Object -ExpandProperty resource | Select-Object -Expandproperty id
                }
                elseif ($Prompt) {
                    ($cdrPatients | ForEach-Object { $_.resource } | Select-Object id, @{Name = 'family'; expression = { ($_.name | Where-Object { $_.use -eq 'usual' }).family } }, @{Name = 'given'; expression = { ($_.name | Where-Object { $_.use -eq 'usual' }).given } }, birthDate) | Out-GridView -PassThru | Select-Object Id -ExpandProperty Id
                }
                else {
                    $cdrPatients | Select-Object -ExpandProperty resource | Select-Object -Expandproperty id
                }
            }
            @($selected | ForEach-Object {
                    $cdrId = $_
                    @{
                        sfPatient  = ($sfPatients | Where-Object { $_.phecc__CDRPID__c -eq $cdrId })
                        cdrPatient = ($cdrPatients | Where-Object { $_.resource.id -eq $cdrId })
                    }
                })
        }
    }
}