Public/Employees/Search-UKGEmployee.ps1

function Search-UKGEmployee {
    <#
    .SYNOPSIS
        Searches for employees in the UKG HR Service Delivery API.

    .DESCRIPTION
        Performs advanced searches for employees using various filter criteria.
        This is the recommended method for finding employees.

    .PARAMETER Filter
        Hashtable of filter criteria. Supports operators like eq, ne, contains, etc.

    .PARAMETER Email
        Search by employee email address.

    .PARAMETER FirstName
        Search by employee first name.

    .PARAMETER LastName
        Search by employee last name.

    .PARAMETER EmployeeNumber
        Search by employee number.

    .PARAMETER OrganizationId
        Search by organization ID.

    .PARAMETER Status
        Search by employee status (active, terminated, etc.).

    .PARAMETER All
        Retrieve all matching results across all pages.

    .PARAMETER PerPage
        Number of results per page (1-100, default 25).

    .PARAMETER Cursor
        Pagination cursor for retrieving a specific page.

    .PARAMETER Fields
        Array of field names to include in the response.

    .EXAMPLE
        Search-UKGEmployee -Email "john.doe@company.com"

    .EXAMPLE
        Search-UKGEmployee -LastName "Smith" -Status "active" -All

    .EXAMPLE
        Search-UKGEmployee -Filter @{ email = @{ contains = "@company.com" } }

    .OUTPUTS
        Array of UKG.Employee objects.
    #>

    [CmdletBinding(DefaultParameterSetName = 'Simple')]
    [OutputType([PSCustomObject[]])]
    param(
        [Parameter(Mandatory, ParameterSetName = 'Advanced')]
        [hashtable]$Filter,

        [Parameter(ParameterSetName = 'Simple')]
        [string]$Email,

        [Parameter(ParameterSetName = 'Simple')]
        [string]$FirstName,

        [Parameter(ParameterSetName = 'Simple')]
        [string]$LastName,

        [Parameter(ParameterSetName = 'Simple')]
        [string]$EmployeeNumber,

        [Parameter(ParameterSetName = 'Simple')]
        [string]$OrganizationId,

        [Parameter(ParameterSetName = 'Simple')]
        [ValidateSet('active', 'terminated', 'pending', 'inactive')]
        [string]$Status,

        [Parameter()]
        [switch]$All,

        [Parameter()]
        [ValidateRange(1, 100)]
        [int]$PerPage = 25,

        [Parameter()]
        [string]$Cursor,

        [Parameter()]
        [string[]]$Fields
    )

    # Build the search body
    $body = @{}

    if ($PSCmdlet.ParameterSetName -eq 'Advanced') {
        $body = $Filter
    }
    else {
        # Build filter from simple parameters
        $filters = @{}

        if ($Email) {
            $filters['email'] = @{ eq = $Email }
        }
        if ($FirstName) {
            $filters['first_name'] = @{ contains = $FirstName }
        }
        if ($LastName) {
            $filters['last_name'] = @{ contains = $LastName }
        }
        if ($EmployeeNumber) {
            $filters['employee_number'] = @{ eq = $EmployeeNumber }
        }
        if ($OrganizationId) {
            $filters['organization_id'] = @{ eq = $OrganizationId }
        }
        if ($Status) {
            $filters['status'] = @{ eq = $Status }
        }

        if ($filters.Count -gt 0) {
            $body = $filters
        }
    }

    # Build query parameters
    $queryParams = @{
        per_page = $PerPage
    }

    if ($Cursor) {
        $queryParams['cursor'] = $Cursor
    }

    if ($Fields) {
        $queryParams['fields'] = $Fields -join ','
    }

    if ($All -and -not $Cursor) {
        # Retrieve all pages
        $allEmployees = Get-UKGAllPages -Endpoint '/employees/search' -Method POST -Body $body -QueryParameters $queryParams
        foreach ($emp in $allEmployees) {
            $emp.PSObject.TypeNames.Insert(0, 'UKG.Employee')
        }
        return $allEmployees
    }
    else {
        # Retrieve single page
        $response = Invoke-UKGRequest -Endpoint '/employees/search' -Method POST -Body $body -QueryParameters $queryParams -ReturnHeaders

        if ($response.Data) {
            foreach ($emp in $response.Data) {
                $emp.PSObject.TypeNames.Insert(0, 'UKG.Employee')
            }

            # Add pagination info
            $pagination = Get-UKGNextPage -Headers $response.Headers
            if ($pagination.NextCursor) {
                Write-Verbose "Next cursor: $($pagination.NextCursor)"
                Write-Verbose "Total count: $($pagination.TotalCount)"
            }

            return $response.Data
        }
    }
}