298 lines
16 KiB
VB.net
298 lines
16 KiB
VB.net
Imports Newtonsoft.Json
|
|
|
|
Public Class cRelayHub
|
|
|
|
Public Class cRelayHubDocument
|
|
Public Property type As String
|
|
Public Property base64String As String
|
|
Public Property filename As String
|
|
Public Property fileType As String
|
|
End Class
|
|
|
|
Public Class cRelayHubTransaction
|
|
Public Property ioPartner As String
|
|
Public Property ioDivision3 As String
|
|
Public Property ioReference As String
|
|
End Class
|
|
|
|
Public Class cRelayHubObjectIdentification
|
|
Public Property objectName As String
|
|
Public Property objectAlias As String
|
|
Public Property declarationType As String
|
|
Public Property referenceNumberOverlay As String ' <--- NEU
|
|
Public Property username As String ' <--- NEU
|
|
End Class
|
|
|
|
Public Class cRelayHubDv1CostAllocation
|
|
Public Property costType As String
|
|
Public Property costs As Decimal
|
|
Public Property currencyCode As String
|
|
End Class
|
|
|
|
Public Class cRelayHubAgentContact
|
|
Public Property contactPersonName As String
|
|
Public Property contactPersonPhoneNumber As String
|
|
Public Property contactPersonPosition As String
|
|
Public Property contactPersonEmail As String ' <--- NEU
|
|
End Class
|
|
|
|
Public Class cRelayHubCost
|
|
Public Property costAmount As String
|
|
Public Property costCurrency As String
|
|
End Class
|
|
|
|
Public Class cRelayHubHeaderData
|
|
Public Property agentContact As cRelayHubAgentContact
|
|
Public Property declarantIsConsignee As Boolean
|
|
Public Property representationRelationshipCode As String ' <- war String
|
|
Public Property inputTaxDeduction As Boolean ' <- war String
|
|
Public Property procedureCodeRequested As String
|
|
' Entfernt: goodsStatus, costs (nicht im Schema an dieser Stelle)
|
|
Public Property transportMeansArrivalIdentity As String
|
|
Public Property transportMeansNationalityCode As String
|
|
Public Property previousAdministrativeReferenceType As String
|
|
Public Property previousAdministrativeReferenceNumber As String
|
|
Public Property destinationFederalState As String
|
|
Public Property destinationCountry As String
|
|
Public Property departureCountry As String
|
|
Public Property addressedCustomsOffice As String
|
|
Public Property dv1CostAllocation As cRelayHubDv1CostAllocation
|
|
End Class
|
|
|
|
Public Class cRelayHubAddress
|
|
Public Property addressType As String
|
|
Public Property participantEORI As String
|
|
Public Property participantSubsidiaryNumber As String
|
|
Public Property companyName As String
|
|
Public Property streetAndNumber As String
|
|
Public Property countryCode As String
|
|
Public Property postalCode As String
|
|
Public Property city As String
|
|
End Class
|
|
|
|
Public Class cRelayHubDeclaration
|
|
Public Property objectIdentification As cRelayHubObjectIdentification
|
|
Public Property headerData As cRelayHubHeaderData
|
|
Public Property addresses As List(Of cRelayHubAddress)
|
|
End Class
|
|
|
|
Public Class cRelayHubAdditionalData
|
|
Public Property transaction As cRelayHubTransaction
|
|
Public Property declaration As List(Of cRelayHubDeclaration)
|
|
End Class
|
|
|
|
Public Class cRelayHubJobOrderRequest
|
|
Public Property referenceNo As String
|
|
Public Property dispatchCountry As String
|
|
Public Property destinationCountry As String
|
|
Public Property regimeType As String
|
|
' Entfernt: customer (vom Schema abgelehnt)
|
|
Public Property documents As List(Of cRelayHubDocument)
|
|
Public Property additionalData As cRelayHubAdditionalData
|
|
|
|
' Neu: Pflichtfeld lt. Fehlermeldung
|
|
Public Property outputApplication As String ' "test" | "dakosy/sftp/vera" | "evrim/excel" | "sec/import/integration"
|
|
End Class
|
|
|
|
Public Class cRelayHubJobOrderResponse
|
|
Public Property id As String
|
|
Public Property status As String
|
|
Public Property createdAt As String
|
|
Public Property referenceNo As String
|
|
End Class
|
|
|
|
Public Class cRelayHubApiResult
|
|
Public Property Success As Boolean
|
|
Public Property StatusCode As Integer
|
|
Public Property Message As String ' Zusammenfassung
|
|
Public Property Details As String ' Volltext/Fehlermeldung
|
|
Public Property Data As cRelayHubJobOrderResponse ' Nur bei 201
|
|
End Class
|
|
|
|
Public Class cRelayHub_sendToRelayHub_JobOrderRequest
|
|
|
|
Shared API_URL As String = "https://declaranthub.singlewindow.io/api/v1-0"
|
|
|
|
' Low-level Sender: holt Access-Token aus cRelayHubToken und sendet JSON
|
|
Private Shared Function SendJobOrder(jsonPayload As String) As Chilkat.HttpResponse
|
|
Dim http As New Chilkat.Http
|
|
http.SetRequestHeader("Accept", "application/json")
|
|
|
|
' *** Token aus der separaten Token-Klasse beziehen ***
|
|
Dim token As String = cRelayHubToken.GetAccessToken()
|
|
http.AuthToken = token
|
|
'http.AuthToken = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJqdkkzQ3BfbTVTb3JpdUFmSEZkZzJWUGgxcDFNWHA3ZnpjNFhyVHpGWVc4In0.eyJleHAiOjE3NjEzMDE4NTQsImlhdCI6MTc2MTIxNTQ1NCwianRpIjoiNWY3MjdkZTUtMmQ2MS00MThkLWJhYWQtNmY5ODM0NDk2NjY2IiwiaXNzIjoiaHR0cHM6Ly9sb2dpbi5zaW5nbGV3aW5kb3cuaW8vYXV0aC9yZWFsbXMvYWdzdyIsImF1ZCI6ImFjY291bnQiLCJzdWIiOiI5OWMwOTFmMy01Mjg1LTRhNzUtODdjNC0zODJlNThlNTBmNGMiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJhZ3N3LWFkbWluIiwic2lkIjoiMzRjMDY4ZGMtNjY3My00NDk5LTgzODAtMjVkOGYyNjI1NGY4IiwiYWxsb3dlZC1vcmlnaW5zIjpbImh0dHBzOi8vc2luZ2xld2luZG93LmlvIiwiaHR0cHM6Ly9hZ3N3LnNpbmdsZXdpbmRvdy5pbyIsImh0dHA6Ly9sb2NhbGhvc3Q6MzAwMSJdLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsiZGVmYXVsdC1yb2xlcy1hZ3N3Iiwib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiJdfSwicmVzb3VyY2VfYWNjZXNzIjp7ImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoicHJvZHVjdC1jYXRhbG9nLXNjcCBwcm9maWxlIGVtYWlsIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsIm5hbWUiOiJEaHViLVByb2QgVXNlciIsInByZWZlcnJlZF91c2VybmFtZSI6ImRodWJAdmVyYWcuYWciLCJnaXZlbl9uYW1lIjoiRGh1Yi1Qcm9kIiwiZmFtaWx5X25hbWUiOiJVc2VyIiwiZW1haWwiOiJkaHViQHZlcmFnLmFnIn0.TZ8GkXrL7SSz1CEOnLB2eAAuVcYu3wlNtnAF6Y3wt0lnMGyse5tsI0YYSfGZG_Ae8zVcPqHqVT4rhDOgIPooBkq71z35ppd6b-FUaS6hSy4cMWQaidsHZr3hkID8amVQcB2vz9Yg985h3MOCSIn86d0x9i0euew3wEpF8eEHSfk_Wqf8jeJbiXAPHfy92K4Xh8IIuh-GXUTyN-NmGM94_NhcQwb4e7YMXjPPuslUsjABEfOvT7v4-AnO5B3ZczX0h0UgafmfiIyXSaL4IzYZojoMJ0CRsHdAK-j4gzXqz4lW0A9KMmHGHn01Oftt9mXfrEmCj0XGWF9xvBuYhxMUAQ"
|
|
Console.WriteLine("Using Token =: " & http.AuthToken)
|
|
Console.WriteLine("API_URL =: " & API_URL)
|
|
Return http.PostJson2(API_URL & "/job-orders/init", "application/json", jsonPayload)
|
|
End Function
|
|
|
|
' Public API: erstellt Job-Order mit 401-Retry
|
|
Public Shared Function query_declarations(request As cRelayHubJobOrderRequest) As cRelayHubApiResult
|
|
Dim result As New cRelayHubApiResult()
|
|
Try
|
|
VERAG_PROG_ALLGEMEIN.cChilkat_Helper.UnlockCilkat()
|
|
|
|
|
|
Dim sanitized = Sanitize(request)
|
|
Dim settings As New JsonSerializerSettings With {
|
|
.NullValueHandling = NullValueHandling.Ignore,
|
|
.ContractResolver = New Newtonsoft.Json.Serialization.DefaultContractResolver With {
|
|
.NamingStrategy = New Newtonsoft.Json.Serialization.CamelCaseNamingStrategy()
|
|
}
|
|
}
|
|
Dim jsonPayload As String = JsonConvert.SerializeObject(sanitized, settings)
|
|
Console.WriteLine("JSON → " & jsonPayload)
|
|
|
|
|
|
'Dim jsonPayload As String = JsonConvert.SerializeObject(request)
|
|
|
|
|
|
|
|
' 1. Versuch
|
|
Dim response As Chilkat.HttpResponse = SendJobOrder(jsonPayload)
|
|
If response Is Nothing Then
|
|
Return New cRelayHubApiResult With {
|
|
.Success = False, .StatusCode = 0, .Message = "Verbindungsfehler",
|
|
.Details = "Keine Antwort erhalten."
|
|
}
|
|
End If
|
|
|
|
'' 401 → Token-Cache invalidieren und genau 1x erneut probieren
|
|
'If response.StatusCode = 401 Then
|
|
' ' WICHTIG:
|
|
' ' Diese Methode sollte in cRelayHubToken als Public verfügbar sein:
|
|
' ' Public Shared Sub ResetTokenCache() : ClearToken() : End Sub
|
|
' ' → Falls noch nicht vorhanden, bitte dort ergänzen.
|
|
' Try
|
|
' cRelayHubToken.ResetTokenCache()
|
|
' Catch
|
|
' ' Falls die Methode (noch) nicht existiert, kann man als Fallback
|
|
' ' hier eine kurze Wartezeit einbauen und anschließend erneut GetValidAccessToken() aufrufen.
|
|
' ' Threading.Thread.Sleep(100)
|
|
' End Try
|
|
|
|
' ' Retry
|
|
' response = SendJobOrder(jsonPayload)
|
|
' If response Is Nothing Then
|
|
' Return New cRelayHubApiResult With {
|
|
' .Success = False, .StatusCode = 0, .Message = "Verbindungsfehler (nach Refresh)",
|
|
' .Details = "Keine Antwort erhalten."
|
|
' }
|
|
' End If
|
|
'End If
|
|
|
|
' Auswertung
|
|
result.StatusCode = response.StatusCode
|
|
Console.WriteLine("result.StatusCode → " & result.StatusCode)
|
|
Select Case response.StatusCode
|
|
Case 201
|
|
Try
|
|
Dim jobResponse As cRelayHubJobOrderResponse =
|
|
JsonConvert.DeserializeObject(Of cRelayHubJobOrderResponse)(response.BodyStr)
|
|
result.Success = True
|
|
result.Message = "Job Order erfolgreich erstellt"
|
|
result.Data = jobResponse
|
|
result.Details = $"ID: {jobResponse.id}, Referenz: {jobResponse.referenceNo}"
|
|
Catch ex As Exception
|
|
result.Success = False
|
|
result.StatusCode = 999
|
|
result.Message = "Antwort konnte nicht gelesen werden"
|
|
result.Details = ex.Message
|
|
End Try
|
|
|
|
Case 400 To 499
|
|
result.Success = False
|
|
result.Message = "Client-Fehler"
|
|
result.Details = response.BodyStr
|
|
|
|
Case 500 To 599
|
|
result.Success = False
|
|
result.Message = "Server-Fehler"
|
|
result.Details = response.BodyStr
|
|
|
|
Case Else
|
|
result.Success = False
|
|
result.Message = $"Unbekannter Fehler (Status {response.StatusCode})"
|
|
result.Details = response.BodyStr
|
|
End Select
|
|
|
|
Return result
|
|
|
|
Catch ex As Exception
|
|
VERAG_PROG_ALLGEMEIN.cErrorHandler.ERR(ex.Message, ex.StackTrace, System.Reflection.MethodInfo.GetCurrentMethod.Name)
|
|
Return New cRelayHubApiResult With {.Success = False, .StatusCode = 0, .Message = "Exception", .Details = ex.ToString()}
|
|
End Try
|
|
End Function
|
|
|
|
Private Shared Function Sanitize(req As cRelayHub.cRelayHubJobOrderRequest) As cRelayHub.cRelayHubJobOrderRequest
|
|
req.outputApplication = If(req.outputApplication, "").Trim()
|
|
req.dispatchCountry = If(req.dispatchCountry, "").Trim().ToUpperInvariant()
|
|
req.destinationCountry = If(req.destinationCountry, "").Trim().ToUpperInvariant()
|
|
|
|
' lokale Fail-fast Checks
|
|
If req.dispatchCountry.Length <> 2 Then Throw New ApplicationException("dispatchCountry ISO-2 erforderlich.")
|
|
If req.destinationCountry.Length <> 2 Then Throw New ApplicationException("destinationCountry ISO-2 erforderlich.")
|
|
|
|
|
|
Return req
|
|
End Function
|
|
|
|
' Beispielfall
|
|
Function CreateSampleJobOrderRequest() As cRelayHubJobOrderRequest
|
|
Dim req As New cRelayHubJobOrderRequest With {
|
|
.referenceNo = "1001K",
|
|
.dispatchCountry = "TR", ' ISO-2
|
|
.destinationCountry = "DE", ' ISO-2 (nicht "EN")
|
|
.regimeType = "IMPORT", ' "IMPORT" | "EXPORT"
|
|
.outputApplication = "test", ' Pflichtfeld lt. Validator
|
|
.documents = New List(Of cRelayHubDocument) From {
|
|
New cRelayHubDocument With {.type = "base64", .base64String = "SGVsbG8sIHRoaXMgaXMgYSBzYW1wbGUgYmFzZTY0IHN0cmluZy4=", .filename = "test.txt", .fileType = "invoice"},
|
|
New cRelayHubDocument With {.type = "base64", .base64String = "SGVsbG8sIHRoaXMgaXMgYSBzYW1wbGUgYmFzZTY0IHN0cmluZy4=", .filename = "test2.txt", .fileType = "atr"},
|
|
New cRelayHubDocument With {.type = "base64", .base64String = "SGVsbG8sIHRoaXMgaXMgYSBzYW1wbGUgYmFzZTY0IHN0cmluZy4=", .filename = "test3.txt", .fileType = "cmr"}
|
|
},
|
|
.additionalData = New cRelayHubAdditionalData With {
|
|
.transaction = New cRelayHubTransaction With {
|
|
.ioPartner = "VERA",
|
|
.ioDivision3 = "SUB",
|
|
.ioReference = "4803/25001763_1301250935SS/samimx"
|
|
},
|
|
.declaration = New List(Of cRelayHubDeclaration) From {
|
|
New cRelayHubDeclaration With {
|
|
.objectIdentification = New cRelayHubObjectIdentification With {
|
|
.objectName = "4803/25001763",
|
|
.objectAlias = "1349846",
|
|
.declarationType = "EZA-D"
|
|
},
|
|
.headerData = New cRelayHubHeaderData With {
|
|
.agentContact = New cRelayHubAgentContact With {
|
|
.contactPersonName = "AMANN",
|
|
.contactPersonPhoneNumber = "+49 123 456 789",
|
|
.contactPersonPosition = "Manager",
|
|
.contactPersonEmail = "a@example.com"
|
|
},
|
|
.declarantIsConsignee = True,
|
|
.representationRelationshipCode = 1, ' Integer
|
|
.inputTaxDeduction = True, ' Boolean
|
|
.procedureCodeRequested = "42", ' goodsStatus/costs entfernt
|
|
.transportMeansArrivalIdentity = "PB1552EC",
|
|
.transportMeansNationalityCode = "BG",
|
|
.previousAdministrativeReferenceType = "T1",
|
|
.previousAdministrativeReferenceNumber = "25TR160100001472M0",
|
|
.destinationFederalState = "07",
|
|
.destinationCountry = "DE",
|
|
.departureCountry = "TR"
|
|
},
|
|
.addresses = New List(Of cRelayHubAddress) From {
|
|
New cRelayHubAddress With {.addressType = "CZ", .participantEORI = "EORI12345", .participantSubsidiaryNumber = "001", .companyName = "SISECAM DIS TIC.A.S.", .streetAndNumber = "D-100 KARAYOLU CD.YAYLA MH.NO.70/C", .countryCode = "TR", .postalCode = "34949", .city = "TUZLA ISTANBUL"},
|
|
New cRelayHubAddress With {.addressType = "CN", .participantEORI = "EORI67890", .participantSubsidiaryNumber = "002", .companyName = "POLYNT COMPOSITES GERMANY GMBH", .streetAndNumber = "KIESELSTRASSE 2", .countryCode = "DE", .postalCode = "56357", .city = "MIEHLEN"}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Return req
|
|
End Function
|
|
|
|
End Class
|
|
End Class |