Selaa lähdekoodia

Restricted merging of ProductDimensionUnits to units that have the same schema.
Added paging and progress support to updating the expressions of a ProductDimensionUnit. (There is a potential problem with this, outlined in task #889 in PRS Digital).

Kenric Nugteren 9 kuukautta sitten
vanhempi
commit
1344d229e5

+ 43 - 14
prs.classes/EnclosedEntities/Dimensions/DimensionUnit.cs

@@ -130,11 +130,16 @@ namespace Comal.Classes
                 return variables;
             }
         }
+
+        public override string ToString()
+        {
+            return $"(ProductDimensionUnit: {Code})";
+        }
     }
 
     public static class DimensionUnitUtils
     {
-        public static Dictionary<Type, int> UpdateExpressions<T, TLink>(T[] items)
+        public static Dictionary<Type, int> UpdateExpressions<T, TLink>(T[] items, IProgress<string> progress)
             where T : DimensionUnit, new()
             where TLink : DimensionUnitLink<T>
         {
@@ -156,10 +161,6 @@ namespace Comal.Classes
                     && entity.HasInterface<IRemotable>()
                     && entity.HasInterface<IPersistent>())
                 {
-                    if(entity == typeof(SupplierProduct))
-                    {
-                        var props = DatabaseSchema.Properties(entity).OrderBy(x => x.Name).ToArray();
-                    }
                     foreach(var property in DatabaseSchema.Properties(entity))
                     {
                         if (property.Parent is null
@@ -172,8 +173,8 @@ namespace Comal.Classes
                         var dimType = dimensionTypes.FirstOrDefault(x => property.Parent.Parent.PropertyType == x.dimType);
                         if(dimType.dimType != null)
                         {
-                            var dict = updateTypes.GetValueOrAdd(entity);
-                            dict.Add(property.Parent.Parent);
+                            var propList = updateTypes.GetValueOrAdd(entity);
+                            propList.Add(property.Parent.Parent);
                         }
                     }
                 }
@@ -211,26 +212,54 @@ namespace Comal.Classes
                 }
                 if(filter != null)
                 {
-                    var results = Client.Create(type).Query(filter, columns).ToObjects(type).Cast<Entity>().ToArray();
-                    if(results.Length > 0)
+                    progress.Report($"Updating {CoreUtils.Neatify(type.GetCaption())}");
+
+                    var nTotal = Client.Create(type).Query(filter, Columns.None(type).Add("ID")).Rows.Count;
+                    var nProcessed = 0;
+                    var nResult = 0;
+                    var done = false;
+
+                    var percentStep = Math.Max(nTotal / 100, 1);
+                    var range = CoreRange.Database(1000);
+
+                    while(nProcessed < nTotal && !done)
                     {
-                        foreach(var result in results)
+                        var rows = Client.Create(type).Query(filter, columns, range: range).Rows;
+                        if (rows.Count == 0) break;
+                        if(rows.Count < 1000)
                         {
+                            done = true;
+                        }
+                        range.Next();
+
+                        var results = new List<Entity>(rows.Count);
+                        for(int i = 0; i < rows.Count; ++i)
+                        {
+                            if(nProcessed % percentStep == 0)
+                            {
+                                progress.Report($"Updating {CoreUtils.Neatify(type.GetCaption())}: {(double)nProcessed / (double)nTotal * 100:F0}%");
+                            }
+                            var obj = (rows[i].ToObject(type) as Entity)!;
                             foreach(var property in properties)
                             {
-                                var id = CoreUtils.GetPropertyValue(result, property.Name + "." + Dimensions.unitid.Property);
+                                var id = CoreUtils.GetPropertyValue(obj, property.Name + "." + Dimensions.unitid.Property);
                                 if(id is Guid guid)
                                 {
                                     var unit = items.First(x => x.ID == guid);
-                                    var dim = (property.Getter()(result) as IDimensions)!;
+                                    var dim = (property.Getter()(obj) as IDimensions)!;
                                     dim.Calculate(dim.Quantity, dim.Length, dim.Width, dim.Height, dim.Weight, unit.Formula, unit.Format);
                                 }
                             }
+                            if (obj.IsChanged())
+                            {
+                                results.Add(obj);
+                                nResult++;
+                            }
+                            nProcessed++;
                         }
-                        results = results.Where(x => x.IsChanged()).ToArray();
-                        nResults[type] = results.Length;
                         Client.Create(type).Save(results, "Updated Value and UnitSize to match dimension unit.");
                     }
+                    nResults[type] = nResult;
                 }
             }
             return nResults;

+ 36 - 2
prs.desktop/Grids/ProductDimensionUnitGrid.cs

@@ -16,6 +16,13 @@ public class ProductDimensionUnitGrid : DynamicDataGrid<ProductDimensionUnit>
     {
         base.Init();
 
+        HiddenColumns.Add(x => x.Code);
+        HiddenColumns.Add(x => x.HasQuantity);
+        HiddenColumns.Add(x => x.HasLength);
+        HiddenColumns.Add(x => x.HasWeight);
+        HiddenColumns.Add(x => x.HasWidth);
+        HiddenColumns.Add(x => x.HasHeight);
+
         AddButton("Update Expressions", null, (button, rows) =>
         {
             UpdateExpressions(rows.ToArray<ProductDimensionUnit>());
@@ -38,7 +45,7 @@ public class ProductDimensionUnitGrid : DynamicDataGrid<ProductDimensionUnit>
         {
             try
             {
-                results = DimensionUnitUtils.UpdateExpressions<ProductDimensionUnit, ProductDimensionUnitLink>(items);
+                results = DimensionUnitUtils.UpdateExpressions<ProductDimensionUnit, ProductDimensionUnitLink>(items, progress);
             }
             catch(Exception e)
             {
@@ -83,7 +90,34 @@ public class ProductDimensionUnitGrid : DynamicDataGrid<ProductDimensionUnit>
 
     protected override bool DoMerge(CoreRow[] rows)
     {
-        return base.DoMerge(rows);
+        var columns = new Column<ProductDimensionUnit>[]
+        {
+            new(x => x.HasLength),
+            new(x => x.HasQuantity),
+            new(x => x.HasHeight),
+            new(x => x.HasWeight),
+            new(x => x.HasWidth),
+        };
+
+        var target = rows[^1].ToObject<ProductDimensionUnit>();
+        if(columns.Any(c => rows.Select(r => r[c.Property]).Distinct().Skip(1).Any()))
+        {
+            MessageWindow.ShowMessage("These dimension units are incompatible, and cannot be merged.\n\n(Dimension units can only be merged if they have the same [HasQuantity], [HasLength], [HasWidth], [HasHeight] and [HasWeight] values).", "Incompatible units", image: MessageWindow.WarningImage);
+            return false;
+        }
+
+        if (base.DoMerge(rows))
+        {
+            if(MessageWindow.ShowYesNo(
+                $"Do you wish to update the UnitSize/Value for every item that uses {target.Code}? (This may take a while)",
+                "Update Expressions?"))
+            {
+                UpdateExpressions([target]);
+            }
+
+            return true;
+        }
+        return false;
     }
 
     protected override void CustomiseEditor(ProductDimensionUnit[] items, DynamicGridColumn column, BaseEditor editor)