Refactor: Add ImporterShared Project

This commit is contained in:
Jonathan Jenne
2021-08-18 13:19:10 +02:00
parent 3abf4b6e87
commit 55e921eb21
38 changed files with 1497 additions and 981 deletions

View File

@@ -0,0 +1,10 @@
Namespace Winline
Public Class Account
Public Property Id As String
Public Property Name As String
Public Property Mandator As String
Public Overrides Function ToString() As String
Return $"{Name} ({Id})"
End Function
End Class
End Namespace

View File

@@ -0,0 +1,261 @@
Imports DigitalData.Modules.Logging
Imports DigitalData.Modules.Language
Imports DigitalData.Modules.Database
Imports ImporterShared
Imports System.Text.RegularExpressions
Namespace Winline
Public Class Data
Inherits BaseClass
Private ReadOnly Database As MSSQLServer
Private ReadOnly Config As Config
Public Accounts As New List(Of Account)
Public Mandators As New List(Of Mandator)
Public Years As List(Of Integer)
Public Const V21_ARTICLENUMBER = "c011"
Public Const V50_ACCOUNTNUMBER = "c002"
Public Const V05_ACCOUNTID = "c002"
Public Const V05_ACCOUNTNAME = "c003"
Public Const T01_DATABASEINFO = "c004"
Public Const T01_MANDATORID = "c000"
Public Const T01_MANDATORNAME = "c003"
Public Sub New(pLogConfig As LogConfig, pDatabase As MSSQLServer, pConfig As Config)
MyBase.New(pLogConfig, pLogConfig.GetLogger())
Database = pDatabase
Config = pConfig
End Sub
Public Function GetWinLineYear(pYear As Integer)
Return (pYear - 1900) * 12
End Function
Public Function GetWinLineYear()
Return GetWinLineYear(Config.GetYear)
End Function
Public Sub LoadAccounts(pMandator As Mandator)
Dim oSQL = $"SELECT [c002], [c003] FROM [{pMandator.Server}].[{pMandator.Database}].[dbo].[v005] WHERE c139 IS NULL"
Dim oTable = Database.GetDatatable(oSQL)
For Each oRow As DataRow In oTable.Rows
Accounts.Add(New Account With {
.Id = oRow.Item(V05_ACCOUNTID),
.Name = oRow.Item(V05_ACCOUNTNAME),
.Mandator = pMandator.Id
})
Next
End Sub
Public Sub LoadMandators()
Dim oSQL = "SELECT [c000], [c003], [c004] FROM [cwlsystem].[dbo].[T001SRV] (NOLOCK)"
Dim oTable = Database.GetDatatable(oSQL)
Mandators.Clear()
For Each oRow As DataRow In oTable.Rows
Dim oDbInfo = SplitConnectionInfo(oRow)
Dim oMandator = New Mandator With {
.Id = oRow.Item(T01_MANDATORID),
.Name = oRow.Item(T01_MANDATORNAME),
.Database = oDbInfo.Item1,
.Server = oDbInfo.Item2
}
Dim oMandatorConfig As Config.MandatorConfig = Config.Mandators.
Where(Function(m) oMandator.Id = m.Name).
SingleOrDefault()
If oMandatorConfig IsNot Nothing Then
oMandator.IsWhitelisted = True
oMandator.Regex = oMandatorConfig.ArticleRegex
oMandator.Order = oMandatorConfig.Order
End If
Mandators.Add(oMandator)
Next
End Sub
Public Sub LoadEconomicYears()
Dim oCurrentYear = Now.Year
Dim oRange As IEnumerable(Of Integer) = Enumerable.Range(oCurrentYear - 10, 12).ToList()
Years = oRange
End Sub
Public Function TryGetAccountNumber(pGLN As String, pMandator As Mandator) As String
Try
Dim oYear As Integer = GetWinLineYear()
Dim oSQL = $"
SELECT
[c002], -- Kundennummer
[c003] -- Kundenname
FROM [{pMandator.Database}].[dbo].[v050]
WHERE [c004] = 2 -- Was für ein Konto??
AND [c260] = {pGLN}
AND [mesocomp] = '{pMandator.Id}' and [mesoyear] = {oYear}"
Dim oTable As DataTable = Database.GetDatatable(oSQL)
' GLN not found in this Mandator, continue to next one
If oTable.Rows.Count = 0 Then
Logger.Debug("GLN [{0}] was not found in Mandator: [{1}]", pGLN, pMandator.Id)
Return Nothing
End If
' Duplicate GLN, exit and do nothing about this number
If oTable.Rows.Count > 1 Then
Logger.Warn("GLN [{0}] was found more than once in Mandator: [{1}]", pGLN, pMandator.Id)
Return Nothing
End If
Dim oRow As DataRow = oTable.Rows.Item(0)
Dim oArticleNumber As String = Utils.NotNull(oRow.Item(V50_ACCOUNTNUMBER), String.Empty)
Return oArticleNumber
Catch ex As Exception
Logger.Error(ex)
Return Nothing
End Try
End Function
Public Function TryGetArticleNumber(pEAN As String, pMandator As Mandator) As String
Try
Dim oYear As Integer = GetWinLineYear()
Dim oSQL As String = $"
SELECT
[c011], -- Artikelnummer
[c003], -- Artikelbezeichnung
[c075], -- EAN-Nummer
[c123] -- Ersatzartikelnummer
FROM [{pMandator.Database}].[dbo].[v021]
WHERE [c075] = '{pEAN}'
AND [mesocomp] = '{pMandator.Id}' AND [mesoyear] = {oYear}"
Dim oTable As DataTable = Database.GetDatatable(oSQL)
' EAN not found in this Mandator, continue to next one
If oTable.Rows.Count = 0 Then
Logger.Debug("EAN [{0}] was not found in Mandator: [{1}]", pEAN, pMandator.Id)
Return Nothing
End If
' Duplicate EAN, exit and do nothing about this number
If oTable.Rows.Count > 1 Then
Logger.Warn("EAN [{0}] was found more than once", pEAN)
Return Nothing
End If
Dim oRow As DataRow = oTable.Rows.Item(0)
Dim oArticleNumber As String = Utils.NotNull(oRow.Item(V21_ARTICLENUMBER), String.Empty)
Return oArticleNumber
Catch ex As Exception
Logger.Error(ex)
Return Nothing
End Try
End Function
Public Function FindMatchingMandatorFromOrder(pData As Schemas.Orders.Input.MESOWebService) As Mandator
Dim oPositions As List(Of Schemas.Orders.Input.MESOWebServiceEXIMVRG_ordersT026) = pData.Items.
Where(Function(i) TypeOf i Is Schemas.Orders.Input.MESOWebServiceEXIMVRG_ordersT026).
Select(Of Schemas.Orders.Input.MESOWebServiceEXIMVRG_ordersT026)(Function(i) i).
ToList()
Dim oYear = GetWinLineYear()
Dim oMandatorId As String = String.Empty
Dim oWhitelistedMandators = Mandators.
Where(Function(m) m.IsWhitelisted = True).
ToList()
For Each oPos In oPositions
For Each oMandator In oWhitelistedMandators
Dim oSQL As String = $"
SELECT
[c011], -- Artikelnummer
[c003], -- Artikelbezeichnung
[c075], -- EAN-Nummer
[c123] -- Ersatzartikelnummer
FROM [{oMandator.Database}].[dbo].[v021]
WHERE [c075] = '{oPos.Artikelnummer}'
AND [mesocomp] = '{oMandator.Id}' AND [mesoyear] = {oYear}"
Dim oTable As DataTable = Database.GetDatatable(oSQL)
' EAN not found in this Mandator, continue to next one
If oTable.Rows.Count = 0 Then
Logger.Debug("EAN [{0}] was not found in Mandator: [{1}]", oPos.Artikelnummer, oMandator.Id)
Continue For
End If
' Duplicate EAN, exit and do nothing about this manda
If oTable.Rows.Count > 1 Then
Logger.Warn("EAN [{0}] was found more than once. Skipping Mandator [{1}]", oPos.Artikelnummer, oMandator.Id)
Exit For
End If
Dim oRow As DataRow = oTable.Rows.Item(0)
Dim oArticleNumber As String = Utils.NotNull(oRow.Item(V21_ARTICLENUMBER), String.Empty)
' EAN was found, now we need to check it against the Regex of the current Mandantor, if one exists
If oMandator.Regex <> String.Empty Then
Try
Dim oRegex As New Regex(oMandator.Regex)
Dim oMatch = oRegex.Match(oArticleNumber)
' If ArticleNumber matches the regex, we assign it and exit
If oMatch.Success Then
oMandatorId = oMandator.Id
Exit For
Else
' If it does not match, continue to the next mandator
End If
Catch ex As Exception
Logger.Error(ex)
Logger.Warn("Regex [{0}] could not be parsed. Skipping.", oMandator.Regex)
End Try
Else
' If no regex was found, we assume the number matches
oMandatorId = oMandator.Id
End If
Next
Next
If oMandatorId = String.Empty Then
Return Nothing
Else
Return oWhitelistedMandators.
Where(Function(m) m.Id = oMandatorId).
Take(1).
SingleOrDefault()
End If
End Function
''' <summary>
''' Turns a database info like "SQLCWLDATEN on SERVER\INSTANCE" into a Tuple of two strings
''' </summary>
''' <param name="pRow"></param>
''' <returns></returns>
Private Function SplitConnectionInfo(pRow As DataRow) As Tuple(Of String, String)
Dim oDbInfo = pRow.Item(T01_DATABASEINFO).ToString()
Dim oSplittedInfo = SplitAtString(oDbInfo.ToUpper, "ON")
Dim oServer = oSplittedInfo.Item(1).Trim()
Dim oDatabase = oSplittedInfo.Item(0).Trim()
If oDatabase.StartsWith("SQL") Then
oDatabase = oDatabase.Remove(0, 3)
End If
Return New Tuple(Of String, String)(oDatabase, oServer)
End Function
Private Function SplitAtString(pStringToSplit As String, pDelimiter As String) As List(Of String)
Dim oDelimiter As String() = New String(0) {pDelimiter}
Return pStringToSplit.
Split(oDelimiter, StringSplitOptions.None).
ToList()
End Function
End Class
End Namespace

View File

@@ -0,0 +1,15 @@
Namespace Winline
Public Class Mandator
Public Property Id As String
Public Property Name As String
Public Property Database As String
Public Property Server As String
Public Property Regex As String
Public Property Order As Integer
Public Property IsWhitelisted As Boolean
Public Overrides Function ToString() As String
Return $"{Name} ({Id})"
End Function
End Class
End Namespace

View File

@@ -0,0 +1,100 @@
Imports System.Xml
Imports System.Net
Imports System.Globalization
Imports AutoMapper
Imports DigitalData.Modules.Logging
Imports DigitalData.Modules.Filesystem
Imports ImporterShared.Documents
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
End Sub
Public Function TransferDocumentToWinLine(pDocument As Document) As Boolean
If TypeOf pDocument.Data Is Schemas.Orders.Input.MESOWebService Then
TransferOrderToWinline(pDocument)
End If
Return True
End Function
Private Function TransferOrderToWinline(pDocument As Document)
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"
Logger.Info("Creating HTTP Request to [{0}]", oWS.BaseUrl)
' TODO: Make better lol
Using oResponse = oRequest.GetResponse()
Using oStream = oResponse.GetResponseStream()
Using oReader As New IO.StreamReader(oStream)
Dim oData = oReader.ReadToEnd()
End Using
End Using
End Using
Return True
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) As String
Dim oSerializer = Serializer.GetSerializer(GetType(Schemas.Orders.Output.MESOWebService))
Dim oSettings As New XmlWriterSettings With {.Indent = True}
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)
If IO.Directory.Exists(oPath) = False Then
IO.Directory.CreateDirectory(oPath)
End If
Using oWriter = XmlWriter.Create(oFilePath, oSettings)
oSerializer.Serialize(oWriter, pData)
End Using
Return oFilePath
End Function
End Class
End Namespace