MultiTool/MultiTool.Shared/Winline/WebServiceData.vb
2021-12-22 15:38:05 +01:00

287 lines
12 KiB
VB.net

Imports System.Net.Http
Imports System.Text
Imports System.Xml
Imports DigitalData.Modules.Filesystem
Imports DigitalData.Modules.Logging
Imports MultiTool.Shared.Documents
Imports MultiTool.Shared.Templates
Imports MultiTool.Shared.Templates.GeneralConfig
Imports MultiTool.Shared.Winline.Entities
Namespace Winline
Public Class WebServiceData
Inherits BaseClass
Private ReadOnly Config As WebServiceConfig
Private ReadOnly Serializer As Serializer
Private ReadOnly GeneralConfig As GeneralConfig
Private ReadOnly FileEx As File
Public Event WebServiceProgress As EventHandler(Of String)
Public Sub New(pLogConfig As LogConfig, pWebserviceConfig As WebServiceConfig, pGeneralConfig As GeneralConfig)
MyBase.New(pLogConfig)
Serializer = New Serializer(pLogConfig)
Config = pWebserviceConfig
GeneralConfig = pGeneralConfig
FileEx = New DigitalData.Modules.Filesystem.File(LogConfig)
End Sub
Public Sub RaiseWebServiceProgress(pMessage As String)
RaiseEvent WebServiceProgress(Me, pMessage)
End Sub
Public Async Function TransferDocumentToWinline(pDocument As Documents.Document, pTemplate As Template, pMandator As Mandator, Optional pIsTest As Boolean = False) As Task(Of Boolean)
Dim oBytes As Byte() = GetBytesFromDocument(pDocument)
Dim oWS = Config
RaiseEvent WebServiceProgress(Me, "Einstellungen laden")
' --- Build all teh filenamez and pathz
Dim oBaseFileName As String = FileEx.GetDateTimeString()
Dim oFileName = FileEx.GetFilenameWithSuffix(oBaseFileName, "Request", "xml")
' --- Get and create path for request/response files
Dim oOutputDirectory = FileEx.GetDateDirectory(pTemplate.OutputWebserviceDirectory)
' Relative Path for Webservice Call
Dim oImportRelativeFilePath = IO.Path.Combine(FileEx.GetDateDirectory(oWS.ImportRelativePath), oFileName)
' Absolute Path to copy Request file
Dim oImportAbsoluteFilePath = IO.Path.Combine(oWS.ImportBasePath, FileEx.GetDateDirectory(oWS.ImportRelativePath), oFileName)
' Output path
Dim oOutputFilePath = IO.Path.Combine(oOutputDirectory, oFileName)
RaiseEvent WebServiceProgress(Me, "Dateien schreiben")
' --- Serialize Data into XML string
IO.File.WriteAllBytes(oOutputFilePath, oBytes)
' --- Copy file to Winline Import Directory
Try
IO.File.Copy(oOutputFilePath, oImportAbsoluteFilePath, True)
Catch ex As Exception
Logger.Error(ex)
Throw ex
End Try
' --- Prepare URL and HTTP Client
Dim oTemplateType = pDocument.TemplateType
Dim oTemplateName = pDocument.TemplateName
' ActionCode: Should this be a test or not?
' 0 = Test call
' 1 = Real call
Dim oActionCode = 1
If pIsTest = True Then
oActionCode = 0
End If
' Byref: Should data be supplied as file or as string?
' 0 = As String
' 1 = As File (relative to Winline Server directory)
Dim oByref = 1
Dim oURL As String = $"{oWS.BaseUrl}/ewlservice/import?User={oWS.Username}&Password={oWS.Password}&Company={pMandator.Id}&Type={oTemplateType}&Vorlage={oTemplateName}&ActionCode={oActionCode}&Byref={oByref}&Data={oImportRelativeFilePath}"
Dim oClient As New HttpClient()
Logger.Info("Creating HTTP Request to [{0}]", oWS.BaseUrl)
RaiseEvent WebServiceProgress(Me, "Anfrage absenden")
' --- Bring the action!
Try
Dim oResponse As HttpResponseMessage = Await oClient.GetAsync(oURL)
Await HandleImportResponse(oResponse, pTemplate, oBaseFileName)
Return True
Catch ex As Exception
Logger.Error(ex)
Throw ex
Finally
oClient.Dispose()
End Try
End Function
Async Function ExportDocumentFromWinline(pDocument As Entities.Document, pTemplate As Template, pMandator As Mandator, Optional pIsTest As Boolean = False) As Task(Of Boolean)
Dim oWS = Config
' --- Build all teh filenamez and pathz
Dim oBaseFileName As String = FileEx.GetDateTimeString()
Dim oFileName = FileEx.GetFilenameWithSuffix(oBaseFileName, "Request", "xml")
' Absolute Path to copy Request file
Dim oImportAbsolutePath = IO.Path.Combine(oWS.ImportBasePath, oWS.ImportRelativePath)
Dim oImportAbsoluteFilePath = IO.Path.Combine(FileEx.GetDateDirectory(oImportAbsolutePath), oFileName)
RaiseEvent WebServiceProgress(Me, "Dateien schreiben")
' --- Prepare URL and HTTP Client
Dim oTemplateType = 30
Dim oTemplateName = pDocument.Schema.Name
Dim oKey = $"{pDocument.Account.Id}-{pDocument.RunningNumber}"
' ActionCode: Should this be a test or not?
' 0 = Test call
' 1 = Real call
Dim oActionCode = 1
If pIsTest = True Then
oActionCode = 0
End If
' Byref: Should data be supplied as file or as string?
' 0 = As String
' 1 = As File (relative to Winline Server directory)
Dim oByref = 0
Dim oURL As String = $"{oWS.BaseUrl}/ewlservice/export?User={oWS.Username}&Password={oWS.Password}&Company={pMandator.Id}&Type={oTemplateType}&Vorlage={oTemplateName}&ActionCode={oActionCode}&Key={oKey}"
Dim oClient As New HttpClient()
Logger.Info("Creating HTTP Request to [{0}]", oWS.BaseUrl)
RaiseEvent WebServiceProgress(Me, "Anfrage absenden")
' --- Bring the action!
Try
Dim oResponse As HttpResponseMessage = Await oClient.GetAsync(oURL)
Await HandleExportResponse(oResponse, pTemplate, oBaseFileName)
Return True
Catch ex As Exception
Logger.Error(ex)
Throw ex
Finally
oClient.Dispose()
End Try
End Function
Private Async Function HandleExportResponse(pResponse As HttpResponseMessage, pTemplate As Template, pBaseFileNAme As String) As Task
pResponse.EnsureSuccessStatusCode()
Dim oResponseBody As String = Await pResponse.Content.ReadAsStringAsync()
Dim oContentType = pResponse.Content.Headers.ContentType.MediaType
Dim oSerializer = Serializer.GetSerializer(GetType(Templates.Entities.MESOWebServiceResult))
RaiseEvent WebServiceProgress(Me, "Antwort verarbeiten")
Select Case oContentType
Case "text/xml"
WriteResponseFile(pTemplate.OutputWebserviceDirectory, pBaseFileNAme, oResponseBody, "xml")
WriteResponseFile(pTemplate.OutputXmlFileDirectory, pBaseFileNAme, oResponseBody, "xml")
WriteResponseFile(FileEx.GetDateDirectory(pTemplate.ArchiveDirectory), pBaseFileNAme, oResponseBody, "xml")
Case "text/html"
WriteResponseFile(pTemplate.OutputWebserviceDirectory, pBaseFileNAme, oResponseBody, "txt")
Throw New ApplicationException(oResponseBody)
Case Else
Throw New ApplicationException(oResponseBody)
End Select
End Function
Private Async Function HandleImportResponse(pResponse As HttpResponseMessage, pTemplate As Template, pBaseFileNAme As String) As Task
pResponse.EnsureSuccessStatusCode()
Dim oResponseBody As String = Await pResponse.Content.ReadAsStringAsync()
Dim oContentType = pResponse.Content.Headers.ContentType.MediaType
Dim oSerializer = Serializer.GetSerializer(GetType(Templates.Entities.MESOWebServiceResult))
RaiseEvent WebServiceProgress(Me, "Antwort verarbeiten")
Select Case oContentType
Case "text/xml"
WriteResponseFile(pTemplate.OutputWebserviceDirectory, pBaseFileNAme, oResponseBody, "xml")
Dim oBytes As Byte() = Encoding.UTF8.GetBytes(oResponseBody)
Using oStream As New IO.MemoryStream(oBytes)
Dim oResponseObject As Templates.Entities.MESOWebServiceResult = oSerializer.Deserialize(oStream)
Dim oErrorStrings As New List(Of String)
If oResponseObject.ResultDetails IsNot Nothing Then
For Each oDetails As Templates.Entities.MESOWebServiceResultResultDetails In oResponseObject.ResultDetails
If oDetails.Success = True Then
Logger.Info("KeyValue: [{0}]", oDetails.KeyValue)
Logger.Info("VoucherNumber: [{0}]", oDetails.VoucherNumber)
Else
Logger.Warn("ErrorCode: [{0}]", oDetails.ErrorCode)
Logger.Warn("ErrorText: [{0}]", oDetails.ErrorText)
oErrorStrings.Add($"[{oDetails.ErrorCode}] {oDetails.ErrorText}")
End If
Next
End If
If oResponseObject.OverallSuccess = False Then
Dim oMessage = $"Request to Webservice was unsuccessful:{vbNewLine}{vbNewLine}{String.Join(vbNewLine, oErrorStrings.ToArray)}"
Throw New ApplicationException(oMessage)
End If
End Using
Case "text/html"
WriteResponseFile(pTemplate.OutputWebserviceDirectory, pBaseFileNAme, oResponseBody, "txt")
Throw New ApplicationException(oResponseBody)
Case Else
Throw New ApplicationException(oResponseBody)
End Select
End Function
Private Function WriteResponseFile(pPath As String, pBaseFileName As String, pResponseBody As String, pExtension As String)
Try
Dim oRequestFileName As String = FileEx.GetFilenameWithSuffix(pBaseFileName, "Response", pExtension)
Dim oFilePath As String = IO.Path.Combine(pPath, oRequestFileName)
IO.File.WriteAllText(oFilePath, pResponseBody)
Return True
Catch ex As Exception
Logger.Error(ex)
Return False
End Try
End Function
Private Function GetBytesFromDocument(pDocument As Documents.Document) As Byte()
Using oStream As New IO.MemoryStream()
Dim w = XmlWriter.Create(oStream)
w.WriteStartDocument()
w.WriteStartElement("MESOWebService")
w.WriteAttributeString("Template", pDocument.TemplateName)
w.WriteAttributeString("TemplateType", pDocument.TemplateType)
w.WriteAttributeString("option", pDocument.Option)
w.WriteAttributeString("printVoucher", pDocument.PrintVoucher)
pDocument.Rows.Sort()
For Each oRow In pDocument.Rows
w.WriteStartElement(oRow.Name)
For Each oField As KeyValuePair(Of String, DocumentRow.FieldValue) In oRow.Fields
If oField.Value.Final = String.Empty Then
Continue For
End If
If oField.Value.IsVirtual Then
Continue For
End If
w.WriteStartElement(oField.Key)
w.WriteValue(oField.Value.Final)
w.WriteEndElement() ' Field
Next
w.WriteEndElement() ' Row
Next
w.WriteEndElement() ' MESOWebService
w.WriteEndDocument() ' Document
w.Close()
Return oStream.ToArray()
End Using
End Function
End Class
End Namespace