Public/Get-EuroExchange.ps1

<#
 
# Get-EuroExchange
 
Rechnet Euros in Nicht-Euro-Währungen gemäß den Vorgaben der EZB.
 
- **Hashtags** UserCmdlet XML Http EZB
 
- **Version** 2020.6.12
 
#>


using namespace System
using namespace System.Management.Automation
$BackupErrorActionPreference = $ErrorActionPreference
$ErrorActionPreference = [ActionPreference]::Stop
Set-StrictMode -Version 'Latest'

function Get-EuroExchange {
    <#
    .SYNOPSIS
    EZB-Währungsrechner
     
    .DESCRIPTION
    Rechnet Euros in Nicht-Euro-Währungen gem. den Vorgaben der EZB.
     
    .INPUTS
    System.String mit Währungssymbolen
    PSCustomObject mit folgenden Properties Currency <string> und Euros <decimal>
     
    .OUTPUTS
    PSCustomObject
     
    .PARAMETER Currency
    Währungssymbol der EZB.
     
    .PARAMETER Euros
    Euro-Betrag der umgerechnet werden soll.
     
    .PARAMETER ListCurrency
    Eine Übersicht aller möglichen Währungssymbole.
     
    .EXAMPLE
    Get-EuroExchange -Currency USD
    Ermittelt den Wechselkurs für US-Dollar
     
    .EXAMPLE
    Get-EuroExchange -Currency USD -Euros 100
     
    .EXAMPLE
    Get-EuroExchange -ListCurrency
     
    .EXAMPLE
    "USD", "RUB", "AUD" | Get-EuroExchange
     
    .EXAMPLE
    "USD", "RUB", "AUD" | Get-EuroExchange -Euros 100
     
    .EXAMPLE
    "USD,10", "RUB,100", "AUD,1000" | ConvertFrom-Csv -Header Currency, Euros | Get-EuroExchange
    #>

    [CmdletBinding(DefaultParameterSetName = 'Calculate')]
    param (
        [Parameter(ParameterSetName = "Calculate", Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateSet('AUD', 'BGN', 'BRL', 'CAD', 'CHF', 'CNY', 'CZK', 'DKK', 'GBP', 'HKD', 'HRK', 'HUF', 'IDR', 'ILS', 'INR', 'ISK', 'JPY', 'KRW', 'MXN', 'MYR', 'NOK', 'NZD', 'PHP', 'PLN', 'RON', 'RUB', 'SEK', 'SGD', 'THB', 'TRY', 'USD', 'ZAR')]
        [Alias("Währung")]
        [string]$Currency,

        [Parameter(ParameterSetName = "Calculate", ValueFromPipelineByPropertyName = $true)]
        [ValidateRange(0.0001, 1000000)]
        [Alias("Euronen")]
        [decimal]$Euros = 1,

        [Parameter(ParameterSetName = "Overview", Mandatory=$true)]
        [switch]$ListCurrency
    )
    begin {
        [datetime]$StartTime = Get-Date

        #region Update local cache and read it
        
        # ! Build Cachefile:
        [string]$EuroExchangeCacheFile = Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath 'EcbEuroExchangeCache.xml'

        # ! Exist Cachefile read timestamp:
        [timespan]$ECBCacheDifferenceSpan = New-TimeSpan -Hours 999
        if ((Test-Path -Path $EuroExchangeCacheFile)) {
            'ECB-EuroExchange-Cache-File found!' | Write-Verbose
            [xml]$EuroExchangeContent = Get-Content -Path $EuroExchangeCacheFile
            [datetime]$EuroExchangeTime = $EuroExchangeContent.Envelope.Cube.Cube | Select-Object -ExpandProperty 'time'
            [timespan]$ECBCacheDifferenceSpan = (Get-Date) - $EuroExchangeTime
        }

        # ! Is Cache-Difference-TimeSpan greater 39h than update from ECB:
        if($ECBCacheDifferenceSpan.TotalHours -ge 39) {
            'The ECB-EuroExchange-Cache-File is updated because the file was not found or is older than 39 hours.' | Write-Verbose
            Invoke-WebRequest -Uri "http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml" | Select-Object -ExpandProperty 'Content' | Set-Content -Path $EuroExchangeCacheFile -Force
        }

        # ! Read Cachefile for the next stapes:
        [xml]$EuroExchangeContent = Get-Content -Path $EuroExchangeCacheFile
        $EuroExchangeCubes = $EuroExchangeContent.Envelope.Cube.Cube.Cube
        "ECB-EuroExchange-Cache-File from $($EuroExchangeContent.Envelope.Cube.Cube | Select-Object -ExpandProperty 'time') read it." | Write-Verbose

        #endregion

        switch ($PSCmdlet.ParameterSetName) {
            'Overview' {
                "Get-EuroExchange works in Overview-Mode (-ListCurrency = $ListCurrency)." | Write-Verbose
                $EuroExchangeCubes | ForEach-Object -Process { [PSCustomObject]@{ Currency = $_.currency } } | Sort-Object -Property 'Currency'
            }
            'Calculate' {
                'Get-EuroExchange works in Calculate-Mode.' | Write-Verbose
            }
        }
    }
    process {
        if($PSCmdlet.ParameterSetName -eq 'Calculate') {
            [decimal]$CurrencyRate = $EuroExchangeCubes | Where-Object -Property 'currency' -EQ -Value $Currency | Select-Object -ExpandProperty 'rate'
            [PSCustomObject]@{
                Currency    = $Currency.ToUpper()
                Rate        = $CurrencyRate
                Euros       = $Euros
                SumCurrency = $CurrencyRate * $Euros
            }
        }
    }
    end {
        [timespan]$Duration = (Get-Date) - $StartTime
        "Done in $($Duration.TotalMilliseconds) ms!" | Write-Verbose
    }
}

<# ! UTest: Feature-Umfang
Get-EuroExchange -Currency USD
Get-EuroExchange -Währung USD
Get-EuroExchange -Currency USD -Euros 100
Get-EuroExchange -ListCurrency
Get-EuroExchange
"USD", "RUB", "AUD" | Get-EuroExchange
"USD", "RUB", "AUD" | Get-EuroExchange -Euros 100
"USD,10", "RUB,100", "AUD,1000" | ConvertFrom-Csv -Header Currency, Euros | Get-EuroExchange
"USD,10", "RUB,100", "AUD,1000" | ConvertFrom-Csv -Header Currency, Euros | Get-EuroExchange | Where-Object SumCurrency -GE 1000
"USD,10", "RUB,100", "AUD,1000" | ConvertFrom-Csv -Header Currency, Euros | Get-EuroExchange | Out-GridView
"USD,10", "RUB,100", "AUD,1000" | ConvertFrom-Csv -Header Währung, Euronen | Get-EuroExchange
Get-EuroExchange -ListCurrency | Get-EuroExchange -Euros 1000
Get-Help -Name Get-EuroExchange -ShowWindow
Show-Command -Name Get-EuroExchange -NoCommonParameter -ErrorPopup | Out-GridView
#>

<# ! UTEST: Validierung
Get-EuroExchange # Currency mus abgefragt werden
Get-EuroExchange -Currency USD -ListCurrency # Diese Parameter-Kombination ist nicht erlaubt
Get-EuroExchange -Euros 100 -ListCurrency # Diese Parameter-Kombination ist nicht erlaubt
Get-EuroExchange -Currency XXX # Gibt es nicht
Get-EuroExchange -Currency USD -Euros -100 # Negative Euros sind nicht erlaubt
Get-EuroExchange -Currency USD -Euros 1000001 # Größer als der max. Bereich.
Get-EuroExchange -Currency USD -Euros 0 # 0 Euros sind nicht erlaubt
Get-EuroExchange -Currency USD -Euros hundert # Nur Zahlen sind erlaubt
Get-EuroExchange -Euros 100 # Ohne Währungssymbol nicht erlaubt
Get-EuroExchange -Currency USD, RUB # Zuviel Währungen
Get-EuroExchange -Currency USD -Euros 50, 100 # Zuviel Euros
#>


$ErrorActionPreference = $BackupErrorActionPreference