123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537 |
- 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.Linq.Expressions;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Media;
- using InABox.Configuration;
- using Microsoft.Xaml.Behaviors.Core;
- 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;
- }
- /// <summary>
- /// Interaction logic for DataEntryPanel.xaml
- /// </summary>
- 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<DataEntryPanelSettings>().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<CanSetupDataEntryTags>())
- {
- 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<DataEntryPanelSettings>().Load();
- var grid = new DynamicItemsListGrid<DataEntryPanelSettings>();
- if (grid.EditItems(new DataEntryPanelSettings[] { settings }))
- {
- new UserConfiguration<DataEntryPanelSettings>().Save(settings);
- LoadSettings();
- }
- }));
- }
- }
- public void Heartbeat(TimeSpan time)
- {
- }
-
- public Dictionary<string, object[]> Selected()
- {
- return new Dictionary<string, object[]>();
- }
-
- 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<SupplierBillEditDocumentLayout>();
- else
- Editor.SetLayoutType<VerticalDynamicEditorGridLayout>();
-
- 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<JobDocumentSetMileStone> 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<string, string>? filter = null;
- if (ce.Value != null)
- {
- filter = new Dictionary<string, string>
- {
- [ce.ColumnName] = ce.Value
- };
- }
- Type? gridType = null;
- if (_selectedType == typeof(JobDocumentSetMileStone))
- {
- gridType = typeof(JobDocumentSetMileStoneDataEntryPopupGrid);
- }
- var popup = new PopupList(_selectedType, _entityID, Array.Empty<string>(), 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<DataEntryDocument>();
- scan.EntityID = _entity.ID;
- if (markasprocessed)
- {
- SaveDocument(scan);
- scan.Archived = DateTime.Now;
- }
- if (scan.IsChanged())
- {
- new Client<DataEntryDocument>().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<Entity>(_selectedType, x => x.ID).IsEqualTo(_entityID),
- _grid.LoadEditorColumns()
- )
- .ToObjects(_selectedType)
- .OfType<Entity>()
- .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<DataEntryPanelSettings>().Save(_settings);
- }
- private void CreateMenuItem<T>(ContextMenu menu, Expression<Func<T,object>> column, string caption, Action<string> action)
- {
- var columnname = CoreUtils.GetFullPropertyName<T, object>(column, ".");
- if (Editor.FindEditor(columnname) != null)
- {
- var menuitem = new MenuItem()
- {
- Header = caption
- };
- menuitem.Click += (sender, args) => action?.Invoke(columnname);
- menu.Items.Add(menuitem);
- }
- }
-
- private void CreateMenuItem<T>(ContextMenu menu, Expression<Func<T,object>> column, string caption, Action<MenuItem,string> build)
- {
- var columnname = CoreUtils.GetFullPropertyName<T, object>(column, ".");
- if (Editor.FindEditor(columnname) != null)
- {
- var menuitem = new MenuItem()
- {
- Header = caption
- };
- build.Invoke(menuitem,columnname);
- menu.Items.Add(menuitem);
- }
- }
- private void _documents_OnOCRContextMenuOpening(object sender, DocumentOCRContextMenuArgs args)
- {
- if (GetEditorType() == typeof(Bill))
- {
-
- CreateMenuItem<Bill>(args.Menu, x=>x.SupplierLink.ID, "Supplier", (m,c) =>
- {
- m.Items.Add(new MenuItem() { Header = "(Loading)", IsEnabled = false });
- Client.Query<Supplier>(
- new Filter<Supplier>(x => x.ABN).IsEqualTo(args.Text).Or(x => x.Name).Contains(args.Text),
- Columns.None<Supplier>().Add(x => x.ID).Add(x => x.Code).Add(x => x.Name),
- new SortOrder<Supplier>(x => x.Code),
- (o, e) =>
- {
- if (o != null)
- {
- Dispatcher.Invoke(() =>
- {
- m.Items.Clear();
- foreach (var supp in o.ToArray<Supplier>())
- {
- m.Items.Add(new MenuItem()
- {
- Header = $"{supp.Code}: {supp.Name}",
- Command = new ActionCommand(() => { Editor.SetEditorValue(c, supp.ID); })
- });
- }
- if (m.Items.Count.Equals(0))
- m.Items.Add(new MenuItem()
- { Header = "(No Suppliers Found)", IsEnabled = false });
- });
- }
- }
- );
- });
-
- CreateMenuItem<Bill>(args.Menu, x => x.Number, "Invoice Number", (c) => Editor.SetEditorValue(c, args.Text));
- if (DateTime.TryParse(args.Text, out var date))
- {
- CreateMenuItem<Bill>(args.Menu, x=>x.BillDate, "Invoice Date", (c) => Editor.SetEditorValue(c, date));
- }
-
- }
- }
- }
|