From d33624c66cf9e6c48bfe278c735179f8cf2f4891 Mon Sep 17 00:00:00 2001 From: Jonathan Jenne Date: Tue, 18 Dec 2018 13:22:32 +0100 Subject: [PATCH] jj firebird --- DDZUGFeRDService/App.config | 12 ++ DDZUGFeRDService/DDZUGFeRDService.vbproj | 5 +- .../My Project/Settings.Designer.vb | 36 +++++ DDZUGFeRDService/My Project/Settings.settings | 12 ++ DDZUGFeRDService/ProjectInstaller.vb | 2 +- DDZUGFeRDService/ThreadRunner.vb | 113 +++++++++++----- DDZUGFeRDService/ZUGFeRDService.Designer.vb | 7 +- DDZUGFeRDService/ZUGFeRDService.resx | 123 ++++++++++++++++++ DDZUGFeRDService/ZUGFeRDService.vb | 21 ++- DD_CommunicationService/App.config | 4 +- .../My Project/Settings.Designer.vb | 4 +- .../My Project/Settings.settings | 4 +- Jobs/EDMI/ZUGFeRD/ImportZUGFeRDFiles.vb | 46 ++++--- Modules.Database/Firebird.vb | 28 ++-- Modules.Interfaces/ZUGFeRDInterface.vb | 2 +- ZUGFeRDTest/Form1.vb | 25 ++-- 16 files changed, 356 insertions(+), 88 deletions(-) create mode 100644 DDZUGFeRDService/ZUGFeRDService.resx diff --git a/DDZUGFeRDService/App.config b/DDZUGFeRDService/App.config index bfa04c81..a6041ca9 100644 --- a/DDZUGFeRDService/App.config +++ b/DDZUGFeRDService/App.config @@ -16,6 +16,18 @@ Digital Data ZUGFeRD Service + + 172.24.12.41 + + + 172.24.12.41:E:\DB\Firebird\Databases\EDMI_TEMPLATE\EDMI_MASTER.FDB + + + sysdba + + + dd + \ No newline at end of file diff --git a/DDZUGFeRDService/DDZUGFeRDService.vbproj b/DDZUGFeRDService/DDZUGFeRDService.vbproj index 443886ad..6c7b8cb1 100644 --- a/DDZUGFeRDService/DDZUGFeRDService.vbproj +++ b/DDZUGFeRDService/DDZUGFeRDService.vbproj @@ -6,7 +6,7 @@ AnyCPU {7DEEC36E-EA5F-4711-AD1E-FD8894F4AD77} WinExe - DDZUGFeRDService.Service1 + DDZUGFeRDService.ZUGFeRDService DDZUGFeRDService DDZUGFeRDService 512 @@ -112,6 +112,9 @@ My.Resources Designer + + ZUGFeRDService.vb + diff --git a/DDZUGFeRDService/My Project/Settings.Designer.vb b/DDZUGFeRDService/My Project/Settings.Designer.vb index 92b56245..fc8f79e7 100644 --- a/DDZUGFeRDService/My Project/Settings.Designer.vb +++ b/DDZUGFeRDService/My Project/Settings.Designer.vb @@ -71,6 +71,42 @@ Namespace My Return CType(Me("SERVICE_DISPLAY_NAME"),String) End Get End Property + + _ + Public ReadOnly Property DB_DATASOURCE() As String + Get + Return CType(Me("DB_DATASOURCE"),String) + End Get + End Property + + _ + Public ReadOnly Property DB_DATABASE() As String + Get + Return CType(Me("DB_DATABASE"),String) + End Get + End Property + + _ + Public ReadOnly Property DB_USER() As String + Get + Return CType(Me("DB_USER"),String) + End Get + End Property + + _ + Public ReadOnly Property DB_PASSWORD() As String + Get + Return CType(Me("DB_PASSWORD"),String) + End Get + End Property End Class End Namespace diff --git a/DDZUGFeRDService/My Project/Settings.settings b/DDZUGFeRDService/My Project/Settings.settings index 89da6a1f..a6374583 100644 --- a/DDZUGFeRDService/My Project/Settings.settings +++ b/DDZUGFeRDService/My Project/Settings.settings @@ -8,5 +8,17 @@ Digital Data ZUGFeRD Service + + 172.24.12.41 + + + 172.24.12.41:E:\DB\Firebird\Databases\EDMI_TEMPLATE\EDMI_MASTER.FDB + + + sysdba + + + dd + \ No newline at end of file diff --git a/DDZUGFeRDService/ProjectInstaller.vb b/DDZUGFeRDService/ProjectInstaller.vb index be3040dd..e066985c 100644 --- a/DDZUGFeRDService/ProjectInstaller.vb +++ b/DDZUGFeRDService/ProjectInstaller.vb @@ -12,7 +12,7 @@ Public Class ProjectInstaller Public Sub New() process = New ServiceProcessInstaller With { - .Account = ServiceAccount.NetworkService + .Account = ServiceAccount.LocalSystem } service = New ServiceInstaller With { .ServiceName = My.Settings.SERVICE_NAME, diff --git a/DDZUGFeRDService/ThreadRunner.vb b/DDZUGFeRDService/ThreadRunner.vb index 2fb3c65a..06dcb1b1 100644 --- a/DDZUGFeRDService/ThreadRunner.vb +++ b/DDZUGFeRDService/ThreadRunner.vb @@ -20,62 +20,72 @@ Public Class ThreadRunner Private _successDirectory As String Private _errorDirectory As String Private _zugferd As ZUGFeRDInterface + Private _jobArguments As WorkerArgs - Private Const TIMER_INTERVAL = 60_000 + Private Const TIMER_INTERVAL_MS = 60_000 - Public Sub New(LogConfig As LogConfig, WatchDirectories As List(Of String), SuccessDirectory As String, ErrorDirectory As String) + Public Sub New(LogConfig As LogConfig, Firebird As Firebird) _logConfig = LogConfig _logger = _logConfig.GetLogger() - _watchDirectories = WatchDirectories - _successDirectory = SuccessDirectory - _errorDirectory = ErrorDirectory + _firebird = Firebird _zugferd = New ZUGFeRDInterface(_logConfig) - If Not Directory.Exists(SuccessDirectory) Then - Throw New DirectoryNotFoundException("SuccessDirectory: " & SuccessDirectory) + Dim args As New WorkerArgs() + args = LoadFolderConfig(args) + args = LoadPropertyMapFor(args, "DEFAULT") + _jobArguments = args + + _logger.Info("Checking SuccessDirectory {0}", args.SuccessDirectory) + If Not Directory.Exists(args.SuccessDirectory) Then + _logger.Warn("SuccessDirectory {0} does not exist!", args.SuccessDirectory) + 'Throw New DirectoryNotFoundException("SuccessDirectory: " & args.SuccessDirectory) End If - If Not Directory.Exists(ErrorDirectory) Then - Throw New DirectoryNotFoundException("ErrorDirectory: " & ErrorDirectory) + _logger.Info("Checking ErrorDirectory {0}", args.ErrorDirectory) + If Not Directory.Exists(args.ErrorDirectory) Then + 'Throw New DirectoryNotFoundException("ErrorDirectory: " & args.ErrorDirectory) + _logger.Warn("ErrorDirectory {0} does not exist!", args.ErrorDirectory) End If - For Each oDirectory In WatchDirectories + For Each oDirectory In args.WatchDirectories + _logger.Info("Checking WatchDirectory {0}", oDirectory) If Not Directory.Exists(oDirectory) Then - Throw New DirectoryNotFoundException("WatchDirectory: " & oDirectory) + 'Throw New DirectoryNotFoundException("WatchDirectory: " & oDirectory) + _logger.Warn("WatchDirectory {0} does not exist!", oDirectory) End If Next _workerThread = New BackgroundWorker() With { - .WorkerReportsProgress = True, + .WorkerReportsProgress = False, .WorkerSupportsCancellation = True } _workerTimer = New Timer With { - .Interval = TIMER_INTERVAL + .Interval = TIMER_INTERVAL_MS } End Sub Public Sub Start() _workerTimer.Start() - _logger.Info("ThreadRunner started.") + _logger.Debug("ThreadRunner started.") End Sub Public Sub [Stop]() - If _workerThread.IsBusy Then - _workerThread.CancelAsync() - _logger.Info("Worker cancelled.") - End If - _workerTimer.Stop() - _logger.Info("ThreadRunner stopped.") + Try + If _workerThread.IsBusy Then + _workerThread.CancelAsync() + _logger.Debug("Worker cancelled.") + End If + _workerTimer.Stop() + _logger.Debug("ThreadRunner stopped.") + Catch ex As Exception + _logger.Error(ex) + End Try End Sub Private Sub TimerElapsed(sender As Object, e As ElapsedEventArgs) Handles _workerTimer.Elapsed If Not _workerThread.IsBusy Then - _workerThread.RunWorkerAsync(New WorkerArgs() With { - .WatchDirectories = _watchDirectories, - .SuccessDirectory = _successDirectory, - .ErrorDirectory = _errorDirectory - }) + _workerThread.RunWorkerAsync(_jobArguments) Else _logger.Warn("Worker is busy") End If @@ -84,14 +94,59 @@ Public Class ThreadRunner Private Sub DoWork(sender As Object, e As DoWorkEventArgs) Handles _workerThread.DoWork Dim args As WorkerArgs = e.Argument + _logger.Debug("Background worker running..") + Dim job As New ImportZUGFeRDFiles(_logConfig, _firebird) job.Start(args) End Sub - Private Sub WorkProgress(sender As Object, e As ProgressChangedEventArgs) Handles _workerThread.ProgressChanged - Throw New NotImplementedException() - End Sub Private Sub WorkCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles _workerThread.RunWorkerCompleted - Throw New NotImplementedException() + _logger.Debug("Background worker completed!") End Sub + + Private Function LoadFolderConfig(args As WorkerArgs) + Dim oSQL As String = "SELECT T1.FOLDER_TYPE, T.FOLDER_PATH FROM TBEDM_FOLDER T, TBEDM_FOLDER_TYPE T1 WHERE T.FOLDER_TYPE_ID = T1.GUID AND T1.""ACTIVE"" = True AND T.""ACTIVE"" = True" + Dim oResult As DataTable = _firebird.GetDatatable(oSQL) + + For Each row As DataRow In oResult.Rows + Dim oFolderType = row.Item("FOLDER_TYPE") + + Select Case oFolderType + Case ZUGFERD_IN + _logger.Debug("Setting WatchDirectory: {0}", row.Item("FOLDER_PATH")) + args.WatchDirectories.Add(row.Item("FOLDER_PATH")) + + Case ZUGFERD_SUCCESS + _logger.Debug("Setting SuccessDirectory: {0}", row.Item("FOLDER_PATH")) + args.SuccessDirectory = row.Item("FOLDER_PATH") + + Case ZUGFERD_ERROR + _logger.Debug("Setting ErrorDirectory: {0}", row.Item("FOLDER_PATH")) + args.ErrorDirectory = row.Item("FOLDER_PATH") + + End Select + Next + + Return args + End Function + + Private Function LoadPropertyMapFor(args As WorkerArgs, specification As String) + Dim oSQL As String = $"SELECT * FROM TBEDM_XML_ITEMS WHERE SPECIFICATION = '{specification}' AND ACTIVE = True" + Dim oResult As DataTable = _firebird.GetDatatable(oSQL) + + For Each row As DataRow In oResult.Rows + Dim xmlPath = row.Item("XML_PATH") + Dim tableName = row.Item("TABLE_NAME") + Dim description = row.Item("DESCRIPTION") + Dim isRequired = row.Item("IS_REQUIRED") + + args.PropertyMap.Add(xmlPath, New XmlItemProperty() With { + .Description = description, + .TableName = tableName, + .IsRequired = isRequired + }) + Next + + Return args + End Function End Class diff --git a/DDZUGFeRDService/ZUGFeRDService.Designer.vb b/DDZUGFeRDService/ZUGFeRDService.Designer.vb index 9a12be56..29419018 100644 --- a/DDZUGFeRDService/ZUGFeRDService.Designer.vb +++ b/DDZUGFeRDService/ZUGFeRDService.Designer.vb @@ -41,8 +41,13 @@ Partial Class ZUGFeRDService ' Das Bearbeiten mit dem Code-Editor ist nicht möglich. _ Private Sub InitializeComponent() - components = New System.ComponentModel.Container() + ' + 'ZUGFeRDService + ' + Me.AutoLog = False + Me.CanShutdown = True Me.ServiceName = "Service1" + End Sub End Class diff --git a/DDZUGFeRDService/ZUGFeRDService.resx b/DDZUGFeRDService/ZUGFeRDService.resx new file mode 100644 index 00000000..e5858cc2 --- /dev/null +++ b/DDZUGFeRDService/ZUGFeRDService.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + \ No newline at end of file diff --git a/DDZUGFeRDService/ZUGFeRDService.vb b/DDZUGFeRDService/ZUGFeRDService.vb index 55c5115f..b30b0486 100644 --- a/DDZUGFeRDService/ZUGFeRDService.vb +++ b/DDZUGFeRDService/ZUGFeRDService.vb @@ -11,19 +11,26 @@ Public Class ZUGFeRDService Protected Overrides Sub OnStart(ByVal args() As String) _logConfig = New LogConfig(LogConfig.PathType.CustomPath, Path.Combine(My.Application.Info.DirectoryPath, "Log")) + _logConfig.Debug = True _logger = _logConfig.GetLogger() _logger.Info($"{My.Settings.SERVICE_NAME} is starting.") - Dim oDataSource As String = "" - Dim oDatabase As String = "" - Dim oUser As String = "" - Dim oPassword As String = "" - Dim watchDirectories As New List(Of String) From {"E:\ZUGFeRD_Import"} + Dim oDataSource As String = My.Settings.DB_DATASOURCE + Dim oDatabase As String = My.Settings.DB_DATABASE + Dim oUser As String = My.Settings.DB_USER + Dim oPassword As String = My.Settings.DB_PASSWORD + + _logger.Debug("Datasource: {0}", oDataSource) + _logger.Debug("Database: {0}", oDatabase) _firebird = New Firebird(_logConfig, oDataSource, oDatabase, oUser, oPassword) - _threadRunner = New ThreadRunner(_logConfig, watchDirectories) - _threadRunner.Start() + Try + _threadRunner = New ThreadRunner(_logConfig, _firebird) + _threadRunner.Start() + Catch ex As Exception + _logger.Error(ex) + End Try End Sub Protected Overrides Sub OnStop() diff --git a/DD_CommunicationService/App.config b/DD_CommunicationService/App.config index 0a9fe0f9..44c12139 100644 --- a/DD_CommunicationService/App.config +++ b/DD_CommunicationService/App.config @@ -11,10 +11,10 @@ - 172.24.12.41:E:\DB\Firebird\Databases\EDMI_TEMPLATE\EDMI_MASTER.FDB + 172.24.12.41 - 172.24.12.41 + 172.24.12.41:E:\DB\Firebird\Databases\EDMI_TEMPLATE\EDMI_MASTER.FDB sysdba diff --git a/DD_CommunicationService/My Project/Settings.Designer.vb b/DD_CommunicationService/My Project/Settings.Designer.vb index 2dd1520d..4b7796f5 100644 --- a/DD_CommunicationService/My Project/Settings.Designer.vb +++ b/DD_CommunicationService/My Project/Settings.Designer.vb @@ -56,7 +56,7 @@ Namespace My _ + Global.System.Configuration.DefaultSettingValueAttribute("172.24.12.41")> _ Public ReadOnly Property FB_ConnString() As String Get Return CType(Me("FB_ConnString"),String) @@ -65,7 +65,7 @@ Namespace My _ + Global.System.Configuration.DefaultSettingValueAttribute("172.24.12.41:E:\DB\Firebird\Databases\EDMI_TEMPLATE\EDMI_MASTER.FDB")> _ Public ReadOnly Property FB_DATABASE() As String Get Return CType(Me("FB_DATABASE"),String) diff --git a/DD_CommunicationService/My Project/Settings.settings b/DD_CommunicationService/My Project/Settings.settings index 597dda7d..e5ab727a 100644 --- a/DD_CommunicationService/My Project/Settings.settings +++ b/DD_CommunicationService/My Project/Settings.settings @@ -3,10 +3,10 @@ - 172.24.12.41:E:\DB\Firebird\Databases\EDMI_TEMPLATE\EDMI_MASTER.FDB + 172.24.12.41 - 172.24.12.41 + 172.24.12.41:E:\DB\Firebird\Databases\EDMI_TEMPLATE\EDMI_MASTER.FDB sysdba diff --git a/Jobs/EDMI/ZUGFeRD/ImportZUGFeRDFiles.vb b/Jobs/EDMI/ZUGFeRD/ImportZUGFeRDFiles.vb index 1e8bbacf..a677fa86 100644 --- a/Jobs/EDMI/ZUGFeRD/ImportZUGFeRDFiles.vb +++ b/Jobs/EDMI/ZUGFeRD/ImportZUGFeRDFiles.vb @@ -9,6 +9,10 @@ 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 @@ -19,16 +23,22 @@ Public Class ImportZUGFeRDFiles Public WatchDirectories As List(Of String) Public SuccessDirectory As String Public ErrorDirectory As String - Public PropertyMap As Dictionary(Of String, 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, String) + 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() @@ -69,24 +79,27 @@ Public Class ImportZUGFeRDFiles oDocument = _zugferd.ExtractZUGFeRDFile(oFile.FullName) For Each mapping In args.PropertyMap - Dim propertyValue As String = PropertyValues.GetPropValue(oDocument, mapping.Value) + 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 - ' Throw New Exception($"Property {mapping.Value} not found or empty.") - 'End If + If String.IsNullOrEmpty(propertyValue) Then + _logger.Warn("Property {0} is empty or not found", propertyDescripton) + End If - Console.WriteLine("{0} => {1}", mapping.Key, propertyValue) - oValues.Add(mapping.Key, propertyValue) + 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 - ' TODO: Insert into scheise - Dim oTableColumnArray = mapping.Key.Split(".") - Dim oTableName = oTableColumnArray.First() - Dim oColumnName = oTableColumnArray.Last() + Console.WriteLine("{0} => {1}", propertyDescripton, propertyValue) + oValues.Add(propertyDescripton, propertyValue) - _logger.Info("Mapping Property {0} to value {1}. Will be inserted into column {2} on table {3}", mapping.Value, propertyValue, oTableName, oColumnName) + 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) - Dim oCommand = $"INSERT INTO {oTableName} (FILEID, ""NAME"", ""VALUE"") VALUES ('{oGuid}', '{oColumnName}', '{propertyValue}')" _firebird.ExecuteNonQueryWithConnection(oCommand, oConnection, Firebird.TransactionMode.ExternalTransaction, oTransaction) Next @@ -97,11 +110,12 @@ Public Class ImportZUGFeRDFiles _logger.Error(ex, "File {0} was not processesd. Transaction rolled back.") Finally oConnection.Close() - '_filesystem.MoveTo(oFile.FullName, oMoveDirectory) + _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) diff --git a/Modules.Database/Firebird.vb b/Modules.Database/Firebird.vb index 989368fe..8891f2bd 100644 --- a/Modules.Database/Firebird.vb +++ b/Modules.Database/Firebird.vb @@ -138,7 +138,8 @@ Public Class Firebird .DataSource = DataSource, .Database = Database, .UserID = User, - .Password = Password + .Password = Password, + .Charset = "UTF8" }.ToString() End Function @@ -153,17 +154,22 @@ Public Class Firebird End Function Private Function MaybeCommitTransaction(Transaction As FbTransaction, TransactionMode As TransactionMode) - If TransactionMode = TransactionMode.NoTransaction Then - Return True - Else - Try - Transaction.Commit() + Select Case TransactionMode + Case TransactionMode.NoTransaction Return True - Catch ex As Exception - _logger.Error(ex) - Return False - End Try - End If + Case TransactionMode.ExternalTransaction + Return True + Case TransactionMode.WithTransaction + Try + Transaction.Commit() + Return True + Catch ex As Exception + _logger.Error(ex) + Return False + End Try + Case Else + Return True + End Select End Function ''' diff --git a/Modules.Interfaces/ZUGFeRDInterface.vb b/Modules.Interfaces/ZUGFeRDInterface.vb index b5dd1685..1640c95c 100644 --- a/Modules.Interfaces/ZUGFeRDInterface.vb +++ b/Modules.Interfaces/ZUGFeRDInterface.vb @@ -9,7 +9,7 @@ Public Class ZUGFeRDInterface Private _logConfig As LogConfig Private _logger As Logger - Private Const ZUGFERD_CONVERTER_EXE = ".\pdf_zugferd_test.exe" + Private Const ZUGFERD_CONVERTER_EXE = "pdf_zugferd_test.exe" Private Const ZUGFERD_CONVERTER_SUCCESS_MESSAGE = "Document contains ZUGFeRD data." Public Enum ErrorType diff --git a/ZUGFeRDTest/Form1.vb b/ZUGFeRDTest/Form1.vb index 58da1a08..21a7141f 100644 --- a/ZUGFeRDTest/Form1.vb +++ b/ZUGFeRDTest/Form1.vb @@ -9,26 +9,16 @@ Imports DigitalData.Modules.Jobs.ImportZUGFeRDFiles Imports DigitalData.Modules.Logging Public Class Form1 - - Public Const ZUGFERD_IN = "ZUGFeRD in" - Public Const ZUGFERD_ERROR = "ZUGFeRD Error" - Public Const ZUGFERD_SUCCESS = "ZUGFeRD Success" - Private _logConfig As LogConfig Private _firebird As Firebird - Private PropertyMap As New Dictionary(Of String, String) + Private PropertyMap As New Dictionary(Of String, XmlItemProperty) + Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load _logConfig = New LogConfig(LogConfig.PathType.CurrentDirectory) _logConfig.Debug = True _firebird = New Firebird(_logConfig, My.Settings.FB_DATASOURCE, My.Settings.FB_DATABASE, My.Settings.FB_USER, My.Settings.FB_PASS) - - PropertyMap.Add("TBEDM_INVOICE_HEAD.INVOICE_NR", "HeaderExchangedDocument.ID.Value") - PropertyMap.Add("TBEDM_INVOICE_HEAD.DOC_TYPE", "HeaderExchangedDocument.Name(0).Value") - PropertyMap.Add("TBEDM_INVOICE_HEAD.INVOICE_DATE", "HeaderExchangedDocument.IssueDateTime.Item.Value") - PropertyMap.Add("TBEDM_INVOICE_HEAD.INVOICE_DATE_FORMAT", "HeaderExchangedDocument.IssueDateTime.Item.format") - PropertyMap.Add("TBEDM_INVOICE_HEAD.NOTE", "HeaderExchangedDocument.IncludedNote(0).Content(0).Value") End Sub Private Function LoadFolderConfig(args As WorkerArgs) @@ -61,9 +51,14 @@ Public Class Form1 For Each row As DataRow In oResult.Rows Dim xmlPath = row.Item("XML_PATH") Dim tableName = row.Item("TABLE_NAME") - Dim tableColumn = row.Item("TABLE_COLUMN") - - args.PropertyMap.Add($"{tableName}.{tableColumn}", xmlPath) + Dim description = row.Item("DESCRIPTION") + Dim isRequired = row.Item("IS_REQUIRED") + + args.PropertyMap.Add(xmlPath, New XmlItemProperty() With { + .Description = description, + .TableName = tableName, + .IsRequired = isRequired + }) Next Return args