Public/Set-Transfer.ps1

function Set-Transfer {
    <#
    .SYNOPSIS
        Updates an existing transfer entry.
 
    .DESCRIPTION
        Modifies properties of an existing transfer identified by ID.
 
    .PARAMETER Id
        The ID of the transfer to update.
 
    .PARAMETER Name
        New name for the transfer.
 
    .PARAMETER StartDate
        New start date for the transfer.
 
    .PARAMETER Frequency
        New frequency for the transfer.
 
    .PARAMETER Amount
        New amount for the transfer.
 
    .PARAMETER FromAccount
        New source account name for the transfer.
 
    .PARAMETER ToAccount
        New destination account name for the transfer.
 
    .PARAMETER Budget
        Optional budget name to target. Uses active budget if not specified.
 
    .PARAMETER DataPath
        Optional custom path for data storage. Overrides budget-based paths.
 
    .EXAMPLE
        Set-Transfer -Id "abc123" -Amount 150.00
 
    .EXAMPLE
        Set-Transfer -Id "abc123" -FromAccount "New Checking"
 
    .OUTPUTS
        Updated Transfer object
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory, ValueFromPipelineByPropertyName)]
        [string]$Id,

        [Parameter()]
        [string]$Name,

        [Parameter()]
        [datetime]$StartDate,

        [Parameter()]
        [ValidateSet('Daily', 'Weekly', 'BiWeekly', 'Monthly', 'Bimonthly', 'Quarterly', 'Yearly')]
        [string]$Frequency,

        [Parameter()]
        [decimal]$Amount,

        [Parameter()]
        [string]$FromAccount,

        [Parameter()]
        [string]$ToAccount,

        [Parameter()]
        [string]$Budget,

        [Parameter()]
        [string]$DataPath
    )

    process {
        $resolvedPath = Resolve-DataPath -DataPath $DataPath -Budget $Budget
        if (-not $resolvedPath) { return }

        $transfers = Read-EntityData -EntityType 'Transfer' -DataPath $resolvedPath
        $transfer = $transfers | Where-Object { $_.Id -eq $Id }

        if (-not $transfer) {
            Write-Error "Transfer with ID '$Id' not found."
            return
        }

        if ($PSBoundParameters.ContainsKey('Name')) { $transfer.Name = $Name }
        if ($PSBoundParameters.ContainsKey('StartDate')) { $transfer.StartDate = $StartDate }
        if ($PSBoundParameters.ContainsKey('Frequency')) { $transfer.Frequency = $Frequency }
        if ($PSBoundParameters.ContainsKey('Amount')) { $transfer.Amount = $Amount }
        
        if ($PSBoundParameters.ContainsKey('FromAccount')) {
            $accounts = Read-EntityData -EntityType 'Account' -DataPath $resolvedPath
            $fromAccountObj = $accounts | Where-Object { $_.Name -eq $FromAccount }
            
            if (-not $fromAccountObj) {
                Write-Error "Source account '$FromAccount' not found."
                return
            }
            $transfer.FromAccountId = $fromAccountObj.Id
        }
        
        if ($PSBoundParameters.ContainsKey('ToAccount')) {
            $accounts = Read-EntityData -EntityType 'Account' -DataPath $resolvedPath
            $toAccountObj = $accounts | Where-Object { $_.Name -eq $ToAccount }
            
            if (-not $toAccountObj) {
                Write-Error "Destination account '$ToAccount' not found."
                return
            }
            $transfer.ToAccountId = $toAccountObj.Id
        }

        # Validate accounts are different if both were changed
        if ($transfer.FromAccountId -eq $transfer.ToAccountId) {
            Write-Error "Source and destination accounts must be different."
            return
        }

        if (Write-EntityData -EntityType 'Transfer' -Data $transfers -DataPath $resolvedPath) {
            Write-Verbose "Updated transfer: $($transfer.Name)"
            return $transfer
        }
    }
}