Merge branch 'newMaster2024' of https://git.it.verag.ag/edv/SDL into newMaster2024

This commit is contained in:
2025-12-05 11:03:28 +01:00
18 changed files with 2751 additions and 940 deletions

View File

@@ -39,6 +39,8 @@ Public Class cKundenErweitert
Property EmailFreigabe_VBDPDF As Boolean = False
Property EmailFreigabe_ABDPDF As Boolean = False
Property EmailFreigabeBeleg_Sendungsunterlagen As Boolean = False
Property EmailFreigabeBeleg_Betreff As Boolean = False
Property EmailFreigabeBeleg_BetreffText As Object = Nothing
Property Email_AVM As Boolean = False
Property Depot_Kunde As Boolean = False
Property FiBuSchnittstelleLG As Boolean = False
@@ -101,7 +103,8 @@ Public Class cKundenErweitert
Property kde_Provisionsverguetung_GSAnKdNr As Object = Nothing
Property kde_zinssatz As Object = Nothing
Property kde_betreuer As Object = Nothing
Property kde_ATEZ_LogicustID As Object = Nothing
Property kde_ATEZ_GreenpulseID As Object = Nothing
Dim SQL As New SQL
@@ -147,6 +150,8 @@ Public Class cKundenErweitert
list.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("EmailFreigabe_VBDPDF", EmailFreigabe_VBDPDF))
list.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("EmailFreigabe_ABDPDF", EmailFreigabe_ABDPDF))
list.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("EmailFreigabeBeleg_Sendungsunterlagen", EmailFreigabeBeleg_Sendungsunterlagen))
list.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("EmailFreigabeBeleg_Betreff", EmailFreigabeBeleg_Betreff))
list.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("EmailFreigabeBeleg_BetreffText", EmailFreigabeBeleg_BetreffText))
list.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("Email_AVM", Email_AVM))
list.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("Depot_Kunde", Depot_Kunde))
list.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("FiBuSchnittstelleLG", FiBuSchnittstelleLG))
@@ -209,6 +214,8 @@ Public Class cKundenErweitert
list.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("kde_CSinsolventAm", kde_CSinsolventAm))
list.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("kde_zinssatz", kde_zinssatz))
list.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("kde_betreuer", kde_betreuer))
list.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("kde_ATEZ_LogicustID", kde_ATEZ_LogicustID))
list.Add(New VERAG_PROG_ALLGEMEIN.SQLVariable("kde_ATEZ_GreenpulseID", kde_ATEZ_GreenpulseID))
Return list
End Function

View File

@@ -368,7 +368,7 @@ Public Class cATEZ_Greenpulse_KafkaDecs
End Class
Public Class cATEZ_Greenpulse_KafkaDecsBuilder_DAKOSY
Public Class cATEZ_Greenpulse_KafkaDecsBuilder_DAKOSY 'WHSL nciht mehr
Public Shared Function BuildByMrn_DAKOSY_Archiv(mrn As String) As cATEZ_Greenpulse_KafkaDecs
Using con As SqlConnection = SQL.GetNewOpenConnectionAVISO()

View File

