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 Config) Private Database As MSSQLServer Private Winline As Data Private FileEx As DigitalData.Modules.Filesystem.File Private WebService As WebService Private DocumentLoader As DocumentLoader Private SchemaLoader As SchemaLoader Private FormHelper As FormHelper Private Grids As List(Of GridControl) Private GridLoader As GridLoader Private GridBuilder As GridBuilder Private CurrentSchemaName As String = Nothing Private CurrentSchema As Schema = Nothing Private CurrentGrid As GridControl = Nothing Private CurrentDocument As Document = Nothing 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, Application.CompanyName, Application.ProductName) Logger = LogConfig.GetLogger() Logger.Info("Starting {0}, Version [{1}]", Application.ProductName, Application.ProductVersion) ConfigManager = New ConfigManager(Of Config)(LogConfig, Application.UserAppDataPath, Application.CommonAppDataPath, Application.StartupPath ) FormHelper = New FormHelper(LogConfig) GridBuilder = New GridBuilder(GridViewFiles) GridBuilder.WithDefaults.WithClipboardHandler() GridViewFiles.OptionsView.ShowAutoFilterRow = False 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 = Application.ProductName } 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, Application.UserAppDataPath) AddHandler WebService.WebServiceProgress, AddressOf WebService_Progress Catch ex As Exception FormHelper.ShowError(ex, My.Resources.frmImportMainExtra.Initialisieren_der_Anwendungs_Daten) End Try txtVersion.Caption = String.Format(txtVersion.Tag.ToString, My.Application.Info.Version.ToString) txtCulture.Caption = String.Format(txtCulture.Tag.ToString, My.Application.UICulture.ToString) End Sub Private Async Sub frmImportMain_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown btnLoadFiles.Enabled = False SplashScreenManager.ShowWaitForm() ' Load WinLine Data Try Winline.Mandators.Clear() Winline.LoadEconomicYears() Await Winline.LoadMandators() ' TODO: Comment in when we finally use the database for additional configuration 'Winline.LoadTemplateConfiguration() For Each oMandator As Mandator In Winline.Mandators SplashScreenManager.SetWaitFormDescription(String.Format(My.Resources.frmImportMainExtra.Lade__0__Konten, oMandator.Id)) Await Winline.LoadAccounts(oMandator) SplashScreenManager.SetWaitFormDescription(String.Format(My.Resources.frmImportMainExtra.Lade__0__Artikel, oMandator.Id)) Await Winline.LoadArticles(oMandator) SplashScreenManager.SetWaitFormDescription(String.Format(My.Resources.frmImportMainExtra.Lade__0__Belegarten, oMandator.Id)) Await Winline.LoadDocumentKinds(oMandator) Next SplashScreenManager.SetWaitFormDescription(My.Resources.frmImportMainExtra.Lade_Oberfläche) lookupMandator.Properties.DataSource = Winline.Mandators lookupMandator.ForceInitialize() lookupMandator.Properties.View.BestFitColumns() DocumentLoader = New DocumentLoader(LogConfig, Winline) SchemaLoader = New SchemaLoader(LogConfig) GridLoader = New GridLoader(LogConfig) SplashScreenManager.SetWaitFormDescription(My.Resources.frmImportMainExtra.Lade_Vorlagen) SchemaLoader.LoadFiles(ConfigManager.Config.SchemaDirectory) CurrentSchemaName = SchemaLoader.SchemaList.First().FullName CurrentSchema = SchemaLoader.GetSchemaFromFile(CurrentSchemaName) Grids = CreateGridsAndColumns(CurrentSchema) For Each oGrid As GridControl In Grids AddHandler oGrid.GotFocus, AddressOf Grid_Focus Next Catch ex As Exception FormHelper.ShowError(ex, My.Resources.frmImportMainExtra.Laden_der_Winline_Daten) Finally SplashScreenManager.CloseWaitForm() btnLoadFiles.Enabled = True End Try End Sub Private Sub Grid_Focus(sender As GridControl, e As EventArgs) CurrentGrid = sender 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(GridControl1, oTable) AddHandler oGrid.DoubleClick, AddressOf Grid_MouseDoubleClick oGrids.Add(oGrid) End If If oTableCounter = 1 Then Dim oGrid = GridLoader.GetGridFromElement(GridControl2, oTable) AddHandler oGrid.DoubleClick, AddressOf Grid_MouseDoubleClick oGrids.Add(oGrid) End If If oTableCounter = 2 Then Dim oGrid = GridLoader.GetGridFromElement(GridControl3, oTable) AddHandler oGrid.DoubleClick, AddressOf Grid_MouseDoubleClick oGrids.Add(oGrid) End If If oTableCounter = 3 Then Dim oGrid = GridLoader.GetGridFromElement(GridControl4, oTable) AddHandler oGrid.DoubleClick, AddressOf Grid_MouseDoubleClick oGrids.Add(oGrid) End If If oTableCounter > 3 Then MsgBox(My.Resources.frmImportMainExtra.Zur_Zeit_werden_nur_bis_zu_4_Tabellen_unterstützt_, 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 oForm As New frmRowEditor(LogConfig, oColumns, oDocumentRow, CurrentDocument.Mandator, Winline) If oForm.ShowDialog() = DialogResult.OK Then Dim oModifiedRow = oForm.DocumentRow Dim oIndex = CurrentDocument.Rows.IndexOf(oModifiedRow) CurrentDocument.Rows.Item(oIndex) = oModifiedRow LoadDocument(CurrentDocument) End If Catch ex As Exception FormHelper.ShowError(ex, My.Resources.frmImportMainExtra.Laden_der_Detailzeilen) End Try End Sub Private Sub btnLoadFiles_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles btnLoadFiles.ItemClick Try SplitContainerGrids.Enabled = False If DocumentLoader.LoadFiles(ConfigManager.Config.InputDirectory, CurrentSchema, lookupMandator.EditValue) Then GridControlFiles.DataSource = Nothing GridControlFiles.DataSource = DocumentLoader.Files txtFilesLoaded.Caption = String.Format(txtFilesLoaded.Tag.ToString, DocumentLoader.Files.Count) End If Catch ex As Exceptions.NoMandatorException MsgBox(My.Resources.frmImportMainExtra.Es_konnte_kein_passender_Mandant_ermittelt_werden, MsgBoxStyle.Information, Text) Catch ex As Exception FormHelper.ShowError(ex, My.Resources.frmImportMainExtra.Laden_der_Detailzeilen) Finally SplitContainerGrids.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(My.Resources.frmImportMainExtra.Bitte_wählen_Sie_einen_Mandanten_aus__bevor_Sie_fortfahren, MsgBoxStyle.Exclamation, Text) Exit Sub End If Dim oMessage = String.Format(My.Resources.frmImportMainExtra.Wollen_Sie_wirklich_die_aktuelle_Datei_neu_laden, oCurrentMandator) Dim oResult As DialogResult = MsgBox(oMessage, 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(My.Resources.frmImportMainExtra.Es_konnte_kein_passender_Mandant_ermittelt_werden, MsgBoxStyle.Information, Text) Catch ex As Exception FormHelper.ShowError(ex, My.Resources.frmImportMainExtra.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 FormHelper.ShowError(ex, My.Resources.frmImportMainExtra.Laden_des_Dokuments) End Try End Sub Private Sub LoadDocument(pDocument As Document) Try Dim oDatasources As New Dictionary(Of String, DataTable) For Each oGrid In Grids oGrid.DataSource = Nothing Next ' 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 = Nothing 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 SplashScreenManager.ShowWaitForm() SetDocumentButtonsEnabled(False) GridControlFiles.Enabled = False btnLoadFiles.Enabled = False SplitContainerGrids.Enabled = False Dim oDocument As Document = GridViewFiles.GetRow(GridViewFiles.FocusedRowHandle) Await WebService.TransferDocumentToWinline(oDocument) MsgBox(My.Resources.frmImportMainExtra.Datei_erfolgreich_in_die_WinLine_übertragen, MsgBoxStyle.Information, Text) Catch ex As HttpRequestException FormHelper.ShowError(ex, My.Resources.frmImportMainExtra.Übertragung_zur_WinLine, My.Resources.frmImportMainExtra.Die_Verbindung_zum_WinLine_Server_ist_fehlgeschlagen) Catch ex As Exception FormHelper.ShowError(ex, My.Resources.frmImportMainExtra.Übertragung_zur_WinLine) Finally SplitContainerGrids.Enabled = True btnLoadFiles.Enabled = True GridControlFiles.Enabled = True SetDocumentButtonsEnabled(True) SplashScreenManager.CloseWaitForm() End Try End Sub Private Sub WebService_Progress(sender As Object, e As String) SplashScreenManager.SetWaitFormDescription(e) End Sub Private Sub btnOpenInputDirectory_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles btnOpenInputDirectory.ItemClick TryOpenDirectory(ConfigManager.Config.InputDirectory, My.Resources.frmImportMainExtra.Eingangsverzeichnis) End Sub Private Sub btnOpenOutputDirectory_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles btnOpenOutputDirectory.ItemClick Dim oOutputDirectory = Path.Combine(Application.UserAppDataPath, "WebService") TryOpenDirectory(oOutputDirectory, My.Resources.frmImportMainExtra.Ausgabeverzeichnis) End Sub Private Sub btnOpenSchemaDirectory_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles btnOpenSchemaDirectory.ItemClick TryOpenDirectory(ConfigManager.Config.SchemaDirectory, My.Resources.frmImportMainExtra.Vorlagenverzeichnis) End Sub Private Sub TryOpenDirectory(pPath As String, pDisplayName As String) If Directory.Exists(pPath) Then Process.Start(pPath) Else Dim oMessage = String.Format(My.Resources.frmImportMainExtra._0__nicht_konfiguriert_oder_nicht_gefunden, pDisplayName) MsgBox(oMessage, 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 Dim oMessage = String.Format(My.Resources.frmImportMainExtra._0__nicht_konfiguriert_oder_nicht_gefunden, pDisplayName) MsgBox(oMessage, 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, My.Resources.frmImportMainExtra.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, My.Resources.frmImportMainExtra.Konfigurationsverzeichnis) 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, My.Resources.frmImportMainExtra.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 Private Sub btnRemoveRow_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles btnRemoveRow.ItemClick If CurrentGrid Is Nothing Then Exit Sub End If Dim oMessage As String = "Wollen Sie die ausgewählte Zeile wirklich löschen?" If MsgBox(oMessage, MsgBoxStyle.Question Or MsgBoxStyle.YesNo, Text) = MsgBoxResult.Yes Then ' Get GUID of currently selected row Dim oView As GridView = CurrentGrid.FocusedView Dim oRow As DataRowView = oView.GetRow(oView.FocusedRowHandle) Dim oGuid = oRow.Row.Item("GUID") ' Get currently selected document Dim oDocument As Document = GridViewFiles.GetRow(GridViewFiles.FocusedRowHandle) Dim oNewRows = oDocument.Rows. Where(Function(r) r.Id.ToString <> oGuid). ToList() oDocument.Rows = oNewRows Dim oIndex = DocumentLoader.Files.IndexOf(oDocument) DocumentLoader.Files.Item(oIndex) = oDocument lookupMandator.EditValue = oDocument.Mandator LoadDocument(oDocument) End If End Sub End Class