Public/Get-ProjectedTransactions.ps1
|
function Get-ProjectedTransactions { <# .SYNOPSIS Generates projected transactions based on billers and earnings. .DESCRIPTION Creates a list of projected transactions for a specified date range based on configured billers and earnings. Calculates running balance for each transaction. .PARAMETER StartDate The start date for the projection period. .PARAMETER EndDate The end date for the projection period. .PARAMETER AccountId Optional account ID to associate with transactions. .PARAMETER InitialBalance The starting balance for the projection. Defaults to 0. .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 Get-ProjectedTransactions -StartDate "2025-01-01" -EndDate "2025-03-31" .EXAMPLE Get-ProjectedTransactions -StartDate (Get-Date) -EndDate (Get-Date).AddMonths(6) -InitialBalance 1000 .EXAMPLE Get-ProjectedTransactions -StartDate "2025-01-01" -EndDate "2025-12-31" -Budget "japan-holiday-2026" .OUTPUTS Array of Transaction objects #> [CmdletBinding()] param( [Parameter(Mandatory)] [datetime]$StartDate, [Parameter(Mandatory)] [datetime]$EndDate, [Parameter()] [string]$AccountId, [Parameter()] [decimal]$InitialBalance = 0, [Parameter()] [string]$Budget, [Parameter()] [string]$DataPath ) $resolvedPath = Resolve-DataPath -DataPath $DataPath -Budget $Budget if (-not $resolvedPath) { return @() } # Get all billers and earnings $billers = Read-EntityData -EntityType 'Biller' -DataPath $resolvedPath $earnings = Read-EntityData -EntityType 'Earning' -DataPath $resolvedPath # Create transaction list $transactions = [System.Collections.ArrayList]::new() # Process earnings (positive transactions) foreach ($earning in $earnings) { $currentDate = Get-NextOccurrence -StartDate $earning.StartDate -Frequency $earning.Frequency -FromDate $StartDate while ($currentDate -le $EndDate) { $transaction = [Transaction]@{ Date = $currentDate Name = $earning.Name Amount = $earning.Amount Balance = 0 # Will calculate later Type = 'Earning' AccountId = $AccountId } $transactions.Add($transaction) | Out-Null # Get next occurrence switch ($earning.Frequency) { 'Daily' { $currentDate = $currentDate.AddDays(1) } 'Weekly' { $currentDate = $currentDate.AddDays(7) } 'BiWeekly' { $currentDate = $currentDate.AddDays(14) } 'Monthly' { $currentDate = $currentDate.AddMonths(1) } 'Bimonthly' { $currentDate = $currentDate.AddMonths(2) } 'Quarterly' { $currentDate = $currentDate.AddMonths(3) } 'Yearly' { $currentDate = $currentDate.AddYears(1) } } } } # Process billers (negative transactions) foreach ($biller in $billers) { $currentDate = Get-NextOccurrence -StartDate $biller.StartDate -Frequency $biller.Frequency -FromDate $StartDate while ($currentDate -le $EndDate) { $transaction = [Transaction]@{ Date = $currentDate Name = $biller.Name Amount = -$biller.Amount # Negative for expenses Balance = 0 # Will calculate later Type = 'Biller' AccountId = $AccountId } $transactions.Add($transaction) | Out-Null # Get next occurrence switch ($biller.Frequency) { 'Daily' { $currentDate = $currentDate.AddDays(1) } 'Weekly' { $currentDate = $currentDate.AddDays(7) } 'BiWeekly' { $currentDate = $currentDate.AddDays(14) } 'Monthly' { $currentDate = $currentDate.AddMonths(1) } 'Bimonthly' { $currentDate = $currentDate.AddMonths(2) } 'Quarterly' { $currentDate = $currentDate.AddMonths(3) } 'Yearly' { $currentDate = $currentDate.AddYears(1) } } } } # Sort transactions by date $sortedTransactions = $transactions | Sort-Object -Property Date # Add initial balance as the first entry $initialTransaction = [Transaction]@{ Date = $StartDate Name = 'Initial Balance' Amount = 0 Balance = $InitialBalance Type = 'Balance' AccountId = $AccountId } # Create final list with initial balance first $finalTransactions = [System.Collections.ArrayList]::new() $finalTransactions.Add($initialTransaction) | Out-Null # Calculate running balance for remaining transactions $runningBalance = $InitialBalance foreach ($transaction in $sortedTransactions) { $runningBalance += $transaction.Amount $transaction.Balance = $runningBalance $finalTransactions.Add($transaction) | Out-Null } return $finalTransactions } |