MultiTool/MultiTool.Form/frmRowEditor.vb

335 lines
13 KiB
VB.net

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.Language
Imports DigitalData.Modules.Logging
Imports DevExpress.XtraEditors
Imports DevExpress.XtraEditors.Repository
Imports DevExpress.XtraEditors.Controls
Imports DevExpress.XtraGrid.Views.Grid
Public Class frmRowEditor
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()
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())
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())
End If
Dim oFieldValue As FieldValue = oField.Value
Dim oValueFromGrid As String = Utils.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.Error = FieldError.None
' Save the grid value to the Field
oFieldValue.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?.Function?.Name = FUNCTION_GLN Then
e.RepositoryItem = AccountPicker
End If
If oColumn.Config?.Function?.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 = Utils.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
' TODO: Remove this workaround if the conditions for errors are good now
'If e.DisplayText = String.Empty And (
' oField.Value.Error = FieldError.AccountNotFound Or
' oField.Value.Error = FieldError.ArticleNotFound) Then
' e.Appearance.BackColor = Color.LightCoral
'End If
End If
'If oField.Value.HasError Then
' e.Appearance.BackColor = Color.LightCoral
'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