|  | @@ -10,7 +10,7 @@ using System.Windows;
 | 
	
		
			
				|  |  |  using System.Windows.Controls;
 | 
	
		
			
				|  |  |  using System.Windows.Media;
 | 
	
		
			
				|  |  |  using InABox.Configuration;
 | 
	
		
			
				|  |  | -using NPOI.SS.Formula.Functions;
 | 
	
		
			
				|  |  | +using PRSDesktop.Panels.DataEntry.Grids;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  namespace PRSDesktop;
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -29,9 +29,6 @@ public class DataEntryPanelSettings : BaseObject, IUserConfigurationSettings
 | 
	
		
			
				|  |  |  /// <summary>
 | 
	
		
			
				|  |  |  /// Interaction logic for DataEntryPanel.xaml
 | 
	
		
			
				|  |  |  /// </summary>
 | 
	
		
			
				|  |  | -/// <remarks>
 | 
	
		
			
				|  |  | -/// This is a host because it has a singular code popup editor
 | 
	
		
			
				|  |  | -/// </remarks>
 | 
	
		
			
				|  |  |  public partial class DataEntryPanel : UserControl, IBasePanel, IDynamicEditorHost
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |      private DataEntryPanelSettings _settings;
 | 
	
	
		
			
				|  | @@ -231,10 +228,9 @@ public partial class DataEntryPanel : UserControl, IBasePanel, IDynamicEditorHos
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      public void LoadLookups(ILookupEditorControl sender)
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  | -        var editor = sender.EditorDefinition as ILookupEditor;
 | 
	
		
			
				|  |  |          var colname = sender.ColumnName;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        var values = editor.Values(colname, Editor.Items);
 | 
	
		
			
				|  |  | +        var values = sender.LookupEditorDefinition.Values(colname, Editor.Items);
 | 
	
		
			
				|  |  |          sender.LoadLookups(values);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -294,23 +290,45 @@ public partial class DataEntryPanel : UserControl, IBasePanel, IDynamicEditorHos
 | 
	
		
			
				|  |  |          
 | 
	
		
			
				|  |  |          DetailBorder.Child = Editor;
 | 
	
		
			
				|  |  |          _grid = DynamicGridUtils.CreateDynamicGrid(typeof(DynamicDataGrid<>), _selectedType) as IDynamicDataGrid;
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        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>();
 | 
	
		
			
				|  |  | -                filter[ce.ColumnName] = ce.Value;
 | 
	
		
			
				|  |  | +                filter = new Dictionary<string, string>
 | 
	
		
			
				|  |  | +                {
 | 
	
		
			
				|  |  | +                    [ce.ColumnName] = ce.Value
 | 
	
		
			
				|  |  | +                };
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            var popup = new PopupList(_selectedType, _entityID, new String[] { }, filter);
 | 
	
		
			
				|  |  | -            popup.OnDefineFilter += type => LookupFactory.DefineFilter(type);
 | 
	
		
			
				|  |  | +            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;
 | 
	
	
		
			
				|  | @@ -362,7 +380,7 @@ public partial class DataEntryPanel : UserControl, IBasePanel, IDynamicEditorHos
 | 
	
		
			
				|  |  |              var row = _documents._dataEntryGrid.SelectedRows.FirstOrDefault();
 | 
	
		
			
				|  |  |              if (row != null)
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  | -                var scan = row?.ToObject<DataEntryDocument>();
 | 
	
		
			
				|  |  | +                var scan = row.ToObject<DataEntryDocument>();
 | 
	
		
			
				|  |  |                  scan.EntityID = _entity.ID;
 | 
	
		
			
				|  |  |                  if (markasprocessed)
 | 
	
		
			
				|  |  |                  {
 | 
	
	
		
			
				|  | @@ -414,6 +432,28 @@ public partial class DataEntryPanel : UserControl, IBasePanel, IDynamicEditorHos
 | 
	
		
			
				|  |  |          _process.Click += (sender, args) => 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)
 |