UblionConnect.psm1
Function Log { param( [Parameter(Mandatory=$true)][String]$msg ) $folder = $env:LOCALAPPDATA + "\ublion" $logFile = Join-Path $folder "logfile.txt" $data = (Get-date).ToString() + " " + $msg Add-Content $logFile $data } function Get-UblionLog { param( [switch]$watching ) $folder = $env:LOCALAPPDATA + "\ublion" $logFile = Join-Path $folder "logfile.txt" if ($watching) { Get-Content $logFile -Wait } else { get-content $logFile } } function Get-DownloadFile { [CmdletBinding()] param($id, $filename, $path) #get the pdf as a file base 64 stream $apiGetPDF = "api/services/app/Document/GetDocumentPDF?id="+$id $result = Start-GetResult -request $apiGetPDF $b64 = $result.result.fileBase64 # construct the filename for the pdf $filename = $path+"\"+$filename $fileOutputPdf = $filename+".pdf" # convert the file from base 64 to byte and write it to disk $bytes = [Convert]::FromBase64String($b64) [IO.File]::WriteAllBytes($fileOutputPdf, $bytes) $apiGetUbl = "api/services/app/Ubl/DownloadUbl" $body = "{""id"": ""$id""}" $result = Start-GetResult -request $apiGetUbl -body $body $fileOutputUbl = $filename+".xml" $downloadFile = "/File/DownloadTempFile?FileType="+$result.result.fileType+"&FileToken="+$result.result.fileToken+"&FileName="+$result.result.filename log -msg ("Download file to $fileOutputPdf") Invoke-RestMethod ((Get-UrlHost)+$downloadFile) -OutFile $fileOutputUbl } <# .SYNOPSIS Get modified documents .DESCRIPTION A document is deleiered when it is changing the state and it's not send before with GetModifiedDocuments, It's a infinitely loop .EXAMPLE An example .NOTES General notes #> function Start-GetResultFiles { [CmdletBinding()] param() $DocumentType = @{Outgoing = 25} $ublionConfiguration = Get-UblionConfiguration While ($true) { if( -not (Test-path $resultFolder)) { mkdir $resultFolder } try { # Check for incoming documents $apiGetModifiedFiles = "api/services/app/Document/GetModifiedDocuments" $result = Start-GetResult -request $apiGetModifiedFiles if ($result.result.GetType().Name -eq "Object[]") { #foreach available document foreach ($document in $result.result){ Write-Host $document.type.id $DocumentType.Outgoing if ($document.type.id -eq $DocumentType.Outgoing) { $outbresultFolderound = Join-Path $ublionConfiguration.baseFolder $ublionConfiguration.incomingFolderOrders } else { $outbresultFolderound = Join-Path $ublionConfiguration.baseFolder $ublionConfiguration.incomingFolderInvoices } Get-DownloadFile -id ($document.id) -filename ($document.name) -path ($outbresultFolderound) } } } catch { write-host error $_ } Start-Sleep -Seconds 10 } } <# .SYNOPSIS Get the tenant url .DESCRIPTION Returns the url host .EXAMPLE An example .NOTES General notes #># function Get-UrlHost { "https://"+(Get-UblionConfiguration).tenant+"_connectapi.fan2customer.com/" } <# .SYNOPSIS Create bearer token .DESCRIPTION Create a bearer token based on the login credentials .EXAMPLE An example .NOTES General notes #># function Get-Token{ $token = $global:token if (-not [string]::IsNullOrEmpty($token)){ $token } else { write-host -backgroundcolor green new token required $data = Get-UblionConfiguration $loginBody = "{""userNameOrEmailAddress"": """+$data.user+""",""password"": """+$data.pass+"""}" $connectionApiString = "api/TokenAuth/Authenticate" $authorizationUrl = (Get-UrlHost) + $connectionApiString $login = Invoke-RestMethod $authorizationUrl -Method Post -Body $loginBody -ContentType "application/json" $global:token = $login.result.accessToken $global:token } } function Start-GetResult{ [CmdletBinding()] param($request, $body) $token = Get-Token $headers = @{"Authorization"="Bearer "+$token;} $requestUrl = (Get-UrlHost) + $request try { if ($body) { $answer = Invoke-RestMethod $requestUrl -Method Post -Body $body -ContentType "application/json" -Headers $headers } else { $answer = Invoke-RestMethod $requestUrl -Headers $headers } } catch { write-host "Token not accepected. Try renewing" if ($global:token) { Remove-Variable token -Scope Global } $token = Get-Token $headers = @{"Authorization"="Bearer "+$token;} if ($body) { $answer = Invoke-RestMethod $requestUrl -Method Post -Body $body -ContentType "application/json" -Headers $headers } else { $answer = Invoke-RestMethod $requestUrl -Headers $headers } } return $answer } function Start-Ublion { [CmdletBinding()] Param ( [Parameter()] [String]$WatchFolder, [Parameter()] [String]$DestinationFolder ) # start watcher for outgoing invoices $ublionConfiguration = Get-UblionConfiguration $filter = '*.JSON' $outbound = Join-Path $ublionConfiguration.baseFolder $ublionConfiguration.outgoingFolderInvoices $resultFolder = Join-Path $ublionConfiguration.baseFolder $ublionConfiguration.outgoingFolderInvoices $fsw = New-Object IO.FileSystemWatcher $outbound, $filter -Property @{IncludeSubdirectories = $false;NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'} $action = { try{ import-module UblionConnect $ublionConfiguration = Get-UblionConfiguration $copyFolder1 = ($ublionConfiguration.copyLocation1) $copyFolder2 = ($ublionConfiguration.copyLocation2) Start-Sleep -Seconds 1 $documentCreateApi = "api/services/app/Document/Create" $path = $Event.SourceEventArgs.FullPath $FileName = $Event.SourceEventArgs.Name $hashfunction = '[IO.File]::ReadAllLines($path)' $base64 = (Invoke-Expression $hashfunction).Replace("""","\""") $sendFile = "{""name"": """+$FileName.Replace(".JSON","")+""",""type"": ""invoiceJson"", ""description"": ""PSUpload"",""file"": """+$base64+"""}" write-host ("Sending: " + "{""name"": """+$FileName.Replace(".JSON","")+""",""type"": ""invoiceJson"", ""file"": fileContent}") Start-GetResult -request $documentCreateApi -body $sendFile if (-not ([string]::IsNullOrEmpty($copyFolder1))) { $newPath = Join-Path $copyFolder1 "invoice" $newPath = Join-Path $newPath $Event.SourceEventArgs.Name $newPath = Join-Path $newPath (Get-Date).ToString("yyyyMMddHHmmss") write-host Copy file to $newPath mkdir $newPath Copy-Item $Event.SourceEventArgs.FullPath $newPath write-host Copy file to $newPath } else { Write-host "copyFolder1 1 not known $copyFolder1" } if (-not ([string]::IsNullOrEmpty($copyFolder2))) { mkdir $copyFolder2 Copy-Item $Event.SourceEventArgs.FullPath $copyFolder2 write-host Copy file to $copyFolder2 } else { Write-host "copyFolder2 1 not known $copyFolder2" } Remove-Item $Event.SourceEventArgs.FullPath } catch { write-host -ForegroundColor Red $_.Exception.Message write-host -ForegroundColor Red $_.Exception.ItemName write-host "ERROR in file "$Event.SourceEventArgs.FullPath -ForegroundColor Red } } $backupscript = Register-ObjectEvent -EventName "Created" -InputObject $fsw -Action $action -MessageData $resultFolder Write-Host "WatchFolder: `"Invoice To Ublion $($baseFolder)`" DestinationFolder: `"$($resultFolder)`" started. Job is in: $backupscript" -ForegroundColor Green #start watcher for incoming invoices if (-not [string]::IsNullOrEmpty($ublionConfiguration.outgoingFolderOrders)){ $filter = '*.JSON' $outbound = Join-Path $ublionConfiguration.baseFolder $ublionConfiguration.outgoingFolderOrders $resultFolder = Join-Path $ublionConfiguration.baseFolder $ublionConfiguration.outgoingFolderOrders $fsw = New-Object IO.FileSystemWatcher $outbound, $filter -Property @{IncludeSubdirectories = $false;NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'} $action = { try{ import-module UblionConnect $ublionConfiguration = Get-UblionConfiguration $copyFolder1 = ($ublionConfiguration.copyLocation1) $copyFolder2 = ($ublionConfiguration.copyLocation2) Start-Sleep -Seconds 1 $documentCreateApi = "api/services/app/Document/Create" $path = $Event.SourceEventArgs.FullPath $FileName = $Event.SourceEventArgs.Name $hashfunction = '[IO.File]::ReadAllLines($path)' $base64 = (Invoke-Expression $hashfunction).Replace("""","\""") $sendFile = "{""name"": """+$FileName.Replace(".JSON","")+""",""type"": ""order"", ""file"": """+$base64+"""}" write-host ("Sending: " + "{""name"": """+$FileName.Replace(".JSON","")+""",""type"": ""order"", ""file"": fileContent}") Start-GetResult -request $documentCreateApi -body $sendFile if (-not ([string]::IsNullOrEmpty($copyFolder1))) { $newPath = Join-Path $copyFolder1 "order" $newPath = Join-Path $newPath $Event.SourceEventArgs.Name $newPath = Join-Path $newPath (Get-Date).ToString("yyyyMMddHHmmss") write-host Copy file to $newPath mkdir $newPath Copy-Item $Event.SourceEventArgs.FullPath $newPath } else { Write-host "copyFolder1 1 not known $copyFolder1" } if (-not ([string]::IsNullOrEmpty($copyFolder2))) { mkdir $copyFolder2 Copy-Item $Event.SourceEventArgs.FullPath $copyFolder2 write-host Copy file to $copyFolder2 } else { Write-host "copyFolder2 1 not known $copyFolder2" } Remove-Item $Event.SourceEventArgs.FullPath } catch { write-host -ForegroundColor Red $_.Exception.Message write-host -ForegroundColor Red $_.Exception.ItemName write-host "ERROR in file "$Event.SourceEventArgs.FullPath -ForegroundColor Red } } $backupscript = Register-ObjectEvent -EventName "Created" -InputObject $fsw -Action $action -MessageData $resultFolder Write-Host "WatchFolder: `"Order to Ublion$($baseFolder)`" DestinationFolder: `"$($resultFolder)`" started. Job is in: $backupscript" -ForegroundColor Green } Log("Start ublion watchers") Start-GetResultFiles Log("Start downloading items") } function Install-Ublion{ [CmdletBinding()] param( [Parameter(Mandatory)] [String]$Tenant, # The base folder [Parameter(Mandatory)] [String]$BaseFolder, [System.Management.Automation.PSCredential] $Credential = $(Get-Credential), # The incoming folder for invoices from ublion [String]$IncomingFolder = "FromUblion", # The folder which contains the document to upload [String]$OutgoingFolder = "ToUblion", #the order folder [String]$OrderPrefix = "Order", #the order folder [String]$InvoicePrefix = "Invoice", ##the template folder [String]$TemplateFolder = "Templates", ##CopyLocation [String]$CopyLocation1 = "", ##CopyLocation [String]$CopyLocation2 = "" ) $secureStringText = $Credential.Password | ConvertFrom-SecureString $folder = $env:LOCALAPPDATA + "\ublion" Install-AppData -DirectoryToCreate $folder Install-AppData -DirectoryToCreate ($BaseFolder + "\" + $InvoicePrefix + $OutgoingFolder) Install-AppData -DirectoryToCreate ($BaseFolder + "\"+ $InvoicePrefix + $IncomingFolder) Install-AppData -DirectoryToCreate ($BaseFolder + "\"+ $InvoicePrefix + $TemplateFolder) if (-not [string]::IsNullOrEmpty($OrderPrefix)) { $OutgoingFolderOrder = $OrderPrefix + $OutgoingFolder $IncomingFolderOrder = $OrderPrefix + $IncomingFolder Install-AppData -DirectoryToCreate ($BaseFolder + "\" + $OutgoingFolderOrder) Install-AppData -DirectoryToCreate ($BaseFolder + "\"+ $IncomingFolderOrder) } Set-Content "$folder\data.log" ( #password $secureStringText + "`n" + #username $Credential.UserName + "`n" + #Tenant $Tenant + "`n" + #Root folder for data $BaseFolder + "`n" + # Outgoing folder invoices $InvoicePrefix + $OutgoingFolder + "`n" + # Incoming folder invoices $InvoicePrefix + $IncomingFolder + "`n" + # Outgoing folder orders $OutgoingFolderOrder + "`n" + # Incoming folder orders $IncomingFolderOrder + "`n" + # Incoming template folder $InvoicePrefix + $TemplateFolder + "`n"+ # Copy Location 1 $CopyLocation1 + "`n" + # Copy Location 2 $CopyLocation2 + "`n" ) Log("Install ublion configuration to $folder") } function Remove-Ublion { $folder = $env:LOCALAPPDATA + "\ublion" if (Test-Path -LiteralPath $folder) { Remove-Item $folder "Ublion configuration removed" } } function Get-UblionConfiguration { $folder = $env:LOCALAPPDATA + "\ublion" $data = (Get-Content "$folder\data.log").split("`n") $secureString = $data[0] | ConvertTo-SecureString $BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($secureString) $UnsecurePassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR) @{user = $data[1] pass = $UnsecurePassword tenant = $data[2] baseFolder = $data[3] outgoingFolderInvoices = $data[4] incomingFolderInvoices = $data[5] outgoingFolderOrders = $data[6] incomingFolderOrders = $data[7] incomingFolderTemplate = $data[8] copyLocation1 = $data[9] copyLocation2 = $data[10] } } <# .SYNOPSIS Create an folder .DESCRIPTION Long description .PARAMETER DirectoryToCreate Parameter description .EXAMPLE An example .NOTES General notes #># function Install-AppData{ [CmdletBinding()] Param( [Parameter(Mandatory = $True)] [String] $DirectoryToCreate) if (-not (Test-Path -LiteralPath $DirectoryToCreate)) { try { New-Item -Path $DirectoryToCreate -ItemType Directory -ErrorAction Stop | Out-Null #-Force } catch { Write-Error -Message "Unable to create directory '$DirectoryToCreate'. Error was: $_" -ErrorAction Stop } "Successfully saved credentials" } else { "Directory already existed" } } <# .SYNOPSIS Upload invoice templates .DESCRIPTION Upload invoice template for footer, main and header. The template is a html file with complete styling. .EXAMPLE An example .NOTES General notes #># function Start-UploadTemplate{ [CmdletBinding()] param() $ublionConfiguration = Get-UblionConfiguration $filter = '*.JSO' $templateFolder = Join-Path $ublionConfiguration.baseFolder $ublionConfiguration.incomingFolderTemplate $filter = '*.html' $fsw = New-Object IO.FileSystemWatcher $templateFolder, $filter -Property @{IncludeSubdirectories = $false;NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'} $action = { write-host Start uploading $Event.SourceEventArgs.FullPath try{ import-module UblionConnect Start-Sleep -Seconds 2 $documentCreateApi = "api/services/app/EmailTemplate/CreateOrEdit" $path = $Event.SourceEventArgs.FullPath $FileName = $Event.SourceEventArgs.Name $hashfunction = '[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes([IO.File]::ReadAllLines($path)))' $base64 = (Invoke-Expression $hashfunction).Replace("""","\""") $sendFile = "{""name"": """+$FileName.replace(".html","")+""",""type"": ""INVOICE"",""description"": ""PSUpload"", ""template"": """+$base64+"""}" write-host request file Start-GetResult -request $documentCreateApi -body $sendFile } catch { write-host -ForegroundColor Red $_.Exception.Message write-host -ForegroundColor Red $_.Exception.ItemName write-host "ERROR in file "$Event.SourceEventArgs.FullPath -ForegroundColor Red } } $backupscript = Register-ObjectEvent -EventName "Changed" -InputObject $fsw -Action $action -MessageData $resultFolder Write-Host "Template watcher is started. WatchFolder: `"$($templateFolder)`" Job is in: $ backupscript" -ForegroundColor Green } function Get-ReleaseNotes { $logData = @( "24/10/2020: Updating template service", "20/08/2020: Fix logic to route order to outgoing folder", "22/07/2020: Add order ", "15/07/2020: Added order functionality, remove connection code, make order folder " ) Write-host $logData } Export-ModuleMember -function Get-DownloadFile Export-ModuleMember -function Start-GetResultFiles Export-ModuleMember -function Get-UrlHost Export-ModuleMember -function Get-Token Export-ModuleMember -function Start-GetResult Export-ModuleMember -function Start-Ublion Export-ModuleMember -function Start-UploadTemplate Export-ModuleMember -function Install-Ublion Export-ModuleMember -function Get-UblionConfiguration Export-ModuleMember -function Get-ReleaseNotes Export-ModuleMember -function Remove-Ublion Export-ModuleMember -function Get-UblionLog |