@@ -1,3 +1,258 @@
Public Class cATEZ_Greenpulse_KafkaInvoices
' Requires NuGet:
' - Confluent.Kafka
' - Newtonsoft.Json
' Target framework: .NET Framework 4.8 oder .NET 6/8
Imports System.Data.SqlClient
Imports System.Threading
Imports System.Windows.Forms
Imports Confluent.Kafka
Imports Newtonsoft.Json
''' <summary>
''' Einfaches Invoice-Payload-Objekt + Kafka-Producer.
''' JSON-Struktur: { "documents": [ { ... } ] }
''' Topic: dev.greenpulse.invoicedata.v1
''' </summary>
Public Class cATEZ_Greenpulse_KafkaInvoices
'========================
'== Kafka: Konfiguration (Klassenebene)
'========================
Public Shared BootstrapServers As String = "192.168.85.250:9092"
Public Shared TopicName As String = "dev.greenpulse.invoicedata.v1"
' Falls SASL/TLS benötigt:
Public Shared UseSasl As Boolean = False
Public Shared SaslUsername As String = ""
Public Shared SaslPassword As String = ""
Public Shared SecurityProtocolSetting As SecurityProtocol = SecurityProtocol.Plaintext
Public Shared SaslMechanismSetting As SaslMechanism = SaslMechanism.Plain
Private Const KEY_VERSION As String = "v1"
Private Const SEP_PIPE As Char = "|"c
'========================
'== Unique-Key-Ermittlung (z. B. nach Country/System/MRN)
'========================
Public Shared Function GetUniqueKey_Pipe(country As String, system As String, mrn As String) As String
Dim c = (country).ToUpperInvariant()
Dim s = (system).ToUpperInvariant()
Dim m = (mrn).ToUpperInvariant()
Return String.Join(SEP_PIPE, New String() {KEY_VERSION, c, s, m})
End Function
'========================
'== Datenobjekt
'========================
<JsonProperty("documents")>
Public Property Documents As List(Of DocumentNode)
Public Class DocumentNode
<JsonProperty("reference")>
Public Property Reference As String
<JsonProperty("doc-type")>
Public Property DocType As String
<JsonProperty("mime-type")>
Public Property MimeType As String
<JsonProperty("blob")>
Public Property Blob As String ' Base64
End Class
'========================
'== Serialisierung
'========================
Public Function ToJson(Optional pretty As Boolean = True) As String
Dim format = If(pretty, Formatting.Indented, Formatting.None)
Return JsonConvert.SerializeObject(Me, format)
End Function
'========================
'== Beispielbefüllung
'========================
Public Shared Function BuildDemo() As cATEZ_Greenpulse_KafkaInvoices
Return New cATEZ_Greenpulse_KafkaInvoices() With {
.Documents = New List(Of DocumentNode) From {
New DocumentNode() With {
.Reference = "Handelsrechnung.pdf",
.DocType = "invoice",
.MimeType = "application/octet-stream",
.Blob = "" ' Base64-String
}
}
}
End Function
'========================
'== Kafka: Insert/Update (per Message-Key)
'========================
Public Shared Function InsertOrUpdateToKafkaSync_Bool(
rec As cATEZ_Greenpulse_KafkaInvoices,
unique_KEY As String,
Optional waitMs As Integer = 30000
) As Boolean
Try
Dim result = InsertOrUpdateToKafkaSync(rec, unique_KEY, waitMs)
Return True
Catch ex As Exception
MessageBox.Show("Fehler beim Senden an Kafka: " & ex.Message,
"Fehler",
MessageBoxButtons.OK,
MessageBoxIcon.Error)
Return False
End Try
End Function
Public Shared Function InsertOrUpdateToKafkaSync(
rec As cATEZ_Greenpulse_KafkaInvoices,
unique_KEY As String,
Optional waitMs As Integer = 30000
) As DeliveryResult(Of String, String)
Dim cfg As New ProducerConfig With {
.BootstrapServers = BootstrapServers,
.EnableIdempotence = True,
.Acks = Acks.All,
.MaxInFlight = 5,
.MessageTimeoutMs = Math.Max(waitMs, 60000),
.RequestTimeoutMs = 30000,
.CompressionType = Confluent.Kafka.CompressionType.Zstd,
.MessageMaxBytes = 20971520, ' ≈ 20 MB
.EnableDeliveryReports = True,
.AllowAutoCreateTopics = True
}
Using producer = New ProducerBuilder(Of String, String)(cfg).Build()
Dim key = unique_KEY
Dim msg = New Message(Of String, String) With {
.Key = key,
.Value = rec.ToJson(False)
}
Dim done As New Threading.ManualResetEventSlim(False)
Dim lastReport As DeliveryResult(Of String, String) = Nothing
producer.Produce(TopicName, msg,
Sub(r)
lastReport = r
done.Set()
End Sub)
If Not done.Wait(waitMs) Then
producer.Flush(TimeSpan.FromSeconds(5))
Throw New TimeoutException($"DeliveryCallback nach {waitMs} ms nicht eingetroffen.")
End If
If lastReport Is Nothing Then
Throw New TimeoutException("DeliveryResult leer.")
End If
If lastReport.Status <> PersistenceStatus.Persisted Then
Throw New Exception($"Sende-Status: {lastReport.Status} @ {lastReport.TopicPartitionOffset}")
End If
Return lastReport
End Using
End Function
End Class
Public Class cATEZ_Greenpulse_KafkaInvoicesBuilder_DAKOSY
''' <summary>
''' Baut ein reines Invoice-Dokument-Payload für Greenpulse
''' aus dem DAKOSY-Archiv zur angegebenen MRN.
''' </summary>
Public Shared Function BuildByMrn_DAKOSY_Archiv(mrn As String) As cATEZ_Greenpulse_KafkaInvoices
Using con As SqlConnection = SQL.GetNewOpenConnectionAVISO()
Dim sql As String = "
SELECT
*
FROM [tbl_DY_Zollmeldungen_Import]
WHERE [Registriernummer_MRN] = @mrn
ORDER BY cast([PositionNo] as int), cast([Positionen] as int), [Id];
"
Dim dt As New DataTable()
Using cmd As New SqlCommand(sql, con)
cmd.Parameters.AddWithValue("@mrn", mrn)
Using da As New SqlDataAdapter(cmd)
da.Fill(dt)
End Using
End Using
If dt.Rows.Count = 0 Then
Throw New InvalidOperationException("Keine Daten zur angegebenen MRN gefunden: " & mrn)
End If
' Nur Dokumente transportieren
Dim obj As New cATEZ_Greenpulse_KafkaInvoices() With {
.Documents = New List(Of cATEZ_Greenpulse_KafkaInvoices.DocumentNode)()
}
' --- Dokumente/Anhänge aus Aviso-Struktur übernehmen ---
Dim sqlHelper As New VERAG_PROG_ALLGEMEIN.SQL
' Achtung: dy_BezugsNr ggf. passend setzen/anpassen
Dim sendungsIdObj As Object = sqlHelper.getValueTxtBySql(
"SELECT dy_SendungsId FROM [tblDakosy_Zollanmeldungen] WHERE dy_BezugsNr=''",
"FMZOLL", , , Nothing)
Dim sendungsId As Integer
If sendungsIdObj IsNot Nothing AndAlso Integer.TryParse(sendungsIdObj.ToString(), sendungsId) AndAlso sendungsId > 0 Then
Dim anhListe As New List(Of cAvisoAnhaenge)
cAvisoAnhaenge.LOAD_LIST_BySendung(anhListe, sendungsId)
For Each doc In anhListe
Select Case doc.anh_Art
Case "Rechnung", "eFatura"
Dim pfad As String = VERAG_PROG_ALLGEMEIN.cDATENSERVER.GET_PDFPath_BY_DocID(doc.anh_docId)
Dim dateiBytes As Byte() = System.IO.File.ReadAllBytes(pfad)
Dim d As New cATEZ_Greenpulse_KafkaInvoices.DocumentNode With {
.Reference = doc.anh_Name,
.DocType = "invoice",
.MimeType = GuessMimeTypeFromNumber(doc.anh_Typ),
.Blob = Convert.ToBase64String(dateiBytes)
}
obj.Documents.Add(d)
End Select
Next
End If
Return obj
End Using
End Function
'---------------------------
' Helper
'---------------------------
Private Shared Function SafeStr(value As Object) As String
If value Is Nothing OrElse Convert.IsDBNull(value) Then Return ""
Return Convert.ToString(value).Trim()
End Function
Public Shared Function GuessMimeTypeFromNumber(num As Object) As String
Dim s As String = SafeStr(num).ToLowerInvariant()
If s.EndsWith(".pdf") OrElse s = "pdf" Then
Return "application/pdf"
End If
If s.EndsWith(".jpg") OrElse s.EndsWith(".jpeg") OrElse s = "jpg" OrElse s = "jpeg" Then
Return "image/jpeg"
End If
If s.EndsWith(".png") OrElse s = "png" Then
Return "image/png"
End If
Return "application/octet-stream"
End Function
End Class