Es gibt ja immer wieder Situationen wo man gewisse einmalige oder wiederholende Aufgaben automatisieren möche. Praktischerweise hat CashCtrl ein API mit guter Abdeckung der Funktionalität, aber der Zugriff darauf mit "von Hand" gebauten Requests ist nicht ganz trivial, insbesondere zum Bearbeiten von Entitäten, wo nur ein Teil der Felder, diese aber komplett und in korrektem Format, übertragen werden müssen.
Da ich wieder einmal an dem Punkt war wo ich für viele Buchungen und Aufträge Anpassungen machen musste, konkret in einem bestehenden Mandanten neu Kostenstellen auf allen Buchungen mit Aufwand/Ertrags-Konten und Auftragspositionen in einer Periode einführen, habe ich beschlossen das API besser Scriptbar zu machen via PowerShell. Ein entsprechendes Modul habe ich nun in einer Alpha-Version soweit funktionsfähig fertiggestellt dass ich diese Aufgabe erledigen konnte. Es sind allerdings bereits alle Entitäten von CashCtrl unterstützt (inkl. Abfragen und Updates), da das Modul auf dem bestehenden .NET-API-Client aufbaut.
Hier das konkrete Beispiel, welches für die Periode "2024" auf allen entsprechenden Buchungen die Kostenstelle "10" setzt.
Import-Module C:\CashCtrlPowershellModule\CashCtrl.dll
$credential = [pscredential]::new("1234567890APIKEY1234567890", [securestring]::new())
# Virtuelles Laufwerk mit dem CashCtrl-Provider verbinden
New-PSDrive -name CC -PSProvider CashCtrl -Root mandantname -Credential $credential
Set-Location CC:\
# ID vom Periode 2024 finden
$fiscalperiodId = (Get-ChildItem fiscalperiod | Where-Object { $_.Name -eq "2024" }).Id
# ID vom der Kostenstelle 10 finden
$costCenterId = (Get-ChildItem account\costcenter | Where-Object { $_.Number -eq "10" }).Id
# Vorlageobjekt erstellen für die Kostenstellen-Zuordnung
$allocation = [bsn.CashCtrl.Entities.AccountCostCenterAllocation]::new()
$allocation.ToCostCenterId = $costCenterId
$allocation.Share = 1.0
# Über alle Konten iterieren welche Aufwand oder Ertrag sind
$orderIds = [System.Collections.Generic.HashSet[int]]::new()
foreach ($account in Get-ChildItem account | Where-Object { $_.AccountClass -in "Expense", "Revenue" }) {
Write-Host "$($account.Number): $($account.Name) ($($account.AccountClass), ID:$($account.Id))"
# Über alle Journaleinträge iterieren des betreffenden Kontos und Periode
foreach ($journal in Get-ChildItem journal -AccountId $account.Id -FiscalperiodId $fiscalperiodId -Full) {
Write-Host "Processing $($journal.Type) journal entry $($journal.Id): $($journal.Title)"
switch ($journal.Type) {
"Order" {
# Die ID des zugrundeliegenden Auftrags für später merken, da nicht direkt veränderbar
$orderIds.Add($journal.OrderId) | Out-Null
}
"Manual" {
# Normale Buchung - Kostenstellenzuordnung setzen
$journal.Allocations.Clear()
$journal.Allocations.Add($allocation);
# Buchung aktualisieren
$journal | Set-Item "journal/$($journal.Id)"
}
"Collective" {
# Sammelbuchung - Kostenstellenzuordnung auf den Einträgen setzen
foreach ($item in $journal.Items) {
if ($item.AffectedAccounts[0].AccountClass -in "Expense", "Revenue") {
$item.Allocations.Clear()
$item.Allocations.Add($allocation);
}
}
# Buchung aktualisieren
$journal | Set-Item "journal/$($journal.Id)"
}
}
}
}
# Über alle vermerkten Aufträge iterieren
foreach ($orderId in $orderIds) {
$order = Get-Item "order\$orderId"
Write-Host "Processing order $($order.Id): $($order.Description), $($order.AssociateName)"
# Über alle Artikel-Einträge des Auftrags iterieren und Kostenstellenzuordnung setzen
foreach ($item in $order.Items | Where-Object { $_.Type -eq "Article" }) {
$item.Allocations.Clear()
$item.Allocations.Add($allocation);
}
# Auftrag aktualisieren
$order | Set-Item "order\$orderId"
}
Das entsprechende Modul ist aufgrund des Alpha-Standes noch nicht in der PS-Gallery publiziert, der Source ist aber zusammen mit dem .NET-API-Client von mir Open-Sourced und kann so gebuildet werden.
https://github.com/avonwyss/bsn.CashCtrl