Improve Error handling across the board

This commit is contained in:
Jonathan Jenne 2022-04-26 12:02:00 +02:00
parent 13af72dee5
commit 3e41502766
19 changed files with 404 additions and 141 deletions

View File

@ -8,6 +8,7 @@
Public Const FUNCTION_PRICE = "PRICE" Public Const FUNCTION_PRICE = "PRICE"
Public Const FUNCTION_SQL = "SQL" Public Const FUNCTION_SQL = "SQL"
Public Const FUNCTION_FIELD = "FIELD" Public Const FUNCTION_FIELD = "FIELD"
Public Const FUNCTION_RUNNINGNUMBER = "RUNNINGNUMBER"
Public Const TEMPLATE_TYPE_DATE = "xs:date" Public Const TEMPLATE_TYPE_DATE = "xs:date"
Public Const TEMPLATE_TYPE_INTEGER = "xs:integer" Public Const TEMPLATE_TYPE_INTEGER = "xs:integer"
@ -56,17 +57,38 @@
[Decimal] [Decimal]
End Enum End Enum
Public Enum FieldError Public Enum FieldErrorType
None None
MissingValue MissingValue
AccountNotFound AccountNotFound
ArticleNotFound ArticleNotFound
End Enum End Enum
Public Enum DocumentError Public Class FieldError
Public Type As FieldErrorType
Public Message As String
Public Overrides Function ToString() As String
Return $"{Message} ({Type})"
End Function
End Class
Public Enum DocumentErrorType
MandatorNotFound MandatorNotFound
MissingXmlAttribute
AttributeValidationFailed
End Enum End Enum
Public Class DocumentError
Public Type As DocumentErrorType
Public Message As String
Public Overrides Function ToString() As String
Return $"{Message} ({Type})"
End Function
End Class
Public Enum XmlFunction Public Enum XmlFunction
None = 0 None = 0
GLN = 1 GLN = 1

View File

@ -26,6 +26,8 @@ Namespace Documents
''' </summary> ''' </summary>
Public Property Selected As Boolean = False Public Property Selected As Boolean = False
Private DocumentErrors As New List(Of DocumentError)
Public ReadOnly Property HasErrors As Boolean Public ReadOnly Property HasErrors As Boolean
Get Get
Return Errors.Count > 0 Return Errors.Count > 0
@ -34,8 +36,11 @@ Namespace Documents
Public ReadOnly Property Errors As List(Of String) Public ReadOnly Property Errors As List(Of String)
Get Get
Dim oRowErrors = Rows.SelectMany(Function(row) row.Errors).ToList() Dim oRowErrors = Rows.
Dim oDocumentErrors As List(Of String) = GetDocumentErrors(). SelectMany(Function(row) row.Errors, Function(row, err) err.ToString).
ToList()
Dim oDocumentErrors As List(Of String) = DocumentErrors.
Select(Function(err) err.ToString()). Select(Function(err) err.ToString()).
ToList() ToList()
Return oDocumentErrors. Return oDocumentErrors.
@ -44,6 +49,13 @@ Namespace Documents
End Get End Get
End Property End Property
Public Sub AddDocumentError(pDocumentError As DocumentErrorType, pMessage As String)
DocumentErrors.Add(New DocumentError With {
.Type = pDocumentError,
.Message = pMessage
})
End Sub
Public ReadOnly Property MandatorId As String Public ReadOnly Property MandatorId As String
Get Get
Return Mandator?.Id Return Mandator?.Id
@ -84,19 +96,12 @@ Namespace Documents
End Function End Function
Public Overrides Function Equals(obj As Object) As Boolean Public Overrides Function Equals(obj As Object) As Boolean
Return FullName = DirectCast(obj, Document).FullName If obj Is Nothing Then
End Function Return False
Private Function GetDocumentErrors() As List(Of DocumentError)
Dim oErrors As New List(Of DocumentError)
If Mandator Is Nothing Then
oErrors.Add(DocumentError.MandatorNotFound)
End If End If
Return oErrors Return FullName = DirectCast(obj, Document).FullName
End Function End Function
End Class End Class
End Namespace End Namespace

View File

