Public/Get-NewPatientDeviceNeeds.ps1

<#
    .SYNOPSIS
    Queries the patients in the org to determine new device needs and returns the fields required for ordering of those devices.

    .DESCRIPTION
    The new device is determined by getting the patient measurement requirements and comparing that against the previous
    measurement requirements. Only the newly added requirements are reported as a need.

    The needs of each patient is persisted into json files named using the CDR identifier in the folder specified with the -Folder parameter.

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

    .OUTPUTS
    An array of PSCustomObject. Each object contains the following keys:
        PostalCode
        MRN
        HomePhone
        TierOfService
        Needs
        Country
        CdrId
        District
        DeliveryChannel
        GivenName
        DOB
        FamilyName
        State
        MobilePhone
        City
        Preferences
        Address

    .PARAMETER Patients
    The patients to retrieve needs. See Get-Patients. If not supplied then get Get-Patients will be called with the value of supplied in the -Status parameter

    .PARAMETER Def
    The metric metadata definitions from Get-MetricDefinitions. If not supplied then it will be called.

    .PARAMETER Folder
    The folder where to create the persistent need files per patient. Defaults to "./temp"

    .PARAMETER Status
    The status to query patients. Default to $null which indicates that needs will be generated for all patients.

    .EXAMPLE
    PS> $needs = Get-NewPatientDeviceNeeds

    .LINK
    Set-Config
    Get-Patients

    .NOTES
    Assumes config is initialized for org access.
    The folder will be created if it does not exist.
    You can force generation of new needs by deleting the specified folder or specifying a different empty folder.
#>

function Get-NewPatientDeviceNeeds {

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

        [Parameter(Mandatory = $false, Position = 1)]
        [PSCustomObject]
        $Def,

        [Parameter(Mandatory = $false, Position = 2)]
        [String]
        $Folder = "./temp",

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

    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)"
        New-Item -ItemType Directory -Force -Path $Folder | Out-Null

        if (-not $PSBoundParameters.ContainsKey('Def')) {
            $Def = Get-MetricDefinitions
        }

        if (-not $PSBoundParameters.ContainsKey('Patients')) {
            $Patients = Get-Patients -Status $Status
        }

        $Sites = $null
        $patientDevices = Get-PatientMeasurementRequirements -Patients $Patients -Def $Def

        foreach ($next in $patientDevices) {
            $fileName = "$($next.patient.cdrPatient.resource.id).json"
            Write-Debug "Reading file: $($fileName)"
            $PatientFile = Join-Path -Path $Folder -ChildPath $fileName
            $persist = $false
            $needs = $null
            if ((Test-Path $PatientFile -PathType Leaf)) {
                $persistedPatient = Get-Content -Path $PatientFile | ConvertFrom-Json
                # Find ids of new measurement needs
                $new = $next.needs | Select-Object Id -ExpandProperty Id | Where-Object { $_ -notin ($persistedPatient.needs | Select-Object Id -ExpandProperty Id) }
                if ($new) {
                    $persist = $true
                    # Just the 'new' needs
                    $needs = $Def.measurements | Where-Object { $_.Id -in $new }
                }
            }
            else {
                $persist = $true
                if ($next.needs) {
                    # All needs are new
                    $needs = $Def.measurements | Where-Object { $_.Id -in ($next.needs | Select-Object Id -ExpandProperty Id) }
                }
            }
            if ($needs) {
                Write-Debug "Processing CDRID: $($next.patient.cdrPatient.resource.id)"
                # Look up patient site name
                if (-not $Sites) {
                    $Sites = Get-SfSites
                }
                $siteName = $Sites | Where-Object { $_.Id -eq $next.patient.sfPatient.phecc__Site__c } | Select-Object -Expand Name

                [PSCustomObject]@{
                    CdrId           = $next.patient.cdrPatient.resource.id
                    Site            = $siteName
                    GivenName       = ($next.patient.cdrPatient.resource.name | Where-Object { $_.use -eq 'usual' } | Select-Object -Property given | Where-Object { $null -ne $_ } | Select-Object -ExpandProperty given) -Join " "
                    FamilyName      = ($next.patient.cdrPatient.resource.name | Where-Object { $_.use -eq 'usual' } | Select-Object -Property family | Where-Object { $null -ne $_ } | Select-Object -ExpandProperty family) -Join " "
                    MRN             = $next.patient.cdrpatient.resource.identifier | Where-Object { $_.system -eq 'MRN' } | Where-Object { $null -ne $_.value } | Select-Object value | Where-Object { $null -ne $_ } | Select-Object -expand value
                    DOB             = $next.patient.cdrPatient.resource.birthDate
                    Address         = $next.patient.cdrpatient.resource.address.line -replace "`n", " "
                    City            = $next.patient.cdrpatient.resource.address | Where-Object { $null -ne $_ } | Select-Object city | Where-Object { $null -ne $_ } | Select-Object -Expand city
                    State           = $next.patient.cdrpatient.resource.address | Where-Object { $null -ne $_ } | Select-Object state | Where-Object { $null -ne $_ } | Select-Object -Expand state
                    PostalCode      = $next.patient.cdrpatient.resource.address | Where-Object { $null -ne $_ } | Select-Object postalCode | Where-Object { $null -ne $_ } | Select-Object -Expand postalCode
                    District        = $next.patient.cdrpatient.resource.address | Where-Object { $null -ne $_ } | Select-Object district | Where-Object { $null -ne $_ } | Select-Object -Expand district
                    Country         = $next.patient.cdrpatient.resource.address | Where-Object { $null -ne $_ } | Select-Object country | Where-Object { $null -ne $_ } | Select-Object -Expand country
                    HomePhone       = $next.patient.cdrpatient.resource.telecom | Where-Object { $_.system -eq 'phone' -and $_.use -eq 'home' } | Where-Object { $null -ne $_.value } | Select-Object value | Where-Object { $null -ne $_ } | Select-Object -Expand value
                    MobilePhone     = $next.patient.cdrpatient.resource.telecom | Where-Object { $_.system -eq 'phone' -and $_.use -eq 'mobile' } | Where-Object { $null -ne $_.value } | Select-Object value | Where-Object { $null -ne $_ } | Select-Object -Expand value
                    TierOfService   = $next.patient.sfPatient.phecc__Tier_of_Service__c
                    DeliveryChannel = $next.patient.sfPatient.phecc__Delivery_Channel__c
                    Needs           = ($needs | Select-Object phecc__Device_Type__c -ExpandProperty phecc__Device_Type__c) -Join "|"
                    Preferences     = [String](($next.preferences | Select-Object -Property Name -ExpandProperty Name) -Join "|")
                }
            }
            if ($persist) {
                $next | ConvertTo-Json -Depth 100 | Set-Content -Path $PatientFile -Force | Out-Null
            }
        }
    }
}