Weedu.psm1

$script:hostUrl = $null;
$script:sessionVar = $null;
$script:logonUser = $null;
$script:forceSync = $false;

function ConvertTo-WeeduGuid {
    param(
        [Parameter(ValueFromPipeline, Mandatory, HelpMessage = "Objekt für welches die Guid aufgelöst werden soll")]
        $data
    )
    process {
        return [string]::Join(",", [array]($data | ForEach-Object {
                    $member = $_ | Get-Member | Where-Object { $_.Name -in ("idb_uid", "UID", "aktualisierteEntitaeten") } | Select-Object -First 1;
                    if ($member) {
                        return $_ | Select-Object -ExpandProperty $member.Name | ConvertTo-WeeduGuid;
                    }
                    if ($_ -is [string] -and $_.StartsWith('!')) {
                        $sha1 = New-Object "System.Security.Cryptography.SHA1Managed";
                        $hash = $sha1.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($_));
                        $guidBytes = [System.Array]::CreateInstance($hash[0].GetType(), 16);
                        [System.Array]::Copy($hash, $guidBytes, 16);
                        return New-Object -typename "System.Guid" -argumentlist (, $guidBytes);
                    }
                    return $_;
                }));
    }
}

function ConvertTo-WeeduDateString {
    param(
        [Parameter(ValueFromPipeline, Mandatory, HelpMessage = "Objekt welches in das Standard-Datumsformat umgewandelt werden soll")]
        $data
    )
    process {
        if ($data -is [System.DateTime]) {
            return $data.ToString("yyyy-MM-dd", [System.Globalization.CultureInfo]::InvariantCulture);
        }
        return [string]$data;
    }
}

function ConvertTo-WeeduPriorityList {
    param(
        [Parameter(Mandatory)]
        $items
    )
    return [array]($items | ForEach-Object { $i = 1 } { [PSCustomObject]@{ "Element" = $_; "Prioritaet" = $i++; } } );
}

function AsString($data) {
    if ($data -is [byte[]]) {
        return [System.Text.Encoding]::UTF8.GetString($data);
    }
    return [string]$data;
}

function Test-EntityExistsInIndex {
    param(
        [Parameter(Mandatory)]
        $uid
    )
    process {
        $EntityUid = ConvertTo-WeeduGuid $uid;
        $WqlString = 'Alles mit uid = "' + $EntityUid + '"';
        $Result = Invoke-WqlQuery -WQLAbfrage $WqlString 3>$null 6>$null;
        if ($Result -ne $null) {
            return $true;
        }
        return $false;
    }
}

function Get-Sicherheitseinstellung {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, Position = 0, ValueFromPipeline)]
        $entitaetUid
    )
    process {
        return (Invoke-Weedu "rest/Sicherheitseinstellungen/{0}" -UriParams @(($entitaetUid | ConvertTo-WeeduGuid)))
    }
}

function New-Sicherheitseinstellung-Object {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, Position = 0)]
        [string]$Dateneigentuemer
    )
    process {
        return [PSCustomObject]@{
            Dateneigentuemer = $Dateneigentuemer;
            Gruppen          = @();
        }
    }
}

function Add-SicherheitseinstellungGruppe {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, ValueFromPipeline)]
        [PSCustomObject]$Sicherheitseinstellung,
        [Parameter(Mandatory, Position = 0)]
        [string]$Gruppe,
        [Parameter(Mandatory, Position = 1)]
        [string]$Stufe
    )
    process {
        $Sicherheitseinstellung.Gruppen += [PSCustomObject]@{
            Gruppe = $Gruppe;
            Stufe  = $Stufe;
        };
        return $Sicherheitseinstellung;
    }
}

function Test-IsWeeduConnected {
    process {
        if (!$script:sessionVar) {
            return $false;
        }
        return $true;
    }
}

function Connect-Weedu {
    [CmdletBinding(DefaultParameterSetName = "UsernamePassword")]
    param(
        [Parameter(Mandatory, Position = 0, ParameterSetName = "UsernamePassword")]
        [string]$Benutzername,
        [Parameter(Mandatory, ParameterSetName = "UsernamePassword")]
        [securestring]$Kennwort,
        [Parameter(Mandatory, Position = 0, ParameterSetName = "Credential")]
        [pscredential]$Credential,
        [Parameter(Mandatory, Position = 1, HelpMessage = "Url zu welcher die Verbindung hergestellt werden soll. Bsp.: https://akad-de.test-weedu.ch")]
        [string]$HostUrl
    )
    process {
        if (-not $PSBoundParameters.ContainsKey("Credential")) {
            $Credential = [System.Management.Automation.PSCredential]::new($Benutzername, $Kennwort);
        }
        $networkCreds = $Credential.GetNetworkCredential();
        $encodedCreds = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("$($networkCreds.UserName):$($networkCreds.Password)"));
        $basicAuthValue = "Basic $encodedCreds";

        $Headers = @{
            Accept        = "application/json, text/javascript, */*"
            Authorization = $basicAuthValue
        };

        if (-not [regex]::IsMatch($HostUrl, "^[^./\\:]+:")) {
            $HostUrl = "https://" + ($HostUrl.TrimStart('/'));
            Write-Verbose "URL mit Protokoll erweitert: $HostUrl";
        }

        [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12;
        try {
            $response = Invoke-WebRequest -Uri "$($HostUrl)/sts/authentication" -Method POST -Headers $Headers -SessionVariable session;
        }
        catch [System.Net.WebException] {
            if ($_.Exception.Response) {
                $responseStream = $_.Exception.Response.GetResponseStream();
                if ($responseStream.CanSeek) {
                    $responseStream.Seek(0, [System.IO.SeekOrigin]::Begin) | Out-Null;
                }
                $response = [Microsoft.PowerShell.Commands.WebResponseObject]::new($_.Exception.Response, $responseStream);
            }
            else {
                $response = [PSCustomObject]@{
                    StatusDescription = $_.Exception.Message;
                    Headers           = @{};
                };
            }
        }

        $script:logonUser = $response.Headers["X-Weedu-Portal-UserId"];

        if ($response.StatusCode -eq 200 -and $script:logonUser) {
            $script:sessionVar = $session;
            $script:hostUrl = $HostUrl.TrimEnd("/");
            Write-Information "Login als $script:logonUser an $script:hostUrl erfolgreich" -InformationAction Continue;
        }
        else {
            $script:sessionVar = $null;
            $script:hostUrl = $null;
            Write-Error "Login Fehlgeschlagen ($($response.StatusDescription)), bitte erneut versuchen" -TargetObject ($response.RawContent) -ErrorAction Stop;
        }
    }
}

function Disconnect-Weedu {
    [CmdletBinding()]
    param()
    process {
        $script:sessionVar = $null;
        $script:hostUrl = $null;
    }
}

function Invoke-ProcessIndexUpdates {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, HelpMessage = "Uids oder Objekte, für die im Index hängige Aktualisierungen abgearbeitet werden sollen.")]
        [array]$itemsToUpdate
    )
    process {
        $body = [PSCustomObject]@{ EntitaetUids = ($itemsToUpdate | % { $_ | ConvertTo-WeeduGuid }) };
        Invoke-Weedu -Uri "/rest/SolrIndex/RebuildSolrDocument?sync" -Body $body -Method POST
    }
}

function AddSyncSuffixIfNeeded([string]$url) {
    if ($script:forceSync) {
        if ($url.IndexOf('?') -gt 0) {
            return "$url&sync";
        }
        return "$($url)?sync";
    }
    return $url;
}

function Invoke-Weedu {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, HelpMessage = "URI ohne Host für Weedu-Request, kann Platzhalter enthalten: {0}")]
        [string]$Uri,
        [Parameter(HelpMessage = "Ersetzungen für Platzhalter der URI")]
        [object[]]$UriParams,
        [string]$Method = "GET",
        [object]$Body,
        [switch]$StatusOnly
    )
    process {
        if (!$script:sessionVar) {
            Write-Error "Weedu Anmeldung ist erforderlich: Connect-Weedu" -ErrorAction Stop;
            break;
        }
        if ($UriParams) {
            $Uri = [string]::Format($Uri, [array]($UriParams | ForEach-Object { if ([string]::IsNullOrEmpty($_)) { "" } else { [uri]::EscapeDataString([System.Convert]::ToString($_, [cultureinfo]::InvariantCulture)) }}));
        }
        $Uri = AddSyncSuffixIfNeeded("$($script:hostUrl)/$($Uri.TrimStart("/"))");

        $Headers = @{
            Accept = "application/json, text/javascript, */*"
        }

        try {
            if ($Body) {
                $Body = ConvertTo-JSON -Compress -Depth 100 $Body;
                Write-Verbose "Weedu-Request Body: $Body";
                $response = Invoke-WebRequest -Uri $Uri -Method $Method -Headers $Headers -WebSession $script:sessionVar -Body ([System.Text.Encoding]::UTF8.GetBytes($Body)) -ContentType "application/json; charset=utf-8" -TimeoutSec 3600;
            }
            else {
                $response = Invoke-WebRequest -Uri $Uri -Method $Method -Headers $Headers -WebSession $script:sessionVar -TimeoutSec 3600;
            }
        }
        catch [System.Net.WebException] {
            $responseStream = $_.Exception.Response.GetResponseStream();
            if ($responseStream.CanSeek) {
                $responseStream.Seek(0, [System.IO.SeekOrigin]::Begin) | Out-Null;
            }
            $response = [Microsoft.PowerShell.Commands.WebResponseObject]::new([System.Net.WebResponse]($_.Exception.Response), $responseStream);
        }
        Write-Verbose "Weedu-Request: $Method $Uri => $($response.StatusCode) $($response.StatusDescription)";

        if ($StatusOnly) {
            $result = $response.StatusCode;
        }
        else {
            $responseContentType = $response.Headers.'Content-Type';
            if (-not $responseContentType) {
                $responseContentType = "application/json";
            }
            $responseContentType = $responseContentType.Split(";")[0].Trim();

            switch ($responseContentType) {
                "application/json" {
                    $result = (AsString($response.Content)) | ConvertFrom-Json;
                }
                "text/xml" {
                    $result = [xml](AsString($response.Content));
                }
                default {
                    $result = AsString($response.Content);
                }
            }

            if ($response.StatusCode -ge 300) {
                Write-Warning -Message $result;
                if ($result.errors) {
                    $result.errors | ForEach-Object { Write-Warning $_ }
                }
                Write-Error -Message "Weedu-Request $Method $Uri nicht erfolgreich: $($response.StatusCode) $($response.StatusDescription)" -TargetObject $result -ErrorAction Stop;
                break;
            }
        }
        return $result;
    }
}

function Invoke-WqlQuery {
    [CmdletBinding(SupportsPaging, DefaultParameterSetName = "Paged")]
    param(
        [Parameter(Mandatory, HelpMessage = "WQL Abfrage. Bsp: Personen [ohne Aktionen]", ValueFromPipeline, Position = 0)]
        [string]$WQLAbfrage,
        [Parameter(HelpMessage = "Default 1", ParameterSetName = "Paged")]
        [int]$Page = 1,
        [Parameter(HelpMessage = "Default 100", ParameterSetName = "Paged")]
        [int]$PageSize = 100,
        [Parameter(HelpMessage = "Default 1", ParameterSetName = "Paged")]
        [int]$PageCount = 1,
        [Parameter(HelpMessage = "Automatisches Paging für alle Einträge", ParameterSetName = "Auto")]
        [switch]$Auto
    )
    process {
        if ($Page -le 0) {
            Write-Error "$($Page) ist kein gueltiger Wert fuer Page! Bitte ein Wert groesser 0 eingeben" -ErrorAction Stop;
            break;
        }
        if ($PageSize -le 0) {
            Write-Error "$($PageSize) ist kein gueltiger Wert fuer PageSize! Bitte ein Wert groesser 0 eingeben" -ErrorAction Stop;
            break;
        }
        if ($PageCount -le 0) {
            Write-Error "$($PageCount) ist kein gueltiger Wert fuer PageCount! Bitte ein Wert groesser 0 eingeben" -ErrorAction Stop;
            break;
        }
        $skip = $PSCmdlet.PagingParameters.Skip;
        $first = [math]::Min($PSCmdlet.PagingParameters.First, [int]::MaxValue);
        if ($Auto) {
            $PageSize = [math]::Min(100, $skip + $first);
            $PageCount = [int]::MaxValue;
        }
        $Page = $Page + [int]([math]::Floor($PSCmdlet.PagingParameters.Skip / $PageSize));
        $PageCount = $PageCount - [int]($PSCmdlet.PagingParameters.Skip / $PageSize);
        if ($PageCount -le 0) {
            Write-Error "Die angegebenen Parameter führen immer zu 0 Resultaten";
            break;
        }
        $skip = $skip % $PageSize;
        $result = Invoke-Weedu -Uri "/index/Abfragen/IndexData?auswahlSpalte=false&wql={0}" -UriParams @($WQLAbfrage) -Method POST -Body ([PSCustomObject]@{ page = $Page; pageSize = $PageSize; });
        $count = $result.result.Total;
        if ($count -eq 0 -or $result.result.data.Count -eq 0) {
            Write-Warning "Die Abfrage lieferte keine Ergebnisse"
        }
        else {
            $elementVon = ($Page - 1) * $PageSize + 1 + $skip;
            $elementBis = [math]::Min($Page * $PageSize * $PageCount, [math]::Min($PSCmdlet.PagingParameters.Skip + $first, $count));
            Write-Information "$elementVon - $elementBis von $($count) Elementen" -InformationAction Continue;
        }
        if ($PSCmdlet.PagingParameters.IncludeTotalCount) {
            Write-Output $PSCmdlet.PagingParameters.NewTotalCount($count, 1.0);
        }
        if ($result.result.data.Count -gt 0) {
            $result.result.data | Select-Object -Skip $skip -First ([Math]::Min($first, [int]::MaxValue));
            $first = $first - ($PageSize - $skip);
            $Page++;
            $PageCount--;
            while (($first -gt 0) -and ($PageCount -gt 0) -and ($result.result.Data.Count -ge $PageSize)) {
                $result = Invoke-Weedu -Uri "/index/Abfragen/IndexData?auswahlSpalte=false&wql={0}" -UriParams @($WQLAbfrage) -Method POST -Body ([PSCustomObject]@{ page = $Page; pageSize = $PageSize; });
                $result.result.data | Select-Object -First ([Math]::Min($first, [int]::MaxValue));
                $first = $first - $PageSize;
                $Page++;
                $PageCount--;
            }
        }
    }
}

function Invoke-WeeduSearch {
    [CmdletBinding(SupportsPaging, DefaultParameterSetName = "Paged")]
    param(
        [Parameter(Mandatory, HelpMessage = "Suchtext", ValueFromPipeline, Position = 0)]
        [string]$query,
        [Parameter(HelpMessage = "WQL-Einschränkung")]
        [string]$wql
    )
    process {
        $result = Invoke-Weedu -Uri "/index/search/GetData" -Method POST -Body ([PSCustomObject]@{ q = $query; page = 1; pageSize = 20; wql = $wql });
        $count = $result.Total;
        if ($count -eq 0 -or $result.Data.Count -eq 0) {
            Write-Warning "Die Suche lieferte keine Ergebnisse"
        } else {
            $result.Data
        }
    }
}

