diff --git a/EDIDocumentImport/Exceptions.vb b/EDIDocumentImport/Exceptions.vb index 9fb25a8..9bd9be2 100644 --- a/EDIDocumentImport/Exceptions.vb +++ b/EDIDocumentImport/Exceptions.vb @@ -7,6 +7,14 @@ End Sub End Class + Public Class WebServiceException + Inherits ApplicationException + + Public Sub New(message As String) + MyBase.New(message) + End Sub + End Class + Public Class NoMandatorException Inherits DocumentShowException diff --git a/EDIDocumentImport/frmMain.vb b/EDIDocumentImport/frmMain.vb index 0b6905e..fe4d53c 100644 --- a/EDIDocumentImport/frmMain.vb +++ b/EDIDocumentImport/frmMain.vb @@ -328,15 +328,26 @@ Public Class frmMain SplitContainerControl3.Collapsed = Not checkShowXml.Checked End Sub - Private Sub BarButtonItem4_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles BarButtonItem4.ItemClick + Private Async Sub BarButtonItem4_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles BarButtonItem4.ItemClick Dim oDocument As Document = GetFocusedDocument() If oDocument Is Nothing Then Exit Sub End If - WebService.TransferDocumentToWinLine(oDocument) + Try + Dim oFinalDocument As Document = TransferChangesToDocument(oDocument) + Dim oResult = Await WebService.TransferDocumentToWinLine(oFinalDocument) + Catch ex As Exception + Logger.Error(ex) + Dim oMessage = $"Fehler beim Übertragen des Dokuments:{vbNewLine}{vbNewLine}{ex.Message}" + MsgBox(oMessage, MsgBoxStyle.Critical, Text) + End Try End Sub + Private Function TransferChangesToDocument(pDocument As Document) + Return pDocument + End Function + Private Sub BarButtonItem8_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles BarButtonItem8.ItemClick TryOpenDirectory(LogConfig.LogDirectory, "Logverzeichnis") End Sub diff --git a/ImporterShared/ImporterShared.vbproj b/ImporterShared/ImporterShared.vbproj index f049aab..45fe769 100644 --- a/ImporterShared/ImporterShared.vbproj +++ b/ImporterShared/ImporterShared.vbproj @@ -117,6 +117,7 @@ + diff --git a/ImporterShared/Schemas/Response.vb b/ImporterShared/Schemas/Response.vb new file mode 100644 index 0000000..fc8597d --- /dev/null +++ b/ImporterShared/Schemas/Response.vb @@ -0,0 +1,104 @@ +'------------------------------------------------------------------------------ +' +' Dieser Code wurde von einem Tool generiert. +' Laufzeitversion:4.0.30319.42000 +' +' Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn +' der Code erneut generiert wird. +' +'------------------------------------------------------------------------------ + +Option Strict Off +Option Explicit On + +Imports System.Xml.Serialization + +' +'This source code was auto-generated by xsd, Version=4.8.3928.0. +' +Namespace Schemas + + ''' + _ + Partial Public Class MESOWebServiceResult + + Private overallSuccessField As Boolean + + Private resultDetailsField As MESOWebServiceResultResultDetails + + ''' + + Public Property OverallSuccess() As Boolean + Get + Return Me.overallSuccessField + End Get + Set + Me.overallSuccessField = Value + End Set + End Property + + ''' + + Public Property ResultDetails() As MESOWebServiceResultResultDetails + Get + Return Me.resultDetailsField + End Get + Set + Me.resultDetailsField = Value + End Set + End Property + End Class + + ''' + + Partial Public Class MESOWebServiceResultResultDetails + + Private successField As Boolean + + Private errorCodeField As String + + Private errorTextField As String + + ''' + + Public Property Success() As Boolean + Get + Return Me.successField + End Get + Set + Me.successField = Value + End Set + End Property + + ''' + + Public Property ErrorCode() As String + Get + Return Me.errorCodeField + End Get + Set + Me.errorCodeField = value + End Set + End Property + + ''' + + Public Property ErrorText() As String + Get + Return Me.errorTextField + End Get + Set + Me.errorTextField = value + End Set + End Property + End Class +End Namespace diff --git a/ImporterShared/Serializer.vb b/ImporterShared/Serializer.vb index b1caf54..260b14c 100644 --- a/ImporterShared/Serializer.vb +++ b/ImporterShared/Serializer.vb @@ -10,7 +10,6 @@ Public Class Serializer Public Function GetSerializer(pSchemaType As Type) As XmlSerializer Dim oSerializer As New XmlSerializer(pSchemaType) - AddHandler oSerializer.UnknownAttribute, Sub(sender As Object, e As XmlAttributeEventArgs) Logger.Debug("[{1}] Unknown Attribute: {0}", e.Attr, pSchemaType.Name) End Sub diff --git a/ImporterShared/Winline/Data.vb b/ImporterShared/Winline/Data.vb index f58d6f1..8168997 100644 --- a/ImporterShared/Winline/Data.vb +++ b/ImporterShared/Winline/Data.vb @@ -53,9 +53,18 @@ Namespace Winline Public Sub LoadAccounts(pMandator As Mandator) Logger.Info("Loading Accounts for Mandator [{0}]", pMandator) + Dim oYear = GetWinLineYear() Try - Dim oSQL = $"SELECT DISTINCT [c002], [c003] FROM [{pMandator.Server}].[{pMandator.Database}].[dbo].[v005] WHERE c139 IS NULL" + Dim oSQL = $" + SELECT DISTINCT + [c002], + [c003] + FROM [{pMandator.Server}].[{pMandator.Database}].[dbo].[v005] + WHERE + c139 IS NULL + AND mesocomp = '{pMandator.Id}' + AND mesoyear = {oYear}" Dim oTable = Database.GetDatatable(oSQL) Dim oAccounts As New List(Of Account) diff --git a/ImporterShared/Winline/WebService.vb b/ImporterShared/Winline/WebService.vb index 774f615..2c4b62f 100644 --- a/ImporterShared/Winline/WebService.vb +++ b/ImporterShared/Winline/WebService.vb @@ -1,10 +1,12 @@ 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 @@ -23,39 +25,90 @@ Namespace Winline Mapper = MapperFactory.GetMapper() End Sub - Public Function TransferDocumentToWinLine(pDocument As Document) As Boolean + Public Async Function TransferDocumentToWinLine(pDocument As Document) As Task(Of Boolean) If TypeOf pDocument.Data Is Schemas.Orders.Input.MESOWebService Then - TransferOrderToWinline(pDocument) + Return Await TransferOrderToWinline(pDocument) + Else + Return False End If - - Return True End Function - Private Function TransferOrderToWinline(pDocument As Document) + Private Async Function TransferOrderToWinline(pDocument As Document) As Task(Of Boolean) Dim oOrderOutput = TransformOrderToOutput(pDocument.Data) Dim oWS As Config.WebServiceConfig = Config.Webservice - Dim oFilePath = SerializeOrder(oOrderOutput) - Dim oXmlString = IO.File.ReadAllText(oFilePath) - pDocument.DataOutput = oOrderOutput - Dim oURL As String = $"{oWS.BaseUrl}/ewlservice/import?User={oWS.Username}&Password={oWS.Password}&Company={pDocument.Mandator}&Type=30&Vorlage=EXIM-VRG_orders&ActionCode=1&Byref=0Data={oXmlString}" - Dim oRequest = WebRequest.Create(oURL) - oRequest.Method = "POST" + ' --- Get and create path for request/response files + Dim oBaseFileName As String = GetBaseFilenameForRequest() + Dim oPath As String = GetBaseWebServicePath() + If IO.Directory.Exists(oPath) = False Then + IO.Directory.CreateDirectory(oPath) + End If + + ' --- Serialize Data into XML string + Dim oXmlString = SerializeOrder(oOrderOutput, oBaseFileName) + Dim oReplacedXmlString = oXmlString.Replace("&", "").Replace("ß", "ss") + 'Dim oEscapedString = Uri.EscapeUriString(oXmlString) + + ' --- Prepare URL and HTTP Client + Dim oURL As String = $"{oWS.BaseUrl}/ewlservice/import?User={oWS.Username}&Password={oWS.Password}&Company={pDocument.Mandator}&Type=30&Vorlage=EXIM-VRG_orders&ActionCode=1&Byref=0&Data={oXmlString}" + Dim oClient As New HttpClient() Logger.Info("Creating HTTP Request to [{0}]", oWS.BaseUrl) - ' TODO: Make better lol + ' --- Bring the action! + Try + Dim oResponse As HttpResponseMessage = Await oClient.PostAsync(New Uri(oURL), New StringContent(String.Empty)) + Await HandleResponse(oResponse, oPath, oBaseFileName) - Using oResponse = oRequest.GetResponse() - Using oStream = oResponse.GetResponseStream() - Using oReader As New IO.StreamReader(oStream) - Dim oData = oReader.ReadToEnd() + 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) + + If oResponseObject.OverallSuccess = False Then + Throw New ApplicationException(oResponseObject.ResultDetails.ErrorText) + End If End Using - End Using - End Using - Return True + Case "text/plain" + 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 @@ -76,25 +129,36 @@ Namespace Winline Return oResult End Function - Private Function SerializeOrder(pData As Schemas.Orders.Output.MESOWebService) As String + Private Function SerializeOrder(pData As Schemas.Orders.Output.MESOWebService, pBaseFileName As String) As String Dim oSerializer = Serializer.GetSerializer(GetType(Schemas.Orders.Output.MESOWebService)) - Dim oSettings As New XmlWriterSettings With {.Indent = True} + Dim oPath As String = GetBaseWebServicePath() - Dim oPath As String = IO.Path.Combine(FileEx.GetAppDataPath("Digital Data", "EDI Document Importer"), "WebService") - Dim oFileName As String = $"{Now:yyyy-MM-dd-ffff}.xml" - Dim oFilePath As String = IO.Path.Combine(oPath, oFileName) + Dim oRequestFileName As String = GetXmlFilenameWithSuffix(pBaseFileName, "Request", "xml") + Dim oFilePath As String = IO.Path.Combine(oPath, oRequestFileName) - If IO.Directory.Exists(oPath) = False Then - IO.Directory.CreateDirectory(oPath) - End If - - Using oWriter = XmlWriter.Create(oFilePath, oSettings) + Using oWriter = XmlWriter.Create(oFilePath, New XmlWriterSettings With {.Indent = True}) oSerializer.Serialize(oWriter, pData) End Using - Return oFilePath + Using oStringWriter As New IO.StringWriter() + Using oXmlWriter = XmlWriter.Create(oStringWriter, New XmlWriterSettings With {.Indent = False}) + oSerializer.Serialize(oXmlWriter, pData) + Return oStringWriter.ToString() + End Using + End Using 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 End Class