Jonathan Jenne c1b6e2ed4d small tweaks
2021-11-18 15:35:02 +01:00

266 lines
11 KiB
VB.net

Imports System.Xml
Imports System.Text
Imports System.Net.Http
Imports DigitalData.Modules.Logging
Imports DigitalData.Modules.Filesystem
Imports MultiTool.Shared.Documents
Namespace Winline
Public Class WebService
Inherits BaseClass
Private ReadOnly Config As Config
Private ReadOnly Serializer As Serializer
Private ReadOnly AppDataPath As String
Public Event WebServiceProgress As EventHandler(Of String)
Public Sub New(pLogConfig As LogConfig, pConfig As Config, pAppDataPath As String)
MyBase.New(pLogConfig, pLogConfig.GetLogger())
Serializer = New Serializer(pLogConfig)
Config = pConfig
AppDataPath = pAppDataPath
End Sub
Public Async Function TransferDocumentToWinline(pDocument As Document, pMandator As Mandator) As Task(Of Boolean)
Dim oBytes As Byte() = GetBytesFromDocument(pDocument)
Dim oWS As Config.WebServiceConfig = Config.Webservice
' --- Get and create path for request/response files
Dim oPath As String = GetBaseWebServicePath()
If IO.Directory.Exists(oPath) = False Then
IO.Directory.CreateDirectory(oPath)
End If
RaiseEvent WebServiceProgress(Me, "Einstellungen laden")
' --- Build all teh filenamez and pathz
Dim oBaseFileName As String = GetBaseFilenameForRequest()
Dim oFileName = GetXmlFilenameWithSuffix(oBaseFileName, "Request", "xml")
' Relative Path for Webservice Call
Dim oImportRelativeFilePath = IO.Path.Combine(GetDateSubDirectoryPath(Config.Webservice.ImportRelativePath), oFileName)
' Absolute Path to copy Request file
Dim oImportAbsolutePath = IO.Path.Combine(Config.Webservice.ImportBasePath, Config.Webservice.ImportRelativePath)
Dim oImportAbsoluteFilePath = IO.Path.Combine(GetDateSubDirectoryPath(oImportAbsolutePath), oFileName)
' --- Serialize Data into XML string
RaiseEvent WebServiceProgress(Me, "Dateien schreiben")
Dim oOutputFilePath = IO.Path.Combine(GetBaseWebServicePath(), oFileName)
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 = Testcall
' 1 = Real call
Dim oActionCode = 1
' 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 HandleResponse(oResponse, oPath, oBaseFileName)
Return True
Catch ex As Exception
Logger.Error(ex)
Throw ex
Finally
oClient.Dispose()
End Try
End Function
Private Async Function HandleResponse(pResponse As HttpResponseMessage, pPath As String, 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(Schemas.MESOWebServiceResult))
RaiseEvent WebServiceProgress(Me, "Antwort verarbeiten")
Select Case oContentType
Case "text/xml"
WriteResponseFile(pPath, pBaseFileNAme, oResponseBody, "xml")
Dim oBytes As Byte() = Encoding.UTF8.GetBytes(oResponseBody)
Using oStream As New IO.MemoryStream(oBytes)
Dim oResponseObject As Schemas.MESOWebServiceResult = oSerializer.Deserialize(oStream)
Dim oErrorStrings As New List(Of String)
For Each oDetails As Schemas.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
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(pPath, 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 = GetXmlFilenameWithSuffix(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 Document) As Byte()
' TODO: should "Lief_Name" be included here?
Dim oFilteredFields As New List(Of String) From {
"Fakt_Name"
}
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 oFilteredFields.Contains(oField.Key) 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
'Private Function TransformOrderToOutput(pData As Schemas.Orders.Input.MESOWebService) As Schemas.Orders.Output.MESOWebService
' Dim oData As Schemas.Orders.Input.MESOWebService = pData
' Dim oResult As Schemas.Orders.Output.MESOWebService = Mapper.Map(Of Schemas.Orders.Output.MESOWebService)(oData)
' Dim oItems = oData.Items.
' Select(Function(i)
' If TypeOf i Is Schemas.Orders.Input.MESOWebServiceEXIMVRG_ordersT025 Then
' Return Mapper.Map(Of Schemas.Orders.Output.MESOWebServiceEXIMVRG_ordersT025)(i)
' Else
' Return Mapper.Map(Of Schemas.Orders.Output.MESOWebServiceEXIMVRG_ordersT026)(i)
' End If
' End Function).
' ToList()
' oResult.Items = oItems.ToArray()
' Return oResult
'End Function
'Private Function SerializeOrder(pData As Schemas.Orders.Output.MESOWebService, pFileName As String) As String
' Dim oSerializer = Serializer.GetSerializer(GetType(Schemas.Orders.Output.MESOWebService))
' Dim oPath As String = GetBaseWebServicePath()
' Dim oFilePath As String = IO.Path.Combine(oPath, pFileName)
' Using oWriter = XmlWriter.Create(oFilePath, New XmlWriterSettings With {.Indent = True})
' oSerializer.Serialize(oWriter, pData)
' End Using
' Return oFilePath
'End Function
Private Function GetBaseWebServicePath() As String
Return IO.Path.Combine(AppDataPath, "WebService")
End Function
Private Function GetBaseFilenameForRequest() As String
Return $"{Now:yyyy-MM-dd_hh-mm-ffff}"
End Function
Private Function GetXmlFilenameWithSuffix(pBaseString As String, pSuffix As String, pExtension As String)
Return $"{pBaseString}-{pSuffix}.{pExtension}"
End Function
Private Function GetDateSubDirectoryPath(pBasePath As String)
Dim oDirectoryPath As String = Now.ToString("yyyy\\MM\\dd")
Dim oFullPath As String = IO.Path.Combine(pBasePath, oDirectoryPath)
If IO.Directory.Exists(oFullPath) = False Then
Try
IO.Directory.CreateDirectory(oFullPath)
Return oFullPath
Catch ex As Exception
Logger.Error(ex)
Return Nothing
End Try
Else
Return oFullPath
End If
End Function
End Class
End Namespace