Browse Source

Added FilterBuilder for type-safe filters

Kenric Nugteren 4 weeks ago
parent
commit
610ded72e8

+ 10 - 5
prs.classes/EnclosedEntities/Dimensions/Dimensions.cs

@@ -259,14 +259,19 @@ namespace Comal.Classes
             filter.Property = prop + unitid.Property;
             filter.IsEqualTo(dim.Unit.ID);
 
-            filter.And(prop + quantity.Property).IsEqualTo(dim.Quantity);
-            filter.And(prop + length.Property).IsEqualTo(dim.Length);
-            filter.And(prop + width.Property).IsEqualTo(dim.Width);
-            filter.And(prop + height.Property).IsEqualTo(dim.Height);
-            filter.And(prop + weight.Property).IsEqualTo(dim.Weight);
+            filter.And<double>(prop + quantity.Property).IsEqualTo(dim.Quantity);
+            filter.And<double>(prop + length.Property).IsEqualTo(dim.Length);
+            filter.And<double>(prop + width.Property).IsEqualTo(dim.Width);
+            filter.And<double>(prop + height.Property).IsEqualTo(dim.Height);
+            filter.And<double>(prop + weight.Property).IsEqualTo(dim.Weight);
 
             return filter.Parent ?? filter;
         }
+        public static Filter<T> DimensionEquals<T, TProp>(this FilterBuilder<T, TProp> filter, IDimensions dim)
+            where TProp : IDimensions
+        {
+            return filter.Filter.DimensionEquals(dim);
+        }
 
         public static IEnumerable<KeyValuePair<Expression<Func<T, object?>>, Expression<Func<U, object?>>>> GetLinks<T, U>()
             where T : IDimensioned

+ 1 - 1
prs.classes/Entities/Employee/EmployeeAlert.cs

@@ -70,7 +70,7 @@ namespace Comal.Classes
                         x =>x.Constant(1),
                         new Filter<EmployeeQualification>(x => x.Qualified).IsEqualTo(DateTime.MinValue)
                             .Or(x=>x.FrontPhoto.ID).IsEqualTo(Guid.Empty)
-                            .Or(x=>x.Expiry).IsLessThan(FilterConstant.Today))
+                            .Or(x=>x.Expiry).IsLessThanConstant(FilterConstant.Today))
                     .WithLink(x => x.Employee.ID, x => x.ID);
         }
         [ComplexFormula(typeof(QualificationsAggregate))]

+ 2 - 2
prs.classes/Entities/Employee/EmployeeLookups.cs

@@ -18,9 +18,9 @@ namespace Comal.Classes
         {
             var filter = new Filter<Employee>(x => x.ID).IsNotEqualTo(Guid.Empty);
             filter.Ands.Add(new Filter<Employee>(x => x.StartDate).IsEqualTo(DateTime.MinValue).Or(x => x.StartDate)
-                .IsLessThanOrEqualTo(FilterConstant.Today));
+                .IsLessThanOrEqualToConstant(FilterConstant.Today));
             filter.Ands.Add(new Filter<Employee>(x => x.FinishDate).IsEqualTo(DateTime.MinValue).Or(x => x.FinishDate)
-                .IsGreaterThanOrEqualTo(FilterConstant.Today));
+                .IsGreaterThanOrEqualToConstant(FilterConstant.Today));
             return filter;
         }
 

+ 1 - 1
prs.classes/Entities/Requisition/RequisitionItem.cs

@@ -35,7 +35,7 @@ namespace Comal.Classes
                     new Filter<StockHolding>(x => x.Product.ID).IsEqualTo(productid)
                         .And(x => x.Style.ID).IsEqualTo(styleid)
                         .And(x => x.Dimensions).DimensionEquals(dimensions)
-                        .And(x => x.Qty).IsNotEqualTo(0.0F),
+                        .And(x => x.Qty).IsNotEqualTo(0.0),
                     x => x.Location.ID);
                 return result;
             }

+ 1 - 1
prs.classes/Entities/Stock/StockHolding/StockHolding.cs

@@ -98,7 +98,7 @@ namespace Comal.Classes
         
             foreach(var column in Columns)
             {
-                filter.Add(new Filter<StockMovement>(column.Cast<StockMovement>()).IsEqualTo(CoreUtils.GetPropertyValue(holding, column.Property)));
+                filter.Add(Filter<StockMovement>.Where<object>(column.Cast<StockMovement>()).IsEqualTo(CoreUtils.GetPropertyValue(holding, column.Property)));
             }
         
             return filter.Combine();

+ 2 - 2
prs.desktop/Dashboards/Common/DigitalFormsDashboard.xaml.cs

