using Comal.Classes;
using InABox.Clients;
using InABox.Core;
using InABox.DynamicGrid;
using InABox.Wpf;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using InABox.Configuration;
using PRSDesktop.Panels.DataEntry.Grids;
namespace PRSDesktop;
public class DataEntryPanelSettings : BaseObject, IUserConfigurationSettings
{
private static readonly double DefaultCacheAge = 7;
[NullEditor]
public double PreviewWidth { get; set; }
[Comment("Age of cached documents before they are deleted (days)")]
[DoubleEditor]
public double CacheAge { get; set; } = DefaultCacheAge;
}
///
/// Interaction logic for DataEntryPanel.xaml
///
public partial class DataEntryPanel : UserControl, IBasePanel, IDynamicEditorHost
{
private DataEntryPanelSettings _settings;
//IPopupEditorControl? _popup;
private IDynamicDataGrid? _grid;
private Type? _selectedType;
// The id of the entity currently being edited.
private Guid _entityID;
// The id of the entity we selected from the grid, as it was when we selected it; this is to cancel, because the lookup for the item
// updates _entityID, and we need to set it back when cancelling.
private Guid _originalID;
private bool _processenabled;
private Entity? _entity;
private Button? _process;
private bool _isChanged;
private bool IsChanged
{
get => _isChanged;
set
{
if(_isChanged != value)
{
_isChanged = value;
Editor.HideButtons = !value;
if (_process != null)
_process.IsEnabled = value;
_documents._dataEntryGrid.IsEnabled = !value;
}
}
}
public void Select(Type? type, Guid id)
{
ClearEditor();
_selectedType = type;
_entityID = id;
if (_selectedType != null)
{
CreateEditor();
PopulateEditor();
//LoadPopup();
}
}
private void ScanPanel_OnSelectScan(string appliesto, Guid entityid, bool processenabled)
{
_processenabled = processenabled;
_originalID = entityid;
Select(
CoreUtils.GetEntityOrNull(appliesto),
entityid
);
}
public DataEntryPanel()
{
InitializeComponent();
LoadSettings();
}
private void LoadSettings()
{
_settings = new UserConfiguration().Load();
_panel.AnchorWidth = _settings.PreviewWidth > 0.0F
? _settings.PreviewWidth
: 500F;
}
public void Setup()
{
_documents.Setup();
IsChanged = false;
}
public void Refresh()
{
if (CheckSaved())
{
_documents.Refresh();
IsChanged = false;
}
}
public bool IsReady { get; set; }
public string SectionName => "Data Entry";
public DataModel DataModel(Selection selection)
{
return new EmptyDataModel();
}
public event DataModelUpdateEvent? OnUpdateDataModel;
public void CreateToolbarButtons(IPanelHost host)
{
if (Security.IsAllowed())
{
host.CreateSetupAction(new PanelAction("Data Entry Tags", null, (action) =>
{
var list = new MasterList(typeof(DataEntryTag));
list.ShowDialog();
}));
host.CreateSetupAction(new PanelAction("Settings", null, (action) =>
{
var settings = new UserConfiguration().Load();
var grid = new DynamicItemsListGrid();
if (grid.EditItems(new DataEntryPanelSettings[] { settings }))
{
new UserConfiguration().Save(settings);
LoadSettings();
}
}));
}
}
public void Heartbeat(TimeSpan time)
{
}
public Dictionary Selected()
{
return new Dictionary();
}
private void CheckSaved(CancelEventArgs cancel)
{
if (!_isChanged)
{
return;
}
var result = MessageBox.Show("You have changes that have not been saved; do you wish to save these changes?", "Save Changes?", MessageBoxButton.YesNoCancel);
if (result == MessageBoxResult.Yes)
{
if (!Editor.Validate())
{
cancel.Cancel = true;
return;
}
DoSave(false);
if (!cancel.Cancel)
MessageBox.Show("Item saved.");
}
else if (result == MessageBoxResult.Cancel)
{
cancel.Cancel = true;
}
}
private bool CheckSaved()
{
var cancel = new CancelEventArgs();
CheckSaved(cancel);
return !cancel.Cancel;
}
public void Shutdown(CancelEventArgs? cancel)
{
if (cancel != null)
CheckSaved(cancel);
if (cancel?.Cancel != true)
_documents.Shutdown(cancel);
}
#region Host
public Type GetEditorType() => _selectedType ?? typeof(BaseObject);
public void LoadLookups(ILookupEditorControl sender)
{
var colname = sender.ColumnName;
var values = sender.LookupEditorDefinition.Values(colname, Editor.Items);
sender.LoadLookups(values);
}
BaseObject[] IDynamicEditorHost.GetItems() => Editor.Items;
public BaseEditor? GetEditor(DynamicGridColumn column) => column.Editor.CloneEditor();
#endregion
private void ClearEditor()
{
DetailBorder.Child = null;
IsChanged = false;
//if (_popup is UIElement element)
// DetailHeader.Children.Remove(element);
}
private void CreateEditor()
{
if (_selectedType == null)
return;
Editor = new EmbeddedDynamicEditorForm();
if (_selectedType == typeof(Bill))
Editor.SetLayoutType();
else
Editor.SetLayoutType();
Editor.HighlightButtons = true;
Editor.HideButtons = true;
Editor.SetValue(Grid.RowProperty, 1);
Editor.SetValue(Grid.ColumnProperty, 0);
Editor.SetValue(Grid.ColumnSpanProperty, 4);
Editor.OnOK += () => { DoSave(false); };
Editor.OnCancel += () =>
{
_entityID = _originalID;
Select(_selectedType, _entityID);
};
Editor.OnChanged += (sender, args) => IsChanged = true;
DetailBorder.Child = Editor;
_grid = (DynamicGridUtils.CreateDynamicGrid(typeof(DynamicDataGrid<>), _selectedType) as IDynamicDataGrid)!;
_grid.OnCustomiseEditor += (sender, items, column, editor) =>
{
if ((editor is BaseCodeEditor be) && editor.Editable.EditorVisible())
{
be.Buttons = new[]
{
new EditorButton(null, "..", 30, DoLookup, false)
};
}
};
_grid.OnAfterEditorValueChangedEvent += (sender, args) =>
{
IsChanged = IsChanged || (_entity?.IsChanged() == true || _originalID != _entityID);
return null;
};
if (_grid is DynamicDataGrid milestoneGrid)
{
milestoneGrid.OnValidate += (o, items, err) =>
{
if (items.Any(x => x.ID == Guid.Empty))
{
err.Add("Cannot create a new milestone from Data Entry screen. Please select a milestone to edit.");
}
};
}
}
private void DoLookup(object editor, object? item)
{
if (_selectedType == null)
return;
if (editor is CodeEditorControl ce)
{
Dictionary? filter = null;
if (ce.Value != null)
{
filter = new Dictionary
{
[ce.ColumnName] = ce.Value
};
}
Type? gridType = null;
if (_selectedType == typeof(JobDocumentSetMileStone))
{
gridType = typeof(JobDocumentSetMileStoneDataEntryPopupGrid);
}
var popup = new PopupList(_selectedType, _entityID, Array.Empty(), filter, gridType: gridType);
popup.OnDefineFilter += LookupFactory.DefineFilter;
if (popup.ShowDialog() == true)
{
_entityID = popup.ID;
Select(_selectedType, _entityID);
}
}
}
private void SaveDocument(DataEntryDocument dataEntryDocument)
{
var doctype = CoreUtils.TypeList(x =>
{
var entityDoc = x.GetInterfaceDefinition(typeof(IEntityDocument<>));
if (entityDoc is null)
{
return false;
}
var linkType = entityDoc.GenericTypeArguments[0].GetInterfaceDefinition(typeof(IEntityLink<>));
if (linkType is null)
{
return false;
}
return linkType.GenericTypeArguments[0] == _selectedType;
}).FirstOrDefault();
if(doctype is null)
{
return;
}
var doc = (IEntityDocument)Activator.CreateInstance(doctype)!;
CoreUtils.SetPropertyValue(doc, "EntityLink.ID", _entityID);
doc.DocumentLink.ID = dataEntryDocument.Document.ID;
doc.Thumbnail = dataEntryDocument.Thumbnail;
ClientFactory.CreateClient(doctype).Save(doc,"Added from Data Entry Screen");
}
private void DoSave(bool markasprocessed)
{
var cancel = new System.ComponentModel.CancelEventArgs();
if (markasprocessed && (_entity is IDataEntryInstance scannable))
scannable.DataEntered = DateTime.Now;
Editor.SaveItem(cancel);
if (!cancel.Cancel)
{
_originalID = _entityID;
_entityID = _entity.ID;
IsChanged = false;
var row = _documents._dataEntryGrid.SelectedRows.FirstOrDefault();
if (row != null)
{
var scan = row.ToObject();
scan.EntityID = _entity.ID;
if (markasprocessed)
{
SaveDocument(scan);
scan.Archived = DateTime.Now;
}
if (scan.IsChanged())
{
new Client().Save(scan, "Updated from Data Entry Screen");
_documents.Refresh();
}
}
}
}
private void PopulateEditor()
{
if (_selectedType == null)
return;
_entity = null;
if (_entityID != Guid.Empty)
{
_entity = Client.Create(_selectedType)
.Query(
Filter.Create(_selectedType, x => x.ID).IsEqualTo(_entityID),
_grid.LoadEditorColumns()
)
.ToObjects(_selectedType)
.OfType()
.FirstOrDefault();
}
_entity ??= Activator.CreateInstance(_selectedType) as Entity;
if (_entity == null)
return;
_grid?.InitialiseEditorForm(Editor, new object[] { _entity }, null, true);
_process = new Button()
{
Content = "Mark as Processed",
BorderBrush = new SolidColorBrush(Colors.DarkBlue),
Background = new SolidColorBrush(Colors.DodgerBlue),
Margin = new Thickness(0, 0, 5, 0),
Padding = new Thickness(10, 0, 10, 0),
IsEnabled = _processenabled
};
_process.Click += (sender, args) =>
{
if (Editor.Validate())
{
DoSave(true);
}
};
Editor.AddButton(_process);
IsChanged = false;
if (_selectedType == typeof(JobDocumentSetMileStone))
{
var disabled = _entityID == Guid.Empty;
foreach (var page in Editor.Pages)
{
if (page is DynamicEditorGrid.DynamicEditPage editPage)
{
foreach (var editor in editPage.Editors)
{
if (editor.EditorDefinition is not BaseCodeEditor)
{
editor.IsEnabled = !disabled && editor.EditorDefinition.Editable.IsEditable();
}
}
}
else
{
page.ReadOnly = disabled;
}
}
}
}
private void _panel_OnOnChanged(object sender, DynamicSplitPanelSettings e)
{
_settings.PreviewWidth = e.AnchorWidth;
new UserConfiguration().Save(_settings);
}
}