516 lines
21 KiB
VB.net
516 lines
21 KiB
VB.net
Imports DigitalData.Modules.Logging
|
|
Imports DigitalData.Modules.Language
|
|
Imports DigitalData.Modules.Database
|
|
Imports MultiTool.Shared.Helpers
|
|
Imports MultiTool.Shared.Schemas
|
|
Imports System.Text.RegularExpressions
|
|
|
|
Namespace Winline
|
|
Public Class WinlineData
|
|
Inherits BaseClass
|
|
|
|
Private ReadOnly Database As MSSQLServer
|
|
Private ReadOnly Config As Config
|
|
|
|
Public Articles As New List(Of Article)
|
|
Public Accounts As New List(Of Account)
|
|
Public Mandators As New List(Of Mandator)
|
|
Public DocumentKinds As New List(Of DocumentKind)
|
|
|
|
Public Years As List(Of Integer)
|
|
|
|
Public Const ALL_MESOCOMP = "mesocomp"
|
|
|
|
Public Const V21_ARTICLENUMBER = "c002"
|
|
Public Const V21_ARTICLEDESCRIPTION = "c003"
|
|
Public Const V21_MAINARTICLENUMBER = "c011"
|
|
Public Const V21_REPLACEMENTARTICLENUMBER = "c123"
|
|
Public Const V21_EAN = "c075"
|
|
|
|
Public Const V50_ACCOUNTNUMBER = "c002"
|
|
Public Const V50_ACCOUNTNAME = "c003"
|
|
Public Const V50_STREETNAME = "c050"
|
|
Public Const V50_ZIPCODE = "c051"
|
|
Public Const V50_CITYNAME = "c052"
|
|
Public Const V50_GLN = "c260"
|
|
|
|
Public Const T45_KEY = "c000"
|
|
Public Const T45_NAME = "c001"
|
|
Public Const T45_CONTACTNUMBER = "c063"
|
|
|
|
Public Const V05_ACCOUNTID = "c002"
|
|
Public Const V05_ACCOUNTNAME = "c003"
|
|
|
|
Public Const T357_KINDID = "c030"
|
|
Public Const T357_KINDNAME = "c001"
|
|
|
|
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
|
|
|
|
<DebuggerStepThrough>
|
|
Public Function GetWinLineYear(pYear As Integer)
|
|
Return (pYear - 1900) * 12
|
|
End Function
|
|
|
|
<DebuggerStepThrough>
|
|
Public Function GetWinLineYear()
|
|
Return GetWinLineYear(Config.GetYear)
|
|
End Function
|
|
|
|
Public Async Function LoadArticles(pMandator As Mandator) As Task
|
|
Logger.Info("Loading Articles for Mandator [{0}]", pMandator)
|
|
Dim oYear = GetWinLineYear()
|
|
|
|
Try
|
|
Dim oSQL = $"
|
|
SELECT DISTINCT
|
|
[c002], -- Artikelnummer
|
|
[c003], -- Bezeichnung
|
|
[c075] -- EAN
|
|
FROM [{pMandator.Server}].[{pMandator.Database}].[dbo].[v021]
|
|
WHERE
|
|
mesocomp = '{pMandator.Id}'
|
|
AND mesoyear = {oYear}"
|
|
|
|
Dim oTable = Await Database.GetDatatableAsync(oSQL)
|
|
Dim oArticles As New List(Of Article)
|
|
|
|
For Each oRow As DataRow In oTable.Rows
|
|
Dim oArticleId As String = GetRowItem(oRow, V21_ARTICLENUMBER, String.Empty)
|
|
Dim oArticleDescription As String = GetRowItem(oRow, V21_ARTICLEDESCRIPTION, String.Empty)
|
|
Dim oEAN As String = GetRowItem(oRow, V21_EAN, String.Empty)
|
|
|
|
oArticles.Add(New Article With {
|
|
.Id = oArticleId,
|
|
.Name = oArticleDescription,
|
|
.EAN = oEAN,
|
|
.Mandator = pMandator
|
|
})
|
|
Next
|
|
Articles.AddRange(oArticles)
|
|
|
|
Logger.Info("[{0}] Articles loaded for Mandator [{1}]", oArticles.Count, pMandator)
|
|
Catch ex As Exception
|
|
Logger.Warn("Could not load Articles for Mandator [{0}]", pMandator)
|
|
Logger.Error(ex)
|
|
End Try
|
|
End Function
|
|
|
|
Public Async Function LoadAccounts(pMandator As Mandator) As Task
|
|
Logger.Info("Loading Accounts for Mandator [{0}]", pMandator)
|
|
Dim oYear = GetWinLineYear()
|
|
|
|
Try
|
|
Dim oSQL = $"
|
|
SELECT DISTINCT
|
|
[c002], -- Kundennummer
|
|
[c003], -- Kundenname
|
|
[c050], -- Straße
|
|
[c052], -- Ort
|
|
[c051], -- PLZ
|
|
[c260] -- GLN
|
|
FROM [{pMandator.Server}].[{pMandator.Database}].[dbo].[v050]
|
|
WHERE
|
|
c139 IS NULL
|
|
AND mesocomp = '{pMandator.Id}'
|
|
AND mesoyear = {oYear}"
|
|
Dim oTable = Await Database.GetDatatableAsync(oSQL)
|
|
Dim oAccounts As New List(Of Account)
|
|
|
|
For Each oRow As DataRow In oTable.Rows
|
|
Dim oAccountNumber As String = GetRowItem(oRow, V50_ACCOUNTNUMBER, String.Empty)
|
|
Dim oAccountName As String = GetRowItem(oRow, V50_ACCOUNTNAME, String.Empty)
|
|
Dim oStreetName As String = GetRowItem(oRow, V50_STREETNAME, String.Empty)
|
|
Dim oZipCode As String = GetRowItem(oRow, V50_ZIPCODE, String.Empty)
|
|
Dim oCityName As String = GetRowItem(oRow, V50_CITYNAME, String.Empty)
|
|
Dim oGLN As String = GetRowItem(oRow, V50_GLN, String.Empty)
|
|
|
|
oAccounts.Add(New Account With {
|
|
.Id = oAccountNumber,
|
|
.Name = oAccountName,
|
|
.StreetName = oStreetName,
|
|
.ZipCode = oZipCode,
|
|
.CityName = oCityName,
|
|
.GLN = oGLN,
|
|
.Mandator = pMandator
|
|
})
|
|
Next
|
|
Accounts.AddRange(oAccounts)
|
|
|
|
Logger.Info("[{0}] Accounts loaded for Mandator [{1}]", oAccounts.Count, pMandator)
|
|
Catch ex As Exception
|
|
Logger.Warn("Could not load Accounts for Mandator [{0}]", pMandator)
|
|
Logger.Error(ex)
|
|
End Try
|
|
End Function
|
|
|
|
Public Async Function LoadMandators() As Task
|
|
Try
|
|
Dim oSQL = "SELECT [c000], [c003], [c004] FROM [cwlsystem].[dbo].[T001SRV] (NOLOCK)"
|
|
Dim oTable = Await Database.GetDatatableAsync(oSQL)
|
|
|
|
Mandators.Clear()
|
|
For Each oRow As DataRow In oTable.Rows
|
|
Dim oDbInfo = SplitConnectionInfo(oRow)
|
|
Dim oMandator = New Mandator With {
|
|
.Id = GetRowItem(oRow, T01_MANDATORID, String.Empty),
|
|
.Name = GetRowItem(oRow, T01_MANDATORNAME, String.Empty),
|
|
.Database = oDbInfo.Item1,
|
|
.Server = oDbInfo.Item2
|
|
}
|
|
|
|
'Dim oMandatorConfig As Config.MandatorConfig = Config.Mandators.
|
|
' Where(Function(m) oMandator.Id = m.Name).
|
|
' SingleOrDefault()
|
|
|
|
'Dim oMandatorConfig2 = MappingConfiguration.Where(Function(c) c.)
|
|
|
|
'If oMandatorConfig IsNot Nothing Then
|
|
' oMandator.IsWhitelisted = True
|
|
' oMandator.Regex = oMandatorConfig.ArticleRegex
|
|
' oMandator.Order = oMandatorConfig.Order
|
|
'End If
|
|
|
|
Mandators.Add(oMandator)
|
|
Next
|
|
|
|
Logger.Info("[{0}] Mandators loaded", Mandators.Count)
|
|
Catch ex As Exception
|
|
Logger.Warn("Could not load Mandators")
|
|
Logger.Error(ex)
|
|
End Try
|
|
End Function
|
|
|
|
Public Sub LoadEconomicYears()
|
|
Dim oCurrentYear = Now.Year
|
|
Dim oRange As IEnumerable(Of Integer) = Enumerable.Range(oCurrentYear - 10, 12).ToList()
|
|
Years = oRange
|
|
End Sub
|
|
|
|
Public Async Function LoadDocumentKinds(pMandator As Mandator) As Task
|
|
Dim oYear As Integer = GetWinLineYear()
|
|
|
|
Try
|
|
' TODO: This is Schaum specific, maybe move to config later
|
|
Dim oSQL = $"
|
|
SELECT
|
|
[c030],
|
|
[c001],
|
|
[mesocomp]
|
|
FROM [{pMandator.Database}].[dbo].[t357] (NOLOCK)
|
|
WHERE (
|
|
[c001] LIKE 'Werk%(VK)' OR
|
|
[c001] LIKE 'Werk%(WK)'
|
|
)
|
|
AND [mesocomp] = '{pMandator.Id}' AND [mesoyear] = {oYear}"
|
|
Dim oTable As DataTable = Await Database.GetDatatableAsync(oSQL)
|
|
Dim oKinds As New List(Of DocumentKind)
|
|
|
|
For Each oRow As DataRow In oTable.Rows
|
|
oKinds.Add(New DocumentKind With {
|
|
.Id = GetRowItem(oRow, T357_KINDID, String.Empty),
|
|
.Name = GetRowItem(oRow, T357_KINDNAME, String.Empty),
|
|
.Mandator = pMandator
|
|
})
|
|
Next
|
|
|
|
DocumentKinds.AddRange(oKinds)
|
|
|
|
Logger.Info("[{0}] DocumentKinds loaded for [{1}]", Mandators.Count, pMandator)
|
|
Catch ex As Exception
|
|
Logger.Warn("Could not load DocumentKinds")
|
|
Logger.Error(ex)
|
|
End Try
|
|
End Function
|
|
|
|
Public Function TryGetAccount(pGLN As String, pMandator As Mandator) As Account
|
|
Try
|
|
If pGLN Is Nothing OrElse pGLN = String.Empty Then
|
|
Return Nothing
|
|
End If
|
|
|
|
Dim oYear As Integer = GetWinLineYear()
|
|
Dim oSQL = $"
|
|
SELECT
|
|
[c002], -- Kundennummer
|
|
[c003], -- Kundenname
|
|
[c050], -- Straße
|
|
[c052], -- Ort
|
|
[c051] -- PLZ
|
|
FROM [{pMandator.Database}].[dbo].[v050]
|
|
WHERE [c004] = 2 -- KontoTyp
|
|
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 oAccountNumber As String = GetRowItem(oRow, V50_ACCOUNTNUMBER, String.Empty)
|
|
Dim oAccountName As String = GetRowItem(oRow, V50_ACCOUNTNAME, String.Empty)
|
|
Dim oStreetName As String = GetRowItem(oRow, V50_STREETNAME, String.Empty)
|
|
Dim oZipCode As String = GetRowItem(oRow, V50_ZIPCODE, String.Empty)
|
|
Dim oCityName As String = GetRowItem(oRow, V50_CITYNAME, String.Empty)
|
|
|
|
Return New Account With {
|
|
.Id = oAccountNumber,
|
|
.Name = oAccountName,
|
|
.StreetName = oStreetName,
|
|
.CityName = oCityName,
|
|
.ZipCode = oZipCode,
|
|
.Mandator = pMandator
|
|
}
|
|
Catch ex As Exception
|
|
Logger.Warn("Error while trying to get account for GLN [{0}]", pGLN)
|
|
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 = GetRowItem(oRow, V21_MAINARTICLENUMBER, String.Empty)
|
|
Return oArticleNumber
|
|
|
|
Catch ex As Exception
|
|
Logger.Error(ex)
|
|
Return Nothing
|
|
|
|
End Try
|
|
End Function
|
|
|
|
Public Function GetContacts(pAccountNumber As String, pMandator As Mandator) As List(Of Contact)
|
|
Try
|
|
Dim oContacts As New List(Of Contact)
|
|
Dim oYear As Integer = GetWinLineYear()
|
|
Dim oSQL As String = $"
|
|
SELECT
|
|
[c000], -- Key
|
|
[c001], -- Name
|
|
[c063] -- Kontaktnummer
|
|
FROM [{pMandator.Database}].[dbo].[t045]
|
|
WHERE [c063] LIKE '{pAccountNumber}-%'
|
|
AND [mesocomp] = '{pMandator.Id}' AND [mesoyear] = {oYear}"
|
|
Dim oTable As DataTable = Database.GetDatatable(oSQL)
|
|
|
|
' Contact not found in this Mandator, continue to next one
|
|
If oTable.Rows.Count = 0 Then
|
|
Logger.Debug("Contact for Account [{0}] was not found in Mandator: [{1}]", pAccountNumber, pMandator.Id)
|
|
Return Nothing
|
|
|
|
End If
|
|
|
|
For Each oRow In oTable.Rows
|
|
oContacts.Add(New Contact With {
|
|
.Id = GetRowItem(Of String)(oRow, T45_KEY, Nothing),
|
|
.Name = GetRowItem(Of String)(oRow, T45_NAME, Nothing),
|
|
.Number = GetRowItem(Of String)(oRow, T45_CONTACTNUMBER, Nothing)
|
|
})
|
|
Next
|
|
|
|
Return oContacts
|
|
Catch ex As Exception
|
|
Logger.Error(ex)
|
|
Return Nothing
|
|
End Try
|
|
End Function
|
|
|
|
Public Function GetReplacementArticleNumber(pArticleNumber As String, pMandator As Mandator)
|
|
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 [c011] = '{pArticleNumber}'
|
|
AND [mesocomp] = '{pMandator.Id}' AND [mesoyear] = {oYear}"
|
|
Dim oTable As DataTable = Database.GetDatatable(oSQL)
|
|
|
|
' ArticleNumber not found in this Mandator, continue to next one
|
|
If oTable.Rows.Count = 0 Then
|
|
Logger.Debug("ArticleNumber [{0}] was not found in Mandator: [{1}]", pArticleNumber, pMandator.Id)
|
|
Return Nothing
|
|
|
|
End If
|
|
|
|
' Duplicate EAN, exit and do nothing about this number
|
|
If oTable.Rows.Count > 1 Then
|
|
Logger.Warn("ArticleNumber [{0}] was found more than once", pArticleNumber)
|
|
Return Nothing
|
|
|
|
End If
|
|
|
|
Dim oRow As DataRow = oTable.Rows.Item(0)
|
|
Dim oReplacementArticleNumber = GetRowItem(Of String)(oRow, V21_REPLACEMENTARTICLENUMBER, Nothing)
|
|
|
|
If oReplacementArticleNumber Is Nothing Then
|
|
Return pArticleNumber
|
|
End If
|
|
|
|
Return GetReplacementArticleNumber(oReplacementArticleNumber, pMandator)
|
|
Catch ex As Exception
|
|
Logger.Error(ex)
|
|
Return Nothing
|
|
End Try
|
|
End Function
|
|
|
|
Public Function FindMatchingMandatorFromOrder(pData As Documents.Document) As Mandator
|
|
Dim oPositions = pData.Rows.
|
|
Where(Function(r) r.Name.ToUpper.EndsWith("T026")).
|
|
ToList()
|
|
Dim oEANNumbers = oPositions.
|
|
Select(Function(p)
|
|
If p.Fields.ContainsKey("Artikelnummer") Then
|
|
Return p.Fields.Item("Artikelnummer").Original
|
|
Else
|
|
' TODO: Throw or ignore?
|
|
Throw New Exceptions.MissingAttributeException("Artikelnummer")
|
|
End If
|
|
End Function).
|
|
Distinct().
|
|
ToList()
|
|
|
|
Dim oYear = GetWinLineYear()
|
|
Dim oMandatorId As String = String.Empty
|
|
Dim oWhitelistedMandators = Mandators.
|
|
Where(Function(m) m.IsWhitelisted = True).
|
|
ToList()
|
|
|
|
For Each oEANNumber In oEANNumbers
|
|
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] = '{oEANNumber}'
|
|
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}]", oEANNumber, 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}]", oEANNumber, oMandator.Id)
|
|
Exit For
|
|
End If
|
|
|
|
Dim oRow As DataRow = oTable.Rows.Item(0)
|
|
Dim oArticleNumber As String = GetRowItem(oRow, V21_MAINARTICLENUMBER, 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
|