@@ -1313,7 +1313,7 @@ public partial class DigitalFormsDashboard : UserControl,
             .And(x => x.FormCompleted).IsLessThan(To.AddDays(1));
         if (Properties.ShowIncompleteForms)
         {
-            completedFilter.Or(x => x.FormCompleted).IsEqualTo(FilterConstant.Null);
+            completedFilter.Or(x => x.FormCompleted).IsEqualToConstant(FilterConstant.Null);
         }
 
         var filter = new Filter<T>(x => x.Form.ID).IsEqualTo(Form!.ID)
@@ -1322,7 +1322,7 @@ public partial class DigitalFormsDashboard : UserControl,
 
         if (Properties.JobID != Guid.Empty && Properties.ShowJobFilter)
         {
-            filter.And(jobLink + ".ID").IsEqualTo(Properties.JobID);
+            filter.And<Guid>(jobLink + ".ID").IsEqualTo(Properties.JobID);
         }
         if (CustomFilter is not null)
         {

+ 2 - 2
prs.desktop/Dashboards/Manufacturing/FactoryProductivity.xaml.cs

@@ -389,14 +389,14 @@ namespace PRSDesktop
             }
 
             private void AddSearchCriteria(Filter<ManufacturingHistory> filter, string search,
-                params Expression<Func<ManufacturingHistory, object>>[] expressions)
+                params Expression<Func<ManufacturingHistory, string>>[] expressions)
             {
                 var comps = search.Trim().Split(' ');
                 foreach (var comp in comps)
                 {
                     Filter<ManufacturingHistory> result = null;
                     foreach (var expression in expressions)
-                        result = result == null ? new Filter<ManufacturingHistory>(expression).Contains(comp) : result.Or(expression).Contains(comp);
+                        result = result == null ? Filter<ManufacturingHistory>.Where(expression).Contains(comp) : result.Or(expression).Contains(comp);
                     filter.Ands.Add(result);
                 }
             }

+ 2 - 2
prs.desktop/Dashboards/System/DatabaseActivityDashboard.xaml.cs

@@ -432,14 +432,14 @@ namespace PRSDesktop
                     _view.Equals(HistoryView.Month) ? _to.AddMonths(-1) : _to.AddYears(-1);
             }
 
-            private void AddSearchCriteria(Filter<UserTracking> filter, string search, params Expression<Func<UserTracking, object>>[] expressions)
+            private void AddSearchCriteria(Filter<UserTracking> filter, string search, params Expression<Func<UserTracking, string>>[] expressions)
             {
                 var comps = search.Trim().Split(' ');
                 foreach (var comp in comps)
                 {
                     Filter<UserTracking> result = null;
                     foreach (var expression in expressions)
-                        result = result == null ? new Filter<UserTracking>(expression).Contains(comp) : result.Or(expression).Contains(comp);
+                        result = result == null ? Filter<UserTracking>.Where(expression).Contains(comp) : result.Or(expression).Contains(comp);
                     filter.Ands.Add(result);
                 }
             }

+ 2 - 2
prs.desktop/Dashboards/System/UserActivity.xaml.cs

@@ -401,14 +401,14 @@ namespace PRSDesktop
             }
 
             private void AddSearchCriteria(Filter<ModuleTracking> filter, string search,
-                params Expression<Func<ModuleTracking, object>>[] expressions)
+                params Expression<Func<ModuleTracking, string>>[] expressions)
             {
                 var comps = search.Trim().Split(' ');
                 foreach (var comp in comps)
                 {
                     Filter<ModuleTracking> result = null;
                     foreach (var expression in expressions)
-                        result = result == null ? new Filter<ModuleTracking>(expression).Contains(comp) : result.Or(expression).Contains(comp);
+                        result = result == null ? Filter<ModuleTracking>.Where(expression).Contains(comp) : result.Or(expression).Contains(comp);
                     filter.Ands.Add(result);
                 }
             }

+ 0 - 9
prs.desktop/Panels/DeliveredOnSite/DeliveredOnSitePanel.xaml.cs

@@ -129,15 +129,6 @@ namespace PRSDesktop
             }
         }
 
-        private Filter<DeliveryItem> SearchFilter(Expression<Func<DeliveryItem, object>> expression)
-        {
-            Filter<DeliveryItem> result = null;
-            var comps = _search.Trim().Split(' ');
-            foreach (var comp in comps)
-                result = result == null ? new Filter<DeliveryItem>(expression).Contains(comp) : result.And(expression).Contains(comp);
-            return result;
-        }
-
         private void Items_OnReload(object sender, Filters<DeliveryItem> criteria, Columns<DeliveryItem> columns, ref SortOrder<DeliveryItem> sortby)
         {
         }

+ 1 - 9
prs.desktop/Panels/DynamicMapColumn.cs