function Get-PersonenMapping {
    param(
        [Parameter(Mandatory, ValueFromPipeline, HelpMessage = "Uid der Person des Personenmappings.")]
        $PersonUid,
        [Parameter(Mandatory, ValueFromPipeline, HelpMessage = "MandantenNummer des Mandanten des Personenmappings.")]
        $MandantenNummer
    )
    process {
        $PersonUid = ConvertTo-WeeduGuid $PersonUid;
        Invoke-Weedu -Uri "rest/Personen/{0}/AbacusMandanten/{1}" -UriParams @($PersonUid, $MandantenNummer) -Method GET;
    }
}


function Set-PersonenMapping {
    [CmdletBinding(DefaultParameterSetName = "KundennummerExplizit")]
    param(
        [Parameter(Mandatory, HelpMessage = "WeeduUid der Person", ValueFromPipeline)]
        [Guid]$PersonUid,
        [Parameter(Mandatory, HelpMessage = "Nummer des AbacusMandanten")]
        [int]$MandantenNummer,
        [Parameter(ParameterSetName = "KundennummerExplizit")]
        $KundenNummer,
        [Parameter(ParameterSetName = "KundennummerGeneriert")]
        [switch]$GeneriereKundenNummer,
        [Parameter()]
        $AdressNummer,
        [Parameter()]
        $ADLoginName,
        [Parameter(HelpMessage = "Flag, ob die Rechnungen von diesem Mandant auch per Email zugestellt werden sollen")]
        [boolean]$RechnungszustellungPerEMail,
        [Parameter(HelpMessage = "String array mit den EMailadressen für die Rechnungszustellung")]
        $ZustellEmailAdressListe,
        [Parameter(HelpMessage = "Flag um zu verhindern das der Kunde die Rechnungen von diesem Mandant auf Papier erhält")]
        [boolean]$PapierrechnungUnterdruecken
    )
    process {
        if (-not ($GeneriereKundenNummer -or $PSBoundParameters.ContainsKey("KundenNummer") -or $PSBoundParameters.ContainsKey("AdressNummer") -or $PSBoundParameters.ContainsKey("ADLoginName"))) {
            Write-Error "KundenNummer/AdressNummer/AdLoginName, mindestens ein Parameter ist erforderlich." -ErrorAction Stop;
            return;
        }
        $Body = New-Object PSCustomObject
        if ($PSBoundParameters.ContainsKey("ADLoginName")) {
            $Body | Add-Member NoteProperty ADUserLogonName $ADLoginName;
        }
        if ($PSBoundParameters.ContainsKey("AdressNummer")) {
            $Body | Add-Member NoteProperty AbacusAdressnummer $AdressNummer;
        }
        if ($PSBoundParameters.ContainsKey("KundenNummer")) {
            $Body | Add-Member NoteProperty AbacusKundennummer $KundenNummer;
        }
        if ($GeneriereKundenNummer) {
            $Body | Add-Member NoteProperty GeneriereKundennummer $True;
        }
        if ($PSBoundParameters.ContainsKey("ZustellEmailAdressListe")) {
            [array]$List = ConvertTo-WeeduPriorityList $ZustellEmailAdressListe;
            if ($null -eq $List) {
                $list = @();
            }
            $Body | Add-Member -MemberType NoteProperty -Name "ZustellEmailAdressListe" -Value $List;
        }
        if($PSBoundParameters.ContainsKey("RechnungszustellungPerEMail")){
            $Body | Add-Member -MemberType NoteProperty -Name "RechnungszustellungPerEMail" -Value $RechnungszustellungPerEMail;
        }
        if($PSBoundParameters.ContainsKey("PapierrechnungUnterdruecken")){
            $Body | Add-Member -MemberType NoteProperty -Name "PapierrechnungUnterdruecken" -Value $PapierrechnungUnterdruecken;
        }

        return Invoke-Weedu -Uri "/rest/Personen/{0}/AbacusMandanten/{1}" -UriParams @($PersonUid, $MandantenNummer) -Method PUT -Body $Body;
    }
}

function New-IndexRegel {
    [CmdletBinding(DefaultParameterSetName = "File")]
    param(
        [Parameter(Mandatory, HelpMessage = "Uid der Regel, empfohlen ist eine Well-Known-UID: !RegelName", Position = 0)]
        [string]$RegelUid,
        [Parameter(Mandatory, Position = 1)]
        [string]$RegelTyp,
        [Parameter(Mandatory, Position = 2)]
        [string]$Bezeichnung,
        [Parameter(Mandatory, Position = 3)]
        [string]$Beschreibung,
        [Parameter(Mandatory, HelpMessage = "Logik der Regel (Razor), z.B. als Here-String", ParameterSetName = "Content")]
        [string]$Logik,
        [Parameter(Mandatory, HelpMessage = "Logik der Regel (Razor) aus einer Datei", ValueFromPipeline, ParameterSetName = "File")]
        $LogikFile,
        [Parameter(Mandatory, HelpMessage = "Sicherheitseinstellung (erstellt z.B. mit New-Sicherheitseinstellung-Object)", Position = 4)]
        [PSCustomObject]$SicherheitsEinstellung
    )
    process {
        if ($PSBoundParameters.ContainsKey("LogikFile")) {
            $Logik = [string](Get-Content $LogikFile -Encoding UTF8 -Raw);
        }
        $Body = [PSCustomObject]@{
            Uid                    = ConvertTo-WeeduGuid $RegelUid;
            RegelTyp               = $RegelTyp;
            Bezeichnung            = $Bezeichnung;
            Beschreibung           = $Beschreibung;
            Logik                  = $Logik;
            Sicherheitseinstellung = $SicherheitsEinstellung;
        };
        return Invoke-Weedu -Uri "/rest/Regeln" -UriParams @() -Method POST -Body $Body;
    }
}

function Set-IndexRegel {
    [CmdletBinding(DefaultParameterSetName = "File")]
    param(
        [Parameter(Mandatory, HelpMessage = "Uid der Regel, z.B. eine Well-Known-UID: !RegelName", Position = 0)]
        [string]$RegelUid,
        [Parameter(Position = 1)]
        [string]$Bezeichnung,
        [Parameter(Position = 2)]
        [string]$Beschreibung,
        [Parameter(HelpMessage = "Logik der Regel (Razor), z.B. als Here-String", ParameterSetName = "Content")]
        [string]$Logik,
        [Parameter(HelpMessage = "Logik der Regel (Razor) aus einer Datei", ValueFromPipeline, ParameterSetName = "File")]
        $LogikFile
    )
    process {
        $Body = [PSCustomObject]@{};
        if ($PSBoundParameters.ContainsKey("Bezeichnung")) {
            $Body | Add-Member NoteProperty Bezeichnung $Bezeichnung;
        }
        if ($PSBoundParameters.ContainsKey("Beschreibung")) {
            $Body | Add-Member NoteProperty Beschreibung $Beschreibung;
        }
        if ($PSBoundParameters.ContainsKey("LogikFile")) {
            $Body | Add-Member NoteProperty Logik ([string](Get-Content $LogikFile -Encoding UTF8 -Raw));
        }
        if ($PSBoundParameters.ContainsKey("Logik")) {
            $Body | Add-Member NoteProperty Logik $Logik;
        }
        return Invoke-Weedu -Uri "/rest/Regeln/{0}" -UriParams @(ConvertTo-WeeduGuid $RegelUid) -Method PUT -Body $Body;
    }
}

function Get-IndexRegel {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, ValueFromPipeline, HelpMessage = "Uid der Regel, z.B. eine Well-Known-UID: !RegelName", Position = 0)]
        [string]$RegelUid
    )
    process {
        return Invoke-Weedu -Uri "/rest/Regeln/{0}" -UriParams @(ConvertTo-WeeduGuid $RegelUid) -Method GET;
    }
}

function Invoke-RechnungStorno {
    [CmdletBinding(DefaultParameterSetName = "UID")]
    param(
        [Parameter(Mandatory, HelpMessage = "Uid der Rechnung", ValueFromPipeline, ParameterSetName = "UID", Position = 0)]
        [Guid]$RechnungUid,
        [Parameter(Mandatory, HelpMessage = "Mandantennummer der Rechnung", ValueFromPipelineByPropertyName, ParameterSetName = "Nummer", Position = 0)]
        [int]$MandantenNummer,
        [Parameter(Mandatory, HelpMessage = "Rechnungsnummer", ValueFromPipelineByPropertyName, ParameterSetName = "Nummer", Position = 1)]
        $RechnungsNummer,
        [Parameter(HelpMessage = "Bemerkung zur Stornierung")]
        [string]$Bemerkung,
        [Parameter(HelpMessage = "Die Rechnung wird neu erstellt, ohne Freigabe zur Verrechnung")]
        [bool]$ErneutVerrechnen,
        [Parameter(HelpMessage = "Das Fibudatum wird nicht auf der neu erstellten Rechnung übernommen")]
        [bool]$FibuDatumLoeschen
    )
    process {
        $Body = [PSCustomObject]@{
            Bemerkung = $Bemerkung
        };
        if ($PSBoundParameters.ContainsKey("ErneutVerrechnen")) {
            $Body | Add-Member -MemberType NoteProperty -Name "ErneutVerrechnen" -Value $ErneutVerrechnen;
        }
        if ($PSBoundParameters.ContainsKey("FibuDatumLoeschen")) {
            $Body | Add-Member -MemberType NoteProperty -Name "FibuDatumLoeschen" -Value $FibuDatumLoeschen;
        }

        if ($RechnungUid) {
            if ($MandantenNummer -or $RechnungsNummer) {
                Write-Error "Bei Angabe einer RechnungsUid kann keine MandantenNummer oder RechnungsNummer angegeben werden" -ErrorAction Stop;
                break;
            }
            return Invoke-Weedu -Uri "/rest/Rechnungen/{0}/Stornieren" -UriParams @($RechnungUid) -Method POST -Body $Body;
        }
        elseif ([bool]$MandantenNummer -and [bool]$RechnungsNummer) {
            return Invoke-Weedu -Uri "/rest/Rechnungen/{0}/{1}/Stornieren" -UriParams @($MandantenNummer, $RechnungsNummer) -Method POST -Body $Body;
        }
        else {
            Write-Error "Entweder nur RechnungsUid oder aber MandantenNummer und RechnungsNummer müssen angegeben werden" -ErrorAction Stop;
            break;
        }
    }
}

function Invoke-RechnungErneutVerrechnen {
    [CmdletBinding(DefaultParameterSetName = "UID")]
    param(
        [Parameter(Mandatory, HelpMessage = "Uid der Rechnung", ValueFromPipeline, ParameterSetName = "UID", Position = 0)]
        [Guid]$RechnungUid,
        [Parameter(Mandatory, HelpMessage = "Mandantennummer der Rechnung", ValueFromPipelineByPropertyName, ParameterSetName = "Nummer", Position = 0)]
        [int]$MandantenNummer,
        [Parameter(Mandatory, HelpMessage = "Rechnungsnummer", ValueFromPipelineByPropertyName, ParameterSetName = "Nummer", Position = 1)]
        $RechnungsNummer,
        [Parameter(HelpMessage = "Optionale explizite Angabe von Verrechnen Ab")]
        $VerrechnenAb,
        [Parameter(HelpMessage = "Optionale explizite Angabe von Ausloesen Bis")]
        $AusloesenBis
    )
    process {
        if ($RechnungUid) {
            if ($MandantenNummer -or $RechnungsNummer) {
                Write-Error "Bei Angabe einer RechnungsUid kann keine MandantenNummer oder RechnungsNummer angegeben werden" -ErrorAction Stop;
                break;
            }
            $rechnung = Invoke-Weedu -Uri "/rest/Rechnungen/{0}" -UriParams @($RechnungUid) -Method GET;
        }
        elseif ([bool]$MandantenNummer -and [bool]$RechnungsNummer) {
            $rechnung = Invoke-Weedu -Uri "/rest/Rechnungen/{0}/{1}" -UriParams @($MandantenNummer, $RechnungsNummer) -Method GET;
        }
        else {
            Write-Error "Entweder nur RechnungsUid oder aber MandantenNummer und RechnungsNummer müssen angegeben werden" -ErrorAction Stop;
            break;
        }

        $Body = New-Object PSCustomObject;
        if ($VerrechnenAb) {
            $Body | Add-Member -MemberType NoteProperty -Name "VerrechnenAb" -Value $VerrechnenAb;
        }
        if ($AusloesenBis) {
            $Body | Add-Member -MemberType NoteProperty -Name "AusloesenBis" -Value $AusloesenBis;
        }

        Write-Output "Rechnung $($rechnung.Rechnungsnummer) (Referenz $($rechnung.ReferencePurchaseOrder)) an $($rechnung.RechnungsempfaengerBezeichnung) wird erneut verrechnet"
        foreach ($quellSystem in $rechnung.Rechnungspositionen | ForEach-Object { $_.QuellSystem } | Sort-Object | Get-Unique) {
            $rechnungsPositionen = [string]::Join(",", ($rechnung.Rechnungspositionen | Where-Object { $_.QuellSystem -eq $quellSystem } | ForEach-Object { [guid]$_.ShipmentItemUid }));
            Write-Verbose "Quellsystem: $quellSystem, Positionen: $rechnungsPositionen";
            switch ($quellSystem) {
                "CommerceCH" {
                    Invoke-Weedu -Uri "/commerce-ch/rest/ShipmentItems/ErneutVerrechnen?uids={0}" -UriParams @($rechnungsPositionen) -Method POST -Body $Body;
                }
                "CommerceDE" {
                    Invoke-Weedu -Uri "/commerce-de/rest/ShipmentItems/ErneutVerrechnen?uids={0}" -UriParams @($rechnungsPositionen) -Method POST -Body $Body;
                }
                default {
                    Write-Warning "Reschnungspositionen des unbekannten Quellsystems $quellSystem werden nicht erneut verrechnet";
                }
            }
        }
    }
}

function Invoke-RechnungVersendenPerMail {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory, HelpMessage = "Uid der Rechnung", ValueFromPipeline)]
        [string]$RechnungUid,
        [Parameter(Mandatory, HelpMessage = "String array mit den EMailadressen für die Rechnungszustellung")]
        $ZustellEmailAdressListe
    )
    process {
        $RechnungUid = ConvertTo-WeeduGuid $RechnungUid;
        [array]$List = $ZustellEmailAdressListe;
        if ($null -eq $List) {
            $List = @();
        }

        $Body = [PSCustomObject]@{
            "VersandMailAdressen" = $List
        };
        return Invoke-Weedu -Uri "/rest/Rechnungen/{0}/MailVersenden" -UriParams @($RechnungUid) -Method POST -Body $Body;
    }
}

function Remove-Rechnung {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, ValueFromPipeline, Position = 0)]
        $RechnungsUid
    )
    process {
        $Body = New-Object PSCustomObject;

        Invoke-Weedu -Uri "rest/Rechnungen/{0}" -UriParams @(ConvertTo-WeeduGuid $RechnungsUid) -Method DELETE;
    }   
}

function Join-Batch {
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline, HelpMessage = "Objekte oder IDs für die Pipeline. Wenn vorhanden, so wird das Property idb_uid oder UID extrahiert.")]
        $PipelineInput,
        [Parameter(HelpMessage = "Anzahl Items pro Batch")]
        [int]$BatchSize
    )
    begin {
        if (-not ($batchSize -ge 1)) {
            $batchSize = 100;
        }
        $batchCollect = [System.Collections.ArrayList]::new($batchSize);
    }
    process {
        foreach ($item in $pipelineInput) {
            $member = $item | Get-Member | Where-Object { $_.Name -in ("idb_uid", "UID") } | Select-Object -First 1;
            if ($member) {
                $batchCollect.Add(($item | Select-Object -ExpandProperty $member.Name)) | Out-Null;
            }
            else {
                $batchCollect.Add($item) | Out-Null;
            }
            if ($batchCollect.Count -ge $batchSize) {
                Write-Output ([string]::Join(",", $batchCollect.ToArray()));
                $batchCollect.Clear();
            }
        }
    }
    end {
        if ($batchCollect.Count) {
            Write-Output ([string]::Join(",", $batchCollect.ToArray()));
        }
    }
}

