Imports System.ComponentModel Imports System.IO Imports System.Reflection Imports System.Text.RegularExpressions Imports System.Xml.Serialization Imports System.Xml.XPath Imports DigitalData.Modules.Language Imports DigitalData.Modules.Logging Imports ImporterShared.Documents Imports ImporterShared.Schemas.Orders Namespace Documents Public Class DocumentLoader Inherits BaseClass Private ReadOnly Winline As Winline.Data Private ReadOnly Serializer As Serializer Public Files As New List(Of Document) Public Sub New(pLogConfig As LogConfig, pWinline As Winline.Data) MyBase.New(pLogConfig, pLogConfig.GetLogger()) Winline = pWinline Serializer = New Serializer(pLogConfig) End Sub Public Function LoadFiles(pInputDirectory) 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) Files.Add(oDocument) Next Return True Catch ex As Exception Logger.Error(ex) Throw New IOException($"Could not load files from directory {pInputDirectory}", ex) End Try End Function Public Function LoadFile(pFileInfo As FileInfo) As Document Dim oFileList As New List(Of FileInfo) From {pFileInfo} Logger.Info("Loading file [{0}]", pFileInfo.Name) Return oFileList. Select(AddressOf WrapFileInfo). Select(AddressOf LoadDocumentData2). Select(Function(d) MatchDataFromWinLine(d, Winline.Mandators)). SingleOrDefault() End Function Private Function LoadDocumentData2(pDocument As Document) As Document Dim oText As String = IO.File.ReadAllText(pDocument.FullName) Dim oDoc = XDocument.Parse(oText) Dim oRootElement As XElement = XmlData.GetElement(oDoc, "MESOWebService") Dim oTemplateName = XmlData.GetElementAttribute(oRootElement, "Template") Dim oTemplateType = XmlData.GetElementAttribute(oRootElement, "TemplateType") Dim oOption = XmlData.GetElementAttribute(oRootElement, "option") Dim oPrintVoucher = XmlData.GetElementAttribute(oRootElement, "printVoucher") Dim oRowElements As List(Of XElement) = oRootElement.Elements.ToList Dim oRows As New List(Of DocumentRow) For Each oElement As XElement In oRowElements Dim oFields As New Dictionary(Of String, DocumentRow.FieldValue) Dim oSubElements = oElement.Descendants().ToList() For Each oSubElement As XElement In oSubElements oFields.Add(oSubElement.Name.ToString, New DocumentRow.FieldValue With { .Original = oSubElement.Value, .Final = oSubElement.Value }) Next Dim oRow = New DocumentRow With { .Name = oElement.Name.ToString, .Fields = oFields } oRows.Add(oRow) Next pDocument.TemplateName = oTemplateName pDocument.TemplateType = oTemplateType pDocument.Rows = oRows pDocument.Option = oOption pDocument.PrintVoucher = oPrintVoucher Return pDocument End Function Private Function MatchDataFromWinLine(pDocument As Document, pMandators As List(Of Winline.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 = Winline.FindMatchingMandatorFromOrder(pDocument) If oMandator Is Nothing Then Logger.Warn("Mandator not found for File [{0}]", pDocument.File.Name) End If pDocument = MatchOrderData(pDocument, oMandator) pDocument.Mandator = oMandator.Id 'If TypeOf pDocument.Data Is Schemas.Orders.Input.MESOWebService Then ' Dim oMandator = Winline.FindMatchingMandatorFromOrder(pDocument.Data) ' Dim oData As Schemas.Orders.Input.MESOWebService = MatchOrderData(pDocument.Data, oMandator) ' If oMandator Is Nothing Then ' Logger.Warn("Mandator not found for File [{0}]", pDocument.File.Name) ' End If ' pDocument.Mandator = oMandator.Id ' pDocument.Data = oData 'End If Return pDocument End Function Private Function MatchOrderData(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