Public/Export-ProjectedTransactions.ps1

function Export-ProjectedTransactions {
    <#
    .SYNOPSIS
        Exports projected transactions to a file.
 
    .DESCRIPTION
        Generates projected transactions and exports them to CSV or JSON format.
        Can export all transactions to a single file, or group by account to create
        separate files per account.
 
    .PARAMETER StartDate
        The start date for the projection period.
 
    .PARAMETER EndDate
        The end date for the projection period.
 
    .PARAMETER OutputPath
        The file path for the export. Extension determines format (.csv or .json).
        When using -GroupByAccount, this becomes the base path for multiple files.
 
    .PARAMETER Account
        Optional account name to filter transactions for a specific account.
 
    .PARAMETER InitialBalance
        The starting balance for the projection. Defaults to 0.
 
    .PARAMETER Format
        Output format: CSV or JSON. If not specified, determined by file extension.
 
    .PARAMETER GroupByAccount
        When specified, creates separate files for each account instead of one combined file.
        Files are named: {BaseName}-{AccountName}.{Extension}
        The AccountId column is excluded from individual account files (redundant).
 
    .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
        Export-ProjectedTransactions -StartDate "2025-01-01" -EndDate "2025-12-31" -OutputPath "C:\budget\2025.csv"
 
    .EXAMPLE
        Export-ProjectedTransactions -StartDate (Get-Date) -EndDate (Get-Date).AddMonths(3) -OutputPath "projection.json" -Format JSON
 
    .EXAMPLE
        Export-ProjectedTransactions -StartDate "2025-01-01" -EndDate "2025-12-31" -OutputPath "C:\budget\transactions.csv" -GroupByAccount
 
        Creates separate files like: transactions-JointBilling.csv, transactions-JointSavings.csv, etc.
 
    .EXAMPLE
        Export-ProjectedTransactions -StartDate "2025-01-01" -EndDate "2025-12-31" -OutputPath "budget.csv" -Account "Joint Billing"
 
    .OUTPUTS
        File path(s) of the exported data
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [datetime]$StartDate,

        [Parameter(Mandatory)]
        [datetime]$EndDate,

        [Parameter(Mandatory)]
        [string]$OutputPath,

        [Parameter()]
        [string]$Account,

        [Parameter()]
        [decimal]$InitialBalance = 0,

        [Parameter()]
        [ValidateSet('CSV', 'JSON')]
        [string]$Format,

        [Parameter()]
        [switch]$GroupByAccount,

        [Parameter()]
        [string]$Budget,

        [Parameter()]
        [string]$DataPath
    )

    # Determine format from file extension if not specified
    if (-not $Format) {
        $extension = [System.IO.Path]::GetExtension($OutputPath).ToLower()
        $Format = switch ($extension) {
            '.json' { 'JSON' }
            '.csv' { 'CSV' }
            default { 'CSV' }
        }
    }

    # Ensure directory exists
    $directory = Split-Path -Path $OutputPath -Parent
    if ($directory -and -not (Test-Path $directory)) {
        New-Item -Path $directory -ItemType Directory -Force | Out-Null
    }

    # Resolve data path for account lookup
    $resolvedPath = Resolve-DataPath -DataPath $DataPath -Budget $Budget
    if (-not $resolvedPath) { return }

    # Handle GroupByAccount mode
    if ($GroupByAccount) {
        $accounts = Read-EntityData -EntityType 'Account' -DataPath $resolvedPath
        
        if (-not $accounts -or $accounts.Count -eq 0) {
            Write-Warning "No accounts found. Cannot group by account."
            return
        }

        $exportedPaths = @()
        $baseName = [System.IO.Path]::GetFileNameWithoutExtension($OutputPath)
        $extension = [System.IO.Path]::GetExtension($OutputPath)
        $outputDir = Split-Path -Path $OutputPath -Parent
        if (-not $outputDir) { $outputDir = '.' }

        foreach ($acct in $accounts) {
            # Get transactions for this specific account
            $transactions = Get-ProjectedTransactions -StartDate $StartDate -EndDate $EndDate -Account $acct.Name -InitialBalance $InitialBalance -Budget $Budget -DataPath $DataPath

            if ($transactions -and $transactions.Count -gt 1) {  # More than just initial balance
                # Sanitize account name for filename
                $safeAccountName = $acct.Name -replace '[^\w\-]', ''
                $accountFilePath = Join-Path $outputDir "$baseName-$safeAccountName$extension"

                try {
                    switch ($Format) {
                        'CSV' {
                            # Exclude AccountId column since each file is account-specific
                            $transactions | Select-Object Date, Name, Amount, Balance, Type |
                                Export-Csv -Path $accountFilePath -NoTypeInformation -ErrorAction Stop
                            Write-Verbose "Exported $($acct.Name) to CSV: $accountFilePath"
                        }
                        'JSON' {
                            $transactions | Select-Object Date, Name, Amount, Balance, Type |
                                ConvertTo-Json -Depth 10 |
                                Set-Content -Path $accountFilePath -ErrorAction Stop
                            Write-Verbose "Exported $($acct.Name) to JSON: $accountFilePath"
                        }
                    }
                    $exportedPaths += (Resolve-Path $accountFilePath).Path
                }
                catch {
                    Write-Error "Failed to export transactions for account '$($acct.Name)': $_"
                }
            }
        }

        return $exportedPaths
    }

    # Standard single-file export
    $getParams = @{
        StartDate = $StartDate
        EndDate = $EndDate
        InitialBalance = $InitialBalance
    }
    if ($Account) { $getParams['Account'] = $Account }
    if ($Budget) { $getParams['Budget'] = $Budget }
    if ($DataPath) { $getParams['DataPath'] = $DataPath }

    $transactions = Get-ProjectedTransactions @getParams

    # Export based on format
    try {
        switch ($Format) {
            'CSV' {
                # Include AccountId if not filtering by account (might have mixed accounts)
                if ($Account) {
                    $transactions | Select-Object Date, Name, Amount, Balance, Type |
                        Export-Csv -Path $OutputPath -NoTypeInformation -ErrorAction Stop
                } else {
                    $transactions | Select-Object Date, Name, Amount, Balance, Type, AccountId |
                        Export-Csv -Path $OutputPath -NoTypeInformation -ErrorAction Stop
                }
                Write-Verbose "Exported to CSV: $OutputPath"
            }
            'JSON' {
                if ($Account) {
                    $transactions | Select-Object Date, Name, Amount, Balance, Type |
                        ConvertTo-Json -Depth 10 |
                        Set-Content -Path $OutputPath -ErrorAction Stop
                } else {
                    $transactions | ConvertTo-Json -Depth 10 |
                        Set-Content -Path $OutputPath -ErrorAction Stop
                }
                Write-Verbose "Exported to JSON: $OutputPath"
            }
        }

        return (Resolve-Path $OutputPath).Path
    }
    catch {
        Write-Error "Failed to export transactions: $_"
    }
}