diff --git a/DDMonorepo.sln b/DDMonorepo.sln
index 1901fe72..f966aadb 100644
--- a/DDMonorepo.sln
+++ b/DDMonorepo.sln
@@ -51,6 +51,8 @@ Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Interfaces", "Modules.Inter
EndProject
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "ZUGFeRDTest", "ZUGFeRDTest\ZUGFeRDTest.vbproj", "{16156434-E471-43F1-8030-76A0DA17CD5A}"
EndProject
+Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Jobs", "Jobs\Jobs.vbproj", "{39EC839A-3C30-4922-A41E-6B09D1DDE5C3}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -117,6 +119,10 @@ Global
{16156434-E471-43F1-8030-76A0DA17CD5A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{16156434-E471-43F1-8030-76A0DA17CD5A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{16156434-E471-43F1-8030-76A0DA17CD5A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {39EC839A-3C30-4922-A41E-6B09D1DDE5C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {39EC839A-3C30-4922-A41E-6B09D1DDE5C3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {39EC839A-3C30-4922-A41E-6B09D1DDE5C3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {39EC839A-3C30-4922-A41E-6B09D1DDE5C3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -137,6 +143,7 @@ Global
{7DEEC36E-EA5F-4711-AD1E-FD8894F4AD77} = {7AF3F9C2-C939-4A08-95C1-0453207E298A}
{AB6F09BF-E794-4F6A-94BB-C97C0BA84D64} = {3E2008C8-27B1-41DD-9B1A-0C4029F6AECC}
{16156434-E471-43F1-8030-76A0DA17CD5A} = {8FFE925E-8B84-45F1-93CB-32B1C96F41EB}
+ {39EC839A-3C30-4922-A41E-6B09D1DDE5C3} = {3E2008C8-27B1-41DD-9B1A-0C4029F6AECC}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C1BE4090-A0FD-48AF-86CB-39099D14B286}
diff --git a/DDZUGFeRDService/DDZUGFeRDService.vbproj b/DDZUGFeRDService/DDZUGFeRDService.vbproj
index bb82b9f2..443886ad 100644
--- a/DDZUGFeRDService/DDZUGFeRDService.vbproj
+++ b/DDZUGFeRDService/DDZUGFeRDService.vbproj
@@ -127,6 +127,10 @@
+
+ {39EC839A-3C30-4922-A41E-6B09D1DDE5C3}
+ Jobs
+
{eaf0ea75-5fa7-485d-89c7-b2d843b03a96}
Database
diff --git a/DDZUGFeRDService/ThreadRunner.vb b/DDZUGFeRDService/ThreadRunner.vb
index 958f7bbf..2fb3c65a 100644
--- a/DDZUGFeRDService/ThreadRunner.vb
+++ b/DDZUGFeRDService/ThreadRunner.vb
@@ -1,7 +1,11 @@
Imports System.ComponentModel
Imports System.IO
Imports System.Timers
+Imports System.Xml.XPath
+Imports DigitalData.Modules.Database
Imports DigitalData.Modules.Interfaces
+Imports DigitalData.Modules.Jobs
+Imports DigitalData.Modules.Jobs.ImportZUGFeRDFiles
Imports DigitalData.Modules.Logging
Public Class ThreadRunner
@@ -11,14 +15,35 @@ Public Class ThreadRunner
Private _logConfig As LogConfig
Private _logger As Logger
- Private _directories As List(Of String)
+ Private _firebird As Firebird
+ Private _watchDirectories As List(Of String)
+ Private _successDirectory As String
+ Private _errorDirectory As String
+ Private _zugferd As ZUGFeRDInterface
Private Const TIMER_INTERVAL = 60_000
- Public Sub New(LogConfig As LogConfig, Directories As List(Of String))
+ Public Sub New(LogConfig As LogConfig, WatchDirectories As List(Of String), SuccessDirectory As String, ErrorDirectory As String)
_logConfig = LogConfig
_logger = _logConfig.GetLogger()
- _directories = Directories
+ _watchDirectories = WatchDirectories
+ _successDirectory = SuccessDirectory
+ _errorDirectory = ErrorDirectory
+ _zugferd = New ZUGFeRDInterface(_logConfig)
+
+ If Not Directory.Exists(SuccessDirectory) Then
+ Throw New DirectoryNotFoundException("SuccessDirectory: " & SuccessDirectory)
+ End If
+
+ If Not Directory.Exists(ErrorDirectory) Then
+ Throw New DirectoryNotFoundException("ErrorDirectory: " & ErrorDirectory)
+ End If
+
+ For Each oDirectory In WatchDirectories
+ If Not Directory.Exists(oDirectory) Then
+ Throw New DirectoryNotFoundException("WatchDirectory: " & oDirectory)
+ End If
+ Next
_workerThread = New BackgroundWorker() With {
.WorkerReportsProgress = True,
@@ -46,33 +71,21 @@ Public Class ThreadRunner
Private Sub TimerElapsed(sender As Object, e As ElapsedEventArgs) Handles _workerTimer.Elapsed
If Not _workerThread.IsBusy Then
- _workerThread.RunWorkerAsync(_directories)
+ _workerThread.RunWorkerAsync(New WorkerArgs() With {
+ .WatchDirectories = _watchDirectories,
+ .SuccessDirectory = _successDirectory,
+ .ErrorDirectory = _errorDirectory
+ })
Else
_logger.Warn("Worker is busy")
End If
End Sub
Private Sub DoWork(sender As Object, e As DoWorkEventArgs) Handles _workerThread.DoWork
- Dim oDirectories As List(Of String) = e.Argument
+ Dim args As WorkerArgs = e.Argument
- For Each oPath As String In oDirectories
- Dim oDirInfo As New DirectoryInfo(oPath)
-
- _logger.Info($"Processing directory {oDirInfo.FullName}..")
-
- If oDirInfo.Exists Then
- Dim oFiles As List(Of FileInfo) = oDirInfo.GetFiles().ToList()
- Dim oFileCount = oFiles.Count
- Dim oCurrentFileCount = 0
-
- For Each oFile In oFiles
- oCurrentFileCount += 1
- _logger.Info($"Processing file {oFile.FullName} (${oCurrentFileCount}/{oFileCount})")
-
- ZUGFeRDInterface.ExtractXMLFile(oFile.FullName)
- Next
- End If
- Next
+ 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()
diff --git a/DDZUGFeRDService/ZUGFeRDService.vb b/DDZUGFeRDService/ZUGFeRDService.vb
index 2b3c0b7e..55c5115f 100644
--- a/DDZUGFeRDService/ZUGFeRDService.vb
+++ b/DDZUGFeRDService/ZUGFeRDService.vb
@@ -18,11 +18,11 @@ Public Class ZUGFeRDService
Dim oDatabase As String = ""
Dim oUser As String = ""
Dim oPassword As String = ""
- Dim directories As New List(Of String) From {"E:\ZUGFeRD_Import"}
+ Dim watchDirectories As New List(Of String) From {"E:\ZUGFeRD_Import"}
_firebird = New Firebird(_logConfig, oDataSource, oDatabase, oUser, oPassword)
- _threadRunner = New ThreadRunner(_logConfig, directories)
+ _threadRunner = New ThreadRunner(_logConfig, watchDirectories)
_threadRunner.Start()
End Sub
diff --git a/Filesystem/File.vb b/Filesystem/File.vb
index 38ba28d6..4d02582f 100644
--- a/Filesystem/File.vb
+++ b/Filesystem/File.vb
@@ -89,6 +89,11 @@ Public Class File
Return True
End Function
+ Public Sub MoveTo(FilePath As String, Directory As String)
+ Dim oFileInfo As New FileInfo(FilePath)
+ IO.File.Move(FilePath, Path.Combine(Directory, oFileInfo.Name))
+ End Sub
+
Private Function TestPathIsDirectory(Path As String) As Boolean
Dim oIsDirectory As Boolean = (System.IO.File.GetAttributes(Path) And FileAttributes.Directory) = FileAttributes.Directory
Return oIsDirectory
diff --git a/Jobs/App.config b/Jobs/App.config
new file mode 100644
index 00000000..731f6de6
--- /dev/null
+++ b/Jobs/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Jobs/EDMI/ZUGFeRD/ImportZUGFeRDFiles.vb b/Jobs/EDMI/ZUGFeRD/ImportZUGFeRDFiles.vb
new file mode 100644
index 00000000..848178b0
--- /dev/null
+++ b/Jobs/EDMI/ZUGFeRD/ImportZUGFeRDFiles.vb
@@ -0,0 +1,99 @@
+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
+
+ 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, String)
+
+ Public Sub New()
+ WatchDirectories = New List(Of String)
+ SuccessDirectory = Nothing
+ ErrorDirectory = Nothing
+ PropertyMap = New Dictionary(Of String, String)
+ End Sub
+ 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)
+
+ Try
+ oDocument = _zugferd.ExtractZUGFeRDFile(oFile.FullName)
+
+ For Each mapping In args.PropertyMap
+ Dim propertyValue As String = PropertyValues.GetPropValue(oDocument, mapping.Value)
+ _logger.Info("Mapping Property {0} to value {1}. Will be inserted into column {2}", mapping.Value, propertyValue, mapping.Key)
+
+ ' TODO: Check for missing values
+ If String.IsNullOrEmpty(propertyValue) Then
+ Throw New Exception($"Property {mapping.Value} not found or empty.")
+ End If
+
+ oValues.Add(mapping.Key, propertyValue)
+ Next
+
+ ' TODO: Insert into scheise
+
+ Catch ex As Exception
+ oMoveDirectory = args.ErrorDirectory
+ _logger.Error(ex)
+ Finally
+ _filesystem.MoveTo(oFile.FullName, oMoveDirectory)
+ _logger.Info("Finished processing file {0}", oFile.Name)
+ End Try
+ Next
+ End If
+
+ _logger.Info("Finished processing directory {0}", oPath)
+ Next
+ End Sub
+
+
+
+
+End Class
diff --git a/Jobs/EDMI/ZUGFeRD/PropertyValues.vb b/Jobs/EDMI/ZUGFeRD/PropertyValues.vb
new file mode 100644
index 00000000..b0bce3ea
--- /dev/null
+++ b/Jobs/EDMI/ZUGFeRD/PropertyValues.vb
@@ -0,0 +1,68 @@
+Imports System.Reflection
+Imports System.Text.RegularExpressions
+
+Public Class PropertyValues
+ Private Shared _indexPattern = "\((\d+)\)"
+ Private Shared _indexRegex As Regex = New Regex(_indexPattern)
+
+ Public Shared Function GetPropValue(Obj As Object, PropertyName As String)
+ Dim oNameParts As String() = PropertyName.Split("."c)
+ Dim oIndexReplaceRegex = "\(\d+\)"
+
+ If IsNothing(Obj) Then
+ Return Nothing
+ End If
+
+ If oNameParts.Length = 1 Then
+ Return Obj.GetType().GetProperty(PropertyName).GetValue(Obj, Nothing)
+ End If
+
+ For Each oPart As String In oNameParts
+ Dim oType As Type = Obj.GetType()
+ Dim oPartName = oPart
+ Dim oIndex As Integer = Nothing
+ Dim oHasIndex As Boolean = HasIndex(oPartName)
+
+ If oHasIndex Then
+ oPartName = StripIndex(oPart)
+ oIndex = GetIndex(oPart)
+ End If
+
+ Dim oInfo As PropertyInfo = oType.GetProperty(oPartName)
+
+ If IsNothing(oInfo) Then
+ Return Nothing
+ End If
+
+ Obj = oInfo.GetValue(Obj, Nothing)
+
+ If oHasIndex Then
+ Obj = Obj(0)
+ End If
+ Next
+
+ Return Obj
+ End Function
+
+ Private Shared Function GetIndex(Prop As String) As Integer
+ If Regex.IsMatch(Prop, _indexPattern) Then
+ Dim oMatch = _indexRegex.Match(Prop)
+ Dim oGroup = oMatch.Groups.Item(1)
+ Dim oValue = oGroup.Value
+
+ Return Integer.Parse(oValue)
+ End If
+
+ Return Nothing
+ End Function
+
+ Private Shared Function StripIndex(Prop As String) As String
+ Return Regex.Replace(Prop, _indexPattern, "")
+ End Function
+
+ Private Shared Function HasIndex(Prop As String) As Boolean
+ Return Regex.IsMatch(Prop, _indexPattern)
+ End Function
+
+
+End Class
diff --git a/Jobs/IJob.vb b/Jobs/IJob.vb
new file mode 100644
index 00000000..cb1aab71
--- /dev/null
+++ b/Jobs/IJob.vb
@@ -0,0 +1,3 @@
+Public Interface IJob
+ Sub Start(Arguments As Object)
+End Interface
diff --git a/Jobs/Jobs.vbproj b/Jobs/Jobs.vbproj
new file mode 100644
index 00000000..d0ad6d0c
--- /dev/null
+++ b/Jobs/Jobs.vbproj
@@ -0,0 +1,101 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {39EC839A-3C30-4922-A41E-6B09D1DDE5C3}
+ Library
+ DigitalData.Modules.Jobs
+ DigitalData.Modules.Jobs
+ 512
+ Empty
+ v4.6.1
+ 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022
+ true
+
+
+ AnyCPU
+ true
+ full
+ true
+ true
+ bin\Debug\
+
+
+ 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022
+
+
+ AnyCPU
+ pdbonly
+ false
+ true
+ true
+ bin\Release\
+
+
+ 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022
+
+
+ On
+
+
+ Binary
+
+
+ Off
+
+
+ On
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {991d0231-4623-496d-8bd0-9ca906029cbc}
+ Filesystem
+
+
+ {EAF0EA75-5FA7-485D-89C7-B2D843B03A96}
+ Database
+
+
+ {AB6F09BF-E794-4F6A-94BB-C97C0BA84D64}
+ Interfaces
+
+
+ {903B2D7D-3B80-4BE9-8713-7447B704E1B0}
+ Logging
+
+
+
+
+
+
+
+
+
+
+
+ ..\packages\NLog.4.5.11\lib\net45\NLog.dll
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Jobs/My Project/AssemblyInfo.vb b/Jobs/My Project/AssemblyInfo.vb
new file mode 100644
index 00000000..228bfeee
--- /dev/null
+++ b/Jobs/My Project/AssemblyInfo.vb
@@ -0,0 +1,34 @@
+Imports System
+Imports System.Reflection
+Imports System.Runtime.InteropServices
+
+' Allgemeine Informationen über eine Assembly werden über die folgenden
+' Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
+' die einer Assembly zugeordnet sind.
+
+' Werte der Assemblyattribute überprüfen
+
+
+
+
+
+
+
+
+
+
+'Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird.
+
+
+' Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
+'
+' Hauptversion
+' Nebenversion
+' Buildnummer
+' Revision
+'
+' Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
+' übernehmen, indem Sie "*" eingeben:
+
+
+
diff --git a/Jobs/packages.config b/Jobs/packages.config
new file mode 100644
index 00000000..f89fa324
--- /dev/null
+++ b/Jobs/packages.config
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/Modules.Database/Firebird.vb b/Modules.Database/Firebird.vb
index 3dd2cbed..db0fefba 100644
--- a/Modules.Database/Firebird.vb
+++ b/Modules.Database/Firebird.vb
@@ -94,6 +94,8 @@ Public Class Firebird
_connectionPassword = Password
_connectionString = oConnectionString
+ _logger.Debug("Connecting to database..")
+
' Test the connection
Dim oConnection = GetConnection()
' If initial connection was successfully, close it
@@ -102,6 +104,8 @@ Public Class Firebird
If oConnection Is Nothing Then
Throw New Exceptions.DatabaseException()
End If
+
+ _logger.Debug("Connection sucessfully established!")
End Sub
Public Function GetConnection() As FbConnection
@@ -165,6 +169,8 @@ Public Class Firebird
''' The Firebird connection to use
''' True, if command was executed sucessfully. Otherwise false.
Public Function ExecuteNonQueryWithConnection(SqlCommand As String, Connection As FbConnection) As Boolean
+ _logger.Debug("Executing Non-Query: {0}", SqlCommand)
+
If Connection Is Nothing Then
Return Nothing
End If
@@ -208,6 +214,8 @@ Public Class Firebird
''' The Firebird connection to use
''' The scalar value if the command was executed successfully. Nothing otherwise.
Public Function GetScalarValueWithConnection(SqlQuery As String, Connection As FbConnection) As Object
+ _logger.Debug("Fetching Scalar-Value: {0}", SqlQuery)
+
If Connection Is Nothing Then
Return Nothing
End If
@@ -252,6 +260,8 @@ Public Class Firebird
''' The Firebird connection to use
''' A datatable containing the results if the command was executed successfully. Nothing otherwise.
Public Function GetDatatableWithConnection(SqlQuery As String, Connection As FbConnection, Optional TransactionMode As TransactionMode = TransactionMode.NoTransaction) As DataTable
+ _logger.Debug("Fetching Datatable: {0}", SqlQuery)
+
If Connection Is Nothing Then
Return Nothing
End If
diff --git a/Modules.Interfaces/ZUGFeRD1p0.vb b/Modules.Interfaces/CrossIndustryDocumentType.vb
similarity index 100%
rename from Modules.Interfaces/ZUGFeRD1p0.vb
rename to Modules.Interfaces/CrossIndustryDocumentType.vb
diff --git a/Modules.Interfaces/Interfaces.vbproj b/Modules.Interfaces/Interfaces.vbproj
index 9118bed5..e3996de3 100644
--- a/Modules.Interfaces/Interfaces.vbproj
+++ b/Modules.Interfaces/Interfaces.vbproj
@@ -88,7 +88,7 @@
Settings.settings
True
-
+
diff --git a/Modules.Interfaces/ZUGFeRDInterface.vb b/Modules.Interfaces/ZUGFeRDInterface.vb
index 8dd60e8c..b5dd1685 100644
--- a/Modules.Interfaces/ZUGFeRDInterface.vb
+++ b/Modules.Interfaces/ZUGFeRDInterface.vb
@@ -28,31 +28,31 @@ Public Class ZUGFeRDInterface
'''
'''
'''
- Public Function ExtractXMLFile(Path As String) As XPathDocument
+ Public Function ExtractZUGFeRDFile(Path As String) As CrossIndustryDocumentType
Dim oException As New Exception
- Dim oXmlDocument = ExtractZugferd(Path)
+ Dim oXmlDocument = ValidateZUGFeRDFile(Path)
If IsNothing(oXmlDocument) Then
Throw New ZUGFeRDExecption(ErrorType.ExtractionFailed, "Datei ist kein gültiges ZUGFeRD Format.")
End If
- Return oXmlDocument
+ Return SerializeZUGFeRDDocument(oXmlDocument)
End Function
- Public Function ExtractZugferd(Path As String) As XPathDocument
- Dim oProcessOutput, oProcessError, oFileContent As String
- Dim oXmlDocument As XPathDocument
- Dim oTempFile = System.IO.Path.GetTempFileName()
- Dim oProcessStartInfo As New ProcessStartInfo() With {
- .FileName = ZUGFERD_CONVERTER_EXE,
- .RedirectStandardError = True,
- .RedirectStandardOutput = True,
- .UseShellExecute = False,
- .Arguments = $"-i ""{Path}"" -o ""{oTempFile}"""
- }
+ Public Function ValidateZUGFeRDFile(Path As String) As XPathDocument
+ Dim oProcessOutput, oProcessError As String
+ Dim oXmlDocument As XPathDocument
+ Dim oTempFile = IO.Path.GetTempFileName()
+
Dim oProcess As New Process() With {
- .StartInfo = oProcessStartInfo
+ .StartInfo = New ProcessStartInfo() With {
+ .FileName = ZUGFERD_CONVERTER_EXE,
+ .RedirectStandardError = True,
+ .RedirectStandardOutput = True,
+ .UseShellExecute = False,
+ .Arguments = $"-i ""{Path}"" -o ""{oTempFile}"""
+ }
}
Try
@@ -62,30 +62,35 @@ Public Class ZUGFeRDInterface
oProcess.WaitForExit()
Catch ex As Exception
_logger.Error(ex)
- Return Nothing
+ Throw ex
End Try
If Not oProcessOutput.Contains(ZUGFERD_CONVERTER_SUCCESS_MESSAGE) Then
_logger.Warn("File {0} is not a valid ZUGFeRD File!", Path)
- Return Nothing
+ Throw New ZUGFeRDExecption(ErrorType.NoValidFile, "Datei ist kein gültiges ZUGFeRD Format.")
End If
Try
- oXmlDocument = New XPath.XPathDocument(oTempFile)
+ oXmlDocument = New XPathDocument(oTempFile)
Catch ex As Exception
_logger.Error(ex)
- Return Nothing
+ Throw ex
End Try
Return oXmlDocument
End Function
- Public Function ParseXMLDocument(doc As XPathDocument)
- Dim nav As XPathNavigator = doc.CreateNavigator()
- Dim reader = nav.ReadSubtree()
+ Public Function SerializeZUGFeRDDocument(Document As XPathDocument) As CrossIndustryDocumentType
+ Try
+ Dim oNavigator As XPathNavigator = Document.CreateNavigator()
+ Dim oReader = oNavigator.ReadSubtree()
+ Dim oSerializer As New XmlSerializer(GetType(CrossIndustryDocumentType))
- Dim serializer As New XmlSerializer(GetType(CrossIndustryDocumentType))
- Dim cross As CrossIndustryDocumentType = serializer.Deserialize(reader)
+ Return oSerializer.Deserialize(oReader)
+ Catch ex As Exception
+ _logger.Error(ex)
+ Throw ex
+ End Try
End Function
End Class
diff --git a/ZUGFeRDTest/App.config b/ZUGFeRDTest/App.config
index 5534e287..203b80fb 100644
--- a/ZUGFeRDTest/App.config
+++ b/ZUGFeRDTest/App.config
@@ -1,6 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+ 172.24.12.41:E:\DB\Firebird\Databases\EDMI_TEMPLATE\EDMI_MASTER.FDB
+
+
+ 172.24.12.41
+
+
+
+
+
+
+ sysdba
+
+
+ dd
+
+
+
\ No newline at end of file
diff --git a/ZUGFeRDTest/Form1.vb b/ZUGFeRDTest/Form1.vb
index bb004c6a..bb109ec2 100644
--- a/ZUGFeRDTest/Form1.vb
+++ b/ZUGFeRDTest/Form1.vb
@@ -1,25 +1,81 @@
-Imports System.Xml
+Imports System.IO
+Imports System.Reflection
+Imports System.Text.RegularExpressions
+Imports System.Xml
+Imports DigitalData.Modules
+Imports DigitalData.Modules.Database
Imports DigitalData.Modules.Interfaces
+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 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)
+ 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
+ args.WatchDirectories.Add(row.Item("FOLDER_PATH"))
+
+ Case ZUGFERD_SUCCESS
+ args.SuccessDirectory = row.Item("FOLDER_PATH")
+
+ Case ZUGFERD_ERROR
+ 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 tableColumn = row.Item("TABLE_COLUMN")
+
+ args.PropertyMap.Add($"{tableName}.{tableColumn}", xmlPath)
+ Next
+
+ Return args
+ End Function
+
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
- Dim logConfig As New LogConfig(LogConfig.PathType.CurrentDirectory)
- Dim logger = logConfig.GetLogger()
+ Dim args As New WorkerArgs()
+ args = LoadFolderConfig(args)
+ args = LoadPropertyMapFor(args, "ZUGFeRD-Invoice")
- OpenFileDialog1.Filter = "pdf Dateien|*.pdf"
- OpenFileDialog1.Multiselect = False
-
- Dim oFDialogResult As DialogResult = OpenFileDialog1.ShowDialog()
- Dim zugferd As ZUGFeRDInterface = New ZUGFeRDInterface(logConfig)
-
- If oFDialogResult = DialogResult.OK Then
- Dim xml As XPath.XPathDocument = zugferd.ExtractXMLFile(OpenFileDialog1.FileName)
-
- zugferd.ParseXMLDocument(xml)
-
- MsgBox("YAY!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
- End If
+ Dim job As New Jobs.ImportZUGFeRDFiles(_logConfig, _firebird)
+ job.Start(args)
End Sub
End Class
diff --git a/ZUGFeRDTest/My Project/Settings.Designer.vb b/ZUGFeRDTest/My Project/Settings.Designer.vb
index 8f7ff546..a170e231 100644
--- a/ZUGFeRDTest/My Project/Settings.Designer.vb
+++ b/ZUGFeRDTest/My Project/Settings.Designer.vb
@@ -1,10 +1,10 @@
'------------------------------------------------------------------------------
'
-' This code was generated by a tool.
-' Runtime Version:4.0.30319.42000
+' Dieser Code wurde von einem Tool generiert.
+' Laufzeitversion:4.0.30319.42000
'
-' Changes to this file may cause incorrect behavior and will be lost if
-' the code is regenerated.
+' Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
+' der Code erneut generiert wird.
'
'------------------------------------------------------------------------------
@@ -13,57 +13,99 @@ Option Explicit On
Namespace My
-
- _
+
+ _
Partial Friend NotInheritable Class MySettings
Inherits Global.System.Configuration.ApplicationSettingsBase
-
- Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings)
-
-#Region "My.Settings Auto-Save Functionality"
+
+ Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings()),MySettings)
+
+#Region "Automatische My.Settings-Speicherfunktion"
#If _MyType = "WindowsForms" Then
- Private Shared addedHandler As Boolean
+ Private Shared addedHandler As Boolean
- Private Shared addedHandlerLockObject As New Object
+ Private Shared addedHandlerLockObject As New Object
- _
- Private Shared Sub AutoSaveSettings(ByVal sender As Global.System.Object, ByVal e As Global.System.EventArgs)
- If My.Application.SaveMySettingsOnExit Then
- My.Settings.Save()
- End If
- End Sub
+ _
+ Private Shared Sub AutoSaveSettings(sender As Global.System.Object, e As Global.System.EventArgs)
+ If My.Application.SaveMySettingsOnExit Then
+ My.Settings.Save()
+ End If
+ End Sub
#End If
#End Region
-
+
Public Shared ReadOnly Property [Default]() As MySettings
Get
-
+
#If _MyType = "WindowsForms" Then
- If Not addedHandler Then
- SyncLock addedHandlerLockObject
- If Not addedHandler Then
- AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings
- addedHandler = True
- End If
- End SyncLock
- End If
+ If Not addedHandler Then
+ SyncLock addedHandlerLockObject
+ If Not addedHandler Then
+ AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings
+ addedHandler = True
+ End If
+ End SyncLock
+ End If
#End If
Return defaultInstance
End Get
End Property
+
+ _
+ Public ReadOnly Property FB_DATABASE() As String
+ Get
+ Return CType(Me("FB_DATABASE"),String)
+ End Get
+ End Property
+
+ _
+ Public ReadOnly Property FB_DATASOURCE() As String
+ Get
+ Return CType(Me("FB_DATASOURCE"),String)
+ End Get
+ End Property
+
+ _
+ Public Property FB_USER() As String
+ Get
+ Return CType(Me("FB_USER"),String)
+ End Get
+ Set
+ Me("FB_USER") = value
+ End Set
+ End Property
+
+ _
+ Public Property FB_PASS() As String
+ Get
+ Return CType(Me("FB_PASS"),String)
+ End Get
+ Set
+ Me("FB_PASS") = value
+ End Set
+ End Property
End Class
End Namespace
Namespace My
-
- _
+
+ _
Friend Module MySettingsProperty
-
- _
+
+ _
Friend ReadOnly Property Settings() As Global.ZUGFeRDTest.My.MySettings
Get
Return Global.ZUGFeRDTest.My.MySettings.Default
diff --git a/ZUGFeRDTest/My Project/Settings.settings b/ZUGFeRDTest/My Project/Settings.settings
index 85b890b3..61758f88 100644
--- a/ZUGFeRDTest/My Project/Settings.settings
+++ b/ZUGFeRDTest/My Project/Settings.settings
@@ -1,7 +1,18 @@
-
-
-
-
-
-
+
+
+
+
+ 172.24.12.41:E:\DB\Firebird\Databases\EDMI_TEMPLATE\EDMI_MASTER.FDB
+
+
+ 172.24.12.41
+
+
+ sysdba
+
+
+ dd
+
+
+
\ No newline at end of file
diff --git a/ZUGFeRDTest/ZUGFeRDTest.vbproj b/ZUGFeRDTest/ZUGFeRDTest.vbproj
index 5ffa10c6..c1d84664 100644
--- a/ZUGFeRDTest/ZUGFeRDTest.vbproj
+++ b/ZUGFeRDTest/ZUGFeRDTest.vbproj
@@ -47,10 +47,19 @@
On
+
+
+ ..\packages\NLog.4.5.11\lib\net45\NLog.dll
+
+
+
+
+
+
@@ -117,8 +126,17 @@
Settings.Designer.vb
+
+
+ {39EC839A-3C30-4922-A41E-6B09D1DDE5C3}
+ Jobs
+
+
+ {EAF0EA75-5FA7-485D-89C7-B2D843B03A96}
+ Database
+
{ab6f09bf-e794-4f6a-94bb-c97c0ba84d64}
Interfaces
diff --git a/ZUGFeRDTest/packages.config b/ZUGFeRDTest/packages.config
new file mode 100644
index 00000000..f89fa324
--- /dev/null
+++ b/ZUGFeRDTest/packages.config
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file