using System; using System.Collections.Generic; using Comal.Classes; using InABox.Core; using InABox.DynamicGrid; using System.Linq; using System.Linq.Expressions; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media.Imaging; using AutoProperties; using Comal.Classes.SecurityDescriptors; using InABox.Clients; using InABox.Configuration; using InABox.Wpf; using InABox.WPF; namespace PRSDesktop.Integrations.Common; public class IntegrationGridCreateEntityArgs(TEntity entity, TType mapping) { public TEntity Entity { get; private set; } = entity; public TType Mapping { get; private set; } = mapping; } public abstract class BaseIntegrationGrid : DynamicItemsListGrid where TType : BaseIntegrationSource, new() where TEntity : Entity, IRemotable, IPersistent, new() where TLink : EntityLink { private static readonly DependencyProperty SourceTypeProperty = DependencyProperty.Register( nameof(SourceType), typeof(IntegrationSourceType), typeof(BaseIntegrationGrid) ); public IntegrationSourceType SourceType { get => (IntegrationSourceType)GetValue(SourceTypeProperty); set => SetValue(SourceTypeProperty, value); } private static readonly DependencyProperty CreateEntityProperty = DependencyProperty.Register( nameof(CreateEntity), typeof(ICommand), typeof(BaseIntegrationGrid) ); public ICommand? CreateEntity { get => GetValue(CreateEntityProperty) as ICommand; set => SetValue(CreateEntityProperty, value); } private static readonly DependencyProperty AfterCreateEntityProperty = DependencyProperty.Register( nameof(AfterCreateEntity), typeof(ICommand), typeof(BaseIntegrationGrid) ); public ICommand? AfterCreateEntity { get => GetValue(AfterCreateEntityProperty) as ICommand; set => SetValue(AfterCreateEntityProperty, value); } private DynamicImageColumn _createordelete; protected override void Init() { base.Init(); var required = Columns.Required(); foreach (var req in required) HiddenColumns.Add(req.Property); HiddenColumns.Add(x => x.DirectMatch); AddButton("Create All", PRSDesktop.Resources.plus.AsBitmapImage(), CreateAll); _createordelete = new DynamicImageColumn(CreateImage, CreateOrDeleteOne); ActionColumns.Add(_createordelete); } private BitmapImage? CreateImage(CoreRow? row) { return row == null ? PRSDesktop.Resources.plus.AsBitmapImage() : row.Get(x => x.Entity.ID) == Guid.Empty ? PRSDesktop.Resources.plus.AsBitmapImage() : row.Get(x=>x.DirectMatch) ? PRSDesktop.Resources.locked.AsBitmapImage() : PRSDesktop.Resources.minus.AsBitmapImage(); } private bool CreateOrDeleteOne(CoreRow? row) { if (row == null) return false; if (row.Get(x => x.DirectMatch) && row.Get(x=>x.Entity.ID) != Guid.Empty) return false; var item = Items[row.Index]; if (item.Entity.ID == Guid.Empty) CreateItem(item); else DeleteItem(item); Refresh(false,true); DoChanged(); return true; } private bool CreateAll(Button button, CoreRow[] rows) { foreach (var item in Items.Where(x => !string.IsNullOrWhiteSpace(x.Code) && x.Entity.ID == Guid.Empty)) CreateItem(item); DoChanged(); return true; } protected abstract Expression> EntityCode { get; } private void CreateItem(TType item) { var lookup = Client.Query( new Filter(EntityCode).IsEqualTo(item.Code), Columns.Required().Add(EntityCode) ).ToArray(); if (lookup.Any()) { item.Source = SourceType; item.Entity.CopyFrom(lookup.First()); item.DirectMatch = true; return; } var entity = new TEntity(); var args = new IntegrationGridCreateEntityArgs(entity,item); try { CreateEntity?.Execute(args); new Client().Save(entity, "Created by Integration Window"); item.Source = SourceType; item.Entity.CopyFrom(entity); item.DirectMatch = true; try { var args2 = new IntegrationGridCreateEntityArgs(entity,item); AfterCreateEntity?.Execute(args2); } catch (Exception e) { MessageWindow.ShowError(e.Message, e, "AfterCreate Error"); Logger.Send(LogType.Error,"",$"Exception in AfterCreateEntity: {e.Message}\n{e.StackTrace}"); } } catch (Exception e) { MessageWindow.ShowError(e.Message, e, "CreateItem Error"); Logger.Send(LogType.Error,"",$"Exception in CreateEntity: {e.Message}\n{e.StackTrace}"); } } private void DeleteItem(TType item) { MultiQuery query = new(); query.Add( new Filter(EntityCode).IsEqualTo(item.Code), Columns.Required().Add(x => x.ID).Add(EntityCode) ); query.Add( new Filter(x=>x.Entity.ID).IsEqualTo(item.Entity.ID).And(x=>x.Code).IsEqualTo(item.Code), Columns.Required().Add(x=>x.ID) ); query.Query(); var mappings = query.Get().ToArray(); if (mappings.Any()) { item.ID = Guid.Empty; Client.Delete(mappings, "Removed By AWG Mapping Window"); } var entities = query.Get().ToArray(); if (entities.Any()) { item.Entity.CopyFrom(entities.First()); item.DirectMatch = true; } else { item.Entity.CopyFrom(new TEntity()); item.DirectMatch = false; } item.CommitChanges(); SaveItem(item); DoChanged(); } protected override void DoReconfigure(DynamicGridOptions options) { base.DoReconfigure(options); options.AddRows = false; options.EditRows = false; options.DeleteRows = false; options.FilterRows = true; options.HideDatabaseFilters = true; options.DirectEdit = true; options.HideDirectEditButton = true; options.SelectColumns = true; options.MultiSelect = true; options.RecordCount = true; } protected override DynamicGridColumns LoadColumns() { var result = new DynamicGridColumns(); result.Add(x => x.Code, 250, "Code"); result.Add(x => x.Description, 0, "Description"); result.Add(x => x.Entity.ID, 200, typeof(TEntity).GetCaption()); return result; } protected override BaseEditor CustomiseEditor(DynamicGridColumn column, BaseEditor editor) { editor = base.CustomiseEditor(column, editor); if (String.Equals(CoreUtils.GetFullPropertyName(x => x.Code, "."), column.ColumnName)) editor.Editable = Editable.Disabled; else if (String.Equals(CoreUtils.GetFullPropertyName(x => x.Description, "."), column.ColumnName)) editor.Editable = Editable.Disabled; else if (String.Equals(CoreUtils.GetFullPropertyName(x => x.Entity.ID, "."), column.ColumnName)) { var popup = new CodePopupEditor(typeof(TEntity)) { CodeColumn = "Code", CanAdd = Security.CanEdit() }; var required = Columns.Required(); foreach (var req in required) popup.OtherColumns[$"Entity.{req.Property}"] = req.Property; popup.OnCreateItem += o => { }; editor = popup; } // else if(new Column(x => x.Entity.ID).IsEqualTo(column.ColumnName) && editor is CodePopupEditor popup) // popup.CanAdd = Security.CanEdit(); return editor; } protected override void OnAfterEditorValueChanged(DynamicEditorGrid? grid, TType[] items, AfterEditorValueChangedArgs args, Dictionary changes) { base.OnAfterEditorValueChanged(grid, items, args, changes); //DoChanged(); } public override void SaveItem(TType item) { var code = CoreUtils.GetPropertyValue(item.Entity, CoreUtils.GetFullPropertyName(EntityCode, "."))?.ToString() ?? ""; item.DirectMatch = Equals(code, item.Code); if (!Equals(item.ID, Guid.Empty) && (Equals(code, item.Code) || string.IsNullOrWhiteSpace(code))) { Client.Delete(item, "Removed By AWG Mapping Window"); item.ID = Guid.Empty; item.CommitChanges(); return; } if (!string.IsNullOrWhiteSpace(code) && !Equals(code,item.Code)) Client.Save(item,"Updated by Integration Window "); base.SaveItem(item); //DoChanged(); } }