Imports System.Collections.Generic Imports System.IO Imports System.Linq Imports DigitalData.Modules.Database Imports DigitalData.Modules.Interfaces Imports DigitalData.Modules.Logging Imports DigitalData.Modules.Filesystem Public Class ImportZUGFeRDFiles Implements IJob Public Const ZUGFERD_IN = "ZUGFeRD in" Public Const ZUGFERD_ERROR = "ZUGFeRD Error" Public Const ZUGFERD_SUCCESS = "ZUGFeRD Success" Private _logger As Logger Private _logConfig As LogConfig Private _zugferd As ZUGFeRDInterface Private _firebird As Firebird Private _filesystem As Filesystem.File Public Class WorkerArgs Public WatchDirectories As List(Of String) Public SuccessDirectory As String Public ErrorDirectory As String Public PropertyMap As Dictionary(Of String, XmlItemProperty) Public Sub New() WatchDirectories = New List(Of String) SuccessDirectory = Nothing ErrorDirectory = Nothing PropertyMap = New Dictionary(Of String, XmlItemProperty) End Sub End Class Public Class XmlItemProperty Public TableName As String Public Description As String Public IsRequired As Boolean End Class Public Sub New(LogConfig As LogConfig, Firebird As Firebird) _logConfig = LogConfig _logger = LogConfig.GetLogger() _firebird = Firebird _filesystem = New Filesystem.File(_logConfig) _zugferd = New ZUGFeRDInterface(_logConfig) End Sub Public Sub Start(Arguments As Object) Implements IJob.Start Dim args As WorkerArgs = Arguments _logger.Info("Starting Job {0}", Me.GetType.Name) For Each oPath As String In args.WatchDirectories Dim oDirInfo As New DirectoryInfo(oPath) _logger.Info($"Start processing directory {oDirInfo.FullName}") If oDirInfo.Exists Then Dim oFiles As List(Of FileInfo) = oDirInfo.GetFiles().ToList() Dim oFileCount = oFiles.Count Dim oCurrentFileCount = 0 _logger.Info("Found {0} files", oFileCount) For Each oFile In oFiles oCurrentFileCount += 1 _logger.Info($"({oCurrentFileCount}/{oFileCount}) Start processing file {oFile.Name}") Dim oMoveDirectory As String = args.SuccessDirectory Dim oDocument As CrossIndustryDocumentType Dim oValues As New Dictionary(Of String, String) Dim oGuid As String = Path.GetFileNameWithoutExtension(oFile.FullName) Dim oConnection = _firebird.GetConnection() Dim oTransaction = oConnection.BeginTransaction() Try oDocument = _zugferd.ExtractZUGFeRDFile(oFile.FullName) For Each mapping In args.PropertyMap Dim propertyValue As String = PropertyValues.GetPropValue(oDocument, mapping.Key) Dim propertyDescripton As String = mapping.Value.Description ' TODO: Check for missing values If String.IsNullOrEmpty(propertyValue) Then _logger.Warn("Property {0} is empty or not found", propertyDescripton) End If If String.IsNullOrEmpty(propertyValue) And mapping.Value.IsRequired Then _logger.Error("Property {0} is empty but required!", propertyDescripton) Throw New ApplicationException($"Property {propertyDescripton} is empty but required!") End If Console.WriteLine("{0} => {1}", propertyDescripton, propertyValue) oValues.Add(propertyDescripton, propertyValue) Dim oTableName = mapping.Value.TableName Dim oCommand = $"INSERT INTO {oTableName} (REFERENCE_GUID, ITEM_DESCRIPTION, ITEM_VALUE) VALUES ('{oGuid}', '{propertyDescripton}', '{propertyValue}')" _logger.Info("Mapping Property {0} to value {1}. Will be inserted into table {2}", propertyDescripton, propertyValue, oTableName) _firebird.ExecuteNonQueryWithConnection(oCommand, oConnection, Firebird.TransactionMode.ExternalTransaction, oTransaction) Next oTransaction.Commit() Catch ex As Exception oTransaction.Rollback() oMoveDirectory = args.ErrorDirectory _logger.Error(ex, "File {0} was not processesd. Transaction rolled back.") Finally oConnection.Close() _filesystem.MoveTo(oFile.FullName, oMoveDirectory) _logger.Info("Finished processing file {0}", oFile.Name) End Try Next Else _logger.Debug("Directory {0} does not exist", oPath) End If _logger.Info("Finished processing directory {0}", oPath) Next End Sub End Class