Imports System.Globalization Imports MultiTool.Common.Documents Imports MultiTool.Common.Documents.DocumentRow Imports MultiTool.Common.Winline Imports MultiTool.Common.Winline.Entities Imports MultiTool.Common.Templates Imports MultiTool.Common.Constants Imports DigitalData.Modules.Logging Imports DigitalData.Modules.Base Imports DevExpress.XtraEditors Imports DevExpress.XtraEditors.Repository Imports DevExpress.XtraEditors.Controls Imports DevExpress.XtraGrid.Views.Grid Public Class frmRowEditor Private ReadOnly LogConfig As LogConfig Private ReadOnly Logger As Logger Private ReadOnly FormHelper As FormHelper Private ReadOnly _Table As Template.Table Private ReadOnly _Columns As List(Of String) Private ReadOnly _DataTable As New DataTable Private ReadOnly _Accounts As List(Of Account) Private ReadOnly _Articles As List(Of Article) Private ReadOnly _DocumentKinds As List(Of DocumentKind) Private ReadOnly _DocumentRow As DocumentRow Private ReadOnly MultilineEditor As New RepositoryItemMemoEdit Private ReadOnly AccountPicker As New RepositoryItemSearchLookUpEdit Private ReadOnly ArticlePicker As New RepositoryItemSearchLookUpEdit Private ReadOnly DocumentKindPicker As New RepositoryItemSearchLookUpEdit Private ReadOnly ReadOnlyEditor As New RepositoryItemTextEdit Private Const COL_KEY = "KEY" Private Const COL_VALUE_ORIGINAL = "VALUE_ORIGINAL" Private Const COL_VALUE_EXTERNAL = "VALUE_EXTERNAL" Private Const COL_VALUE_FINAL = "VALUE_FINAL" Public ReadOnly Property DocumentRow As DocumentRow Get Return _DocumentRow End Get End Property Public Sub New(pLogConfig As LogConfig, pColumns As List(Of String), pDocumentRow As DocumentRow, pMandator As Mandator, pWinline As WinlineData, pTable As Template.Table) InitializeComponent() LogConfig = pLogConfig Logger = pLogConfig.GetLogger() FormHelper = New FormHelper(pLogConfig, Me) _Columns = pColumns _Accounts = pWinline.Accounts.Where(Function(a) a.Mandator.Id = pMandator.Id).ToList() _Articles = pWinline.Articles.Where(Function(a) a.Mandator.Id = pMandator.Id).ToList() _DocumentKinds = pWinline.DocumentKinds.Where(Function(k) k.Mandator.Id = pMandator.Id).ToList() _DocumentRow = pDocumentRow _Table = pTable ' TODO: Show text similar to NullText when account number is not in the list/datasource AccountPicker.DataSource = _Accounts AccountPicker.DisplayMember = "Name" AccountPicker.ValueMember = "Id" 'AccountPicker.NullText = "[Kein Konto gefunden]" ArticlePicker.DataSource = _Articles ArticlePicker.DisplayMember = "Description" ArticlePicker.ValueMember = "Id" 'ArticlePicker.NullText = "[Kein Artikel gefunden]" DocumentKindPicker.DataSource = _DocumentKinds DocumentKindPicker.ValueMember = "Id" DocumentKindPicker.DisplayMember = "Name" 'DocumentKindPicker.NullText = "[Keine Belegart gefunden]" ReadOnlyEditor.ReadOnly = True 'DatePicker.CalendarTimeEditing = DevExpress.Utils.DefaultBoolean.False 'DatePicker.EditMask = "yyyy-MM-dd" 'DatePicker.Mask.MaskType = DevExpress.XtraEditors.Mask.MaskType.DateTimeAdvancingCaret 'DatePicker.DisplayFormat.FormatString = "yyyy-MM-dd" ' DatePicker.DisplayFormat.FormatType = DevExpress.Utils.FormatType.DateTime 'DatePicker.DisplayFormat.FormatString = "d" 'DatePicker.EditFormat.FormatString = "yyyy-MM-dd" 'DatePicker.EditFormat.FormatType = DevExpress.Utils.FormatType.DateTime 'DatePicker.EditFormat.FormatString = "d" 'DatePicker.Mask.UseMaskAsDisplayFormat = True 'DatePicker.Mask.MaskType = DevExpress.XtraEditors.Mask.MaskType.DateTime ' DatePicker.Mask.EditMask = "yyyy-MM-dd" 'AddHandler DatePicker.ParseEditValue, AddressOf DatePicker_ParseEditValue 'MaskDateEditor.Mask.EditMask = "yyyy-MM-dd" 'MaskDateEditor.Mask.MaskType = DevExpress.XtraEditors.Mask.MaskType.Simple End Sub Private Sub DatePicker_ParseEditValue(sender As Object, e As ConvertEditValueEventArgs) If TypeOf sender Is RepositoryItemDateEdit Then Debug.WriteLine($"RepoItem # {e.Value} # {e.Value.GetType.Name}") ElseIf TypeOf sender Is DateEdit Then Debug.WriteLine($"DateEdit # {e.Value} # {e.Value.GetType.Name}") End If End Sub Private Sub frmRowEditor_Load(sender As Object, e As EventArgs) Handles Me.Load Try Dim oDict = New Dictionary(Of String, FieldValue) For Each oColumnName As String In _Columns Dim oField = _DocumentRow.Fields. Where(Function(f) f.Key = oColumnName). SingleOrDefault() Dim oColumn = _Table.Columns. Where(Function(c) c.Name = oColumnName). SingleOrDefault() ' Only Show Columns that are set to visible If oColumn?.Config?.IsVisible = False Then Continue For End If If oField.Value Is Nothing Then ' TODO: Do we need to create a new field value here? ' aka. do we need to configure fieldvalue from column settings oDict.Add(oColumnName, New FieldValue(LogConfig)) Else oDict.Add(oColumnName, oField.Value) End If Next _DataTable.Columns.Clear() _DataTable.Columns.Add(COL_KEY) _DataTable.Columns.Add(COL_VALUE_ORIGINAL) _DataTable.Columns.Add(COL_VALUE_EXTERNAL) _DataTable.Columns.Add(COL_VALUE_FINAL) For Each oKV In oDict _DataTable.Rows.Add(oKV.Key, oKV.Value.Original, oKV.Value.External, oKV.Value.Final) Next GridControl1.DataSource = _DataTable Catch ex As Exception FormHelper.ShowError(ex, My.Resources.frmShared.Laden_des_Formulars) End Try End Sub Private Sub btnSave_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles btnSave.ItemClick SaveAndClose() End Sub Private Sub SaveAndClose() Try GridView1.CloseEditor() For Each oRow As DataRow In _DataTable.Rows Dim oField = _DocumentRow.Fields. Where(Function(f) f.Key = oRow.Item(COL_KEY)). SingleOrDefault() ' TODO: Why do we need to create new fieldvalues here? ' aka. why would the be a value for which no fieldvalue exists yet? ' If there are (non-virtual) fields in the template which do not have a value yet, ' this might happen. If oField.Key Is Nothing Then oField = New KeyValuePair(Of String, FieldValue)(oRow.Item(COL_KEY), New FieldValue(LogConfig)) End If Dim oFieldValue As FieldValue = oField.Value Dim oValueFromGrid As String = ObjectEx.NotNull(oRow.Item(COL_VALUE_FINAL), String.Empty) ' Do the dirtiest date validation of all times If oField.Value.DataType = ColumnType.Date And oValueFromGrid.Length > 0 Then If TryParseDate(oValueFromGrid) Is Nothing Then MsgBox(String.Format(My.Resources.frmRowEditorExtra.Datumswert_für___0___enthält_einen_ungüligen_Wert, oField.Key), MsgBoxStyle.Exclamation, Text) Exit Sub End If End If ' If the value was changed If Not oFieldValue.Final.Equals(oValueFromGrid) Then ' If new value is not empty, any error will be removed. ' Could cause problems in the future because a value might not equal to 'no error'. 'If oValueFromGrid <> String.Empty Then ' oFieldValue.Error = FieldError.None 'End If ' 03.12.21: For now we always remove the error if ANYTHING changed about the field oFieldValue.Errors.Clear() ' Save the grid value to the Field oFieldValue.SetValue("Final", oValueFromGrid.Trim()) If _DocumentRow.Fields.ContainsKey(oField.Key) Then _DocumentRow.Fields.Item(oField.Key) = oFieldValue Else _DocumentRow.Fields.Add(oField.Key, oFieldValue) End If End If Next DialogResult = DialogResult.OK Close() Catch ex As Exception MsgBox("") Logger.Error(ex) End Try End Sub Private Function TryParseDate(pValue As String) Try Return Date.ParseExact(pValue, "yyyy-MM-dd", CultureInfo.InvariantCulture) Catch ex As Exception Return Nothing End Try End Function Private Sub btnApplyFromWinline_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles btnApplyFromWinline.ItemClick CopyValueToFinalColumn(COL_VALUE_EXTERNAL) End Sub Private Sub btnApplyFromOriginal_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles btnApplyFromOriginal.ItemClick CopyValueToFinalColumn(COL_VALUE_ORIGINAL) End Sub Private Sub btnClearValue_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles btnClearValue.ItemClick CopyValueToFinalColumn(String.Empty) End Sub Private Sub CopyValueToFinalColumn(pSourceColumnNameOrValue As String) Dim oSelectedRow As DataRow = GridView1.GetDataRow(GridView1.FocusedRowHandle) If oSelectedRow Is Nothing Then Exit Sub End If Select Case pSourceColumnNameOrValue Case COL_VALUE_EXTERNAL oSelectedRow.Item(COL_VALUE_FINAL) = oSelectedRow.Item(pSourceColumnNameOrValue) Case COL_VALUE_ORIGINAL oSelectedRow.Item(COL_VALUE_FINAL) = oSelectedRow.Item(pSourceColumnNameOrValue) Case Else oSelectedRow.Item(COL_VALUE_FINAL) = pSourceColumnNameOrValue End Select oSelectedRow.AcceptChanges() GridView1.CloseEditor() GridView1.RefreshData() End Sub Private Sub GridView1_CustomRowCellEdit(sender As Object, e As CustomRowCellEditEventArgs) Handles GridView1.CustomRowCellEdit Dim oDataRow As DataRow = GridView1.GetDataRow(e.RowHandle) Dim oKey As String = oDataRow.Item(COL_KEY) If e.Column.FieldName = COL_VALUE_ORIGINAL Or e.Column.FieldName = COL_VALUE_FINAL Then If e.CellValue.ToString.Length > 100 Then e.RepositoryItem = MultilineEditor End If End If If e.Column.FieldName = COL_VALUE_FINAL Then Dim oColumn = _Table.Columns. Where(Function(c) c.Name = oKey). SingleOrDefault() If oColumn Is Nothing Then Exit Sub End If If oColumn.Config?.Functions.Any(Function(f) f.Name = FUNCTION_GLN) Then e.RepositoryItem = AccountPicker End If If oColumn.Config?.Functions.Any(Function(f) f.Name = FUNCTION_EAN) Then e.RepositoryItem = ArticlePicker End If If e.CellValue.ToString.Length > 30 Then e.RepositoryItem = MultilineEditor End If If oColumn.Config?.IsReadOnly Then e.RepositoryItem = ReadOnlyEditor End If End If End Sub 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) Dim oValue As String = ObjectEx.NotNull(oDataRow.Item(COL_VALUE_FINAL), String.Empty) Dim oColumn = _Table.Columns. Where(Function(c) c.Name = oKey). SingleOrDefault() Dim oField = _DocumentRow.Fields. Where(Function(f) f.Key = oKey). SingleOrDefault() If e.Column.FieldName = COL_VALUE_FINAL Then If oColumn IsNot Nothing Then If oColumn.Config?.IsReadOnly Then e.Appearance.BackColor = Color.LightGray End If End If If oField.Value.HasError Then e.Appearance.BackColor = Color.LightCoral End If End If End Sub Private Sub frmRowEditor_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown If e.KeyCode = Keys.F5 Then SaveAndClose() End If End Sub End Class