function New-Quellprodukt-Object {
    [CmdletBinding(DefaultParameterSetName = "UID")]
    param(
        [Parameter(ValueFromPipeline, Position = 0)]
        $OrderItemUid,
        [string]$Sku,
        [string]$Ean,
        [double]$Price
    )
    process {
        $Quellprodukt = New-Object PSCustomObject;
        if ($PSBoundParameters.ContainsKey("OrderItemUid")) {
            $Quellprodukt | Add-Member -MemberType NoteProperty -Name "OrderItemUid" -Value (ConvertTo-WeeduGuid $OrderItemUid);
        }
        if ($PSBoundParameters.ContainsKey("Sku")) {
            $Quellprodukt | Add-Member -MemberType NoteProperty -Name "Sku" -Value $Sku;
        }
        if ($PSBoundParameters.ContainsKey("Ean")) {
            $Quellprodukt | Add-Member -MemberType NoteProperty -Name "Ean" -Value $Ean;
        }
        if ($PSBoundParameters.ContainsKey("Price")) {
            $Quellprodukt | Add-Member -MemberType NoteProperty -Name "Price" -Value $Price;
        }
        return $Quellprodukt;
    }
}

function Get-Rechnungsvorschau {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, ValueFromPipeline, HelpMessage = "Uid der Person für die die Rechnungsvorschau erzeugt werden soll.")]
        $PersonUid
    )
    process {
        Invoke-Weedu -Uri "rest/Rechnungen/vorschau/{0}" -UriParams @(ConvertTo-WeeduGuid $PersonUid) -Method GET;
    }
}

function New-Multiplikator-Object {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, Position = 0)]
        [int]$Zaehler,
        [Parameter(Mandatory, Position = 1)]
        [int]$Nenner,
        [Parameter(Mandatory, Position = 2)]
        [string]$Text
    )
    process {
        return [PSCustomObject]@{
            Zaehler = $Zaehler;
            Nenner  = $Nenner;
            Text    = $Text;
        };
    }
}

function Add-Multiplikator {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, ValueFromPipeline)]
        $Multiplikator,
        [Parameter(Mandatory, Position = 0)]
        [int]$Zaehler,
        [Parameter(Mandatory, Position = 1)]
        [int]$Nenner,
        [Parameter(Mandatory, Position = 2)]
        [string]$Text
    )
    begin {
        $MultiplikatorCollect = [System.Collections.ArrayList]::new();
    }
    process {
        $MultiplikatorCollect.Add($Multiplikator) | Out-Null;
    }
    end {
        $MultiplikatorCollect.Add((New-Multiplikator-Object $Zaehler $Nenner $Text)) | Out-Null;
        return $MultiplikatorCollect.ToArray();
    }
}

function New-Teilverrechnung-Object {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, ValueFromPipeline, Position = 0)]
        $FakturierungsabschnittUid,        
        [Parameter(Mandatory, Position = 1)]
        [int]$Zaehler,
        [Parameter(Mandatory, Position = 2)]
        [int]$Nenner,
        [Parameter(Mandatory, Position = 3)]
        [string]$Text,
        [Parameter(Mandatory, Position = 4)]
        [string]$LeistungszeitraumVon,
        [Parameter(Mandatory, Position = 5)]
        [string]$LeistungszeitraumBis
    )
    process {
        return [PSCustomObject]@{
            FakturierungsabschnittUid = ConvertTo-WeeduGuid $FakturierungsabschnittUid;
            Zaehler                   = $Zaehler;
            Nenner                    = $Nenner;
            Text                      = $Text;
            LeistungszeitraumVon      = $LeistungszeitraumVon;
            LeistungszeitraumBis      = $LeistungszeitraumBis;
        };
    }
}

function New-Fakturierungsabschnitt {
    [CmdletBinding()]
    param(
        $FakturierungsabschnittUid,
        [Parameter(Mandatory, ValueFromPipeline, Position = 0)]
        $AnlassUid,
        [Parameter(Mandatory)]
        $ProduktUid,
        [Parameter(Mandatory)]
        $FakturierenAm,
        [Parameter(Mandatory)]
        $LeistungszeitraumVon,
        [Parameter(Mandatory)]
        $LeistungszeitraumBis,
        [Parameter(Mandatory)]
        [int]$Menge,
        $RegelGruppierungsmerkmal,
        $KostentragerUid,
        $FakturierungsMultiplikatoren,
        [decimal]$ManuellerPreis
    )
    process {
        $AnlassUid = ConvertTo-WeeduGuid $AnlassUid;

        $Body = New-Object PSCustomObject;        
        $Body | Add-Member -MemberType NoteProperty -Name "ProduktUid" -Value (ConvertTo-WeeduGuid $ProduktUid);
        $Body | Add-Member -MemberType NoteProperty -Name "FakturierenAm" -Value $FakturierenAm;
        $Body | Add-Member -MemberType NoteProperty -Name "LeistungszeitraumVon" -Value $LeistungszeitraumVon;
        $Body | Add-Member -MemberType NoteProperty -Name "LeistungszeitraumBis" -Value $LeistungszeitraumBis;

        if ($PSBoundParameters.ContainsKey("FakturierungsabschnittUid")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Uid" -Value (ConvertTo-WeeduGuid $FakturierungsabschnittUid);
        }
        if ($PSBoundParameters.ContainsKey("Menge")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Menge" -Value $Menge;
        }
        if ($PSBoundParameters.ContainsKey("RegelGruppierungsmerkmal")) {
            $Body | Add-Member -MemberType NoteProperty -Name "RegelGruppierungsmerkmal" -Value (ConvertTo-WeeduGuid $RegelGruppierungsmerkmal);
        }
        if ($PSBoundParameters.ContainsKey("KostentragerUid")) {
            $Body | Add-Member -MemberType NoteProperty -Name "KostentragerUid" -Value (ConvertTo-WeeduGuid $KostentragerUid);
        }
        if ($PSBoundParameters.ContainsKey("FakturierungsMultiplikatoren")) {
            $Body | Add-Member -MemberType NoteProperty -Name "FakturierungsMultiplikatoren" -Value ([array]$FakturierungsMultiplikatoren);
        }
        if ($PSBoundParameters.ContainsKey("ManuellerPreis")) {
            $Body | Add-Member -MemberType NoteProperty -Name "ManuellerPreis" -Value $ManuellerPreis;
        }

        Invoke-Weedu -Uri "rest/Anlaesse/{0}/Fakturierungsabschnitte" -UriParams @($AnlassUid) -Method POST -Body $Body;
    }
}

function Set-Fakturierungsabschnitt {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, ValueFromPipeline, Position = 0)]
        $FakturierungsabschnittUid,
        [Parameter(Mandatory, Position = 1)]
        $AnlassUid,
        $ProduktUid,
        $FakturierenAm,
        $LeistungszeitraumVon,
        $LeistungszeitraumBis,
        [int]$Menge,
        $RegelGruppierungsmerkmal,
        $KostentragerUid,
        $FakturierungsMultiplikatoren,
        [decimal]$ManuellerPreis
    )
    process {
        $FakturierungsabschnittUid = ConvertTo-WeeduGuid $FakturierungsabschnittUid;
        $AnlassUid = ConvertTo-WeeduGuid $AnlassUid;

        $Body = New-Object PSCustomObject;        
        if ($PSBoundParameters.ContainsKey("ProduktUid")) {
            $Body | Add-Member -MemberType NoteProperty -Name "ProduktUid" -Value (ConvertTo-WeeduGuid $ProduktUid);
        }
        if ($PSBoundParameters.ContainsKey("FakturierenAm")) {
            $Body | Add-Member -MemberType NoteProperty -Name "FakturierenAm" -Value $FakturierenAm;
        }
        if ($PSBoundParameters.ContainsKey("LeistungszeitraumVon")) {
            $Body | Add-Member -MemberType NoteProperty -Name "LeistungszeitraumVon" -Value $LeistungszeitraumVon;
        }
        if ($PSBoundParameters.ContainsKey("LeistungszeitraumBis")) {
            $Body | Add-Member -MemberType NoteProperty -Name "LeistungszeitraumBis" -Value $LeistungszeitraumBis;
        }
        if ($PSBoundParameters.ContainsKey("Menge")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Menge" -Value $Menge;
        }
        if ($PSBoundParameters.ContainsKey("RegelGruppierungsmerkmal")) {
            $Body | Add-Member -MemberType NoteProperty -Name "RegelGruppierungsmerkmal" -Value (ConvertTo-WeeduGuid $RegelGruppierungsmerkmal);
        }
        if ($PSBoundParameters.ContainsKey("KostentragerUid")) {
            $Body | Add-Member -MemberType NoteProperty -Name "KostentragerUid" -Value (ConvertTo-WeeduGuid $KostentragerUid);
        }
        if ($PSBoundParameters.ContainsKey("FakturierungsMultiplikatoren")) {
            $Body | Add-Member -MemberType NoteProperty -Name "FakturierungsMultiplikatoren" -Value ([array]$FakturierungsMultiplikatoren);
        }
        if ($PSBoundParameters.ContainsKey("ManuellerPreis")) {
            $Body | Add-Member -MemberType NoteProperty -Name "ManuellerPreis" -Value $ManuellerPreis;
        }

        Invoke-Weedu -Uri "rest/Anlaesse/{0}/Fakturierungsabschnitte/{1}" -UriParams @($AnlassUid, $FakturierungsabschnittUid) -Method PUT -Body $Body;
    }
}

function Remove-Fakturierungsabschnitt {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, ValueFromPipeline, Position = 0)]
        $FakturierungsabschnittUid,
        [Parameter(Mandatory, Position = 1)]
        $AnlassUid
    )
    process {
        $FakturierungsabschnittUid = ConvertTo-WeeduGuid $FakturierungsabschnittUid;
        $AnlassUid = ConvertTo-WeeduGuid $AnlassUid;

        $Body = New-Object PSCustomObject;

        Invoke-Weedu -Uri "rest/Anlaesse/{0}/Fakturierungsabschnitte/{1}" -UriParams @($AnlassUid, $FakturierungsabschnittUid) -Method DELETE -Body $Body;
    }
}

function Get-RechnungsSplit {
    param(
        [Parameter(Mandatory, ValueFromPipeline, HelpMessage = "Uid des RechnungsSplits.")]
        $RechnungsSplitUid
    )
    process {
        Invoke-Weedu -Uri "rest/Rechnungssplits/{0}" -UriParams @(ConvertTo-WeeduGuid $RechnungsSplitUid) -Method GET;
    }
}

function New-RechnungsSplit {
    [CmdletBinding()]
    param(
        $RechnungsSplitUid,
        [Parameter(Mandatory, ValueFromPipeline, Position = 0)]
        $PersonMappingUid,
        [Parameter(Mandatory)]
        $RechnungsempfaengerUid,
        $RechnungsadresseUid,
        [Parameter(Mandatory)]
        $Anteil,
        [Parameter(Mandatory)]
        $Bezeichnung,
        $Bemerkung,
        [int]$SortierPrioritaet,
        $PlatzhalterProdukte
    )
    process {
        $Body = [PSCustomObject]@{
            PersonMappingUid       = (ConvertTo-WeeduGuid $PersonMappingUid);
            RechnungsempfaengerUid = (ConvertTo-WeeduGuid $RechnungsempfaengerUid);
            Anteil                 = $Anteil;
            Bezeichnung            = $Bezeichnung;
        };

        if ($PSBoundParameters.ContainsKey("RechnungsSplitUid")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Uid" -Value (ConvertTo-WeeduGuid $RechnungsSplitUid);
        }
        if ($PSBoundParameters.ContainsKey("RechnungsadresseUid")) {
            if ($RechnungsadresseUid -ne $null) {
                $RechnungsadresseUid = ConvertTo-WeeduGuid $RechnungsadresseUid;
            }
            $Body | Add-Member -MemberType NoteProperty -Name "RechnungsadresseUid" -Value $RechnungsadresseUid;
        }
        if ($PSBoundParameters.ContainsKey("Bemerkung")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Bemerkung" -Value $Bemerkung;
        }
        if ($PSBoundParameters.ContainsKey("SortierPrioritaet")) {
            $Body | Add-Member -MemberType NoteProperty -Name "SortierPrioritaet" -Value $SortierPrioritaet;
        }
        if ($PSBoundParameters.ContainsKey("PlatzhalterProdukte")) {
            if ($PlatzhalterProdukte -ne $null) {
                [array]$PlatzhalterProdukte = [array]($PlatzhalterProdukte | ForEach-Object { ConvertTo-WeeduGuid $_ });
            }
            $Body | Add-Member -MemberType NoteProperty -Name "PlatzhalterProdukte" -Value $PlatzhalterProdukte;
        }

        Invoke-Weedu -Uri "rest/Rechnungssplits" -Method POST -Body $Body;
    }
}

function Set-RechnungsSplit {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, ValueFromPipeline, Position = 0)]
        $RechnungsSplitUid,
        $RechnungsadresseUid,
        $Anteil,
        $Bezeichnung,
        $Bemerkung,
        [int]$SortierPrioritaet,
        $PlatzhalterProdukte
    )
    process {
        $RechnungsSplitUid = ConvertTo-WeeduGuid $RechnungsSplitUid;

        $Body = New-Object PSCustomObject;        
        if ($PSBoundParameters.ContainsKey("PersonMappingUid")) {
            $Body | Add-Member -MemberType NoteProperty -Name "PersonMappingUid" -Value (ConvertTo-WeeduGuid $PersonMappingUid);
        }
        if ($PSBoundParameters.ContainsKey("RechnungsempfaengerUid")) {
            $Body | Add-Member -MemberType NoteProperty -Name "RechnungsempfaengerUid" -Value (ConvertTo-WeeduGuid $RechnungsempfaengerUid);
        }
        if ($PSBoundParameters.ContainsKey("RechnungsadresseUid")) {
            if ($RechnungsadresseUid -ne $null) {
                $RechnungsadresseUid = ConvertTo-WeeduGuid $RechnungsadresseUid;
            }
            $Body | Add-Member -MemberType NoteProperty -Name "RechnungsadresseUid" -Value $RechnungsadresseUid;
        }
        if ($PSBoundParameters.ContainsKey("Anteil")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Anteil" -Value $Anteil;
        }
        if ($PSBoundParameters.ContainsKey("Bezeichnung")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Bezeichnung" -Value $Bezeichnung;
        }
        if ($PSBoundParameters.ContainsKey("Bemerkung")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Bemerkung" -Value $Bemerkung;
        }
        if ($PSBoundParameters.ContainsKey("SortierPrioritaet")) {
            $Body | Add-Member -MemberType NoteProperty -Name "SortierPrioritaet" -Value $SortierPrioritaet;
        }
        if ($PSBoundParameters.ContainsKey("PlatzhalterProdukte")) {
            if ($PlatzhalterProdukte -ne $null) {
                [array]$PlatzhalterProdukte = [array]($PlatzhalterProdukte | ForEach-Object { ConvertTo-WeeduGuid $_ });
            }
            $Body | Add-Member -MemberType NoteProperty -Name "PlatzhalterProdukte" -Value $PlatzhalterProdukte;
        }

        Invoke-Weedu -Uri "rest/Rechnungssplits/{0}" -UriParams @($RechnungsSplitUid) -Method PUT -Body $Body;
    }
}