@@ -54,16 +54,8 @@ namespace PRSDesktop
             
             Longitude = CoreUtils.GetFullPropertyName(property, ".") + ".Longitude";
             grid.HiddenColumns.Add(CoreUtils.GetPropertyExpression<T>(Longitude));
-            try
-            {
-                Geofence =  $"{CoreUtils.GetFullPropertyName(property, ".")}.{nameof(Address.Geofence)}";
-                grid.HiddenColumns.Add(CoreUtils.GetPropertyExpression<T>(Geofence));
-            }
-            catch (Exception e)
-            {
-                Geofence = "";
-            }
 
+            Geofence = "";
             
             Image = MapImage;
             Action = MapClick;

+ 6 - 6
prs.desktop/Panels/Jobs/Summary/JobSummaryGrid.cs

@@ -379,13 +379,13 @@ internal class JobSummaryGrid : DynamicDataGrid<JobMaterial>, IMasterDetailContr
 
     private void ShowDetailGrid<TEntity>(
         String columnname,
-        Expression<Func<TEntity, object?>> productcol,
+        Expression<Func<TEntity, Guid>> productcol,
         Guid productid,
-        Expression<Func<TEntity, object?>> stylecol,
+        Expression<Func<TEntity, Guid>> stylecol,
         Guid? styleid,
         Expression<Func<TEntity, IDimensions>> dimcol,
         IDimensions? dimensions,
-        Expression<Func<TEntity, object?>>? jobcol,
+        Expression<Func<TEntity, Guid>>? jobcol,
         Filter<TEntity>? extrafilter,
         Func<CoreRow, bool>? rowfilter
     )
@@ -405,9 +405,9 @@ internal class JobSummaryGrid : DynamicDataGrid<JobMaterial>, IMasterDetailContr
         });
         grid.OnDefineFilter += t =>
         {
-            var filter = new Filter<TEntity>(productcol).IsEqualTo(productid);
+            var filter = Filter<TEntity>.Where(productcol).IsEqualTo(productid);
             if(dimensions is not null)
-                filter = filter.And(CoreUtils.GetFullPropertyName(dimcol, ".")).DimensionEquals(dimensions);
+                filter = filter.And<IDimensions>(CoreUtils.GetFullPropertyName(dimcol, ".")).DimensionEquals(dimensions);
             if (styleid.HasValue)
                 filter = filter.And(stylecol).IsEqualTo(styleid);
 
@@ -774,7 +774,7 @@ internal class JobSummaryGrid : DynamicDataGrid<JobMaterial>, IMasterDetailContr
                     var results = Client.QueryMultiple(
                         new KeyedQueryDef<StockHolding>(
                             new Filter<StockHolding>(x => x.Product.ID).InList(pids)
-                                .And(x => x.Units).IsNotEqualTo(0.0F)
+                                .And(x => x.Units).IsNotEqualTo(0.0)
                                 .And(new Filter<StockHolding>(x => x.Job.ID).IsEqualTo(Guid.Empty).Or(x => x.Job.ID).IsNotEqualTo(jobID))
                                 .And(ReservesFilter<StockHolding>(x => x.Job)),
                             Columns.None<StockHolding>().Add(x => x.Product.ID)

+ 1 - 1
prs.desktop/Panels/Products/Locations/StockHoldingGrid.cs

@@ -365,7 +365,7 @@ public class StockHoldingGrid : DynamicDataGrid<StockHolding>
                         StockHolding.GetFilter(holding),
                         x => x.JobRequisitionItem.ID)
                     // We don't care about stuff which has nothing in stock, which means it's been either issued or cancelled.
-                    .And(x => x.InStock).IsNotEqualTo(FilterConstant.Zero);
+                    .And(x => x.InStock).IsNotEqualToConstant(FilterConstant.Zero);
             }
             else
             {

+ 6 - 6
prs.desktop/Panels/Stock Forecast/StockForecastGrid.cs

@@ -518,13 +518,13 @@ public class StockForecastGrid : DynamicItemsListGrid<StockForecastItem>, IDataM
     
     private IDynamicDataGrid BuildDetailGrid<TEntity>(
         String tag, 
-        Expression<Func<TEntity,object?>> productcol, 
+        Expression<Func<TEntity,Guid>> productcol, 
         Guid productid, 
-        Expression<Func<TEntity,object?>> stylecol, 
+        Expression<Func<TEntity,Guid>> stylecol, 
         Guid? styleid, 
         Expression<Func<TEntity, IDimensions>> dimcol, 
         IDimensions? dimensions,
-        Expression<Func<TEntity,object?>>? jobcol,
+        Expression<Func<TEntity,Guid>>? jobcol,
         Filter<TEntity>? extrafilter,
         Func<CoreRow,bool>? rowfilter
     )
@@ -544,15 +544,15 @@ public class StockForecastGrid : DynamicItemsListGrid<StockForecastItem>, IDataM
         });
         _grid.OnDefineFilter += t =>
         {
-            var _filter = new Filter<TEntity>(productcol).IsEqualTo(productid);
+            var _filter = Filter<TEntity>.Where(productcol).IsEqualTo(productid);
             if(dimensions is not null)
-                _filter = _filter.And(CoreUtils.GetFullPropertyName(dimcol, ".")).DimensionEquals(dimensions);
+                _filter = _filter.And<IDimensions>(CoreUtils.GetFullPropertyName(dimcol, ".")).DimensionEquals(dimensions);
             
             if (styleid.HasValue)
                 _filter = _filter.And(stylecol).IsEqualTo(styleid);
 
             if (jobcol != null)
-                _filter = _filter.And(new Filter<TEntity>(jobcol).InList(JobIDs));
+                _filter = _filter.And(Filter<TEntity>.Where(jobcol).InList(JobIDs));
                 
             if (extrafilter != null)
                 _filter = _filter.And(extrafilter);

+ 0 - 9
prs.desktop/Panels/Tasks/TasksByStatusControl.xaml.cs

@@ -568,15 +568,6 @@ public partial class TasksByStatusControl : UserControl, ITaskControl, INotifyPr
         Host.SaveSettings();
     }
 
