Browse Source

Updated security tokens and columns

Kenric Nugteren 6 days ago
parent
commit
b74a536bee

+ 1 - 1
prs.classes/SecurityDescriptors/Common_Descriptors.cs

@@ -58,7 +58,7 @@ namespace Comal.Classes
     }
     
     [Caption("View Picking Lists Dock")]
-    public class CanViewRequisitionsDock : EnabledSecurityDescriptor<LogisticsLicense, PickingList>
+    public class CanViewPickingListDock : EnabledSecurityDescriptor<LogisticsLicense, PickingList>
     {
     }
     

+ 3 - 3
prs.classes/SecurityDescriptors/Logistics_Descriptors.cs

@@ -4,17 +4,17 @@ using InABox.Core;
 namespace Comal.Classes
 {
     [Caption("Can Close Requisitions without Photos")]
-    public class CanSkipRequisitionPhotos : DisabledSecurityDescriptor<LogisticsLicense, PickingList>
+    public class CanSkipPickingListPhotos : DisabledSecurityDescriptor<LogisticsLicense, PickingList>
     {
     }
 
     [Caption("Can Update Requisition Stock Movements")]
-    public class CanUpdateRequisitionStockMovements : DisabledSecurityDescriptor<LogisticsLicense, PickingList>
+    public class CanUpdatePickingListStockMovements : DisabledSecurityDescriptor<LogisticsLicense, PickingList>
     {
     }
 
     [Caption("Can Archive Requisitions")]
-    public class CanArchiveRequisitions : DisabledSecurityDescriptor<LogisticsLicense, PickingList>
+    public class CanArchivePickingLists : DisabledSecurityDescriptor<LogisticsLicense, PickingList>
     {
     }
 

+ 1 - 1
prs.desktop/MainWindow.xaml.cs

@@ -795,7 +795,7 @@ public partial class MainWindow : IPanelHostControl
         SetupDock<CanViewProductDock>(ProductLookupDock, ProductLookup);
         SetupDock<CanViewDigitalFormsDock>(DigitalFormsDock, DigitalForms);
         SetupDock<CanViewProblemsDock>(ProblemsDock, Problems);
-        SetupDock<CanViewRequisitionsDock>(RequisitionsDock, Requisitions);
+        SetupDock<CanViewPickingListDock>(RequisitionsDock, Requisitions);
 
         _ribbon.InvalidateArrange();
     }

+ 1 - 1
prs.desktop/Panels/PickingLists/PickingListGrid.cs

@@ -132,7 +132,7 @@ internal class PickingListGrid : DynamicDataGrid<PickingList>
 
         else if (column.ColumnName.Equals("Filled"))
         {
-            editor.Editable = Security.IsAllowed<CanSkipRequisitionPhotos>() || (items != null && items.Any() && items.First().Documents > 0)
+            editor.Editable = Security.IsAllowed<CanSkipPickingListPhotos>() || (items != null && items.Any() && items.First().Documents > 0)
                 ? Editable.Enabled
                 : Editable.Hidden;
         }

+ 1 - 1
prs.desktop/Panels/PickingLists/PickingListPanel.xaml.cs

@@ -341,7 +341,7 @@ public partial class PickingListPanel : UserControl, IPanel<PickingList>
         MarkAsFilled.IsEnabled = _pickingList != null && _pickingList.Archived.IsEmpty() && _pickingList.StockUpdated.IsEmpty();
         MarkAsFilledDescription.Content = _pickingList == null || _pickingList.Filled.IsEmpty() ? "Mark As Filled" : "Clear Filled Flag";
 
-        UpdateStock.IsEnabled = Security.IsAllowed<CanUpdateRequisitionStockMovements>() && _pickingList != null &&
+        UpdateStock.IsEnabled = Security.IsAllowed<CanUpdatePickingListStockMovements>() && _pickingList != null &&
                                 !_pickingList.Filled.IsEmpty();
         UpdateStockDescription.Content =
             _pickingList == null || _pickingList.StockUpdated.IsEmpty() ? "Update Stock Holdings" : "Clear Stock Movements";