function Remove-RechnungsSplit {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, ValueFromPipeline, Position = 0)]
        $RechnungsSplitUid
    )
    process {
        $RechnungsSplitUid = ConvertTo-WeeduGuid $RechnungsSplitUid;

        $Body = New-Object PSCustomObject;

        Invoke-Weedu -Uri "rest/Rechnungssplits/{0}" -UriParams @($RechnungsSplitUid) -Method DELETE -Body $Body;
    }
}

function Set-AnmeldungsFakturierung {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, ValueFromPipeline, Position = 0)]
        $AnmeldungUid,
        [boolean]$ManuelleFakturierung,
        $RechnungsadresseUid,
        [int]$RechnungsrhythmusAnzahlRaten,
        [int]$RechnungsrhythmusAufpreisProzente,
        [string]$RechnungsrhythmusCron,
        [int]$VorausFakturierungAnzahlTage,
        [string]$RechnungspositionKopfzeile,
        [string]$RechnungspositionFusszeile,
        [string]$RechnungspositionText,
        [string]$IvVerfuegungsnummer,
        [string]$IvVerfuegungsdauerVon,
        [string]$IvVerfuegungsdauerBis,
        [string]$IvBetreuungsperson,
        $FakturierungsMultiplikatoren,
        $Teilverrechnungen
    )
    process {
        $AnmeldungUid = ConvertTo-WeeduGuid $AnmeldungUid;

        $Body = New-Object PSCustomObject;        
        if ($PSBoundParameters.ContainsKey("ManuelleFakturierung")) {
            $Body | Add-Member -MemberType NoteProperty -Name "ManuelleFakturierung" -Value $ManuelleFakturierung;
        }                    
        if ($PSBoundParameters.ContainsKey("RechnungsadresseUid")) {
            $Body | Add-Member -MemberType NoteProperty -Name "RechnungsadresseUid" -Value (ConvertTo-WeeduGuid $RechnungsadresseUid);
        }
        if ($PSBoundParameters.ContainsKey("RechnungsrhythmusAnzahlRaten")) {
            $Body | Add-Member -MemberType NoteProperty -Name "RechnungsrhythmusAnzahlRaten" -Value $RechnungsrhythmusAnzahlRaten;
        }
        if ($PSBoundParameters.ContainsKey("RechnungsrhythmusAufpreisProzente")) {
            $Body | Add-Member -MemberType NoteProperty -Name "RechnungsrhythmusAufpreisProzente" -Value $RechnungsrhythmusAufpreisProzente;
        }
        if ($PSBoundParameters.ContainsKey("RechnungsrhythmusCron")) {
            $Body | Add-Member -MemberType NoteProperty -Name "RechnungsrhythmusCron" -Value $RechnungsrhythmusCron;
        }
        if ($PSBoundParameters.ContainsKey("VorausFakturierungAnzahlTage")) {
            $Body | Add-Member -MemberType NoteProperty -Name "VorausFakturierungAnzahlTage" -Value $VorausFakturierungAnzahlTage;
        }
        if ($PSBoundParameters.ContainsKey("RechnungspositionKopfzeile")) {
            $Body | Add-Member -MemberType NoteProperty -Name "RechnungspositionKopfzeile" -Value $RechnungspositionKopfzeile;
        }
        if ($PSBoundParameters.ContainsKey("RechnungspositionFusszeile")) {
            $Body | Add-Member -MemberType NoteProperty -Name "RechnungspositionFusszeile" -Value $RechnungspositionFusszeile;
        }
        if ($PSBoundParameters.ContainsKey("RechnungspositionText")) {
            $Body | Add-Member -MemberType NoteProperty -Name "RechnungspositionText" -Value $RechnungspositionText;
        }
        if ($PSBoundParameters.ContainsKey("IvVerfuegungsnummer")) {
            $Body | Add-Member -MemberType NoteProperty -Name "IvVerfuegungsnummer" -Value $IvVerfuegungsnummer;
        }
        if ($PSBoundParameters.ContainsKey("IvVerfuegungsdauerVon")) {
            $Body | Add-Member -MemberType NoteProperty -Name "IvVerfuegungsdauerVon" -Value $IvVerfuegungsdauerVon;
        }
        if ($PSBoundParameters.ContainsKey("IvVerfuegungsdauerBis")) {
            $Body | Add-Member -MemberType NoteProperty -Name "IvVerfuegungsdauerBis" -Value $IvVerfuegungsdauerBis;
        }
        if ($PSBoundParameters.ContainsKey("IvBetreuungsperson")) {
            $Body | Add-Member -MemberType NoteProperty -Name "IvBetreuungsperson" -Value $IvBetreuungsperson;
        }

        if ($PSBoundParameters.ContainsKey("FakturierungsMultiplikatoren")) {
            $Body | Add-Member -MemberType NoteProperty -Name "FakturierungsMultiplikatoren" -Value ([array]$FakturierungsMultiplikatoren);
        }
        if ($PSBoundParameters.ContainsKey("Teilverrechnungen")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Teilverrechnungen" -Value ([array]$Teilverrechnungen);
        }

        Invoke-Weedu -Uri "rest/Anmeldungen/{0}/Fakturierungseinstellungen" -UriParams @($AnmeldungUid) -Method PUT -Body $Body;
    }
}

function Remove-AnmeldungsFakturierung {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, ValueFromPipeline, Position = 0)]
        $AnmeldungUid
    )
    process {
        $AnmeldungUid = ConvertTo-WeeduGuid $AnmeldungUid;

        $Body = New-Object PSCustomObject;

        Invoke-Weedu -Uri "rest/Anmeldungen/{0}/Fakturierungseinstellungen" -UriParams @($AnmeldungUid) -Method DELETE -Body $Body;
    }
}

function Invoke-AnmeldungFakturieren {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, ValueFromPipeline = $true, Position = 0)]
        $AnmeldungUid,
        [Parameter(Mandatory, Position = 1)]
        $FakturierenBis
    )
    process {
        $AnmeldungUid = ConvertTo-WeeduGuid $AnmeldungUid;

        $Body = New-Object PSCustomObject;
        $Body | Add-Member -MemberType NoteProperty -Name "FakturierenBis" -Value $FakturierenBis;

        Invoke-Weedu -Uri "rest/Anmeldungen/{0}/fakturieren" -UriParams @($AnmeldungUid) -Method POST -Body $Body;
    }
}

function Invoke-ProduktFakturieren {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, ValueFromPipeline, Position = 0)]
        $ProductUid,
        [Parameter(Mandatory, Position = 1)]
        [string]$CommerceShop,
        [Parameter(Mandatory, Position = 2)]
        $RechnungsempfaengerUid,
        [Parameter(Mandatory, Position = 3)]
        [decimal]$Menge,
        $LeistungsempfaengerUid,
        $RechnungsadresseUid,
        $VerrechnenAb,
        $VerrechnenAbWennBerechtigt,
        $AusloesenBis,
        $AusloesenBisWennBerechtigt,
        $PositionstextListe,
        $RechnungstextHeaderListe,
        $RechnungstextFooterListe,
        $Lieferdatum,
        $Gruppierungsmerkmal,
        $DispoDatum,
        $KostentraegerUid,
        $KostentraegerText,
        $LeistungszeitraumVon,
        $LeistungszeitraumBis,
        $FibuDatum,
        $FakturierungsMultiplikatoren,
        [string]$Rechnungsrhythmus,
        [int]$RechnungsrhythmusMenge,
        [int]$RechnungsrhythmusAufpreisProzente,
        $EntstandenAus,
        [decimal]$ManuellerPreis
    )
    process {
        $ProductUid = ConvertTo-WeeduGuid $ProductUid;
        
        $Body = New-Object PSCustomObject;        
        $Body | Add-Member -MemberType NoteProperty -Name "RechnungsempfaengerUid" -Value (ConvertTo-WeeduGuid $RechnungsempfaengerUid);
        $Body | Add-Member -MemberType NoteProperty -Name "Menge" -Value $Menge;

        if ($PSBoundParameters.ContainsKey("LeistungsempfaengerUid")) {
            $Body | Add-Member -MemberType NoteProperty -Name "LeistungsempfaengerUid" -Value (ConvertTo-WeeduGuid $LeistungsempfaengerUid);
        }
        if ($PSBoundParameters.ContainsKey("RechnungsadresseUid")) {
            $Body | Add-Member -MemberType NoteProperty -Name "RechnungsadresseUid" -Value (ConvertTo-WeeduGuid $RechnungsadresseUid);
        }
        if ($PSBoundParameters.ContainsKey("VerrechnenAb")) {
            $Body | Add-Member -MemberType NoteProperty -Name "VerrechnenAb" -Value $VerrechnenAb;
        }
        if ($PSBoundParameters.ContainsKey("VerrechnenAbWennBerechtigt")) {
            $Body | Add-Member -MemberType NoteProperty -Name "VerrechnenAbWennBerechtigt" -Value $VerrechnenAbWennBerechtigt;
        }
        if ($PSBoundParameters.ContainsKey("AusloesenBis")) {
            $Body | Add-Member -MemberType NoteProperty -Name "AusloesenBis" -Value $AusloesenBis;
        }
        if ($PSBoundParameters.ContainsKey("AusloesenBisWennBerechtigt")) {
            $Body | Add-Member -MemberType NoteProperty -Name "AusloesenBisWennBerechtigt" -Value $AusloesenBisWennBerechtigt;
        }
        if ($PSBoundParameters.ContainsKey("Lieferdatum")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Lieferdatum" -Value $Lieferdatum;
        }
        if ($PSBoundParameters.ContainsKey("Gruppierungsmerkmal")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Gruppierungsmerkmal" -Value (ConvertTo-WeeduGuid $Gruppierungsmerkmal);
        }
        if ($PSBoundParameters.ContainsKey("DispoDatum")) {
            $Body | Add-Member -MemberType NoteProperty -Name "DispoDatum" -Value $DispoDatum;
        }
        if ($PSBoundParameters.ContainsKey("FibuDatum")) {
            $Body | Add-Member -MemberType NoteProperty -Name "FibuDatum" -Value $FibuDatum;
        }
        if ($PSBoundParameters.ContainsKey("KostentraegerUid")) {
            $Body | Add-Member -MemberType NoteProperty -Name "KostentraegerUid" -Value (ConvertTo-WeeduGuid $KostentraegerUid);
        }
        if ($PSBoundParameters.ContainsKey("KostentraegerText")) {
            $Body | Add-Member -MemberType NoteProperty -Name "KostentraegerText" -Value $KostentraegerText;
        }
        if ($PSBoundParameters.ContainsKey("LeistungszeitraumVon")) {
            $Body | Add-Member -MemberType NoteProperty -Name "LeistungszeitraumVon" -Value $LeistungszeitraumVon;
        }
        if ($PSBoundParameters.ContainsKey("LeistungszeitraumBis")) {
            $Body | Add-Member -MemberType NoteProperty -Name "LeistungszeitraumBis" -Value $LeistungszeitraumBis;
        }
        if ($PSBoundParameters.ContainsKey("PositionstextListe")) {
            $Body | Add-Member -MemberType NoteProperty -Name "PositionstextListe" -Value (ConvertTo-WeeduPriorityList $PositionstextListe);
        }
        if ($PSBoundParameters.ContainsKey("RechnungstextHeaderListe")) {
            $Body | Add-Member -MemberType NoteProperty -Name "RechnungstextHeaderListe" -Value (ConvertTo-WeeduPriorityList $RechnungstextHeaderListe);
        }
        if ($PSBoundParameters.ContainsKey("RechnungstextFooterListe")) {
            $Body | Add-Member -MemberType NoteProperty -Name "RechnungstextFooterListe" -Value (ConvertTo-WeeduPriorityList $RechnungstextFooterListe);
        }
        if ($PSBoundParameters.ContainsKey("FakturierungsMultiplikatoren")) {
            $Body | Add-Member -MemberType NoteProperty -Name "FakturierungsMultiplikatoren" -Value ([array]$FakturierungsMultiplikatoren);
        }
        if ($PSBoundParameters.ContainsKey("Rechnungsrhythmus")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Rechnungsrhythmus" -Value $Rechnungsrhythmus;
        }
        if ($PSBoundParameters.ContainsKey("RechnungsrhythmusMenge")) {
            $Body | Add-Member -MemberType NoteProperty -Name "RechnungsrhythmusMenge" -Value $RechnungsrhythmusMenge;
        }
        if ($PSBoundParameters.ContainsKey("RechnungsrhythmusAufpreisProzente")) {
            $Body | Add-Member -MemberType NoteProperty -Name "RechnungsrhythmusAufpreisProzente" -Value $RechnungsrhythmusAufpreisProzente;
        }
        if ($PSBoundParameters.ContainsKey("EntstandenAus")) {
            $Body | Add-Member -MemberType NoteProperty -Name "EntstandenAus" -Value ([array]$EntstandenAus);
        }
        if ($PSBoundParameters.ContainsKey("ManuellerPreis")) {
            $Body | Add-Member -MemberType NoteProperty -Name "ManuellerPreis" -Value $ManuellerPreis;
        }
        
        Invoke-Weedu -Uri "commerce-{0}/rest/Products/{1}/Fakturieren" -UriParams @($CommerceShop, $ProductUid) -Method POST -Body $Body;
    }
}

function Enable-ExternalLogin {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, ValueFromPipeline, Position = 0)]
        $PersonUid
    )
    process {
        $PersonUid = ConvertTo-WeeduGuid $PersonUid;
        $Body = [PSCustomObject]@{
            "LoginUid" = $PersonUid
        };

        Write-Verbose "PersonUid: $PersonUid";
        Invoke-Weedu -Uri "rest/Personen/ExternesLogin/Reaktivieren" -UriParams @() -Method POST -Body $Body;
    }
}

function Disable-ExternalLogin {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, ValueFromPipeline, Position = 0)]
        $PersonUid
    )
    process {
        $PersonUid = ConvertTo-WeeduGuid $PersonUid;
        $Body = [PSCustomObject]@{
            "LoginUid" = $PersonUid
        };

        Write-Verbose "PersonUid: $PersonUid";
        Invoke-Weedu -Uri "rest/Personen/ExternesLogin/Sperren" -UriParams @() -Method POST -Body $Body;
    }
}

