diff --git a/VERAG_PROG_ALLGEMEIN/VERAG_Zollanmeldung/cVERAG_CustomsDeclarations.vb b/VERAG_PROG_ALLGEMEIN/VERAG_Zollanmeldung/cVERAG_CustomsDeclarations.vb index 929e53f1..a1a50cb8 100644 --- a/VERAG_PROG_ALLGEMEIN/VERAG_Zollanmeldung/cVERAG_CustomsDeclarations.vb +++ b/VERAG_PROG_ALLGEMEIN/VERAG_Zollanmeldung/cVERAG_CustomsDeclarations.vb @@ -76,6 +76,54 @@ Public Class cVERAG_CustomsDeclarations Public Property za_Sachbearbeiter As String Public Property za_SachbearbeiterId As String Public Property za_TotGrossMass As Decimal? + ' EXPORT: optionale Kopfdaten + Public Property za_ExportDeclarationType As String + Public Property za_ExportSecurity As String + Public Property za_ExportPartyConstellation As String + Public Property za_ExportStatus As String + Public Property za_ExportExitDate As Date? + Public Property za_ExportExitOfficeDeclared As String + Public Property za_ExportExitOfficeActual As String + Public Property za_ExportPresentationOffice As String + Public Property za_ExportRegistrationExternal As String + Public Property za_ExportNatureOfTransaction As String + Public Property za_ExportLocationType As String + Public Property za_ExportLocationQualifier As String + Public Property za_ExportLocationIdentifier As String + Public Property za_ExportLocationAuthorisation As String + Public Property za_ExportLocationStreet As String + Public Property za_ExportLocationPostcode As String + Public Property za_ExportLocationCity As String + Public Property za_ExportLocationCountry As String + Public Property za_ExportPresentationStart As Date? + Public Property za_ExportLoadingEnd As Date? + Public Property za_ExportContainerIndicator As String + Public Property za_ExportBorderVehicle As String + Public Property za_ExportBorderVehicleType As String + Public Property za_ExportBorderVehicleNationality As String + Public Property za_ExportExitConfirmationDate As Date? + ' NCTS: optionale Kopfdaten + Public Property za_TransitType As String + Public Property za_TransitStatus As String + Public Property za_TransitDepartureOffice As String + Public Property za_TransitDestinationOffice As String + Public Property za_TransitLimitDate As Date? + Public Property za_TransitArrivalDate As Date? + Public Property za_TransitCompletionDate As Date? + Public Property za_TransitReducedDataset As Boolean? + Public Property za_TransitSecurityCode As String + Public Property za_TransitLocationType As String + Public Property za_TransitLocationQualifier As String + Public Property za_TransitLocationIdentifier As String + Public Property za_TransitSealNumbers As String + Public Property za_TransitContainerIndicator As Boolean? + Public Property za_TransitBorderVehicle As String + Public Property za_TransitBorderVehicleType As String + Public Property za_TransitBorderVehicleNationality As String + Public Property HouseConsignments As New List(Of cVERAG_CustomsDeclarations_HouseConsignment) + Public Property TransitGuarantees As New List(Of cVERAG_CustomsDeclarations_TransitGuarantee) + Public Property TransitOffices As New List(Of cVERAG_CustomsDeclarations_TransitOffice) + Public Property Parties As New List(Of cVERAG_CustomsDeclarations_Parties) Public Property Items As New List(Of cVERAG_CustomsDeclarations_Item) @@ -152,7 +200,49 @@ Public Class cVERAG_CustomsDeclarations New SQLVariable("za_Remarks", za_Remarks), New SQLVariable("za_Sachbearbeiter", za_Sachbearbeiter), New SQLVariable("za_SachbearbeiterId", za_SachbearbeiterId), - New SQLVariable("za_TotGrossMass", za_TotGrossMass) + New SQLVariable("za_TotGrossMass", za_TotGrossMass), + New SQLVariable("za_ExportDeclarationType", za_ExportDeclarationType), + New SQLVariable("za_ExportSecurity", za_ExportSecurity), + New SQLVariable("za_ExportPartyConstellation", za_ExportPartyConstellation), + New SQLVariable("za_ExportStatus", za_ExportStatus), + New SQLVariable("za_ExportExitDate", za_ExportExitDate), + New SQLVariable("za_ExportExitOfficeDeclared", za_ExportExitOfficeDeclared), + New SQLVariable("za_ExportExitOfficeActual", za_ExportExitOfficeActual), + New SQLVariable("za_ExportPresentationOffice", za_ExportPresentationOffice), + New SQLVariable("za_ExportRegistrationExternal", za_ExportRegistrationExternal), + New SQLVariable("za_ExportNatureOfTransaction", za_ExportNatureOfTransaction), + New SQLVariable("za_ExportLocationType", za_ExportLocationType), + New SQLVariable("za_ExportLocationQualifier", za_ExportLocationQualifier), + New SQLVariable("za_ExportLocationIdentifier", za_ExportLocationIdentifier), + New SQLVariable("za_ExportLocationAuthorisation", za_ExportLocationAuthorisation), + New SQLVariable("za_ExportLocationStreet", za_ExportLocationStreet), + New SQLVariable("za_ExportLocationPostcode", za_ExportLocationPostcode), + New SQLVariable("za_ExportLocationCity", za_ExportLocationCity), + New SQLVariable("za_ExportLocationCountry", za_ExportLocationCountry), + New SQLVariable("za_ExportPresentationStart", za_ExportPresentationStart), + New SQLVariable("za_ExportLoadingEnd", za_ExportLoadingEnd), + New SQLVariable("za_ExportContainerIndicator", za_ExportContainerIndicator), + New SQLVariable("za_ExportBorderVehicle", za_ExportBorderVehicle), + New SQLVariable("za_ExportBorderVehicleType", za_ExportBorderVehicleType), + New SQLVariable("za_ExportBorderVehicleNationality", za_ExportBorderVehicleNationality), + New SQLVariable("za_ExportExitConfirmationDate", za_ExportExitConfirmationDate), + New SQLVariable("za_TransitType", za_TransitType), + New SQLVariable("za_TransitStatus", za_TransitStatus), + New SQLVariable("za_TransitDepartureOffice", za_TransitDepartureOffice), + New SQLVariable("za_TransitDestinationOffice", za_TransitDestinationOffice), + New SQLVariable("za_TransitLimitDate", za_TransitLimitDate), + New SQLVariable("za_TransitArrivalDate", za_TransitArrivalDate), + New SQLVariable("za_TransitCompletionDate", za_TransitCompletionDate), + New SQLVariable("za_TransitReducedDataset", za_TransitReducedDataset), + New SQLVariable("za_TransitSecurityCode", za_TransitSecurityCode), + New SQLVariable("za_TransitLocationType", za_TransitLocationType), + New SQLVariable("za_TransitLocationQualifier", za_TransitLocationQualifier), + New SQLVariable("za_TransitLocationIdentifier", za_TransitLocationIdentifier), + New SQLVariable("za_TransitSealNumbers", za_TransitSealNumbers), + New SQLVariable("za_TransitContainerIndicator", za_TransitContainerIndicator), + New SQLVariable("za_TransitBorderVehicle", za_TransitBorderVehicle), + New SQLVariable("za_TransitBorderVehicleType", za_TransitBorderVehicleType), + New SQLVariable("za_TransitBorderVehicleNationality", za_TransitBorderVehicleNationality) } End Function @@ -824,30 +914,31 @@ Public Class cVERAG_CustomsDeclarations End Try Return Nothing End Function + Public Sub LOAD_TRANSIT() + If za_Id <= 0 Then Return + HouseConsignments = cVERAG_NCTS_Repository.LoadHouses(za_Id) + TransitGuarantees = cVERAG_NCTS_Repository.LoadGuarantees(za_Id) + TransitOffices = cVERAG_NCTS_Repository.LoadOffices(za_Id) + Dim byId = HouseConsignments.ToDictionary(Function(h) h.zaHC_Id, Function(h) h.zaHC_Number) + For Each it In Items + If it.zaItem_HouseConsignmentId.HasValue AndAlso byId.ContainsKey(it.zaItem_HouseConsignmentId.Value) Then + it.zaItem_HouseConsignmentNumber = byId(it.zaItem_HouseConsignmentId.Value) + End If + Next + End Sub + + ' Separat nach SAVE(): ersetzt die NCTS-Kinddaten inkl. HC-Verknüpfung. + Public Sub SAVE_TRANSIT() + If za_Id <= 0 Then Throw New InvalidOperationException("Zuerst SAVE() aufrufen.") + cVERAG_NCTS_Repository.SaveTransit(za_Id, HouseConsignments, TransitGuarantees, TransitOffices, Items) + End Sub + + ' Alle Standarddaten inkl. Packages in EINER Transaktion speichern. Public Function SAVE() As Boolean - Dim list = getParameterList() - - Dim sqlstr = - "BEGIN TRAN " & - "IF EXISTS(SELECT 1 FROM tblVERAG_CustomsDeclarations WHERE za_Id=@za_Id) " & - "BEGIN " & getUpdateCmd() & " END " & - "ELSE BEGIN " & getInsertCmd() & " END " & - "COMMIT TRAN" - - za_Id = SQL.doSQLVarListID(za_Id, sqlstr, "FMZOLL", , list) - If za_Id <= 0 Then Return False - - cVERAG_CustomsDeclarations_Parties.REPLACE_ALL(za_Id, Parties) - cVERAG_CustomsDeclarations_Document.REPLACE_HEAD(za_Id, Documents) - - ' Items zuerst speichern, damit zaItem_Id für Item-Duties vorhanden ist - cVERAG_CustomsDeclarations_Item.REPLACE_ALL(za_Id, Items) - - ' Nur Header-Duties speichern (zaDuty_zaItemId bleibt NULL) - cVERAG_CustomsDeclarations_Duty.REPLACE_HEAD(za_Id, Duties) - - Return True + cVERAG_CustomsDeclarations_SaveRepository.Save(Me) + Return za_Id > 0 End Function + End Class Public Class cVERAG_CustomsDeclarations_Parties @@ -856,6 +947,7 @@ Public Class cVERAG_CustomsDeclarations_Parties Public Property zaParty_zaId As Integer Public Property zaParty_Role As String Public Property zaParty_EORI As String + Public Property zaParty_SubsidiaryNumber As String Public Property zaParty_EORI_NL As String Public Property zaParty_Name As String Public Property zaParty_Street As String @@ -876,6 +968,7 @@ Public Class cVERAG_CustomsDeclarations_Parties New SQLVariable("zaParty_zaId", zaParty_zaId), New SQLVariable("zaParty_Role", zaParty_Role), New SQLVariable("zaParty_EORI", zaParty_EORI), + New SQLVariable("zaParty_SubsidiaryNumber", zaParty_SubsidiaryNumber), New SQLVariable("zaParty_EORI_NL", zaParty_EORI_NL), New SQLVariable("zaParty_Name", zaParty_Name), New SQLVariable("zaParty_Street", zaParty_Street), @@ -967,7 +1060,16 @@ Public Class cVERAG_CustomsDeclarations_Item Public Property zaItem_Id As Integer Public Property zaItem_zaId As Integer Public Property zaItem_PosNo As Integer + Public Property zaItem_HouseConsignmentId As Integer? + Public Property zaItem_HouseConsignmentNumber As Integer? ' Transient mapping before SAVE_TRANSIT + Public Property zaItem_ExportUCR As String + Public Property zaItem_ExportRegionDispatch As String + Public Property zaItem_ExportCountry As String + Public Property zaItem_ExportNatureOfTransaction As String + Public Property zaItem_ExportStatCurrency As String + Public Property zaItem_ExportCUSCode As String + Public Property zaItem_ExportRegistrationExternal As String Public Property zaItem_ArticleCode As String Public Property zaItem_HSCode As String Public Property zaItem_HSAddition1 As String @@ -984,6 +1086,8 @@ Public Class cVERAG_CustomsDeclarations_Item Public Property zaItem_HSAddCodes10 As String Public Property zaItem_Description As String + Public Property Packages As New List(Of cVERAG_CustomsDeclarations_ItemPackage) + Public Property zaItem_PackageColli As String Public Property zaItem_PackageType As String Public Property zaItem_PackageMark As String @@ -1028,6 +1132,14 @@ Public Class cVERAG_CustomsDeclarations_Item New SQLVariable("zaItem_Id", zaItem_Id,, True), New SQLVariable("zaItem_zaId", zaItem_zaId), New SQLVariable("zaItem_PosNo", zaItem_PosNo), + New SQLVariable("zaItem_HouseConsignmentId", zaItem_HouseConsignmentId), + New SQLVariable("zaItem_ExportUCR", zaItem_ExportUCR), + New SQLVariable("zaItem_ExportRegionDispatch", zaItem_ExportRegionDispatch), + New SQLVariable("zaItem_ExportCountry", zaItem_ExportCountry), + New SQLVariable("zaItem_ExportNatureOfTransaction", zaItem_ExportNatureOfTransaction), + New SQLVariable("zaItem_ExportStatCurrency", zaItem_ExportStatCurrency), + New SQLVariable("zaItem_ExportCUSCode", zaItem_ExportCUSCode), + New SQLVariable("zaItem_ExportRegistrationExternal", zaItem_ExportRegistrationExternal), New SQLVariable("zaItem_ArticleCode", zaItem_ArticleCode), New SQLVariable("zaItem_HSCode", zaItem_HSCode), New SQLVariable("zaItem_HSAddition1", zaItem_HSAddition1), @@ -1084,25 +1196,9 @@ Public Class cVERAG_CustomsDeclarations_Item ' ---------- DELETE + INSERT ---------- + ' Auch direkte Aufrufer speichern Positionen, Dokumente, Abgaben und Packstücke atomar. Public Shared Sub REPLACE_ALL(zaId As Integer, list As List(Of cVERAG_CustomsDeclarations_Item)) - - Dim SQL As New VERAG_PROG_ALLGEMEIN.SQL - - SQL.doSQL("DELETE FROM tblVERAG_CustomsDeclarations_Items WHERE zaItem_zaId=" & zaId, "FMZOLL") - SQL.doSQL("DELETE FROM tblVERAG_CustomsDeclarations_Documents WHERE zaDoc_zaId=" & zaId & " AND zaDoc_ItemId is not null", "FMZOLL") - - ' Nur Item-Duties löschen; Header-Duties bleiben erhalten und werden separat gespeichert - SQL.doSQL("DELETE FROM tblVERAG_CustomsDeclarations_Duties WHERE zaDuty_zaId=" & zaId & " AND zaDuty_zaItemId IS NOT NULL", "FMZOLL") - - If list Is Nothing Then Exit Sub - - For Each it In list - it.zaItem_zaId = zaId - it.zaItem_Id = SQL.doSQLVarListID(it.zaItem_Id, it.getInsertCmd(), "FMZOLL", , it.getParameterList()) - - cVERAG_CustomsDeclarations_Document.INSERT_ITEM(it.zaItem_zaId, it.zaItem_Id, it.Documents) - cVERAG_CustomsDeclarations_Duty.INSERT_ITEM(it.zaItem_zaId, it.zaItem_Id, it.Duties) - Next + cVERAG_CustomsDeclarations_SaveRepository.ReplaceItems(zaId, list) End Sub Public Shared Function LOAD_BY_ZAID(zaId As Integer, Optional where As String = "") As List(Of cVERAG_CustomsDeclarations_Item) @@ -1149,6 +1245,8 @@ Public Class cVERAG_CustomsDeclarations_Item it.Duties = cVERAG_CustomsDeclarations_Duty.LOAD_ITEM_BY_ITEMID(zaId, it.zaItem_Id) + + it.Packages = cVERAG_CustomsDeclarations_ItemPackage.LOAD_ITEM(it.zaItem_Id) Next Catch ex As Exception @@ -1476,3 +1574,343 @@ Public Class cVERAG_CustomsDeclarations_Document End Class + +' ========================================================================== +' NCTS-Erweiterung. Die vorhandene SAVE()-Methode speichert weiterhin Importdaten. +' Für Transit nach SAVE() zusätzlich SAVE_TRANSIT() aufrufen. +' ========================================================================== +Public Class cVERAG_CustomsDeclarations_HouseConsignment + Public Property zaHC_Id As Integer + Public Property zaHC_Number As Integer + Public Property zaHC_Reference As String + Public Property zaHC_UCR As String + Public Property zaHC_CountryDispatch As String + Public Property zaHC_CountryDestination As String + Public Property zaHC_GrossMass As Decimal? +End Class +Public Class cVERAG_CustomsDeclarations_TransitGuarantee + Public Property zaGRT_Type As String + Public Property zaGRT_GRN As String + Public Property zaGRT_Reference As String + Public Property zaGRT_Amount As Decimal? + Public Property zaGRT_Currency As String +End Class +Public Class cVERAG_CustomsDeclarations_TransitOffice + Public Property zaTO_Sequence As Integer + Public Property zaTO_Office As String + Public Property zaTO_ExpectedArrival As Date? +End Class +Public NotInheritable Class cVERAG_NCTS_Repository + Private Sub New() + End Sub + Private Shared Function Db(v As Object) As Object + Return If(v Is Nothing, CType(DBNull.Value, Object), v) + End Function + Private Shared Sub Add(cmd As SqlCommand, name As String, value As Object) + cmd.Parameters.AddWithValue(name, Db(value)) + End Sub + Private Shared Function OpenConnection() As SqlConnection + Return (New VERAG_PROG_ALLGEMEIN.SQL).GetNewOpenConnectionFMZOLL() + End Function + Public Shared Function LoadHouses(zaId As Integer) As List(Of cVERAG_CustomsDeclarations_HouseConsignment) + Dim result As New List(Of cVERAG_CustomsDeclarations_HouseConsignment) + Using cn = OpenConnection(), cmd As New SqlCommand("SELECT * FROM dbo.tblVERAG_CustomsDeclarations_HouseConsignments WHERE zaHC_zaId=@id ORDER BY zaHC_Number", cn) + Add(cmd, "@id", zaId) + Using r = cmd.ExecuteReader() + While r.Read() + result.Add(New cVERAG_CustomsDeclarations_HouseConsignment With { + .zaHC_Id = CInt(r("zaHC_Id")), .zaHC_Number = CInt(r("zaHC_Number")), + .zaHC_Reference = If(r.IsDBNull(r.GetOrdinal("zaHC_Reference")), Nothing, CStr(r("zaHC_Reference"))), + .zaHC_UCR = If(r.IsDBNull(r.GetOrdinal("zaHC_UCR")), Nothing, CStr(r("zaHC_UCR"))), + .zaHC_CountryDispatch = If(r.IsDBNull(r.GetOrdinal("zaHC_CountryDispatch")), Nothing, CStr(r("zaHC_CountryDispatch"))), + .zaHC_CountryDestination = If(r.IsDBNull(r.GetOrdinal("zaHC_CountryDestination")), Nothing, CStr(r("zaHC_CountryDestination"))), + .zaHC_GrossMass = If(r.IsDBNull(r.GetOrdinal("zaHC_GrossMass")), CType(Nothing, Decimal?), CDec(r("zaHC_GrossMass")))}) + End While + End Using + End Using + Return result + End Function + Public Shared Function LoadGuarantees(zaId As Integer) As List(Of cVERAG_CustomsDeclarations_TransitGuarantee) + Dim result As New List(Of cVERAG_CustomsDeclarations_TransitGuarantee) + Using cn = OpenConnection(), cmd As New SqlCommand("SELECT * FROM dbo.tblVERAG_CustomsDeclarations_TransitGuarantees WHERE zaGRT_zaId=@id ORDER BY zaGRT_Id", cn) + Add(cmd, "@id", zaId) + Using r = cmd.ExecuteReader() + While r.Read() + result.Add(New cVERAG_CustomsDeclarations_TransitGuarantee With { + .zaGRT_Type = If(r.IsDBNull(r.GetOrdinal("zaGRT_Type")), Nothing, CStr(r("zaGRT_Type"))), + .zaGRT_GRN = If(r.IsDBNull(r.GetOrdinal("zaGRT_GRN")), Nothing, CStr(r("zaGRT_GRN"))), + .zaGRT_Reference = If(r.IsDBNull(r.GetOrdinal("zaGRT_Reference")), Nothing, CStr(r("zaGRT_Reference"))), + .zaGRT_Amount = If(r.IsDBNull(r.GetOrdinal("zaGRT_Amount")), CType(Nothing, Decimal?), CDec(r("zaGRT_Amount"))), + .zaGRT_Currency = If(r.IsDBNull(r.GetOrdinal("zaGRT_Currency")), Nothing, CStr(r("zaGRT_Currency")))}) + End While + End Using + End Using + Return result + End Function + Public Shared Function LoadOffices(zaId As Integer) As List(Of cVERAG_CustomsDeclarations_TransitOffice) + Dim result As New List(Of cVERAG_CustomsDeclarations_TransitOffice) + Using cn = OpenConnection(), cmd As New SqlCommand("SELECT * FROM dbo.tblVERAG_CustomsDeclarations_TransitOffices WHERE zaTO_zaId=@id ORDER BY zaTO_Sequence", cn) + Add(cmd, "@id", zaId) + Using r = cmd.ExecuteReader() + While r.Read() + result.Add(New cVERAG_CustomsDeclarations_TransitOffice With { + .zaTO_Sequence = CInt(r("zaTO_Sequence")), .zaTO_Office = CStr(r("zaTO_Office")), + .zaTO_ExpectedArrival = If(r.IsDBNull(r.GetOrdinal("zaTO_ExpectedArrival")), CType(Nothing, Date?), CDate(r("zaTO_ExpectedArrival")))}) + End While + End Using + End Using + Return result + End Function + Public Shared Sub SaveTransit(zaId As Integer, houses As List(Of cVERAG_CustomsDeclarations_HouseConsignment), guarantees As List(Of cVERAG_CustomsDeclarations_TransitGuarantee), offices As List(Of cVERAG_CustomsDeclarations_TransitOffice), items As List(Of cVERAG_CustomsDeclarations_Item)) + Using cn = OpenConnection(), tx = cn.BeginTransaction() + Try + ' Zuerst alte HC-Verweise lösen, dann HC neu aufbauen. + Execute(cn, tx, "UPDATE dbo.tblVERAG_CustomsDeclarations_Items SET zaItem_HouseConsignmentId=NULL WHERE zaItem_zaId=@id", zaId) + Execute(cn, tx, "DELETE FROM dbo.tblVERAG_CustomsDeclarations_HouseConsignments WHERE zaHC_zaId=@id", zaId) + Execute(cn, tx, "DELETE FROM dbo.tblVERAG_CustomsDeclarations_TransitGuarantees WHERE zaGRT_zaId=@id", zaId) + Execute(cn, tx, "DELETE FROM dbo.tblVERAG_CustomsDeclarations_TransitOffices WHERE zaTO_zaId=@id", zaId) + Dim houseIds As New Dictionary(Of Integer, Integer) + For Each h In If(houses, New List(Of cVERAG_CustomsDeclarations_HouseConsignment)) + Using cmd As New SqlCommand("INSERT INTO dbo.tblVERAG_CustomsDeclarations_HouseConsignments (zaHC_zaId,zaHC_Number,zaHC_Reference,zaHC_UCR,zaHC_CountryDispatch,zaHC_CountryDestination,zaHC_GrossMass) OUTPUT INSERTED.zaHC_Id VALUES (@id,@n,@r,@u,@d,@c,@m)", cn, tx) + Add(cmd, "@id", zaId) : Add(cmd, "@n", h.zaHC_Number) : Add(cmd, "@r", h.zaHC_Reference) + Add(cmd, "@u", h.zaHC_UCR) : Add(cmd, "@d", h.zaHC_CountryDispatch) + Add(cmd, "@c", h.zaHC_CountryDestination) : Add(cmd, "@m", h.zaHC_GrossMass) + h.zaHC_Id = CInt(cmd.ExecuteScalar()) + houseIds.Add(h.zaHC_Number, h.zaHC_Id) + End Using + Next + For Each it In If(items, New List(Of cVERAG_CustomsDeclarations_Item)) + If it.zaItem_HouseConsignmentNumber.HasValue Then + If Not houseIds.ContainsKey(it.zaItem_HouseConsignmentNumber.Value) Then Throw New InvalidOperationException("Unbekannte House-Nummer: " & it.zaItem_HouseConsignmentNumber.Value) + Using cmd As New SqlCommand("UPDATE dbo.tblVERAG_CustomsDeclarations_Items SET zaItem_HouseConsignmentId=@hc WHERE zaItem_Id=@item AND zaItem_zaId=@id", cn, tx) + Add(cmd, "@hc", houseIds(it.zaItem_HouseConsignmentNumber.Value)) : Add(cmd, "@item", it.zaItem_Id) : Add(cmd, "@id", zaId) + If cmd.ExecuteNonQuery() <> 1 Then Throw New InvalidOperationException("Position nicht gefunden: " & it.zaItem_Id) + End Using + End If + Next + For Each g In If(guarantees, New List(Of cVERAG_CustomsDeclarations_TransitGuarantee)) + Using cmd As New SqlCommand("INSERT INTO dbo.tblVERAG_CustomsDeclarations_TransitGuarantees (zaGRT_zaId,zaGRT_Type,zaGRT_GRN,zaGRT_Reference,zaGRT_Amount,zaGRT_Currency) VALUES (@id,@t,@g,@r,@a,@c)", cn, tx) + Add(cmd, "@id", zaId) : Add(cmd, "@t", g.zaGRT_Type) : Add(cmd, "@g", g.zaGRT_GRN) + Add(cmd, "@r", g.zaGRT_Reference) : Add(cmd, "@a", g.zaGRT_Amount) : Add(cmd, "@c", g.zaGRT_Currency) + cmd.ExecuteNonQuery() + End Using + Next + For Each o In If(offices, New List(Of cVERAG_CustomsDeclarations_TransitOffice)) + Using cmd As New SqlCommand("INSERT INTO dbo.tblVERAG_CustomsDeclarations_TransitOffices (zaTO_zaId,zaTO_Sequence,zaTO_Office,zaTO_ExpectedArrival) VALUES (@id,@n,@o,@d)", cn, tx) + Add(cmd, "@id", zaId) : Add(cmd, "@n", o.zaTO_Sequence) + Add(cmd, "@o", o.zaTO_Office) : Add(cmd, "@d", o.zaTO_ExpectedArrival) + cmd.ExecuteNonQuery() + End Using + Next + tx.Commit() + Catch + tx.Rollback() + Throw + End Try + End Using + End Sub + Private Shared Sub Execute(cn As SqlConnection, tx As SqlTransaction, sqlText As String, zaId As Integer) + Using cmd As New SqlCommand(sqlText, cn, tx) + Add(cmd, "@id", zaId) + cmd.ExecuteNonQuery() + End Using + End Sub +End Class + + +' Gemeinsame Packstücke für IMPORT, EXPORT und TRANSIT. +' Bei TRANSIT wird die House-Consignment-Zuordnung über die Warenposition hergestellt. +' Bestehende zaItem_Package*-Felder bleiben für ältere Datensätze erhalten; +' neue Packstücke ausschließlich über Packages speichern, nicht parallel duplizieren. +Public Class cVERAG_CustomsDeclarations_ItemPackage + Public Property zaPkg_Id As Integer + Public Property zaPkg_zaItemId As Integer + Public Property zaPkg_Type As String + Public Property zaPkg_Number As Integer? + Public Property zaPkg_Marks As String + + Public Shared Function LOAD_ITEM(itemId As Integer) As List(Of cVERAG_CustomsDeclarations_ItemPackage) + Dim result As New List(Of cVERAG_CustomsDeclarations_ItemPackage) + Dim sql As New VERAG_PROG_ALLGEMEIN.SQL + Using cn As SqlConnection = SQL.GetNewOpenConnectionFMZOLL() + Using cmd As New SqlCommand("SELECT zaPkg_Id,zaPkg_zaItemId,zaPkg_Type,zaPkg_Number,zaPkg_Marks FROM dbo.tblVERAG_CustomsDeclarations_ItemPackages WHERE zaPkg_zaItemId=@id ORDER BY zaPkg_Id", cn) + cmd.Parameters.AddWithValue("@id", itemId) + Using dr As SqlDataReader = cmd.ExecuteReader() + While dr.Read() + Dim pkg As New cVERAG_CustomsDeclarations_ItemPackage With { + .zaPkg_Id = CInt(dr("zaPkg_Id")), + .zaPkg_zaItemId = CInt(dr("zaPkg_zaItemId")), + .zaPkg_Type = If(dr.IsDBNull(dr.GetOrdinal("zaPkg_Type")), Nothing, CStr(dr("zaPkg_Type"))), + .zaPkg_Marks = If(dr.IsDBNull(dr.GetOrdinal("zaPkg_Marks")), Nothing, CStr(dr("zaPkg_Marks"))) + } + If Not dr.IsDBNull(dr.GetOrdinal("zaPkg_Number")) Then pkg.zaPkg_Number = CInt(dr("zaPkg_Number")) + result.Add(pkg) + End While + End Using + End Using + End Using + Return result + End Function + + Public Shared Sub INSERT_ITEM(itemId As Integer, packages As List(Of cVERAG_CustomsDeclarations_ItemPackage)) + If packages Is Nothing OrElse packages.Count = 0 Then Return + Dim sql As New VERAG_PROG_ALLGEMEIN.SQL + Using cn As SqlConnection = SQL.GetNewOpenConnectionFMZOLL() + For Each pkg In packages + Using cmd As New SqlCommand("INSERT INTO dbo.tblVERAG_CustomsDeclarations_ItemPackages (zaPkg_zaItemId,zaPkg_Type,zaPkg_Number,zaPkg_Marks) VALUES (@id,@type,@number,@marks); SELECT CAST(SCOPE_IDENTITY() AS int)", cn) + cmd.Parameters.AddWithValue("@id", itemId) + cmd.Parameters.AddWithValue("@type", If(CType(pkg.zaPkg_Type, Object), DBNull.Value)) + cmd.Parameters.AddWithValue("@number", If(CType(pkg.zaPkg_Number, Object), DBNull.Value)) + cmd.Parameters.AddWithValue("@marks", If(CType(pkg.zaPkg_Marks, Object), DBNull.Value)) + pkg.zaPkg_Id = CInt(cmd.ExecuteScalar()) + pkg.zaPkg_zaItemId = itemId + End Using + Next + End Using + End Sub +End Class + +' Atomarer Speicherpfad für Kopf/Parties/Items/Documents/Duties/Packages. +' NCTS-HouseConsignments/Guarantees/Offices bleiben vorerst bei SAVE_TRANSIT(). +Public NotInheritable Class cVERAG_CustomsDeclarations_SaveRepository + Private Sub New() + End Sub + Private Shared Function Db(value As Object) As Object + Return If(value Is Nothing, CType(DBNull.Value, Object), value) + End Function + Private Shared Sub Execute(cn As SqlConnection, tx As SqlTransaction, statement As String, id As Integer) + Using cmd As New SqlCommand(statement, cn, tx) + cmd.Parameters.Add("@id", SqlDbType.Int).Value = id + cmd.ExecuteNonQuery() + End Using + End Sub + Private Shared Function WriteObject(cn As SqlConnection, tx As SqlTransaction, tableName As String, obj As Object, values As List(Of SQLVariable), Optional existingId As Integer = 0) As Integer + Dim fields = values.Where(Function(v) Not v.isPrimaryParam).ToList() + Dim pk = values.First(Function(v) v.isPrimaryParam).Text + Dim sqlText As String + If existingId > 0 Then + sqlText = "UPDATE dbo.[" & tableName & "] SET " & String.Join(",", fields.Select(Function(v) "[" & v.Text & "]= @" & v.Text)) & " WHERE [" & pk & "]= @__id" + Else + sqlText = "INSERT INTO dbo.[" & tableName & "] (" & String.Join(",", fields.Select(Function(v) "[" & v.Text & "]")) & ") OUTPUT INSERTED.[" & pk & "] VALUES (" & String.Join(",", fields.Select(Function(v) "@" & v.Text)) & ")" + End If + Using cmd As New SqlCommand(sqlText, cn, tx) + For Each field In fields + Dim prop = obj.GetType().GetProperty(field.Scalarvariable) + If prop Is Nothing Then Throw New InvalidOperationException("Fehlende Eigenschaft: " & field.Scalarvariable) + cmd.Parameters.AddWithValue("@" & field.Text, Db(prop.GetValue(obj))) + Next + If existingId > 0 Then + cmd.Parameters.Add("@__id", SqlDbType.Int).Value = existingId + If cmd.ExecuteNonQuery() <> 1 Then Throw New InvalidOperationException("Datensatz nicht gefunden: " & tableName & " / " & existingId) + Return existingId + End If + Return CInt(cmd.ExecuteScalar()) + End Using + End Function + Private Shared Sub InsertPackages(cn As SqlConnection, tx As SqlTransaction, it As cVERAG_CustomsDeclarations_Item) + Dim packages = it.Packages + ' Kompatibilität: bestehende Aufrufer befüllen weiterhin nur die drei Legacy-Felder. + If packages Is Nothing OrElse packages.Count = 0 Then + If Not String.IsNullOrWhiteSpace(it.zaItem_PackageType) OrElse Not String.IsNullOrWhiteSpace(it.zaItem_PackageColli) OrElse Not String.IsNullOrWhiteSpace(it.zaItem_PackageMark) Then + Dim n As Integer + Dim parsed As Integer? = If(Integer.TryParse(it.zaItem_PackageColli, n), CType(n, Integer?), Nothing) + packages = New List(Of cVERAG_CustomsDeclarations_ItemPackage) From {New cVERAG_CustomsDeclarations_ItemPackage With {.zaPkg_Type = it.zaItem_PackageType, .zaPkg_Number = parsed, .zaPkg_Marks = it.zaItem_PackageMark}} + it.Packages = packages + End If + End If + If packages Is Nothing Then Return + For Each pkg In packages + Using cmd As New SqlCommand("INSERT INTO dbo.tblVERAG_CustomsDeclarations_ItemPackages (zaPkg_zaItemId,zaPkg_Type,zaPkg_Number,zaPkg_Marks) OUTPUT INSERTED.zaPkg_Id VALUES (@item,@type,@number,@marks)", cn, tx) + cmd.Parameters.Add("@item", SqlDbType.Int).Value = it.zaItem_Id + cmd.Parameters.AddWithValue("@type", Db(pkg.zaPkg_Type)) + cmd.Parameters.AddWithValue("@number", Db(pkg.zaPkg_Number)) + cmd.Parameters.AddWithValue("@marks", Db(pkg.zaPkg_Marks)) + pkg.zaPkg_Id = CInt(cmd.ExecuteScalar()) + pkg.zaPkg_zaItemId = it.zaItem_Id + End Using + Next + End Sub + Private Shared Sub ReplaceItemsInTransaction(cn As SqlConnection, tx As SqlTransaction, zaId As Integer, items As List(Of cVERAG_CustomsDeclarations_Item)) + Execute(cn, tx, "DELETE FROM dbo.tblVERAG_CustomsDeclarations_ItemPackages WHERE zaPkg_zaItemId IN (SELECT zaItem_Id FROM dbo.tblVERAG_CustomsDeclarations_Items WHERE zaItem_zaId=@id)", zaId) + Execute(cn, tx, "DELETE FROM dbo.tblVERAG_CustomsDeclarations_Documents WHERE zaDoc_zaId=@id AND zaDoc_ItemId IS NOT NULL", zaId) + Execute(cn, tx, "DELETE FROM dbo.tblVERAG_CustomsDeclarations_Duties WHERE zaDuty_zaId=@id AND zaDuty_zaItemId IS NOT NULL", zaId) + Execute(cn, tx, "DELETE FROM dbo.tblVERAG_CustomsDeclarations_Items WHERE zaItem_zaId=@id", zaId) + If items Is Nothing Then Return + For Each it In items + it.zaItem_zaId = zaId + ' Die alten Item-IDs sind nach DELETE ungültig. Auch NCTS-FK muss gültig sein. + it.zaItem_Id = WriteObject(cn, tx, "tblVERAG_CustomsDeclarations_Items", it, it.getParameterList()) + If it.Documents IsNot Nothing Then + For Each doc In it.Documents + doc.zaDoc_zaId = zaId : doc.zaDoc_ItemId = it.zaItem_Id + doc.zaDoc_Id = WriteObject(cn, tx, "tblVERAG_CustomsDeclarations_Documents", doc, doc.getParameterList()) + Next + End If + If it.Duties IsNot Nothing Then + For Each duty In it.Duties + duty.zaDuty_zaId = zaId : duty.zaDuty_zaItemId = it.zaItem_Id + duty.zaDuty_Id = WriteObject(cn, tx, "tblVERAG_CustomsDeclarations_Duties", duty, duty.getParameterList()) + Next + End If + InsertPackages(cn, tx, it) + Next + End Sub + Public Shared Sub ReplaceItems(zaId As Integer, items As List(Of cVERAG_CustomsDeclarations_Item)) + Dim sql As New VERAG_PROG_ALLGEMEIN.SQL + Using cn As SqlConnection = SQL.GetNewOpenConnectionFMZOLL() + Using tx = cn.BeginTransaction() + Try + ReplaceItemsInTransaction(cn, tx, zaId, items) + tx.Commit() + Catch + tx.Rollback() + Throw + End Try + End Using + End Using + End Sub + Public Shared Sub Save(za As cVERAG_CustomsDeclarations) + Dim sql As New VERAG_PROG_ALLGEMEIN.SQL + Using cn As SqlConnection = SQL.GetNewOpenConnectionFMZOLL() + Using tx = cn.BeginTransaction() + Try + Dim exists As Boolean = False + If za.za_Id > 0 Then + Using cmd As New SqlCommand("SELECT COUNT(1) FROM dbo.tblVERAG_CustomsDeclarations WITH (UPDLOCK,HOLDLOCK) WHERE za_Id=@id", cn, tx) + cmd.Parameters.Add("@id", SqlDbType.Int).Value = za.za_Id + exists = CInt(cmd.ExecuteScalar()) > 0 + End Using + End If + za.za_Id = WriteObject(cn, tx, "tblVERAG_CustomsDeclarations", za, za.getParameterList(), If(exists, za.za_Id, 0)) + Execute(cn, tx, "DELETE FROM dbo.tblVERAG_CustomsDeclarations_Parties WHERE zaParty_zaId=@id", za.za_Id) + If za.Parties IsNot Nothing Then + For Each party In za.Parties + party.zaParty_zaId = za.za_Id + party.zaParty_Id = WriteObject(cn, tx, "tblVERAG_CustomsDeclarations_Parties", party, party.getParameterList()) + Next + End If + Execute(cn, tx, "DELETE FROM dbo.tblVERAG_CustomsDeclarations_Documents WHERE zaDoc_zaId=@id AND zaDoc_ItemId IS NULL", za.za_Id) + If za.Documents IsNot Nothing Then + For Each doc In za.Documents + doc.zaDoc_zaId = za.za_Id : doc.zaDoc_ItemId = Nothing + doc.zaDoc_Id = WriteObject(cn, tx, "tblVERAG_CustomsDeclarations_Documents", doc, doc.getParameterList()) + Next + End If + ReplaceItemsInTransaction(cn, tx, za.za_Id, za.Items) + Execute(cn, tx, "DELETE FROM dbo.tblVERAG_CustomsDeclarations_Duties WHERE zaDuty_zaId=@id AND zaDuty_zaItemId IS NULL", za.za_Id) + If za.Duties IsNot Nothing Then + For Each duty In za.Duties + duty.zaDuty_zaId = za.za_Id : duty.zaDuty_zaItemId = Nothing + duty.zaDuty_Id = WriteObject(cn, tx, "tblVERAG_CustomsDeclarations_Duties", duty, duty.getParameterList()) + Next + End If + tx.Commit() + za.hasEntry = True + Catch + tx.Rollback() + Throw + End Try + End Using + End Using + End Sub +End Class