525 lines
21 KiB
VB.net
525 lines
21 KiB
VB.net
Imports Chilkat
|
||
Imports Newtonsoft.Json
|
||
Imports Newtonsoft.Json.Linq
|
||
Public Class cModalTransIMPORT
|
||
' VB.NET Klasse zur vollständigen Abbildung der Declaration Data laut Modaltrans API
|
||
Public Class cMT_IMP_CustomsDeclarationRequest
|
||
Public Property auto_send As Boolean?
|
||
Public Property badge_code As String
|
||
Public Property service_code As String
|
||
Public Property doc_type As String
|
||
Public Property declaration_type As String
|
||
Public Property commercial_ref As String
|
||
Public Property ducr As String
|
||
Public Property mucr As String
|
||
Public Property ducr_part As String
|
||
Public Property declarant_eori As String
|
||
Public Property declarant_name As String
|
||
Public Property declarant_address As String
|
||
Public Property declarant_city_name As String
|
||
Public Property declarant_country_id As String
|
||
Public Property declarant_postcode As String
|
||
Public Property declarant_rep As String
|
||
Public Property export_country_id As String
|
||
Public Property consignor_eori As String
|
||
Public Property consignor_name As String
|
||
Public Property consignor_address As String
|
||
Public Property consignor_city_name As String
|
||
Public Property consignor_country_id As String
|
||
Public Property consignor_postcode As String
|
||
Public Property multiple_consignor As Boolean?
|
||
Public Property import_country_id As String
|
||
Public Property consignee_eori As String
|
||
Public Property consignee_name As String
|
||
Public Property consignee_address As String
|
||
Public Property consignee_city_name As String
|
||
Public Property consignee_country_id As String
|
||
Public Property consignee_postcode As String
|
||
Public Property multiple_consignee As Boolean?
|
||
Public Property invoice_amount As Decimal?
|
||
Public Property invoice_curr As String
|
||
Public Property goods_location As String
|
||
Public Property border_transport_type As String
|
||
Public Property border_vehicle_coun As String
|
||
Public Property border_vehicle_code As String
|
||
Public Property inland_transport_type As String
|
||
Public Property container_no As String
|
||
Public Property gvms_interested As Boolean?
|
||
Public Property freight_amount As Decimal?
|
||
Public Property freight_curr As String
|
||
Public Property payment_method As String
|
||
Public Property carrier_eori As String
|
||
Public Property carrier_name As String
|
||
Public Property carrier_address As String
|
||
Public Property carrier_city_name As String
|
||
Public Property carrier_country_id As String
|
||
Public Property carrier_postcode As String
|
||
Public Property total_packages As Integer
|
||
Public Property nature_of_transaction As String
|
||
Public Property premises_code As String
|
||
Public Property first_dan_no As String
|
||
Public Property second_dan_no As String
|
||
Public Property insurance_amount As Decimal?
|
||
Public Property other_amounts As Decimal?
|
||
Public Property airport_code As String
|
||
Public Property apportment_indicator As String
|
||
Public Property total_gross_weight As Decimal?
|
||
Public Property total_net_weight As Decimal?
|
||
Public Property airfreight_cost As Decimal?
|
||
Public Property insurance_curr As String
|
||
Public Property other_amounts_curr As String
|
||
Public Property vat_adjustment As Decimal?
|
||
Public Property vat_adjustment_curr As String
|
||
Public Property discount_amount As Decimal?
|
||
Public Property discount_curr As String
|
||
Public Property discount_rate As Decimal?
|
||
Public Property warehouse_type As String
|
||
Public Property incoterm As String
|
||
Public Property incoterm_location As String
|
||
Public Property trader_ref As String
|
||
Public Property arrival_transport_type As String
|
||
Public Property guarantee_code As String
|
||
Public Property guarantee_reference As String
|
||
Public Property evrim_xml As String
|
||
Public Property goods_attributes As List(Of cMT_IMP_GoodsItem)
|
||
Public Property parties_attributes As List(Of cMT_IMP_PartyAttribute)
|
||
Public Property trader_additions_attributes As List(Of cMT_IMP_TraderAddition)
|
||
End Class
|
||
|
||
Public Class cMT_IMP_GoodsItem
|
||
Public Property commodity As String
|
||
Public Property consignee_name As String
|
||
Public Property sender_name As String
|
||
Public Property packs_attributes As List(Of cMT_IMP_PackAttribute)
|
||
End Class
|
||
|
||
Public Class cMT_IMP_PackAttribute
|
||
Public Property pack_type As String
|
||
Public Property notes As String
|
||
End Class
|
||
|
||
Public Class cMT_IMP_PartyAttribute
|
||
Public Property name As String
|
||
Public Property eori As String
|
||
Public Property role As String
|
||
End Class
|
||
|
||
Public Class cMT_IMP_TraderAddition
|
||
Public Property field As String
|
||
Public Property value As String
|
||
Public Property type As String
|
||
Public Property description As String
|
||
End Class
|
||
|
||
|
||
Public Class cMT_IMP_CustomsDeclarationResponse
|
||
Public Property status As String
|
||
Public Property declarationId As String
|
||
Public Property message As String
|
||
|
||
' Optional: wenn die API weitere Felder liefert
|
||
Public Property referenceNumber As String
|
||
Public Property createdAt As DateTime?
|
||
Public Property updatedAt As DateTime?
|
||
Public Property declaration_data As cMT_IMP_CustomsDeclarationRequest
|
||
End Class
|
||
|
||
|
||
Public Class cModaltransApiClient_IMPORT
|
||
|
||
|
||
Private baseUrl As String = "https://app.modaltrans.com"
|
||
Private http As New Chilkat.Http()
|
||
Private authToken As String
|
||
|
||
|
||
|
||
|
||
Public Sub New()
|
||
VERAG_PROG_ALLGEMEIN.cChilkat_Helper.UnlockCilkat()
|
||
|
||
http.SetRequestHeader("Content-Type", "application/json")
|
||
End Sub
|
||
|
||
|
||
|
||
' 📤 Senden der Zollanmeldung
|
||
Public Function SendDeclaration(request As cMT_IMP_CustomsDeclarationRequest) As cMT_IMP_CustomsDeclarationResponse
|
||
Dim result As New cMT_IMP_CustomsDeclarationResponse()
|
||
|
||
If Not cModalTransBase.Authenticate(authToken) Then
|
||
result.status = "Error"
|
||
result.message = "❌ Authentifizierung fehlgeschlagen."
|
||
Console.WriteLine(result.message)
|
||
Return result
|
||
End If
|
||
http.SetRequestHeader("Authorization", "Bearer " & authToken)
|
||
|
||
Dim jsonPayload As String = JsonConvert.SerializeObject(New With {.declaration_data = request})
|
||
Dim url As String = baseUrl & "/api/v1/customs_declarations"
|
||
|
||
Dim resp As Chilkat.HttpResponse = http.PostJson(url, jsonPayload)
|
||
|
||
If resp Is Nothing Then
|
||
result.status = "Error"
|
||
result.message = "❌ Fehler beim Senden: " & http.LastErrorText
|
||
Console.WriteLine(result.message)
|
||
Return result
|
||
End If
|
||
|
||
Select Case resp.StatusCode
|
||
Case 201 ' Created
|
||
Try
|
||
result = JsonConvert.DeserializeObject(Of cMT_IMP_CustomsDeclarationResponse)(resp.BodyStr)
|
||
result.status = "Success"
|
||
Console.WriteLine("✅ Zollanmeldung erfolgreich erstellt.")
|
||
Catch ex As Exception
|
||
result.status = "Error"
|
||
result.message = "❌ Fehler beim Parsen der Erfolgsantwort: " & ex.Message
|
||
Console.WriteLine(result.message)
|
||
End Try
|
||
|
||
Case 400
|
||
result.status = "Bad Request"
|
||
result.message = resp.BodyStr
|
||
Console.WriteLine("⚠️ Ungültige Anfrage (400): " & result.message)
|
||
|
||
Case 401
|
||
result.status = "Unauthorized"
|
||
result.message = "❌ Nicht autorisiert (401)"
|
||
Console.WriteLine(result.message)
|
||
|
||
Case 422
|
||
result.status = "Validation Error"
|
||
result.message = resp.BodyStr
|
||
Console.WriteLine("⚠️ Validierungsfehler (422): " & result.message)
|
||
|
||
Case Else
|
||
result.status = "Error"
|
||
result.message = $"❌ Unerwarteter Fehler: {resp.StatusCode}" & vbCrLf & resp.BodyStr
|
||
Console.WriteLine(result.message)
|
||
End Select
|
||
|
||
Return result
|
||
End Function
|
||
|
||
' 📥 Zollanmeldung abrufen
|
||
Public Function GetDeclaration(declarationId As String) As cMT_IMP_CustomsDeclarationRequest
|
||
If Not cModalTransBase.Authenticate(authToken) Then
|
||
Console.WriteLine("❌ Authentifizierung fehlgeschlagen.")
|
||
Return Nothing
|
||
End If
|
||
http.SetRequestHeader("Authorization", "Bearer " & authToken)
|
||
|
||
Dim url As String = $"{baseUrl}/api/v1/customs_declarations/{declarationId}"
|
||
Dim responseStr As String = http.QuickGetStr(url)
|
||
|
||
If Not http.LastMethodSuccess Then
|
||
Console.WriteLine("❌ Fehler beim Abrufen: " & http.LastErrorText)
|
||
Return Nothing
|
||
End If
|
||
|
||
Dim statusCode As Integer = http.LastStatus
|
||
Select Case statusCode
|
||
Case 200
|
||
Try
|
||
Dim json = JsonConvert.DeserializeObject(Of JObject)(responseStr)
|
||
Dim data = json.SelectToken("declaration_data")
|
||
Dim result = data.ToObject(Of cMT_IMP_CustomsDeclarationRequest)()
|
||
Console.WriteLine("✅ Zollanmeldung erfolgreich abgerufen.")
|
||
Return result
|
||
Catch ex As Exception
|
||
Console.WriteLine("❌ Fehler beim Parsen: " & ex.Message)
|
||
End Try
|
||
Case 404
|
||
Console.WriteLine("⚠️ Zollanmeldung nicht gefunden (404).")
|
||
Case 401
|
||
Console.WriteLine("❌ Nicht autorisiert (401).")
|
||
Case Else
|
||
Console.WriteLine($"❌ Unerwarteter Fehler: {statusCode}")
|
||
Console.WriteLine(responseStr)
|
||
End Select
|
||
|
||
Return Nothing
|
||
End Function
|
||
|
||
Public Function ListDeclarationsFromDate(fromDate As DateTime, Optional page As Integer = 1) As List(Of cMT_IMP_CustomsDeclarationResponse)
|
||
Dim declarations As New List(Of cMT_IMP_CustomsDeclarationResponse)()
|
||
|
||
If Not cModalTransBase.Authenticate(authToken) Then
|
||
Throw New Exception("Authentifizierung fehlgeschlagen")
|
||
End If
|
||
http.SetRequestHeader("Authorization", "Bearer " & authToken)
|
||
|
||
|
||
Dim url As String = $"{baseUrl}/api/v1/customs_declarations?from_date={fromDate:yyyy-MM-dd}&page={page}"
|
||
|
||
Dim responseStr As String = http.QuickGetStr(url)
|
||
|
||
If http.LastMethodSuccess Then
|
||
Try
|
||
' Optional: falls die Antwort als { data: [ ... ] } zurückkommt
|
||
Dim json = JsonConvert.DeserializeObject(Of JObject)(responseStr)
|
||
Dim dataArray = json.SelectToken("data")
|
||
If dataArray IsNot Nothing Then
|
||
declarations = dataArray.ToObject(Of List(Of cMT_IMP_CustomsDeclarationResponse))()
|
||
Else
|
||
' Falls direkt eine Liste zurückkommt
|
||
declarations = JsonConvert.DeserializeObject(Of List(Of cMT_IMP_CustomsDeclarationResponse))(responseStr)
|
||
End If
|
||
Catch ex As Exception
|
||
Throw New Exception("Fehler beim Parsen der Antwort: " & ex.Message)
|
||
End Try
|
||
Else
|
||
Throw New Exception("Fehler beim Abruf: " & http.LastErrorText)
|
||
End If
|
||
|
||
|
||
Return declarations
|
||
End Function
|
||
|
||
End Class
|
||
|
||
|
||
|
||
|
||
|
||
'--------------------------------------------------------------------------------------------------
|
||
|
||
|
||
Public Shared Sub CreateAndSendMinimalImportDeclaration(LRN)
|
||
' Objekt mit allen notwendigen Pflichtfeldern befüllen
|
||
Dim importRequest As New cMT_IMP_CustomsDeclarationRequest With {
|
||
.doc_type = "import",
|
||
.declaration_type = "IMA",
|
||
.declarant_eori = "GB123456789000",
|
||
.declarant_name = "Demo Importer Ltd.",
|
||
.export_country_id = "TR",
|
||
.consignor_name = "Nimbo Teknoloji Ltd.",
|
||
.consignor_address = "Techno Street 12",
|
||
.consignor_city_name = "Istanbul",
|
||
.consignor_country_id = "TR",
|
||
.consignor_postcode = "34000",
|
||
.import_country_id = "GB",
|
||
.consignee_name = "Demo Importer Ltd.",
|
||
.consignee_address = "Import Road 34",
|
||
.consignee_city_name = "London",
|
||
.consignee_country_id = "GB",
|
||
.consignee_postcode = "W1A 1AA",
|
||
.goods_location = "GBFXT",
|
||
.border_transport_type = "3", ' z. B. Straße
|
||
.total_packages = 5,
|
||
.commercial_ref = LRN, ' .trader_ref = LRN,
|
||
.ducr = LRN
|
||
}
|
||
|
||
' API-Client erstellen (mit Benutzer & Passwort in der Klasse eingebaut)
|
||
Dim client As New cModaltransApiClient_IMPORT()
|
||
|
||
' Senden und Ergebnis anzeigen
|
||
Dim response As cMT_IMP_CustomsDeclarationResponse = client.SendDeclaration(importRequest)
|
||
|
||
If response IsNot Nothing Then
|
||
Console.WriteLine("Status: " & response.status)
|
||
Console.WriteLine("Message: " & response.message)
|
||
Console.WriteLine("Declaration ID: " & response.declarationId)
|
||
Else
|
||
Console.WriteLine("Keine Antwort erhalten.")
|
||
End If
|
||
End Sub
|
||
|
||
|
||
Public Shared Function ceateAndSend_IMP_FromSENDUNG(LRN As String, SND As cSendungen) As Boolean
|
||
If SND.tblSnd_AvisoID <= 0 Then Return False
|
||
Dim AVISO As cAviso = (New cAvisoDAL).LesenAviso(SND.tblSnd_AvisoID, "")
|
||
Return ceateAndSend_IMP_FromSENDUNG(LRN, SND, AVISO)
|
||
End Function
|
||
|
||
|
||
Public Shared Function ceateAndSend_IMP_FromSENDUNG(LRN As String, SND As cSendungen, AVISO As cAviso) As Boolean
|
||
' Objekt mit allen notwendigen Pflichtfeldern befüllen
|
||
Dim MT_IMP As New cMT_IMP_CustomsDeclarationRequest With {
|
||
.doc_type = "import",
|
||
.declaration_type = "IMD", ' IMA-_> Arrived
|
||
.declarant_eori = VERAG_PROG_ALLGEMEIN.cAllgemein.UK_EORI_LTD,
|
||
.declarant_name = "VERAG-UNISPED Ltd",
|
||
.declarant_rep = "2",
|
||
.goods_location = "GBAUDEUDEUDEU",
|
||
.import_country_id = "GB",
|
||
.total_packages = 5,
|
||
.nature_of_transaction = "11", ' Kaufgeschäft 11 Outright purchase/sale
|
||
.commercial_ref = LRN, ' .trader_ref = LRN,
|
||
.ducr = LRN
|
||
}
|
||
|
||
Dim ioReference = LRN & Now.ToString("ddMMyyyy_HHmmss")
|
||
|
||
|
||
Select Case If(AVISO.Transportmittelart, "")
|
||
Case "CONTAINER"
|
||
MT_IMP.border_transport_type = "1" ' z. B. Ocean
|
||
MT_IMP.arrival_transport_type = "10"
|
||
Case Else
|
||
MT_IMP.border_transport_type = "6" ' z. B. 3 Straße '?6 RORO??
|
||
MT_IMP.arrival_transport_type = "30"
|
||
|
||
End Select
|
||
|
||
MT_IMP.inland_transport_type = "3" ' z. B. Straße '?6 RORO??
|
||
MT_IMP.border_vehicle_code = AVISO.LKW_Nr
|
||
MT_IMP.border_vehicle_coun = AVISO.LKW_Nationalitaet
|
||
|
||
|
||
|
||
If SND.tblSnd_EmpfaengerKdNr > 0 Then
|
||
Dim AD As New cAdressen(SND.tblSnd_EmpfaengerKdNr)
|
||
Dim KD As New cKunde(SND.tblSnd_EmpfaengerKdNr)
|
||
Dim CN As New VERAG_PROG_ALLGEMEIN.cRelayHub.cRelayHubAddress
|
||
CN.addressType = "CN"
|
||
MT_IMP.consignee_eori = If(KD.EORITIN, "")
|
||
MT_IMP.consignee_name = AD.Name_1
|
||
MT_IMP.consignee_address = AD.Straße
|
||
MT_IMP.consignee_postcode = AD.PLZ
|
||
MT_IMP.consignee_city_name = AD.Ort
|
||
MT_IMP.consignee_country_id = cProgramFunctions.getISO2Land(AD.LandKz)
|
||
|
||
End If
|
||
|
||
If SND.tblSnd_AbsenderKdNr > 0 Then
|
||
Dim AD As New cAdressen(SND.tblSnd_AbsenderKdNr)
|
||
Dim KD As New cKunde(SND.tblSnd_AbsenderKdNr)
|
||
Dim CZ As New VERAG_PROG_ALLGEMEIN.cRelayHub.cRelayHubAddress
|
||
|
||
MT_IMP.consignor_eori = If(KD.EORITIN, "")
|
||
MT_IMP.consignor_name = AD.Name_1
|
||
MT_IMP.consignor_address = AD.Straße
|
||
MT_IMP.consignor_postcode = AD.PLZ
|
||
MT_IMP.consignor_city_name = AD.Ort
|
||
MT_IMP.consignor_country_id = cProgramFunctions.getISO2Land(AD.LandKz)
|
||
MT_IMP.export_country_id = MT_IMP.consignor_country_id
|
||
End If
|
||
|
||
|
||
|
||
' API-Client erstellen (mit Benutzer & Passwort in der Klasse eingebaut)
|
||
Dim client As New cModaltransApiClient_IMPORT()
|
||
|
||
' Senden und Ergebnis anzeigen
|
||
Dim response As cMT_IMP_CustomsDeclarationResponse = client.SendDeclaration(MT_IMP)
|
||
|
||
If response IsNot Nothing Then
|
||
Console.WriteLine("Status: " & response.status)
|
||
Console.WriteLine("Message: " & response.message)
|
||
Console.WriteLine("Declaration ID: " & response.declarationId)
|
||
' Console.WriteLine("Declaration DUCR: " & response.declaration_data.ducr)
|
||
|
||
If response.status = "Success" Then
|
||
MsgBox(response.message)
|
||
Else
|
||
MsgBox(response.message)
|
||
Return False
|
||
End If
|
||
|
||
Return True
|
||
Else
|
||
MsgBox("Keine Antwort erhalten.")
|
||
Console.WriteLine("Keine Antwort erhalten.")
|
||
End If
|
||
Return False
|
||
|
||
End Function
|
||
|
||
|
||
|
||
|
||
|
||
|
||
Public Shared Function ceateAndSend_EXP_FromSENDUNG(LRN As String, SND As cSendungen) As Boolean
|
||
If SND.tblSnd_AvisoID <= 0 Then Return False
|
||
Dim AVISO As cAviso = (New cAvisoDAL).LesenAviso(SND.tblSnd_AvisoID, "")
|
||
Return ceateAndSend_EXP_FromSENDUNG(LRN, SND, AVISO)
|
||
End Function
|
||
|
||
|
||
Public Shared Function ceateAndSend_EXP_FromSENDUNG(LRN As String, SND As cSendungen, AVISO As cAviso) As Boolean
|
||
' Objekt mit allen notwendigen Pflichtfeldern befüllen
|
||
Dim MT_IMP As New cMT_IMP_CustomsDeclarationRequest With {
|
||
.doc_type = "export",
|
||
.declaration_type = "EXA", ' IMA-_> Arrived
|
||
.declarant_eori = VERAG_PROG_ALLGEMEIN.cAllgemein.UK_EORI_LTD,
|
||
.declarant_name = "VERAG-UNISPED Ltd",
|
||
.declarant_rep = "2",
|
||
.goods_location = "GBAUDEUDEUDEU",
|
||
.total_packages = 5,
|
||
.nature_of_transaction = "11", ' Kaufgeschäft 11 Outright purchase/sale
|
||
.commercial_ref = LRN, ' .trader_ref = LRN,
|
||
.ducr = LRN
|
||
}
|
||
|
||
Dim ioReference = LRN & Now.ToString("ddMMyyyy_HHmmss")
|
||
|
||
|
||
Select Case If(AVISO.Transportmittelart, "")
|
||
Case "CONTAINER"
|
||
MT_IMP.border_transport_type = "1" ' z. B. Ocean
|
||
MT_IMP.arrival_transport_type = "10"
|
||
Case Else
|
||
MT_IMP.border_transport_type = "6" ' z. B. 3 Straße '?6 RORO??
|
||
MT_IMP.arrival_transport_type = "30"
|
||
|
||
End Select
|
||
|
||
MT_IMP.inland_transport_type = "3" ' z. B. Straße '?6 RORO??
|
||
MT_IMP.border_vehicle_code = AVISO.LKW_Nr
|
||
MT_IMP.border_vehicle_coun = AVISO.LKW_Nationalitaet
|
||
|
||
|
||
|
||
If SND.tblSnd_EmpfaengerKdNr > 0 Then
|
||
Dim AD As New cAdressen(SND.tblSnd_EmpfaengerKdNr)
|
||
Dim KD As New cKunde(SND.tblSnd_EmpfaengerKdNr)
|
||
Dim CN As New VERAG_PROG_ALLGEMEIN.cRelayHub.cRelayHubAddress
|
||
CN.addressType = "CN"
|
||
MT_IMP.consignee_eori = If(KD.EORITIN, "")
|
||
MT_IMP.consignee_name = AD.Name_1
|
||
MT_IMP.consignee_address = AD.Straße
|
||
MT_IMP.consignee_postcode = AD.PLZ
|
||
MT_IMP.consignee_city_name = AD.Ort
|
||
MT_IMP.consignee_country_id = cProgramFunctions.getISO2Land(AD.LandKz)
|
||
|
||
End If
|
||
|
||
If SND.tblSnd_AbsenderKdNr > 0 Then
|
||
Dim AD As New cAdressen(SND.tblSnd_AbsenderKdNr)
|
||
Dim KD As New cKunde(SND.tblSnd_AbsenderKdNr)
|
||
Dim CZ As New VERAG_PROG_ALLGEMEIN.cRelayHub.cRelayHubAddress
|
||
|
||
MT_IMP.consignor_eori = If(KD.EORITIN, "")
|
||
MT_IMP.consignor_name = AD.Name_1
|
||
MT_IMP.consignor_address = AD.Straße
|
||
MT_IMP.consignor_postcode = AD.PLZ
|
||
MT_IMP.consignor_city_name = AD.Ort
|
||
MT_IMP.consignor_country_id = cProgramFunctions.getISO2Land(AD.LandKz)
|
||
MT_IMP.export_country_id = MT_IMP.consignor_country_id
|
||
MT_IMP.import_country_id = MT_IMP.consignor_country_id 'muss lt. API mitgegeben werden
|
||
End If
|
||
|
||
|
||
|
||
' API-Client erstellen (mit Benutzer & Passwort in der Klasse eingebaut)
|
||
Dim client As New cModaltransApiClient_IMPORT()
|
||
|
||
' Senden und Ergebnis anzeigen
|
||
Dim response As cMT_IMP_CustomsDeclarationResponse = client.SendDeclaration(MT_IMP)
|
||
|
||
If response IsNot Nothing Then
|
||
Console.WriteLine("Status: " & response.status)
|
||
Console.WriteLine("Message: " & response.message)
|
||
Console.WriteLine("Declaration ID: " & response.declarationId)
|
||
Return True
|
||
Else
|
||
Console.WriteLine("Keine Antwort erhalten.")
|
||
End If
|
||
Return False
|
||
End Function
|
||
End Class |