function New-PostAdresse-Object {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory, HelpMessage = "Privat, Geschaeft, Andere")]
        [string]$Kategorie,
        [Parameter(HelpMessage = "Ab wann soll das Kommunikationsmittel gültig sein. Wenn leer dann wird das aktuelle Datum genommen. Format 2017-10-20T14:22")]
        $GueltigAb,
        [Parameter(HelpMessage = "Bis wann soll das Kommunikationsmittel gültig sein. Format 2017-10-20T14:22")]
        $GueltigBis,
        [string]$Bemerkungen,
        [boolean]$Notfall,
        [boolean]$Wohnsitz,
        [Parameter(Mandatory, HelpMessage = "ISO Code des Landes. Bsp.: CH für Schweiz")]
        [string]$Land,
        [Parameter(HelpMessage = "Kann nur für Land Schweiz, Lichtenstein oder Deutschland verwendet weden", ParameterSetName = "AdresseChDe")]
        [string]$Strasse,
        [Parameter(HelpMessage = "Kann nur für Land Schweiz, Lichtenstein oder Deutschland verwendet weden", ParameterSetName = "AdresseChDe")]
        [string]$Hausnummer,
        [Parameter(HelpMessage = "Kann nur für Land Schweiz, Lichtenstein oder Deutschland verwendet weden", ParameterSetName = "AdresseChDe")]
        $Postfach,
        [Parameter(HelpMessage = "Kann nur für Land Schweiz, Lichtenstein oder Deutschland verwendet weden", ParameterSetName = "AdresseChDe")]
        $PLZ,
        [Parameter(HelpMessage = "Kann nur für Land Schweiz, Lichtenstein oder Deutschland verwendet weden", ParameterSetName = "AdresseChDe")]
        [string]$Ort,
        [Parameter(HelpMessage = "Zusatzdaten zur Adresse: Bsp.: Firmenname, zHd, c/o ...")]
        [string]$Zusatzzeile1,
        [Parameter(HelpMessage = "Zusatzdaten zur Adresse: Bsp.: Firmenname, zHd, c/o ...")]
        [string]$Zusatzzeile2,
        [Parameter(HelpMessage = "Muss für Länder exklusive Schweiz/Lichtenstein/Deutschland verwendet werden", ParameterSetName = "AdresseGenerisch")]
        [string]$Adresse1,
        [Parameter(HelpMessage = "Muss für Länder exklusive Schweiz/Lichtenstein/Deutschland verwendet werden", ParameterSetName = "AdresseGenerisch")]
        [string]$Adresse2,
        [Parameter(HelpMessage = "Muss für Länder exklusive Schweiz/Lichtenstein/Deutschland verwendet werden", ParameterSetName = "AdresseGenerisch")]
        [string]$Adresse3
    )
    process {
        if (($PSBoundParameters.ContainsKey("Adresse1") -or $PSBoundParameters.ContainsKey("Adresse2") -or $PSBoundParameters.ContainsKey("Adresse3")) -and ($Land -eq "CH" -or $Land -eq "LI" -or $Land -eq "DE")) {
            Write-Error "Für Land CH/LI/DE darf Adresse1 bis Adresse3 nicht verwendet werden"
            return $null;
        }
        if ($Land -eq "CH" -or $Land -eq "LI") {
            return New-Kommunikationsmittel-Object -Type "PostadresseSchweiz" -Kategorie $Kategorie -GueltigAb $GueltigAb -GueltigBis $GueltigBis -Bemerkungen $Bemerkungen -Notfall $Notfall -Wohnsitz $Wohnsitz -Land $Land -Strasse $Strasse -Hausnummer $Hausnummer -Postfach $Postfach -PLZ $PLZ -Ort $Ort -Zusatzzeile1 $Zusatzzeile1 -Zusatzzeile2 $Zusatzzeile2;
        }
        elseif ($Land -eq "DE") {
            return New-Kommunikationsmittel-Object -Type "PostadresseDeutschland" -Kategorie $Kategorie -GueltigAb $GueltigAb -GueltigBis $GueltigBis -Bemerkungen $Bemerkungen -Notfall $Notfall -Wohnsitz $Wohnsitz -Land $Land -Strasse $Strasse -Hausnummer $Hausnummer -Postfach $Postfach -PLZ $PLZ -Ort $Ort -Zusatzzeile1 $Zusatzzeile1 -Zusatzzeile2 $Zusatzzeile2;
        }
        else {
            if (-not $PSBoundParameters.ContainsKey("Adresse1") -and -not $PSBoundParameters.ContainsKey("Adresse2") -and -not $PSBoundParameters.ContainsKey("Adresse3")) {
                $Adresse1 = "$Strasse $Hausnummer";
                $Adresse2 = "$PLZ $Ort";
            }
            return New-Kommunikationsmittel-Object -Type "PostadresseGenerisch" -Kategorie $Kategorie -GueltigAb $GueltigAb -GueltigBis $GueltigBis -Bemerkungen $Bemerkungen -Notfall $Notfall -Wohnsitz $Wohnsitz -Land $Land -Zusatzzeile1 $Zusatzzeile1 -Zusatzzeile2 $Zusatzzeile2 -Adresse1 $Adresse1 -Adresse2 $Adresse2 -Adresse3 $Adresse3;
        }
    }
}

function New-Kommunikationsmittel-Object {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, HelpMessage = "Typen: EMailAdresse, Festnetznummer, Faxnummer, Mobilenummer, PostadresseSchweiz, PostadresseDeutschland, PostadresseGenerisch, WwwAdresse, IndirektesKommunikationsmittel")]
        [string]$Type,
        [Parameter(Mandatory, HelpMessage = "Privat, Geschaeft, Andere")]
        [string]$Kategorie,
        [Parameter(HelpMessage = "Ab wann soll das Kommunikationsmittel gültig sein. Wenn leer dann wird das aktuelle Datum genommen. Format 2017-10-20T14:22")]
        $GueltigAb,
        [Parameter(HelpMessage = "Bis wann soll das Kommunikationsmittel gültig sein. Format 2017-10-20T14:22")]
        $GueltigBis,
        [string]$Bemerkungen,
        [boolean]$Notfall,
        [boolean]$Wohnsitz,
        [Parameter(HelpMessage = "Verwenden bei Type = EMailAdresse")]
        [string]$Adresse,
        [Parameter(HelpMessage = "Verwenden bei Typen Festnetznummer, Faxnummer oder Mobilenummer")]
        [string]$Nummer,
        [Parameter(HelpMessage = "Verwenden bei Type = WwwAdresse")]
        [string]$Url,
        [Parameter(HelpMessage = "Verwenden bei Typen PostadresseSchweiz, PostadresseDeutschland oder PostadresseGenerisch. Bsp.: CH für Schweiz")]
        [string]$Land,
        [Parameter(HelpMessage = "Verwenden bei Typen PostadresseSchweiz, PostadresseDeutschland")]
        [string]$Strasse,
        [Parameter(HelpMessage = "Verwenden bei Typen PostadresseSchweiz, PostadresseDeutschland")]
        [string]$Hausnummer,
        [Parameter(HelpMessage = "Verwenden bei Typen PostadresseSchweiz, PostadresseDeutschland")]
        $Postfach,
        [Parameter(HelpMessage = "Verwenden bei Typen PostadresseSchweiz, PostadresseDeutschland")]
        $PLZ,
        [Parameter(HelpMessage = "Verwenden bei Typen PostadresseSchweiz, PostadresseDeutschland")]
        [string]$Ort,
        [Parameter(HelpMessage = "Verwenden bei Typen PostadresseSchweiz, PostadresseDeutschland, PostadresseGenerisch")]
        [string]$Zusatzzeile1,
        [Parameter(HelpMessage = "Verwenden bei Typen PostadresseSchweiz, PostadresseDeutschland, PostadresseGenerisch")]
        [string]$Zusatzzeile2,
        [Parameter(HelpMessage = "Verwenden bei Type = PostadresseGenerisch")]
        [string]$Adresse1,
        [Parameter(HelpMessage = "Verwenden bei Type = PostadresseGenerisch")]
        [string]$Adresse2,
        [Parameter(HelpMessage = "Verwenden bei Type = PostadresseGenerisch")]
        [string]$Adresse3,
        [Parameter(HelpMessage = "GUID des Kommunikationsmittels einer anderen Person. Verwendung bei Type = IndirektesKommunikationsmittel")]
        $PersonKommunikationsmittelUid,
        [Parameter(HelpMessage = "Position in der Kommunikationsmittel-Liste der Person (Standardwert: 0, also neues bevorzugtes Kommunikationsmittel)")]
        [int]$Index

    )
    process {
        if ("IndirektesKommunikationsmittel" -Contains $Type) {
            $Kommunikationsmittel = [PSCustomObject]@{
                type      = $Type;
                Kategorie = $Kategorie;
            };

            if ($PSBoundParameters.ContainsKey("PersonKommunikationsmittelUid")) {
                $Kommunikationsmittel | Add-Member -MemberType NoteProperty -Name "Kommunikationsmittel" -Value $PersonKommunikationsmittelUid;
            }
        }
        else {
            $Kommunikationsmittel = [PSCustomObject]@{
                type      = "DirektesKommunikationsmittel";
                Kategorie = $Kategorie;
            };

            $KommunikationsmittelAdresse = [PSCustomObject]@{ type = $Type; };

            if ($PSBoundParameters.ContainsKey("Adresse")) {
                $KommunikationsmittelAdresse | Add-Member -MemberType NoteProperty -Name "Adresse" -Value $Adresse.Trim();
            }
            if ($PSBoundParameters.ContainsKey("Nummer")) {
                $KommunikationsmittelAdresse | Add-Member -MemberType NoteProperty -Name "Nummer" -Value $Nummer.Trim();
            }
            if ($PSBoundParameters.ContainsKey("Url")) {
                $KommunikationsmittelAdresse | Add-Member -MemberType NoteProperty -Name "Url" -Value $Url.Trim();
            }
            if ($PSBoundParameters.ContainsKey("Land")) {
                $KommunikationsmittelAdresse | Add-Member -MemberType NoteProperty -Name "Land" -Value $Land;
            }
            if ($PSBoundParameters.ContainsKey("Strasse")) {
                $KommunikationsmittelAdresse | Add-Member -MemberType NoteProperty -Name "Strasse" -Value $Strasse;
            }
            if ($PSBoundParameters.ContainsKey("Hausnummer")) {
                $KommunikationsmittelAdresse | Add-Member -MemberType NoteProperty -Name "Hausnummer" -Value $Hausnummer;
            }
            if ($PSBoundParameters.ContainsKey("Postfach")) {
                $KommunikationsmittelAdresse | Add-Member -MemberType NoteProperty -Name "Postfach" -Value $Postfach;
            }
            if ($PSBoundParameters.ContainsKey("PLZ")) {
                $KommunikationsmittelAdresse | Add-Member -MemberType NoteProperty -Name "PLZ" -Value $PLZ;
            }
            if ($PSBoundParameters.ContainsKey("Ort")) {
                $KommunikationsmittelAdresse | Add-Member -MemberType NoteProperty -Name "Ort" -Value $Ort;
            }
            if ($PSBoundParameters.ContainsKey("Zusatzzeile1")) {
                $KommunikationsmittelAdresse | Add-Member -MemberType NoteProperty -Name "Zusatzzeile1" -Value $Zusatzzeile1;
            }
            if ($PSBoundParameters.ContainsKey("Zusatzzeile2")) {
                $KommunikationsmittelAdresse | Add-Member -MemberType NoteProperty -Name "Zusatzzeile2" -Value $Zusatzzeile2;
            }
            if ($PSBoundParameters.ContainsKey("Adresse1")) {
                $KommunikationsmittelAdresse | Add-Member -MemberType NoteProperty -Name "Adresse1" -Value $Adresse1;
            }
            if ($PSBoundParameters.ContainsKey("Adresse2")) {
                $KommunikationsmittelAdresse | Add-Member -MemberType NoteProperty -Name "Adresse2" -Value $Adresse2;
            }
            if ($PSBoundParameters.ContainsKey("Adresse3")) {
                $KommunikationsmittelAdresse | Add-Member -MemberType NoteProperty -Name "Adresse3" -Value $Adresse3;
            }

            $Kommunikationsmittel | Add-Member -MemberType NoteProperty -Name "Adresse" -Value $KommunikationsmittelAdresse;
        }
        if ($PSBoundParameters.ContainsKey("Bemerkungen")) {
            $Kommunikationsmittel | Add-Member -MemberType NoteProperty -Name "Bemerkungen" -Value $Bemerkungen;
        }
        if ($PSBoundParameters.ContainsKey("GueltigBis")) {
            $Kommunikationsmittel | Add-Member -MemberType NoteProperty -Name "GueltigBis" -Value $GueltigBis;
        }
        if ($PSBoundParameters.ContainsKey("GueltigAb") -and $GueltigAb) {
            $Kommunikationsmittel | Add-Member -MemberType NoteProperty -Name "GueltigAb" -Value $GueltigAb;
        }
        if ($PSBoundParameters.ContainsKey("Notfall")) {
            $Kommunikationsmittel | Add-Member -MemberType NoteProperty -Name "Notfall" -Value $Notfall;
        }
        if ($PSBoundParameters.ContainsKey("Wohnsitz")) {
            $Kommunikationsmittel | Add-Member -MemberType NoteProperty -Name "Wohnsitz" -Value $Wohnsitz;
        }
        if ($PSBoundParameters.ContainsKey("Index")) {
            $Kommunikationsmittel | Add-Member -MemberType NoteProperty -Name "index" -Value $Index;
        }
        return $Kommunikationsmittel
    }
}

function New-PersonKommunikationsmittel {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, HelpMessage = "GUID, welche die Person systemweit eindeutig referenziert (synthetische oder echte)")]
        [string]$PersonUid,
        [Parameter(Mandatory, HelpMessage = "Kommunikationsmittel (erstellt z.B. mit New-Kommunikationsmittel-Object)")]
        $Kommunikationsmittel
    )
    process {
        return Invoke-Weedu -Uri "/rest/Personen/{0}/Kommunikationsmittel" -UriParams @($PersonUid) -Method POST -Body $Kommunikationsmittel;
    }
}

function Edit-PersonKommunikationsmittel {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, HelpMessage = "GUID, welche das Kommunikationsmittel referenziert (synthetische oder echte)")]
        [string]$KommunikationsmittelUid,
        [Parameter(Mandatory, HelpMessage = "GUID, welche die Person systemweit eindeutig referenziert (synthetische oder echte)")]
        [string]$PersonUid,
        [Parameter(Mandatory, HelpMessage = "Kommunikationsmittel (erstellt z.B. mit New-Kommunikationsmittel-Object)")]
        $Kommunikationsmittel
    )
    process {
        return Invoke-Weedu -Uri "/rest/Personen/{0}/Kommunikationsmittel/{1}" -UriParams @((ConvertTo-WeeduGuid $PersonUid), (ConvertTo-WeeduGuid $KommunikationsmittelUid)) -Method PUT -Body $Kommunikationsmittel;
    }
}

function Set-PersonKommunikationsmittel {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, HelpMessage = "WeeduUid der Person")]
        $PersonUid,
        [Parameter(Mandatory, HelpMessage = "Liste von Kommunikationsmittel (erstellt z.B. mit New-Kommunikationsmittel-Object)")]
        [array]$KommunikationsmittelListe
    )
    process {
        return Invoke-Weedu -Uri "/rest/Personen/{0}/Kommunikationsmittel" -UriParams @(ConvertTo-WeeduGuid $PersonUid) -Method PUT -Body $KommunikationsmittelListe;
    }
}

function Set-Kommunikationsmittel {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, HelpMessage = "WeeduUid der Person")]
        $PersonUid,
        [Parameter(Mandatory, HelpMessage = "KommunikationsmittelUid der Person")]
        $KommunikationsmittelUid,
        [Parameter(Mandatory, HelpMessage = "Kommunikationsmittel (erstellt z.B. mit New-Kommunikationsmittel-Object)")]
        $Kommunikationsmittel
    )
    process {
        return Invoke-Weedu -Uri "/rest/Personen/{0}/Kommunikationsmittel/{1}" -UriParams @((ConvertTo-WeeduGuid $PersonUid), (ConvertTo-WeeduGuid $KommunikationsmittelUid)) -Method PUT -Body $Kommunikationsmittel;
    }
}

