270 lines
11 KiB
VB.net
270 lines
11 KiB
VB.net
Imports System.Globalization
|
|
Imports System.IO
|
|
Imports DigitalData.Modules.Logging
|
|
Imports MultiTool.Shared.Schemas
|
|
Imports MultiTool.Shared.Winline
|
|
|
|
Namespace Documents
|
|
Public Class DocumentLoader
|
|
Inherits BaseClass
|
|
|
|
Private ReadOnly Winline As Winline.Data
|
|
|
|
Public Files As New List(Of Document)
|
|
|
|
|
|
Public Sub New(pLogConfig As LogConfig, pWinline As Winline.Data)
|
|
MyBase.New(pLogConfig, pLogConfig.GetLogger())
|
|
Winline = pWinline
|
|
End Sub
|
|
|
|
|
|
Public Function LoadFiles(pInputDirectory As String, pSchema As Schema, pMandator As Mandator) As Boolean
|
|
If pInputDirectory = String.Empty Then
|
|
Throw New ArgumentNullException("InputDirectory")
|
|
End If
|
|
|
|
Logger.Info("Loading files from directory [{0}]", pInputDirectory)
|
|
Files.Clear()
|
|
|
|
Try
|
|
Dim oDirectory As New DirectoryInfo(pInputDirectory)
|
|
Dim oFiles = oDirectory.GetFiles()
|
|
|
|
Logger.Debug("Found [{0}] files in directory [{1}]", oFiles.Count, oDirectory)
|
|
|
|
For Each oFile In oFiles
|
|
Dim oDocument = LoadFile(oFile, pSchema, pMandator)
|
|
Files.Add(oDocument)
|
|
Next
|
|
|
|
Return True
|
|
|
|
Catch ex As Exception
|
|
Logger.Error(ex)
|
|
Throw ex
|
|
|
|
End Try
|
|
End Function
|
|
|
|
Public Function LoadFile(pFileInfo As FileInfo, pSchema As Schema, pMandator As Mandator) As Document
|
|
Dim oFileList As New List(Of FileInfo) From {pFileInfo}
|
|
Logger.Info("Loading file [{0}]", pFileInfo.Name)
|
|
|
|
Try
|
|
Return oFileList.
|
|
Select(AddressOf WrapFileInfo).
|
|
Select(Function(d) IncludeSchema(d, pSchema)).
|
|
Select(Function(d) LoadDocumentData(d, pSchema)).
|
|
Select(Function(d) MatchDataFromWinLine(d, Winline.Mandators, pMandator)).
|
|
SingleOrDefault()
|
|
Catch ex As Exception
|
|
Logger.Error(ex)
|
|
Throw ex
|
|
End Try
|
|
End Function
|
|
|
|
|
|
Private Function IncludeSchema(pDocument As Document, pSchema As Schema) As Document
|
|
pDocument.Schema = pSchema
|
|
Return pDocument
|
|
End Function
|
|
|
|
|
|
''' <summary>
|
|
''' Loads a single document from the FullName Property in the Document Object
|
|
''' </summary>
|
|
''' <example>
|
|
'''
|
|
''' A document might look like this:
|
|
''' <MESOWebService>
|
|
''' <Row1></Row1>
|
|
''' <Row2></Row2>
|
|
''' <Row3></Row3>
|
|
''' </MESOWebService>
|
|
'''
|
|
''' </example>
|
|
Private Function LoadDocumentData(pDocument As Document, pSchema As Schema) As Document
|
|
Dim oText As String = IO.File.ReadAllText(pDocument.FullName)
|
|
Dim oDoc = XDocument.Parse(oText)
|
|
|
|
Dim oRootElement As XElement = XmlData.GetElement(oDoc, "MESOWebService")
|
|
If oRootElement Is Nothing Then
|
|
Throw New Exceptions.MalformedXmlException("Datei enthält kein MESOWebService-Element")
|
|
End If
|
|
|
|
Dim oTemplateName = XmlData.GetElementAttribute(oRootElement, "Template")
|
|
If oTemplateName Is Nothing Then
|
|
Throw New Exceptions.MalformedXmlException("Datei enthält kein Template-Attribut")
|
|
End If
|
|
|
|
Dim oTemplateType = XmlData.GetElementAttribute(oRootElement, "TemplateType")
|
|
If oTemplateType Is Nothing Then
|
|
Throw New Exceptions.MalformedXmlException("Datei enthält kein TemplateType-Attribut")
|
|
End If
|
|
|
|
Dim oOption = XmlData.GetElementAttribute(oRootElement, "option")
|
|
If oOption Is Nothing Then
|
|
Throw New Exceptions.MalformedXmlException("Datei enthält kein option-Attribut")
|
|
End If
|
|
|
|
Dim oPrintVoucher = XmlData.GetElementAttribute(oRootElement, "printVoucher")
|
|
If oPrintVoucher Is Nothing Then
|
|
Throw New Exceptions.MalformedXmlException("Datei enthält kein printVoucher-Attribut")
|
|
End If
|
|
|
|
' The first level of Elements are the document Rows
|
|
Dim oTopLevelElements As List(Of XElement) = oRootElement.Elements.ToList
|
|
Dim oDocumentRows As New List(Of DocumentRow)
|
|
|
|
For Each oTopLevelElement As XElement In oTopLevelElements
|
|
Dim oFields As New Dictionary(Of String, DocumentRow.FieldValue)
|
|
Dim oSubElements = oTopLevelElement.Descendants().ToList()
|
|
Dim oTable = pSchema.Tables.
|
|
Where(Function(t) t.Name = oTopLevelElement.Name).
|
|
FirstOrDefault()
|
|
|
|
For Each oSubElement As XElement In oSubElements
|
|
Dim oSchemaField = oTable.Columns.
|
|
Where(Function(c) c.Name = oSubElement.Name).
|
|
SingleOrDefault()
|
|
|
|
Dim oValue = oSubElement.Value
|
|
|
|
' TODO: Needed when we have time for date times
|
|
'If oSchemaField.DataType = Constants.ColumnType.Date Then
|
|
' Dim oDate = Date.ParseExact(oValue, "yyyy-MM-dd", CultureInfo.InvariantCulture)
|
|
' oValue = oDate.ToString("d")
|
|
'End If
|
|
|
|
oFields.Add(oSubElement.Name.ToString, New DocumentRow.FieldValue With {
|
|
.Original = oValue,
|
|
.Final = oValue,
|
|
.DataType = oSchemaField.DataType
|
|
})
|
|
Next
|
|
|
|
' Create a DocumentRow object for each Top Level Element
|
|
Dim oRow = New DocumentRow With {
|
|
.Name = oTopLevelElement.Name.ToString,
|
|
.Fields = oFields
|
|
}
|
|
|
|
oDocumentRows.Add(oRow)
|
|
Next
|
|
|
|
' Update the document
|
|
pDocument.TemplateName = oTemplateName
|
|
pDocument.TemplateType = oTemplateType
|
|
pDocument.Option = oOption
|
|
pDocument.PrintVoucher = oPrintVoucher
|
|
pDocument.Rows = oDocumentRows
|
|
|
|
Return pDocument
|
|
End Function
|
|
|
|
|
|
Private Function MatchDataFromWinLine(pDocument As Document, pMandators As List(Of Mandator), pMandator As Mandator) As Document
|
|
Dim oMandators As List(Of Winline.Mandator) = pMandators.
|
|
Where(Function(m) m.IsWhitelisted = True).
|
|
OrderBy(Function(m) m.Order).
|
|
ToList()
|
|
|
|
Dim oMandator As Mandator = Nothing
|
|
If pMandator IsNot Nothing Then
|
|
oMandator = pMandator
|
|
Else
|
|
oMandator = Winline.FindMatchingMandatorFromOrder(pDocument)
|
|
End If
|
|
|
|
If oMandator Is Nothing Then
|
|
Logger.Warn("Mandator not found for File [{0}]", pDocument.File.Name)
|
|
Throw New Exceptions.NoMandatorException($"Mandator not found for file [{pDocument.File.Name}]")
|
|
End If
|
|
|
|
pDocument = MatchDocumentData(pDocument, oMandator)
|
|
pDocument.Mandator = oMandator
|
|
|
|
Return pDocument
|
|
End Function
|
|
|
|
Private Function MatchDocumentData(pDocument As Document, pMandator As Winline.Mandator) As Document
|
|
Dim oYear = Winline.GetWinLineYear()
|
|
|
|
If pMandator Is Nothing Then
|
|
Return pDocument
|
|
End If
|
|
|
|
Dim oHead As DocumentRow = pDocument.Rows.
|
|
Where(Function(r) r.Name.ToUpper.EndsWith("T025")).
|
|
SetValue(Sub(r As DocumentRow) SetAccountByGLN(r, pMandator, "Fakt_Kontonummer", "Fakt_Name")).
|
|
SetValue(Sub(r As DocumentRow) SetAccountByGLN(r, pMandator, "Lief_Kontonummer", "Lief_Name")).
|
|
FirstOrDefault()
|
|
|
|
Dim oPositions As List(Of DocumentRow) = pDocument.Rows.
|
|
Where(Function(r) r.Name.ToUpper.EndsWith("T026")).
|
|
SetValue(Sub(oRow As DocumentRow)
|
|
Dim oNumberItem As DocumentRow.FieldValue = oRow.Fields.GetOrDefault("Artikelnummer")
|
|
If oNumberItem Is Nothing Then
|
|
Exit Sub
|
|
End If
|
|
|
|
Dim oArticleNumber = Winline.TryGetArticleNumber(oNumberItem.Original, pMandator)
|
|
If oArticleNumber IsNot Nothing Then
|
|
oNumberItem.External = oArticleNumber
|
|
oNumberItem.Final = oArticleNumber
|
|
End If
|
|
End Sub).
|
|
ToList()
|
|
|
|
Dim oList As New List(Of DocumentRow) From {oHead}
|
|
pDocument.Rows = oList.Concat(oPositions).ToList()
|
|
|
|
Return pDocument
|
|
End Function
|
|
|
|
Private Sub SetAccountByGLN(oRow As DocumentRow, pMandator As Winline.Mandator, pNumberField As String, pNameField As String)
|
|
' Try to read the Account number (which is a GLN really) and account Name
|
|
Dim oNumberItem As DocumentRow.FieldValue = oRow.Fields.GetOrDefault(pNumberField)
|
|
Dim oNameItem As DocumentRow.FieldValue = oRow.Fields.GetOrDefault(pNameField)
|
|
Dim oContainsAccountName As Boolean = Not IsNothing(oNameItem)
|
|
|
|
If oNumberItem Is Nothing Then
|
|
Exit Sub
|
|
End If
|
|
|
|
' Try to find an account that matches the GLN
|
|
Dim oAccount = Winline.TryGetAccount(oNumberItem.Original, pMandator)
|
|
|
|
' If an account was found, set it for External and Final value
|
|
If oAccount IsNot Nothing Then
|
|
oNumberItem.External = oAccount.Id
|
|
oNumberItem.Final = oAccount.Id
|
|
|
|
If oContainsAccountName Then
|
|
oNameItem.External = oAccount.Name
|
|
oNameItem.Final = oAccount.Name
|
|
Else
|
|
oRow.Fields.Add(pNameField, New DocumentRow.FieldValue() With {
|
|
.External = oAccount.Name,
|
|
.Final = oAccount.Name
|
|
})
|
|
End If
|
|
End If
|
|
End Sub
|
|
|
|
Private Function TryGetDictionaryItem(Of T)(pDictionary As IDictionary(Of String, T), pKey As String) As T
|
|
If pDictionary.ContainsKey(pKey) Then
|
|
Return pDictionary.Item(pKey)
|
|
Else
|
|
Return Nothing
|
|
End If
|
|
End Function
|
|
|
|
|
|
Private Function WrapFileInfo(pFileInfo As FileInfo) As Document
|
|
Return New Document With {.File = pFileInfo}
|
|
End Function
|
|
End Class
|
|
|
|
End Namespace |