diff --git a/Interfaces/ZUGFeRDInterface.vb b/Interfaces/ZUGFeRDInterface.vb
index 5031a5d9..f991b87d 100644
--- a/Interfaces/ZUGFeRDInterface.vb
+++ b/Interfaces/ZUGFeRDInterface.vb
@@ -8,42 +8,87 @@ Imports DigitalData.Modules.Logging
Imports GdPicture14
Public Class ZUGFeRDInterface
- Private _logConfig As LogConfig
- Private _logger As Logger
+ Private ReadOnly _logConfig As LogConfig
+ Private ReadOnly _logger As Logger
+ Private ReadOnly _Options As ZugferdOptions
+
+ Private ReadOnly ValidFilenames As New List(Of String) From {
+ PDFEmbeds.ZUGFERD_XML_FILENAME.ToUpper,
+ PDFEmbeds.FACTUR_X_XML_FILENAME_DE.ToUpper,
+ PDFEmbeds.FACTUR_X_XML_FILENAME_FR.ToUpper
+ }
+
+ Private AllowedFilenames As New List(Of String)
Public Enum ErrorType
NoValidFile
NoZugferd
NoValidZugferd
MissingProperties
+ UnsupportedFormat
UnknownError
End Enum
Public ReadOnly Property FileGroup As FileGroups
Public ReadOnly Property PropertyValues As PropertyValues
- Public Sub New(LogConfig As LogConfig, GDPictureKey As String)
- _logConfig = LogConfig
+ Public Class ZugferdOptions
+ Public Property AllowFacturX_Filename As Boolean = True
+ Public Property AllowXRechnung_Filename As Boolean = True
+ End Class
+
+ '''
+ ''' Create a new instance of ZUGFeRDInterface
+ '''
+ ''' A LogConfig object
+ ''' A valid GDPicture License
+ ''' Optional parameters to control various settings
+ Public Sub New(pLogConfig As LogConfig, pGDPictureKey As String, Optional pOptions As ZugferdOptions = Nothing)
+ _logConfig = pLogConfig
_logger = _logConfig.GetLogger()
+ If pOptions Is Nothing Then
+ _Options = New ZugferdOptions()
+ Else
+ _Options = pOptions
+ End If
+
+ ApplyFilenameOptions(_Options)
+
FileGroup = New FileGroups(_logConfig)
PropertyValues = New PropertyValues(_logConfig)
Try
Dim oLicenseManager As New LicenseManager
- oLicenseManager.RegisterKEY(GDPictureKey)
+ oLicenseManager.RegisterKEY(pGDPictureKey)
Catch ex As Exception
_logger.Warn("GDPicture License could not be registered!")
_logger.Error(ex)
End Try
End Sub
+ Private Sub ApplyFilenameOptions(pOptions As ZugferdOptions)
+ Dim oAllowedFilenames As List(Of String) = ValidFilenames
+
+ If pOptions.AllowFacturX_Filename = False Then
+ oAllowedFilenames = oAllowedFilenames.
+ Except(New List(Of String) From {PDFEmbeds.FACTUR_X_XML_FILENAME_FR}).ToList()
+ End If
+
+ If pOptions.AllowXRechnung_Filename = False Then
+ oAllowedFilenames = oAllowedFilenames.
+ Except(New List(Of String) From {PDFEmbeds.FACTUR_X_XML_FILENAME_DE}).ToList()
+ End If
+
+ AllowedFilenames = oAllowedFilenames
+ End Sub
+
+
'''
''' Validates a ZUGFeRD File and extracts the XML Document from it
'''
'''
'''
- '''
Public Function ExtractZUGFeRDFileWithGDPicture(Path As String) As Object
Dim oXmlDocument = ValidateZUGFeRDFileWithGDPicture(Path)
@@ -59,7 +104,6 @@ Public Class ZUGFeRDInterface
'''
'''
'''
- '''
Public Function ExtractZUGFeRDFileWithGDPicture(Stream As Stream) As Object
Dim oXmlDocument = ValidateZUGFeRDFileWithGDPicture(Stream)
@@ -73,15 +117,15 @@ Public Class ZUGFeRDInterface
'''
''' Validates a ZUGFeRD File and extracts the XML Document from it
'''
- '''
+ '''
'''
- '''
- Public Function ValidateZUGFeRDFileWithGDPicture(Stream As Stream) As XPathDocument
+ ''' The embedded xml data as an XPath document
+ Public Function ValidateZUGFeRDFileWithGDPicture(pStream As Stream) As XPathDocument
Dim oEmbedExtractor = New PDFEmbeds(_logConfig)
- Dim oAllowedExtensions = New List(Of String) From {"xml"}
Try
- Dim oFiles = oEmbedExtractor.Extract(Stream, oAllowedExtensions)
+ ' Extract XML attachments only!
+ Dim oFiles = oEmbedExtractor.Extract(pStream, New List(Of String) From {"xml"})
' Attachments are in this case the files that are embedded into a pdf file,
' like for example the zugferd-invoice.xml file
@@ -98,12 +142,18 @@ Public Class ZUGFeRDInterface
End Try
End Function
- Public Function ValidateZUGFeRDFileWithGDPicture(Path As String) As XPathDocument
+ '''
+ ''' Validates a ZUGFeRD File and extracts the XML Document from it
+ '''
+ '''
+ '''
+ ''' The embedded xml data as an XPath document
+ Public Function ValidateZUGFeRDFileWithGDPicture(pPath As String) As XPathDocument
Dim oEmbedExtractor = New PDFEmbeds(_logConfig)
- Dim oAllowedExtensions = New List(Of String) From {"xml"}
Try
- Dim oFiles = oEmbedExtractor.Extract(Path, oAllowedExtensions)
+ ' Extract XML attachments only!
+ Dim oFiles = oEmbedExtractor.Extract(pPath, New List(Of String) From {"xml"})
' Attachments are in this case the files that are embedded into a pdf file,
' like for example the zugferd-invoice.xml file
@@ -120,34 +170,38 @@ Public Class ZUGFeRDInterface
End Try
End Function
- Private Function HandleEmbeddedFiles(Results As List(Of PDFEmbeds.EmbeddedFile)) As XPathDocument
+ Private Function HandleEmbeddedFiles(pResults As List(Of PDFEmbeds.EmbeddedFile)) As XPathDocument
Dim oXmlDocument As XPathDocument
- If Results Is Nothing Then
+ If pResults Is Nothing Then
Throw New ZUGFeRDExecption(ErrorType.NoZugferd, "Datei ist keine ZUGFeRD Datei, weil die Attachments nicht gelesen werden konnten.")
End If
- If Results.Count = 0 Then
+ If pResults.Count = 0 Then
Throw New ZUGFeRDExecption(ErrorType.NoZugferd, "Datei ist keine ZUGFeRD Datei, weil sie keine Attachments enthält.")
End If
- Dim oValidFilenames As New List(Of String) From {
- PDFEmbeds.ZUGFERD_XML_FILENAME.ToUpper,
- PDFEmbeds.FACTUR_X_XML_FILENAME_DE.ToUpper,
- PDFEmbeds.FACTUR_X_XML_FILENAME_FR.ToUpper
- }
-
' Find the first file which filename matches the valid filenames for embedded invoice files
- Dim oFoundResult As PDFEmbeds.EmbeddedFile = Results.
- Where(Function(result) oValidFilenames.Contains(result.FileName.ToUpper)).
+ Dim oValidResult As PDFEmbeds.EmbeddedFile = pResults.
+ Where(Function(result) ValidFilenames.Contains(result.FileName.ToUpper)).
FirstOrDefault()
- If oFoundResult Is Nothing Then
- Throw New ZUGFeRDExecption(ErrorType.NoZugferd, "Datei ist keine ZUGFeRD Datei, weil die zugferd-invoice.xml nicht gefunden wurde.")
+ If oValidResult Is Nothing Then
+ Throw New ZUGFeRDExecption(ErrorType.NoZugferd, "Datei ist keine ZUGFeRD Datei, weil keine entsprechende XML-Datei gefunden wurde.")
+ End If
+
+ ' Search the embedded files for the ones which are allowed as per the configuration.
+ ' The config might say, allow ZUGFeRD but not Factur-X.
+ Dim oAllowedResult As PDFEmbeds.EmbeddedFile = pResults.
+ Where(Function(result) AllowedFilenames.Contains(result.FileName.ToUpper)).
+ FirstOrDefault()
+
+ If oAllowedResult Is Nothing Then
+ Throw New ZUGFeRDExecption(ErrorType.UnsupportedFormat, "Datei ist eine ZUGFeRD Datei, aber das Format wird nicht unterstützt.")
End If
Try
- Using oStream As New MemoryStream(oFoundResult.FileContents)
+ Using oStream As New MemoryStream(oAllowedResult.FileContents)
oXmlDocument = New XPathDocument(oStream)
End Using
@@ -163,9 +217,9 @@ Public Class ZUGFeRDInterface
End Try
End Function
- Public Function SerializeZUGFeRDDocument(Document As XPathDocument) As Object
+ Public Function SerializeZUGFeRDDocument(pDocument As XPathDocument) As Object
Try
- Dim oNavigator As XPathNavigator = Document.CreateNavigator()
+ Dim oNavigator As XPathNavigator = pDocument.CreateNavigator()
Dim oReader As XmlReader
Dim oResult = Nothing
diff --git a/Interfaces/ZUGFeRDInterface/PDFEmbeds.vb b/Interfaces/ZUGFeRDInterface/PDFEmbeds.vb
index b9143772..2385a93b 100644
--- a/Interfaces/ZUGFeRDInterface/PDFEmbeds.vb
+++ b/Interfaces/ZUGFeRDInterface/PDFEmbeds.vb
@@ -28,7 +28,7 @@ Public Class PDFEmbeds
Public Function Extract(FilePath As String, AllowedExtensions As List(Of String)) As List(Of EmbeddedFile)
Dim oFile As New List(Of EmbeddedFile)
Dim oFileInfo As FileInfo
- Dim oExtensions = AllowedExtensions.ConvertAll(New Converter(Of String, String)(Function(ext) ext.ToUpper))
+ Dim oExtensions = AllowedExtensions.Select(Function(ext) ext.ToUpper).ToList()
Logger.Debug("Extracting embedded files from [{0}]", FilePath)
@@ -69,7 +69,7 @@ Public Class PDFEmbeds
''' List of allowed extensions to be extracted
Public Function Extract(Stream As Stream, AllowedExtensions As List(Of String)) As List(Of EmbeddedFile)
Dim oResults As New List(Of EmbeddedFile)
- Dim oExtensions = AllowedExtensions.ConvertAll(New Converter(Of String, String)(Function(ext) ext.ToUpper))
+ Dim oExtensions = AllowedExtensions.Select(Function(ext) ext.ToUpper).ToList()
Logger.Debug("Extracting embedded files from stream")
diff --git a/Jobs/EDMI/ADSync/ADSyncArgs.vb b/Jobs/ADSync/ADSyncArgs.vb
similarity index 100%
rename from Jobs/EDMI/ADSync/ADSyncArgs.vb
rename to Jobs/ADSync/ADSyncArgs.vb
diff --git a/Jobs/EDMI/ADSync/ADSyncJob.vb b/Jobs/ADSync/ADSyncJob.vb
similarity index 100%
rename from Jobs/EDMI/ADSync/ADSyncJob.vb
rename to Jobs/ADSync/ADSyncJob.vb
diff --git a/Jobs/Exceptions.vb b/Jobs/Exceptions.vb
index 17d69987..bdd4c341 100644
--- a/Jobs/Exceptions.vb
+++ b/Jobs/Exceptions.vb
@@ -40,6 +40,14 @@ Public Class Exceptions
End Sub
End Class
+ Public Class UnsupportedFerdException
+ Inherits ApplicationException
+
+ Public Sub New()
+ MyBase.New("ZUGFeRD document found but is not supported!")
+ End Sub
+ End Class
+
Public Class NoFerdsException
Inherits ApplicationException
diff --git a/Jobs/EDMI/GraphQL/GraphQLArgs.vb b/Jobs/GraphQL/GraphQLArgs.vb
similarity index 100%
rename from Jobs/EDMI/GraphQL/GraphQLArgs.vb
rename to Jobs/GraphQL/GraphQLArgs.vb
diff --git a/Jobs/EDMI/GraphQL/GraphQLConfig.vb b/Jobs/GraphQL/GraphQLConfig.vb
similarity index 100%
rename from Jobs/EDMI/GraphQL/GraphQLConfig.vb
rename to Jobs/GraphQL/GraphQLConfig.vb
diff --git a/Jobs/EDMI/GraphQL/GraphQLJob.vb b/Jobs/GraphQL/GraphQLJob.vb
similarity index 100%
rename from Jobs/EDMI/GraphQL/GraphQLJob.vb
rename to Jobs/GraphQL/GraphQLJob.vb
diff --git a/Jobs/EDMI/GraphQL/GraphQLQuery.vb b/Jobs/GraphQL/GraphQLQuery.vb
similarity index 100%
rename from Jobs/EDMI/GraphQL/GraphQLQuery.vb
rename to Jobs/GraphQL/GraphQLQuery.vb
diff --git a/Jobs/Jobs.vbproj b/Jobs/Jobs.vbproj
index 90a55cd3..496f0acf 100644
--- a/Jobs/Jobs.vbproj
+++ b/Jobs/Jobs.vbproj
@@ -91,17 +91,17 @@
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Jobs/EDMI/ZUGFeRD/EmailData.vb b/Jobs/ZUGFeRD/EmailData.vb
similarity index 100%
rename from Jobs/EDMI/ZUGFeRD/EmailData.vb
rename to Jobs/ZUGFeRD/EmailData.vb
diff --git a/Jobs/EDMI/ZUGFeRD/EmailFunctions.vb b/Jobs/ZUGFeRD/EmailFunctions.vb
similarity index 100%
rename from Jobs/EDMI/ZUGFeRD/EmailFunctions.vb
rename to Jobs/ZUGFeRD/EmailFunctions.vb
diff --git a/Jobs/EDMI/ZUGFeRD/EmailStrings.vb b/Jobs/ZUGFeRD/EmailStrings.vb
similarity index 93%
rename from Jobs/EDMI/ZUGFeRD/EmailStrings.vb
rename to Jobs/ZUGFeRD/EmailStrings.vb
index 3def7e00..b29e11ea 100644
--- a/Jobs/EDMI/ZUGFeRD/EmailStrings.vb
+++ b/Jobs/ZUGFeRD/EmailStrings.vb
@@ -37,4 +37,8 @@
Betrags-Werte weisen ungültiges Format auf (25,01 anstatt 25.01)
"
+
+ Public Const EMAIL_UNSUPPORTED_DOCUMENT = "
+ Ihre Email enthielt ein ZUGFeRD Dokument, welches aber zur Zeit noch nicht unsterstützt wird.
+ "
End Class
diff --git a/Jobs/EDMI/ZUGFeRD/ImportZUGFeRDFiles.vb b/Jobs/ZUGFeRD/ImportZUGFeRDFiles.vb
similarity index 95%
rename from Jobs/EDMI/ZUGFeRD/ImportZUGFeRDFiles.vb
rename to Jobs/ZUGFeRD/ImportZUGFeRDFiles.vb
index 11914534..cb09f2aa 100644
--- a/Jobs/EDMI/ZUGFeRD/ImportZUGFeRDFiles.vb
+++ b/Jobs/ZUGFeRD/ImportZUGFeRDFiles.vb
@@ -26,35 +26,33 @@ Public Class ImportZUGFeRDFiles
Private Const DIRECTORY_DONT_MOVE = "DIRECTORY_DONT_MOVE"
-
' List of allowed extensions for PDF/A Attachments
' This list should not contain xml so the zugferd xml file will be filtered out
- Private ReadOnly AllowedExtensions As List(Of String) = New List(Of String) From {"docx", "doc", "pdf", "xls", "xlsx", "ppt", "pptx", "txt"}
+ Private ReadOnly AllowedExtensions As New List(Of String) From {"docx", "doc", "pdf", "xls", "xlsx", "ppt", "pptx", "txt"}
Private ReadOnly _logger As Logger
Private ReadOnly _logConfig As LogConfig
- Private ReadOnly _zugferd As ZUGFeRDInterface
Private ReadOnly _firebird As Firebird
Private ReadOnly _filesystem As Filesystem.File
- Private ReadOnly _EmailOutAccountId As Integer
Private ReadOnly _mssql As MSSQLServer
Private ReadOnly _email As EmailFunctions
+ Private ReadOnly _gdpictureLicenseKey As String
+ Private _zugferd As ZUGFeRDInterface
+ Private _EmailOutAccountId As Integer
- Public Sub New(LogConfig As LogConfig, Firebird As Firebird, pEmailOutAccount As Integer, pPortalName As String, Optional MSSQL As MSSQLServer = Nothing)
+ Public Sub New(LogConfig As LogConfig, Firebird As Firebird, Optional MSSQL As MSSQLServer = Nothing)
_logConfig = LogConfig
_logger = LogConfig.GetLogger()
_firebird = Firebird
_filesystem = New Filesystem.File(_logConfig)
_mssql = MSSQL
- _EmailOutAccountId = pEmailOutAccount
_email = New EmailFunctions(LogConfig, _mssql, _firebird)
_logger.Debug("Registering GDPicture License")
If _mssql IsNot Nothing Then
Dim oSQL = "SELECT LICENSE FROM TBDD_3RD_PARTY_MODULES WHERE NAME = 'GDPICTURE'"
- Dim oLicenseKey As String = _mssql.GetScalarValue(oSQL)
- _zugferd = New ZUGFeRDInterface(_logConfig, oLicenseKey)
+ _gdpictureLicenseKey = _mssql.GetScalarValue(oSQL)
Else
_logger.Warn("GDPicture License could not be registered! MSSQL is not enabled!")
Throw New ArgumentNullException("MSSQL")
@@ -125,6 +123,14 @@ Public Class ImportZUGFeRDFiles
Dim oPropertyExtractor = New PropertyValues(_logConfig)
Dim oAttachmentExtractor = New PDFEmbeds(_logConfig)
+ _EmailOutAccountId = oArgs.EmailOutProfileId
+
+ Dim oOptions As New ZUGFeRDInterface.ZugferdOptions() With {
+ .AllowFacturX_Filename = oArgs.AllowFacturX,
+ .AllowXRechnung_Filename = oArgs.AllowXRechnung
+ }
+ _zugferd = New ZUGFeRDInterface(_logConfig, _gdpictureLicenseKey, oOptions)
+
_logger.Debug("Starting Job {0}", [GetType].Name)
Try
@@ -238,6 +244,10 @@ Public Class ImportZUGFeRDFiles
oEmailAttachmentFiles.Add(oFile)
Continue For
+ Case ZUGFeRDInterface.ErrorType.UnsupportedFormat
+ _logger.Info("File [{0}] is an unsupported ZUFeRD document format!")
+ Throw New UnsupportedFerdException()
+
Case ZUGFeRDInterface.ErrorType.NoValidZugferd
_logger.Warn("File [{0}] is an Incorrectly formatted ZUGFeRD document!", oFile.Name)
Throw New InvalidFerdException()
@@ -380,6 +390,18 @@ Public Class ImportZUGFeRDFiles
_email.AddToEmailQueueMSSQL(oMessageId, oBody, oEmailData, "MD5HashException", _EmailOutAccountId, oArgs.NamePortal)
AddRejectedState(oMessageId, "MD5HashException", "Die gesendete Rechnung wurde bereits verarbeitet!", "", oSQLTransaction)
+ Catch ex As UnsupportedFerdException
+ _logger.Error(ex)
+
+ ' When UnsupportedFerdException is thrown, we don't have a MD5Hash yet.
+ ' That 's why we set it to String.Empty here.
+ Create_HistoryEntry(oMessageId, String.Empty, "REJECTED - ZUGFeRD yes but unsupported format", oFBTransaction)
+
+ Dim oBody = EmailStrings.EMAIL_UNSUPPORTED_DOCUMENT
+ Dim oEmailData = MoveAndRenameEmailToRejected(oArgs, oMessageId)
+ _email.AddToEmailQueueMSSQL(oMessageId, oBody, oEmailData, "UnsupportedFerdException", _EmailOutAccountId, oArgs.NamePortal)
+ AddRejectedState(oMessageId, "UnsupportedFerdException", "Nicht unterstütztes Datenformat", "", oSQLTransaction)
+
Catch ex As InvalidFerdException
_logger.Error(ex)
diff --git a/Jobs/EDMI/ZUGFeRD/WorkerArgs.vb b/Jobs/ZUGFeRD/WorkerArgs.vb
similarity index 84%
rename from Jobs/EDMI/ZUGFeRD/WorkerArgs.vb
rename to Jobs/ZUGFeRD/WorkerArgs.vb
index 662f107f..a34a90b0 100644
--- a/Jobs/EDMI/ZUGFeRD/WorkerArgs.vb
+++ b/Jobs/ZUGFeRD/WorkerArgs.vb
@@ -14,10 +14,16 @@ Public Class WorkerArgs
' Property Parameter
Public PropertyMap As New Dictionary(Of String, XmlItemProperty)
+ ' Email Parameter
+ Public EmailOutProfileId As Integer = 0
+
' Misc Flag Parameters
Public InsertIntoSQLServer As Boolean = False
Public ExceptionEmailAddress As String = Nothing
Public IgnoreRejectionStatus As Boolean = False
Public MaxAttachmentSizeInMegaBytes As Integer = -1
Public NamePortal As String = "NO PORTAL_NAME IN CONFIG"
+
+ Public AllowFacturX As Boolean = True
+ Public AllowXRechnung As Boolean = True
End Class
\ No newline at end of file