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