MultiTool/MultiTool.Form/frmImportMain.vb
2021-10-29 10:37:04 +02:00

436 lines
17 KiB
VB.net

Imports System.ComponentModel
Imports System.IO
Imports System.Net.Http
Imports System.Xml
Imports DevExpress.Utils.Behaviors.Common
Imports DevExpress.XtraGrid
Imports DevExpress.XtraGrid.Views.Grid
Imports DigitalData.Controls.SQLConfig
Imports DigitalData.GUIs.Common
Imports DigitalData.Modules.Config
Imports DigitalData.Modules.Database
Imports DigitalData.Modules.Logging
Imports MultiTool.Shared
Imports MultiTool.Shared.Documents
Imports MultiTool.Shared.Schemas
Imports MultiTool.Shared.Winline
Public Class frmImportMain
Private LogConfig As LogConfig
Private Logger As Logger
Private ConfigManager As ConfigManager(Of MultiTool.Shared.Config)
Private Database As MSSQLServer
Private Winline As Data
Private FileEx As DigitalData.Modules.Filesystem.File
Private WebService As WebService
Private PositionData As PositionData
Private DocumentLoader As Documents.DocumentLoader
Private SchemaLoader As Schemas.SchemaLoader
Private Message As Message
Private Grids As List(Of GridControl)
Private GridLoader As GridLoader
Private GridBuilder As GridBuilder
Private CurrentSchemaName As String
Private CurrentSchema As Schema
Private CurrentDocument As Document
Public Sub New()
InitializeComponent()
BehaviorManager.Attach(Of PersistenceBehavior)(Me, AddressOf LoadPersistenceSettings)
End Sub
Protected Overrides Sub OnLoad(e As EventArgs)
GridControlFiles.ForceInitialize()
MyBase.OnLoad(e)
End Sub
Private Sub LoadPersistenceSettings(pBehaviour As PersistenceBehavior)
pBehaviour.Properties.StoreChildLayouts = DevExpress.Utils.DefaultBoolean.True
pBehaviour.Properties.Storage = Storage.File
pBehaviour.Properties.Path = Application.UserAppDataPath
End Sub
Private Sub frmImportMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Try
txtVersion.Caption = String.Format(txtVersion.Caption, Application.ProductVersion)
LogConfig = New LogConfig(LogConfig.PathType.AppData, Nothing, Nothing, "Digital Data", "EDI Document Importer")
Logger = LogConfig.GetLogger()
Logger.Info("EDI Document Importer, Version [{0}]", Application.ProductVersion)
ConfigManager = New ConfigManager(Of Config)(LogConfig,
Application.UserAppDataPath,
Application.CommonAppDataPath,
Application.StartupPath)
Message = New Message(LogConfig)
GridBuilder = New GridBuilder(GridViewFiles)
GridBuilder.WithDefaults.WithClipboardHandler()
FileEx = New DigitalData.Modules.Filesystem.File(LogConfig)
' If ConnectionString does not exist, show SQL Config Form
If ConfigManager.Config.ConnectionString = String.Empty Then
Dim oForm As New frmSQLConfig(LogConfig) With {
.FormTitle = "EDI Document Importer"
}
Dim oResult = oForm.ShowDialog()
If oResult = DialogResult.OK Then
ConfigManager.Config.ConnectionString = oForm.ConnectionString
ConfigManager.Save()
End If
End If
' Initialize Database
Dim oConnectionString = MSSQLServer.DecryptConnectionString(ConfigManager.Config.ConnectionString)
Database = New MSSQLServer(LogConfig, oConnectionString)
Winline = New Data(LogConfig, Database, ConfigManager.Config)
WebService = New WebService(LogConfig, ConfigManager.Config)
PositionData = New PositionData(LogConfig, Winline)
Catch ex As Exception
ShowError(ex, "Initialisieren der Anwendungs Daten")
End Try
' Load WinLine Data
Try
Winline.Mandators.Clear()
Winline.LoadMandators()
Winline.LoadEconomicYears()
Winline.LoadDocumentKinds(Winline.Mandators)
' TODO: Comment in when we finally use the database for additional configuration
'Winline.LoadTemplateConfiguration()
For Each oMandator As Mandator In Winline.Mandators
Winline.LoadAccounts(oMandator)
Next
lookupMandator.Properties.DataSource = Winline.Mandators
lookupMandator.ForceInitialize()
lookupMandator.Properties.View.BestFitColumns()
Catch ex As Exception
ShowError(ex, "Laden der WinLine Daten")
End Try
Try
DocumentLoader = New DocumentLoader(LogConfig, Winline)
SchemaLoader = New SchemaLoader(LogConfig)
GridLoader = New GridLoader(LogConfig)
SchemaLoader.LoadFiles(ConfigManager.Config.SchemaDirectory)
CurrentSchemaName = SchemaLoader.SchemaList.First().FullName
CurrentSchema = SchemaLoader.GetSchemaFromFile(CurrentSchemaName)
Grids = CreateGridsAndColumns(CurrentSchema)
Catch ex As Exception
ShowError(ex, "Laden der Vorlagen Daten")
End Try
txtVersion.Caption = String.Format(txtVersion.Tag.ToString, My.Application.Info.Version.ToString)
End Sub
Private Function CreateGridsAndColumns(pSchema As Schemas.Schema) As List(Of GridControl)
Dim oGrids As New List(Of GridControl)
Dim oTableCounter = 0
For Each oTable In pSchema.Tables
If oTableCounter = 0 Then
Dim oGrid = GridLoader.GetGridFromElement(oTable)
AddHandler oGrid.DoubleClick, AddressOf Grid_MouseDoubleClick
SplitContainerGrids1.Panel1.Controls.Add(oGrid)
oGrids.Add(oGrid)
End If
If oTableCounter = 1 Then
Dim oGrid = GridLoader.GetGridFromElement(oTable)
AddHandler oGrid.DoubleClick, AddressOf Grid_MouseDoubleClick
SplitContainerGrids1.Panel2.Controls.Add(oGrid)
oGrids.Add(oGrid)
End If
If oTableCounter = 2 Then
Dim oGrid = GridLoader.GetGridFromElement(oTable)
AddHandler oGrid.DoubleClick, AddressOf Grid_MouseDoubleClick
SplitContainerGrids2.Panel1.Controls.Add(oGrid)
oGrids.Add(oGrid)
End If
If oTableCounter = 3 Then
Dim oGrid = GridLoader.GetGridFromElement(oTable)
AddHandler oGrid.DoubleClick, AddressOf Grid_MouseDoubleClick
SplitContainerGrids2.Panel2.Controls.Add(oGrid)
oGrids.Add(oGrid)
End If
If oTableCounter > 3 Then
MsgBox("Only 4 Tables are allowed currently!", MsgBoxStyle.Exclamation, Text)
End If
oTableCounter += 1
Next
If oTableCounter < 3 Then
SplitContainerGrids.PanelVisibility = DevExpress.XtraEditors.SplitPanelVisibility.Panel1
End If
Return oGrids
End Function
Private Sub Grid_MouseDoubleClick(sender As Object, e As MouseEventArgs) Handles GridControlFiles.MouseDoubleClick
Try
Dim oGrid As GridControl = DirectCast(sender, GridControl)
Dim oView As GridView = DirectCast(oGrid.FocusedView, GridView)
Dim oHitInfo = oView.CalcHitInfo(e.Location)
If Not oHitInfo.InDataRow Then
Exit Sub
End If
Dim oRow As DataRow = oView.GetDataRow(oView.FocusedRowHandle)
Dim oColumns = oView.Columns.Select(Function(c) c.FieldName).ToList()
Dim oDocumentRow = CurrentDocument.Rows.
Where(Function(r) r.Id.ToString = oRow.Item("GUID")).
SingleOrDefault()
Dim oAccounts = Winline.Accounts.
Where(Function(a) a.Mandator = CurrentDocument.Mandator.Id).
ToList()
Dim oForm As New frmRowEditor(oColumns, oDocumentRow, oAccounts)
If oForm.ShowDialog() = DialogResult.OK Then
Dim oModifiedRow = oForm.DocumentRow
Dim oIndex = CurrentDocument.Rows.IndexOf(oModifiedRow)
'Dim oGuid = CurrentDocument.Rows.
' Where(Function(r) r.Id = oModifiedRow.Id).
' Select(Function(r) r.Id)
CurrentDocument.Rows.Item(oIndex) = oModifiedRow
LoadDocument(CurrentDocument)
End If
Catch ex As Exception
ShowError(ex, "Laden der Detailzeilen")
End Try
End Sub
Private Sub btnLoadFiles_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles btnLoadFiles.ItemClick
Try
SplitContainerControl1.Enabled = False
If DocumentLoader.LoadFiles(ConfigManager.Config.InputDirectory, CurrentSchema, lookupMandator.EditValue) Then
GridControlFiles.DataSource = DocumentLoader.Files
txtFilesLoaded.Caption = String.Format(txtFilesLoaded.Tag.ToString, DocumentLoader.Files.Count)
End If
Catch ex As Exceptions.NoMandatorException
MsgBox("Es konnte kein passender Mandant anhand der geladenen Daten ermittelt werden. Bitte wählen Sie einen aus der Liste.", MsgBoxStyle.Information, Text)
Catch ex As Exception
ShowError(ex, "Laden der Dokumente")
Finally
SplitContainerControl1.Enabled = True
End Try
End Sub
Private Sub btnReloadFile_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles btnReloadFile.ItemClick
Dim oCurrentMandator As Mandator = TryCast(lookupMandator.EditValue, Mandator)
If oCurrentMandator Is Nothing Then
MsgBox("Bitte wählen Sie einen Mandanten aus, bevor Sie fortfahren!", MsgBoxStyle.Exclamation, Text)
Exit Sub
End If
Dim oResult As DialogResult = MsgBox($"Wollen Sie wirklich die aktuelle Datei mit dem gewählten Mandanten ({oCurrentMandator.Name}) neu laden? Alle von Ihnen getätigten Änderungen werden dabei verworfen.", MsgBoxStyle.Question Or MsgBoxStyle.YesNo, Text)
Try
If oResult = DialogResult.Yes Then
Dim oDocument As Document = GridViewFiles.GetRow(GridViewFiles.FocusedRowHandle)
Dim oNewDocument = DocumentLoader.LoadFile(oDocument.File, CurrentSchema, lookupMandator.EditValue)
Dim oIndex = DocumentLoader.Files.IndexOf(oDocument)
DocumentLoader.Files.Item(oIndex) = oNewDocument
LoadDocument(oNewDocument)
End If
Catch ex As Exceptions.NoMandatorException
MsgBox("Es konnte kein passender Mandant anhand der geladenen Daten ermittelt werden. Bitte wählen Sie einen aus der Liste.", MsgBoxStyle.Information, Text)
Catch ex As Exception
ShowError(ex, "Neuladen des Dokuments")
End Try
End Sub
Private Sub GridViewFiles_FocusedRowChanged(sender As Object, e As Views.Base.FocusedRowChangedEventArgs) Handles GridViewFiles.FocusedRowChanged
Try
Dim oDocument As Document = GridViewFiles.GetRow(e.FocusedRowHandle)
If oDocument Is Nothing Then
Exit Sub
End If
lookupMandator.EditValue = oDocument.Mandator
LoadDocument(oDocument)
Catch ex As Exception
ShowError(ex, "Laden des Dokuments")
End Try
End Sub
Private Sub LoadDocument(pDocument As Document)
Try
Dim oDatasources As New Dictionary(Of String, DataTable)
' List of Root Elements in XML
For Each oRow In pDocument.Rows
Dim oGrid As GridControl = Grids.
Where(Function(g) g.Name = oRow.Name).
SingleOrDefault()
' Create initial Datatable if none exists for this Root Element
If Not oDatasources.ContainsKey(oRow.Name) Then
Dim oTable As New DataTable()
oTable.Columns.Add(New DataColumn("GUID"))
For Each oField In oRow.Fields
oTable.Columns.Add(New DataColumn(oField.Key))
Next
oDatasources.Add(oRow.Name, oTable)
oGrid.DataSource = oTable
End If
Dim oDataTable = oDatasources.Item(oRow.Name)
Dim oDataRow = oDataTable.NewRow()
oDataRow.Item("GUID") = oRow.Id.ToString
For Each oField In oRow.Fields
oDataRow.Item(oField.Key) = oField.Value
Next
oDataTable.Rows.Add(oDataRow)
oDataTable.AcceptChanges()
Next
txtCurrentFile.Caption = String.Format(txtCurrentFile.Tag.ToString, pDocument.Name)
CurrentDocument = pDocument
SetDocumentButtonsEnabled(True)
Catch ex As Exception
SetDocumentButtonsEnabled(False)
Logger.Error(ex)
Throw ex
End Try
End Sub
Private Sub SetDocumentButtonsEnabled(pEnabled As Boolean)
btnShowXml.Enabled = pEnabled
btnReloadFile.Enabled = pEnabled
btnTransferFile.Enabled = pEnabled
' TODO: Implement all file transfer first
' btnTransferAllFiles.Enabled = pEnabled
End Sub
Private Async Sub btnTransferFile_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles btnTransferFile.ItemClick
Try
GridViewFiles.ShowLoadingPanel()
SetDocumentButtonsEnabled(False)
btnLoadFiles.Enabled = False
SplitContainerGrids.Enabled = False
Dim oDocument As Document = GridViewFiles.GetRow(GridViewFiles.FocusedRowHandle)
Await WebService.TransferDocumentToWinline(oDocument)
MsgBox("Datei erfolgreich in die WinLine übertragen!", MsgBoxStyle.Information, Text)
Catch ex As HttpRequestException
ShowError(ex, "Übertragung zur WinLine", "Die Verbindung zum WinLine Server ist fehlgeschlagen. Bitte prüfen Sie die Konfiguration des Programs und den Zustand des WinLine Servers")
Catch ex As Exception
ShowError(ex, "Übertragung zur WinLine")
Finally
SplitContainerGrids.Enabled = True
btnLoadFiles.Enabled = True
SetDocumentButtonsEnabled(False)
GridViewFiles.HideLoadingPanel()
End Try
End Sub
Private Sub btnOpenInputDirectory_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles btnOpenInputDirectory.ItemClick
TryOpenDirectory(ConfigManager.Config.InputDirectory, "Eingangsverzeichnis")
End Sub
Private Sub btnOpenOutputDirectory_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles btnOpenOutputDirectory.ItemClick
Dim oOutputDirectory = IO.Path.Combine(FileEx.GetAppDataPath("Digital Data", "EDI Document Importer"), "WebService")
TryOpenDirectory(oOutputDirectory, "Ausgabeverzeichnis")
End Sub
Private Sub btnOpenSchemaDirectory_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles btnOpenSchemaDirectory.ItemClick
TryOpenDirectory(ConfigManager.Config.SchemaDirectory, "Vorlagenverzeichnis")
End Sub
Private Sub TryOpenDirectory(pPath As String, pDisplayName As String)
If Directory.Exists(pPath) Then
Process.Start(pPath)
Else
MsgBox($"{pDisplayName} nicht konfiguriert oder nicht gefunden!", MsgBoxStyle.Exclamation, Text)
End If
End Sub
Private Sub TryOpenFile(pPath As String, pDisplayName As String)
If File.Exists(pPath) Then
Process.Start(pPath)
Else
MsgBox($"{pDisplayName} nicht konfiguriert oder nicht gefunden!", MsgBoxStyle.Exclamation, Text)
End If
End Sub
Private Sub btnOpenLogDirectory_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles btnOpenLogDirectory.ItemClick
TryOpenDirectory(LogConfig.LogDirectory, "Logverzeichnis")
End Sub
Private Sub btnOpenConfigDirectory_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles btnOpenConfigDirectory.ItemClick
Dim oUserConfigDirectory = New FileInfo(ConfigManager.UserConfigPath).Directory
TryOpenDirectory(oUserConfigDirectory.FullName, "Konfigurationsverzeichnis")
End Sub
Private Sub ShowError(pException As Exception, pFunction As String, Optional pDetails As String = "")
Dim oMessage = $"In der Funktion '{pFunction}' ist folgender Fehler aufgetreten:{vbNewLine}{vbNewLine}{pException.Message}"
If pDetails <> String.Empty Then
oMessage &= $"{vbNewLine}{pDetails}"
End If
Logger.Error(pException)
MsgBox(oMessage, MsgBoxStyle.Critical, Text)
End Sub
Private Sub btnShowXml_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles btnShowXml.ItemClick
Dim oForm As New frmXmlEditor With {.FileName = CurrentDocument.FullName}
oForm.Show()
End Sub
Private Sub txtCurrentFile_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles txtCurrentFile.ItemClick
If CurrentDocument IsNot Nothing Then
TryOpenFile(CurrentDocument.FullName, "Aktuelle Datei")
End If
End Sub
Private Sub btnConfig_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles btnConfig.ItemClick
Dim oForm As New frmConfig With {
.ConfigManager = ConfigManager
}
oForm.ShowDialog()
End Sub
End Class