2021-08-27 15:20:35 +02:00

219 lines
9.0 KiB
VB.net

Imports System.Xml
Imports System.Net
Imports System.Net.Http
Imports System.Globalization
Imports AutoMapper
Imports DigitalData.Modules.Logging
Imports DigitalData.Modules.Filesystem
Imports ImporterShared.Documents
Imports System.Text
Namespace Winline
Public Class WebService
Inherits BaseClass
Private ReadOnly Config As Config
Private ReadOnly Serializer As Serializer
Private ReadOnly Mapper As AutoMapper.Mapper
Private ReadOnly FileEx As File
Public Sub New(pLogConfig As LogConfig, pConfig As Config)
MyBase.New(pLogConfig, pLogConfig.GetLogger())
FileEx = New File(pLogConfig)
Serializer = New Serializer(pLogConfig)
Config = pConfig
Mapper = MapperFactory.GetMapper()
End Sub
Public Async Function TransferDocumentToWinLine(pDocument As Document) As Task(Of Boolean)
If TypeOf pDocument.Data Is Schemas.Orders.Input.MESOWebService Then
Return Await TransferOrderToWinline(pDocument)
Else
Return False
End If
End Function
Private Async Function TransferOrderToWinline(pDocument As Document) As Task(Of Boolean)
Dim oOrderOutput = TransformOrderToOutput(pDocument.Data)
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
' --- 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
Dim oOutputFilePath = SerializeOrder(oOrderOutput, oFileName)
' --- 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 = 30
Dim oTemplateName = "EXIM-VRG_orders"
' 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={pDocument.Mandator}&Type={oTemplateType}&Vorlage={oTemplateName}&ActionCode={oActionCode}&Byref={oByref}&Data={oImportRelativeFilePath}"
Dim oClient As New HttpClient()
Logger.Info("Creating HTTP Request to [{0}]", oWS.BaseUrl)
' --- 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))
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)
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)
End If
Next
If oResponseObject.OverallSuccess = False Then
Throw New ApplicationException("Request to Webservice was unsuccessful. Please check the logs.")
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 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(FileEx.GetAppDataPath("Digital Data", "EDI Document Importer"), "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