Functions/Get-Locations.ps1

function Get-Locations {
    <#
    .SYNOPSIS
        Retrieves client locations via the Gorelo API.
 
    .DESCRIPTION
        - Preffered Method If -ClientId is specified, retrieves all locations for that specific client from /clients/{ClientId}/locations.
        - If no ClientId is specified, retrieves all clients from /clients and loops through each to get all their locations.
        - Optionally filters results by Name, BillingContactIds, City, State, or Country.
        - Only one filter can be used at a time.
        - Returns a combined list of all matching locations, including their associated ClientId.
 
    .PARAMETER BaseUrl
        Base API URL (default: https://api.usw.gorelo.io)
 
    .PARAMETER ApiVersion
        API version (default: v1)
 
    .PARAMETER ApiKey
        API key for authentication.
 
    .PARAMETER ClientId
        (Optional) Retrieve locations for a specific client.
 
    .PARAMETER Name
        (Optional) Filter results by location name (supports wildcards).
 
    .PARAMETER BillingContactIds
        (Optional) Filter results by billing contact ID(s). Accepts one or more IDs.
 
    .PARAMETER City
        (Optional) Filter results by city (supports wildcards).
 
    .PARAMETER State
        (Optional) Filter results by state (supports wildcards).
 
    .PARAMETER Country
        (Optional) Filter results by country (supports wildcards).
 
    .EXAMPLE
        Retrieve all locations for all clients
        Get-Locations -ApiKey "12345"
 
    .EXAMPLE
        Retrieve all locations for a specific client
        Get-Locations -ApiKey "12345" -ClientId "CL-000789"
 
    .EXAMPLE
        Retrieve only locations whose name contains "Office"
        Get-Locations -ApiKey "12345" -Name "*Office*"
 
    .EXAMPLE
        Retrieve locations associated with a single billing contact
        Get-Locations -ApiKey "12345" -BillingContactIds "BC-00123"
 
    .EXAMPLE
        Retrieve locations associated with multiple billing contacts
        Get-Locations -ApiKey "12345" -BillingContactIds "BC-00123","BC-00456"
 
    .EXAMPLE
        Retrieve locations in a specific city
        Get-Locations -ApiKey "12345" -City "Sydney"
 
    .EXAMPLE
        Retrieve locations by state (supports partial matches)
        Get-Locations -ApiKey "12345" -State "*New South*"
 
    .EXAMPLE
        Retrieve locations by country
        Get-Locations -ApiKey "12345" -Country "Australia"
   .NOTES
        Note: There is no all locations endpoint and only /clients/{ClientId}/locations so /clients is run for nearly all cmdlets and the filtered
    #>


    [CmdletBinding()]
    param(
        [string]$BaseUrl     = "https://api.usw.gorelo.io",
        [string]$ApiVersion  = "v1",

        [Parameter(Mandatory = $true)]
        [string]$ApiKey,

        [string]$ClientId,

        [string]$Name,
        [string[]]$BillingContactIds,
        [string]$City,
        [string]$State,
        [string]$Country
    )

    # --- Filter enforcement ---
    $filters = @($Name, $BillingContactIds, $City, $State, $Country) | Where-Object { $_ }
    if ($filters.Count -gt 1) {
        throw "Please specify only one search filter at a time (Name, BillingContactIds, City, State, or Country)."
    }

    if (-not $ApiKey) {
        throw "API key not provided. Use -ApiKey"
    }

    $headers = @{
        "X-API-Key"    = $ApiKey
        "Accept"       = "application/json"
        "Content-Type" = "application/json"
    }

    $allLocations = @()

    # --- If ClientId provided, only fetch for that client ---
    if ($ClientId) {
        $uri = "$($BaseUrl.TrimEnd('/'))/$($ApiVersion.Trim('/'))/clients/$ClientId/locations"

        try {
            Write-Verbose "Fetching locations for client $ClientId"
            $response = Invoke-RestMethod -Uri $uri -Method GET -Headers $headers -ErrorAction Stop

            foreach ($loc in $response) {
                $loc | Add-Member -NotePropertyName ClientId -NotePropertyValue $ClientId -Force
                $allLocations += $loc
            }
        }
        catch {
            $err = $_
            Write-Warning "Failed to retrieve locations for client $ClientId : $($err.Exception.Message)"
        }
    }
    else {
        # --- No ClientId: get all clients first ---
        $clientsUri = "$($BaseUrl.TrimEnd('/'))/$($ApiVersion.Trim('/'))/clients"

        try {
            Write-Verbose "Retrieving client list from $clientsUri"
            $clients = Invoke-RestMethod -Uri $clientsUri -Method GET -Headers $headers -ErrorAction Stop
        }
        catch {
            throw "Failed to retrieve clients: $($_.Exception.Message)"
        }

        foreach ($client in $clients) {
            if (-not $client.ID) { continue }

            $clientId = $client.ID
            $locUri = "$($BaseUrl.TrimEnd('/'))/$($ApiVersion.Trim('/'))/clients/$clientId/locations"

            try {
                Write-Verbose "Retrieving locations for client $clientId"
                $locations = Invoke-RestMethod -Uri $locUri -Method GET -Headers $headers -ErrorAction Stop

                foreach ($loc in $locations) {
                    $loc | Add-Member -NotePropertyName ClientId -NotePropertyValue $clientId -Force
                    $allLocations += $loc
                }
            }
            catch {
                Write-Warning "Failed to get locations for client $clientId : $($_.Exception.Message)"
            }
        }
    }

    # --- Single filter application ---
    switch ($true) {
        { $Name } {
            Write-Verbose "Filtering locations by Name: $Name"
            $allLocations = $allLocations | Where-Object { $_.Name -like $Name }
            break
        }
        { $BillingContactIds } {
            Write-Verbose "Filtering locations by BillingContactIds: $($BillingContactIds -join ', ')"
            $allLocations = $allLocations | Where-Object {
                $_.BillingContactIds -and (
                    @($_.BillingContactIds) -match ($BillingContactIds -join '|')
                )
            }
            break
        }
        { $City } {
            Write-Verbose "Filtering locations by City: $City"
            $allLocations = $allLocations | Where-Object { $_.City -like $City }
            break
        }
        { $State } {
            Write-Verbose "Filtering locations by State: $State"
            $allLocations = $allLocations | Where-Object { $_.State -like $State }
            break
        }
        { $Country } {
            Write-Verbose "Filtering locations by Country: $Country"
            $allLocations = $allLocations | Where-Object { $_.Country -like $Country }
            break
        }
    }

    return $allLocations
}



<#
 
$APIKey = 'xxx'
 
Get-Locations -ApiKey $APIKey # Gets All Locations
Get-Locations -ApiKey $APIKey -ClientId "xxx" # Gets Locations by ClientID
Get-Locations -ApiKey $APIKey -Name "xxx*" # Gets Locations by Name
Get-Locations -ApiKey $APIKey -BillingContactIds "xxx" # Gets Locations by BillingContactIds
Get-Locations -ApiKey $APIKey -City "xxx" # Gets Locations by City
Get-Locations -ApiKey $APIKey -State "xxx" # Gets Locations by Sate
Get-Locations -ApiKey $APIKey -Country "xxxx" # Gets Locations by Country
 
#>