From 47c22e9361b972a7dd485898ed6095b2c28e5e78 Mon Sep 17 00:00:00 2001 From: Jonathan Jenne Date: Tue, 16 Nov 2021 16:16:46 +0100 Subject: [PATCH] Validation and stuff --- MultiTool.Form/GlobalSuppressions.vb | 8 ++ MultiTool.Form/GridLoader.vb | 3 - MultiTool.Form/MultiTool.Form.vbproj | 1 + MultiTool.Form/frmConfig.vb | 9 +- MultiTool.Form/frmRowEditor.vb | 22 ++-- MultiTool.Shared/Documents/DocumentLoader.vb | 124 +++++++++++++----- MultiTool.Shared/Documents/DocumentRow.vb | 1 + MultiTool.Shared/IDictionaryEx.vb | 5 + MultiTool.Shared/Schemas/Schema.vb | 3 + MultiTool.Shared/Schemas/SchemaLoader.vb | 8 ++ .../Winline/Entities/ColumnConfig.vb | 24 ++-- MultiTool.Shared/Winline/WebService.vb | 1 - MultiTool.Shared/Winline/WinlineData.vb | 9 +- 13 files changed, 144 insertions(+), 74 deletions(-) create mode 100644 MultiTool.Form/GlobalSuppressions.vb diff --git a/MultiTool.Form/GlobalSuppressions.vb b/MultiTool.Form/GlobalSuppressions.vb new file mode 100644 index 0000000..fa65077 --- /dev/null +++ b/MultiTool.Form/GlobalSuppressions.vb @@ -0,0 +1,8 @@ +' This file is used by Code Analysis to maintain SuppressMessage +' attributes that are applied to this project. +' Project-level suppressions either have no target or are given +' a specific target and scoped to a namespace, type, member, etc. + +Imports System.Diagnostics.CodeAnalysis + + diff --git a/MultiTool.Form/GridLoader.vb b/MultiTool.Form/GridLoader.vb index 813dbfb..0423993 100644 --- a/MultiTool.Form/GridLoader.vb +++ b/MultiTool.Form/GridLoader.vb @@ -8,11 +8,8 @@ Imports MultiTool.Shared.Constants Public Class GridLoader Inherits BaseClass - Private ReadOnly TemplateConfig As Winline.Configuration - Public Sub New(pLogConfig As LogConfig, pTemplateConfig As Winline.Configuration) MyBase.New(pLogConfig, pLogConfig.GetLogger()) - TemplateConfig = pTemplateConfig End Sub Public Function GetGridFromElement(pGrid As GridControl, pTable As Schemas.Schema.Table) As GridControl diff --git a/MultiTool.Form/MultiTool.Form.vbproj b/MultiTool.Form/MultiTool.Form.vbproj index 2ed2887..159b54e 100644 --- a/MultiTool.Form/MultiTool.Form.vbproj +++ b/MultiTool.Form/MultiTool.Form.vbproj @@ -181,6 +181,7 @@ Form + OrderReport.vb diff --git a/MultiTool.Form/frmConfig.vb b/MultiTool.Form/frmConfig.vb index 819d43c..2f7aa17 100644 --- a/MultiTool.Form/frmConfig.vb +++ b/MultiTool.Form/frmConfig.vb @@ -5,8 +5,7 @@ Imports DigitalData.Modules.Logging Public Class frmConfig Public Property ConfigManager As ConfigManager(Of MultiTool.Shared.Config) - Private LogConfig As LogConfig - Private FormHelper As FormHelper + Private ReadOnly FormHelper As FormHelper Private ReadOnly Property Config As MultiTool.Shared.Config Get @@ -19,14 +18,14 @@ Public Class frmConfig InitializeComponent() ' Fügen Sie Initialisierungen nach dem InitializeComponent()-Aufruf hinzu. - LogConfig = pLogConfig FormHelper = New FormHelper(pLogConfig) End Sub Private Sub frmConfig_Load(sender As Object, e As EventArgs) Handles MyBase.Load Dim oConnectionString = MSSQLServer.DecryptConnectionString(Config.ConnectionString) - Dim oBuilder As New SqlConnectionStringBuilder(oConnectionString) - oBuilder.InitialCatalog = "DD_ECM" + Dim oBuilder As New SqlConnectionStringBuilder(oConnectionString) With { + .InitialCatalog = "DD_ECM" + } TBEDI_XML_ITEMSTableAdapter.Connection.ConnectionString = oBuilder.ToString() TBEDI_XML_ITEMSTableAdapter.Fill(Me.DS_DD_ECM.TBEDI_XML_ITEMS) diff --git a/MultiTool.Form/frmRowEditor.vb b/MultiTool.Form/frmRowEditor.vb index 3f8556f..ebab0bf 100644 --- a/MultiTool.Form/frmRowEditor.vb +++ b/MultiTool.Form/frmRowEditor.vb @@ -247,23 +247,25 @@ Public Class frmRowEditor Private Sub GridView1_CustomDrawCell(sender As Object, e As DevExpress.XtraGrid.Views.Base.RowCellCustomDrawEventArgs) Handles GridView1.CustomDrawCell Dim oDataRow As DataRow = GridView1.GetDataRow(e.RowHandle) Dim oKey As String = oDataRow.Item(COL_KEY) - - If e.Column.FieldName = COL_VALUE_FINAL Then - Dim oColumn = _Table.Columns. + Dim oValue As String = oDataRow.Item(COL_VALUE_FINAL) + Dim oColumn = _Table.Columns. Where(Function(c) c.Name = oKey). SingleOrDefault() + If e.Column.FieldName = COL_VALUE_FINAL Then If oColumn Is Nothing Then - Exit Sub - End If + If oColumn.Config?.IsReadOnly Then + e.Appearance.BackColor = Color.LightGray + End If - If oColumn.Config?.IsReadOnly Then - e.Appearance.BackColor = Color.LightGray + If oColumn.Config?.IsRequired AndAlso e.CellValue.ToString.Length = 0 Then + e.Appearance.BackColor = Color.LightCoral + End If End If + End If - If (oColumn.IsRequired Or oColumn.Config?.IsRequired) AndAlso e.CellValue.ToString.Length = 0 Then - e.Appearance.BackColor = Color.LightCoral - End If + If oColumn.Config?.IsRequired AndAlso oValue.ToString.Length = 0 Then + e.Appearance.BackColor = Color.LightCoral End If End Sub End Class diff --git a/MultiTool.Shared/Documents/DocumentLoader.vb b/MultiTool.Shared/Documents/DocumentLoader.vb index f15dd94..c9f6efc 100644 --- a/MultiTool.Shared/Documents/DocumentLoader.vb +++ b/MultiTool.Shared/Documents/DocumentLoader.vb @@ -77,7 +77,7 @@ Namespace Documents Select(AddressOf WrapFileInfo). Select(Function(d) IncludeSchema(d, pSchema)). Select(Function(d) LoadDocumentData(d, pSchema)). - Select(Function(d) MatchDataFromWinLine(d, Winline.Mandators, pMandator)). + Select(Function(d) MatchDataFromWinLine(d, Winline.Mandators, pMandator, pSchema)). SingleOrDefault() Catch ex As Exception Logger.Error(ex) @@ -145,9 +145,9 @@ Namespace Documents Where(Function(t) t.Name = oTopLevelElement.Name). FirstOrDefault() - ' TODO: All fields in the schema should be generated, - ' only creating the ones with values leads to wrong visual cues when asking for - ' docs/rows/fields with errors + + + For Each oSubElement As XElement In oSubElements Dim oSchemaField = oTable.Columns. @@ -167,6 +167,25 @@ Namespace Documents .Final = oValue, .DataType = oSchemaField.DataType }) + + Next + + ' TODO: All fields in the schema should be generated, + ' only creating the ones with values leads to wrong visual cues when asking for + ' docs/rows/fields with errors + For Each oColumn In oTable.Columns + If oFields.ContainsKey(oColumn.Name) Then + Continue For + End If + + Dim oColumnError = DocumentRow.FieldError.None + If oColumn.Config?.IsRequired Then + oColumnError = DocumentRow.FieldError.MissingValue + End If + + oFields.Add(oColumn.Name, New DocumentRow.FieldValue With { + .[Error] = oColumnError + }) Next ' Create a DocumentRow object for each Top Level Element @@ -189,7 +208,7 @@ Namespace Documents End Function - Private Function MatchDataFromWinLine(pDocument As Document, pMandators As List(Of Mandator), pMandator As Mandator) As Document + Private Function MatchDataFromWinLine(pDocument As Document, pMandators As List(Of Mandator), pMandator As Mandator, pSchema As Schema) As Document Dim oMandators As List(Of Winline.Mandator) = pMandators. Where(Function(m) m.IsWhitelisted = True). OrderBy(Function(m) m.Order). @@ -207,45 +226,77 @@ Namespace Documents Throw New Exceptions.NoMandatorException($"Mandator not found for file [{pDocument.File.Name}]") End If - pDocument = MatchDocumentData(pDocument, oMandator) + pDocument = MatchDocumentData(pDocument, oMandator, pSchema) pDocument.Mandator = oMandator Return pDocument End Function - Private Function MatchDocumentData(pDocument As Document, pMandator As Winline.Mandator) As Document + Private Function MatchDocumentData(pDocument As Document, pMandator As Winline.Mandator, pSchema As Schema) As Document Dim oYear = Winline.GetWinLineYear() If pMandator Is Nothing Then Return pDocument End If - Dim oHead As DocumentRow = pDocument.Rows. - Where(Function(r) r.Name.ToUpper.EndsWith("T025")). - SetValue(Sub(r As DocumentRow) SetAccountByGLN(r, pMandator, "Fakt_Kontonummer", "Fakt_Name")). - SetValue(Sub(r As DocumentRow) SetAccountByGLN(r, pMandator, "Lief_Kontonummer", "Lief_Name")). - FirstOrDefault() - - Dim oPositions As List(Of DocumentRow) = pDocument.Rows. - Where(Function(r) r.Name.ToUpper.EndsWith("T026")). - SetValue(Sub(oRow As DocumentRow) - Dim oNumberItem As DocumentRow.FieldValue = oRow.Fields.GetOrDefault("Artikelnummer") - If oNumberItem Is Nothing Then - Exit Sub - End If - - Dim oArticleNumber = Winline.TryGetArticleNumber(oNumberItem.Original, pMandator) - If oArticleNumber IsNot Nothing Then - oNumberItem.External = oArticleNumber - oNumberItem.Final = oArticleNumber - Else - oNumberItem.Error = DocumentRow.FieldError.ArticleNotFound - End If - End Sub). - ToList() + For Each oRow As DocumentRow In pDocument.Rows + Dim oTable = pSchema.Tables.Where(Function(t) t.Name = oRow.Name).SingleOrDefault() + + For Each oField In oRow.Fields + If oTable Is Nothing Then + Exit For + End If + + Dim oColumn = oTable.Columns.Where(Function(c) c.Name = oField.Key).SingleOrDefault() + If oColumn Is Nothing Then + Continue For + End If + + Dim oFunctionName = oColumn.Config?.Function?.Name + + If oFunctionName = "GLN" Then + SetAccountByGLN(oRow, pMandator, oField.Key, Nothing) + End If + + If oFunctionName = "EAN" Then + Dim oNumberItem As DocumentRow.FieldValue = oRow.Fields.GetOrDefault(oField.Key) + Dim oArticleNumber = Winline.TryGetArticleNumber(oNumberItem.Original, pMandator) + If oArticleNumber IsNot Nothing Then + oNumberItem.External = oArticleNumber + oNumberItem.Final = oArticleNumber + Else + oNumberItem.Error = DocumentRow.FieldError.ArticleNotFound + End If + End If + Next + Next - Dim oList As New List(Of DocumentRow) From {oHead} - pDocument.Rows = oList.Concat(oPositions).ToList() + 'Dim oHead As DocumentRow = pDocument.Rows. + ' Where(Function(r) r.Name.ToUpper.EndsWith("T025")). + ' SetValue(Sub(r As DocumentRow) SetAccountByGLN(r, pMandator, "Fakt_Kontonummer", "Fakt_Name")). + ' SetValue(Sub(r As DocumentRow) SetAccountByGLN(r, pMandator, "Lief_Kontonummer", "Lief_Name")). + ' FirstOrDefault() + + 'Dim oPositions As List(Of DocumentRow) = pDocument.Rows. + ' Where(Function(r) r.Name.ToUpper.EndsWith("T026")). + ' SetValue(Sub(oRow As DocumentRow) + ' Dim oNumberItem As DocumentRow.FieldValue = oRow.Fields.GetOrDefault("Artikelnummer") + ' If oNumberItem Is Nothing Then + ' Exit Sub + ' End If + + ' Dim oArticleNumber = Winline.TryGetArticleNumber(oNumberItem.Original, pMandator) + ' If oArticleNumber IsNot Nothing Then + ' oNumberItem.External = oArticleNumber + ' oNumberItem.Final = oArticleNumber + ' Else + ' oNumberItem.Error = DocumentRow.FieldError.ArticleNotFound + ' End If + ' End Sub). + ' ToList() + + 'Dim oList As New List(Of DocumentRow) From {oHead} + 'pDocument.Rows = oList.Concat(oPositions).ToList() Return pDocument End Function @@ -272,10 +323,11 @@ Namespace Documents oNameItem.External = oAccount.Name oNameItem.Final = oAccount.Name Else - oRow.Fields.Add(pNameField, New DocumentRow.FieldValue() With { - .External = oAccount.Name, - .Final = oAccount.Name - }) + ' TODO: What to to if name field is missing or not set? + 'oRow.Fields.Add(pNameField, New DocumentRow.FieldValue() With { + ' .External = oAccount.Name, + ' .Final = oAccount.Name + '}) End If Else oNumberItem.Error = DocumentRow.FieldError.AccountNotFound diff --git a/MultiTool.Shared/Documents/DocumentRow.vb b/MultiTool.Shared/Documents/DocumentRow.vb index 0cfa5fc..4727dc4 100644 --- a/MultiTool.Shared/Documents/DocumentRow.vb +++ b/MultiTool.Shared/Documents/DocumentRow.vb @@ -20,6 +20,7 @@ Public Enum FieldError None + MissingValue AccountNotFound ArticleNotFound End Enum diff --git a/MultiTool.Shared/IDictionaryEx.vb b/MultiTool.Shared/IDictionaryEx.vb index 488c1b3..83ae04b 100644 --- a/MultiTool.Shared/IDictionaryEx.vb +++ b/MultiTool.Shared/IDictionaryEx.vb @@ -4,6 +4,11 @@ Module IDictionaryEx Function GetOrDefault(Of TKey, TValue)(pDictionary As Dictionary(Of TKey, TValue), pKey As TKey, Optional pOnMissing As TValue = Nothing) As TValue Dim oValue As TValue + + If pKey Is Nothing Then + Return Nothing + End If + Return IIf(pDictionary.TryGetValue(pKey, oValue), oValue, pOnMissing) End Function diff --git a/MultiTool.Shared/Schemas/Schema.vb b/MultiTool.Shared/Schemas/Schema.vb index 49a66dd..24da6c7 100644 --- a/MultiTool.Shared/Schemas/Schema.vb +++ b/MultiTool.Shared/Schemas/Schema.vb @@ -13,6 +13,9 @@ Namespace Schemas Class Column Public Property Name As String Public Property DataType As Constants.ColumnType + ''' + ''' Required value from Schema. This value will be written in the ColumnConfig and is not relevant from that point on. + ''' Public Property IsRequired As Boolean Public Property Config As ColumnConfig End Class diff --git a/MultiTool.Shared/Schemas/SchemaLoader.vb b/MultiTool.Shared/Schemas/SchemaLoader.vb index 84fef15..891a227 100644 --- a/MultiTool.Shared/Schemas/SchemaLoader.vb +++ b/MultiTool.Shared/Schemas/SchemaLoader.vb @@ -87,6 +87,14 @@ Namespace Schemas For Each oTable In pSchema.Tables For Each oColumn As Schema.Column In oTable.Columns Dim oConfig = pTemplateConfig.GetColumn(oColumn.Name) + + If oConfig Is Nothing Then + oConfig = New Winline.ColumnConfig With { + .IsRequired = oColumn.IsRequired, + .Name = oColumn.Name + } + End If + oColumn.Config = oConfig Next Next diff --git a/MultiTool.Shared/Winline/Entities/ColumnConfig.vb b/MultiTool.Shared/Winline/Entities/ColumnConfig.vb index cb8cddb..0510937 100644 --- a/MultiTool.Shared/Winline/Entities/ColumnConfig.vb +++ b/MultiTool.Shared/Winline/Entities/ColumnConfig.vb @@ -2,18 +2,18 @@ Namespace Winline Public Class ColumnConfig - Public Name As String - Public Root As String - Public Type As ColumnType - Public Template As String - Public OrderKey As Integer - - Public IsHead As Boolean - Public IsReadOnly As Boolean - Public IsVisible As Boolean - Public IsRequired As Boolean - - Public [Function] As ColumnFunction + Public Property Name As String + Public Property Root As String + Public Property Type As ColumnType + Public Property Template As String + Public Property OrderKey As Integer + + Public Property IsHead As Boolean + Public Property IsReadOnly As Boolean + Public Property IsVisible As Boolean + Public Property IsRequired As Boolean + + Public Property [Function] As ColumnFunction Public Class ColumnFunction Public Id As XmlFunction diff --git a/MultiTool.Shared/Winline/WebService.vb b/MultiTool.Shared/Winline/WebService.vb index ecce99b..106bad9 100644 --- a/MultiTool.Shared/Winline/WebService.vb +++ b/MultiTool.Shared/Winline/WebService.vb @@ -20,7 +20,6 @@ Namespace Winline Serializer = New Serializer(pLogConfig) Config = pConfig AppDataPath = pAppDataPath - 'Mapper = MapperFactory.GetMapper() End Sub Public Async Function TransferDocumentToWinline(pDocument As Document) As Task(Of Boolean) diff --git a/MultiTool.Shared/Winline/WinlineData.vb b/MultiTool.Shared/Winline/WinlineData.vb index 58568be..03cb37b 100644 --- a/MultiTool.Shared/Winline/WinlineData.vb +++ b/MultiTool.Shared/Winline/WinlineData.vb @@ -1,10 +1,8 @@ Imports DigitalData.Modules.Logging Imports DigitalData.Modules.Language Imports DigitalData.Modules.Database -Imports MultiTool.Shared Imports System.Text.RegularExpressions - Namespace Winline Public Class WinlineData Inherits BaseClass @@ -20,9 +18,6 @@ Namespace Winline Public Years As List(Of Integer) Public TemplateConfiguration As New Configuration - 'Public XmlConfigHead As List(Of TemplateColumn) - 'Public XmlConfigPositions As List(Of TemplateColumn) - Public Const ALL_MESOCOMP = "mesocomp" Public Const VWEDI_XML_ITEMS = "VWEDI_XML_ITEMS" @@ -499,7 +494,7 @@ Namespace Winline Dim oItems As New List(Of ColumnConfig) For Each oRow As DataRow In oTable.Rows - Dim oColumn As New ColumnConfig With { + Dim oColumn As New ColumnConfig() With { .Name = GetRowItem(oRow, "XML_NAME", String.Empty), .Root = GetRowItem(oRow, "XML_ROOT", String.Empty), .Type = ColumnConfig.ConvertType(GetRowItem(oRow, "DATA_TYPE", String.Empty)), @@ -520,7 +515,7 @@ Namespace Winline Next Dim oColumns = oItems - TemplateConfiguration = New Winline.Configuration With { + TemplateConfiguration = New Configuration With { .Columns = oColumns }