UblionConnect.psm1

function Get-DownloadFile {
    [CmdletBinding()]
    param($id, $filename)
       $apiGetPDF = "api/services/app/Document/GetDocumentPDF?id="+$id
       $result   = Start-GetResult -request $apiGetPDF
       $b64      = $result.result.fileBase64

       
       $outbresultFolderound = (Get-UblionConfiguration).baseFolder + "/FromUblion"
       $filename = $resultFolder+"\"+$filename
       $fileOutputPdf = $filename+".pdf"
       $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
     
   
       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()

    While ($true) {
        if( -not (Test-path $resultFolder))
        {
            mkdir $resultFolder
        }
        try {
            $apiGetModifiedFiles = "api/services/app/Document/GetModifiedDocuments"
            $result = Start-GetResult -request $apiGetModifiedFiles
            if ($result.result.GetType().Name -eq "Object[]") {
                foreach ($document in $result.result){
                    Get-DownloadFile -id ($document.id) -filename ($document.name)
                }
            } 
        } 
        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 {
    (Get-UblionCredentials).tenant
}

<#
.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-UblionCredentials
    $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" -Headers  @{'Abp.TenantId' = 1013}

    $global:token = $login.result.accessToken
    $global:token
    }
}
function Start-GetResult{
    [CmdletBinding()]
    param($request, $body)
    $token = Get-Token
    $headers = @{"Authorization"="Bearer "+$token;
                 'Abp.TenantId' = 1013}
    $requestUrl = (Get-UrlHost) + $request
    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
        )
    Process {
        $filter = '*.JSO'
        $outbound = (Get-UblionConfiguration).baseFolder + "/ToUblion"
        $fsw = New-Object IO.FileSystemWatcher $outbound, $filter -Property @{IncludeSubdirectories = $false;NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'} 
        $action = {
            try{ 
                import-module UblionTopbakkers
                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(".JSO","")+""",""type"": ""invoiceJson"", ""file"": """+$base64+"""}"

                Start-GetResult -request $documentCreateApi -body $sendFile
                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: `"$($baseFolder)`" DestinationFolder: `"$($resultFolder)`" started. Job is in: $backupscript" -ForegroundColor Green
    }
}

function Install-Ublion{
    
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [String]$Tenant,
        
        [System.Management.Automation.PSCredential]
        $Credential = $(Get-Credential),

        
        [Parameter(Mandatory)]
        [String]$BaseFolder
    )

    $secureStringText = $Credential.Password | ConvertFrom-SecureString 
    $folder = $env:LOCALAPPDATA + "\ublion"
    Install-AppData -DirectoryToCreate $folder


    
    Install-AppData -DirectoryToCreate ($BaseFolder + "\ToUblion")
    Install-AppData -DirectoryToCreate ($BaseFolder + "\FromUblion")
    Set-Content "$folder\data.log" ($secureStringText + "`n" + $Credential.UserName + "`n" + $Tenant + "`n" + $BaseFolder)
}


function Remove-Ublion {
    $folder = $env:LOCALAPPDATA + "\ublion"
    if (Test-Path -LiteralPath $folder) {
        Remove-Item $folder
        "Ublion configuration removed"
    }
}

function Get-UblionCredentials {
    $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]
    }
}
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()
    Process {
        $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 UblionTopbakkers
                Start-Sleep -Seconds 2
                $documentCreateApi = "api/services/app/EmailTemplates/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","")+""",""description"": ""invoiceJson"", ""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
    }
}


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