function New-Einzelperson {
    [CmdletBinding()]
    param(
        [Parameter(HelpMessage = "Uid der Person (synthetische oder echte)")]
        $PersonUid,
        [Parameter(Mandatory)]
        [string]$Vorname,
        [Parameter(Mandatory)]
        [string]$Name,
        [Parameter(Mandatory, HelpMessage = "de, en, fr, it, usw.")]
        [string]$Korrespondenzsprache,
        [Parameter(HelpMessage = "Weiblich, Maennlich")]
        [string]$Geschlecht,
        [Parameter(HelpMessage = "Format 1992-02-27")]
        $Geburtsdatum,
        [boolean]$Verstorben,
        [Parameter(HelpMessage = "de, en, fr, it, usw.")]
        [string]$Muttersprache,
        [string]$Sozialversicherungsnummer,
        [int]$MatrikelnummerCH,
        [string]$Anredezusatz,
        [Parameter(HelpMessage = "gültige Werte sind 'DDr,Dr,PD,Prof,ProfDDr,ProfDr'")]
        [string]$AkademischerTitel,
        [string]$TitelZusatz,
        [string]$Titel2,
        [string]$Funktion,
        [string]$Beruf,
        $Branche,
        $Staatsangehoerigkeit,
        $Heimatort,
        $Auslaenderkategorie,
        [Parameter(HelpMessage = "Format 2020-02-27")]
        $BewilligungBis,
        [string]$Geburtsort,
        [boolean]$Aufnahmesperre,
        [boolean]$Aktiv,
        [boolean]$HatCiceroMitgliedschaft,
        [int]$FinmaRegisternummer,
        [Parameter(HelpMessage = "Liste von Kommunikationsmittel (erstellt z.B. mit New-Kommunikationsmittel-Object)")]
        [array]$KommunikationsmittelListe,
        [Parameter(Mandatory, HelpMessage = "Sicherheitseinstellung (erstellt z.B. mit New-Sicherheitseinstellung-Object)")]
        [PSCustomObject]$SicherheitsEinstellung,
        [Parameter(HelpMessage = "Liste von Tags welche dieser Person hinzugefügt werden sollen")]
        [array]$AddTagsListe
    )
    process {
        $Body = [PSCustomObject]@{
            type                   = "Einzelperson";
            Vorname                = $Vorname;
            Name                   = $Name;
            Korrespondenzsprache   = $Korrespondenzsprache;
            Sicherheitseinstellung = $SicherheitsEinstellung;
        };

        if ($PSBoundParameters.ContainsKey("PersonUid")) {
            $PersonUid = ConvertTo-WeeduGuid $PersonUid;
        }
        else {
            $PersonUid = New-Guid;
        }
        $Body | Add-Member -MemberType NoteProperty -Name "Uid" -Value $PersonUid;

        if ($PSBoundParameters.ContainsKey("Geschlecht")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Geschlecht" -Value $Geschlecht;
        }
        if ($PSBoundParameters.ContainsKey("Geburtsdatum")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Geburtsdatum" -Value $Geburtsdatum;
        }
        if ($PSBoundParameters.ContainsKey("Verstorben")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Verstorben" -Value $Verstorben;
        }
        if ($PSBoundParameters.ContainsKey("Muttersprache")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Muttersprache" -Value $Muttersprache;
        }
        if ($PSBoundParameters.ContainsKey("Sozialversicherungsnummer")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Sozialversicherungsnummer" -Value $Sozialversicherungsnummer;
        }
        if ($PSBoundParameters.ContainsKey("MatrikelnummerCH")) {
            $Body | Add-Member -MemberType NoteProperty -Name "MatrikelnummerCH" -Value $MatrikelnummerCH;
        }
        if ($PSBoundParameters.ContainsKey("Anredezusatz")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Anredezusatz" -Value $Anredezusatz;
        }
        if ($PSBoundParameters.ContainsKey("AkademischerTitel")) {
            $Body | Add-Member -MemberType NoteProperty -Name "AkademischerTitel" -Value $AkademischerTitel;
        }
        if ($PSBoundParameters.ContainsKey("TitelZusatz")) {
            $Body | Add-Member -MemberType NoteProperty -Name "TitelZusatz" -Value $TitelZusatz;
        }
        if ($PSBoundParameters.ContainsKey("Titel2")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Titel2" -Value $Titel2;
        }
        if ($PSBoundParameters.ContainsKey("Funktion")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Funktion" -Value $Funktion;
        }
        if ($PSBoundParameters.ContainsKey("Beruf")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Beruf" -Value $Beruf;
        }
        if ($PSBoundParameters.ContainsKey("Branche")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Branche" -Value $Branche;
        }
        if ($PSBoundParameters.ContainsKey("Staatsangehoerigkeit")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Staatsangehoerigkeit" -Value $Staatsangehoerigkeit;
        }
        if ($PSBoundParameters.ContainsKey("Heimatort")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Heimatort" -Value $Heimatort;
        }
        if ($PSBoundParameters.ContainsKey("Auslaenderkategorie")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Auslaenderkategorie" -Value $Auslaenderkategorie;
        }
        if ($PSBoundParameters.ContainsKey("BewilligungBis")) {
            $Body | Add-Member -MemberType NoteProperty -Name "BewilligungBis" -Value $BewilligungBis;
        }
        if ($PSBoundParameters.ContainsKey("Geburtsort")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Geburtsort" -Value $Geburtsort;
        }
        if ($PSBoundParameters.ContainsKey("Aufnahmesperre")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Aufnahmesperre" -Value $Aufnahmesperre;
        }
        if ($PSBoundParameters.ContainsKey("HatCiceroMitgliedschaft")) {
            $Body | Add-Member -MemberType NoteProperty -Name "HatCiceroMitgliedschaft" -Value $HatCiceroMitgliedschaft;
        }
        if ($PSBoundParameters.ContainsKey("FinmaRegisternummer")) {
            $Body | Add-Member -MemberType NoteProperty -Name "FinmaRegisternummer" -Value $FinmaRegisternummer;
        }
        if ($PSBoundParameters.ContainsKey("KommunikationsmittelListe")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Kommunikationsmittel" -Value $KommunikationsmittelListe;
        }
        if ($PSBoundParameters.ContainsKey("Aktiv")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Aktiv" -Value $Aktiv;
        }

        $res = Invoke-Weedu -Uri "rest/Personen" -Method POST -Body $Body;

        if ($PSBoundParameters.ContainsKey("AddTagsListe")) {
            Edit-Tags -MasterUid $PersonUid -Add $AddTagsListe
        }

        return $res;
    }
}

function Set-Einzelperson {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, HelpMessage = "Uid der Person (synthetische oder echte)")]
        $PersonUid,
        [string]$Vorname,
        [string]$Name,
        [Parameter(HelpMessage = "de, en, fr, it, usw.")]
        [string]$Korrespondenzsprache,
        [Parameter(HelpMessage = "Weiblich, Maennlich")]
        [string]$Geschlecht,
        [Parameter(HelpMessage = "Format 1992-02-27")]
        $Geburtsdatum,
        [boolean]$Verstorben,
        [Parameter(HelpMessage = "de, en, fr, it, usw.")]
        [string]$Muttersprache,
        [string]$Sozialversicherungsnummer,
        [int]$MatrikelnummerCH,
        [string]$Anredezusatz,
        [Parameter(HelpMessage = "gültige Werte sind 'DDr,Dr,PD,Prof,ProfDDr,ProfDr'")]
        [string]$AkademischerTitel,
        [string]$TitelZusatz,
        [string]$Titel2,
        [string]$Funktion,
        [string]$Beruf,
        $Branche,
        $Staatsangehoerigkeit,
        $Heimatort,
        $Auslaenderkategorie,
        [Parameter(HelpMessage = "Format 2020-02-27")]
        $BewilligungBis,
        [string]$Geburtsort,
        [boolean]$Aufnahmesperre,
        [boolean]$Aktiv,
        [boolean]$HatCiceroMitgliedschaft,
        [int]$FinmaRegisternummer,
        [Parameter(HelpMessage = "Liste von Kommunikationsmittel (erstellt z.B. mit New-Kommunikationsmittel-Object)")]
        [array]$KommunikationsmittelListe,
        [Parameter(HelpMessage = "Liste von Tags welche dieser Person hinzugefügt werden sollen")]
        [array]$AddTagsListe,
        [Parameter(HelpMessage = "Liste von Tags welche auf dieser Person gelöscht werden sollen")]
        [array]$RemoveTagsListe
    )
    process {
        $Body = [PSCustomObject]@{
            type = "Einzelperson";
        };

        $PersonUid = ConvertTo-WeeduGuid $PersonUid;
        if ($PSBoundParameters.ContainsKey("Vorname")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Vorname" -Value $Vorname;
        }
        if ($PSBoundParameters.ContainsKey("Name")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Name" -Value $Name;
        }
        if ($PSBoundParameters.ContainsKey("Korrespondenzsprache")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Korrespondenzsprache" -Value $Korrespondenzsprache;
        }
        if ($PSBoundParameters.ContainsKey("Geschlecht")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Geschlecht" -Value $Geschlecht;
        }
        if ($PSBoundParameters.ContainsKey("Geburtsdatum")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Geburtsdatum" -Value $Geburtsdatum;
        }
        if ($PSBoundParameters.ContainsKey("Verstorben")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Verstorben" -Value $Verstorben;
        }
        if ($PSBoundParameters.ContainsKey("Muttersprache")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Muttersprache" -Value $Muttersprache;
        }
        if ($PSBoundParameters.ContainsKey("Sozialversicherungsnummer")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Sozialversicherungsnummer" -Value $Sozialversicherungsnummer;
        }
        if ($PSBoundParameters.ContainsKey("MatrikelnummerCH")) {
            $Body | Add-Member -MemberType NoteProperty -Name "MatrikelnummerCH" -Value $MatrikelnummerCH;
        }
        if ($PSBoundParameters.ContainsKey("Anredezusatz")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Anredezusatz" -Value $Anredezusatz;
        }
        if ($PSBoundParameters.ContainsKey("AkademischerTitel")) {
            $Body | Add-Member -MemberType NoteProperty -Name "AkademischerTitel" -Value $AkademischerTitel;
        }
        if ($PSBoundParameters.ContainsKey("TitelZusatz")) {
            $Body | Add-Member -MemberType NoteProperty -Name "TitelZusatz" -Value $TitelZusatz;
        }
        if ($PSBoundParameters.ContainsKey("Titel2")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Titel2" -Value $Titel2;
        }
        if ($PSBoundParameters.ContainsKey("Funktion")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Funktion" -Value $Funktion;
        }
        if ($PSBoundParameters.ContainsKey("Beruf")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Beruf" -Value $Beruf;
        }
        if ($PSBoundParameters.ContainsKey("Branche")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Branche" -Value $Branche;
        }
        if ($PSBoundParameters.ContainsKey("Staatsangehoerigkeit")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Staatsangehoerigkeit" -Value $Staatsangehoerigkeit;
        }
        if ($PSBoundParameters.ContainsKey("Heimatort")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Heimatort" -Value $Heimatort;
        }
        if ($PSBoundParameters.ContainsKey("Auslaenderkategorie")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Auslaenderkategorie" -Value $Auslaenderkategorie;
        }
        if ($PSBoundParameters.ContainsKey("BewilligungBis")) {
            $Body | Add-Member -MemberType NoteProperty -Name "BewilligungBis" -Value $BewilligungBis;
        }
        if ($PSBoundParameters.ContainsKey("Geburtsort")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Geburtsort" -Value $Geburtsort;
        }
        if ($PSBoundParameters.ContainsKey("Aufnahmesperre")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Aufnahmesperre" -Value $Aufnahmesperre;
        }
        if ($PSBoundParameters.ContainsKey("HatCiceroMitgliedschaft")) {
            $Body | Add-Member -MemberType NoteProperty -Name "HatCiceroMitgliedschaft" -Value $HatCiceroMitgliedschaft;
        }
        if ($PSBoundParameters.ContainsKey("FinmaRegisternummer")) {
            $Body | Add-Member -MemberType NoteProperty -Name "FinmaRegisternummer" -Value $FinmaRegisternummer;
        }
        if ($PSBoundParameters.ContainsKey("Aktiv")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Aktiv" -Value $Aktiv;
        }

        if ($PSBoundParameters.ContainsKey("AddTagsListe") -or $PSBoundParameters.ContainsKey("RemoveTagsListe")) {
            if (-not $PSBoundParameters.ContainsKey("AddTagsListe")) {
                $AddTagsListe = @();
            }
            if (-not $PSBoundParameters.ContainsKey("RemoveTagsListe")) {
                $RemoveTagsListe = @();
            }
            Edit-Tags -MasterUid $PersonUid -Add $AddTagsListe -Remove $RemoveTagsListe
        }

        if ($KommunikationsmittelListe -ne $null) {
            Set-PersonKommunikationsmittel -PersonUid $PersonUid -KommunikationsmittelListe $KommunikationsmittelListe;
        }

        return Invoke-Weedu -Uri "/rest/Personen/{0}" -UriParams $PersonUid -Method PUT -Body $Body;
    }
}

function New-Organisation {
    [CmdletBinding()]
    param(
        [Parameter(HelpMessage = "Uid der Organisation (synthetische oder echte)")]
        $OrganisationUid,
        [Parameter(Mandatory)]
        [string]$Organisationsname,
        [Parameter(HelpMessage = "Bsp.: Firmenstrukturen_Abteilung")]
        [string]$Organisationsform,
        [Parameter(Mandatory, HelpMessage = "de, en, fr, it, usw.")]
        [string]$Korrespondenzsprache,
        [Parameter(HelpMessage = "Format CHE-999.999.999")]
        [string]$UnternehmensId,
        $Branche,
        [Parameter(HelpMessage = "gültige Werte sind 'Anzahl0001bis9,Anzahl0010bis49,Anzahl0050bis149,Anzahl0150bis499,Anzahl0500bis4999,Anzahl5000UndMehr'")]
        [string]$Mitarbeiteranzahl,
        [int]$FinmaRegisternummer,
        [boolean]$Aufnahmesperre,
        [boolean]$Aktiv,
        [Parameter(HelpMessage = "Liste von Kommunikationsmittel (erstellt z.B. mit New-Kommunikationsmittel-Object)")]
        [array]$KommunikationsmittelListe,
        [Parameter(Mandatory, HelpMessage = "Sicherheitseinstellung (erstellt z.B. mit New-Sicherheitseinstellung-Object)")]
        [PSCustomObject]$SicherheitsEinstellung,
        [Parameter(HelpMessage = "Liste von Tags welche dieser Organisation hinzugefügt werden sollen")]
        [array]$AddTagsListe
    )
    process {
        $Body = [PSCustomObject]@{
            type                   = "Organisation";
            Organisationsname      = $Organisationsname;
            Korrespondenzsprache   = $Korrespondenzsprache;
            Sicherheitseinstellung = $SicherheitsEinstellung;
        };

        if ($PSBoundParameters.ContainsKey("OrganisationUid")) {
            $OrganisationUid = ConvertTo-WeeduGuid $OrganisationUid;
        }
        else {
            $OrganisationUid = New-Guid;
        }
        $Body | Add-Member -MemberType NoteProperty -Name "Uid" -Value $OrganisationUid;

        if ($PSBoundParameters.ContainsKey("Organisationsform")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Organisationsform" -Value $Organisationsform;
        }
        if ($PSBoundParameters.ContainsKey("UnternehmensId")) {
            $Body | Add-Member -MemberType NoteProperty -Name "UnternehmensId" -Value $UnternehmensId;
        }
        if ($PSBoundParameters.ContainsKey("Branche")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Branche" -Value $Branche;
        }
        if ($PSBoundParameters.ContainsKey("Mitarbeiteranzahl")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Mitarbeiteranzahl" -Value $Mitarbeiteranzahl;
        }
        if ($PSBoundParameters.ContainsKey("FinmaRegisternummer")) {
            $Body | Add-Member -MemberType NoteProperty -Name "FinmaRegisternummer" -Value $FinmaRegisternummer;
        }
        if ($PSBoundParameters.ContainsKey("Aufnahmesperre")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Aufnahmesperre" -Value $Aufnahmesperre;
        }
        if ($PSBoundParameters.ContainsKey("KommunikationsmittelListe")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Kommunikationsmittel" -Value $KommunikationsmittelListe;
        }
        if ($PSBoundParameters.ContainsKey("Aktiv")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Aktiv" -Value $Aktiv;
        }

        $res = Invoke-Weedu -Uri "rest/Personen" -Method POST -Body $Body;
        if ($PSBoundParameters.ContainsKey("AddTagsListe")) {
            Edit-Tags -MasterUid $OrganisationUid -Add ([array]$AddTagsListe)
        }
        return $res;
    }
}

