1199 lines
56 KiB
VB.net
1199 lines
56 KiB
VB.net
Imports System.Configuration
|
|
Imports System.IO
|
|
Imports System.Net
|
|
Imports System.Net.Mail
|
|
Imports System.Text
|
|
Imports Newtonsoft.Json
|
|
Imports Newtonsoft.Json.Linq
|
|
Imports VERAG_PROG_ALLGEMEIN
|
|
|
|
Public Class frmSendungsDokumentanforderung
|
|
Private ReadOnly AvisoDAL As New cAvisoDAL
|
|
Public Property AvisoID As Integer
|
|
Public Property SendungID As Integer
|
|
|
|
Private ReadOnly _anforderungCheckboxes As New List(Of CheckBox)
|
|
Private ReadOnly _anhangsartIdByCheckbox As New Dictionary(Of CheckBox, Integer)
|
|
Private ReadOnly _backendBezeichnungByCodeId As New Dictionary(Of Integer, String)
|
|
Private ReadOnly _selectedAnhangsartIdByCodeId As New Dictionary(Of Integer, Integer)
|
|
Private ReadOnly _documentCustomNameByCodeId As New Dictionary(Of Integer, String)
|
|
Private ReadOnly _documentBaseTextByCodeId As New Dictionary(Of Integer, String)
|
|
Private ReadOnly _anhangsartenOptions As New List(Of AnhangsartOption)
|
|
Private ReadOnly _bereichByCodeId As New Dictionary(Of Integer, Integer)
|
|
|
|
Private _selectedDocumentCodeId As Integer
|
|
Private _isLoadingDocumentEditor As Boolean
|
|
|
|
Private Const DefaultDocumentBaseText As String = "Bitte das Dokument hochladen."
|
|
Private Const BereichDokumentMain As Integer = 1
|
|
|
|
Private Shared _customerPortalJwtToken As String = ""
|
|
Private Shared _customerPortalJwtExpUtc As DateTime = DateTime.MinValue
|
|
Private Shared _customerPortalAnhangsartenMap As Dictionary(Of String, Integer) = Nothing
|
|
Private Shared _customerPortalAnhangsartenFetchedUtc As DateTime = DateTime.MinValue
|
|
Private Shared _customerPortalCustomFilenameAnhangsartId As Integer = -1
|
|
Private ReadOnly _kontaktEmailRows As New List(Of KontaktEmailRow)
|
|
|
|
Public Sub New(avisoId As Integer, sendungId As Integer, state As DokumentanforderungState)
|
|
InitializeComponent()
|
|
AvisoID = avisoId
|
|
SendungID = sendungId
|
|
Icon = cMeineFunktionenAVISO.GetProgrammIcon
|
|
_stateToApply = If(state, New DokumentanforderungState())
|
|
End Sub
|
|
|
|
Private ReadOnly _stateToApply As DokumentanforderungState
|
|
|
|
Private Sub frmSendungsDokumentanforderung_Load(sender As Object, e As EventArgs) Handles MyBase.Load
|
|
VERAG_PROG_ALLGEMEIN.cAllgemein._TRANSLATE(Me)
|
|
If cmbCustomerUploadLanguage.SelectedIndex < 0 Then
|
|
Dim idx = cmbCustomerUploadLanguage.Items.IndexOf("de")
|
|
If idx >= 0 Then
|
|
cmbCustomerUploadLanguage.SelectedIndex = idx
|
|
ElseIf cmbCustomerUploadLanguage.Items.Count > 0 Then
|
|
cmbCustomerUploadLanguage.SelectedIndex = 0
|
|
End If
|
|
End If
|
|
|
|
InitializeDocumentEditor()
|
|
SetupDynamicAnforderungCheckboxes()
|
|
ApplyStateToUi(_stateToApply)
|
|
InitializeKontaktEmailGrid()
|
|
LoadKontaktEmails()
|
|
End Sub
|
|
|
|
Private Sub InitializeKontaktEmailGrid()
|
|
If dgvKontaktEmails.Columns.Count > 0 Then Return
|
|
dgvKontaktEmails.AutoGenerateColumns = False
|
|
|
|
Dim colRolle As New DataGridViewTextBoxColumn()
|
|
colRolle.Name = "colRolle"
|
|
colRolle.HeaderText = "Rolle"
|
|
colRolle.DataPropertyName = "Rolle"
|
|
colRolle.Width = 100
|
|
dgvKontaktEmails.Columns.Add(colRolle)
|
|
|
|
Dim colArt As New DataGridViewTextBoxColumn()
|
|
colArt.Name = "colArt"
|
|
colArt.HeaderText = "Art"
|
|
colArt.DataPropertyName = "Art"
|
|
colArt.Width = 130
|
|
dgvKontaktEmails.Columns.Add(colArt)
|
|
|
|
Dim colEmail As New DataGridViewTextBoxColumn()
|
|
colEmail.Name = "colEmail"
|
|
colEmail.HeaderText = "E-Mail"
|
|
colEmail.DataPropertyName = "Email"
|
|
colEmail.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill
|
|
dgvKontaktEmails.Columns.Add(colEmail)
|
|
End Sub
|
|
|
|
Private Sub LoadKontaktEmails()
|
|
_kontaktEmailRows.Clear()
|
|
dgvKontaktEmails.Rows.Clear()
|
|
|
|
Dim dedupe As New HashSet(Of String)(StringComparer.OrdinalIgnoreCase)
|
|
|
|
Dim fraechterKdNr As Integer = 0
|
|
Dim auftraggeberKdNr As Integer = 0
|
|
Dim avisiererKdNr As Integer = 0
|
|
Dim empfaengerKdNr As Integer = 0
|
|
Dim absenderKdNr As Integer = 0
|
|
Dim frachtfuehrerKdNr As Integer = 0
|
|
|
|
Try
|
|
If SendungID > 0 Then
|
|
Dim dtSnd = AvisoDAL.loadDataTableBySQL("SELECT tblSnd_AvisiererKdNr, tblSnd_AuftraggeberKdNr, tblSnd_EmpfaengerKdNr, tblSnd_AbsenderKdNr, tblSnd_FrachtfuehrerKdNr FROM tblSendungen WHERE tblSnd_SendungID = " & SendungID)
|
|
If dtSnd IsNot Nothing AndAlso dtSnd.Rows.Count > 0 Then
|
|
Dim r = dtSnd.Rows(0)
|
|
avisiererKdNr = ToIntSafe(r("tblSnd_AvisiererKdNr"))
|
|
auftraggeberKdNr = ToIntSafe(r("tblSnd_AuftraggeberKdNr"))
|
|
empfaengerKdNr = ToIntSafe(r("tblSnd_EmpfaengerKdNr"))
|
|
absenderKdNr = ToIntSafe(r("tblSnd_AbsenderKdNr"))
|
|
frachtfuehrerKdNr = ToIntSafe(r("tblSnd_FrachtfuehrerKdNr"))
|
|
End If
|
|
End If
|
|
|
|
If AvisoID > 0 Then
|
|
Dim dtAviso = AvisoDAL.loadDataTableBySQL("SELECT Frächter_KdNr, Auftraggeber_KdNr FROM tblAviso WHERE AvisoID = " & AvisoID)
|
|
If dtAviso IsNot Nothing AndAlso dtAviso.Rows.Count > 0 Then
|
|
Dim r = dtAviso.Rows(0)
|
|
fraechterKdNr = ToIntSafe(r("Frächter_KdNr"))
|
|
If auftraggeberKdNr = 0 Then
|
|
auftraggeberKdNr = ToIntSafe(r("Auftraggeber_KdNr"))
|
|
End If
|
|
End If
|
|
End If
|
|
Catch
|
|
End Try
|
|
|
|
AddKontaktEmailsByKunde("Frächter", fraechterKdNr, dedupe)
|
|
AddKontaktEmailsByKunde("Avisierer", avisiererKdNr, dedupe)
|
|
AddKontaktEmailsByKunde("Auftraggeber", auftraggeberKdNr, dedupe)
|
|
AddKontaktEmailsByKunde("Empfänger", empfaengerKdNr, dedupe)
|
|
AddKontaktEmailsByKunde("Absender", absenderKdNr, dedupe)
|
|
AddKontaktEmailsByKunde("Frachtführer", frachtfuehrerKdNr, dedupe)
|
|
|
|
For Each row In _kontaktEmailRows
|
|
dgvKontaktEmails.Rows.Add(row.Rolle, row.Art, row.Email)
|
|
Next
|
|
If If(txtCustomerUploadEmail.Text, "").Trim() = "" AndAlso dgvKontaktEmails.Rows.Count > 0 Then
|
|
txtCustomerUploadEmail.Text = If(dgvKontaktEmails.Rows(0).Cells("colEmail").Value, "").ToString().Trim()
|
|
End If
|
|
End Sub
|
|
|
|
Private Sub AddKontaktEmailsByKunde(rolle As String, kundenNr As Integer, dedupe As HashSet(Of String))
|
|
If kundenNr <= 0 Then Return
|
|
|
|
' 1. E-Mails aus Kundenstammdaten laden (direkt von Datenbank)
|
|
Try
|
|
Dim sql As String = "SELECT E_Mail, E_Mail2 FROM Adressen WHERE AdressenNr = " & kundenNr
|
|
Using conn As System.Data.SqlClient.SqlConnection = VERAG_PROG_ALLGEMEIN.cSqlDb.GetNewOpenConnectionFMZOLL(False)
|
|
Using cmd As New System.Data.SqlClient.SqlCommand(sql, conn)
|
|
Using reader = cmd.ExecuteReader()
|
|
If reader.Read() Then
|
|
Dim email1 = If(reader("E_Mail") Is DBNull.Value, "", reader("E_Mail").ToString().Trim())
|
|
Dim email2 = If(reader("E_Mail2") Is DBNull.Value, "", reader("E_Mail2").ToString().Trim())
|
|
|
|
If email1 <> "" Then
|
|
For Each splitEmail In email1.Split({";"c, ","c}, StringSplitOptions.RemoveEmptyEntries)
|
|
Dim em = splitEmail.Trim()
|
|
If em = "" Then Continue For
|
|
Dim key1 = rolle & "|" & kundenNr.ToString() & "|Stammdaten|" & em.ToLowerInvariant()
|
|
If Not dedupe.Contains(key1) Then
|
|
dedupe.Add(key1)
|
|
_kontaktEmailRows.Add(New KontaktEmailRow With {.Rolle = rolle, .Art = "Stammdaten", .Email = em})
|
|
End If
|
|
Next
|
|
End If
|
|
|
|
If email2 <> "" Then
|
|
For Each splitEmail In email2.Split({";"c, ","c}, StringSplitOptions.RemoveEmptyEntries)
|
|
Dim em = splitEmail.Trim()
|
|
If em = "" Then Continue For
|
|
Dim key2 = rolle & "|" & kundenNr.ToString() & "|Stammdaten|" & em.ToLowerInvariant()
|
|
If Not dedupe.Contains(key2) Then
|
|
dedupe.Add(key2)
|
|
_kontaktEmailRows.Add(New KontaktEmailRow With {.Rolle = rolle, .Art = "Stammdaten", .Email = em})
|
|
End If
|
|
Next
|
|
End If
|
|
End If
|
|
End Using
|
|
End Using
|
|
End Using
|
|
Catch
|
|
End Try
|
|
|
|
' 2. E-Mails aus E-Mail-Benachrichtigungen (Sendungsdetails) laden (direkt von Datenbank)
|
|
Try
|
|
Dim sql As String = "SELECT eb_ebartId, eb_EMail, eb_cc, eb_bcc FROM tblEmailBenachrichtigung WHERE eb_KundenNr = " & kundenNr
|
|
Using conn As System.Data.SqlClient.SqlConnection = VERAG_PROG_ALLGEMEIN.cSqlDb.GetNewOpenConnectionFMZOLL(False)
|
|
Using cmd As New System.Data.SqlClient.SqlCommand(sql, conn)
|
|
Using reader = cmd.ExecuteReader()
|
|
While reader.Read()
|
|
Dim artId = If(reader("eb_ebartId") Is DBNull.Value, 0, Convert.ToInt32(reader("eb_ebartId")))
|
|
Dim email = If(reader("eb_EMail") Is DBNull.Value, "", reader("eb_EMail").ToString().Trim())
|
|
Dim isCc = If(reader("eb_cc") Is DBNull.Value, False, Convert.ToBoolean(reader("eb_cc")))
|
|
Dim isBcc = If(reader("eb_bcc") Is DBNull.Value, False, Convert.ToBoolean(reader("eb_bcc")))
|
|
|
|
If email = "" Then Continue While
|
|
|
|
Dim empfaengerArt = If(isBcc, "BCC", If(isCc, "CC", "AN"))
|
|
Dim artText = ResolveMailArtLabel(artId) & " / " & empfaengerArt
|
|
|
|
For Each splitEmail In email.Split({";"c, ","c}, StringSplitOptions.RemoveEmptyEntries)
|
|
Dim em = splitEmail.Trim()
|
|
If em = "" Then Continue For
|
|
Dim key = rolle & "|" & kundenNr.ToString() & "|" & artText & "|" & em.ToLowerInvariant()
|
|
If Not dedupe.Contains(key) Then
|
|
dedupe.Add(key)
|
|
_kontaktEmailRows.Add(New KontaktEmailRow With {.Rolle = rolle, .Art = artText, .Email = em})
|
|
End If
|
|
Next
|
|
End While
|
|
End Using
|
|
End Using
|
|
End Using
|
|
Catch
|
|
End Try
|
|
End Sub
|
|
|
|
Private Function ResolveMailArtLabel(artId As Integer) As String
|
|
Select Case artId
|
|
Case 1
|
|
Return "Ankunft"
|
|
Case 2
|
|
Return "Freigabe"
|
|
Case 3
|
|
Return "Ankunft Export"
|
|
Case 4
|
|
Return "Freigabe Export"
|
|
Case 5
|
|
Return "Status"
|
|
Case Else
|
|
Return "Unbekannt"
|
|
End Select
|
|
End Function
|
|
|
|
Private Function ToIntSafe(value As Object) As Integer
|
|
Try
|
|
If value Is Nothing Then Return 0
|
|
Dim tmp As Integer = 0
|
|
If Integer.TryParse(value.ToString(), tmp) Then Return tmp
|
|
Catch
|
|
End Try
|
|
Return 0
|
|
End Function
|
|
|
|
Private Sub dgvKontaktEmails_CellDoubleClick(sender As Object, e As DataGridViewCellEventArgs) Handles dgvKontaktEmails.CellDoubleClick
|
|
If e.RowIndex < 0 OrElse e.RowIndex >= dgvKontaktEmails.Rows.Count Then Return
|
|
Dim emailObj = dgvKontaktEmails.Rows(e.RowIndex).Cells("colEmail").Value
|
|
Dim email = If(emailObj, "").ToString().Trim()
|
|
If email = "" Then Return
|
|
txtCustomerUploadEmail.Text = email
|
|
End Sub
|
|
|
|
Private Sub InitializeDocumentEditor()
|
|
RemoveHandler txtDocumentEditorName.TextChanged, AddressOf DocumentEditorInputChanged
|
|
AddHandler txtDocumentEditorName.TextChanged, AddressOf DocumentEditorInputChanged
|
|
RemoveHandler txtDocumentEditorInfo.TextChanged, AddressOf DocumentEditorInputChanged
|
|
AddHandler txtDocumentEditorInfo.TextChanged, AddressOf DocumentEditorInputChanged
|
|
|
|
EnsureAnhangsartenOptionsLoaded()
|
|
|
|
RemoveHandler cmbDocumentEditorAnhangsart.SelectedIndexChanged, AddressOf DocumentEditorAnhangsartChanged
|
|
cmbDocumentEditorAnhangsart.BeginUpdate()
|
|
cmbDocumentEditorAnhangsart.Items.Clear()
|
|
For Each optionItem In _anhangsartenOptions
|
|
cmbDocumentEditorAnhangsart.Items.Add(optionItem)
|
|
Next
|
|
cmbDocumentEditorAnhangsart.EndUpdate()
|
|
AddHandler cmbDocumentEditorAnhangsart.SelectedIndexChanged, AddressOf DocumentEditorAnhangsartChanged
|
|
|
|
ClearDocumentEditor()
|
|
End Sub
|
|
|
|
Private Sub SetupDynamicAnforderungCheckboxes()
|
|
_anforderungCheckboxes.Clear()
|
|
_anhangsartIdByCheckbox.Clear()
|
|
_backendBezeichnungByCodeId.Clear()
|
|
_selectedAnhangsartIdByCodeId.Clear()
|
|
_documentCustomNameByCodeId.Clear()
|
|
_documentBaseTextByCodeId.Clear()
|
|
_bereichByCodeId.Clear()
|
|
_selectedDocumentCodeId = 0
|
|
|
|
Dim dt As DataTable = Nothing
|
|
Try
|
|
dt = AvisoDAL.loadDataTableBySQL("SELECT [VermerkCodeId],[Bezeichnung],[FrontendBezeichnung],[AvisoAnhangsartId],[AnforderungBereich] FROM [VermerkeCodes] WHERE [Anforderung]=1 ORDER BY [Bezeichnung]")
|
|
Catch
|
|
Try
|
|
dt = AvisoDAL.loadDataTableBySQL("SELECT [VermerkCodeId],[Bezeichnung],[AvisoAnhangsartId],[AnforderungBereich] FROM [VermerkeCodes] WHERE [Anforderung]=1 ORDER BY [Bezeichnung]")
|
|
Catch
|
|
Return
|
|
End Try
|
|
End Try
|
|
|
|
If dt Is Nothing OrElse dt.Rows.Count = 0 Then Return
|
|
EnsureAnhangsartenOptionsLoaded()
|
|
flpDokumenteFehlenMain.Controls.Clear()
|
|
|
|
For Each row As DataRow In dt.Rows
|
|
Dim id As Integer
|
|
Try
|
|
id = CInt(row("VermerkCodeId"))
|
|
Catch
|
|
Continue For
|
|
End Try
|
|
|
|
Dim bezeichnung = If(IsDBNull(row("Bezeichnung")), "", CStr(row("Bezeichnung"))).Trim()
|
|
If bezeichnung = "" Then Continue For
|
|
_backendBezeichnungByCodeId(id) = bezeichnung
|
|
|
|
Dim frontendBezeichnung = bezeichnung
|
|
If dt.Columns.Contains("FrontendBezeichnung") Then
|
|
frontendBezeichnung = If(IsDBNull(row("FrontendBezeichnung")), "", CStr(row("FrontendBezeichnung"))).Trim()
|
|
If frontendBezeichnung = "" Then frontendBezeichnung = bezeichnung
|
|
End If
|
|
|
|
If bezeichnung.ToLowerInvariant().Contains("nicht leserlich") Then Continue For
|
|
|
|
Dim bereich As Integer = 0
|
|
Try
|
|
If Not IsDBNull(row("AnforderungBereich")) Then bereich = CInt(row("AnforderungBereich"))
|
|
Catch
|
|
End Try
|
|
_bereichByCodeId(id) = bereich
|
|
If bereich <> BereichDokumentMain Then Continue For
|
|
|
|
Dim cb As New CheckBox()
|
|
cb.Text = frontendBezeichnung
|
|
cb.Tag = id
|
|
cb.Margin = New Padding(0, 0, 4, 0)
|
|
cb.BackColor = Color.Transparent
|
|
cb.UseVisualStyleBackColor = False
|
|
ConfigureAnforderungCheckbox(cb, flpDokumenteFehlenMain)
|
|
AddHandler cb.CheckedChanged, AddressOf DynamicAnforderungCheckboxChanged
|
|
flpDokumenteFehlenMain.Controls.Add(cb)
|
|
|
|
Dim anhangsartId As Integer = 0
|
|
Try
|
|
If Not IsDBNull(row("AvisoAnhangsartId")) Then anhangsartId = CInt(row("AvisoAnhangsartId"))
|
|
Catch
|
|
End Try
|
|
_anhangsartIdByCheckbox(cb) = anhangsartId
|
|
If Not _documentCustomNameByCodeId.ContainsKey(id) Then
|
|
_documentCustomNameByCodeId(id) = GetAnhangsartDisplayTextById(anhangsartId)
|
|
End If
|
|
|
|
_anforderungCheckboxes.Add(cb)
|
|
Next
|
|
End Sub
|
|
|
|
Private Sub ConfigureAnforderungCheckbox(cb As CheckBox, container As Control)
|
|
cb.AutoSize = False
|
|
cb.Height = 18
|
|
Dim usableWidth = Math.Max(120, container.Width - 20)
|
|
Dim cbWidth = CInt(Math.Floor((usableWidth - 4) / 3))
|
|
cb.Width = Math.Max(80, Math.Min(cbWidth, 220))
|
|
End Sub
|
|
|
|
Private Sub DocumentEditorInputChanged(sender As Object, e As EventArgs)
|
|
If _isLoadingDocumentEditor OrElse _selectedDocumentCodeId <= 0 Then Return
|
|
_documentCustomNameByCodeId(_selectedDocumentCodeId) = If(txtDocumentEditorName.Text, "").Trim()
|
|
_documentBaseTextByCodeId(_selectedDocumentCodeId) = If(txtDocumentEditorInfo.Text, "").Trim()
|
|
|
|
Dim tab = TryCast(flpDocumentTabs.Controls("tab_" & _selectedDocumentCodeId), Panel)
|
|
If tab Is Nothing Then Return
|
|
Dim lblText = TryCast(tab.Controls("lblText"), Label)
|
|
Dim lblClose = TryCast(tab.Controls("lblClose"), Label)
|
|
If lblText Is Nothing OrElse lblClose Is Nothing Then Return
|
|
lblText.Text = _documentCustomNameByCodeId(_selectedDocumentCodeId)
|
|
If lblText.Text = "" Then lblText.Text = "Unbenannt"
|
|
lblText.PerformLayout()
|
|
lblClose.Location = New Point(lblText.Right + 5, 5)
|
|
tab.Width = lblClose.Right + 5
|
|
End Sub
|
|
|
|
Private Sub DocumentEditorAnhangsartChanged(sender As Object, e As EventArgs)
|
|
If _isLoadingDocumentEditor OrElse _selectedDocumentCodeId <= 0 Then Return
|
|
Dim selected = TryCast(cmbDocumentEditorAnhangsart.SelectedItem, AnhangsartOption)
|
|
If selected Is Nothing Then Return
|
|
_selectedAnhangsartIdByCodeId(_selectedDocumentCodeId) = selected.Id
|
|
End Sub
|
|
|
|
Private Sub EnsureAnhangsartenOptionsLoaded()
|
|
If _anhangsartenOptions.Count > 0 Then Return
|
|
Dim dt As DataTable = Nothing
|
|
Try
|
|
dt = AvisoDAL.loadDataTableBySQL("SELECT [aa_id],[aa_bezeichnung],[aa_name] FROM [tblAvisoAnhangsarten] WHERE [aa_aktiv]=1 ORDER BY [aa_sort],[aa_bezeichnung]")
|
|
Catch
|
|
Return
|
|
End Try
|
|
If dt Is Nothing Then Return
|
|
|
|
For Each row As DataRow In dt.Rows
|
|
Dim id As Integer = 0
|
|
Try
|
|
id = CInt(row("aa_id"))
|
|
Catch
|
|
Continue For
|
|
End Try
|
|
If id <= 0 Then Continue For
|
|
|
|
Dim alreadyAdded As Boolean = False
|
|
For Each existing In _anhangsartenOptions
|
|
If existing.Id = id Then
|
|
alreadyAdded = True
|
|
Exit For
|
|
End If
|
|
Next
|
|
If alreadyAdded Then Continue For
|
|
|
|
Dim text = If(IsDBNull(row("aa_bezeichnung")), "", CStr(row("aa_bezeichnung"))).Trim()
|
|
If text = "" Then text = If(IsDBNull(row("aa_name")), "", CStr(row("aa_name"))).Trim()
|
|
If text = "" Then text = "#" & id.ToString()
|
|
_anhangsartenOptions.Add(New AnhangsartOption(id, text))
|
|
Next
|
|
End Sub
|
|
|
|
Private Sub SelectAnhangsartInEditor(anhangsartId As Integer)
|
|
cmbDocumentEditorAnhangsart.SelectedIndex = -1
|
|
If anhangsartId <= 0 Then Return
|
|
For i = 0 To cmbDocumentEditorAnhangsart.Items.Count - 1
|
|
Dim optionItem = TryCast(cmbDocumentEditorAnhangsart.Items(i), AnhangsartOption)
|
|
If optionItem IsNot Nothing AndAlso optionItem.Id = anhangsartId Then
|
|
cmbDocumentEditorAnhangsart.SelectedIndex = i
|
|
Exit For
|
|
End If
|
|
Next
|
|
End Sub
|
|
|
|
Private Function GetAnhangsartDisplayTextById(anhangsartId As Integer) As String
|
|
If anhangsartId <= 0 Then Return ""
|
|
EnsureAnhangsartenOptionsLoaded()
|
|
For Each optionItem In _anhangsartenOptions
|
|
If optionItem.Id = anhangsartId Then Return If(optionItem.Text, "").Trim()
|
|
Next
|
|
Return ""
|
|
End Function
|
|
|
|
Private Function TryGetCheckboxCodeId(cb As CheckBox, ByRef codeId As Integer) As Boolean
|
|
codeId = 0
|
|
If cb Is Nothing OrElse cb.Tag Is Nothing Then Return False
|
|
Return Integer.TryParse(cb.Tag.ToString(), codeId) AndAlso codeId > 0
|
|
End Function
|
|
|
|
Private Sub ClearDocumentEditor()
|
|
_selectedDocumentCodeId = 0
|
|
_isLoadingDocumentEditor = True
|
|
txtDocumentEditorName.Text = ""
|
|
txtDocumentEditorInfo.Text = ""
|
|
cmbDocumentEditorAnhangsart.SelectedIndex = -1
|
|
_isLoadingDocumentEditor = False
|
|
lblDocumentEditorStatus.Text = "Wählen Sie ein Dokument, um Name und Dokument Info anzupassen."
|
|
End Sub
|
|
|
|
Private Sub SelectDocument(codeId As Integer)
|
|
_selectedDocumentCodeId = codeId
|
|
If codeId <= 0 Then
|
|
ClearDocumentEditor()
|
|
SyncTabs()
|
|
Return
|
|
End If
|
|
|
|
Dim targetCb As CheckBox = Nothing
|
|
For Each cb In _anforderungCheckboxes
|
|
If cb.Tag IsNot Nothing AndAlso cb.Tag.ToString() = codeId.ToString() Then
|
|
targetCb = cb
|
|
Exit For
|
|
End If
|
|
Next
|
|
If targetCb Is Nothing Then Return
|
|
|
|
Dim anhangsartId = GetEffectiveAnhangsartId(targetCb)
|
|
Dim customName = ""
|
|
If _documentCustomNameByCodeId.ContainsKey(codeId) Then
|
|
customName = If(_documentCustomNameByCodeId(codeId), "").Trim()
|
|
Else
|
|
customName = GetAnhangsartDisplayTextById(anhangsartId)
|
|
_documentCustomNameByCodeId(codeId) = customName
|
|
End If
|
|
Dim baseText = GetDocumentBaseTextByCodeId(codeId)
|
|
|
|
_isLoadingDocumentEditor = True
|
|
txtDocumentEditorName.Text = customName
|
|
txtDocumentEditorInfo.Text = baseText
|
|
SelectAnhangsartInEditor(anhangsartId)
|
|
_isLoadingDocumentEditor = False
|
|
|
|
If anhangsartId > 0 Then _selectedAnhangsartIdByCodeId(codeId) = anhangsartId
|
|
lblDocumentEditorStatus.ForeColor = Color.FromArgb(0, 102, 153)
|
|
lblDocumentEditorStatus.Text = "Ausgewählt: " & If(targetCb.Text, "").Trim()
|
|
SyncTabs()
|
|
End Sub
|
|
|
|
Private Function CreateTab(codeId As Integer, text As String) As Panel
|
|
Dim pnl As New Panel()
|
|
pnl.Name = "tab_" & codeId
|
|
pnl.Tag = codeId
|
|
pnl.Height = 28
|
|
pnl.BackColor = Color.White
|
|
pnl.BorderStyle = BorderStyle.FixedSingle
|
|
pnl.Margin = New Padding(2, 4, 2, 0)
|
|
pnl.Cursor = Cursors.Hand
|
|
|
|
Dim lblText As New Label()
|
|
lblText.Name = "lblText"
|
|
lblText.Text = If(text = "", "Unbenannt", text)
|
|
lblText.AutoSize = True
|
|
lblText.Location = New Point(5, 5)
|
|
lblText.Tag = codeId
|
|
lblText.Cursor = Cursors.Hand
|
|
AddHandler lblText.Click, AddressOf Tab_Click
|
|
pnl.Controls.Add(lblText)
|
|
|
|
Dim lblClose As New Label()
|
|
lblClose.Name = "lblClose"
|
|
lblClose.Text = "X"
|
|
lblClose.AutoSize = True
|
|
lblClose.ForeColor = Color.Red
|
|
lblClose.Font = New Font("Microsoft Sans Serif", 8.25!, FontStyle.Bold)
|
|
lblClose.Cursor = Cursors.Hand
|
|
lblClose.Tag = codeId
|
|
AddHandler lblClose.Click, AddressOf TabClose_Click
|
|
pnl.Controls.Add(lblClose)
|
|
|
|
lblText.PerformLayout()
|
|
lblClose.Location = New Point(lblText.Right + 5, 5)
|
|
pnl.Width = lblClose.Right + 5
|
|
|
|
AddHandler pnl.Click, AddressOf Tab_Click
|
|
Return pnl
|
|
End Function
|
|
|
|
Private Sub SyncTabs()
|
|
flpDocumentTabs.SuspendLayout()
|
|
Dim requiredCodeIds As New List(Of Integer)
|
|
For Each cb In _anforderungCheckboxes
|
|
If cb.Checked Then
|
|
Dim codeId As Integer = 0
|
|
If Integer.TryParse(cb.Tag.ToString(), codeId) Then requiredCodeIds.Add(codeId)
|
|
End If
|
|
Next
|
|
|
|
Dim i = flpDocumentTabs.Controls.Count - 1
|
|
While i >= 0
|
|
Dim pnl = TryCast(flpDocumentTabs.Controls(i), Panel)
|
|
If pnl IsNot Nothing Then
|
|
Dim codeId = CInt(pnl.Tag)
|
|
If Not requiredCodeIds.Contains(codeId) Then
|
|
flpDocumentTabs.Controls.RemoveAt(i)
|
|
pnl.Dispose()
|
|
End If
|
|
End If
|
|
i -= 1
|
|
End While
|
|
|
|
For Each codeId In requiredCodeIds
|
|
Dim existingTab = TryCast(flpDocumentTabs.Controls("tab_" & codeId), Panel)
|
|
Dim text = If(_documentCustomNameByCodeId.ContainsKey(codeId), _documentCustomNameByCodeId(codeId), "")
|
|
If existingTab Is Nothing Then
|
|
existingTab = CreateTab(codeId, text)
|
|
flpDocumentTabs.Controls.Add(existingTab)
|
|
Else
|
|
Dim lblText = TryCast(existingTab.Controls("lblText"), Label)
|
|
Dim lblClose = TryCast(existingTab.Controls("lblClose"), Label)
|
|
If lblText IsNot Nothing AndAlso lblClose IsNot Nothing Then
|
|
lblText.Text = If(text = "", "Unbenannt", text)
|
|
lblText.PerformLayout()
|
|
lblClose.Location = New Point(lblText.Right + 5, 5)
|
|
existingTab.Width = lblClose.Right + 5
|
|
End If
|
|
End If
|
|
|
|
If codeId = _selectedDocumentCodeId Then
|
|
existingTab.BackColor = Color.White
|
|
existingTab.BorderStyle = BorderStyle.FixedSingle
|
|
existingTab.Height = 28
|
|
existingTab.Margin = New Padding(2, 2, 2, 0)
|
|
Else
|
|
existingTab.BackColor = Color.LightGray
|
|
existingTab.BorderStyle = BorderStyle.None
|
|
existingTab.Height = 25
|
|
existingTab.Margin = New Padding(2, 5, 2, 0)
|
|
End If
|
|
Next
|
|
|
|
flpDocumentTabs.ResumeLayout()
|
|
If _selectedDocumentCodeId > 0 AndAlso Not requiredCodeIds.Contains(_selectedDocumentCodeId) Then
|
|
If requiredCodeIds.Count > 0 Then
|
|
SelectDocument(requiredCodeIds(0))
|
|
Else
|
|
ClearDocumentEditor()
|
|
End If
|
|
ElseIf _selectedDocumentCodeId = 0 AndAlso requiredCodeIds.Count > 0 Then
|
|
SelectDocument(requiredCodeIds(0))
|
|
End If
|
|
End Sub
|
|
|
|
Private Sub Tab_Click(sender As Object, e As EventArgs)
|
|
Dim ctrl = TryCast(sender, Control)
|
|
If ctrl Is Nothing OrElse ctrl.Tag Is Nothing Then Return
|
|
Dim codeId As Integer = 0
|
|
If Integer.TryParse(ctrl.Tag.ToString(), codeId) Then SelectDocument(codeId)
|
|
End Sub
|
|
|
|
Private Sub TabClose_Click(sender As Object, e As EventArgs)
|
|
Dim ctrl = TryCast(sender, Control)
|
|
If ctrl Is Nothing OrElse ctrl.Tag Is Nothing Then Return
|
|
Dim codeId As Integer = 0
|
|
If Not Integer.TryParse(ctrl.Tag.ToString(), codeId) Then Return
|
|
For Each cb In _anforderungCheckboxes
|
|
If cb.Tag IsNot Nothing AndAlso cb.Tag.ToString() = codeId.ToString() Then
|
|
cb.Checked = False
|
|
Exit For
|
|
End If
|
|
Next
|
|
End Sub
|
|
|
|
Private Function GetEffectiveDocumentName(cb As CheckBox) As String
|
|
Dim codeId As Integer = 0
|
|
If TryGetCheckboxCodeId(cb, codeId) AndAlso _documentCustomNameByCodeId.ContainsKey(codeId) Then
|
|
Return If(_documentCustomNameByCodeId(codeId), "").Trim()
|
|
End If
|
|
Return ""
|
|
End Function
|
|
|
|
Private Function GetDocumentBaseText(cb As CheckBox) As String
|
|
Dim codeId As Integer = 0
|
|
If TryGetCheckboxCodeId(cb, codeId) Then Return GetDocumentBaseTextByCodeId(codeId)
|
|
Return DefaultDocumentBaseText
|
|
End Function
|
|
|
|
Private Function GetDocumentBaseTextByCodeId(codeId As Integer) As String
|
|
If codeId > 0 AndAlso _documentBaseTextByCodeId.ContainsKey(codeId) Then
|
|
Dim configuredBaseText = If(_documentBaseTextByCodeId(codeId), "").Trim()
|
|
If configuredBaseText <> "" Then Return configuredBaseText
|
|
End If
|
|
Return DefaultDocumentBaseText
|
|
End Function
|
|
|
|
Private Function GetEffectiveAnhangsartId(cb As CheckBox) As Integer
|
|
Dim codeId As Integer = 0
|
|
If TryGetCheckboxCodeId(cb, codeId) Then
|
|
If _selectedAnhangsartIdByCodeId.ContainsKey(codeId) AndAlso _selectedAnhangsartIdByCodeId(codeId) > 0 Then
|
|
Return _selectedAnhangsartIdByCodeId(codeId)
|
|
End If
|
|
End If
|
|
Dim defaultId As Integer = 0
|
|
If _anhangsartIdByCheckbox.TryGetValue(cb, defaultId) Then Return defaultId
|
|
Return 0
|
|
End Function
|
|
|
|
Private Function BuildUploadCustomText(baseText As String) As String
|
|
Dim effectiveBaseText = If(baseText, "").Trim()
|
|
If effectiveBaseText = "" Then effectiveBaseText = DefaultDocumentBaseText
|
|
Return effectiveBaseText
|
|
End Function
|
|
|
|
Private Function ValidateDocumentSelectionPayload(documentName As String, baseText As String, anhangsartId As Integer, ByRef validationError As String) As Boolean
|
|
validationError = ""
|
|
If anhangsartId <= 0 Then validationError = "ANHANGSART_ID_FEHLT" : Return False
|
|
documentName = If(documentName, "").Trim()
|
|
If documentName = "" Then validationError = "DOKUMENTNAME_FEHLT" : Return False
|
|
If documentName.Length > 120 Then validationError = "DOKUMENTNAME_ZU_LANG" : Return False
|
|
If If(baseText, "").Trim().Length > 500 Then validationError = "BASETEXT_ZU_LANG" : Return False
|
|
Return True
|
|
End Function
|
|
|
|
Private Sub DynamicAnforderungCheckboxChanged(sender As Object, e As EventArgs)
|
|
Dim cb = TryCast(sender, CheckBox)
|
|
If cb Is Nothing Then Return
|
|
If cb.Checked Then
|
|
Dim codeId As Integer = 0
|
|
If Integer.TryParse(cb.Tag.ToString(), codeId) Then SelectDocument(codeId)
|
|
Else
|
|
SyncTabs()
|
|
End If
|
|
End Sub
|
|
|
|
Private Function HasPrimaryDokumentSelection() As Boolean
|
|
For Each cb In _anforderungCheckboxes
|
|
Dim codeId As Integer = 0
|
|
If cb IsNot Nothing AndAlso cb.Checked AndAlso Integer.TryParse(If(cb.Tag, "").ToString(), codeId) Then
|
|
If _bereichByCodeId.ContainsKey(codeId) AndAlso _bereichByCodeId(codeId) = BereichDokumentMain Then
|
|
Return True
|
|
End If
|
|
End If
|
|
Next
|
|
Return False
|
|
End Function
|
|
|
|
Private Sub SonstChanged(sender As Object, e As EventArgs) Handles txtSonstigesDokumentFehlt.TextChanged
|
|
cbxSonstDok.Checked = (sender.text <> "")
|
|
End Sub
|
|
|
|
Private Sub btnVermerkSetzen_Click(sender As Object, e As EventArgs) Handles btnVermerkSetzen.Click
|
|
lblErrDokument.Visible = False
|
|
If Not HasPrimaryDokumentSelection() AndAlso Not cbxSonstDok.Checked AndAlso Not cbxNichtLeserlich.Checked Then
|
|
lblErrDokument.Visible = True
|
|
Exit Sub
|
|
End If
|
|
If cbxSonstDok.Checked AndAlso txtSonstigesDokumentFehlt.Text.Trim = "" Then
|
|
lblErrDokument.Visible = True
|
|
txtSonstigesDokumentFehlt.Focus()
|
|
Exit Sub
|
|
End If
|
|
DialogResult = DialogResult.OK
|
|
Close()
|
|
End Sub
|
|
|
|
Private Sub btnCustomerUploadLink_Click(sender As Object, e As EventArgs) Handles btnCustomerUploadLink.Click
|
|
Dim validityHours = CInt(nudCustomerUploadValidityHours.Value)
|
|
Dim config = GetCustomerPortalApiConfig()
|
|
If config Is Nothing Then Exit Sub
|
|
|
|
Dim jwtToken = ""
|
|
Dim authErr = ""
|
|
If Not TryGetCustomerPortalJwtToken(config, jwtToken, authErr) Then
|
|
MsgBox("Fehler bei Authentifizierung: " & authErr, vbExclamation)
|
|
Exit Sub
|
|
End If
|
|
|
|
Dim anhangsartenMap As Dictionary(Of String, Integer) = Nothing
|
|
Dim anhangsartenErr = ""
|
|
If Not TryGetCustomerPortalAnhangsartenMap(config, jwtToken, anhangsartenMap, anhangsartenErr) Then
|
|
MsgBox("Fehler beim Laden der Dokumentarten: " & anhangsartenErr, vbExclamation)
|
|
Exit Sub
|
|
End If
|
|
|
|
Dim requirements = BuildCustomerUploadRequirements(anhangsartenMap)
|
|
If requirements Is Nothing Then Exit Sub
|
|
If requirements.Count = 0 Then
|
|
MsgBox("Bitte mindestens ein Dokument im Bereich 'Dokument(e) fehlen' auswählen.", vbInformation)
|
|
Label20.ForeColor = Color.Red
|
|
Label20.Text = "Für den Upload-Link muss mindestens ein Dokument ausgewählt sein."
|
|
Exit Sub
|
|
End If
|
|
Label20.ForeColor = Color.FromArgb(0, 102, 153)
|
|
Label20.Text = "Bitte zuerst Dokument(e) oben auswählen."
|
|
|
|
Cursor = Cursors.WaitCursor
|
|
Try
|
|
Dim linkUrl = ""
|
|
Dim errorCode = ""
|
|
If Not TryCreateCustomerUploadLinkMultiWithoutEmail(config, requirements, validityHours, linkUrl, errorCode) Then
|
|
MsgBox("Fehler beim Erzeugen des Upload-Links: " & errorCode, vbExclamation)
|
|
Exit Sub
|
|
End If
|
|
If linkUrl <> "" Then
|
|
Clipboard.SetText(linkUrl)
|
|
MsgBox("Upload-Link wurde in die Zwischenablage kopiert.", vbInformation)
|
|
Else
|
|
MsgBox("Upload-Link konnte nicht aus der Antwort gelesen werden.", vbExclamation)
|
|
End If
|
|
Finally
|
|
Cursor = Cursors.Default
|
|
End Try
|
|
End Sub
|
|
|
|
Private Sub btnCustomerUploadEmail_Click(sender As Object, e As EventArgs) Handles btnCustomerUploadEmail.Click
|
|
Dim recipient = If(txtCustomerUploadEmail.Text, "").Trim()
|
|
If recipient = "" Then MsgBox("Bitte eine E-Mail-Adresse eingeben.", vbInformation) : txtCustomerUploadEmail.Focus() : Exit Sub
|
|
Try
|
|
Dim addr As New MailAddress(recipient)
|
|
recipient = addr.Address
|
|
Catch
|
|
MsgBox("E-Mail-Adresse ist ungültig.", vbInformation)
|
|
txtCustomerUploadEmail.Focus()
|
|
Exit Sub
|
|
End Try
|
|
|
|
Dim emailText = If(txtCustomerUploadEmailText.Text, "").Trim()
|
|
If emailText = "" Then MsgBox("Bitte den Text eintragen.", vbInformation) : txtCustomerUploadEmailText.Focus() : Exit Sub
|
|
|
|
Dim validityHours = CInt(nudCustomerUploadValidityHours.Value)
|
|
Dim language = If(TryCast(cmbCustomerUploadLanguage.SelectedItem, String), If(cmbCustomerUploadLanguage.Text, "").Trim())
|
|
language = language.ToLowerInvariant()
|
|
If language <> "de" AndAlso language <> "en" AndAlso language <> "tr" AndAlso language <> "sr" AndAlso language <> "bg" Then language = "de"
|
|
|
|
Dim config = GetCustomerPortalApiConfig()
|
|
If config Is Nothing Then Exit Sub
|
|
|
|
Dim jwtToken = ""
|
|
Dim authErr = ""
|
|
If Not TryGetCustomerPortalJwtToken(config, jwtToken, authErr) Then MsgBox("Fehler bei Authentifizierung: " & authErr, vbExclamation) : Exit Sub
|
|
|
|
Dim anhangsartenMap As Dictionary(Of String, Integer) = Nothing
|
|
Dim anhangsartenErr = ""
|
|
If Not TryGetCustomerPortalAnhangsartenMap(config, jwtToken, anhangsartenMap, anhangsartenErr) Then MsgBox("Fehler beim Laden der Dokumentarten: " & anhangsartenErr, vbExclamation) : Exit Sub
|
|
|
|
Dim requirements = BuildCustomerUploadRequirements(anhangsartenMap)
|
|
If requirements Is Nothing Then Exit Sub
|
|
If requirements.Count = 0 Then
|
|
MsgBox("Bitte mindestens ein Dokument im Bereich 'Dokument(e) fehlen' auswählen.", vbInformation)
|
|
Label20.ForeColor = Color.Red
|
|
Label20.Text = "Für den Upload-Link muss mindestens ein Dokument ausgewählt sein."
|
|
Exit Sub
|
|
End If
|
|
Label20.ForeColor = Color.FromArgb(0, 102, 153)
|
|
Label20.Text = "Bitte zuerst Dokument(e) oben auswählen."
|
|
|
|
Cursor = Cursors.WaitCursor
|
|
Try
|
|
Dim linkUrl = ""
|
|
Dim errorCode = ""
|
|
If Not TryRequestCustomerUploadLinkMultiWithEmail(config, requirements, recipient, emailText, language, validityHours, linkUrl, errorCode) Then
|
|
MsgBox("Fehler beim Versand der E-Mail: " & errorCode, vbExclamation)
|
|
Exit Sub
|
|
End If
|
|
If linkUrl <> "" Then Clipboard.SetText(linkUrl)
|
|
MsgBox("E-Mail wurde ausgelöst.", vbInformation)
|
|
Finally
|
|
Cursor = Cursors.Default
|
|
End Try
|
|
End Sub
|
|
|
|
Public Function BuildState() As DokumentanforderungState
|
|
Dim result As New DokumentanforderungState()
|
|
result.SelectedCodeIds = New List(Of Integer)
|
|
For Each cb In _anforderungCheckboxes
|
|
Dim codeId As Integer = 0
|
|
If cb.Checked AndAlso Integer.TryParse(If(cb.Tag, "").ToString(), codeId) Then result.SelectedCodeIds.Add(codeId)
|
|
Next
|
|
result.SelectedAnhangsartIdByCodeId = New Dictionary(Of Integer, Integer)(_selectedAnhangsartIdByCodeId)
|
|
result.DocumentCustomNameByCodeId = New Dictionary(Of Integer, String)(_documentCustomNameByCodeId)
|
|
result.DocumentBaseTextByCodeId = New Dictionary(Of Integer, String)(_documentBaseTextByCodeId)
|
|
result.SonstDokChecked = cbxSonstDok.Checked
|
|
result.SonstigesDokumentName = If(txtSonstigesDokumentFehlt.Text, "").Trim()
|
|
result.NichtLeserlichChecked = cbxNichtLeserlich.Checked
|
|
result.CustomerUploadEmail = If(txtCustomerUploadEmail.Text, "").Trim()
|
|
result.CustomerUploadLanguage = If(TryCast(cmbCustomerUploadLanguage.SelectedItem, String), If(cmbCustomerUploadLanguage.Text, "").Trim())
|
|
result.CustomerUploadEmailText = If(txtCustomerUploadEmailText.Text, "").Trim()
|
|
result.CustomerUploadValidityHours = CInt(nudCustomerUploadValidityHours.Value)
|
|
Return result
|
|
End Function
|
|
|
|
Private Sub ApplyStateToUi(state As DokumentanforderungState)
|
|
If state Is Nothing Then Return
|
|
_selectedAnhangsartIdByCodeId.Clear()
|
|
_documentCustomNameByCodeId.Clear()
|
|
_documentBaseTextByCodeId.Clear()
|
|
For Each kvp In state.SelectedAnhangsartIdByCodeId
|
|
_selectedAnhangsartIdByCodeId(kvp.Key) = kvp.Value
|
|
Next
|
|
For Each kvp In state.DocumentCustomNameByCodeId
|
|
_documentCustomNameByCodeId(kvp.Key) = kvp.Value
|
|
Next
|
|
For Each kvp In state.DocumentBaseTextByCodeId
|
|
_documentBaseTextByCodeId(kvp.Key) = kvp.Value
|
|
Next
|
|
|
|
For Each cb In _anforderungCheckboxes
|
|
Dim codeId As Integer = 0
|
|
cb.Checked = Integer.TryParse(If(cb.Tag, "").ToString(), codeId) AndAlso state.SelectedCodeIds.Contains(codeId)
|
|
Next
|
|
|
|
cbxSonstDok.Checked = state.SonstDokChecked
|
|
txtSonstigesDokumentFehlt.Text = If(state.SonstigesDokumentName, "")
|
|
cbxNichtLeserlich.Checked = state.NichtLeserlichChecked
|
|
txtCustomerUploadEmail.Text = If(state.CustomerUploadEmail, "")
|
|
txtCustomerUploadEmailText.Text = If(state.CustomerUploadEmailText, "Bitte laden Sie die angeforderten Dokumente über den Link hoch.")
|
|
nudCustomerUploadValidityHours.Value = Math.Max(nudCustomerUploadValidityHours.Minimum, Math.Min(nudCustomerUploadValidityHours.Maximum, state.CustomerUploadValidityHours))
|
|
|
|
Dim language = If(state.CustomerUploadLanguage, "").Trim().ToLowerInvariant()
|
|
Dim idx = cmbCustomerUploadLanguage.Items.IndexOf(language)
|
|
If idx >= 0 Then cmbCustomerUploadLanguage.SelectedIndex = idx
|
|
SyncTabs()
|
|
End Sub
|
|
|
|
Private Class CustomerPortalApiConfig
|
|
Public Property BaseUrl As String
|
|
Public Property Username As String
|
|
Public Property Password As String
|
|
End Class
|
|
|
|
Private Function GetCustomerPortalApiConfig() As CustomerPortalApiConfig
|
|
Dim baseUrl = If(System.Environment.GetEnvironmentVariable("AVISO_CUSTOMERPORTAL_API_BASEURL"), "").Trim()
|
|
If baseUrl = "" Then baseUrl = If(ConfigurationManager.AppSettings("CustomerPortalApiBaseUrl"), "").Trim()
|
|
If baseUrl = "" Then baseUrl = "https://login.server.verag.ag"
|
|
Dim username = If(System.Environment.GetEnvironmentVariable("AVISO_CUSTOMERPORTAL_API_USERNAME"), "").Trim()
|
|
If username = "" Then username = If(ConfigurationManager.AppSettings("CustomerPortalApiUsername"), "").Trim()
|
|
Dim password = If(System.Environment.GetEnvironmentVariable("AVISO_CUSTOMERPORTAL_API_PASSWORD"), "").Trim()
|
|
If password = "" Then password = If(ConfigurationManager.AppSettings("CustomerPortalApiPassword"), "").Trim()
|
|
If username = "" OrElse password = "" Then
|
|
MsgBox("CustomerPortalApiUsername/CustomerPortalApiPassword fehlt in App.config (oder ENV: AVISO_CUSTOMERPORTAL_API_USERNAME / AVISO_CUSTOMERPORTAL_API_PASSWORD).", vbExclamation)
|
|
Return Nothing
|
|
End If
|
|
Return New CustomerPortalApiConfig With {.BaseUrl = baseUrl, .Username = username, .Password = password}
|
|
End Function
|
|
|
|
Private Function TryGetCustomerPortalJwtToken(ByVal config As CustomerPortalApiConfig, ByRef jwtToken As String, ByRef errorCode As String) As Boolean
|
|
jwtToken = ""
|
|
errorCode = ""
|
|
If _customerPortalJwtToken <> "" Then
|
|
If _customerPortalJwtExpUtc = DateTime.MinValue OrElse DateTime.UtcNow < _customerPortalJwtExpUtc.AddMinutes(-1) Then
|
|
jwtToken = _customerPortalJwtToken
|
|
Return True
|
|
End If
|
|
End If
|
|
|
|
Dim url = config.BaseUrl.TrimEnd("/"c) & "/api/auth/login"
|
|
Dim payload As New Dictionary(Of String, Object) From {{"username", config.Username}, {"password", config.Password}}
|
|
Dim jsonBody = JsonConvert.SerializeObject(payload)
|
|
Try
|
|
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
|
|
Dim request = CType(WebRequest.Create(url), HttpWebRequest)
|
|
request.Method = "POST"
|
|
request.ContentType = "application/json"
|
|
request.Accept = "application/json"
|
|
request.Timeout = 15000
|
|
Using requestStream = request.GetRequestStream()
|
|
Using writer As New StreamWriter(requestStream, Encoding.UTF8)
|
|
writer.Write(jsonBody)
|
|
End Using
|
|
End Using
|
|
Using response = CType(request.GetResponse(), HttpWebResponse)
|
|
Using reader As New StreamReader(response.GetResponseStream(), Encoding.UTF8)
|
|
Dim respText = reader.ReadToEnd()
|
|
Dim jobj = JObject.Parse(respText)
|
|
Dim token = (If(jobj("token"), New JValue(""))).ToString().Trim()
|
|
If token = "" Then errorCode = "TOKEN_MISSING" : Return False
|
|
_customerPortalJwtToken = token
|
|
_customerPortalJwtExpUtc = ExtractJwtExpUtcOrMin(token)
|
|
jwtToken = token
|
|
Return True
|
|
End Using
|
|
End Using
|
|
Catch ex As WebException
|
|
errorCode = ReadWebExceptionMessage(ex)
|
|
Return False
|
|
Catch ex As Exception
|
|
errorCode = ex.Message
|
|
Return False
|
|
End Try
|
|
End Function
|
|
|
|
Private Function ExtractJwtExpUtcOrMin(ByVal jwt As String) As DateTime
|
|
Try
|
|
Dim parts = If(jwt, "").Split("."c)
|
|
If parts.Length < 2 Then Return DateTime.MinValue
|
|
Dim payloadJson = Encoding.UTF8.GetString(Base64UrlDecode(parts(1)))
|
|
Dim jobj = JObject.Parse(payloadJson)
|
|
Dim expToken = jobj("exp")
|
|
If expToken Is Nothing Then Return DateTime.MinValue
|
|
Dim expSeconds As Long
|
|
If Long.TryParse(expToken.ToString(), expSeconds) Then Return DateTimeOffset.FromUnixTimeSeconds(expSeconds).UtcDateTime
|
|
Catch
|
|
End Try
|
|
Return DateTime.MinValue
|
|
End Function
|
|
|
|
Private Function Base64UrlDecode(ByVal input As String) As Byte()
|
|
Dim s = If(input, "").Replace("-"c, "+"c).Replace("_"c, "/"c)
|
|
Select Case (s.Length Mod 4)
|
|
Case 2
|
|
s &= "=="
|
|
Case 3
|
|
s &= "="
|
|
End Select
|
|
Return Convert.FromBase64String(s)
|
|
End Function
|
|
|
|
Private Function BuildCustomerUploadRequirements(ByVal anhangsartenMap As Dictionary(Of String, Integer)) As List(Of Object)
|
|
Dim requirements As New List(Of Object)
|
|
Dim missing As New List(Of String)
|
|
|
|
For Each cb In _anforderungCheckboxes
|
|
If cb Is Nothing OrElse Not cb.Checked Then Continue For
|
|
Dim documentType = GetEffectiveDocumentName(cb)
|
|
If documentType = "" Then Continue For
|
|
Dim baseText = GetDocumentBaseText(cb)
|
|
Dim validationError = ""
|
|
Dim anhangsartId = GetEffectiveAnhangsartId(cb)
|
|
If anhangsartId <= 0 Then missing.Add(documentType) : Continue For
|
|
If Not ValidateDocumentSelectionPayload(documentType, baseText, anhangsartId, validationError) Then
|
|
MsgBox("Ungültige Eingabe für Dokument '" & documentType & "': " & validationError, vbInformation)
|
|
Return Nothing
|
|
End If
|
|
AddCustomerUploadRequirementByAnhangsartId(requirements, documentType, anhangsartId, BuildUploadCustomText(baseText))
|
|
Next
|
|
|
|
If cbxSonstDok.Checked Then
|
|
Dim custom = If(txtSonstigesDokumentFehlt.Text, "").Trim()
|
|
If custom = "" Then
|
|
MsgBox("Bitte den Dokumentnamen eintragen.", vbInformation)
|
|
txtSonstigesDokumentFehlt.Focus()
|
|
Return Nothing
|
|
End If
|
|
AddCustomerUploadRequirement(requirements, missing, anhangsartenMap, True, custom, {"SONSTIGES", "DOKUMENT"}, "Bitte " & custom & " hochladen.", True)
|
|
End If
|
|
|
|
If missing.Count > 0 Then
|
|
MsgBox("Anhangsarten nicht gefunden: " & String.Join(", ", missing), vbExclamation)
|
|
Return Nothing
|
|
End If
|
|
Return requirements
|
|
End Function
|
|
|
|
Private Sub AddCustomerUploadRequirementByAnhangsartId(ByVal requirements As List(Of Object), ByVal documentType As String, ByVal anhangsartId As Integer, ByVal customText As String)
|
|
If requirements Is Nothing OrElse anhangsartId <= 0 Then Exit Sub
|
|
requirements.Add(New Dictionary(Of String, Object) From {{"documentType", documentType}, {"anhangsartId", anhangsartId}, {"customText", customText}})
|
|
End Sub
|
|
|
|
Private Sub AddCustomerUploadRequirement(ByVal requirements As List(Of Object), ByVal missing As List(Of String), ByVal anhangsartenMap As Dictionary(Of String, Integer), ByVal isSelected As Boolean, ByVal documentType As String, ByVal anhangsartenCandidates As String(), ByVal customText As String, ByVal allowCustomFilename As Boolean)
|
|
If Not isSelected Then Exit Sub
|
|
Dim anhangsartId = ResolveAnhangsartId(anhangsartenCandidates, anhangsartenMap)
|
|
If anhangsartId <= 0 AndAlso allowCustomFilename AndAlso _customerPortalCustomFilenameAnhangsartId > 0 Then anhangsartId = _customerPortalCustomFilenameAnhangsartId
|
|
If anhangsartId <= 0 Then missing.Add(documentType) : Exit Sub
|
|
requirements.Add(New Dictionary(Of String, Object) From {{"documentType", documentType}, {"anhangsartId", anhangsartId}, {"customText", customText}})
|
|
End Sub
|
|
|
|
Private Function ResolveAnhangsartId(ByVal candidates As IEnumerable(Of String), ByVal anhangsartenMap As Dictionary(Of String, Integer)) As Integer
|
|
If candidates Is Nothing OrElse anhangsartenMap Is Nothing Then Return -1
|
|
For Each c In candidates
|
|
Dim key = If(c, "").Trim()
|
|
If key = "" Then Continue For
|
|
Dim id As Integer
|
|
If anhangsartenMap.TryGetValue(key.ToUpperInvariant(), id) Then Return id
|
|
Next
|
|
Return -1
|
|
End Function
|
|
|
|
Private Function TryGetCustomerPortalAnhangsartenMap(ByVal config As CustomerPortalApiConfig, ByVal jwtToken As String, ByRef anhangsartenMap As Dictionary(Of String, Integer), ByRef errorCode As String) As Boolean
|
|
anhangsartenMap = Nothing
|
|
errorCode = ""
|
|
If _customerPortalAnhangsartenMap IsNot Nothing AndAlso _customerPortalAnhangsartenFetchedUtc <> DateTime.MinValue Then
|
|
If DateTime.UtcNow < _customerPortalAnhangsartenFetchedUtc.AddMinutes(30) Then
|
|
anhangsartenMap = _customerPortalAnhangsartenMap
|
|
Return True
|
|
End If
|
|
End If
|
|
|
|
Dim url = config.BaseUrl.TrimEnd("/"c) & "/api/AvisoUpload/anhangsarten/all"
|
|
Dim request = CType(WebRequest.Create(url), HttpWebRequest)
|
|
request.Method = "GET"
|
|
request.Accept = "application/json"
|
|
request.Timeout = 15000
|
|
request.Headers(HttpRequestHeader.Authorization) = "Bearer " & jwtToken
|
|
Try
|
|
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
|
|
Using response = CType(request.GetResponse(), HttpWebResponse)
|
|
Using reader As New StreamReader(response.GetResponseStream(), Encoding.UTF8)
|
|
Dim respText = If(reader.ReadToEnd(), "").Trim()
|
|
Dim map As New Dictionary(Of String, Integer)(StringComparer.OrdinalIgnoreCase)
|
|
Dim customFilenameId As Integer = -1
|
|
If respText.StartsWith("[") Then
|
|
Dim arr = JArray.Parse(respText)
|
|
For Each t In arr
|
|
Dim id = 0
|
|
If t("id") IsNot Nothing AndAlso Integer.TryParse(t("id").ToString(), id) Then
|
|
Dim name = (If(t("name"), New JValue(""))).ToString().Trim()
|
|
Dim bez = (If(t("bezeichnung"), New JValue(""))).ToString().Trim()
|
|
If name <> "" Then map(name.ToUpperInvariant()) = id
|
|
If bez <> "" Then map(bez.ToUpperInvariant()) = id
|
|
If id = 24 Then customFilenameId = 24
|
|
End If
|
|
Next
|
|
ElseIf respText.StartsWith("{") Then
|
|
Dim jobj = JObject.Parse(respText)
|
|
errorCode = (If(jobj("message"), If(jobj("code"), New JValue("ANHANGSARTEN_LOAD_FAILED")))).ToString()
|
|
Return False
|
|
Else
|
|
errorCode = "ANHANGSARTEN_INVALID_RESPONSE"
|
|
Return False
|
|
End If
|
|
If map.Count = 0 Then errorCode = "ANHANGSARTEN_EMPTY" : Return False
|
|
_customerPortalCustomFilenameAnhangsartId = customFilenameId
|
|
_customerPortalAnhangsartenMap = map
|
|
_customerPortalAnhangsartenFetchedUtc = DateTime.UtcNow
|
|
anhangsartenMap = map
|
|
Return True
|
|
End Using
|
|
End Using
|
|
Catch ex As WebException
|
|
errorCode = ReadWebExceptionMessage(ex)
|
|
Return False
|
|
Catch ex As Exception
|
|
errorCode = ex.Message
|
|
Return False
|
|
End Try
|
|
End Function
|
|
|
|
Private Function TryCreateCustomerUploadLinkMultiWithoutEmail(ByVal config As CustomerPortalApiConfig, ByVal requirements As List(Of Object), ByVal validityHours As Integer, ByRef linkUrl As String, ByRef errorCode As String) As Boolean
|
|
linkUrl = ""
|
|
errorCode = ""
|
|
Dim url = config.BaseUrl.TrimEnd("/"c) & "/api/PublicCustomerDocuments/create-upload-link-multi"
|
|
Dim payload As New Dictionary(Of String, Object) From {{"avisoId", AvisoID}, {"validityHours", validityHours}, {"requirements", requirements}}
|
|
If SendungID > 0 Then payload("sendungsId") = SendungID
|
|
Dim jsonBody = JsonConvert.SerializeObject(payload)
|
|
Dim jwtToken = ""
|
|
Dim authErr = ""
|
|
If Not TryGetCustomerPortalJwtToken(config, jwtToken, authErr) Then errorCode = authErr : Return False
|
|
Return TryPostCustomerPortalJson(url, jwtToken, jsonBody, linkUrl, errorCode)
|
|
End Function
|
|
|
|
Private Function TryRequestCustomerUploadLinkMultiWithEmail(ByVal config As CustomerPortalApiConfig, ByVal requirements As List(Of Object), ByVal recipientEmail As String, ByVal emailText As String, ByVal language As String, ByVal validityHours As Integer, ByRef linkUrl As String, ByRef errorCode As String) As Boolean
|
|
linkUrl = ""
|
|
errorCode = ""
|
|
Dim url = config.BaseUrl.TrimEnd("/"c) & "/api/PublicCustomerDocuments/request-upload-link-multi"
|
|
If language Is Nothing OrElse language.Trim() = "" Then language = "de"
|
|
Dim payload As New Dictionary(Of String, Object) From {{"avisoId", AvisoID}, {"emailText", emailText}, {"language", language}, {"validityHours", validityHours}, {"requirements", requirements}}
|
|
If SendungID > 0 Then payload("sendungsId") = SendungID
|
|
payload("recipientEmail") = recipientEmail
|
|
Dim jsonBody = JsonConvert.SerializeObject(payload)
|
|
Dim jwtToken = ""
|
|
Dim authErr = ""
|
|
If Not TryGetCustomerPortalJwtToken(config, jwtToken, authErr) Then errorCode = authErr : Return False
|
|
Return TryPostCustomerPortalJson(url, jwtToken, jsonBody, linkUrl, errorCode)
|
|
End Function
|
|
|
|
Private Function TryPostCustomerPortalJson(ByVal url As String, ByVal jwtToken As String, ByVal jsonBody As String, ByRef linkUrl As String, ByRef errorCode As String) As Boolean
|
|
Dim request = CType(WebRequest.Create(url), HttpWebRequest)
|
|
request.Method = "POST"
|
|
request.ContentType = "application/json"
|
|
request.Accept = "application/json"
|
|
request.Timeout = 15000
|
|
request.Headers(HttpRequestHeader.Authorization) = "Bearer " & jwtToken
|
|
Using requestStream = request.GetRequestStream()
|
|
Using writer As New StreamWriter(requestStream, Encoding.UTF8)
|
|
writer.Write(jsonBody)
|
|
End Using
|
|
End Using
|
|
Using response = CType(request.GetResponse(), HttpWebResponse)
|
|
Using reader As New StreamReader(response.GetResponseStream(), Encoding.UTF8)
|
|
Dim respText = reader.ReadToEnd()
|
|
Dim jobj = JObject.Parse(respText)
|
|
Dim result = (If(jobj("result"), New JValue(""))).ToString()
|
|
If String.Equals(result, "pass", StringComparison.OrdinalIgnoreCase) Then
|
|
Dim link = (If(jobj.SelectToken("data.linkUrl"), New JValue(""))).ToString()
|
|
If link = "" Then link = (If(jobj.SelectToken("linkUrl"), New JValue(""))).ToString()
|
|
linkUrl = link
|
|
Return True
|
|
End If
|
|
errorCode = (If(jobj("message"), New JValue("UNKNOWN_ERROR"))).ToString()
|
|
Return False
|
|
End Using
|
|
End Using
|
|
End Function
|
|
|
|
Private Function ReadWebExceptionMessage(ByVal ex As WebException) As String
|
|
Dim body = ""
|
|
Try
|
|
If ex.Response IsNot Nothing Then
|
|
Using respStream = ex.Response.GetResponseStream()
|
|
If respStream IsNot Nothing Then
|
|
Using reader As New StreamReader(respStream, Encoding.UTF8)
|
|
body = reader.ReadToEnd()
|
|
End Using
|
|
End If
|
|
End Using
|
|
End If
|
|
Catch
|
|
End Try
|
|
If body <> "" Then
|
|
Try
|
|
Dim jobj = JObject.Parse(body)
|
|
Return (If(jobj("message"), New JValue(ex.Message))).ToString()
|
|
Catch
|
|
Return ex.Message
|
|
End Try
|
|
End If
|
|
Return ex.Message
|
|
End Function
|
|
|
|
Private Class AnhangsartOption
|
|
Public ReadOnly Id As Integer
|
|
Public ReadOnly Text As String
|
|
Public Sub New(id As Integer, text As String)
|
|
Me.Id = id
|
|
Me.Text = If(text, "").Trim()
|
|
End Sub
|
|
Public Overrides Function ToString() As String
|
|
Return Text
|
|
End Function
|
|
End Class
|
|
|
|
Private Class KontaktEmailRow
|
|
Public Property Rolle As String
|
|
Public Property Art As String
|
|
Public Property Email As String
|
|
End Class
|
|
|
|
Public Class DokumentanforderungState
|
|
Public Property SelectedCodeIds As New List(Of Integer)
|
|
Public Property SelectedAnhangsartIdByCodeId As New Dictionary(Of Integer, Integer)
|
|
Public Property DocumentCustomNameByCodeId As New Dictionary(Of Integer, String)
|
|
Public Property DocumentBaseTextByCodeId As New Dictionary(Of Integer, String)
|
|
Public Property SonstDokChecked As Boolean
|
|
Public Property SonstigesDokumentName As String
|
|
Public Property NichtLeserlichChecked As Boolean
|
|
Public Property CustomerUploadEmail As String
|
|
Public Property CustomerUploadLanguage As String = "de"
|
|
Public Property CustomerUploadEmailText As String = "Bitte laden Sie die angeforderten Dokumente über den Link hoch."
|
|
Public Property CustomerUploadValidityHours As Integer = 168
|
|
End Class
|
|
End Class
|