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, [ValidateSet('SUPPLY_DATE','DELIVERY_DATE','SUPPLY_TEXT', 'DELIVERY_TEXT')]$SupplyDateType, [string]$SupplyDate, [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; supply_date_type=$SupplyDateType; supply_date=$SupplyDate; 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 CurrencyCode Optional CurrencyCode of Credit Note .PARAMETER InvoiceId Optional Id of Invoice the creditnote was created from. .PARAMETER CreditNoteItems Items of the Credit note #> function Add-BMTCreditNote { [CmdletBinding()] Param( [Parameter(Mandatory=$true)] [string]$ClientId, [string]$Label, [decimal]$TemplateId, [string]$CurrencyCode, [long]$InvoiceId, [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($TemplateId) { $creditNote.Add("template_id", $TemplateId); } if($CurrencyCode) { $creditNote.Add("currency_code", $CurrencyCode); } if($InvoiceId) { $creditNote.Add("invoice_id", $InvoiceId); } $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 Return the PDF of the Invoice .PARAMETER Id Id of invoice to get PDF for. #> function Read-BMTInvoicePdf { [CmdletBinding()] Param( [Parameter(Mandatory = $true)][long]$Id ) if(!$script:key) { Connect-BMT -UseCredentialsManager $True; } $parameters = @{ api_key=$script:key; format="pdf" } $uri = New-HttpQueryString "${baseUrl}/invoices/${Id}/pdf" $parameters $response = Invoke-WebRequest -Uri $uri -Method Get -ContentType "application/pdf" -Headers @{Accept="application/pdf"}; return [byte[]]$response.Content; } <# .SYNOPSIS Get Credite Note by CreditNoteId .PARAMETER Id Id of credit note to get. #> function Get-BMTCreditNote { [CmdletBinding()] Param( [Parameter(Mandatory = $true)][long]$Id ) if(!$script:key) { Connect-BMT -UseCredentialsManager $True; } $parameters = @{ api_key=$script:key; } $uri = New-HttpQueryString "${baseUrl}/credit-notes/${Id}" $parameters $response = Invoke-RestMethod -Uri $uri -Method Get -ContentType "application/json; charset=utf-8" -Headers @{Accept="application/json"}; return $response."credit-note" } <# .SYNOPSIS Return the PDF of the CreditNote .PARAMETER Id Id of creditnote to get PDF for. #> function Read-BMTCreditNotePdf { [CmdletBinding()] Param( [Parameter(Mandatory = $true)][long]$Id ) if(!$script:key) { Connect-BMT -UseCredentialsManager $True; } $parameters = @{ api_key=$script:key; format="pdf" } $uri = New-HttpQueryString "${baseUrl}/credit-notes/${Id}/pdf" $parameters $response = Invoke-WebRequest -Uri $uri -Method Get -ContentType "application/pdf" -Headers @{Accept="application/pdf"}; return [byte[]]$response.Content; } <# .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 Custom Attributes are resolved into a flat list .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"}; if($response.client.'client-property-values'.'client-property-value') { $response.client.'client-property-values'.'client-property-value' | ForEach-Object { $response.client | Add-Member -MemberType NoteProperty -Name "property$($_.client_property_id)" -Value $_.value } } 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 Return the PDF of the Offer .PARAMETER Id Id of offer to get PDF for. #> function Read-BMTOfferPdf { [CmdletBinding()] Param( [Parameter(Mandatory = $true)][long]$Id ) if(!$script:key) { Connect-BMT -UseCredentialsManager $True; } $parameters = @{ api_key=$script:key; format="pdf" } $uri = New-HttpQueryString "${baseUrl}/offers/${Id}/pdf" $parameters $response = Invoke-WebRequest -Uri $uri -Method Get -ContentType "application/pdf" -Headers @{Accept="application/pdf"}; return [byte[]]$response.Content; } <# .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 } <# .SYNOPSIS Adds an Inbox document .DESCRIPTION .PARAMETER Content Stream of content of document as byte[] #> function Add-BMTInboxDoc { [CmdletBinding()] Param( [Parameter(ValueFromPipeline)][byte[]]$Content ) if(!$script:key) { Connect-BMT -UseCredentialsManager $True; } $parameters = @{ api_key=$script:key; } $uri = New-HttpQueryString "${baseUrl}/inbox-documents" $parameters $convertedContent = [System.Convert]::ToBase64String($Content); $bodyAsJson = ConvertTo-JSON( @{ "inbox-document"= @{ base64file=$convertedContent; } }); $response = $(Invoke-RestMethod -Uri $uri -Method Post -Body $bodyAsJson -ContentType "application/json; charset=utf-8" -Headers @{Accept="application/json"}); return $response."inbox-document".id; } <# .SYNOPSIS Removes an Inbox file by id .DESCRIPTION .PARAMETER InboxDocumentId Id of InboxDocument to remove #> function Remove-BMTInboxDoc { [CmdletBinding()] Param( [string]$InboxDocumentId ) if(!$script:key) { Connect-BMT -UseCredentialsManager $True; } $parameters = @{ api_key=$script:key; } $uri = New-HttpQueryString "${baseUrl}/inbox-documents/${InboxDocumentId}" $parameters Invoke-RestMethod -Uri $uri -Method Delete -ContentType "application/json; charset=utf-8" -Headers @{Accept="application/json"}; } <# .SYNOPSIS Reads metadata from an InboxDocument by Id .DESCRIPTION .PARAMETER InboxDocumentId Id of InboxDocument to get metadata for .OUTPUTS hashtable containing metadata as key-value-pairs #> function Read-BMTInboxDoc { [CmdletBinding()] Param( [string]$InboxDocumentId ) if(!$script:key) { Connect-BMT -UseCredentialsManager $True; } $parameters = @{ api_key=$script:key; } $uri = New-HttpQueryString "${baseUrl}/inbox-documents/${InboxDocumentId}" $parameters $response = $(Invoke-RestMethod -Uri $uri -Method Get -ContentType "application/json; charset=utf-8" -Headers @{Accept="application/json"}); $result = @{}; foreach($data in $response."inbox-document".metadata.data) { $result.Add($data.key, $data.value); } return $result; } ## 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 } |