257 lines
12 KiB
VB.net
257 lines
12 KiB
VB.net
Imports System.Globalization
|
|
Imports Newtonsoft.Json
|
|
Imports VERAG_PROG_ALLGEMEIN
|
|
|
|
Public Class cDakosyEZA_Greenpulse
|
|
|
|
' ==========================================================
|
|
' BuildByMrn_DY: Erzeugt Kafka-Objekt aus cDakosyEZA (DY)
|
|
' ==========================================================
|
|
Public Shared Function BuildByMrn(eza As cDakosyEZA) As cATEZ_Greenpulse_KafkaDecs
|
|
If eza Is Nothing Then Throw New ArgumentNullException(NameOf(eza))
|
|
|
|
' --- Adressen (Heuristik: CN=Importer, CZ=Exporter, DT=Declarant) ---
|
|
Dim importer = GuessAddressByType(eza.eza_ADRESSEN, {"CN", "IM", "IMP"})
|
|
Dim exporter = GuessAddressByType(eza.eza_ADRESSEN, {"CZ", "EX", "EXP"})
|
|
Dim declarant = GuessAddressByType(eza.eza_ADRESSEN, {"DT", "DEC", "ANM", "DECLARANT"})
|
|
|
|
' --- Rechnungsdaten (Unterlagen N380) ---
|
|
Dim inv = If(eza.eza_UNTERLAGEN IsNot Nothing,
|
|
eza.eza_UNTERLAGEN.FirstOrDefault(Function(u) SafeStr(u.ezaUl_Art).Equals("N380", StringComparison.OrdinalIgnoreCase) _
|
|
AndAlso Not String.IsNullOrWhiteSpace(SafeStr(u.ezaUl_Nummer))),
|
|
Nothing)
|
|
|
|
' --- Kopf/Zielschema ---
|
|
Dim dest As New cATEZ_Greenpulse_KafkaDecs With {
|
|
.Declaration = New cATEZ_Greenpulse_KafkaDecs.DeclarationNode With {
|
|
.DeclarationSourceId = SafeStr(eza.eza_ANR),
|
|
.DeclarationNo = SafeStr(eza.eza_MRN),
|
|
.DeclarationDate = ToDateYMD(FirstNonEmpty(eza.eza_Anmeldedatum, eza.eza_Erstellung)),
|
|
.RequestedProcedure = SafeStr(eza.eza_VerfahrenBeantragtCode),
|
|
.PreviousProcedure = "",
|
|
.Goods = New List(Of cATEZ_Greenpulse_KafkaDecs.GoodItem)()
|
|
},
|
|
.Parties = New cATEZ_Greenpulse_KafkaDecs.PartiesNode With {
|
|
.ImporterIdentificationNumber = FirstNonEmptyStr(If(importer IsNot Nothing, importer.ezaAd_TeilnehmerEORI, Nothing),
|
|
If(importer IsNot Nothing, importer.ezaAd_AdressCode, Nothing)),
|
|
.ExporterIdentificationNumber = FirstNonEmptyStr(If(exporter IsNot Nothing, exporter.ezaAd_TeilnehmerEORI, Nothing),
|
|
If(exporter IsNot Nothing, exporter.ezaAd_AdressCode, Nothing)),
|
|
.ReportingDeclarantEORINumber = FirstNonEmptyStr(If(declarant IsNot Nothing, declarant.ezaAd_TeilnehmerEORI, Nothing),
|
|
If(declarant IsNot Nothing, declarant.ezaAd_AdressCode, Nothing)),
|
|
.TypeOfRepresentation = SafeStr(eza.eza_VertretungsVerhaeltnisCode)
|
|
},
|
|
.Commercial = New cATEZ_Greenpulse_KafkaDecs.CommercialNode With {
|
|
.InvoiceNumbers = If(inv IsNot Nothing, SafeStr(inv.ezaUl_Nummer), ""),
|
|
.InvoiceDate = If(inv IsNot Nothing, ToDateYMD(inv.ezaUl_DatumAusstellung), "")
|
|
},
|
|
.ExporterDetails = New cATEZ_Greenpulse_KafkaDecs.ExporterDetailsNode With {
|
|
.ExporterTitle = FirstNonEmptyStr(If(exporter IsNot Nothing, exporter.ezaAd_NameFirma1, Nothing),
|
|
If(exporter IsNot Nothing, exporter.ezaAd_NameFirma2, Nothing)),
|
|
.ExporterEmail = "",
|
|
.ExporterPhone = ""
|
|
},
|
|
.ImporterDetails = New cATEZ_Greenpulse_KafkaDecs.ImporterDetailsNode With {
|
|
.ImporterTitle = FirstNonEmptyStr(If(importer IsNot Nothing, importer.ezaAd_NameFirma1, Nothing),
|
|
If(importer IsNot Nothing, importer.ezaAd_NameFirma2, Nothing)),
|
|
.ImporterEmail = "",
|
|
.ImporterPhone = "",
|
|
.ImporterCountryCodeOrMemberState = SafeStr(If(importer IsNot Nothing, importer.ezaAd_LandCode, Nothing)),
|
|
.ImporterSubdivision = "",
|
|
.ImporterCity = SafeStr(If(importer IsNot Nothing, importer.ezaAd_Ort, Nothing)),
|
|
.ImporterStreet = MergeStreet(importer),
|
|
.ImporterStreetAdditional = SafeStr(If(importer IsNot Nothing, importer.ezaAd_StrasseHausNr2, Nothing)),
|
|
.ImporterAddressNumber = "",
|
|
.ImporterPostCode = SafeStr(If(importer IsNot Nothing, importer.ezaAd_PLZ, Nothing)),
|
|
.ImporterPoBox = "",
|
|
.ImporterCoordinateLongitudeX = "",
|
|
.ImporterCoordinateLatitudeY = ""
|
|
}
|
|
}
|
|
|
|
' --- Falls EORI vorhanden: spezifisch befüllen (Lookup/Mapping via Helper) ---
|
|
Dim impEori As String = SafeStr(If(importer IsNot Nothing, importer.ezaAd_TeilnehmerEORI, Nothing))
|
|
If Not String.IsNullOrWhiteSpace(impEori) Then
|
|
PopulateImporterByEori(impEori, dest.Parties, dest.ImporterDetails)
|
|
End If
|
|
|
|
Dim expEori As String = SafeStr(If(exporter IsNot Nothing, exporter.ezaAd_TeilnehmerEORI, Nothing))
|
|
If Not String.IsNullOrWhiteSpace(expEori) Then
|
|
PopulateExporterByEori(expEori, dest.Parties, dest.ExporterDetails)
|
|
End If
|
|
|
|
Dim decEori As String = SafeStr(If(declarant IsNot Nothing, declarant.ezaAd_TeilnehmerEORI, Nothing))
|
|
If Not String.IsNullOrWhiteSpace(decEori) Then
|
|
PopulateDeclarantByEori(decEori, dest.Parties)
|
|
End If
|
|
|
|
' --- Warenpositionen -> Goods ---
|
|
If eza.eza_WARENPOS IsNot Nothing Then
|
|
For Each wp In eza.eza_WARENPOS
|
|
Dim gi As New cATEZ_Greenpulse_KafkaDecs.GoodItem With {
|
|
.CommodityCode = SafeStr(wp.ezaWP_WarennummerEZT),
|
|
.OriginCountryCode = SafeStr(wp.ezaWP_UrsprungslandCode),
|
|
.NetMass = ToInvariantStr(wp.ezaWP_Eigenmasse),
|
|
.TypeOfMeasurementUnit = UnitCodeToKafkaName(FirstNonEmptyStr(wp.ezaWP_WarenMasseinheit1, wp.ezaWP_AHStatMengeMasseinheit, "KGM")),
|
|
.SpecialProcedures = New cATEZ_Greenpulse_KafkaDecs.SpecialProceduresNode With {
|
|
.MemberStateAutharization = SafeStr(If(importer IsNot Nothing, importer.ezaAd_LandCode, Nothing)),
|
|
.DischargeBillWaiver = "",
|
|
.Authorisation = FirstNonEmptyStr(wp.ezaWP_Bewilligungsnummer, eza.eza_BewilligungsIDZLAVUV),
|
|
.StartTime = "",
|
|
.EndTime = "",
|
|
.Deadline = ""
|
|
}
|
|
}
|
|
dest.Declaration.Goods.Add(gi)
|
|
Next
|
|
End If
|
|
|
|
' --- Previous/Requested Procedure ggf. aus erster Position ziehen ---
|
|
Dim wp0 = If(eza.eza_WARENPOS IsNot Nothing, eza.eza_WARENPOS.FirstOrDefault(), Nothing)
|
|
If wp0 IsNot Nothing Then
|
|
If String.IsNullOrWhiteSpace(dest.Declaration.RequestedProcedure) Then
|
|
dest.Declaration.RequestedProcedure = SafeStr(wp0.ezaWP_Zollverfahren)
|
|
End If
|
|
dest.Declaration.PreviousProcedure = SafeStr(wp0.ezaWP_VerfahrensCodeVorangegangenesVerfahren)
|
|
End If
|
|
|
|
Return dest
|
|
End Function
|
|
|
|
' =========================
|
|
' Populate-Helper (mit TODO)
|
|
' =========================
|
|
|
|
' Importer: ergänzt Parties.ImporterIdentificationNumber und ImporterDetails anhand EORI
|
|
Private Shared Sub PopulateImporterByEori(eori As String,
|
|
ByRef parties As cATEZ_Greenpulse_KafkaDecs.PartiesNode,
|
|
ByRef details As cATEZ_Greenpulse_KafkaDecs.ImporterDetailsNode)
|
|
' Pflicht: EORI in Parties
|
|
parties.ImporterIdentificationNumber = eori
|
|
Dim AD As VERAG_PROG_ALLGEMEIN.cAdressen = cZOLL_IMPORT.getAdresseFromEORI(eori, "", "")
|
|
|
|
If AD IsNot Nothing Then
|
|
details.ImporterTitle = (If(AD.Name_1, "") & " " & If(AD.Name_2, "")).trim
|
|
details.ImporterCountryCodeOrMemberState = VERAG_PROG_ALLGEMEIN.cProgramFunctions.getISO2Land(AD.LandKz)
|
|
details.ImporterCity = AD.Ort
|
|
details.ImporterStreet = AD.Straße
|
|
details.ImporterAddressNumber = ""
|
|
details.ImporterPostCode = AD.PLZ
|
|
details.ImporterEmail = AD.E_Mail
|
|
details.ImporterPhone = AD.Telefon
|
|
End If
|
|
End Sub
|
|
|
|
' Exporter: ergänzt Parties.ExporterIdentificationNumber und ExporterDetails anhand EORI
|
|
Private Shared Sub PopulateExporterByEori(eori As String,
|
|
ByRef parties As cATEZ_Greenpulse_KafkaDecs.PartiesNode,
|
|
ByRef details As cATEZ_Greenpulse_KafkaDecs.ExporterDetailsNode)
|
|
parties.ExporterIdentificationNumber = eori
|
|
Dim AD As VERAG_PROG_ALLGEMEIN.cAdressen = cZOLL_IMPORT.getAdresseFromEORI(eori, "", "")
|
|
|
|
If AD IsNot Nothing Then
|
|
details.ExporterTitle = (If(AD.Name_1, "") & " " & If(AD.Name_2, "")).trim
|
|
'details.exporterCountryCodeOrMemberState = VERAG_PROG_ALLGEMEIN.cProgramFunctions.getISO2Land(AD.LandKz)
|
|
'details.exporterCity = AD.Ort
|
|
'details.exporterStreet = AD.Straße
|
|
'details.exporterAddressNumber = ""
|
|
'details.exporterPostCode = AD.PLZ
|
|
details.ExporterEmail = AD.E_Mail
|
|
details.ExporterPhone = AD.Telefon
|
|
End If
|
|
End Sub
|
|
|
|
' Declarant: ergänzt Parties.ReportingDeclarantEORINumber (weitere Daten optional)
|
|
Private Shared Sub PopulateDeclarantByEori(eori As String,
|
|
ByRef parties As cATEZ_Greenpulse_KafkaDecs.PartiesNode)
|
|
parties.ReportingDeclarantEORINumber = eori
|
|
|
|
' TODO: Optional Stammdaten-Lookup für weitere deklarantenbezogene Daten,
|
|
' z. B. Standard-Vertretungsverhältnis, Niederlassungsnummer etc.
|
|
' Dim m = PartnerRepo.GetByEori(eori)
|
|
' If m IsNot Nothing Then
|
|
' ' ggf. parties.TypeOfRepresentation = m.DefaultRepType
|
|
' End If
|
|
End Sub
|
|
|
|
' JSON-Wrapper
|
|
Public Shared Function BuildJsonByMrn(eza As cDakosyEZA, Optional pretty As Boolean = True) As String
|
|
Dim obj = BuildByMrn(eza)
|
|
Return obj.ToJson(pretty)
|
|
End Function
|
|
|
|
' -----------------------------
|
|
' Helper (ggf. einmalig zentral)
|
|
' -----------------------------
|
|
Private Shared Function GuessAddressByType(list As List(Of cDakosy_EZA_Adressen), types As IEnumerable(Of String)) As cDakosy_EZA_Adressen
|
|
If list Is Nothing Then Return Nothing
|
|
Dim setTypes = New HashSet(Of String)(types.Select(Function(t) t.ToUpperInvariant()))
|
|
Dim hit = list.FirstOrDefault(Function(a) setTypes.Contains(SafeStr(a.ezaAd_AdressTyp).ToUpperInvariant()))
|
|
If hit IsNot Nothing Then Return hit
|
|
Dim hitEori = list.FirstOrDefault(Function(a) Not String.IsNullOrWhiteSpace(SafeStr(a.ezaAd_TeilnehmerEORI)))
|
|
If hitEori IsNot Nothing Then
|
|
Return hitEori
|
|
Else
|
|
Return list.FirstOrDefault()
|
|
End If
|
|
End Function
|
|
|
|
Private Shared Function MergeStreet(addr As cDakosy_EZA_Adressen) As String
|
|
If addr Is Nothing Then Return ""
|
|
Dim s1 = SafeStr(addr.ezaAd_StrasseHausNr1)
|
|
Dim s2 = SafeStr(addr.ezaAd_StrasseHausNr2)
|
|
If s2 <> "" Then Return (s1 & " " & s2).Trim()
|
|
Return s1
|
|
End Function
|
|
|
|
Private Shared Function UnitCodeToKafkaName(code As String) As String
|
|
Select Case SafeStr(code).ToUpperInvariant()
|
|
Case "KGM" : Return "Kilograms"
|
|
Case "TNE", "T" : Return "Tonnes"
|
|
Case "LTR" : Return "Litres"
|
|
Case "NAR", "NMB" : Return "Number of items"
|
|
Case Else : Return code
|
|
End Select
|
|
End Function
|
|
|
|
Private Shared Function ToDateYMD(value As Object) As String
|
|
If value Is Nothing Then Return ""
|
|
Dim dt As DateTime
|
|
If DateTime.TryParse(SafeStr(value), dt) Then
|
|
Return dt.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture)
|
|
End If
|
|
Return ""
|
|
End Function
|
|
|
|
Private Shared Function ToInvariantStr(value As Object) As String
|
|
If value Is Nothing Then Return ""
|
|
If TypeOf value Is IFormattable Then
|
|
Return DirectCast(value, IFormattable).ToString(Nothing, CultureInfo.InvariantCulture)
|
|
End If
|
|
Return Convert.ToString(value, CultureInfo.InvariantCulture)
|
|
End Function
|
|
|
|
Private Shared Function SafeStr(o As Object) As String
|
|
If o Is Nothing Then Return ""
|
|
Dim s = Convert.ToString(o).Trim()
|
|
Return If(s, "")
|
|
End Function
|
|
|
|
Private Shared Function FirstNonEmpty(ParamArray values() As Object) As Object
|
|
For Each v In values
|
|
If v IsNot Nothing AndAlso Not String.IsNullOrWhiteSpace(SafeStr(v)) Then
|
|
Return v
|
|
End If
|
|
Next
|
|
Return Nothing
|
|
End Function
|
|
|
|
Private Shared Function FirstNonEmptyStr(ParamArray values() As Object) As String
|
|
For Each v In values
|
|
Dim s = SafeStr(v)
|
|
If Not String.IsNullOrWhiteSpace(s) Then Return s
|
|
Next
|
|
Return ""
|
|
End Function
|
|
|
|
End Class
|