@ -65,22 +65,13 @@ Namespace Documents
Logger.Debug("Found [{0}] files in directory [{1}]", oFiles.Count, oDirectory) Logger.Debug("Found [{0}] files in directory [{1}]", oFiles.Count, oDirectory)
For Each oFile In oFiles For Each oFile In oFiles
Try Logger.Info("Loading file [{0}]", oFile.Name)
Dim oDocument = Await LoadFile(oFile, pTemplate, pMandator) Dim oDocument = Await LoadFile(oFile, pTemplate, pMandator)
Files.Add(oDocument) Files.Add(oDocument)
FilesLoaded = Files.Count FilesLoaded = Files.Count
Dim oInfo As New FileLoadInfo(FilesTotal, FilesLoaded) Dim oInfo As New FileLoadInfo(FilesTotal, FilesLoaded)
RaiseEvent FileLoadComplete(Me, oInfo) RaiseEvent FileLoadComplete(Me, oInfo)
Catch ex As MissingAttributeException
Logger.Error(ex)
Throw New DocumentLoaderException($"Missing Attribute '{ex.Message}' in File '{oFile.Name}'")
Catch ex As Exception
Logger.Error(ex)
Throw ex
End Try
Next Next
Return True Return True
@ -93,20 +84,52 @@ Namespace Documents
End Function End Function
Public Async Function LoadFile(pFileInfo As FileInfo, pTemplate As Template, pMandator As Mandator) As Task(Of Document) Public Async Function LoadFile(pFileInfo As FileInfo, pTemplate As Template, pMandator As Mandator) As Task(Of Document)
Dim oFileList As New List(Of FileInfo) From {pFileInfo} Logger.Debug("Creating new Document object for file [{0}]", pFileInfo.Name)
Logger.Info("Loading file [{0}]", pFileInfo.Name) Dim oDocument As Document = New Document With {
.File = pFileInfo,
.Schema = pTemplate
}
Try Try
Return Await oFileList. oDocument = LoadDocumentData(oDocument, pTemplate, TemplateConfig)
Select(AddressOf WrapFileInfo).
Select(Function(d) IncludeSchema(d, pTemplate)).
Select(Function(d) LoadDocumentData(d, pTemplate, TemplateConfig)).
Select(Async Function(d) Await MatchDataFromWinLine(d, Winline.Mandators, pMandator, pTemplate)).
SingleOrDefault()
Catch ex As Exception Catch ex As Exception
Logger.Error(ex)
Throw ex Throw ex
Logger.Error(ex)
End Try End Try
Try
oDocument = Await MatchDataFromWinLine(oDocument, Winline.Mandators, pMandator, pTemplate)
Catch ex As Exception
Throw ex
Logger.Error(ex)
End Try
Try
oDocument = MarkRequiredFields(oDocument)
Catch ex As Exception
Throw ex
Logger.Error(ex)
End Try
Return oDocument
End Function
Public Function MarkRequiredFields(pDocument As Document) As Document
For Each oRow In pDocument.Rows
For Each oField In oRow.Fields
If oField.Value.Final = String.Empty And oField.Value.IsRequired Then
oField.Value.AddFieldError(FieldErrorType.MissingValue, $"Attribut '{oField.Key}' ist ein Pflichtfeld, wurde aber nicht gefüllt.")
End If
Next
Next
Return pDocument
End Function End Function
Public Sub ReplaceDocument(pDocument As Document) Public Sub ReplaceDocument(pDocument As Document)
@ -154,27 +177,27 @@ Namespace Documents
Dim oRootElement As XElement = XmlData.GetElement(oDoc, "MESOWebService") Dim oRootElement As XElement = XmlData.GetElement(oDoc, "MESOWebService")
If oRootElement Is Nothing Then If oRootElement Is Nothing Then
Throw New MalformedXmlException("Datei enthält kein MESOWebService-Element") pDocument.AddDocumentError(DocumentErrorType.MissingXmlAttribute, "Datei enthält kein MESOWebService-Attribut")
End If End If
Dim oTemplateName = XmlData.GetElementAttribute(oRootElement, "Template") Dim oTemplateName = XmlData.GetElementAttribute(oRootElement, "Template")
If oTemplateName Is Nothing Then If oTemplateName Is Nothing Then
Throw New MalformedXmlException("Datei enthält kein Template-Attribut") pDocument.AddDocumentError(DocumentErrorType.MissingXmlAttribute, "Datei enthält kein Template-Attribut")
End If End If
Dim oTemplateType = XmlData.GetElementAttribute(oRootElement, "TemplateType") Dim oTemplateType = XmlData.GetElementAttribute(oRootElement, "TemplateType")
If oTemplateType Is Nothing Then If oTemplateType Is Nothing Then
Throw New MalformedXmlException("Datei enthält kein TemplateType-Attribut") pDocument.AddDocumentError(DocumentErrorType.MissingXmlAttribute, "Datei enthält kein TemplateType-Attribut")
End If End If
Dim oOption = XmlData.GetElementAttribute(oRootElement, "option") Dim oOption = XmlData.GetElementAttribute(oRootElement, "option")
If oOption Is Nothing Then If oOption Is Nothing Then
Throw New MalformedXmlException("Datei enthält kein option-Attribut") pDocument.AddDocumentError(DocumentErrorType.MissingXmlAttribute, "Datei enthält kein option-Attribut")
End If End If
Dim oPrintVoucher = XmlData.GetElementAttribute(oRootElement, "printVoucher") Dim oPrintVoucher = XmlData.GetElementAttribute(oRootElement, "printVoucher")
If oPrintVoucher Is Nothing Then If oPrintVoucher Is Nothing Then
Throw New MalformedXmlException("Datei enthält kein printVoucher-Attribut") pDocument.AddDocumentError(DocumentErrorType.MissingXmlAttribute, "Datei enthält kein printVoucher-Attribut")
End If End If
' The first level of Elements are the document Rows ' The first level of Elements are the document Rows
@ -227,16 +250,18 @@ Namespace Documents
Else Else
Logger.Debug("Creating new field from Configuration: [{0}]", oColumn.Name) Logger.Debug("Creating new field from Configuration: [{0}]", oColumn.Name)
Dim oColumnError = FieldError.None Dim oValue = New DocumentRow.FieldValue With {
If oColumn.Config?.IsRequired Then
oColumnError = FieldError.MissingValue
End If
oFields.Add(oColumn.Name, New DocumentRow.FieldValue With {
.[Error] = oColumnError,
.SortKey = oColumnSortKey, .SortKey = oColumnSortKey,
.IsVirtual = oColumn.Config.IsVirtual .IsVirtual = oColumn.Config.IsVirtual
}) }
'oValue.Error = FieldErrorType.None
If oColumn.Config?.IsRequired Then
'oValue.Error = FieldErrorType.MissingValue
oValue.AddFieldError(FieldErrorType.MissingValue, $"Attribut {oSubElement.Name} wird benötigt, ist aber nicht gefüllt.")
End If
oFields.Add(oColumn.Name, oValue)
End If End If
oColumnSortKey += 1 oColumnSortKey += 1
@ -282,6 +307,9 @@ Namespace Documents
If oMandator Is Nothing Then If oMandator Is Nothing Then
Logger.Warn("Mandator not found for File [{0}]", pDocument.File.Name) Logger.Warn("Mandator not found for File [{0}]", pDocument.File.Name)
' Without mandator, we just exit, life is meaningless.
pDocument.AddDocumentError(DocumentErrorType.MandatorNotFound, "Mandant nicht gefunden. Verarbeitung wurde abgebrochen.")
Else Else
' Set mandator befor applying any functions that depend on a valid mandator ' Set mandator befor applying any functions that depend on a valid mandator
pDocument.Mandator = oMandator pDocument.Mandator = oMandator
@ -290,7 +318,7 @@ Namespace Documents
.RunningFunction = "Winline-Funktionen" .RunningFunction = "Winline-Funktionen"
}) })
pDocument = ApplyDefinedItemFunctionsForImport(pDocument, oMandator, pTemplate) pDocument = Await ApplyDefinedItemFunctionsForImportAsync(pDocument, oMandator, pTemplate)
pDocument = ApplyDynamicItemFunctionsForImport(pDocument, oMandator) pDocument = ApplyDynamicItemFunctionsForImport(pDocument, oMandator)
RaiseEvent FileLoadProgress(Me, New FileLoadProgressInfo(FilesTotal, FilesLoaded) With { RaiseEvent FileLoadProgress(Me, New FileLoadProgressInfo(FilesTotal, FilesLoaded) With {
@ -355,7 +383,7 @@ Namespace Documents
Return pDocument Return pDocument
End Function End Function
Private Function ApplyDefinedItemFunctionsForImport(pDocument As Document, pMandator As Mandator, pTemplate As Template) As Document Private Async Function ApplyDefinedItemFunctionsForImportAsync(pDocument As Document, pMandator As Mandator, pTemplate As Template) As Task(Of Document)
For Each oRow As DocumentRow In pDocument.Rows For Each oRow As DocumentRow In pDocument.Rows
Dim oTable = pTemplate.Tables.Where(Function(table) table.Name = oRow.TableName).SingleOrDefault() Dim oTable = pTemplate.Tables.Where(Function(table) table.Name = oRow.TableName).SingleOrDefault()
@ -373,14 +401,17 @@ Namespace Documents
Dim oFunctionParams = oColumn.Config.FunctionParams Dim oFunctionParams = oColumn.Config.FunctionParams
Dim oParamsDict = ParseFunctionParamsAsDict(oFunctionParams) Dim oParamsDict = ParseFunctionParamsAsDict(oFunctionParams)
If oFunctionName = Constants.FUNCTION_GLN Then If oFunctionName = FUNCTION_GLN Then
SetAccountByGLN(oRow, pMandator, oField.Key, Nothing, oParamsDict) SetAccountByGLN(oRow, pMandator, oField.Key, Nothing, oParamsDict)
End If End If
If oFunctionName = Constants.FUNCTION_EAN Then If oFunctionName = FUNCTION_EAN Then
SetArticleByEAN(oRow, pMandator, oField.Key) SetArticleByEAN(oRow, pMandator, oField.Key)
End If End If
If oFunctionName = FUNCTION_RUNNINGNUMBER Then
Await SetVersionedRunningNumber(pDocument, oRow, pMandator, oField.Key, oParamsDict)
End If
Next Next
Next Next
@ -481,9 +512,7 @@ Namespace Documents
pDocument.Rows. pDocument.Rows.
SelectMany(Function(row) row.Fields). SelectMany(Function(row) row.Fields).
Where(Function(field) field.Key = oMapping.DestinationItem). Where(Function(field) field.Key = oMapping.DestinationItem).
SetValue(Sub(field) SetValue(Sub(field) field.Value.Final = oMapping.DestinationValue)
field.Value.Final = oMapping.DestinationValue
End Sub)
Else Else
' don't do anything ' don't do anything
@ -494,12 +523,12 @@ Namespace Documents
Return pDocument Return pDocument
End Function End Function
Private Async Function SetPrice(pRow As DocumentRow, pPriceField As String, oFieldMap As Dictionary(Of String, String), pDocument As Document, pMandator As Mandator, pTemplate As Template) As Task Private Async Function SetPrice(pRow As DocumentRow, pPriceField As String, pParamMap As Dictionary(Of String, String), pDocument As Document, pMandator As Mandator, pTemplate As Template) As Task
Dim oPriceItem As DocumentRow.FieldValue = pRow.Fields.GetOrDefault(pPriceField) Dim oPriceItem As DocumentRow.FieldValue = pRow.Fields.GetOrDefault(pPriceField)
' These fields are fetched from the current row ' These fields are fetched from the current row
Const PARAMETER_ARTICLE = "Article" Const PARAMETER_ARTICLE = "Article"
Dim oArticleNumberField As String = oFieldMap.GetOrDefault(PARAMETER_ARTICLE, Nothing) Dim oArticleNumberField As String = pParamMap.GetOrDefault(PARAMETER_ARTICLE, Nothing)
If oArticleNumberField Is Nothing Then If oArticleNumberField Is Nothing Then
Logger.Warn("Parameter '{0}' not found for Function PRICE", PARAMETER_ARTICLE) Logger.Warn("Parameter '{0}' not found for Function PRICE", PARAMETER_ARTICLE)
End If End If
@ -510,7 +539,7 @@ Namespace Documents
Dim oArticleNumber As String = pRow.Fields.Item(oArticleNumberField).Final Dim oArticleNumber As String = pRow.Fields.Item(oArticleNumberField).Final
Const PARAMETER_QUANTITY = "Quantity" Const PARAMETER_QUANTITY = "Quantity"
Dim oQuantityField As String = oFieldMap.GetOrDefault(PARAMETER_QUANTITY, Nothing) Dim oQuantityField As String = pParamMap.GetOrDefault(PARAMETER_QUANTITY, Nothing)
If oQuantityField Is Nothing Then If oQuantityField Is Nothing Then
Logger.Warn("Parameter '{0}' not found for Function PRICE", PARAMETER_QUANTITY) Logger.Warn("Parameter '{0}' not found for Function PRICE", PARAMETER_QUANTITY)
End If End If
@ -521,13 +550,13 @@ Namespace Documents
End If End If
' These fields a fetched from the head row, ie. the first row ' These fields a fetched from the head row, ie. the first row
Dim oAccountNumberField As String = oFieldMap.GetOrDefault("Account", Nothing) Dim oAccountNumberField As String = pParamMap.GetOrDefault("Account", Nothing)
Dim oAccountNumber = pDocument.GetFieldValue(oAccountNumberField) Dim oAccountNumber = pDocument.GetFieldValue(oAccountNumberField)
Dim oDocumentDateField As String = oFieldMap.GetOrDefault("DocumentDate", Nothing) Dim oDocumentDateField As String = pParamMap.GetOrDefault("DocumentDate", Nothing)
Dim oDocumentDate = pDocument.GetFieldValue(oDocumentDateField) Dim oDocumentDate = pDocument.GetFieldValue(oDocumentDateField)
Dim oDocumentKindField As String = oFieldMap.GetOrDefault("DocumentKind", Nothing) Dim oDocumentKindField As String = pParamMap.GetOrDefault("DocumentKind", Nothing)
Dim oDocumentKind As Integer = 0 Dim oDocumentKind As Integer = 0
If Integer.TryParse(pDocument.GetFieldValue(oDocumentKindField), oDocumentKind) = False Then If Integer.TryParse(pDocument.GetFieldValue(oDocumentKindField), oDocumentKind) = False Then
Logger.Warn("Value for parameter DocumentKind could not be parsed. Setting to 0.") Logger.Warn("Value for parameter DocumentKind could not be parsed. Setting to 0.")
@ -538,10 +567,10 @@ Namespace Documents
' TODO: This function should not be hardcoded, but be replaced with virtual field or something.. ' TODO: This function should not be hardcoded, but be replaced with virtual field or something..
' It is related to customer SCHAUM and nothing general ' It is related to customer SCHAUM and nothing general
Dim oWaitingDays As Integer = Await Winline.TryGetWaitingDays(oDocumentKind, pMandator) Dim oWaitingDays As Integer = Await Winline.TryGetWaitingDaysAsync(oDocumentKind, pMandator)
' END TODO ' END TODO
Dim oArticlePrice As Double = Await Winline.TryGetArticlePrice(oArticleNumber, oAccountNumber, oQuantity, oDocumentDate, pMandator, pTemplate, oWaitingDays) Dim oArticlePrice As Double = Await Winline.TryGetArticlePriceAsync(oArticleNumber, oAccountNumber, oQuantity, oDocumentDate, pMandator, pTemplate, oWaitingDays)
If oArticlePrice > 0 Then If oArticlePrice > 0 Then
oPriceItem.External = oArticlePrice oPriceItem.External = oArticlePrice
@ -559,7 +588,8 @@ Namespace Documents
oNumberItem.External = oArticleNumber oNumberItem.External = oArticleNumber
oNumberItem.Final = oArticleNumber oNumberItem.Final = oArticleNumber
Else Else
oNumberItem.Error = FieldError.ArticleNotFound 'oNumberItem.Error = FieldErrorType.ArticleNotFound
oNumberItem.AddFieldError(FieldErrorType.ArticleNotFound, $"EAN in Attribut '{pArticleField}' konnte nicht aufgelöst werden.")
End If End If
End Sub End Sub
@ -597,7 +627,8 @@ Namespace Documents
' If no account was found and the field is required, ' If no account was found and the field is required,
' mark it as error. Otherwise, do nothing. ' mark it as error. Otherwise, do nothing.
If oNumberItem.IsRequired Then If oNumberItem.IsRequired Then
oNumberItem.Error = FieldError.AccountNotFound 'oNumberItem.Error = FieldErrorType.AccountNotFound
oNumberItem.AddFieldError(FieldErrorType.AccountNotFound, $"GLN in Attribut '{pNumberField}' konnte nicht aufgelöst werden.")
End If End If
End If End If
Catch ex As Exception Catch ex As Exception
@ -606,9 +637,31 @@ Namespace Documents
End Try End Try
End Sub End Sub
Private Function WrapFileInfo(pFileInfo As FileInfo) As Document Public Async Function SetVersionedRunningNumber(pDocument As Document, pRow As DocumentRow, pMandator As Mandator, pRunningNumberField As String, pParams As Dictionary(Of String, String)) As Task
Logger.Debug("Creating new Document object for file [{0}]", pFileInfo.Name) Try
Return New Document With {.File = pFileInfo} Const PARAMETER_ACCOUNT = "Account"
Dim oAccountField As String = pParams.GetOrDefault(PARAMETER_ACCOUNT, Nothing)
If oAccountField Is Nothing Then
Logger.Warn("Parameter '{0}' not found for Function RUNNINGNUMBER", PARAMETER_ACCOUNT)
End If
Dim oRunningNumberItem As DocumentRow.FieldValue = pRow.Fields.GetOrDefault(pRunningNumberField)
Dim oRunningNumber = oRunningNumberItem.Final
Dim oAccountNumberItem As DocumentRow.FieldValue = pRow.Fields.GetOrDefault(oAccountField)
Dim oAccountNumber = oAccountNumberItem.Final
Dim oVersionedNumber = Await Winline.GetVersionedRunningNumberAsync(pDocument, pMandator, oAccountNumber, oRunningNumber)
If oVersionedNumber <> oRunningNumber Then
oRunningNumberItem.External = oVersionedNumber
oRunningNumberItem.Final = oVersionedNumber
End If
Catch ex As Exception
Logger.Error(ex)
Throw ex
End Try
End Function End Function
Private Function ParseFunctionParamsAsDict(pParams As String) As Dictionary(Of String, String) Private Function ParseFunctionParamsAsDict(pParams As String) As Dictionary(Of String, String)

View File

@ -35,11 +35,11 @@ Namespace Documents
End Get End Get
End Property End Property
Public ReadOnly Property Errors As List(Of String) Public ReadOnly Property Errors As List(Of FieldError)
Get Get
Return Fields. Return Fields.
Where(Function(f) f.Value.HasError). Where(Function(f) f.Value.HasError).
Select(Function(f) $"{f.Key} has Error: {f.Value.Error}").ToList() SelectMany(Function(f) f.Value.Errors).ToList()
End Get End Get
End Property End Property
@ -57,11 +57,8 @@ Namespace Documents
Private _Original As String = "" Private _Original As String = ""
Public Property DataType As ColumnType = ColumnType.String Public Property DataType As ColumnType = ColumnType.String
Public Property [Error] As FieldError = FieldError.None
Public Sub New() Public Property Errors As New List(Of FieldError)
End Sub
Public Property Original As String Public Property Original As String
Get Get
@ -107,9 +104,17 @@ Namespace Documents
End Select End Select
End Function End Function
Public Sub AddFieldError(pType As FieldErrorType, pMessage As String)
Errors.Add(New FieldError() With {
.Type = pType,
.Message = pMessage
})
End Sub
Public ReadOnly Property HasError As Boolean Public ReadOnly Property HasError As Boolean
Get Get
Return [Error] <> FieldError.None Or (IsRequired And Final = String.Empty) ' Required check was moved to DocumentLoader
Return Errors.Count > 0 'Or (IsRequired And Final = String.Empty)
End Get End Get
End Property End Property

View File

@ -57,18 +57,12 @@
MyBase.New(message) MyBase.New(message)
End Sub End Sub
End Class End Class
Public Class NoMandatorException
Public Class LengthExceededException
Inherits MultiToolException Inherits MultiToolException
Public Sub New(message As String) Public Sub New(attribute As String)
MyBase.New(message) MyBase.New(attribute)
End Sub
End Class
Public Class MalformedXmlException
Inherits MultiToolException
Public Sub New(message As String)
MyBase.New(message)
End Sub End Sub
End Class End Class

View File

@ -1,10 +1,13 @@
Imports DigitalData.Modules.Logging Imports System.Text.RegularExpressions
Imports DigitalData.Modules.Logging
Imports DigitalData.Modules.Database Imports DigitalData.Modules.Database
Imports MultiTool.Common.Winline.Entities
Imports System.Text.RegularExpressions
Imports MultiTool.Common.Templates
Imports MultiTool.Common.Constants
Imports DigitalData.Modules.Language Imports DigitalData.Modules.Language
Imports DigitalData.Modules.Filesystem
Imports MultiTool.Common.Winline.Entities
Imports MultiTool.Common.Constants
Imports MultiTool.Common.Templates
Imports MultiTool.Common.Exceptions
Imports MultiTool.Common.Documents
Namespace Winline Namespace Winline
Public Class WinlineData Public Class WinlineData
@ -14,6 +17,7 @@ Namespace Winline
Private ReadOnly Property MandatorConfig As MandatorConfig Private ReadOnly Property MandatorConfig As MandatorConfig
Private ReadOnly Property MappingConfig As MappingConfig Private ReadOnly Property MappingConfig As MappingConfig
Private ReadOnly Property Patterns As Patterns Private ReadOnly Property Patterns As Patterns
Private ReadOnly Property FileEx As File
Public Property Articles As New List(Of Article) Public Property Articles As New List(Of Article)
Public Property Accounts As New List(Of Account) Public Property Accounts As New List(Of Account)
@ -29,6 +33,8 @@ Namespace Winline
Config = pConfig Config = pConfig
MandatorConfig = pMandatorConfig MandatorConfig = pMandatorConfig
MappingConfig = pMappingConfig MappingConfig = pMappingConfig
FileEx = New File(pLogConfig)
Years = LoadEconomicYears()
End Sub End Sub
''' <summary> ''' <summary>
@ -65,8 +71,14 @@ Namespace Winline
Public Property Year As Integer Public Property Year As Integer
End Class End Class
Private Function LoadEconomicYears() As IEnumerable(Of Integer)
Dim oCurrentYear = Now.Year
Dim oRange As IEnumerable(Of Integer) = Enumerable.Range(oCurrentYear - 10, 12).ToList()
Return oRange
End Function
Public Async Function LoadArticles(pMandator As Mandator) As Task
Public Async Function LoadArticlesAsync(pMandator As Mandator) As Task
Logger.Info("Loading Articles for Mandator [{0}]", pMandator) Logger.Info("Loading Articles for Mandator [{0}]", pMandator)
Dim oYear = Config.GetWinLineYear() Dim oYear = Config.GetWinLineYear()
@ -104,7 +116,7 @@ Namespace Winline
End Try End Try
End Function End Function
Public Async Function LoadPackingUnits(pMandator As Mandator) As Task Public Async Function LoadPackingUnitsAsync(pMandator As Mandator) As Task
Logger.Info("Loading Packing Units for Mandator [{0}]", pMandator) Logger.Info("Loading Packing Units for Mandator [{0}]", pMandator)
Dim oYear = Config.GetWinLineYear() Dim oYear = Config.GetWinLineYear()
@ -155,7 +167,7 @@ Namespace Winline
End Try End Try
End Function End Function
Public Async Function LoadAccounts(pMandator As Mandator) As Task Public Async Function LoadAccountsAsync(pMandator As Mandator) As Task
Logger.Info("Loading Accounts for Mandator [{0}]", pMandator) Logger.Info("Loading Accounts for Mandator [{0}]", pMandator)
Dim oYear = Config.GetWinLineYear() Dim oYear = Config.GetWinLineYear()
@ -207,7 +219,7 @@ Namespace Winline
End Try End Try
End Function End Function
Public Async Function LoadMandators() As Task Public Async Function LoadMandatorsAsync() As Task
Try Try
Dim oSQL = "SELECT [c000], [c003], [c004] FROM [cwlsystem].[dbo].[T001SRV] (NOLOCK)" Dim oSQL = "SELECT [c000], [c003], [c004] FROM [cwlsystem].[dbo].[T001SRV] (NOLOCK)"
Dim oTable = Await Database.GetDatatableAsync(oSQL) Dim oTable = Await Database.GetDatatableAsync(oSQL)
@ -241,13 +253,9 @@ Namespace Winline
End Try End Try
End Function End Function
Public Sub LoadEconomicYears()
Dim oCurrentYear = Now.Year
Dim oRange As IEnumerable(Of Integer) = Enumerable.Range(oCurrentYear - 10, 12).ToList()
Years = oRange
End Sub
Public Async Function LoadDocumentKinds(pMandator As Mandator) As Task
Public Async Function LoadDocumentKindsAsync(pMandator As Mandator) As Task
Dim oYear As Integer = Config.GetWinLineYear() Dim oYear As Integer = Config.GetWinLineYear()
Try Try
@ -388,11 +396,11 @@ Namespace Winline
End Try End Try
End Function End Function
Public Async Function TryGetArticlePrice(pArticle As String, pAccountNumber As String, pQuantity As String, pDocumentDate As Date, pMandator As Mandator, pTemplate As Template) As Task(Of Double) Public Async Function TryGetArticlePriceAsync(pArticle As String, pAccountNumber As String, pQuantity As String, pDocumentDate As Date, pMandator As Mandator, pTemplate As Template) As Task(Of Double)
Return Await TryGetArticlePrice(pArticle, pAccountNumber, pQuantity, pDocumentDate, pMandator, pTemplate, 0) Return Await TryGetArticlePriceAsync(pArticle, pAccountNumber, pQuantity, pDocumentDate, pMandator, pTemplate, 0)
End Function End Function
Public Async Function TryGetArticlePrice(pArticle As String, pAccountNumber As String, pQuantity As String, pDocumentDate As Date, pMandator As Mandator, pTemplate As Template, pWaitingDays As Integer) As Task(Of Double) Public Async Function TryGetArticlePriceAsync(pArticle As String, pAccountNumber As String, pQuantity As String, pDocumentDate As Date, pMandator As Mandator, pTemplate As Template, pWaitingDays As Integer) As Task(Of Double)
Try Try
Dim oUserName = Environment.UserName Dim oUserName = Environment.UserName
Dim oYear As Integer = Config.GetWinLineYear() Dim oYear As Integer = Config.GetWinLineYear()
@ -475,7 +483,7 @@ Namespace Winline
''' <summary> ''' <summary>
''' This function is completely SCHAUM related. ''' This function is completely SCHAUM related.
''' </summary> ''' </summary>
Public Async Function TryGetWaitingDays(pDocumentKind As Integer, pMandator As Mandator) As Task(Of Integer) Public Async Function TryGetWaitingDaysAsync(pDocumentKind As Integer, pMandator As Mandator) As Task(Of Integer)
Try Try
Dim oSql = $" Dim oSql = $"
SELECT [Karenztage].[u012] FROM [{pMandator.Database}].[dbo].[t670] As [Werksdefinition] SELECT [Karenztage].[u012] FROM [{pMandator.Database}].[dbo].[t670] As [Werksdefinition]
@ -894,6 +902,69 @@ Namespace Winline
End Try End Try
End Function End Function
Private ReadOnly RunningNumberVersionRegex As Regex = New Regex("~\d{1,3}$")
Private ReadOnly RunningNumberMaximumLength As Integer = 20
Public Async Function GetVersionedRunningNumberAsync(pDocument As Document, pMandator As Mandator, pAccountNumber As String, pRunningNumber As String) As Task(Of String)
Try
Dim oYear As Integer = Config.GetWinLineYear()
Dim oSql As String = $"
SELECT COUNT(*) FROM [{pMandator.Database}].[dbo].[v250]
WHERE
[c021] = '{pAccountNumber}' AND -- Account '
[c022] = '{pRunningNumber}' AND -- Running Number '
--[c035] = '4711' -- Belegart, needed?
[c144] IS NULL AND -- Stornonummer Angebot
[c145] IS NULL AND -- Stornonummer Auftrag
[c146] IS NULL AND -- Stornonummer Lieferschein
[c147] IS NULL AND -- Stornonummer Faktura
[mesocomp] = '{pMandator.Id}' --AND [mesoyear] = {oYear}
"
Dim oExistingCount = Await Database.GetScalarValueAsync(oSql)
If oExistingCount = 0 Then
Logger.Debug("Running number [{0}] does not exist yet. Returning.")
Return pRunningNumber
Else
Logger.Debug("Running number [{0}] already exists. Checking again.")
Dim oVersionResult = FileEx.GetVersionedString(pRunningNumber, "~"c)
Dim oFinalLength As Integer = oVersionResult.Item1.Count + oVersionResult.Item2.ToString.Count + 1
If oFinalLength > RunningNumberMaximumLength Then
Logger.Warn("Running number is too long ({0} chars total) and cannot be versioned. Versioning needs at least 2 characters.", oFinalLength)
pDocument.AddDocumentError(DocumentErrorType.AttributeValidationFailed, "Das Feld Laufnummer hat die zulässige Länge überschritten.")
Return pRunningNumber
End If
Return Await GetVersionedRunningNumberAsync(pDocument, pMandator, pAccountNumber, $"{oVersionResult.Item1}~{oVersionResult.Item2}")
End If
Catch ex As MultiToolException
Logger.Error(ex)
Throw ex
Catch ex As Exception
Logger.Warn("Error while getting versioned running number for mandator [{0}] and running number [{1}]", pMandator, pRunningNumber)
Logger.Error(ex)
Return Nothing
End Try
End Function
Public Function VersionNumber(pNumber As String) As String
Dim oRunningNumberBase As String
If RunningNumberVersionRegex.IsMatch(pNumber) Then
Dim oSplitNumber = pNumber.Split("~")
oRunningNumberBase = oSplitNumber.First()
Dim oRunningNumberVersion As Integer = Integer.Parse(oSplitNumber.Last())
Return $"{oRunningNumberBase}~{oRunningNumberVersion + 1}"
Else
Return $"{pNumber}~2"
End If
End Function
Public Async Function ExecuteFinalSQL(pDocument As ExportDocument, pTemplate As Template, pMandator As Mandator) As Task(Of Boolean) Public Async Function ExecuteFinalSQL(pDocument As ExportDocument, pTemplate As Template, pMandator As Mandator) As Task(Of Boolean)
Try Try
Dim oSql As String = Patterns.ReplaceForExport(pDocument, pMandator, pTemplate.FinalSQL) Dim oSql As String = Patterns.ReplaceForExport(pDocument, pMandator, pTemplate.FinalSQL)

View File

@ -0,0 +1,15 @@
Imports Microsoft.VisualBasic.ApplicationServices
Namespace My
' Für MyApplication sind folgende Ereignisse verfügbar:
' Startup: Wird beim Starten der Anwendung noch vor dem Erstellen des Startformulars ausgelöst.
' Shutdown: Wird nach dem Schließen aller Anwendungsformulare ausgelöst. Dieses Ereignis wird nicht ausgelöst, wenn die Anwendung mit einem Fehler beendet wird.
' UnhandledException: Wird bei einem Ausnahmefehler ausgelöst.
' StartupNextInstance: Wird beim Starten einer Einzelinstanzanwendung ausgelöst, wenn die Anwendung bereits aktiv ist.
' NetworkAvailabilityChanged: Wird beim Herstellen oder Trennen der Netzwerkverbindung ausgelöst.
Partial Friend Class MyApplication
Protected Overrides Function OnUnhandledException(e As UnhandledExceptionEventArgs) As Boolean
Return MyBase.OnUnhandledException(e)
End Function
End Class
End Namespace

View File

@ -158,6 +158,7 @@
<Import Include="System.Threading.Tasks" /> <Import Include="System.Threading.Tasks" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="ApplicationEvents.vb" />
<Compile Include="DS_DD_ECM.Designer.vb"> <Compile Include="DS_DD_ECM.Designer.vb">
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>
<DesignTime>True</DesignTime> <DesignTime>True</DesignTime>
@ -338,6 +339,7 @@
<ItemGroup> <ItemGroup>
<Content Include="CREATE_DATABASE.sql" /> <Content Include="CREATE_DATABASE.sql" />
<Content Include="MultiTool.ico" /> <Content Include="MultiTool.ico" />
<None Include="Resources\highimportance1.svg" />
<None Include="Resources\highimportance.svg" /> <None Include="Resources\highimportance.svg" />
<None Include="Resources\refreshpivottable.svg" /> <None Include="Resources\refreshpivottable.svg" />
<None Include="Resources\update.svg" /> <None Include="Resources\update.svg" />

View File

@ -370,6 +370,16 @@ Namespace My.Resources
End Get End Get
End Property End Property
'''<summary>
''' Sucht eine lokalisierte Ressource vom Typ DevExpress.Utils.Svg.SvgImage.
'''</summary>
Friend ReadOnly Property highimportance1() As DevExpress.Utils.Svg.SvgImage
Get
Dim obj As Object = ResourceManager.GetObject("highimportance1", resourceCulture)
Return CType(obj,DevExpress.Utils.Svg.SvgImage)
End Get
End Property
'''<summary> '''<summary>
''' Sucht eine lokalisierte Ressource vom Typ DevExpress.Utils.Svg.SvgImage. ''' Sucht eine lokalisierte Ressource vom Typ DevExpress.Utils.Svg.SvgImage.
'''</summary> '''</summary>

View File

@ -187,9 +187,6 @@
<data name="actions_arrow4down" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="actions_arrow4down" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\actions_arrow4down.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value> <value>..\Resources\actions_arrow4down.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data> </data>
<data name="open1" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\open1.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data>
<data name="bo_unknown1" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="bo_unknown1" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\bo_unknown1.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value> <value>..\Resources\bo_unknown1.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data> </data>
@ -199,6 +196,9 @@
<data name="open3" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="open3" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\open3.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value> <value>..\Resources\open3.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data> </data>
<data name="bo_sale" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\bo_sale.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data>
<data name="actions_checkcircled" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="actions_checkcircled" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\actions_checkcircled.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value> <value>..\Resources\actions_checkcircled.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data> </data>
@ -220,9 +220,6 @@
<data name="actions_send1" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="actions_send1" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\actions_send1.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value> <value>..\Resources\actions_send1.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data> </data>
<data name="actions_send4" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\actions_send4.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data>
<data name="actions_send2" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="actions_send2" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\actions_send2.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value> <value>..\Resources\actions_send2.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data> </data>
@ -238,9 +235,6 @@
<data name="open23" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="open23" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\open23.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value> <value>..\Resources\open23.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data> </data>
<data name="insertpagecount" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\insertpagecount.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data>
<data name="actions_reload1" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="actions_reload1" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\actions_reload1.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value> <value>..\Resources\actions_reload1.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data> </data>
@ -274,6 +268,9 @@
<data name="paymentrefund" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="paymentrefund" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\paymentrefund.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value> <value>..\Resources\paymentrefund.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data> </data>
<data name="squarified" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\squarified.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data>
<data name="support" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="support" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\support.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value> <value>..\Resources\support.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data> </data>
@ -289,8 +286,8 @@
<data name="preview" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="preview" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\preview.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value> <value>..\Resources\preview.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data> </data>
<data name="bo_sale" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="insertpagecount" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\bo_sale.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value> <value>..\Resources\insertpagecount.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data> </data>
<data name="exporttopdf" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="exporttopdf" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\exporttopdf.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value> <value>..\Resources\exporttopdf.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
@ -310,14 +307,20 @@
<data name="showallfieldcodes" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="showallfieldcodes" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\showallfieldcodes.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value> <value>..\Resources\showallfieldcodes.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data> </data>
<data name="actions_delete" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="open1" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\actions_delete.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value> <value>..\Resources\open1.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data>
<data name="highimportance" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\highimportance.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data> </data>
<data name="actions_addcircled" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="actions_addcircled" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\actions_addcircled.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value> <value>..\Resources\actions_addcircled.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data> </data>
<data name="squarified" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="actions_delete" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\squarified.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value> <value>..\Resources\actions_delete.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data>
<data name="actions_send4" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\actions_send4.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data> </data>
<data name="logical2" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="logical2" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\logical2.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value> <value>..\Resources\logical2.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
@ -334,7 +337,7 @@
<data name="actions_checkcircled2" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="actions_checkcircled2" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\actions_checkcircled2.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value> <value>..\Resources\actions_checkcircled2.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data> </data>
<data name="highimportance" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="highimportance1" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\highimportance.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value> <value>..\Resources\highimportance1.svg;DevExpress.Utils.Svg.SvgImage, DevExpress.Data.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data> </data>
</root> </root>

View File

@ -0,0 +1,19 @@
<?xml version='1.0' encoding='UTF-8'?>
<svg x="0px" y="0px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" id="Layer_1" style="enable-background:new 0 0 32 32">
<style type="text/css">
.Yellow{fill:#FFB115;}
.Red{fill:#D11C1C;}
.Blue{fill:#1177D7;}
.Green{fill:#039C23;}
.Black{fill:#727272;}
.White{fill:#FFFFFF;}
.st0{opacity:0.5;}
.st1{display:none;}
.st2{display:inline;fill:#039C23;}
.st3{display:inline;fill:#D11C1C;}
.st4{display:inline;fill:#727272;}
</style>
<g id="HighImportance">
<path d="M16,2C8.3,2,2,8.3,2,16s6.3,14,14,14s14-6.3,14-14S23.7,2,16,2z M16,24c-1.1,0-2-0.9-2-2s0.9-2,2-2s2,0.9,2,2 S17.1,24,16,24z M18,18h-4V8h4V18z" class="Red" />
</g>
</svg>

View File

@ -58,6 +58,7 @@ Partial Class frmImportMain
Me.btnCalculatePrices = New DevExpress.XtraBars.BarButtonItem() Me.btnCalculatePrices = New DevExpress.XtraBars.BarButtonItem()
Me.btnOpenLogDirectory2 = New DevExpress.XtraBars.BarButtonItem() Me.btnOpenLogDirectory2 = New DevExpress.XtraBars.BarButtonItem()
Me.txtErrors = New DevExpress.XtraBars.BarStaticItem() Me.txtErrors = New DevExpress.XtraBars.BarStaticItem()
Me.btnShowErrors = New DevExpress.XtraBars.BarButtonItem()
Me.RibbonPage1 = New DevExpress.XtraBars.Ribbon.RibbonPage() Me.RibbonPage1 = New DevExpress.XtraBars.Ribbon.RibbonPage()
Me.RibbonPageGroupLoad = New DevExpress.XtraBars.Ribbon.RibbonPageGroup() Me.RibbonPageGroupLoad = New DevExpress.XtraBars.Ribbon.RibbonPageGroup()
Me.RibbonPageGroupReport = New DevExpress.XtraBars.Ribbon.RibbonPageGroup() Me.RibbonPageGroupReport = New DevExpress.XtraBars.Ribbon.RibbonPageGroup()
@ -223,9 +224,9 @@ Partial Class frmImportMain
'RibbonControl 'RibbonControl
' '
Me.RibbonControl.ExpandCollapseItem.Id = 0 Me.RibbonControl.ExpandCollapseItem.Id = 0
Me.RibbonControl.Items.AddRange(New DevExpress.XtraBars.BarItem() {Me.RibbonControl.ExpandCollapseItem, Me.RibbonControl.SearchEditItem, Me.txtFilesLoaded, Me.btnLoadFiles, Me.btnTransferFile, Me.btnOpenInputDirectory, Me.btnOpenOutputDirectory, Me.btnOpenSchemaDirectory, Me.btnReloadFile, Me.btnTransferAllFiles, Me.btnOpenReport, Me.btnShowXml, Me.btnOpenLogDirectory, Me.btnOpenConfigDirectory, Me.txtCurrentFile, Me.btnConfig, Me.btnRemoveRow, Me.btnTestTransferFile, Me.BarButtonItem1, Me.btnDebugExportReport, Me.btnEditRow, Me.btnCalculatePrices, Me.btnOpenLogDirectory2, Me.txtErrors}) Me.RibbonControl.Items.AddRange(New DevExpress.XtraBars.BarItem() {Me.RibbonControl.ExpandCollapseItem, Me.RibbonControl.SearchEditItem, Me.txtFilesLoaded, Me.btnLoadFiles, Me.btnTransferFile, Me.btnOpenInputDirectory, Me.btnOpenOutputDirectory, Me.btnOpenSchemaDirectory, Me.btnReloadFile, Me.btnTransferAllFiles, Me.btnOpenReport, Me.btnShowXml, Me.btnOpenLogDirectory, Me.btnOpenConfigDirectory, Me.txtCurrentFile, Me.btnConfig, Me.btnRemoveRow, Me.btnTestTransferFile, Me.BarButtonItem1, Me.btnDebugExportReport, Me.btnEditRow, Me.btnCalculatePrices, Me.btnOpenLogDirectory2, Me.txtErrors, Me.btnShowErrors})
resources.ApplyResources(Me.RibbonControl, "RibbonControl") resources.ApplyResources(Me.RibbonControl, "RibbonControl")
Me.RibbonControl.MaxItemId = 39 Me.RibbonControl.MaxItemId = 40
Me.RibbonControl.Name = "RibbonControl" Me.RibbonControl.Name = "RibbonControl"
Me.RibbonControl.Pages.AddRange(New DevExpress.XtraBars.Ribbon.RibbonPage() {Me.RibbonPage1, Me.RibbonPage2}) Me.RibbonControl.Pages.AddRange(New DevExpress.XtraBars.Ribbon.RibbonPage() {Me.RibbonPage1, Me.RibbonPage2})
Me.RibbonControl.RepositoryItems.AddRange(New DevExpress.XtraEditors.Repository.RepositoryItem() {Me.RepositoryItemComboBox1, Me.RepositoryItemProgressBar1}) Me.RibbonControl.RepositoryItems.AddRange(New DevExpress.XtraEditors.Repository.RepositoryItem() {Me.RepositoryItemComboBox1, Me.RepositoryItemProgressBar1})
@ -400,6 +401,14 @@ Partial Class frmImportMain
Me.txtErrors.PaintStyle = DevExpress.XtraBars.BarItemPaintStyle.CaptionGlyph Me.txtErrors.PaintStyle = DevExpress.XtraBars.BarItemPaintStyle.CaptionGlyph
Me.txtErrors.Tag = "Fehler: {0}" Me.txtErrors.Tag = "Fehler: {0}"
' '
'btnShowErrors
'
resources.ApplyResources(Me.btnShowErrors, "btnShowErrors")
Me.btnShowErrors.Enabled = False
Me.btnShowErrors.Id = 39
Me.btnShowErrors.ImageOptions.SvgImage = Global.MultiTool.Form.My.Resources.Resources.highimportance1
Me.btnShowErrors.Name = "btnShowErrors"
'
'RibbonPage1 'RibbonPage1
' '
Me.RibbonPage1.Groups.AddRange(New DevExpress.XtraBars.Ribbon.RibbonPageGroup() {Me.RibbonPageGroupLoad, Me.RibbonPageGroupReport, Me.RibbonPageGroupTransfer, Me.RibbonPageGroupEdit}) Me.RibbonPage1.Groups.AddRange(New DevExpress.XtraBars.Ribbon.RibbonPageGroup() {Me.RibbonPageGroupLoad, Me.RibbonPageGroupReport, Me.RibbonPageGroupTransfer, Me.RibbonPageGroupEdit})
@ -434,6 +443,7 @@ Partial Class frmImportMain
Me.RibbonPageGroupEdit.ItemLinks.Add(Me.btnEditRow) Me.RibbonPageGroupEdit.ItemLinks.Add(Me.btnEditRow)
Me.RibbonPageGroupEdit.ItemLinks.Add(Me.btnRemoveRow) Me.RibbonPageGroupEdit.ItemLinks.Add(Me.btnRemoveRow)
Me.RibbonPageGroupEdit.ItemLinks.Add(Me.btnCalculatePrices) Me.RibbonPageGroupEdit.ItemLinks.Add(Me.btnCalculatePrices)
Me.RibbonPageGroupEdit.ItemLinks.Add(Me.btnShowErrors)
Me.RibbonPageGroupEdit.Name = "RibbonPageGroupEdit" Me.RibbonPageGroupEdit.Name = "RibbonPageGroupEdit"
resources.ApplyResources(Me.RibbonPageGroupEdit, "RibbonPageGroupEdit") resources.ApplyResources(Me.RibbonPageGroupEdit, "RibbonPageGroupEdit")
' '
@ -760,4 +770,5 @@ Partial Class frmImportMain
Friend WithEvents btnCalculatePrices As DevExpress.XtraBars.BarButtonItem Friend WithEvents btnCalculatePrices As DevExpress.XtraBars.BarButtonItem
Friend WithEvents btnOpenLogDirectory2 As DevExpress.XtraBars.BarButtonItem Friend WithEvents btnOpenLogDirectory2 As DevExpress.XtraBars.BarButtonItem
Friend WithEvents txtErrors As DevExpress.XtraBars.BarStaticItem Friend WithEvents txtErrors As DevExpress.XtraBars.BarStaticItem
Friend WithEvents btnShowErrors As DevExpress.XtraBars.BarButtonItem
End Class End Class

View File

@ -256,6 +256,9 @@
<data name="txtErrors.Caption" xml:space="preserve"> <data name="txtErrors.Caption" xml:space="preserve">
<value>Fehler: 0</value> <value>Fehler: 0</value>
</data> </data>
<data name="btnShowErrors.Caption" xml:space="preserve">
<value>Fehler anzeigen</value>
</data>
<data name="RibbonControl.Location" type="System.Drawing.Point, System.Drawing"> <data name="RibbonControl.Location" type="System.Drawing.Point, System.Drawing">
<value>0, 0</value> <value>0, 0</value>
</data> </data>
@ -962,6 +965,12 @@
<data name="&gt;&gt;txtErrors.Type" xml:space="preserve"> <data name="&gt;&gt;txtErrors.Type" xml:space="preserve">
<value>DevExpress.XtraBars.BarStaticItem, DevExpress.XtraBars.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value> <value>DevExpress.XtraBars.BarStaticItem, DevExpress.XtraBars.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data> </data>
<data name="&gt;&gt;btnShowErrors.Name" xml:space="preserve">
<value>btnShowErrors</value>
</data>
<data name="&gt;&gt;btnShowErrors.Type" xml:space="preserve">
<value>DevExpress.XtraBars.BarButtonItem, DevExpress.XtraBars.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data>
<data name="&gt;&gt;RibbonPage1.Name" xml:space="preserve"> <data name="&gt;&gt;RibbonPage1.Name" xml:space="preserve">
<value>RibbonPage1</value> <value>RibbonPage1</value>
</data> </data>

View File

@ -457,12 +457,6 @@ Public Class frmImportMain
LoadDocument(oNewDocument) LoadDocument(oNewDocument)
End If End If
Catch ex As NoMandatorException
FormHelper.ShowError(ex, My.Resources.frmImportMainExtra.Neuladen_des_Dokuments, My.Resources.frmImportMainExtra.Es_konnte_kein_passender_Mandant_ermittelt_werden)
Catch ex As MissingAttributeException
FormHelper.ShowError(ex, My.Resources.frmImportMainExtra.Neuladen_des_Dokuments, "Ein benötigtes Attribut wurde nicht gefunden.")
Catch ex As Exception Catch ex As Exception
FormHelper.ShowError(ex, My.Resources.frmImportMainExtra.Neuladen_des_Dokuments) FormHelper.ShowError(ex, My.Resources.frmImportMainExtra.Neuladen_des_Dokuments)
@ -621,8 +615,10 @@ Public Class frmImportMain
If pDocument.HasErrors = True Then If pDocument.HasErrors = True Then
btnCalculatePrices.Enabled = False btnCalculatePrices.Enabled = False
btnShowErrors.Enabled = True
Else Else
btnCalculatePrices.Enabled = True btnCalculatePrices.Enabled = True
btnShowErrors.Enabled = False
End If End If
If pDocument.Mandator Is Nothing Then If pDocument.Mandator Is Nothing Then
@ -683,8 +679,6 @@ Public Class frmImportMain
txtFilesLoaded.Caption = String.Format(My.Resources.frmImportMainExtra._0__Dateien_geladen, DocumentLoader.Files.Count) txtFilesLoaded.Caption = String.Format(My.Resources.frmImportMainExtra._0__Dateien_geladen, DocumentLoader.Files.Count)
End If End If
Catch ex As NoMandatorException
MsgBox(My.Resources.frmImportMainExtra.Es_konnte_kein_passender_Mandant_ermittelt_werden, MsgBoxStyle.Information, Text)
Catch ex As Exception Catch ex As Exception
FormHelper.ShowError(ex, My.Resources.frmImportMainExtra.Laden_der_Dokumente) FormHelper.ShowError(ex, My.Resources.frmImportMainExtra.Laden_der_Dokumente)
@ -876,6 +870,16 @@ Public Class frmImportMain
End If End If
End Sub End Sub
Private Sub btnShowErrors_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles btnShowErrors.ItemClick
If CurrentDocument IsNot Nothing Then
Dim oErrors = CurrentDocument.Errors.
Select(Function(s) " - " & s).
ToList()
Dim oMessage = String.Join(vbNewLine, oErrors)
MsgBox($"Datei enthält {oErrors.Count} Fehler:{vbNewLine}{vbNewLine}{oMessage}", MsgBoxStyle.Exclamation, Text)
End If
End Sub
#End Region #End Region

View File

@ -90,18 +90,17 @@ Public Class frmMain
Private Async Function LoadWinlineData(Winline As WinlineData) As Task Private Async Function LoadWinlineData(Winline As WinlineData) As Task
Winline.Mandators.Clear() Winline.Mandators.Clear()
Winline.LoadEconomicYears() Await Winline.LoadMandatorsAsync()
Await Winline.LoadMandators()
For Each oMandator As Mandator In Winline.Mandators For Each oMandator As Mandator In Winline.Mandators
SplashScreenManager.SetWaitFormDescription(String.Format(My.Resources.frmImportMainExtra.Lade__0__Konten, oMandator.Id)) SplashScreenManager.SetWaitFormDescription(String.Format(My.Resources.frmImportMainExtra.Lade__0__Konten, oMandator.Id))
Await Winline.LoadAccounts(oMandator) Await Winline.LoadAccountsAsync(oMandator)
SplashScreenManager.SetWaitFormDescription(String.Format(My.Resources.frmImportMainExtra.Lade__0__Artikel, oMandator.Id)) SplashScreenManager.SetWaitFormDescription(String.Format(My.Resources.frmImportMainExtra.Lade__0__Artikel, oMandator.Id))
Await Winline.LoadArticles(oMandator) Await Winline.LoadArticlesAsync(oMandator)
SplashScreenManager.SetWaitFormDescription(String.Format(My.Resources.frmImportMainExtra.Lade__0__Belegarten, oMandator.Id)) SplashScreenManager.SetWaitFormDescription(String.Format(My.Resources.frmImportMainExtra.Lade__0__Belegarten, oMandator.Id))
Await Winline.LoadDocumentKinds(oMandator) Await Winline.LoadDocumentKindsAsync(oMandator)
SplashScreenManager.SetWaitFormDescription(String.Format("Lade {0}/Colli", oMandator.Id)) SplashScreenManager.SetWaitFormDescription(String.Format("Lade {0}/Colli", oMandator.Id))
Await Winline.LoadPackingUnits(oMandator) Await Winline.LoadPackingUnitsAsync(oMandator)
Next Next
My.Winline = Winline My.Winline = Winline

View File

@ -184,7 +184,8 @@ Public Class frmRowEditor
'End If 'End If
' 03.12.21: For now we always remove the error if ANYTHING changed about the field ' 03.12.21: For now we always remove the error if ANYTHING changed about the field
oFieldValue.Error = FieldError.None 'oFieldValue.Error = FieldErrorType.None
oFieldValue.Errors.Clear()
' Save the grid value to the Field ' Save the grid value to the Field
oFieldValue.Final = oValueFromGrid.Trim() oFieldValue.Final = oValueFromGrid.Trim()

View File

@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.6.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
<PackageReference Include="MSTest.TestAdapter" Version="2.1.1" />
<PackageReference Include="MSTest.TestFramework" Version="2.1.1" />
<PackageReference Include="coverlet.collector" Version="1.3.0" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,13 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace MultiTool.Test
{
[TestClass]
public class WinlineDataTest
{
[TestMethod]
public void Test_VersionNumber()
{
}
}
}

View File

@ -9,6 +9,8 @@ Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "MultiTool.Common", "MultiTo
EndProject EndProject
Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "Multitool.Form.Setup", "Multitool.Form.Setup\Multitool.Form.Setup.wixproj", "{A03D1911-C6D6-4AD0-9601-4D277B35E91D}" Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "Multitool.Form.Setup", "Multitool.Form.Setup\Multitool.Form.Setup.wixproj", "{A03D1911-C6D6-4AD0-9601-4D277B35E91D}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MultiTool.Test", "MultiTool.Test\MultiTool.Test.csproj", "{2FCD4E08-F750-49D5-854D-719A55074D30}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -39,6 +41,14 @@ Global
{A03D1911-C6D6-4AD0-9601-4D277B35E91D}.Release|Any CPU.ActiveCfg = Release|x86 {A03D1911-C6D6-4AD0-9601-4D277B35E91D}.Release|Any CPU.ActiveCfg = Release|x86
{A03D1911-C6D6-4AD0-9601-4D277B35E91D}.Release|x86.ActiveCfg = Release|x86 {A03D1911-C6D6-4AD0-9601-4D277B35E91D}.Release|x86.ActiveCfg = Release|x86
{A03D1911-C6D6-4AD0-9601-4D277B35E91D}.Release|x86.Build.0 = Release|x86 {A03D1911-C6D6-4AD0-9601-4D277B35E91D}.Release|x86.Build.0 = Release|x86
{2FCD4E08-F750-49D5-854D-719A55074D30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2FCD4E08-F750-49D5-854D-719A55074D30}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2FCD4E08-F750-49D5-854D-719A55074D30}.Debug|x86.ActiveCfg = Debug|Any CPU
{2FCD4E08-F750-49D5-854D-719A55074D30}.Debug|x86.Build.0 = Debug|Any CPU
{2FCD4E08-F750-49D5-854D-719A55074D30}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2FCD4E08-F750-49D5-854D-719A55074D30}.Release|Any CPU.Build.0 = Release|Any CPU
{2FCD4E08-F750-49D5-854D-719A55074D30}.Release|x86.ActiveCfg = Release|Any CPU
{2FCD4E08-F750-49D5-854D-719A55074D30}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE