Compare commits

...

5 Commits

Author SHA1 Message Date
Jonathan Jenne
2894d398d0 Version 1.3.0.0 2022-05-03 16:25:33 +02:00
Jonathan Jenne
8743f0c4b1 Filter out inactive accounts and document kinds 2022-05-03 15:59:18 +02:00
Jonathan Jenne
8e02ed7159 Rename TemplateConfigItem to FieldConfig 2022-05-03 15:38:35 +02:00
Jonathan Jenne
5accfbe002 Add PreferExternalValue to control which value will be the final value 2022-05-03 15:32:35 +02:00
Jonathan Jenne
5fe4079028 Execute SQL function when loading document 2022-05-03 12:29:08 +02:00
12 changed files with 156 additions and 79 deletions

View File

@@ -7,6 +7,7 @@ Imports MultiTool.Common.Templates
Imports MultiTool.Common.Winline
Imports MultiTool.Common.Winline.Entities
Imports MultiTool.Common.Constants
Imports DigitalData.Modules.Database
Namespace Documents
Public Class DocumentLoader
@@ -16,6 +17,7 @@ Namespace Documents
Private ReadOnly MappingConfig As MappingConfig
Private ReadOnly TemplateConfig As TemplateConfig
Private ReadOnly ApplicationConfig As Config
Private ReadOnly Patterns As Patterns
Public Property Files As New List(Of Document)
@@ -45,12 +47,13 @@ Namespace Documents
End Sub
End Class
Public Sub New(pLogConfig As LogConfig, pWinline As WinlineData, pMappingConfig As MappingConfig, pTemplateConfig As TemplateConfig, pApplicationConfig As Config)
MyBase.New(pLogConfig)
Public Sub New(pLogConfig As LogConfig, pWinline As WinlineData, pDatabase As MSSQLServer, pMappingConfig As MappingConfig, pTemplateConfig As TemplateConfig, pGeneralConfig As GeneralConfig, pApplicationConfig As Config)
MyBase.New(pLogConfig, pDatabase)
Winline = pWinline
MappingConfig = pMappingConfig
TemplateConfig = pTemplateConfig
ApplicationConfig = pApplicationConfig
Patterns = New Patterns(pLogConfig, pGeneralConfig)
End Sub
Public Async Function LoadFiles(pTemplate As Template, pMandator As Mandator) As Task(Of Boolean)
@@ -239,29 +242,20 @@ Namespace Documents
' oValue = oDate.ToString("d")
'End If
oFields.Add(oSubElement.Name.ToString, New DocumentRow.FieldValue With {
.Original = oValue,
.Final = oValue,
.DataType = oColumn.DataType,
.IsRequired = oRequired,
.IsVirtual = oColumn.Config.IsVirtual,
.SortKey = oColumnSortKey
})
Dim oFieldValue = GetFieldValueFromColumn(oColumn, oColumnSortKey)
oFieldValue.SetOriginalValue(oValue)
oFields.Add(oSubElement.Name.ToString, oFieldValue)
Else
Logger.Debug("Creating new field from Configuration: [{0}]", oColumn.Name)
Dim oValue = New DocumentRow.FieldValue With {
.SortKey = oColumnSortKey,
.IsVirtual = oColumn.Config.IsVirtual
}
Dim oFieldValue = GetFieldValueFromColumn(oColumn, oColumnSortKey)
'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.")
oFieldValue.AddFieldError(FieldErrorType.MissingValue, $"Attribut {oSubElement.Name} wird benötigt, ist aber nicht gefüllt.")
End If
oFields.Add(oColumn.Name, oValue)
oFields.Add(oColumn.Name, oFieldValue)
End If
oColumnSortKey += 1
@@ -288,6 +282,16 @@ Namespace Documents
Return pDocument
End Function
Public Function GetFieldValueFromColumn(pColumn As Template.Column, pSortKey As Integer) As DocumentRow.FieldValue
Return New DocumentRow.FieldValue With {
.DataType = pColumn.DataType,
.IsRequired = pColumn.IsRequired,
.IsVirtual = pColumn.Config.IsVirtual,
.PreferExternalValue = pColumn.Config.PreferExternalValue,
.SortKey = pSortKey
}
End Function
Private Async Function MatchDataFromWinLine(pDocument As Document, pMandators As List(Of Mandator), pMandator As Mandator, pTemplate As Template) As Task(Of Document)
Dim oMandators As List(Of Mandator) = pMandators.
@@ -314,34 +318,59 @@ Namespace Documents
' Set mandator befor applying any functions that depend on a valid mandator
pDocument.Mandator = oMandator
RaiseEvent FileLoadProgress(Me, New FileLoadProgressInfo(FilesTotal, FilesLoaded) With {
.RunningFunction = "Winline-Funktionen"
})
RaiseEvent FileLoadProgress(Me, New FileLoadProgressInfo(FilesTotal, FilesLoaded) With {.RunningFunction = "Winline-Funktionen"})
pDocument = Await ApplyDefinedItemFunctionsForImportAsync(pDocument, oMandator, pTemplate)
pDocument = ApplyDynamicItemFunctionsForImport(pDocument, oMandator)
RaiseEvent FileLoadProgress(Me, New FileLoadProgressInfo(FilesTotal, FilesLoaded) With {
.RunningFunction = "Preis-Funktionen"
})
RaiseEvent FileLoadProgress(Me, New FileLoadProgressInfo(FilesTotal, FilesLoaded) With {.RunningFunction = "Preis-Funktionen"})
If ApplicationConfig.AutomaticPriceCalculation = True Then
' These functions will only be applied if the document does not have errors
pDocument = Await MaybeApplyPriceFunctions(pDocument, oMandator, pTemplate)
End If
RaiseEvent FileLoadProgress(Me, New FileLoadProgressInfo(FilesTotal, FilesLoaded) With {
.RunningFunction = "Feld-Funktionen"
})
RaiseEvent FileLoadProgress(Me, New FileLoadProgressInfo(FilesTotal, FilesLoaded) With {.RunningFunction = "Feld-Funktionen"})
pDocument = ApplySQLFunctionForImport(pDocument, TemplateConfig.SqlItems)
' This function needs to be the last one because
' it can relate to any previously set value
ApplyFieldFunctionForImport(pDocument, oMandator, pTemplate)
pDocument = ApplyFieldFunctionForImport(pDocument, oMandator, pTemplate)
End If
Return pDocument
End Function
Private Function ApplySQLFunctionForImport(pDocument As Document, pSQLConfig As List(Of FieldConfig)) As Document
For Each oSQLConfigItem In pSQLConfig
' FieldList is a list of fields that will be changed
' Example: Setting SQL for Article StorageLocation will invoke the sql for each row
Dim oRowList = pDocument.Rows.
Where(Function(row) row.Fields.Any(Function(field) field.Key = oSQLConfigItem.Name)).
ToList()
For Each oRow As DocumentRow In oRowList
Dim oSQL = oSQLConfigItem.Function.Params
Dim oField = oRow.Fields.
Where(Function(field) field.Key = oSQLConfigItem.Name).
SingleOrDefault()
oSQL = Patterns.ReplaceForImport(pDocument, oRow, oSQL)
Dim oValue = Database.GetScalarValue(oSQL)
If oValue IsNot Nothing Then
oField.Value.SetExternalValue(oValue)
End If
Next
Next
Return pDocument
End Function
''' <summary>
''' Apply price calculation to the documents products
'''
@@ -465,7 +494,7 @@ Namespace Documents
Dim oValue As String = Utils.NotNull(oRawValue, String.Empty)
If oValue <> String.Empty Then
oField.Value.Final = oValue
oField.Value.SetExternalValue(oValue)
End If
Else
@@ -512,7 +541,7 @@ Namespace Documents
pDocument.Rows.
SelectMany(Function(row) row.Fields).
Where(Function(field) field.Key = oMapping.DestinationItem).
SetValue(Sub(field) field.Value.Final = oMapping.DestinationValue)
SetValue(Sub(field) field.Value.SetExternalValue(oMapping.DestinationValue))
Else
' don't do anything
@@ -573,8 +602,7 @@ Namespace Documents
Dim oArticlePrice As Double = Await Winline.TryGetArticlePriceAsync(oArticleNumber, oAccountNumber, oQuantity, oDocumentDate, pMandator, pTemplate, oWaitingDays)
If oArticlePrice > 0 Then
oPriceItem.External = oArticlePrice
oPriceItem.Final = oArticlePrice
oPriceItem.SetExternalValue(oArticlePrice)
Logger.Info("Price for Item [{0}] set to [{1}]", pPriceField, oArticlePrice)
Else
Logger.Warn("Price for Item [{0}] could not be found!", pPriceField)
@@ -584,9 +612,9 @@ Namespace Documents
Private Sub SetArticleByEAN(pRow As DocumentRow, pMandator As Mandator, pArticleField As String)
Dim oNumberItem As DocumentRow.FieldValue = pRow.Fields.GetOrDefault(pArticleField)
Dim oArticleNumber = Winline.TryGetArticleNumber(oNumberItem.Original, pMandator)
If oArticleNumber IsNot Nothing Then
oNumberItem.External = oArticleNumber
oNumberItem.Final = oArticleNumber
oNumberItem.SetExternalValue(oArticleNumber)
Else
'oNumberItem.Error = FieldErrorType.ArticleNotFound
oNumberItem.AddFieldError(FieldErrorType.ArticleNotFound, $"EAN in Attribut '{pArticleField}' konnte nicht aufgelöst werden.")
@@ -610,12 +638,10 @@ Namespace Documents
' If an account was found, set it for External and Final value
If oAccount IsNot Nothing Then
oNumberItem.External = oAccount.Id
oNumberItem.Final = oAccount.Id
oNumberItem.SetExternalValue(oAccount.Id)
If oContainsAccountName Then
oNameItem.External = oAccount.Name
oNameItem.Final = oAccount.Name
oNameItem.SetExternalValue(oAccount.Name)
Else
' TODO: What to to if name field is missing or not set?
'oRow.Fields.Add(pNameField, New DocumentRow.FieldValue() With {
@@ -654,8 +680,7 @@ Namespace Documents
Dim oVersionedNumber = Await Winline.GetVersionedRunningNumberAsync(pDocument, pMandator, oAccountNumber, oRunningNumber)
If oVersionedNumber <> oRunningNumber Then
oRunningNumberItem.External = oVersionedNumber
oRunningNumberItem.Final = oVersionedNumber
oRunningNumberItem.SetExternalValue(oVersionedNumber)
End If
Catch ex As Exception

View File

@@ -51,6 +51,18 @@ Namespace Documents
Return SortKey.CompareTo(DirectCast(other, DocumentRow).SortKey)
End Function
''' <summary>
''' TODO: Use this class to
''' </summary>
Public Class Field
Public ReadOnly Property Name
Public Property Value As FieldValue
Public Sub New(pName As String)
Name = pName
End Sub
End Class
Public Class FieldValue
Private _Final As String = ""
Private _External As String = ""
@@ -60,38 +72,33 @@ Namespace Documents
Public Property Errors As New List(Of FieldError)
Public Property Original As String
Public ReadOnly Property Original As String
Get
Return FormatValue(_Original, DataType)
End Get
Set(value As String)
_Original = value
End Set
End Property
Public Property External As String
Public ReadOnly Property External As String
Get
Return FormatValue(_External, DataType)
End Get
Set(value As String)
_External = value
End Set
End Property
Public Property Final As String
Public ReadOnly Property Final As String
Get
Return FormatValue(_Final, DataType)
End Get
Set(value As String)
_Final = value
End Set
End Property
Public Property IsRequired As Boolean = False
Public Property IsVirtual As Boolean = False
Public Property PreferExternalValue As Boolean = True
Public Property SortKey As Integer = 0
Public Function GetValue(pValueType) As String
Public Sub New()
End Sub
Public Function GetValue(pValueType As String) As String
Select Case pValueType
Case "Original"
Return Original
@@ -104,6 +111,19 @@ Namespace Documents
End Select
End Function
Public Sub SetValue(pValueType As String, pValue As String)
Select Case pValueType
Case "Original"
_Original = pValue
Case "External"
_External = pValue
Case "Final"
_Final = pValue
Case Else
' Noop
End Select
End Sub
Public Sub AddFieldError(pType As FieldErrorType, pMessage As String)
Errors.Add(New FieldError() With {
.Type = pType,
@@ -111,6 +131,27 @@ Namespace Documents
})
End Sub
Public Sub SetExternalValue(pValue As String)
_External = pValue
' Set the external value as the final value, overriding the original / previous external value
' if the external value should be preferred
If PreferExternalValue = True Then
_Final = pValue
End If
' If there is no Original value (because the field is virtual),
' set the external value as the final value regardless of the PreferExternalValue setting
If Original = String.Empty Then
_Final = pValue
End If
End Sub
Public Sub SetOriginalValue(pValue As String)
_Original = pValue
_Final = pValue
End Sub
Public ReadOnly Property HasError As Boolean
Get
' Required check was moved to DocumentLoader

View File

@@ -151,7 +151,7 @@
<Compile Include="Winline\Entities\Contact.vb" />
<Compile Include="Winline\Entities\DocumentKind.vb" />
<Compile Include="Winline\Entities\Mandator.vb" />
<Compile Include="Templates\TemplateConfigItem.vb" />
<Compile Include="Templates\FieldConfig.vb" />
<Compile Include="Winline\WebServiceData.vb" />
<Compile Include="XmlData.vb" />
</ItemGroup>

View File

@@ -56,11 +56,7 @@ Public Class ReportGenerator(Of TReport As IReport)
{"Lagerstand", "Text10"}
})
Dim oSQLConfig = TemplateConfig.Items.
Where(Function(item) item.Function.Name = Constants.FUNCTION_SQL).
ToList()
pDocument = FillFieldValuesFromSQL(pDocument, oSQLConfig, oFilePath)
pDocument = FillFieldValuesFromSQL(pDocument, TemplateConfig.SqlItems, oFilePath)
Dim oHeadRow = pDocument.Rows.
Where(Function(r) r.TableName.EndsWith("T025")).
@@ -107,7 +103,7 @@ Public Class ReportGenerator(Of TReport As IReport)
Return oResult
End Function
Private Function FillFieldValuesFromSQL(pDocument As Document, pSQLConfig As List(Of TemplateConfigItem), pReportFileName As String) As Document
Private Function FillFieldValuesFromSQL(pDocument As Document, pSQLConfig As List(Of FieldConfig), pReportFileName As String) As Document
For Each oSQLConfigItem In pSQLConfig
' FieldList is a list of fields that will be changed
' Example: Setting SQL for Article StorageLocation will invoke the sql for each row
@@ -116,17 +112,17 @@ Public Class ReportGenerator(Of TReport As IReport)
ToList()
For Each oRow As DocumentRow In oRowList
Dim oSQL = oSQLConfigItem.Function.Params
Dim oField = oRow.Fields.
Where(Function(field) field.Key = oSQLConfigItem.Name).
SingleOrDefault()
Dim oSQL = oSQLConfigItem.Function.Params
oSQL = Patterns.ReplaceForImport(pDocument, oRow, pReportFileName, oSQL)
oSQL = Patterns.ReplaceForImportFinalSQL(pDocument, pReportFileName, oSQL)
Dim oValue = Database.GetScalarValue(oSQL)
If oValue IsNot Nothing Then
oField.Value.Final = oValue
oField.Value.SetExternalValue(oValue)
End If
Next
Next

View File

@@ -2,7 +2,7 @@
Imports DigitalData.Modules.Language
Namespace Templates
Public Class TemplateConfigItem
Public Class FieldConfig
Public Property Name As String
Public Property Table As String
Public Property Type As ColumnType
@@ -14,6 +14,7 @@ Namespace Templates
Public Property IsVisible As Boolean
Public Property IsRequired As Boolean
Public Property IsVirtual As Boolean
Public Property PreferExternalValue As Boolean
Public Property [Function] As ColumnFunction

View File

@@ -123,7 +123,7 @@ Namespace Templates
''' Required value from Schema. This value will be written in the ColumnConfig and is not relevant from that point on.
''' </summary>
Public Property IsRequired As Boolean
Public Property Config As TemplateConfigItem
Public Property Config As FieldConfig
Public Overrides Function ToString() As String
Return Name

View File

@@ -6,9 +6,17 @@ Namespace Templates
''' Class for loading column/field config from database
''' </summary>
Public Class TemplateConfig
Public Property Items As List(Of TemplateConfigItem)
Public Property Items As List(Of FieldConfig)
Public Function GetColumn(pName As String, pTable As String) As TemplateConfigItem
Public ReadOnly Property SqlItems As List(Of FieldConfig)
Get
Return Items.
Where(Function(item) item.Function.Name = Constants.FUNCTION_SQL).
ToList()
End Get
End Property
Public Function GetColumn(pName As String, pTable As String) As FieldConfig
Return Items.
Where(Function(c) c.Name = pName And c.Table = pTable).
FirstOrDefault()

View File

@@ -154,21 +154,22 @@ Namespace Templates
Public Async Function LoadTemplateConfiguration() As Task(Of Boolean)
Try
Dim oTable As DataTable = Await Database.GetDatatableAsync(SQL_VWMT_ITEMS)
Dim oItems As New List(Of TemplateConfigItem)
Dim oItems As New List(Of FieldConfig)
For Each oRow As DataRow In oTable.Rows
Dim oColumn As New TemplateConfigItem() With {
Dim oColumn As New FieldConfig() With {
.Template = oRow.ItemEx("TEMPLATE_NAME", String.Empty),
.Table = oRow.ItemEx("XML_TABLE", String.Empty),
.Name = oRow.ItemEx("XML_ITEM", String.Empty),
.Type = TemplateConfigItem.ConvertType(ItemEx(oRow, "DATA_TYPE", String.Empty)),
.Type = FieldConfig.ConvertType(ItemEx(oRow, "DATA_TYPE", String.Empty)),
.OrderKey = oRow.ItemEx("ORDER_KEY", 0),
.IsReadOnly = oRow.ItemEx("IS_READ_ONLY", False),
.IsVisible = oRow.ItemEx("IS_VISIBLE", True),
.IsRequired = oRow.ItemEx("IS_REQUIRED", False),
.IsVirtual = oRow.ItemEx("IS_VIRTUAL", False),
.IsHead = oRow.ItemEx("IS_HEAD", True),
.[Function] = New TemplateConfigItem.ColumnFunction With {
.PreferExternalValue = oRow.ItemEx("PREFER_EXTERNAL", True),
.[Function] = New FieldConfig.ColumnFunction With {
.Id = oRow.ItemEx("FUNCTION_ID", 0),
.Name = oRow.ItemEx("FUNCTION_NAME", String.Empty),
.Params = oRow.ItemEx("FUNCTION_PARAMETERS", String.Empty)
@@ -242,10 +243,10 @@ Namespace Templates
For Each oTable In oTemplate.Tables
For Each oColumn As Template.Column In oTable.Columns
Dim oConfig As TemplateConfigItem = pTemplateConfig.GetColumn(oColumn.Name, oTable.Name)
Dim oConfig As FieldConfig = pTemplateConfig.GetColumn(oColumn.Name, oTable.Name)
If oConfig Is Nothing Then
oConfig = New TemplateConfigItem With {
oConfig = New FieldConfig With {
.IsRequired = oColumn.IsRequired,
.Name = oColumn.Name
}

View File

@@ -182,7 +182,8 @@ Namespace Winline
[c260] -- GLN
FROM [{pMandator.Server}].[{pMandator.Database}].[dbo].[v050]
WHERE
c139 IS NULL
c139 IS NULL -- Kontentyp
AND c105 IS NULL -- Inaktiv
AND mesocomp = '{pMandator.Id}'
AND mesoyear = {oYear}"
Dim oTable = Await Database.GetDatatableAsync(oSQL)
@@ -270,6 +271,7 @@ Namespace Winline
[c001] LIKE 'Werk%(VK)' OR
[c001] LIKE 'Werk%(WK)'
)
AND c129 IS NULL -- Inaktiv
AND [mesocomp] = '{pMandator.Id}' AND [mesoyear] = {oYear}"
Dim oTable As DataTable = Await Database.GetDatatableAsync(oSQL)
Dim oKinds As New List(Of DocumentKind)

View File

@@ -13,7 +13,7 @@ Imports System.Runtime.InteropServices
<Assembly: AssemblyCompany("Digital Data")>
<Assembly: AssemblyProduct("WebService Multitool")>
<Assembly: AssemblyCopyright("Copyright © 2022")>
<Assembly: AssemblyTrademark("1.2.9.4")>
<Assembly: AssemblyTrademark("1.3.0.0")>
<Assembly: ComVisible(False)>
@@ -31,5 +31,5 @@ Imports System.Runtime.InteropServices
' indem Sie "*" wie unten gezeigt eingeben:
' <Assembly: AssemblyVersion("1.0.*")>
<Assembly: AssemblyVersion("1.2.9.4")>
<Assembly: AssemblyVersion("1.3.0.0")>
<Assembly: AssemblyFileVersion("1.0.0.0")>

View File

@@ -91,7 +91,11 @@ Public Class frmImportMain
lookupMandator.ForceInitialize()
lookupMandator.Properties.View.BestFitColumns()
DocumentLoader = New DocumentLoader(LogConfig, Winline, My.MappingConfiguration, My.TemplateConfiguration, ConfigManager.Config)
DocumentLoader = New DocumentLoader(LogConfig, Winline, Database,
My.MappingConfiguration,
My.TemplateConfiguration,
My.GeneralConfiguration,
ConfigManager.Config)
DocumentCleaner = New DocumentCleaner(LogConfig, CurrentTemplate)
GridLoader = New GridLoader(LogConfig)

View File

@@ -184,11 +184,10 @@ Public Class frmRowEditor
'End If
' 03.12.21: For now we always remove the error if ANYTHING changed about the field
'oFieldValue.Error = FieldErrorType.None
oFieldValue.Errors.Clear()
' Save the grid value to the Field
oFieldValue.Final = oValueFromGrid.Trim()
oFieldValue.SetValue("Final", oValueFromGrid.Trim())
If _DocumentRow.Fields.ContainsKey(oField.Key) Then
_DocumentRow.Fields.Item(oField.Key) = oFieldValue