+ 150 - 4
prs.shared/Database Update Scripts/Update_8_58.cs

@@ -1,6 +1,8 @@
 using Comal.Classes;
+using InABox.Configuration;
 using InABox.Core;
 using InABox.Database;
+using InABox.DynamicGrid;
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -73,13 +75,13 @@ internal class Update_8_58 : DatabaseUpdateScript
             {
                 foreach (var item in chunk)
                 {
+                    item.SetObserving(false);
+                    var originalValue = toColumn.PropertyDefinition.Getter()(item);
                     toColumn.PropertyDefinition.Setter()(
                         item,
                         fromColumn.PropertyDefinition.Getter()(item));
-                    if (!item.HasOriginalValue(toColumn.Property))
-                    {
-                        item.SetOriginalValue(toColumn.Property, Guid.Empty);
-                    }
+                    item.SetOriginalValue(toColumn.Property, originalValue);
+                    item.SetObserving(true);
                 }
                 provider.Save(chunk);
             },
@@ -524,6 +526,145 @@ internal class Update_8_58 : DatabaseUpdateScript
         RenameTable<RequisitionKanban, PickingListKanban>(provider);
     }
 
+    private static void UpdateColumns<T>(IProvider provider)
+        where T : Entity, IDatabaseStoredSettings, new()
+    {
+        var settings = provider.Query(
+            Filter<T>.Where(x => x.Section).IsEqualTo(nameof(DynamicGridColumns)),
+            Columns.None<T>()
+                .Add(x => x.ID)
+                .Add(x => x.Key)
+                .Add(x => x.Contents))
+            .ToArray<T>();
+
+        var changedSettings = new List<T>();
+        foreach(var setting in settings)
+        {
+            if (setting.Key.IsNullOrWhiteSpace()) continue;
+
+            var entityName = setting.Key.Split('.')[^1];
+            var entity = CoreUtils.Entities.Where(x => x.Name == entityName
+                && x.IsSubclassOf(typeof(Entity)))
+                .FirstOrDefault();
+            if (entity is null) continue;
+
+            var columns = Serialization.Deserialize<DynamicGridColumns>(setting.Contents);
+            if(columns is not null)
+            {
+                var changed = false;
+                foreach(var column in columns)
+                {
+                    var i = 0;
+                    while(i < column.ColumnName.Length)
+                    {
+                        var index = column.ColumnName.IndexOf("Link.", i);
+                        if (index == -1) break;
+
+                        var columnName = column.ColumnName[0..index];
+                        if(DatabaseSchema.Property(entity, columnName) is IProperty property)
+                        {
+                            column.ColumnName = $"{property.Name}.{column.ColumnName[(index + 5)..]}";
+                            changed = true;
+                        }
+                        else
+                        {
+                            i = index + 5;
+                        }
+                    }
+                }
+                if (changed)
+                {
+                    setting.Contents = Serialization.Serialize(columns);
+                    changedSettings.Add(setting);
+                }
+            }
+        }
+
+        provider.Save(changedSettings);
+    }
+    private static void UpdateColumns(IProvider provider)
+    {
+        UpdateColumns<GlobalSettings>(provider);
+        UpdateColumns<UserSettings>(provider);
+    }
+
+    private static void UpdateSecurityToken<T>(IProvider provider, string oldDescriptor, string newDescriptor)
+        where T : Entity, ISecurityToken, new()
+    {
+        var tokens = provider.Query(
+            Filter<T>.Where(x => x.Descriptor).IsEqualTo(oldDescriptor),
+            Columns.None<T>()
+                .Add(x => x.ID)
+                .Add(x => x.Descriptor))
+            .ToArray<T>();
+        foreach(var token in tokens)
+        {
+            token.Descriptor = newDescriptor;
+        }
+        provider.Save(tokens);
+    }
+    private static void UpdateSecurityToken(IProvider provider, string oldDescriptor, string newDescriptor)
+    {
+        UpdateSecurityToken<GlobalSecurityToken>(provider, oldDescriptor, newDescriptor);
+        UpdateSecurityToken<UserSecurityToken>(provider, oldDescriptor, newDescriptor);
+        UpdateSecurityToken<SecurityToken>(provider, oldDescriptor, newDescriptor);
+    }
+
+    private static void UpdateAutoSecurityToken<TFrom, TTo>(IProvider provider, Type token)
+    {
+        var toDescriptor = (Activator.CreateInstance(token.MakeGenericType(typeof(TTo))) as IAutoSecurityDescriptor)!;
+        var overriden = Security.SecurityDescriptorOverride(toDescriptor);
+        if (overriden != toDescriptor) return; // No point in updating these if the token has been overriden.
+
+        var fromDescriptor = (Activator.CreateInstance(token.MakeGenericType(typeof(TFrom))) as IAutoSecurityDescriptor)!;
+
+        UpdateSecurityToken(provider, Security.SecurityDescriptorOverride(fromDescriptor).Code, toDescriptor.Code);
+    }
+    private static void UpdateAutoSecurityTokens<TFrom, TTo>(IProvider provider)
+    {
+        var list = CoreUtils.Entities.Where(
+            x => x.HasInterface(typeof(IAutoSecurityDescriptor)))
+            .ToArray();
+        foreach(var T in CoreUtils.Entities.Where(
+            x => x.HasInterface(typeof(IAutoSecurityDescriptor))
+                && x.IsGenericType && x.GetGenericArguments().Length == 1))
+        {
+            UpdateAutoSecurityToken<TFrom, TTo>(provider, T);
+        }
+    }
+
+    private static void UpdateSecurityTokens(IProvider provider)
+    {
+        UpdateSecurityToken(provider, "CanViewRequisitionsDock", nameof(CanViewPickingListDock));
+        UpdateSecurityToken(provider, "CanSkipRequisitionPhotos", nameof(CanSkipPickingListPhotos));
+        UpdateSecurityToken(provider, "CanUpdateRequisitionStockMovements", nameof(CanUpdatePickingListStockMovements));
+        UpdateSecurityToken(provider, "CanArchiveRequisitions", nameof(CanArchivePickingLists));
+
+        UpdateAutoSecurityTokens<Requisition, PickingList>(provider);
+        UpdateAutoSecurityTokens<RequisitionItem, PickingListItem>(provider);
+        UpdateAutoSecurityTokens<RequisitionDestination, PickingListDestination>(provider);
+        UpdateAutoSecurityTokens<RequisitionDocument, PickingListDocument>(provider);
+        UpdateAutoSecurityTokens<RequisitionKanban, PickingListKanban>(provider);
+    }
+
+    private static void ConvertSettings<T>(IProvider provider, string fromSection, string toSection)
+        where T : Entity, IDatabaseStoredSettings, new()
+    {
+        var settings = provider.Query(
+            Filter<T>.Where(x => x.Section).IsEqualTo(fromSection),
+            Columns.None<T>()
+                .Add(x => x.ID)
+                .Add(x => x.Section))
+            .ToArray<T>();
+
+        foreach(var setting in settings)
+        {
+            setting.Section = toSection;
+        }
+
+        provider.Save(settings);
+    }
+
     public override bool Update()
     {
         var provider = DbFactory.NewProvider(Logger.Main);
@@ -531,6 +672,11 @@ internal class Update_8_58 : DatabaseUpdateScript
         UpdateTimeSheets(provider);
 
         ConvertLinks(provider);
+        UpdateColumns(provider);
+
+        UpdateSecurityTokens(provider);
+
+        ConvertSettings<UserSettings>(provider, "RequisitionSettings", "PickingListSettings");
 
         ConvertQAQuestions(provider);