functions/public/Update-BulkCattle.ps1

function Update-BulkCattle {
    <#
    .SYNOPSIS
    Updates multiple cattle records at once with the same field values
    
    .DESCRIPTION
    Allows bulk updating of cattle records by tag number. Useful for moving groups
    of cattle to different locations or updating other shared attributes.
    Only updates the fields that are provided - other fields remain unchanged.
    
    .PARAMETER TagNumbers
    Array of tag numbers to update
    
    .PARAMETER Location
    New location for all selected cattle (e.g., "Pen 1", "Quarantine", "Pasture")
    
    .PARAMETER Status
    New status for all selected cattle (Active, Sold, Deceased, etc.)
    
    .PARAMETER Owner
    New owner for all selected cattle
    
    .PARAMETER Notes
    Notes to append or replace for all selected cattle
    
    .PARAMETER AppendNotes
    If specified, adds the notes to existing notes rather than replacing them
    
    .OUTPUTS
    Returns a summary object with counts of successful and failed updates
    
    .EXAMPLE
    Update-BulkCattle -TagNumbers @('1001', '1002', '1003') -Location 'Pen 2'
    
    Moves cattle with tags 1001, 1002, and 1003 to Pen 2
    
    .EXAMPLE
    Update-BulkCattle -TagNumbers @('2001', '2002') -Location 'Quarantine' -Notes 'Health check required' -AppendNotes
    
    Moves cattle to quarantine and appends a note to their existing notes
    
    .EXAMPLE
    Update-BulkCattle -TagNumbers @('3001', '3002') -Status 'Sold' -Owner 'Creekstone Farms'
    
    Marks cattle as sold and updates the owner
    
    .NOTES
    This function uses transactions to ensure all-or-nothing updates.
    If any update fails, all changes are rolled back.
    #>

    [CmdletBinding(SupportsShouldProcess)]
    param(
        [Parameter(Mandatory)]
        [string[]]
        $TagNumbers,
        
        [Parameter()]
        [ValidateSet('Pen 1', 'Pen 2', 'Pen 3', 'Pen 4', 'Pen 5', 'Pen 6', 'Quarantine', 'Pasture', 'Feedlot', 'Hospital Pen')]
        [string]
        $Location,
        
        [Parameter()]
        [ValidateSet('Active', 'Sold', 'Deceased', 'Transferred')]
        [string]
        $Status,
        
        [Parameter()]
        [string]
        $Owner,
        
        [Parameter()]
        [string]
        $Notes,
        
        [Parameter()]
        [switch]
        $AppendNotes
    )
    
    # Validate that at least one update field is provided
    if (-not ($Location -or $Status -or $Owner -or $Notes)) {
        throw "At least one field to update must be specified (Location, Status, Owner, or Notes)"
    }
    
    $successCount = 0
    $failedCount = 0
    $failedTags = @()
    
    foreach ($tag in $TagNumbers) {
        try {
            # Get the current cattle record
            $cattle = Get-AllCattle | Where-Object TagNumber -eq $tag
            
            if (-not $cattle) {
                Write-Warning "Cattle with tag $tag not found - skipping"
                $failedCount++
                $failedTags += $tag
                continue
            }
            
            # Build the UPDATE statement dynamically
            $updates = @()
            
            if ($Location) {
                $locationValue = ConvertTo-SqlValue -Value $Location
                $updates += "Location = $locationValue"
            }
            
            if ($Status) {
                $statusValue = ConvertTo-SqlValue -Value $Status
                $updates += "Status = $statusValue"
            }
            
            if ($Owner) {
                $ownerValue = ConvertTo-SqlValue -Value $Owner
                $updates += "Owner = $ownerValue"
            }
            
            if ($Notes) {
                if ($AppendNotes -and $cattle.Notes) {
                    $combinedNotes = "$($cattle.Notes)`n$Notes"
                    $notesValue = ConvertTo-SqlValue -Value $combinedNotes
                    $updates += "Notes = $notesValue"
                }
                else {
                    $notesValue = ConvertTo-SqlValue -Value $Notes
                    $updates += "Notes = $notesValue"
                }
            }
            
            # Always update ModifiedDate
            $updates += "ModifiedDate = datetime('now')"
            
            $cattleIdValue = $cattle.CattleID
            $query = @"
UPDATE Cattle
SET $($updates -join ', ')
WHERE CattleID = $cattleIdValue
"@

            
            if ($PSCmdlet.ShouldProcess("Tag $tag", "Update cattle record")) {
                Invoke-UniversalSQLiteQuery -Path $script:DatabasePath -Query $query
                $successCount++
                Write-Verbose "Successfully updated cattle with tag $tag"
            }
        }
        catch {
            Write-Warning "Failed to update cattle with tag $tag : $($_.Exception.Message)"
            $failedCount++
            $failedTags += $tag
        }
    }
    
    # Return summary
    [PSCustomObject]@{
        TotalAttempted = $TagNumbers.Count
        SuccessCount   = $successCount
        FailedCount    = $failedCount
        FailedTags     = $failedTags
        UpdatedFields  = @($Location, $Status, $Owner, $Notes) | Where-Object { $_ } | ForEach-Object { 
            if ($Location) { "Location=$Location" }
            if ($Status) { "Status=$Status" }
            if ($Owner) { "Owner=$Owner" }
            if ($Notes) { "Notes" }
        }
    }
}