Billomat.psm1
$baseUrl = "https://guidnew.billomat.net/api"; <# .SYNOPSIS Connects to Billomat. .DESCRIPTION Credentials can be persisted using https://www.powershellgallery.com/packages/CredentialsManager/ by setting the parameter UseCredentialsManager to $True. o $Credential -eq $Null -and $UseCredentialsManager -eq $Null -> credentials are requested and are not persisted o $Credential -ne $Null -and $UseCredentialsManager -eq $Null -> passed credentials are used and not persisted o $Credential -ne $Null -and $UseCredentialsManager -ne $Null -> passed credentials are used and persisted o $Credential -eq $Null -and $UseCredentialsManager -ne $Null -> Persisted credentials are used .PARAMETER Credential Credential to access Billomat with. I not provided they get requested. .PARAMETER UseCredentialsManager If $True, credentials are read and written using the CredentialsManager. Only Password part, containing the APIKey, is used. #> function Connect-BMT { [CmdletBinding()] Param( [PSCredential]$Credential, [Boolean]$UseCredentialsManager = $False ) #end param # check module prerequisites if($UseCredentialsManager) { $module = Get-Module -ListAvailable -Name "CredentialsManager"; if (!$module) { throw "Module 'CredentialsManager' needed. Please install executing 'Install-Module -Name CredentialsManager' as Administrator."; } } if($UseCredentialsManager -and $Credential -eq $Null) { $Credential = Read-Credential -ListAvailable | Where { $_.Environment -eq "Billomat" } } if(!$Credential) { $Credential = Get-Credential -Message "Please enter API Key for Billomat as password (username can be anything)."; } if($UseCredentialsManager) { Write-Credential "Billomat" -Credential $Credential; } $script:key = $Credential.GetNetworkCredential().password ; } class InvoiceItem { [string]$unit [decimal]$quantity [decimal]$unit_price [string]$title [string]$description } <# .SYNOPSIS Adds an invoice to Billomat. .DESCRIPTION .PARAMETER ClientId Id of client to add the invoice for .PARAMETER Label Optional Label of Invoice .PARAMETER InvoiceItems Items of the Invoice #> function Add-BMTInvoice { [CmdletBinding()] Param( [Parameter(Mandatory=$true)][string]$ClientId, [string]$Label, [InvoiceItem[]]$InvoiceItems ) #end param if(!$script:key) { Connect-BMT -UseCredentialsManager $True; } $parameters = @{ api_key=$script:key; } $uri = New-HttpQueryString "${baseUrl}/invoices" $parameters $bodyAsJson = ConvertTo-JSON( @{ invoice= @{ client_id=$ClientId; label=$Label; } }); $result = $(Invoke-RestMethod -Uri $uri -Method Post -Body $bodyAsJson -ContentType "application/json; charset=utf-8" -Headers @{Accept="application/json"}); foreach($item in $InvoiceItems) { Add-BMTInvoiceItem -InvoiceId $result.invoice.id -Item $item | Out-Null; } return $result.invoice; } <# .SYNOPSIS Adds an item to an invoice. .DESCRIPTION .PARAMETER InvoiceId Id of invoice to add item to .PARAMETER Item Item to be added #> function Add-BMTInvoiceItem { [CmdletBinding()] Param( [Parameter(Mandatory=$true)][string]$InvoiceId, [InvoiceItem]$Item ) #end param if(!$script:key) { Connect-BMT -UseCredentialsManager $True; } $parameters = @{ api_key=$script:key; } $uri = New-HttpQueryString "${baseUrl}/invoice-items" $parameters $bodyAsJson = ConvertTo-JSON( @{ "invoice-item"= @{ invoice_id=$InvoiceId; unit=$Item.unit; unit_price=$Item.unit_price; quantity=$Item.quantity; title=$Item.title; description=$Item.description; } }); $result = $(Invoke-RestMethod -Uri $uri -Method Post -Body $bodyAsJson -ContentType "application/json; charset=utf-8" -Headers @{Accept="application/json"}); return $result."invoice-item" } class CreditNoteItem { [string]$unit [decimal]$quantity [decimal]$unit_price [string]$title [string]$tax_name [decimal]$tax_rate [string]$description } <# .SYNOPSIS Adds a credit note to Billomat. .DESCRIPTION .PARAMETER ClientId Id of client to add the credit note for .PARAMETER Label Optional Label of Credit Note .PARAMETER TemplateId Optional Id of Template to use .PARAMETER CreditNoteItems Items of the Credit note #> function Add-BMTCreditNote { [CmdletBinding()] Param( [Parameter(Mandatory=$true)] [string]$ClientId, [string]$Label, [decimal]$TemplateId, [CreditNoteItem[]]$CreditNoteItems ) #end param if(!$script:key) { Connect-BMT -UseCredentialsManager $True; } $parameters = @{ api_key=$script:key; } $uri = New-HttpQueryString "${baseUrl}/credit-notes" $parameters $creditNote = @{ client_id=$ClientId; } if($label) { $creditNote.Add("label", $Label); } if($template_id) { $creditNote.Add("template_id", $TemplateId); } $bodyAsJson = ConvertTo-JSON( @{ "credit-note"= $creditNote }); $result = $(Invoke-RestMethod -Uri $uri -Method Post -Body $bodyAsJson -ContentType "application/json; charset=utf-8" -Headers @{Accept="application/json"}); foreach($item in $CreditNoteItems) { Add-BMTCreditNoteItem -CreditNoteId $result."credit-note".id -Item $item | Out-Null; } return $result."credit-note"; } <# .SYNOPSIS Adds an item to a credit note. .DESCRIPTION .PARAMETER CreditNoteId Id of credit note to add item to .PARAMETER Item Item to be added #> function Add-BMTCreditNoteItem { [CmdletBinding()] Param( [Parameter(Mandatory=$true)][string]$CreditNoteId, [CreditNoteItem]$Item ) #end param if(!$script:key) { Connect-BMT -UseCredentialsManager $True; } $parameters = @{ api_key=$script:key; } $uri = New-HttpQueryString "${baseUrl}/credit-note-items" $parameters $creditNoteItem = @{ credit_note_id=$CreditNoteId; } if($Item.unit) { $creditNoteItem.Add("unit", $Item.unit); } if($Item.unit_price) { $creditNoteItem.Add("unit_price", $Item.unit_price); } if($Item.quantity) { $creditNoteItem.Add("quantity", $Item.quantity); } if($Item.title) { $creditNoteItem.Add("title", $Item.title); } if($Item.tax_name) { $creditNoteItem.Add("tax_name", $Item.tax_name); } if($Item.tax_rate) { $creditNoteItem.Add("tax_rate", $Item.tax_rate); } if($Item.description) { $creditNoteItem.Add("description", $Item.description); } $bodyAsJson = ConvertTo-JSON( @{ "credit-note-item"= $creditNoteItem }); $result = $(Invoke-RestMethod -Uri $uri -Method Post -Body $bodyAsJson -ContentType "application/json; charset=utf-8" -Headers @{Accept="application/json"}); return $result."credit-note-item" } <# .SYNOPSIS Get Invoice Payments by Invoice Id or from/until .PARAMETER InvoiceId Id of Invoice to filter the payments for. .PARAMETER From Date from which on to receive payments. Only date-part is considered. .PARAMETER To Date until which on to receive payments to. Only date-part is considered. #> function Get-BMTInvoicePayments { [CmdletBinding()] Param( [string]$InvoiceId, [DateTime]$From, [DateTime]$To ) if(!$script:key) { Connect-BMT -UseCredentialsManager $True; } $parameters = @{ api_key=$script:key; } if($InvoiceId) { $parameters.Add("invoice_id", $InvoiceId) } if($From) { $parameters.Add("from", $From.ToString('yyyy-MM-dd')) } if($To) { $parameters.Add("to", $To.ToString('yyyy-MM-dd')) } $uri = New-HttpQueryString "${baseUrl}/invoice-payments" $parameters $response = Invoke-RestMethod -Uri $uri -Method Get -ContentType "application/json; charset=utf-8" -Headers @{Accept="application/json"}; if($response."invoice-payments"."@total" -eq 0) { return @(); } return $response."invoice-payments"."invoice-payment" } <# .SYNOPSIS Get Invoice by ClientId or Status from Billomat .PARAMETER ClientId Optional Id of client to get. .PARAMETER Status Optional Status of invoices to get (DRAFT, OPEN, PAID, OVERDUE, CANCELED). Separate by comma for multiple stati .PARAMETER From Optional startdate to get invoices from .PARAMETER To Optional enddate to get invoices until #> function Get-BMTInvoices { [CmdletBinding()] Param( [string]$ClientId, [string]$Status, [DateTime]$From, [DateTime]$To ) if(!$script:key) { Connect-BMT -UseCredentialsManager $True; } $parameters = @{ api_key=$script:key; } if($ClientId) { $parameters.Add("client_id", $ClientId) } if($Status) { $parameters.Add("status", $Status) } if($From) { $parameters.Add("from", $From.ToString('yyyy-MM-dd')) } if($To) { $parameters.Add("to", $To.ToString('yyyy-MM-dd')) } $uri = New-HttpQueryString "${baseUrl}/invoices" $parameters $response = Invoke-RestMethod -Uri $uri -Method Get -ContentType "application/json; charset=utf-8" -Headers @{Accept="application/json"}; if($response.invoices."@total" -eq 0) { return @(); } return $response.invoices.invoice } <# .SYNOPSIS Get Invoice by InvoiceId .PARAMETER Id Id of invoice to get. #> function Get-BMTInvoice { [CmdletBinding()] Param( [Parameter(Mandatory = $true)][long]$Id ) if(!$script:key) { Connect-BMT -UseCredentialsManager $True; } $parameters = @{ api_key=$script:key; } $uri = New-HttpQueryString "${baseUrl}/invoices/${Id}" $parameters $response = Invoke-RestMethod -Uri $uri -Method Get -ContentType "application/json; charset=utf-8" -Headers @{Accept="application/json"}; return $response.invoice } <# .SYNOPSIS Get Templates from Billomat .PARAMETER type Optional Type of template to filter for (INVOICE, OFFER, CONFIRMATION, REMINDER, DELIVERY_NOTE, CREDIT_NOTE, LETTER). Separate by comma for multiple types #> function Get-BMTTemplates { [CmdletBinding()] Param( [string]$Type ) if(!$script:key) { Connect-BMT -UseCredentialsManager $True; } $parameters = @{ api_key=$script:key; } if($Type) { $parameters.Add("type", $Type) } $uri = New-HttpQueryString "${baseUrl}/templates" $parameters $response = Invoke-RestMethod -Uri $uri -Method Get -ContentType "application/json; charset=utf-8" -Headers @{Accept="application/json"}; if($response.templates."@total" -eq 0) { return @(); } return $response.templates.template } <# .SYNOPSIS Get Client by Name or ClientNumber from Billomat .DESCRIPTION If no client is found, an empty array is returned. .PARAMETER Name Name of client to get. Returns all clients having the given value in their name. .PARAMETER ClientNumber Number of client to get. #> function Get-BMTClients { [CmdletBinding()] Param( [string]$Name, [string]$ClientNumber ) if(!$script:key) { Connect-BMT -UseCredentialsManager $True; } $parameters = @{ api_key=$script:key; } if($Name) { $parameters.Add("name", $Name) } if($ClientNumber) { $parameters.Add("client_number", $ClientNumber) } $uri = New-HttpQueryString "${baseUrl}/clients" $parameters $response = Invoke-RestMethod -Uri $uri -Method Get -ContentType "application/json; charset=utf-8" -Headers @{Accept="application/json"}; if($response.clients."@total" -eq 0) { return @(); } return $response.clients.client } <# .SYNOPSIS Get Client by Id .DESCRIPTION .PARAMETER Id Id of client to get. #> function Get-BMTClient { [CmdletBinding()] Param( [long]$Id ) if(!$script:key) { Connect-BMT -UseCredentialsManager $True; } $parameters = @{ api_key=$script:key; } $uri = New-HttpQueryString "${baseUrl}/clients/${Id}" $parameters $response = Invoke-RestMethod -Uri $uri -Method Get -ContentType "application/json; charset=utf-8" -Headers @{Accept="application/json"}; return $response.client } <# .SYNOPSIS Get Contacts by client .DESCRIPTION If no contact is found, an empty array is returned. .PARAMETER ClientId Id of client to receive contacts for. #> function Get-BMTContacts { [CmdletBinding()] Param( [int]$ClientId ) if(!$script:key) { Connect-BMT -UseCredentialsManager $True; } $parameters = @{ api_key=$script:key; client_id=$ClientId } $uri = New-HttpQueryString "${baseUrl}/contacts" $parameters $response = Invoke-RestMethod -Uri $uri -Method Get -ContentType "application/json; charset=utf-8" -Headers @{Accept="application/json"}; if($response.contacts."@total" -eq 0) { return @(); } return $response.contacts.contact } <# .SYNOPSIS Get Contact by Id .DESCRIPTION .PARAMETER Id Id of contact to get. #> function Get-BMTContact { [CmdletBinding()] Param( [int]$Id ) if(!$script:key) { Connect-BMT -UseCredentialsManager $True; } $parameters = @{ api_key=$script:key; } $uri = New-HttpQueryString "${baseUrl}/contacts/${Id}" $parameters $response = Invoke-RestMethod -Uri $uri -Method Get -ContentType "application/json; charset=utf-8" -Headers @{Accept="application/json"}; return $response.contact } <# .SYNOPSIS Get Offer by OfferId .PARAMETER Id Id of offer to get. #> function Get-BMTOffer { [CmdletBinding()] Param( [Parameter(Mandatory = $true)][long]$Id ) if(!$script:key) { Connect-BMT -UseCredentialsManager $True; } $parameters = @{ api_key=$script:key; } $uri = New-HttpQueryString "${baseUrl}/offers/${Id}" $parameters $response = Invoke-RestMethod -Uri $uri -Method Get -ContentType "application/json; charset=utf-8" -Headers @{Accept="application/json"}; return $response.offer } <# .SYNOPSIS Get Offers by offernumber .DESCRIPTION .PARAMETER OfferNumber Number of offer to get. #> function Get-BMTOffers { [CmdletBinding()] Param( [string]$OfferNumber ) if(!$script:key) { Connect-BMT -UseCredentialsManager $True; } $parameters = @{ api_key=$script:key; offer_number=$OfferNumber; } $uri = New-HttpQueryString "${baseUrl}/offers" $parameters $response = Invoke-RestMethod -Uri $uri -Method Get -ContentType "application/json; charset=utf-8" -Headers @{Accept="application/json"}; if($response.offers."@total" -eq 0) { return @(); } return $response.offers.offer } ## Private Functions function New-HttpQueryString { [CmdletBinding()] param ( [Parameter(Mandatory = $true)][String]$Uri, [Parameter(Mandatory = $true)][Hashtable]$QueryParameter ) # Add System.Web Add-Type -AssemblyName System.Web # Create a http name value collection from an empty string $nvCollection = [System.Web.HttpUtility]::ParseQueryString([String]::Empty) foreach ($key in $QueryParameter.Keys) { $nvCollection.Add($key, $QueryParameter.$key) } # Build the uri $uriRequest = [System.UriBuilder]$uri $uriRequest.Query = $nvCollection.ToString() return $uriRequest.Uri.OriginalString } |