Imports DigitalData.Modules.Logging
Imports DigitalData.Modules.Database
Imports DigitalData.Modules.Base
Imports System.Data
Imports System.IO
Imports System.Data.SqlClient
Imports System.Collections.Generic
Imports System.Text.RegularExpressions
Namespace ZUGFeRD
Public Class EmailFunctions
Private ReadOnly _logConfig As LogConfig
Private ReadOnly _logger As Logger
Private ReadOnly _mssql As MSSQLServer
Public Sub New(LogConfig As LogConfig, MSSQL As MSSQLServer)
_logConfig = LogConfig
_logger = _logConfig.GetLogger()
_mssql = MSSQL
End Sub
'''
''' Method to decide wether we use the old or the new
''' Rejection E-mail method.
'''
''' TODO we have no information about the language of the receiver at the moment
'''
''' E-Mail Message ID
''' Body Text
''' Email Data object
''' Exception Title
''' Sending Profile from config
''' Name of the Portal from config
''' ID for E-Mail-Template from config
''' Error Code
Public Sub AddToEmailQueueMSSQL(pMessageId As String, pBodyText As String, pEmailData As EmailData, pSourceProcedure As String,
pEmailAccountId As Integer, pNamePortal As String, pTemplateId As Integer, pErrorCode As ErrorCode)
Dim useLegacyMethod = True
Dim oErrorCode As String = String.Empty
' ErrorCode valid?
If pErrorCode <> ErrorCode.Unknown Then
Dim intCode As Integer = DirectCast(pErrorCode, Integer)
oErrorCode = $"ZUGFERD_Rejection_{intCode}"
Dim oSQL = $"SELECT COUNT(*) FROM TBDD_GUI_LANGUAGE_PHRASE WHERE TITLE = '{oErrorCode}'"
If _mssql.GetScalarValue(oSQL) > 0 Then
useLegacyMethod = False
Else
_logger.Warn($"Rejection reason [{oErrorCode}] not found in TBDD_GUI_LANGUAGE_PHRASE!")
End If
End If
' Gibt es das Template in TBDD_EMAIL_TEMPLATE?
If useLegacyMethod = False AndAlso pTemplateId > 0 Then
Try
Dim oSQL = $"SELECT COUNT(*) FROM TBDD_EMAIL_TEMPLATE WHERE GUID = {pTemplateId}"
If _mssql.GetScalarValue(oSQL) <= 0 Then
_logger.Warn($"EMAIL_TEMPLATE [{pTemplateId}] not found in TBDD_EMAIL_TEMPLATE!")
useLegacyMethod = True
End If
Catch ex As Exception
_logger.Error(ex)
useLegacyMethod = True
End Try
Else
_logger.Debug($"RejectionTemplateId not configured!")
useLegacyMethod = True
End If
' Check if Stored Procedure PRDD_SEND_REJECTION_MAIL exists
If useLegacyMethod = False Then
Try
Dim oSQL = $"SELECT COUNT(*) FROM sys.objects WHERE type = 'P' AND OBJECT_ID = OBJECT_ID('dbo.PRDD_SEND_REJECTION_MAIL')"
If _mssql.GetScalarValue(oSQL) <= 0 Then
_logger.Warn($"Procedure ['PRDD_SEND_REJECTION_MAIL'] not found in Database!")
useLegacyMethod = True
End If
Catch ex As Exception
_logger.Error(ex)
useLegacyMethod = True
End Try
End If
If useLegacyMethod = True Then
_logger.Warn("New rejection mail logic is not configured correctly, use legacy logic instead!")
AddToEmailQueueMSSQL(pMessageId, pBodyText, pEmailData, pSourceProcedure, pEmailAccountId, pNamePortal)
Else
_logger.Debug("New rejection mail logic is configured!")
AddToEmailQueueMSSQL(pMessageId, pTemplateId, oErrorCode, pEmailAccountId)
End If
End Sub
'''
''' Function calls SP PRDD_SEND_REJECTION_MAIL
''' for sending rejection mail.
'''
''' E-Mail Message ID
''' GUID for TBDD_EMAIL_TEMPLATE from config
''' ErrorID (TBDD_GUI_LANGUAGE_PHRASE)
''' Sending profile from config
Private Sub AddToEmailQueueMSSQL(pMessageId As String, pTemplateId As Integer, pErrorCode As String, pEmailAccountId As Integer)
Try
Dim oExecute = $"EXECUTE dbo.PRDD_SEND_REJECTION_MAIL
'{pMessageId}'
, 0
, {pEmailAccountId}
, 'ZUGFeRD Service'
, {pTemplateId}
, '{pErrorCode}'
, 77
"
If _mssql.ExecuteNonQuery(oExecute) = False Then
_logger.Warn("Could not execute PRDD_SEND_REJECTION_MAIL. See error log!")
End If
Catch ex As Exception
_logger.Error(ex)
End Try
End Sub
Private Sub AddToEmailQueueMSSQL(MessageId As String, BodyText As String, pEmailData As EmailData, SourceProcedure As String, pEmailAccountId As Integer, NamePortal As String)
If pEmailData Is Nothing Then
_logger.Warn("EmailData is empty. Email will not be sent!")
Exit Sub
End If
Try
Dim oJobId = RandomValue(1, 10000)
Dim oReference = MessageId
Dim oEmailTo = ""
Dim oSubject = EmailStrings.EMAIL_SUBJECT_REJECTED.Replace(EmailStrings.constNAME_ZUGFERD_PORTAL, NamePortal)
Dim oCreatedWho = "ZUGFeRD Service"
Dim oMaskedBodyText = BodyText.Replace("'", "''")
Dim oSubjectBodyText = String.Format(EmailStrings.EMAIL_SUBJECT_TEXT.Replace(EmailStrings.constNAME_ZUGFERD_PORTAL, NamePortal), pEmailData.Subject).Replace("'", "''")
Dim oCompleteBodyText = oMaskedBodyText & oSubjectBodyText
Dim oFinalBodyText = String.Format(EmailStrings.EMAIL_WRAPPING_TEXT.Replace(EmailStrings.constNAME_ZUGFERD_PORTAL, NamePortal), oCompleteBodyText)
Dim oEmailAddress = pEmailData.From
Dim oAttachmentPath = pEmailData.Attachment
If oAttachmentPath <> String.Empty Then
_logger.Debug($"Attachment_String [{oAttachmentPath}]!")
If IO.File.Exists(oAttachmentPath) = False Then
_logger.Info($"Attachment.File [{oAttachmentPath}] is not existing!!!")
End If
End If
Dim oAttachmentPathEscaped = oAttachmentPath.Replace("'", "''")
If IsNothing(oEmailAddress) OrElse String.IsNullOrWhiteSpace(oEmailAddress) Then
_logger.Warn("Could not find email-address for MessageId {0}", MessageId)
oEmailTo = String.Empty
Else
oEmailTo = oEmailAddress
End If
_logger.Debug("Generated Email:")
_logger.Debug("To: {0}", oEmailTo)
_logger.Debug("Subject: {0}", oSubject)
_logger.Debug("Body {0}", oFinalBodyText)
Dim osql = $"Select MAX(GUID) FROM TBEMLP_HISTORY WHERE EMAIL_MSGID = '{MessageId}'"
Dim oHistoryID = _mssql.GetScalarValue(osql)
If IsNumeric(oHistoryID) Then
Dim oInsert = $"INSERT INTO [dbo].[TBEMLP_EMAIL_OUT]
([REMINDER_TYPE_ID]
,[SENDING_PROFILE]
,[REFERENCE_ID]
,[REFERENCE_STRING]
,[WF_ID]
,[EMAIL_ADRESS]
,[EMAIL_SUBJ]
,[EMAIL_BODY]
,[COMMENT]
,[ADDED_WHO]
,EMAIL_ATTMT1)
VALUES
(77
,{pEmailAccountId}
,{oHistoryID}
,'{MessageId}'
,77
,'{oEmailTo}'
,'{oSubject}'
,'{oFinalBodyText}'
,'{SourceProcedure}'
,'{oCreatedWho}'
,'{oAttachmentPathEscaped}')"
_mssql.ExecuteNonQuery(oInsert)
Else
_logger.Warn("Could not get oHistoryID in AddToEmailQueueMSSQL!!")
End If
Catch ex As Exception
_logger.Error(ex)
End Try
End Sub
Public Function GetEmailDataForMessageId(MessageId As String) As EmailData
Dim oSQL = $"SELECT EMAIL_FROM, EMAIL_SUBJECT FROM TBEMLP_HISTORY WHERE EMAIL_MSGID = '{MessageId}'"
Try
Dim oDatatable = _mssql.GetDatatable(oSQL)
Dim oRow As DataRow
If oDatatable.Rows.Count = 0 Then
_logger.Warn("Got no results for MessageId {0}", MessageId)
Return Nothing
ElseIf oDatatable.Rows.Count > 1 Then
_logger.Warn("Got too many results for MessageId {0}. Using last row.", MessageId)
End If
_logger.Debug("Got Email Data for FileId {0}", MessageId)
oRow = oDatatable.Rows.Item(oDatatable.Rows.Count - 1)
Dim oFromDefault = String.Format("No Sender found for ({0})", MessageId)
Dim oFrom = oRow.ItemEx("EMAIL_FROM", oFromDefault)
Dim oSubjectDefault = String.Format("No Subject found for ({0})", MessageId)
Dim oSubject = oRow.ItemEx("EMAIL_SUBJECT", oSubjectDefault)
_logger.Info("Email Data for [{0}] fetched!", MessageId)
Return New EmailData() With {
.From = oFrom,
.Subject = oSubject
}
Catch ex As Exception
_logger.Warn("Could not fetch Email Data for FileId {0}", MessageId)
Return Nothing
End Try
End Function
Public Function GetOriginalEmailPath(OriginalEmailDirectory As String, MessageId As String) As String
Dim oAttachmentFile = MessageId & ".eml"
Dim oAttachmentPath = Path.Combine(OriginalEmailDirectory, oAttachmentFile)
If File.Exists(oAttachmentPath) Then
Return oAttachmentPath
Else
_logger.Warn("Email File {0} does not exist. Empty String will be returned.", oAttachmentPath)
Return String.Empty
End If
End Function
Private Function RandomValue(lowerBound As Integer, upperBound As Integer) As Integer
Dim oRandomValue = CInt(Math.Floor((upperBound - lowerBound + 1) * Rnd())) + lowerBound
Return oRandomValue
End Function
Public Function CreateBodyForMissingProperties(OriginalFilename As String, MissingProperties As List(Of String)) As String
Dim oBody = String.Format(EmailStrings.EMAIL_MISSINGPROPERTIES_1, OriginalFilename)
If MissingProperties.Count > 0 Then
oBody &= $"{vbNewLine}{vbNewLine}"
oBody &= EmailStrings.EMAIL_MISSINGPROPERTIES_2
oBody &= $"{vbNewLine}{vbNewLine}"
For Each prop In MissingProperties
oBody &= $"- {prop}"
Next
End If
Return oBody
End Function
Public Function CreateBodyForUnhandledException(MessageId As String, Exception As Exception) As String
Dim oBody = String.Format(EmailStrings.EMAIL_UNHANDLED_EXCEPTION, MessageId, Exception.Message, Exception.StackTrace)
Return oBody
End Function
End Class
End Namespace