function Set-Organisation {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, HelpMessage = "Uid der Organisation (synthetische oder echte)")]
        $OrganisationUid,
        [string]$Organisationsname,
        [Parameter(HelpMessage = "Bsp.: Firmenstrukturen_Abteilung")]
        [string]$Organisationsform,
        [Parameter(HelpMessage = "de, en, fr, it, usw.")]
        [string]$Korrespondenzsprache,
        [Parameter(HelpMessage = "Format CHE-999.999.999")]
        [string]$UnternehmensId,
        $Branche,
        [Parameter(HelpMessage = "gültige Werte sind 'Anzahl0001bis9,Anzahl0010bis49,Anzahl0050bis149,Anzahl0150bis499,Anzahl0500bis4999,Anzahl5000UndMehr'")]
        [string]$Mitarbeiteranzahl,
        [int]$FinmaRegisternummer,
        [boolean]$Aufnahmesperre,
        [boolean]$Aktiv,
        [Parameter(HelpMessage = "Liste von Kommunikationsmittel (erstellt z.B. mit New-Kommunikationsmittel-Object)")]
        [array]$KommunikationsmittelListe,
        [Parameter(HelpMessage = "Liste von Tags welche dieser Organisation hinzugefügt werden sollen")]
        [array]$AddTagsListe,
        [Parameter(HelpMessage = "Liste von Tags welche auf dieser Organisation gelöscht werden sollen")]
        [array]$RemoveTagsListe
    )
    process {
        $OrganisationGuid = ConvertTo-WeeduGuid $OrganisationUid;
        $Body = [PSCustomObject]@{
            type = "Organisation";
        };

        if ($PSBoundParameters.ContainsKey("Organisationsname")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Organisationsname" -Value $Organisationsname;
        }
        if ($PSBoundParameters.ContainsKey("Organisationsform")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Organisationsform" -Value $Organisationsform;
        }
        if ($PSBoundParameters.ContainsKey("Korrespondenzsprache")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Korrespondenzsprache" -Value $Korrespondenzsprache;
        }
        if ($PSBoundParameters.ContainsKey("UnternehmensId")) {
            $Body | Add-Member -MemberType NoteProperty -Name "UnternehmensId" -Value $UnternehmensId;
        }
        if ($PSBoundParameters.ContainsKey("Branche")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Branche" -Value $Branche;
        }
        if ($PSBoundParameters.ContainsKey("Mitarbeiteranzahl")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Mitarbeiteranzahl" -Value $Mitarbeiteranzahl;
        }
        if ($PSBoundParameters.ContainsKey("FinmaRegisternummer")) {
            $Body | Add-Member -MemberType NoteProperty -Name "FinmaRegisternummer" -Value $FinmaRegisternummer;
        }
        if ($PSBoundParameters.ContainsKey("Aufnahmesperre")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Aufnahmesperre" -Value $Aufnahmesperre;
        }
        if ($PSBoundParameters.ContainsKey("Aktiv")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Aktiv" -Value $Aktiv;
        }

        if ($PSBoundParameters.ContainsKey("AddTagsListe") -or $PSBoundParameters.ContainsKey("RemoveTagsListe")) {
            if (-not $PSBoundParameters.ContainsKey("AddTagsListe")) {
                $AddTagsListe = @();
            }
            if (-not $PSBoundParameters.ContainsKey("RemoveTagsListe")) {
                $RemoveTagsListe = @();
            }
            Edit-Tags -MasterUid $OrganisationUid -Add $AddTagsListe -Remove $RemoveTagsListe;
        }

        if ($KommunikationsmittelListe -ne $null) {
            Set-PersonKommunikationsmittel -PersonUid $OrganisationUid -KommunikationsmittelListe $KommunikationsmittelListe;
        }

        return Invoke-Weedu -Uri "/rest/Personen/{0}" -UriParams $OrganisationGuid -Method PUT -Body $Body;
    }
}

function New-Familie {
    [CmdletBinding()]
    param(
        [Parameter(HelpMessage = "Uid der Familie (synthetische oder echte)")]
        $FamilieUid,
        [Parameter(Mandatory)]
        [string]$Familienname,
        [Parameter(HelpMessage = "John, Jane, Jérôme, Isabella")]
        [string]$Vornamen,
        [Parameter(Mandatory, HelpMessage = "de, en, fr, it, usw.")]
        [string]$Korrespondenzsprache,
        [boolean]$Aktiv,
        [Parameter(HelpMessage = "Liste von Kommunikationsmittel (erstellt z.B. mit New-Kommunikationsmittel-Object)")]
        [array]$KommunikationsmittelListe,
        [Parameter(Mandatory, HelpMessage = "Sicherheitseinstellung (erstellt z.B. mit New-Sicherheitseinstellung-Object)")]
        [PSCustomObject]$SicherheitsEinstellung,
        [Parameter(HelpMessage = "Liste von Tags welche dieser Organisation hinzugefügt werden sollen")]
        [array]$AddTagsListe
    )
    process {
        $Body = [PSCustomObject]@{
            type                   = "Familie";
            Familienname           = $Familienname;
            Korrespondenzsprache   = $Korrespondenzsprache;
            Sicherheitseinstellung = $SicherheitsEinstellung;
        };

        if ($PSBoundParameters.ContainsKey("FamilieUid")) {
            $FamilieUid = ConvertTo-WeeduGuid $FamilieUid;
        }
        else {
            $FamilieUid = New-Guid;
        }
        $Body | Add-Member -MemberType NoteProperty -Name "Uid" -Value $FamilieUid;

        if ($PSBoundParameters.ContainsKey("Vornamen")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Vornamen" -Value $Vornamen;
        }
        if ($PSBoundParameters.ContainsKey("KommunikationsmittelListe")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Kommunikationsmittel" -Value $KommunikationsmittelListe;
        }
        if ($PSBoundParameters.ContainsKey("Aktiv")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Aktiv" -Value $Aktiv;
        }

        $res = Invoke-Weedu -Uri "rest/Personen" -Method POST -Body $Body;
        if ($PSBoundParameters.ContainsKey("AddTagsListe")) {
            Edit-Tags -MasterUid $FamilieUid -Add $AddTagsListe;
        }
        return $res;
    }
}

function Set-Familie {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, HelpMessage = "Uid der Familie (synthetische oder echte)")]
        $FamilieUid,
        [string]$Familienname,
        [Parameter(HelpMessage = "John, Jane, Jérôme, Isabella")]
        [string]$Vornamen,
        [Parameter(HelpMessage = "de, en, fr, it, usw.")]
        [string]$Korrespondenzsprache,
        [boolean]$Aktiv,
        [Parameter(HelpMessage = "Liste von Kommunikationsmittel (erstellt z.B. mit New-Kommunikationsmittel-Object)")]
        [array]$KommunikationsmittelListe,
        [Parameter(HelpMessage = "Liste von Tags welche dieser Organisation hinzugefügt werden sollen")]
        [array]$AddTagsListe,
        [Parameter(HelpMessage = "Liste von Tags welche auf dieser Organisation gelöscht werden sollen")]
        [array]$RemoveTagsListe
    )
    process {
        $Body = [PSCustomObject]@{
            type = "Familie";
        };

        $FamilieUid = ConvertTo-WeeduGuid $FamilieUid;
        if ($PSBoundParameters.ContainsKey("Familienname")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Familienname" -Value $Familienname;
        }
        if ($PSBoundParameters.ContainsKey("Vornamen")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Vornamen" -Value $Vornamen;
        }
        if ($PSBoundParameters.ContainsKey("Korrespondenzsprache")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Korrespondenzsprache" -Value $Korrespondenzsprache;
        }
        if ($PSBoundParameters.ContainsKey("Aktiv")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Aktiv" -Value $Aktiv;
        }

        if ($PSBoundParameters.ContainsKey("AddTagsListe") -or $PSBoundParameters.ContainsKey("RemoveTagsListe")) {
            if (-not $PSBoundParameters.ContainsKey("AddTagsListe")) {
                $AddTagsListe = @();
            }
            if (-not $PSBoundParameters.ContainsKey("RemoveTagsListe")) {
                $RemoveTagsListe = @();
            }
            Edit-Tags -MasterUid $FamilieUid -Add $AddTagsListe -Remove $RemoveTagsListe;
        }

        if ($KommunikationsmittelListe -ne $null) {
            Set-PersonKommunikationsmittel -PersonUid $FamilieUid -KommunikationsmittelListe $KommunikationsmittelListe;
        }

        return Invoke-Weedu -Uri "/rest/Personen/{0}" -UriParams $FamilieUid -Method PUT -Body $Body;
    }
}

function New-AbacusMandant {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, HelpMessage = "Mandantennummer")]
        [int]$Mandantennummer,
        [Parameter(Mandatory, HelpMessage = "Mandantenname")]
        [string]$Mandantenname,
        [Parameter(HelpMessage = "Vergibt weedu Kundennummern für diesen Mandanten?")]
        [bool]$WeeduVergibtKundennummer,
        [Parameter(HelpMessage = "Tiefste Kundennummer, die weedu vergeben darf")]
        [int]$AbacusKundennummerRangeMin,
        [Parameter(HelpMessage = "Höchste Kundennummer, die weedu vergeben darf")]
        [int]$AbacusKundennummerRangeMax,
        [Parameter(HelpMessage = "Übermittelt weedu Personendaten für diesen Mandanten?")]
        [bool]$WeeduUebermitteltPersonendaten,
        [Parameter(HelpMessage = "Verwaltet weedu die Mitarbeiter für diesen Mandanten?")]
        [bool]$WeeduVerwaltetMitarbeiter,
        [Parameter(Mandatory, HelpMessage = "Sicherheitseinstellung (erstellt z.B. mit New-Sicherheitseinstellung-Object)")]
        [PSCustomObject]$SicherheitsEinstellung
    )
    process {
        $Body = [PSCustomObject]@{
            Mandantennummer        = $Mandantennummer;
            Mandantenname          = $Mandantenname;
            Sicherheitseinstellung = $SicherheitsEinstellung;
        };
        if ($PSBoundParameters.ContainsKey("WeeduVergibtKundennummer")) {
            $Body | Add-Member -MemberType NoteProperty -Name "WeeduVergibtKundennummer" -Value $WeeduVergibtKundennummer;
        }
        if ($PSBoundParameters.ContainsKey("AbacusKundennummerRangeMin")) {
            $Body | Add-Member -MemberType NoteProperty -Name "AbacusKundennummerRangeMin" -Value $AbacusKundennummerRangeMin;
        }
        if ($PSBoundParameters.ContainsKey("AbacusKundennummerRangeMax")) {
            $Body | Add-Member -MemberType NoteProperty -Name "AbacusKundennummerRangeMax" -Value $AbacusKundennummerRangeMax;
        }
        if ($PSBoundParameters.ContainsKey("WeeduUebermitteltPersonendaten")) {
            $Body | Add-Member -MemberType NoteProperty -Name "WeeduUebermitteltPersonendaten" -Value $WeeduUebermitteltPersonendaten;
        }
        if ($PSBoundParameters.ContainsKey("WeeduVerwaltetMitarbeiter")) {
            $Body | Add-Member -MemberType NoteProperty -Name "WeeduVerwaltetMitarbeiter" -Value $WeeduVerwaltetMitarbeiter;
        }
        return Invoke-Weedu -Uri "rest/AbacusMandanten" -Method POST -Body $Body;
    }
}

function New-Anlass {
    [CmdletBinding()]
    param(
        [Parameter(HelpMessage = "WeeduUid des Anlasses (synthetische oder echte)")]
        $AnlassUid,
        [Parameter(Mandatory, HelpMessage = "Anlass-Typ, der erstellt werden soll")]
        $Type,
        [Parameter(HelpMessage = "WeeduUid einer Modulversion")]
        $ModulversionUid,
        [Parameter(Mandatory, HelpMessage = "Kurzbezeichnung für den Anlass")]
        $Kurzbezeichnung,
        [Parameter(HelpMessage = "Ergänzende Bezeichnung für den Anlass")]
        $ErgaenzendeBezeichnung,
        [Parameter(HelpMessage = "Format 2013-05-01T00:00:00Z")]
        $Starttermin,
        [Parameter(HelpMessage = "Format 2013-05-01T00:00:00Z")]
        $Endtermin,
        [Parameter(HelpMessage = "Gibt an, ob Anmeldungen möglich sind")]
        [bool]$Anmeldbar,
        [Parameter(HelpMessage = "Lehrpersonen, die dam Anlass zugeordnet werden")]
        [array]$Lehrpersonen,
        [Parameter(Mandatory, HelpMessage = "Sicherheitseinstellung (erstellt z.B. mit New-Sicherheitseinstellung-Object)")]
        [PSCustomObject]$SicherheitsEinstellung
    )
    process {
        $Body = [PSCustomObject]@{
            type                   = $Type;
            Kurzbezeichnung        = $Kurzbezeichnung;
            Sicherheitseinstellung = $SicherheitsEinstellung;
        };
        if ($PSBoundParameters.ContainsKey("AnlassUid")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Uid" -Value $AnlassUid;
        }
        if ($PSBoundParameters.ContainsKey("ModulversionUid")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Modulversion" -Value $ModulversionUid;
        }
        if ($PSBoundParameters.ContainsKey("ErgaenzendeBezeichnung")) {
            $Body | Add-Member -MemberType NoteProperty -Name "ErgaenzendeBezeichnung" -Value $ErgaenzendeBezeichnung;
        }
        if ($PSBoundParameters.ContainsKey("Starttermin")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Starttermin" -Value $Starttermin;
        }
        if ($PSBoundParameters.ContainsKey("Endtermin")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Endtermin" -Value $Endtermin;
        }
        if ($PSBoundParameters.ContainsKey("Anmeldbar")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Anmeldbar" -Value $Anmeldbar;
        }
        if ($PSBoundParameters.ContainsKey("Lehrpersonen")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Lehrpersonen" -Value ($Lehrpersonen | ForEach-Object { ConvertTo-WeeduGuid $_ });
        }
        return Invoke-Weedu -Uri "rest/Anlaesse" -Method POST -Body $Body;
    }
}

