RVR.Declarations.psm1
function Send-Declaration { <# .SYNOPSIS Send the declaration using Outlook. .DESCRIPTION Send the declaration using Outlook. .PARAMETER recipient The recipient to send the declaration to .PARAMETER subject The email message subject. .PARAMETER Transactions The transactions to include in the mail message .PARAMETER SumAmount The total amount of declarations (eur) .PARAMETER SMTPSendCredential The credentials used to authenticate with the SMTP server smtp.office365.com. You're required to authenticate using your O365 credentials. An [System.Management.Automation.PSCredential] object is expected. #> [cmdletbinding()] param( $Recipient, $Bcc, $Subject = 'Parkeerdeclaraties Robert van Reems', $Transactions, $SumAmount, # The credential used for the SMTP connection [parameter(Mandatory = $true)] [System.Management.Automation.PSCredential] $SMTPSendCredential ) begin { # Compile the Message body $Body = "<HTML> Beste collega, <br></br> <br>Hierbij de declaraties van mijn parkeerkosten in Den Bosch Pettelaar park. Deze kosten zijn gemaakt voor mijn werkzaamheden bij de Volksbank.</br> <br>De transacties staan hieronder:</br> <br>$( $Transactions | ConvertTo-Html -As Table -Fragment -Property date, Amount, Description )</br> <br>Het totaal bedrag komt neer op $SumAmount Euro</br> <br></br> <br>Alvast bedankt voor het verwerken.</br> <br></br> <br>Robert van Reems</br> </HTML> " } process { # The hashtable with splatted arguments for easy reading. $HashArguments = @{ To = $Recipient Body = $Body SmtpServer = 'smtp.office365.com' From = $SMTPSendCredential.UserName Subject = $Subject Credential = $SMTPSendCredential UseSsl = $true BodyAsHtml = $true } # Add BCC recipient if param $Bcc is provided if($Bcc){ $HashArguments.Add("Bcc", $Bcc) } # Send the message Write-Verbose "Sending email message to $Recipient and BCC: $Bcc" Send-MailMessage @HashArguments -ErrorAction Stop } end { Write-Verbose 'Ending normally' } } function Get-BankTransaction { <# .SYNOPSIS The function that imports the CSV exported from the bank .DESCRIPTION The function that imports the CSV exported from the bank .PARAMETER Path Path to the CSV-file #> [cmdletbinding()] param ( [ValidateScript( { if ( -Not ($_ | Test-Path) ) { throw "File or folder does not exist" exit } return $true })] [System.IO.FileInfo]$Path ) # The predefined header for the CSV-file # TODO update columns $header = 'Date', 'Account', 'CounterAccount', 'ReadableOrgName', 'Kolom4', 'Kolom5', 'Kolom6', 'Currency', 'Kolom8', 'Currency2', 'Amount', 'Date2', 'Date3', 'Unknown', 'Unknown1', 'Unknown2', 'Unknown3', 'Description', 'Unknown4' $Transactions = [System.Collections.ArrayList]@() Write-Verbose "Importing $path" try { $Transactions += Import-Csv -Delimiter ';' -Path $Path -Header $header } catch { throw "Failed to import CSV-file $Path with error: $_" exit } Write-Verbose "Imported transactions is: $($Transactions.count)" Write-Verbose 'Filtering the transactions' $FilteredTransactions = $Transactions.Where( { $_.Description -like '*PETTELR*' -and $_.Amount -eq '-4.00' }) return $FilteredTransactions } function Test-TransactionIsDeclared { <# .SYNOPSIS Tests if the transaction is allready declared or not. .DESCRIPTION Tests if the transaction is allready declared or not. .PARAMETER Transaction The transaction to test .PARAMETER Path Path to the database file (CSV) containing allready declared transactions #> [cmdletbinding()] [OutputType([boolean])] param ( [parameter()] [ValidateNotNull()] $Transaction, [parameter()] [ValidateScript( { if ( -Not ($_ | Test-Path) ) { throw "File or folder does not exist" exit } return $true })] [System.IO.FileInfo]$Path ) begin { # Import the CSV to $Declared CSV # I'm using script scope so the contents can be cached. # Check if cache exists if (-not $Script:DeclaredTransactions) { try { Write-Verbose "Importing Declared transactions file $path" $Script:DeclaredTransactions = Import-Csv $Path } catch { throw "Failed to import declared transactions file $path with error $_ " exit } } } process { # Check if there are declared transactions if ($Script:DeclaredTransactions.count -gt 1) { # If there are declared transactions check them. if ( $Script:DeclaredTransactions.Description.Contains($transaction.Description) ) { return $true } else { return $false } } } end { } } function Get-ToDeclareTransaction { <# .SYNOPSIS This returnes the transactions that have yet to be declared. .DESCRIPTION This returnes the transactions that have yet to be declared. .PARAMETER BankTransactionsPath The path to the Bank transactions CSV file .PARAMETER DeclaredTransactionsPath Path to the database file (CSV) containing allready declared transactions #> [cmdletbinding()] param( [ValidateScript( { if ( -Not ($_ | Test-Path) ) { throw "File or folder does not exist" exit } return $true })] [System.IO.FileInfo]$BankTransactionsPath, $DeclaredTransactionsPath ) begin { # Get the Bank transactions from CSV Write-Verbose "Importing bank transactions $BankTransactionsPath" $BankTransactions = Get-BankTransaction -ErrorAction Stop -Path $BankTransactionsPath } process { # Loop through each transaction and check if it's allready declared $ToDeclareTransactions = @() foreach ($transaction in $BankTransactions) { if (Test-TransactionIsDeclared -Path $DeclaredTransactionsPath -Transaction $transaction ) { # The transaction is allready declared Write-Verbose "$($transaction.description) is allready declared." } else { Write-Verbose "$($transaction.description) is not yet declared." $ToDeclareTransactions += $transaction } } } end { $ToDeclareTransactions } } function New-Declaration { <# .SYNOPSIS Creates a new declaration email containing all the not yet declared transactions. .DESCRIPTION This function takes a CSV file from the SNS-bank to search for new transactions that have to be declared. If new declarations are found it sends them using Outlook. .PARAMETER BankTransactionsPath The path to the CSV-file exported from the bank. .PARAMETER DeclaredTransactionsPath Path to the database file (CSV) containing allready declared transactions. You should allways use the same file. .PARAMETER Recipient The recipient of the e-mail message. .PARAMETER SMTPSendCredential The credentials used to authenticate with the SMTP server smtp.office365.com. You're required to authenticate using your O365 credentials. An [System.Management.Automation.PSCredential] object is expected. .EXAMPLE Use .\test-transactions.csv as input and send the declaration. PS> New-Declaration -BankTransactionsPath .\test-transactions.csv -recipient xxx@xmail.com #> [cmdletbinding(SupportsShouldProcess=$True)] param( [parameter(Mandatory)] [ValidateScript( { if ( -Not ($_ | Test-Path) ) { throw "File or folder does not exist" exit } return $true })] [System.IO.FileInfo]$BankTransactionsPath, [System.IO.FileInfo]$DeclaredTransactionsPath, $Recipient, $Bcc, [parameter(Mandatory = $True)] [System.Management.Automation.PSCredential] $SMTPSendCredential ) Begin { Write-Verbose 'Starting New-Declaration' # Set the $DeclaredTransactionsPath if it isn't set. if( $null -eq $DeclaredTransactionsPath ){ # Set the path using my documents env var. $DeclaredTransactionsPath = ([Environment]::GetFolderPath("MyDocuments") ) # Ubuntu fix: DeclaredTransactionsPath is pointing to /home/<username>. if($DeclaredTransactionsPath -notlike "*Document*") { $DeclaredTransactionsPath = Join-Path -Path $DeclaredTransactionsPath -ChildPath 'Documents' } #Add the fileName to the $DeclaredTransactionsPath $DeclaredTransactionsPath = Join-Path -Path $DeclaredTransactionsPath -ChildPath 'MyDeclarations.csv' Write-Verbose "No DeclaredTransactionsPath declared it is set to: $DeclaredTransactionsPath" } # Create new DeclaredTransactions CSV if it doesn't exist if (-not (Test-Path $DeclaredTransactionsPath) ) { Write-Verbose 'Create new Declared transactions file' # Create the file forcefully New-Item $DeclaredTransactionsPath -Force | Out-Null } } Process { # Get the transactions that should be declared $ToDeclareTransactions = @() $ToDeclareTransactions += Get-ToDeclareTransaction -BankTransactionsPath $BankTransactionsPath -DeclaredTransactionsPath $DeclaredTransactionsPath $sum = 0 foreach ($transaction in $ToDeclareTransactions) { $sum = $sum + [int]$transaction.Amount } # Since $sum is a negative interger I'll have to convert it to positive $sum = -$sum # utilise whatif If ($PSCmdlet.ShouldProcess("Sending message")) { # If new transactions are found send the mail and update the $DeclaredTransactionsPath. if($ToDeclareTransactions.count -gt 0){ Write-Verbose "Sum of transactions (euro): $sum" # Hash table with arguments $HashArguments = @{ Transactions = $ToDeclareTransactions SumAmount = $sum recipient = $recipient SMTPSendCredential = $SMTPSendCredential } # Add BCC recipient if param $Bcc is provided if($Bcc){ $HashArguments.Add("Bcc", $Bcc) } Send-Declaration @HashArguments # TODO update $DeclaredTransactions try { Write-Verbose "Writing new transactions to $DeclaredTransactionsPath" $ToDeclareTransactions | Export-Csv -Path $DeclaredTransactionsPath -Append -ErrorAction Stop -Force } catch { throw "Failed to update $DeclaredTransactionsPath with error: $_ " Exit } } } } End { # empty cache $Script:DeclaredTransactions = $null Write-Verbose 'Ending normally' } } |