-    private static Filter<T> GetSearchFilter<T>(Expression<Func<T, object?>> expression, string searchText) where T : Entity, new()
-    {
-        Filter<T>? result = null;
-        var comps = searchText.Trim().Split(' ');
-        foreach (var comp in comps)
-            result = result == null ? new Filter<T>(expression).Contains(comp) : result.And(expression).Contains(comp);
-        return result ?? new Filter<T>().All();
-    }
-
     private Filter<KanbanSubscriber> GetKanbanSubscriberFilter()
     {
         var filter = new Filter<KanbanSubscriber>(x => x.Kanban.Closed).IsEqualTo(DateTime.MinValue);

+ 2 - 2
prs.desktop/Utils/CustomModuleUtils.cs

@@ -27,9 +27,9 @@ namespace PRSDesktop
 
         public static IEnumerable<Tuple<CustomModule, Bitmap>> LoadCustomModuleThumbnails(IList<CustomModule> modules)
         {
-            var thumbids = modules.Where(x => x.Thumbnail.IsValid()).Select(x => x.Thumbnail.ID);
+            var thumbids = modules.Where(x => x.Thumbnail.IsValid()).Select(x => x.Thumbnail.ID).ToArray();
             var thumbs = thumbids.Any()
-                ? new Client<Document>().Load(Filter<Document>.List(x => x.ID, ListOperator.Includes, thumbids))
+                ? new Client<Document>().Load(Filter<Document>.Where(x => x.ID).InList(thumbids))
                 : Array.Empty<Document>();
 
             var list = new List<Tuple<CustomModule, Bitmap>>();

+ 4 - 4
prs.shared/Database Update Scripts/Update_7_00.cs

@@ -12,10 +12,10 @@ public class Update_7_00 : DatabaseUpdateScript
     public override bool Update()
     {
         Convert<Assignment>(
-            new Filter<Assignment>(x=>x.Booked.Start).IsEqualTo(DateTime.MinValue)
-                .And(x=>x.Booked.Finish).IsEqualTo(DateTime.MinValue)
-                .And(x=>x.Actual.Finish).IsEqualTo(DateTime.MinValue)
-                .And(x=>x.Actual.Finish).IsEqualTo(DateTime.MinValue),
+            new Filter<Assignment>(x=>x.Booked.Start).IsEqualTo(TimeSpan.Zero)
+                .And(x=>x.Booked.Finish).IsEqualTo(TimeSpan.Zero)
+                .And(x=>x.Actual.Finish).IsEqualTo(TimeSpan.Zero)
+                .And(x=>x.Actual.Finish).IsEqualTo(TimeSpan.Zero),
             new Map<Assignment>("Start",x => x.Booked.Start),
             new Map<Assignment>("Finish",x => x.Booked.Finish),
             new Map<Assignment>("Start",x => x.Actual.Start),

+ 1 - 1
prs.stores/DeliveryNotificationStore.cs

@@ -122,7 +122,7 @@ namespace Comal.Stores
             {
                 var shipments = FindSubStore<Shipment>()
                     .Query(
-                        Filter<Shipment>.List(x => x.ID, ListOperator.Includes, deliveredracks),
+                        Filter<Shipment>.Where(x => x.ID).InList(deliveredracks.ToArray()),
                         Columns.None<Shipment>().Add(x => x.ID).Add(x => x.Delivery.ID))
                     .ToObjects<Shipment>().ToList();
                 foreach (var shipment in shipments)