function New-Anmeldung {
    [CmdletBinding()]
    param(
        [Parameter(HelpMessage = "WeeduUid der Anmeldung (synthetische oder echte)")]
        $AnmeldungUid,
        [Parameter(HelpMessage = "WeeduUid eines Anlasses")]
        $AnlassUid,
        [Parameter(HelpMessage = "WeeduUid einer Modulversion")]
        $ModulversionUid,
        [Parameter(Mandatory, HelpMessage = "WeeduUid einer Person")]
        $LeistungsempfaengerUid,
        [Parameter(HelpMessage = "Format 2013-05-01T00:00:00Z")]
        $EingangAnmeldung,
        [Parameter(HelpMessage = "WeeduUid einer Person")]
        $VertragspartnerUid,
        [Parameter(HelpMessage = "WeeduUids von Personen als Array")]
        [array]$WeitereVertragspartnerUids,
        [Parameter(HelpMessage = "WeeduUids von Personen als Array")]
        [array]$WeitereBetroffenePersonenUids,
        [Parameter(HelpMessage = "Format 2013-07-21T00:00:00Z")]
        $Vertragsabschluss,
        [Parameter(HelpMessage = "Format 2014-04-01T00:00:00Z")]
        $GewuenschterStart,
        [Parameter(HelpMessage = "WeeduUid eines Kommunikationsmittels")]
        $LieferadresseUid,
        [Parameter(HelpMessage = "Format 2013-05-01T00:00:00Z")]
        $Kuendigungstermin,
        [Parameter(HelpMessage = "Format 2013-05-01T00:00:00Z")]
        $Kuendigungseingang,
        [Parameter(HelpMessage = "Format 2013-05-01T00:00:00Z")]
        $AbweichenderStarttermin,
        [Parameter(HelpMessage = "Format 2013-05-01T00:00:00Z")]
        $AbweichenderEndtermin,
        [string]$Bemerkungen,
        [Parameter(HelpMessage = "Mögliche Status: 'Abgeschlossen, Annulliert, Definitiv, Gekuendigt, Geloescht, InVerlaengerung, KeineDurchfuehrung, Laeuft, Pendent, Unterbrochen'")]
        [string]$Status
    )
    process {
        $Body = [PSCustomObject]@{
            type                = "Anmeldung";
            Leistungsempfaenger = ConvertTo-WeeduGuid $LeistungsempfaengerUid;
        };
        if ($PSBoundParameters.ContainsKey("AnmeldungUid")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Uid" -Value $AnmeldungUid;
        }
        if ($PSBoundParameters.ContainsKey("AnlassUid")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Anlass" -Value $AnlassUid;
        }
        if ($PSBoundParameters.ContainsKey("ModulversionUid")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Modulversion" -Value $ModulversionUid;
        }
        if ($PSBoundParameters.ContainsKey("EingangAnmeldung")) {
            $Body | Add-Member -MemberType NoteProperty -Name "EingangAnmeldung" -Value $EingangAnmeldung;
        }
        if ($PSBoundParameters.ContainsKey("VertragspartnerUid")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Vertragspartner" -Value $VertragspartnerUid;
        }
        if ($PSBoundParameters.ContainsKey("WeitereVertragspartnerUids")) {
            $Body | Add-Member -MemberType NoteProperty -Name "WeitereVertragspartner" -Value $WeitereVertragspartnerUids;
        }
        if ($PSBoundParameters.ContainsKey("WeitereBetroffenePersonenUids")) {
            $Body | Add-Member -MemberType NoteProperty -Name "WeitereBetroffenePersonen" -Value $WeitereBetroffenePersonenUids;
        }
        if ($PSBoundParameters.ContainsKey("Vertragsabschluss")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Vertragsabschluss" -Value $Vertragsabschluss;
        }
        if ($PSBoundParameters.ContainsKey("GewuenschterStart")) {
            $Body | Add-Member -MemberType NoteProperty -Name "GewuenschterStart" -Value $GewuenschterStart;
        }
        if ($PSBoundParameters.ContainsKey("LieferadresseUid")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Lieferadresse" -Value $LieferadresseUid;
        }
        if ($PSBoundParameters.ContainsKey("Kuendigungstermin")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Kuendigungstermin" -Value $Kuendigungstermin;
        }
        if ($PSBoundParameters.ContainsKey("Kuendigungseingang")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Kuendigungseingang" -Value $Kuendigungseingang;
        }
        if ($PSBoundParameters.ContainsKey("AbweichenderStarttermin")) {
            $Body | Add-Member -MemberType NoteProperty -Name "AbweichenderStarttermin" -Value $AbweichenderStarttermin;
        }
        if ($PSBoundParameters.ContainsKey("AbweichenderEndtermin")) {
            $Body | Add-Member -MemberType NoteProperty -Name "AbweichenderEndtermin" -Value $AbweichenderEndtermin;
        }
        if ($PSBoundParameters.ContainsKey("Bemerkungen")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Bemerkungen" -Value $Bemerkungen;
        }
        if ($PSBoundParameters.ContainsKey("Status")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Status" -Value $Status;
        }

        return Invoke-Weedu -Uri "rest/Anmeldungen" -Method POST -Body $Body;
    }
}

function Set-Anmeldung {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, HelpMessage = "WeeduUid der Anmeldung (synthetische oder echte)")]
        $AnmeldungUid,
        [Parameter(HelpMessage = "WeeduUid eines Anlasses")]
        $AnlassUid,
        [Parameter(HelpMessage = "WeeduUid einer Modulversion")]
        $ModulversionUid,
        [Parameter(HelpMessage = "WeeduUid einer Person")]
        $LeistungsempfaengerUid,
        [Parameter(HelpMessage = "Format 2013-05-01T00:00:00Z")]
        $EingangAnmeldung,
        [Parameter(HelpMessage = "WeeduUid einer Person")]
        $VertragspartnerUid,
        [Parameter(HelpMessage = "WeeduUids von Personen als Array")]
        [array]$WeitereVertragspartnerUids,
        [Parameter(HelpMessage = "WeeduUids von Personen als Array")]
        [array]$WeitereBetroffenePersonenUids,
        [Parameter(HelpMessage = "Format 2013-07-21T00:00:00Z")]
        $Vertragsabschluss,
        [Parameter(HelpMessage = "Format 2014-04-01T00:00:00Z")]
        $GewuenschterStart,
        [Parameter(HelpMessage = "WeeduUid eines Kommunikationsmittels")]
        $LieferadresseUid,
        [Parameter(HelpMessage = "Format 2013-05-01T00:00:00Z")]
        $Kuendigungstermin,
        [Parameter(HelpMessage = "Format 2013-05-01T00:00:00Z")]
        $Kuendigungseingang,
        [Parameter(HelpMessage = "Format 2013-05-01T00:00:00Z")]
        $AbweichenderStarttermin,
        [Parameter(HelpMessage = "Format 2013-05-01T00:00:00Z")]
        $AbweichenderEndtermin,
        [string]$Bemerkungen,
        [Parameter(HelpMessage = "Mögliche Status: 'Abgeschlossen, Annulliert, Definitiv, Gekuendigt, Geloescht, InVerlaengerung, KeineDurchfuehrung, Laeuft, Pendent, Unterbrochen'")]
        [string]$Status
    )
    process {
        $Body = [PSCustomObject]@{
            type = "Anmeldung";
        };
        if ($PSBoundParameters.ContainsKey("AnlassUid")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Anlass" -Value $AnlassUid;
        }
        if ($PSBoundParameters.ContainsKey("ModulversionUid")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Modulversion" -Value $ModulversionUid;
        }
        if ($PSBoundParameters.ContainsKey("EingangAnmeldung")) {
            $Body | Add-Member -MemberType NoteProperty -Name "EingangAnmeldung" -Value $EingangAnmeldung;
        }
        if ($PSBoundParameters.ContainsKey("VertragspartnerUid")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Vertragspartner" -Value $VertragspartnerUid;
        }
        if ($PSBoundParameters.ContainsKey("WeitereVertragspartnerUids")) {
            $Body | Add-Member -MemberType NoteProperty -Name "WeitereVertragspartner" -Value $WeitereVertragspartnerUids;
        }
        if ($PSBoundParameters.ContainsKey("WeitereBetroffenePersonenUids")) {
            $Body | Add-Member -MemberType NoteProperty -Name "WeitereBetroffenePersonen" -Value $WeitereBetroffenePersonenUids;
        }
        if ($PSBoundParameters.ContainsKey("Vertragsabschluss")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Vertragsabschluss" -Value $Vertragsabschluss;
        }
        if ($PSBoundParameters.ContainsKey("GewuenschterStart")) {
            $Body | Add-Member -MemberType NoteProperty -Name "GewuenschterStart" -Value $GewuenschterStart;
        }
        if ($PSBoundParameters.ContainsKey("LieferadresseUid")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Lieferadresse" -Value $LieferadresseUid;
        }
        if ($PSBoundParameters.ContainsKey("Kuendigungstermin")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Kuendigungstermin" -Value $Kuendigungstermin;
        }
        if ($PSBoundParameters.ContainsKey("Kuendigungseingang")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Kuendigungseingang" -Value $Kuendigungseingang;
        }
        if ($PSBoundParameters.ContainsKey("AbweichenderStarttermin")) {
            $Body | Add-Member -MemberType NoteProperty -Name "AbweichenderStarttermin" -Value $AbweichenderStarttermin;
        }
        if ($PSBoundParameters.ContainsKey("AbweichenderEndtermin")) {
            $Body | Add-Member -MemberType NoteProperty -Name "AbweichenderEndtermin" -Value $AbweichenderEndtermin;
        }
        if ($PSBoundParameters.ContainsKey("Bemerkungen")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Bemerkungen" -Value $Bemerkungen;
        }
        if ($PSBoundParameters.ContainsKey("Status")) {
            $Body | Add-Member -MemberType NoteProperty -Name "Status" -Value $Status;
        }

        return Invoke-Weedu -Uri "rest/Anmeldungen/{0}" -UriParams @(ConvertTo-WeeduGuid $AnmeldungUid) -Method PUT -Body $Body;
    }
}

function Edit-Tags {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, HelpMessage = "WeeduUid der Entität")]
        $MasterUid,
        [Parameter(HelpMessage = "String array der Tags welche hinzugefügt werden sollen")]
        [string[]]$Add,
        [Parameter(HelpMessage = "String array der Tags welche entfernt werden sollen")]
        [string[]]$Remove
    )
    process {
        $Body = [PSCustomObject]@{};
        if ($PSBoundParameters.ContainsKey("Add")) {
            $Body | Add-Member -MemberType NoteProperty -Name "add" -Value $Add;
        }
        if ($PSBoundParameters.ContainsKey("Remove")) {
            $Body | Add-Member -MemberType NoteProperty -Name "remove" -Value $Remove;
        }

        return Invoke-Weedu -Uri "rest/Entitaet/{0}/Tags" -UriParams @((ConvertTo-WeeduGuid $MasterUid)) -Method POST -Body $Body;
    }
}

function Remove-TransferAnAbacus {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, HelpMessage = "WeeduUid des Transfers an Abacus (synthetische oder echte)", ValueFromPipeline, Position = 0)]
        $TransferAnAbacusUid,
        [Parameter(Mandatory, HelpMessage = "Grund der Quittierung des Transfers an Abacus")]
        [string]$Kommentar
    )
    process {
        $Body = [PSCustomObject]@{
            Kommentar = $Kommentar;
        };

        Invoke-Weedu -Uri "rest/TransfersAnAbacus/{0}/Quittieren" -UriParams @((ConvertTo-WeeduGuid $TransferAnAbacusUid)) -Method POST -Body $Body; ;
    }   
}

function Invoke-TransferAnAbacusErneutSenden {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, HelpMessage = "WeeduUid einer TransferAnAbacus Entität", ValueFromPipeline)]
        $TransferAnAbacusUid
    )
    process {
        $Body = [PSCustomObject]@{};
        return Invoke-Weedu -Uri "/rest/TransfersAnAbacus/{0}/ErneutSenden" -UriParams @((ConvertTo-WeeduGuid $TransferAnAbacusUid)) -Method POST -Body $Body;
    }
}


function Enable-WeeduSyncOperation {
    $script:forceSync = $true
}

function Disable-WeeduSyncOperation {
    $script:forceSync = $false
}

function Get-AusgabeKanaelStatusFuerEntitaet {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, HelpMessage = "EntitaetUid für welche die Ausgabe Kanaele geprüft werden.")]
        $EntitaetUid
    )
    process {
        Invoke-Weedu -Uri "rest/AusgabeKanalStatus/{0}" -UriParams @(ConvertTo-WeeduGuid $EntitaetUid) -Method GET;
    }
}


Export-ModuleMember -function Connect-Weedu
Export-ModuleMember -function Disconnect-Weedu
Export-ModuleMember -function Test-IsWeeduConnected

Export-ModuleMember -function Join-Batch
Export-ModuleMember -function Test-EntityExistsInIndex
Export-ModuleMember -function Invoke-Weedu
Export-ModuleMember -function Invoke-WqlQuery
Export-ModuleMember -function Invoke-WeeduSearch
Export-ModuleMember -function Get-PersonenMapping
Export-ModuleMember -function Set-PersonenMapping
Export-ModuleMember -function Invoke-RechnungStorno
Export-ModuleMember -function Invoke-RechnungErneutVerrechnen
Export-ModuleMember -function Invoke-RechnungVersendenPerMail
Export-ModuleMember -function Remove-Rechnung
Export-ModuleMember -function New-Quellprodukt-Object
Export-ModuleMember -function Get-Rechnungsvorschau
Export-ModuleMember -function New-Sicherheitseinstellung-Object
Export-ModuleMember -function Get-Sicherheitseinstellung
Export-ModuleMember -function Add-SicherheitseinstellungGruppe
Export-ModuleMember -function New-IndexRegel
Export-ModuleMember -function Set-IndexRegel
Export-ModuleMember -function Get-IndexRegel
Export-ModuleMember -function New-Einzelperson
Export-ModuleMember -function Set-Einzelperson
Export-ModuleMember -function New-Organisation
Export-ModuleMember -function Set-Organisation
Export-ModuleMember -function New-Familie
Export-ModuleMember -function Set-Familie
Export-ModuleMember -function New-PostAdresse-Object
Export-ModuleMember -function New-Kommunikationsmittel-Object
Export-ModuleMember -function New-PersonKommunikationsmittel
Export-ModuleMember -function Set-PersonKommunikationsmittel
Export-ModuleMember -function Set-Kommunikationsmittel
Export-ModuleMember -function New-Anmeldung
Export-ModuleMember -function Set-Anmeldung
Export-ModuleMember -function Enable-ExternalLogin
Export-ModuleMember -function Disable-ExternalLogin
Export-ModuleMember -function ConvertTo-WeeduGuid
Export-ModuleMember -function ConvertTo-WeeduDateString
Export-ModuleMember -function ConvertTo-WeeduPriorityList
Export-ModuleMember -function New-Multiplikator-Object
Export-ModuleMember -function Add-Multiplikator
Export-ModuleMember -function Invoke-ProduktFakturieren
Export-ModuleMember -function New-Fakturierungsabschnitt
Export-ModuleMember -function Set-Fakturierungsabschnitt
Export-ModuleMember -function Remove-Fakturierungsabschnitt
Export-ModuleMember -function Get-RechnungsSplit
Export-ModuleMember -function New-RechnungsSplit
Export-ModuleMember -function Set-RechnungsSplit
Export-ModuleMember -function Remove-RechnungsSplit
Export-ModuleMember -function New-Teilverrechnung-Object
Export-ModuleMember -function Set-AnmeldungsFakturierung
Export-ModuleMember -function Remove-AnmeldungsFakturierung
Export-ModuleMember -function Invoke-AnmeldungFakturieren
Export-ModuleMember -function New-Anlass
Export-ModuleMember -function New-AbacusMandant
Export-ModuleMember -function Invoke-ProcessIndexUpdates
Export-ModuleMember -function Enable-WeeduSyncOperation
Export-ModuleMember -function Disable-WeeduSyncOperation
Export-ModuleMember -function Remove-TransferAnAbacus
Export-ModuleMember -function Invoke-TransferAnAbacusErneutSenden
Export-ModuleMember -function Edit-Tags
Export-ModuleMember -function Get-AusgabeKanaelStatusFuerEntitaet