Kopf-Sammelabrechnung

This commit is contained in:
2025-08-28 13:20:16 +02:00
parent 0100b3ed89
commit c126b4a064
11 changed files with 788 additions and 95 deletions

View File

@@ -0,0 +1,311 @@

' Requires NuGet:
' - Confluent.Kafka
' - Newtonsoft.Json
' Target framework: .NET Framework 4.8 oder .NET 6/8 (passt beides)
Imports System.Threading
Imports System.Threading.Tasks
Imports Confluent.Kafka
Imports Newtonsoft.Json
Namespace Verag.Udm
''' <summary>
''' UDM-Record inkl. Beispielbefüllung und Kafka-Producer.
''' Datenschema gemäß bereitgestellter JSON-Struktur. :contentReference[oaicite:1]{index=1}
''' </summary>
Public Class cATEZ_Greenpulse_KafkaDecs
'========================
'== Kafka: Konfiguration (Klassenebene)
'========================
Public Shared BootstrapServers As String = "192.168.85.250:8888" 'http://192.168.85.250:8888
Public Shared TopicName As String = "greenpulse.declarationdata.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
'========================
'== Datenobjekte lt. UDM-Schema
'========================
<JsonProperty("declaration")>
Public Property Declaration As DeclarationNode
<JsonProperty("parties")>
Public Property Parties As PartiesNode
<JsonProperty("commercial")>
Public Property Commercial As CommercialNode
<JsonProperty("exporterDetails")>
Public Property ExporterDetails As ExporterDetailsNode
<JsonProperty("importerDetails")>
Public Property ImporterDetails As ImporterDetailsNode
'--- declaration ---
Public Class DeclarationNode
<JsonProperty("declarationsourceId")>
Public Property DeclarationSourceId As String
<JsonProperty("declarationNo")>
Public Property DeclarationNo As String
<JsonProperty("declarationDate")>
Public Property DeclarationDate As String
<JsonProperty("requestedProcedure")>
Public Property RequestedProcedure As String
<JsonProperty("previousProcedure")>
Public Property PreviousProcedure As String
<JsonProperty("goods")>
Public Property Goods As List(Of GoodItem)
End Class
Public Class GoodItem
<JsonProperty("commodityCode")>
Public Property CommodityCode As String
<JsonProperty("originCountryCode")>
Public Property OriginCountryCode As String
<JsonProperty("netMass")>
Public Property NetMass As String
<JsonProperty("typeOfMeasurementUnit")>
Public Property TypeOfMeasurementUnit As String
<JsonProperty("specialProcedures")>
Public Property SpecialProcedures As SpecialProceduresNode
End Class
Public Class SpecialProceduresNode
<JsonProperty("memberStateAutharization")>
Public Property MemberStateAutharization As String
<JsonProperty("dischargeBillWaiver")>
Public Property DischargeBillWaiver As String
<JsonProperty("authorisation")>
Public Property Authorisation As String
<JsonProperty("startTime")>
Public Property StartTime As String
<JsonProperty("endTime")>
Public Property EndTime As String
<JsonProperty("deadline")>
Public Property Deadline As String
End Class
'--- parties ---
Public Class PartiesNode
<JsonProperty("importerIdentificationNumber")>
Public Property ImporterIdentificationNumber As String
<JsonProperty("exporterIdentificationNumber")>
Public Property ExporterIdentificationNumber As String
<JsonProperty("reportingDeclarantEORINumber")>
Public Property ReportingDeclarantEORINumber As String
<JsonProperty("typeOfRepresentation")>
Public Property TypeOfRepresentation As String
End Class
'--- commercial ---
Public Class CommercialNode
<JsonProperty("invoiceNumbers")>
Public Property InvoiceNumbers As String
<JsonProperty("invoiceDate")>
Public Property InvoiceDate As String
End Class
'--- exporterDetails ---
Public Class ExporterDetailsNode
<JsonProperty("exporterTitle")>
Public Property ExporterTitle As String
<JsonProperty("exporterEmail")>
Public Property ExporterEmail As String
<JsonProperty("exporterPhone")>
Public Property ExporterPhone As String
End Class
'--- importerDetails ---
Public Class ImporterDetailsNode
<JsonProperty("importerTitle")>
Public Property ImporterTitle As String
<JsonProperty("importerEmail")>
Public Property ImporterEmail As String
<JsonProperty("importerPhone")>
Public Property ImporterPhone As String
<JsonProperty("importerCountryCodeOrMemberState")>
Public Property ImporterCountryCodeOrMemberState As String
<JsonProperty("importerSubdivision")>
Public Property ImporterSubdivision As String
<JsonProperty("importerCity")>
Public Property ImporterCity As String
<JsonProperty("importerStreet")>
Public Property ImporterStreet As String
<JsonProperty("importerStreetAdditional")>
Public Property ImporterStreetAdditional As String
<JsonProperty("importerAddressNumber")>
Public Property ImporterAddressNumber As String
<JsonProperty("importerPostCode")>
Public Property ImporterPostCode As String
<JsonProperty("importerPoBox")>
Public Property ImporterPoBox As String
<JsonProperty("importerCoordinateLongitudeX")>
Public Property ImporterCoordinateLongitudeX As String
<JsonProperty("importerCoordinateLatitudeY")>
Public Property ImporterCoordinateLatitudeY As String
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_KafkaDecs
Return New cATEZ_Greenpulse_KafkaDecs() With {
.Declaration = New DeclarationNode() With {
.DeclarationSourceId = "xx123",
.DeclarationNo = "24AT000000INL0JD01",
.DeclarationDate = "2024-11-22",
.RequestedProcedure = "40",
.PreviousProcedure = "00",
.Goods = New List(Of GoodItem) From {
New GoodItem() With {
.CommodityCode = "72072710",
.OriginCountryCode = "TR",
.NetMass = "150",
.TypeOfMeasurementUnit = "Tonnes",
.SpecialProcedures = New SpecialProceduresNode() With {
.MemberStateAutharization = "AT",
.DischargeBillWaiver = "01",
.Authorisation = "Name of authorisation",
.StartTime = "2024-10-22",
.EndTime = "2024-11-22",
.Deadline = "2024-12-22"
}
}
}
},
.Parties = New PartiesNode() With {
.ImporterIdentificationNumber = "ATEOS1000000001",
.ExporterIdentificationNumber = "FR123456789000",
.ReportingDeclarantEORINumber = "ATEOS1000000002",
.TypeOfRepresentation = "01"
},
.Commercial = New CommercialNode() With {
.InvoiceNumbers = "123456789",
.InvoiceDate = "2024-11-22"
},
.ExporterDetails = New ExporterDetailsNode() With {
.ExporterTitle = "",
.ExporterEmail = "",
.ExporterPhone = ""
},
.ImporterDetails = New ImporterDetailsNode() With {
.ImporterTitle = "Importer name",
.ImporterEmail = "info@test.com",
.ImporterPhone = "123456789",
.ImporterCountryCodeOrMemberState = "DE",
.ImporterSubdivision = "Sub-division",
.ImporterCity = "City name",
.ImporterStreet = "Street Name",
.ImporterStreetAdditional = "Street additonal name",
.ImporterAddressNumber = "10",
.ImporterPostCode = "DCL-123",
.ImporterPoBox = "PO DCL-123",
.ImporterCoordinateLongitudeX = "41.0091982",
.ImporterCoordinateLatitudeY = "28.9662187"
}
}
End Function
'========================
'== Unique-Key-Ermittlung (leer gelassen später definieren)
'========================
Public Shared Function GetUniqueKey(ByVal record As cATEZ_Greenpulse_KafkaDecs) As String
' TODO: Hier Logik zur Schlüsselbildung implementieren (z.B. declarationsourceId + declarationNo)
Return ""
End Function
'========================
'== Kafka: Insert/Update (per Message-Key)
'========================
Public Shared Async Function InsertOrUpdateToKafkaAsync(ByVal record As cATEZ_Greenpulse_KafkaDecs,
Optional ct As CancellationToken = Nothing) As Task(Of DeliveryResult(Of String, String))
Dim cfg As New ProducerConfig() With {
.BootstrapServers = BootstrapServers,
.Acks = Acks.All,
.EnableIdempotence = True,
.MessageTimeoutMs = 30000
}
If UseSasl Then
cfg.SecurityProtocol = SecurityProtocolSetting
cfg.SaslMechanism = SaslMechanismSetting
cfg.SaslUsername = SaslUsername
cfg.SaslPassword = SaslPassword
' Optional: cfg.SslCaLocation = "path\to\ca.pem"
End If
Dim key As String = GetUniqueKey(record) ' bleibt leer bis du definierst
Dim payload As String = record.ToJson(False)
Using producer As IProducer(Of String, String) = New ProducerBuilder(Of String, String)(cfg).Build()
Dim msg As New Message(Of String, String) With {
.key = key,
.Value = payload
}
Dim result = Await producer.ProduceAsync(TopicName, msg, ct)
' Flush ist bei Await ProduceAsync nicht zwingend nötig, hier dennoch zur Sicherheit:
producer.Flush(TimeSpan.FromSeconds(5))
Return result
End Using
End Function
'========================
'== Sync-Wrapper (falls bevorzugt)
'========================
Public Shared Function InsertOrUpdateToKafka(ByVal record As cATEZ_Greenpulse_KafkaDecs) As DeliveryResult(Of String, String)
Return InsertOrUpdateToKafkaAsync(record).GetAwaiter().GetResult()
End Function
End Class
End Namespace