diff --git a/Ctoss.Example/JsonExamples.cs b/Ctoss.Example/JsonExamples.cs
new file mode 100644
index 0000000..e0e6fc4
--- /dev/null
+++ b/Ctoss.Example/JsonExamples.cs
@@ -0,0 +1,51 @@
+namespace Ctoss.Example;
+
+public static class JsonExamples
+{
+ ///
+ /// This JSON snippet contains an example of the date range filter with
+ /// an illustration that field is case-insensitive.
+ ///
+ public const string PlainDateRangeFilter =
+ """
+ {
+ "filters":{
+ "PrOpErTy":{
+ "filterType":"date",
+ "type":"inRange",
+ "dateFrom":"10/10/2002",
+ "dateTo":"10/12/2020"
+ }
+ }
+ }
+ """;
+
+ ///
+ /// This illustrates how to define multiple conditions, and use CTOSS configuration to define the virtual field ms
+ ///
+ public const string MultipleConditionsNumberFilter =
+ """
+ {
+ "filters":{
+ "mc":{
+ "filterType":"number",
+ "operator": "and",
+ "conditions":[
+ {
+ "filterType":"number",
+ "type":"GreaterThan",
+ "filter":"10"
+ },
+ {
+ "filterType":"number",
+ "type":"LessThan",
+ "filter":"15"
+ }
+ ]
+ }
+ }
+ }
+ """;
+
+
+}
diff --git a/Ctoss.Example/Program.cs b/Ctoss.Example/Program.cs
index 35167f8..9c62d4d 100644
--- a/Ctoss.Example/Program.cs
+++ b/Ctoss.Example/Program.cs
@@ -1,5 +1,4 @@
-using Ctoss.Configuration;
-using Ctoss.Configuration.Builders;
+using Ctoss.Configuration.Builders;
using Ctoss.Example;
using Ctoss.Extensions;
using Ctoss.Models;
@@ -18,83 +17,8 @@
.Property(x => x.TextField, settings => { settings.IgnoreCase = true; })
.Apply();
-const string jsonFilter =
- """
- {
- "PrOpErTy": {
- "filterType": "date",
- "condition1": {
- "filterType": "date",
- "type": "inRange",
- "dateFrom": "10/10/2002",
- "dateTo": "10/12/2020"
- },
- "conditions": [
- {
- "filterType": "date",
- "type": "inRange",
- "date": "10/10/2002",
- "dateTo": "10/12/2020"
- }
- ]
- }
- }
- """;
-
-const string jsonNumericFilter =
- """
- {
- "mc": {
- "filterType": "number",
- "condition1": {
- "filterType": "number",
- "type": "inRange",
- "filter": "1",
- "filterTo": "20"
- },
- "conditions": [
- {
- "filterType": "number",
- "type": "GreaterThan",
- "filter": "10"
- }
- ]
- }
- }
- """;
-
-const string jsonTextFilter =
- """
- {
- "TextField": {
- "filterType": "text",
- "condition1": {
- "filterType": "text",
- "type": "contains",
- "filter": "a"
- },
- "conditions": [
- {
- "filterType": "text",
- "type": "contains",
- "filter": "a"
- }
- ]
- }
- }
- """;
-
-/*
- * The CTOSS gives you three overloads of the method WithFilter which evaluates a given filter and provides you with
- * a filtering Expression> fully compatible with IQueryable and EF.
- *
- * Overloads:
- * - WithFilter(this IQueryable query, string jsonFilter)
- * - WithFilter(this IQueryable query, string propertyName, Filter filter)
- * - WithFilter(this IQueryable query, Dictionary filters)
- */
var entities = ExampleEntityFaker.GetN(100).AsQueryable()
- .WithFilter(jsonFilter) // <-- This is the extension method from the ctoss library
+ .WithFilter(JsonExamples.PlainDateRangeFilter)
.ToList();
Console.WriteLine("Filtered entities:");
@@ -112,23 +36,10 @@
};
var numericEntities = ExampleNumericEntityFaker.GetN(100).AsQueryable()
- .WithFilter(jsonNumericFilter) // <-- This is the extension method from the ctoss library
+ .WithFilter(JsonExamples.MultipleConditionsNumberFilter)
.WithSorting(sortings)
.WithPagination(1, 10)
.ToList();
foreach (var entity in numericEntities)
Console.WriteLine($"A: {entity.A}, B: {entity.B}, SubEntity = ({entity.SubEntity.A + entity.SubEntity.B})");
-
-Console.WriteLine("\nText entities:");
-
-var textEntity = new ExampleTextEntity()
-{
- TextField = "abc"
-};
-
-var textEntities = new List { textEntity }.AsQueryable()
- .WithFilter(jsonTextFilter) // <-- This is the extension method from the ctoss library
- .ToList();
-
-foreach (var entity in textEntities) Console.WriteLine(entity.TextField);
\ No newline at end of file
diff --git a/Ctoss.Tests/DateFilterTests.cs b/Ctoss.Tests/DateFilterTests.cs
index 4d6d647..cb86de2 100644
--- a/Ctoss.Tests/DateFilterTests.cs
+++ b/Ctoss.Tests/DateFilterTests.cs
@@ -1,7 +1,6 @@
using Ctoss.Builders.Filters;
-using Ctoss.Models;
-using Ctoss.Models.Conditions;
using Ctoss.Models.Enums;
+using Ctoss.Models.V2;
using Ctoss.Tests.Models;
namespace Ctoss.Tests;
@@ -12,35 +11,19 @@ public class DateFilterTests
private readonly List _testEntities =
[
- new TestEntity
- {
- NumericProperty = 10, StringProperty = "abc", DateTimeProperty = new DateOnly(2022, 1, 1)
- },
- new TestEntity
- {
- NumericProperty = 20, StringProperty = "def", DateTimeProperty = new DateOnly(2023, 2, 2)
- },
- new TestEntity
- {
- NumericProperty = 30, StringProperty = "ghi", DateTimeProperty = new DateOnly(2024, 3, 3)
- }
+ new TestEntity(numericProperty: 10, stringProperty: "abc", dateTimeProperty: new DateOnly(2022, 1, 1)),
+ new TestEntity(numericProperty: 20, stringProperty: "def", dateTimeProperty: new DateOnly(2023, 2, 2)),
+ new TestEntity(numericProperty: 30, stringProperty: "ghi", dateTimeProperty: new DateOnly(2024, 3, 3))
];
[Fact]
public void DateFilter_Equals_Success()
{
- var condition = new DateFilterCondition
- {
- DateFrom = "01/01/2022",
- FilterType = "date",
- Type = DateFilterOptions.Equals
- };
-
- var filter = new Filter
+ var filter = new FilterModel
{
FilterType = "date",
- Condition1 = condition,
- Conditions = new List { condition }
+ DateFrom = "01/01/2022",
+ Type = "equals"
};
var expr = _filterBuilder.GetExpression("DateTimeProperty", filter)!;
@@ -53,18 +36,11 @@ public void DateFilter_Equals_Success()
[Fact]
public void DateFilter_GreaterThen_Success()
{
- var condition = new DateFilterCondition
+ var filter = new FilterModel
{
- DateFrom = "02/02/2023",
FilterType = "date",
- Type = DateFilterOptions.GreaterThen
- };
-
- var filter = new Filter
- {
- FilterType = "date",
- Condition1 = condition,
- Conditions = new List { condition }
+ DateFrom = "02/02/2023",
+ Type = "GreaterThen"
};
var expr = _filterBuilder.GetExpression("DateTimeProperty", filter)!;
@@ -77,17 +53,10 @@ public void DateFilter_GreaterThen_Success()
[Fact]
public void DateFilter_Blank_Success()
{
- var condition = new DateFilterCondition
- {
- FilterType = "date",
- Type = DateFilterOptions.Blank
- };
-
- var filter = new Filter
+ var filter = new FilterModel
{
FilterType = "date",
- Condition1 = condition,
- Conditions = new List { condition }
+ Type = "Blank"
};
var expr = _filterBuilder.GetExpression("DateTimeProperty", filter)!;
@@ -99,18 +68,11 @@ public void DateFilter_Blank_Success()
[Fact]
public void DateFilter_LessThen_Success()
{
- var condition = new DateFilterCondition
- {
- DateFrom = "01/01/2023",
- FilterType = "date",
- Type = DateFilterOptions.LessThen
- };
-
- var filter = new Filter
+ var filter = new FilterModel
{
FilterType = "date",
- Condition1 = condition,
- Conditions = new List { condition }
+ DateFrom = "01/01/2023",
+ Type = "LessThen"
};
var expr = _filterBuilder.GetExpression("DateTimeProperty", filter)!;
@@ -123,17 +85,10 @@ public void DateFilter_LessThen_Success()
[Fact]
public void DateFilter_NotBlank_Success()
{
- var condition = new DateFilterCondition
+ var filter = new FilterModel
{
FilterType = "date",
- Type = DateFilterOptions.NotBlank
- };
-
- var filter = new Filter
- {
- FilterType = "date",
- Condition1 = condition,
- Conditions = new List { condition }
+ Type = "NotBlank"
};
var expr = _filterBuilder.GetExpression("DateTimeProperty", filter)!;
@@ -145,19 +100,12 @@ public void DateFilter_NotBlank_Success()
[Fact]
public void DateFilter_InRange_Success()
{
- var condition = new DateFilterCondition
+ var filter = new FilterModel
{
+ FilterType = "date",
DateFrom = "06/06/2021",
DateTo = "09/09/2024",
- FilterType = "date",
- Type = DateFilterOptions.InRange
- };
-
- var filter = new Filter
- {
- FilterType = "date",
- Condition1 = condition,
- Conditions = new List { condition }
+ Type = "InRange"
};
var expr = _filterBuilder.GetExpression("DateTimeProperty", filter)!;
@@ -169,26 +117,24 @@ public void DateFilter_InRange_Success()
[Fact]
public void DateFilter_NotEquals_Success()
{
- var condition1 = new DateFilterCondition
+ var condition1 = new DateCondition
{
DateFrom = "01/01/2022",
FilterType = "date",
Type = DateFilterOptions.NotEquals
};
- var condition2 = new DateFilterCondition
+ var condition2 = new DateCondition
{
DateFrom = "03/03/2024",
FilterType = "date",
Type = DateFilterOptions.NotEquals
};
- var filter = new Filter
+ var filter = new FilterModel
{
FilterType = "date",
Operator = Operator.And,
- Condition1 = condition1,
- Condition2 = condition2,
- Conditions = new List { condition1, condition2 }
+ Conditions = new List { condition1, condition2 }
};
var expr = _filterBuilder.GetExpression("DateTimeProperty", filter)!;
@@ -201,27 +147,25 @@ public void DateFilter_NotEquals_Success()
[Fact]
public void DateFilter_Composed_Success()
{
- var condition1 = new DateFilterCondition
+ var condition1 = new DateCondition
{
DateFrom = "01/01/2022",
FilterType = "date",
Type = DateFilterOptions.NotEquals
};
- var condition2 = new DateFilterCondition
+ var condition2 = new DateCondition
{
DateFrom = "03/03/2024",
FilterType = "date",
Type = DateFilterOptions.LessThen
};
- var filter = new Filter
+ var filter = new FilterModel
{
- Operator = Operator.And,
FilterType = "date",
- Condition1 = condition1,
- Condition2 = condition2,
- Conditions = new List
+ Operator = Operator.And,
+ Conditions = new List
{
condition1, condition2
}
@@ -233,4 +177,4 @@ public void DateFilter_Composed_Success()
Assert.Single(result);
Assert.Equal(new DateOnly(2023, 02, 02), result.First().DateTimeProperty);
}
-}
+}
\ No newline at end of file
diff --git a/Ctoss.Tests/Models/TestEntity.cs b/Ctoss.Tests/Models/TestEntity.cs
index 773ded5..c3f9212 100644
--- a/Ctoss.Tests/Models/TestEntity.cs
+++ b/Ctoss.Tests/Models/TestEntity.cs
@@ -2,6 +2,17 @@
public class TestEntity
{
+ public TestEntity()
+ {
+ }
+
+ public TestEntity(int? numericProperty, string? stringProperty, DateOnly dateTimeProperty)
+ {
+ NumericProperty = numericProperty;
+ StringProperty = stringProperty;
+ DateTimeProperty = dateTimeProperty;
+ }
+
public string? StringProperty { get; set; } = null!;
public DateOnly DateTimeProperty { get; set; }
public int? NumericProperty { get; set; }
diff --git a/Ctoss.Tests/NumberFilterTests.cs b/Ctoss.Tests/NumberFilterTests.cs
index cf3dab0..0dca290 100644
--- a/Ctoss.Tests/NumberFilterTests.cs
+++ b/Ctoss.Tests/NumberFilterTests.cs
@@ -1,7 +1,6 @@
using Ctoss.Builders.Filters;
-using Ctoss.Models;
-using Ctoss.Models.Conditions;
using Ctoss.Models.Enums;
+using Ctoss.Models.V2;
using Ctoss.Tests.Models;
namespace Ctoss.Tests;
@@ -29,18 +28,11 @@ public class FilterTests
[Fact]
public void NumericFilter_Equals_Success()
{
- var condition = new NumberFilterCondition
+ var filter = new FilterModel
{
Filter = "10",
FilterType = "number",
- Type = NumberFilterOptions.Equals
- };
-
- var filter = new Filter
- {
- FilterType = "number",
- Condition1 = condition,
- Conditions = new List { condition }
+ Type = "Equals"
};
var expr = _filterBuilder.GetExpression("NumericProperty", filter)!;
@@ -53,20 +45,12 @@ public void NumericFilter_Equals_Success()
[Fact]
public void NumericFilter_GreaterThen_Success()
{
- var condition = new NumberFilterCondition
- {
- Filter = "20",
- FilterType = "number",
- Type = NumberFilterOptions.GreaterThan
- };
-
- var filter = new Filter
+ var filter = new FilterModel
{
FilterType = "number",
- Condition1 = condition,
- Conditions = new List { condition }
+ Filter = "20",
+ Type = "GreaterThan"
};
-
var expr = _filterBuilder.GetExpression("NumericProperty", filter)!;
var result = _testEntities.AsQueryable().Where(expr).ToList();
@@ -77,18 +61,11 @@ public void NumericFilter_GreaterThen_Success()
[Fact]
public void NumericFilter_GreaterThenOrEquals_Success()
{
- var condition = new NumberFilterCondition
+ var filter = new FilterModel
{
Filter = "30",
FilterType = "number",
- Type = NumberFilterOptions.GreaterThanOrEqual
- };
-
- var filter = new Filter
- {
- FilterType = "number",
- Condition1 = condition,
- Conditions = new List { condition }
+ Type = "GreaterThanOrEqual"
};
var expr = _filterBuilder.GetExpression("NumericProperty", filter)!;
@@ -101,18 +78,11 @@ public void NumericFilter_GreaterThenOrEquals_Success()
[Fact]
public void NumericFilter_LessThen_Success()
{
- var condition = new NumberFilterCondition
+ var filter = new FilterModel
{
Filter = "20",
FilterType = "number",
- Type = NumberFilterOptions.LessThan
- };
-
- var filter = new Filter
- {
- FilterType = "number",
- Condition1 = condition,
- Conditions = new List { condition }
+ Type = "LessThan"
};
var expr = _filterBuilder.GetExpression("NumericProperty", filter)!;
@@ -125,18 +95,11 @@ public void NumericFilter_LessThen_Success()
[Fact]
public void NumericFilter_LessThenOrEquals_Success()
{
- var condition = new NumberFilterCondition
+ var filter = new FilterModel
{
Filter = "10",
FilterType = "number",
- Type = NumberFilterOptions.LessThanOrEqual
- };
-
- var filter = new Filter
- {
- FilterType = "number",
- Condition1 = condition,
- Conditions = new List { condition }
+ Type = "LessThanOrEqual"
};
var expr = _filterBuilder.GetExpression("NumericProperty", filter)!;
@@ -149,19 +112,12 @@ public void NumericFilter_LessThenOrEquals_Success()
[Fact]
public void NumericFilter_InRange_Success()
{
- var condition = new NumberFilterCondition
+ var filter = new FilterModel
{
Filter = "0",
FilterTo = "12",
FilterType = "number",
- Type = NumberFilterOptions.InRange
- };
-
- var filter = new Filter
- {
- FilterType = "number",
- Condition1 = condition,
- Conditions = new List { condition }
+ Type = "InRange"
};
var expr = _filterBuilder.GetExpression("NumericProperty", filter)!;
@@ -174,26 +130,24 @@ public void NumericFilter_InRange_Success()
[Fact]
public void NumericFilter_NotEquals_Success()
{
- var condition1 = new NumberFilterCondition
+ var condition1 = new NumberCondition
{
Filter = "10",
FilterType = "number",
Type = NumberFilterOptions.NotEquals
};
- var condition2 = new NumberFilterCondition
+ var condition2 = new NumberCondition
{
Filter = "20",
FilterType = "number",
Type = NumberFilterOptions.NotEquals
};
- var filter = new Filter
+ var filter = new FilterModel
{
FilterType = "number",
Operator = Operator.And,
- Condition1 = condition1,
- Condition2 = condition2,
- Conditions = new List { condition1, condition2 }
+ Conditions = new List { condition1, condition2 }
};
var expr = _filterBuilder.GetExpression("NumericProperty", filter)!;
@@ -206,18 +160,11 @@ public void NumericFilter_NotEquals_Success()
[Fact]
public void NumericFilter_NotBlank_Success()
{
- var condition1 = new NumberFilterCondition
+ var filter = new FilterModel
{
Filter = "10",
FilterType = "number",
- Type = NumberFilterOptions.NotBlank
- };
-
- var filter = new Filter
- {
- FilterType = "number",
- Condition1 = condition1,
- Conditions = new List { condition1 }
+ Type = "NotBlank"
};
var expr = _filterBuilder.GetExpression("NumericProperty", filter)!;
@@ -229,50 +176,40 @@ public void NumericFilter_NotBlank_Success()
[Fact]
public void NumericFilter_Blank_Success()
{
- var condition1 = new NumberFilterCondition
- {
- Filter = "10",
- FilterType = "number",
- Type = NumberFilterOptions.Blank
- };
-
- var filter = new Filter
+ var filter = new FilterModel
{
FilterType = "number",
- Condition1 = condition1,
- Conditions = new List { condition1 }
+ Type = "Blank"
};
var expr = _filterBuilder.GetExpression("NumericProperty", filter)!;
var result = _testEntities.AsQueryable().Where(expr).ToList();
- Assert.Equal(0, result.Count);
+ Assert.Empty(result);
}
[Fact]
public void NumericFilter_Composed_Success()
{
- var condition1 = new NumberFilterCondition
+ var condition1 = new NumberCondition
{
Filter = "25",
FilterType = "number",
Type = NumberFilterOptions.LessThan
};
- var condition2 = new NumberFilterCondition
+ var condition2 = new NumberCondition
{
Filter = "10",
FilterType = "number",
Type = NumberFilterOptions.NotEquals
};
- var filter = new Filter
+ var filter = new FilterModel
{
Operator = Operator.And,
FilterType = "number",
- Condition1 = condition1,
- Condition2 = condition2,
- Conditions = new List
+ Conditions = new List
{
condition1, condition2
}
@@ -284,4 +221,4 @@ public void NumericFilter_Composed_Success()
Assert.Single(result);
Assert.Equal(20, result.First().NumericProperty);
}
-}
+}
\ No newline at end of file
diff --git a/Ctoss.Tests/TextFilterTests.cs b/Ctoss.Tests/TextFilterTests.cs
index 4e3d063..8b5f8be 100644
--- a/Ctoss.Tests/TextFilterTests.cs
+++ b/Ctoss.Tests/TextFilterTests.cs
@@ -1,7 +1,6 @@
using Ctoss.Builders.Filters;
-using Ctoss.Models;
-using Ctoss.Models.Conditions;
using Ctoss.Models.Enums;
+using Ctoss.Models.V2;
using Ctoss.Tests.Models;
namespace Ctoss.Tests;
@@ -29,18 +28,11 @@ public class TextFilterTests
[Fact]
public void TextFilter_Equals_Success()
{
- var condition = new TextFilterCondition
+ var filter = new FilterModel
{
Filter = "abc",
FilterType = "text",
- Type = TextFilterOptions.Equals
- };
-
- var filter = new Filter
- {
- FilterType = "text",
- Condition1 = condition,
- Conditions = new List { condition }
+ Type = "Equals"
};
var expr = _filterBuilder.GetExpression("StringProperty", filter)!;
@@ -53,18 +45,11 @@ public void TextFilter_Equals_Success()
[Fact]
public void TextFilter_StartsWith_Success()
{
- var condition = new TextFilterCondition
+ var filter = new FilterModel
{
Filter = "a",
FilterType = "text",
- Type = TextFilterOptions.StartsWith
- };
-
- var filter = new Filter
- {
- FilterType = "text",
- Condition1 = condition,
- Conditions = new List { condition }
+ Type = "StartsWith"
};
var expr = _filterBuilder.GetExpression("StringProperty", filter)!;
@@ -77,18 +62,11 @@ public void TextFilter_StartsWith_Success()
[Fact]
public void TextFilter_EndsWith_Success()
{
- var condition = new TextFilterCondition
+ var filter = new FilterModel
{
Filter = "c",
FilterType = "text",
- Type = TextFilterOptions.EndsWith
- };
-
- var filter = new Filter
- {
- FilterType = "text",
- Condition1 = condition,
- Conditions = new List { condition }
+ Type = "EndsWith"
};
var expr = _filterBuilder.GetExpression("StringProperty", filter)!;
@@ -101,17 +79,10 @@ public void TextFilter_EndsWith_Success()
[Fact]
public void TextFilter_NotBlank_Success()
{
- var condition = new TextFilterCondition
- {
- FilterType = "text",
- Type = TextFilterOptions.NotBlank
- };
-
- var filter = new Filter
+ var filter = new FilterModel
{
FilterType = "text",
- Condition1 = condition,
- Conditions = new List { condition }
+ Type = "NotBlank"
};
var expr = _filterBuilder.GetExpression("StringProperty", filter)!;
@@ -123,18 +94,11 @@ public void TextFilter_NotBlank_Success()
[Fact]
public void TextFilter_Contains_Success()
{
- var condition = new TextFilterCondition
+ var filter = new FilterModel
{
Filter = "ab",
FilterType = "text",
- Type = TextFilterOptions.Contains
- };
-
- var filter = new Filter
- {
- FilterType = "text",
- Condition1 = condition,
- Conditions = new List { condition }
+ Type = "Contains"
};
var expr = _filterBuilder.GetExpression("StringProperty", filter)!;
@@ -147,26 +111,24 @@ public void TextFilter_Contains_Success()
[Fact]
public void TextFilter_NotEquals_Success()
{
- var condition1 = new TextFilterCondition
+ var condition1 = new TextCondition
{
Filter = "abc",
FilterType = "text",
Type = TextFilterOptions.NotEquals
};
- var condition2 = new TextFilterCondition
+ var condition2 = new TextCondition
{
Filter = "ghi",
FilterType = "text",
Type = TextFilterOptions.NotEquals
};
- var filter = new Filter
+ var filter = new FilterModel
{
FilterType = "text",
Operator = Operator.And,
- Condition1 = condition1,
- Condition2 = condition2,
- Conditions = new List { condition1, condition2 }
+ Conditions = new List { condition1, condition2 }
};
var expr = _filterBuilder.GetExpression("StringProperty", filter)!;
@@ -179,27 +141,25 @@ public void TextFilter_NotEquals_Success()
[Fact]
public void TextFilter_Composed_Success()
{
- var condition1 = new TextFilterCondition
+ var condition1 = new TextCondition
{
Filter = "def",
FilterType = "text",
Type = TextFilterOptions.NotEquals
};
- var condition2 = new TextFilterCondition
+ var condition2 = new TextCondition
{
Filter = "a",
FilterType = "text",
Type = TextFilterOptions.StartsWith
};
- var filter = new Filter
+ var filter = new FilterModel
{
Operator = Operator.And,
FilterType = "text",
- Condition1 = condition1,
- Condition2 = condition2,
- Conditions = new List
+ Conditions = new List
{
condition1, condition2
}
diff --git a/Ctoss/Builders/Filters/DateFilterBuilder.cs b/Ctoss/Builders/Filters/DateFilterBuilder.cs
index 11ca072..bbbfb39 100644
--- a/Ctoss/Builders/Filters/DateFilterBuilder.cs
+++ b/Ctoss/Builders/Filters/DateFilterBuilder.cs
@@ -1,12 +1,12 @@
using System.Linq.Expressions;
-using Ctoss.Models.Conditions;
using Ctoss.Models.Enums;
+using Ctoss.Models.V2;
namespace Ctoss.Builders.Filters;
-public class DateFilterBuilder : IPropertyFilterBuilder
+public class DateFilterBuilder : IPropertyFilterBuilder
{
- public Expression> GetExpression(string property, DateFilterCondition condition)
+ public Expression> GetExpression(string property, DateCondition condition)
{
return condition.Type switch
{
@@ -18,7 +18,7 @@ DateFilterOptions.Blank or DateFilterOptions.NotBlank or DateFilterOptions.Empty
};
}
- private Expression> GetBlankExpression(string property, DateFilterCondition condition)
+ private Expression> GetBlankExpression(string property, DateCondition condition)
{
var propertyType = IPropertyBuilder.GetPropertyType(property);
@@ -45,7 +45,7 @@ DateFilterOptions.Empty or DateFilterOptions.Blank
};
}
- private Expression> GetRangeExpression(string property, DateFilterCondition condition)
+ private Expression> GetRangeExpression(string property, DateCondition condition)
{
var propertyType = IPropertyBuilder.GetPropertyType(property);
@@ -72,7 +72,7 @@ private Expression> GetRangeExpression(string property, DateFil
Expression.AndAlso(greaterThan, lessThan), parameter);
}
- private Expression> GetComparisonExpression(string property, DateFilterCondition condition)
+ private Expression> GetComparisonExpression(string property, DateCondition condition)
{
var parameter = Expression.Parameter(typeof(T), "x");
diff --git a/Ctoss/Builders/Filters/FilterBuilder.cs b/Ctoss/Builders/Filters/FilterBuilder.cs
index 327c579..942754a 100644
--- a/Ctoss/Builders/Filters/FilterBuilder.cs
+++ b/Ctoss/Builders/Filters/FilterBuilder.cs
@@ -1,38 +1,42 @@
using System.Linq.Expressions;
using System.Reflection;
using Ctoss.Extensions;
-using Ctoss.Models;
-using Ctoss.Models.Conditions;
using Ctoss.Models.Enums;
+using Ctoss.Models.V2;
namespace Ctoss.Builders.Filters;
public class FilterBuilder
{
- private readonly IPropertyFilterBuilder _textFilterBuilder = new TextFilterBuilder();
- private readonly IPropertyFilterBuilder _dateFilterBuilder = new DateFilterBuilder();
- private readonly IPropertyFilterBuilder _numberFilterBuilder = new NumberFilterBuilder();
+ private readonly IPropertyFilterBuilder _textFilterBuilder = new TextFilterBuilder();
+ private readonly IPropertyFilterBuilder _dateFilterBuilder = new DateFilterBuilder();
+ private readonly IPropertyFilterBuilder _numberFilterBuilder = new NumberFilterBuilder();
+ private readonly IPropertyFilterBuilder _setFilterBuilder = new SetFilterBuilder();
- public Expression>? GetExpression(Dictionary? filters)
+ public Expression>? GetExpression(AgGridFilter? filterSet)
{
- if (filters == null)
+ if (filterSet == null)
return null;
var expressions = new List>>();
- expressions.AddRange(filters.Select(filter => GetExpressionInternal(filter.Key, filter.Value)));
+ expressions.AddRange(filterSet.Filters
+ .Select(filter => GetExpressionInternal(filter.Key, filter.Value)));
return expressions.Aggregate((acc, expr) => acc.AndAlso(expr));
}
- public Expression>? GetExpression(string property, Filter filter)
- => GetExpression(new Dictionary { { property, filter } });
+ public Expression>? GetExpression(string property, FilterModel filter)
+ => GetExpression(new AgGridFilter
+ {
+ Filters = new Dictionary { { property, filter } }
+ });
- private Expression> GetExpressionInternal(string property, Filter? filter)
+ private Expression> GetExpressionInternal(string property, FilterModel? filter)
{
if (filter == null)
return _ => true;
- if (filter.Operator != Operator.NoOp)
+ if (filter.Operator != null && filter.Operator != Operator.NoOp)
{
return filter.Conditions?
.Select(c => GetFilterExpr(property, c))
@@ -44,10 +48,46 @@ private Expression> GetExpressionInternal(string property, Filt
})!;
}
- return GetFilterExpr(property, filter.Condition1);
+ return GetFilterExpr(property, MapPlainFilterToConditions(filter));
+ }
+
+ private static FilterConditionBase MapPlainFilterToConditions(FilterModel filter)
+ {
+ if (filter.Conditions is not null && filter.Conditions?.Count != 0)
+ throw new ArgumentException("The given filter is not a plain filter");
+
+ return filter.FilterType switch
+ {
+ "text" => new TextCondition
+ {
+ Type = Enum.Parse(filter.Type, ignoreCase: true),
+ Filter = filter.Filter!,
+ FilterType = filter.FilterType
+ },
+ "date" => new DateCondition
+ {
+ Type = Enum.Parse(filter.Type, ignoreCase: true),
+ DateFrom = filter.DateFrom,
+ DateTo = filter.DateTo,
+ FilterType = filter.FilterType
+ },
+ "number" => new NumberCondition
+ {
+ Type = Enum.Parse(filter.Type, ignoreCase: true),
+ Filter = filter.Filter!,
+ FilterTo = filter.FilterTo!,
+ FilterType = filter.FilterType
+ },
+ "set" => new SetCondition
+ {
+ FilterType = filter.FilterType,
+ Values = filter.Values
+ },
+ _ => throw new ArgumentException("Unknown filter type")
+ };
}
- private Expression> GetFilterExpr(string property, FilterCondition? condition)
+ private Expression> GetFilterExpr(string property, FilterConditionBase? condition)
{
// NOTE: first of all, we're trying to get a real property name from the given one.
// If we find it, we can use it to work with an expression. Else the given property name will be used.
@@ -57,13 +97,15 @@ private Expression> GetFilterExpr(string property, FilterCondit
var propertyName = normalizedProperty?.Name ?? property;
return condition switch
{
- TextFilterCondition textCondition
+ TextCondition textCondition
=> _textFilterBuilder.GetExpression(propertyName, textCondition),
- DateFilterCondition dateCondition
+ DateCondition dateCondition
=> _dateFilterBuilder.GetExpression(propertyName, dateCondition),
- NumberFilterCondition numberCondition
+ NumberCondition numberCondition
=> _numberFilterBuilder.GetExpression(propertyName, numberCondition),
+ SetCondition setCondition
+ => _setFilterBuilder.GetExpression(propertyName, setCondition),
_ => _ => true
};
}
-}
+}
\ No newline at end of file
diff --git a/Ctoss/Builders/Filters/NumberFilterBuilder.cs b/Ctoss/Builders/Filters/NumberFilterBuilder.cs
index 2353980..e7440a0 100644
--- a/Ctoss/Builders/Filters/NumberFilterBuilder.cs
+++ b/Ctoss/Builders/Filters/NumberFilterBuilder.cs
@@ -1,12 +1,12 @@
using System.Linq.Expressions;
-using Ctoss.Models.Conditions;
using Ctoss.Models.Enums;
+using Ctoss.Models.V2;
namespace Ctoss.Builders.Filters;
-public class NumberFilterBuilder : IPropertyFilterBuilder
+public class NumberFilterBuilder : IPropertyFilterBuilder
{
- public Expression> GetExpression(string property, NumberFilterCondition condition)
+ public Expression> GetExpression(string property, NumberCondition condition)
{
return condition.Type switch
{
@@ -18,7 +18,7 @@ NumberFilterOptions.Blank or NumberFilterOptions.NotBlank or NumberFilterOptions
};
}
- private Expression> GetBlankExpression(string property, NumberFilterCondition condition)
+ private Expression> GetBlankExpression(string property, NumberCondition condition)
{
var propertyType = IPropertyBuilder.GetPropertyType(property);
@@ -49,7 +49,7 @@ NumberFilterOptions.Empty or NumberFilterOptions.NotBlank
};
}
- private Expression> GetRangeExpression(string property, NumberFilterCondition condition)
+ private Expression> GetRangeExpression(string property, NumberCondition condition)
{
if (string.IsNullOrEmpty(condition.Filter))
throw new ArgumentException("Filter value is required.");
@@ -77,7 +77,7 @@ private Expression> GetRangeExpression(string property, NumberF
);
}
- private Expression> GetComparisonExpression(string property, NumberFilterCondition condition)
+ private Expression> GetComparisonExpression(string property, NumberCondition condition)
{
if (string.IsNullOrEmpty(condition.Filter))
throw new ArgumentException("Filter value is required.");
diff --git a/Ctoss/Builders/Filters/SetFilterBuilder.cs b/Ctoss/Builders/Filters/SetFilterBuilder.cs
new file mode 100644
index 0000000..72ed70d
--- /dev/null
+++ b/Ctoss/Builders/Filters/SetFilterBuilder.cs
@@ -0,0 +1,12 @@
+using System.Linq.Expressions;
+using Ctoss.Models.V2;
+
+namespace Ctoss.Builders.Filters;
+
+internal class SetFilterBuilder : IPropertyFilterBuilder
+{
+ public Expression> GetExpression(string property, SetCondition condition)
+ {
+ throw new NotImplementedException();
+ }
+}
\ No newline at end of file
diff --git a/Ctoss/Builders/Filters/TextFilterBuilder.cs b/Ctoss/Builders/Filters/TextFilterBuilder.cs
index c9b7809..2de7cfa 100644
--- a/Ctoss/Builders/Filters/TextFilterBuilder.cs
+++ b/Ctoss/Builders/Filters/TextFilterBuilder.cs
@@ -1,13 +1,13 @@
using System.Linq.Expressions;
using Ctoss.Configuration;
-using Ctoss.Models.Conditions;
using Ctoss.Models.Enums;
+using Ctoss.Models.V2;
namespace Ctoss.Builders.Filters;
-public class TextFilterBuilder : IPropertyFilterBuilder
+public class TextFilterBuilder : IPropertyFilterBuilder
{
- public Expression> GetExpression(string property, TextFilterCondition condition)
+ public Expression> GetExpression(string property, TextCondition condition)
{
var parameter = Expression.Parameter(typeof(T), "x");
var propertyExpression = IPropertyFilterBuilder
diff --git a/Ctoss/Ctoss.csproj b/Ctoss/Ctoss.csproj
index 53b40fa..b4e89ab 100644
--- a/Ctoss/Ctoss.csproj
+++ b/Ctoss/Ctoss.csproj
@@ -5,7 +5,7 @@
enable
enable
Ctoss
- 10
+ 11
diff --git a/Ctoss/Extensions/AgGridExtensions.cs b/Ctoss/Extensions/AgGridExtensions.cs
index 5d32861..832e37e 100644
--- a/Ctoss/Extensions/AgGridExtensions.cs
+++ b/Ctoss/Extensions/AgGridExtensions.cs
@@ -6,7 +6,7 @@ public static class AgGridExtensions
{
public static AgGridQueryResult Apply(this IEnumerable all, AgGridQuery query)
{
- var applyFilter = query.FilterModel is { Count: > 0 };
+ var applyFilter = query.FilterModel!.Filters is { Count: > 0 };
if (applyFilter)
all = all.WithFilter(query.FilterModel!);
@@ -17,7 +17,7 @@ public static AgGridQueryResult Apply(this IEnumerable all, AgGridQuery
var array = all.ToArray();
var totalCount = array.Length;
var paginated = array
- .Skip(query.StartRow - 1)
+ .Skip(query.StartRow)
.Take(query.EndRow - query.StartRow)
.ToList();
@@ -26,7 +26,7 @@ public static AgGridQueryResult Apply(this IEnumerable all, AgGridQuery
public static AgGridQueryResult Apply(this IQueryable all, AgGridQuery query)
{
- var applyFilter = query.FilterModel is { Count: > 0 };
+ var applyFilter = query.FilterModel!.Filters is { Count: > 0 };
if (applyFilter)
all = all.WithFilter(query.FilterModel!);
@@ -36,7 +36,7 @@ public static AgGridQueryResult Apply(this IQueryable all, AgGridQuery
var totalCount = all.Count();
var paginated = all
- .Skip(query.StartRow - 1)
+ .Skip(query.StartRow)
.Take(query.EndRow - query.StartRow)
.ToList();
diff --git a/Ctoss/Extensions/EnumerableExtensions.cs b/Ctoss/Extensions/EnumerableExtensions.cs
index cc562bf..1405eb7 100644
--- a/Ctoss/Extensions/EnumerableExtensions.cs
+++ b/Ctoss/Extensions/EnumerableExtensions.cs
@@ -4,6 +4,7 @@
using Ctoss.Json;
using Ctoss.Models;
using Ctoss.Models.Enums;
+using Ctoss.Models.V2;
namespace Ctoss.Extensions;
@@ -70,24 +71,29 @@ public static IEnumerable WithSorting(this IEnumerable query, List WithFilter(
this IEnumerable query, string jsonFilter) =>
query.WithFilter(
- JsonSerializer.Deserialize>(
+ JsonSerializer.Deserialize(
jsonFilter, CtossJsonDefaults.DefaultJsonOptions)
);
public static IEnumerable WithFilter(
- this IEnumerable query, string propertyName, Filter? filter) =>
+ this IEnumerable query, string propertyName, FilterModel? filter) =>
filter is null
? query
- : WithFilter(query, new Dictionary { { propertyName, filter } });
+ : WithFilter(
+ query,
+ new AgGridFilter
+ {
+ Filters = new Dictionary { { propertyName, filter } }
+ });
public static IEnumerable WithFilter(
- this IEnumerable query, Dictionary? filters)
+ this IEnumerable query, AgGridFilter? filterSet)
{
- if (filters is null || !filters.Any())
+ if (filterSet is null || !filterSet.Filters.Any())
return query;
var filterBuilder = new FilterBuilder();
- var predicate = filterBuilder.GetExpression(filters);
+ var predicate = filterBuilder.GetExpression(filterSet);
if (predicate is null)
throw new ArgumentException("Invalid filter");
diff --git a/Ctoss/Extensions/QueryableExtensions.cs b/Ctoss/Extensions/QueryableExtensions.cs
index 02de9c4..c332327 100644
--- a/Ctoss/Extensions/QueryableExtensions.cs
+++ b/Ctoss/Extensions/QueryableExtensions.cs
@@ -4,6 +4,7 @@
using Ctoss.Json;
using Ctoss.Models;
using Ctoss.Models.Enums;
+using Ctoss.Models.V2;
namespace Ctoss.Extensions;
@@ -70,24 +71,29 @@ public static IQueryable WithSorting(this IQueryable query, List WithFilter(
this IQueryable query, string jsonFilter) =>
query.WithFilter(
- JsonSerializer.Deserialize>(
+ JsonSerializer.Deserialize(
jsonFilter, CtossJsonDefaults.DefaultJsonOptions)
);
public static IQueryable WithFilter(
- this IQueryable query, string propertyName, Filter? filter) =>
+ this IQueryable query, string propertyName, FilterModel? filter) =>
filter is null
? query
- : WithFilter(query, new Dictionary { { propertyName, filter } });
+ : WithFilter(
+ query,
+ new AgGridFilter
+ {
+ Filters = new Dictionary { { propertyName, filter } }
+ });
public static IQueryable WithFilter(
- this IQueryable query, Dictionary? filters)
+ this IQueryable query, AgGridFilter? filtersSet)
{
- if (filters is null || !filters.Any())
+ if (filtersSet is null || !filtersSet.Filters.Any())
return query;
var filterBuilder = new FilterBuilder();
- var predicate = filterBuilder.GetExpression(filters);
+ var predicate = filterBuilder.GetExpression(filtersSet);
if (predicate is null)
throw new ArgumentException("Invalid filter");
diff --git a/Ctoss/Json/FilterConditionConverter.cs b/Ctoss/Json/FilterConditionConverter.cs
deleted file mode 100644
index e25b591..0000000
--- a/Ctoss/Json/FilterConditionConverter.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-using System.Text.Json;
-using System.Text.Json.Serialization;
-using Ctoss.Models.Conditions;
-
-namespace Ctoss.Json;
-
-internal class FilterConditionConverter : JsonConverter
-{
- public override FilterCondition Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
- {
- using var doc = JsonDocument.ParseValue(ref reader);
- var root = doc.RootElement;
- var filterType = root.GetProperty("filterType").GetString()
- ?? throw new ArgumentException("filterType is required");
-
- return (filterType switch
- {
- "text" => JsonSerializer.Deserialize(root.GetRawText(), options),
- "number" => JsonSerializer.Deserialize(root.GetRawText(), options),
- "date" => JsonSerializer.Deserialize(root.GetRawText(), options),
- _ => throw new NotSupportedException($"FilterType {filterType} is not supported")
- })!;
- }
-
- public override void Write(Utf8JsonWriter writer, FilterCondition value, JsonSerializerOptions options)
- {
- JsonSerializer.Serialize(writer, (object)value, options);
- }
-}
diff --git a/Ctoss/Json/FilterConverter.cs b/Ctoss/Json/FilterConverter.cs
new file mode 100644
index 0000000..88ae9dc
--- /dev/null
+++ b/Ctoss/Json/FilterConverter.cs
@@ -0,0 +1,29 @@
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace Ctoss.Models.V2;
+
+public class FilterConverter : JsonConverter
+{
+ public override FilterConditionBase? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ using var doc = JsonDocument.ParseValue(ref reader);
+ var root = doc.RootElement;
+ var filterType = root.GetProperty("filterType").GetString();
+
+ return filterType switch
+ {
+ "text" => JsonSerializer.Deserialize(root.GetRawText(), options),
+ "number" => JsonSerializer.Deserialize(root.GetRawText(), options),
+ "date" => JsonSerializer.Deserialize(root.GetRawText(), options),
+ "set" => JsonSerializer.Deserialize(root.GetRawText(), options),
+ "multi" => JsonSerializer.Deserialize(root.GetRawText(), options),
+ _ => throw new NotSupportedException($"Filter type '{filterType}' is not supported")
+ };
+ }
+
+ public override void Write(Utf8JsonWriter writer, FilterConditionBase? value, JsonSerializerOptions options)
+ {
+ JsonSerializer.Serialize(writer, value, value.GetType(), options);
+ }
+}
\ No newline at end of file
diff --git a/Ctoss/Json/JsonDefaults.cs b/Ctoss/Json/JsonDefaults.cs
index 8905544..127c661 100644
--- a/Ctoss/Json/JsonDefaults.cs
+++ b/Ctoss/Json/JsonDefaults.cs
@@ -1,5 +1,7 @@
using System.Text.Json;
+using System.Text.Json.Serialization;
using Ctoss.Models.Enums;
+using Ctoss.Models.V2;
namespace Ctoss.Json;
@@ -9,7 +11,8 @@ public static class CtossJsonDefaults
{
Converters =
{
- new FilterConditionConverter(),
+ new FilterConverter(),
+ new NumberToStringConverter(),
new JsonStringEnumConverter(),
new JsonStringEnumConverter(),
new JsonStringEnumConverter(),
@@ -17,5 +20,6 @@ public static class CtossJsonDefaults
new JsonStringEnumConverter()
},
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
+ NumberHandling = JsonNumberHandling.WriteAsString
};
}
diff --git a/Ctoss/Json/NumberToStringConverter.cs b/Ctoss/Json/NumberToStringConverter.cs
new file mode 100644
index 0000000..b723dd7
--- /dev/null
+++ b/Ctoss/Json/NumberToStringConverter.cs
@@ -0,0 +1,22 @@
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace Ctoss.Json;
+
+public class NumberToStringConverter : JsonConverter
+{
+ public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ return reader.TokenType switch
+ {
+ JsonTokenType.Number => reader.GetDouble().ToString(),
+ JsonTokenType.String => reader.GetString(),
+ _ => throw new JsonException("Unexpected token type")
+ };
+ }
+
+ public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
+ {
+ writer.WriteStringValue(value);
+ }
+}
diff --git a/Ctoss/Models/AgGrid/AgGridQuery.cs b/Ctoss/Models/AgGrid/AgGridQuery.cs
index e70aa3c..abe6e51 100644
--- a/Ctoss/Models/AgGrid/AgGridQuery.cs
+++ b/Ctoss/Models/AgGrid/AgGridQuery.cs
@@ -1,8 +1,10 @@
+using Ctoss.Models.V2;
+
namespace Ctoss.Models.AgGrid;
public record AgGridQuery(
int StartRow,
int EndRow,
List? SortModel,
- Dictionary? FilterModel
-);
\ No newline at end of file
+ AgGridFilter? FilterModel
+);
diff --git a/Ctoss/Models/Conditions/DateFilterCondition.cs b/Ctoss/Models/Conditions/DateFilterCondition.cs
deleted file mode 100644
index 4b6f05a..0000000
--- a/Ctoss/Models/Conditions/DateFilterCondition.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using Ctoss.Models.Enums;
-
-namespace Ctoss.Models.Conditions;
-
-public record DateFilterCondition : FilterCondition
-{
- public string? DateFrom { get; init; }
- public string? DateTo { get; init; }
- public DateFilterOptions? Type { get; init; }
-}
diff --git a/Ctoss/Models/Conditions/FilterCondition.cs b/Ctoss/Models/Conditions/FilterCondition.cs
deleted file mode 100644
index b400fdf..0000000
--- a/Ctoss/Models/Conditions/FilterCondition.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-namespace Ctoss.Models.Conditions;
-
-public record FilterCondition
-{
- public string FilterType { get; init; } = null!;
-}
diff --git a/Ctoss/Models/Conditions/NumberFilterCondition.cs b/Ctoss/Models/Conditions/NumberFilterCondition.cs
deleted file mode 100644
index 6ae06ba..0000000
--- a/Ctoss/Models/Conditions/NumberFilterCondition.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using Ctoss.Models.Enums;
-
-namespace Ctoss.Models.Conditions;
-
-public record NumberFilterCondition : FilterCondition
-{
- public string? Filter { get; init; }
- public string? FilterTo { get; init; }
- public NumberFilterOptions? Type { get; init; }
-}
diff --git a/Ctoss/Models/Conditions/TextFilterCondition.cs b/Ctoss/Models/Conditions/TextFilterCondition.cs
deleted file mode 100644
index e13e195..0000000
--- a/Ctoss/Models/Conditions/TextFilterCondition.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Ctoss.Models.Conditions;
-
-public record TextFilterCondition : FilterCondition
-{
- public string? Filter { get; init; }
- public Enums.TextFilterOptions Type { get; init; }
-}
diff --git a/Ctoss/Models/Filter.cs b/Ctoss/Models/Filter.cs
deleted file mode 100644
index 836a7fd..0000000
--- a/Ctoss/Models/Filter.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using Ctoss.Models.Conditions;
-using Ctoss.Models.Enums;
-
-namespace Ctoss.Models;
-
-public class Filter
-{
- public string FilterType { get; set; } = null!;
- public Operator Operator { get; set; }
- public FilterCondition? Condition1 { get; set; }
- public FilterCondition? Condition2 { get; set; }
- public List? Conditions { get; set; }
-}
diff --git a/Ctoss/Models/V2/AgGridFilter.cs b/Ctoss/Models/V2/AgGridFilter.cs
new file mode 100644
index 0000000..764f799
--- /dev/null
+++ b/Ctoss/Models/V2/AgGridFilter.cs
@@ -0,0 +1,6 @@
+namespace Ctoss.Models.V2;
+
+public record AgGridFilter
+{
+ public Dictionary Filters { get; init; } = null!;
+}
\ No newline at end of file
diff --git a/Ctoss/Models/V2/DateCondition.cs b/Ctoss/Models/V2/DateCondition.cs
new file mode 100644
index 0000000..be095c3
--- /dev/null
+++ b/Ctoss/Models/V2/DateCondition.cs
@@ -0,0 +1,10 @@
+using Ctoss.Models.Enums;
+
+namespace Ctoss.Models.V2;
+
+public record DateCondition : FilterConditionBase
+{
+ public DateFilterOptions Type { get; init; }
+ public string? DateFrom { get; init; }
+ public string? DateTo { get; init; }
+}
\ No newline at end of file
diff --git a/Ctoss/Models/V2/FilterConditionBase.cs b/Ctoss/Models/V2/FilterConditionBase.cs
new file mode 100644
index 0000000..0bd5cdb
--- /dev/null
+++ b/Ctoss/Models/V2/FilterConditionBase.cs
@@ -0,0 +1,9 @@
+using System.Text.Json.Serialization;
+
+namespace Ctoss.Models.V2;
+
+[JsonConverter(typeof(FilterConverter))]
+public abstract record FilterConditionBase
+{
+ public string FilterType { get; init; } = null!;
+}
\ No newline at end of file
diff --git a/Ctoss/Models/V2/FilterModel.cs b/Ctoss/Models/V2/FilterModel.cs
new file mode 100644
index 0000000..2ab0c2c
--- /dev/null
+++ b/Ctoss/Models/V2/FilterModel.cs
@@ -0,0 +1,22 @@
+using System.Text.Json.Serialization;
+using Ctoss.Json;
+using Ctoss.Models.Enums;
+
+namespace Ctoss.Models.V2;
+
+public record FilterModel
+{
+ public string FilterType { get; init; } = null!;
+ public string Type { get; init; } = null!;
+ public Operator? Operator { get; init; }
+ public List? Conditions { get; init; }
+
+ // This is done to support plain filters. Most of these properties will be empty
+ [JsonConverter(typeof(NumberToStringConverter))]
+ public string? Filter { get; set; }
+ [JsonConverter(typeof(NumberToStringConverter))]
+ public string? FilterTo { get; set; }
+ public string? DateFrom { get; set; }
+ public string? DateTo { get; set; }
+ public List Values { get; init; } = null!;
+}
\ No newline at end of file
diff --git a/Ctoss/Models/V2/MultiCondition.cs b/Ctoss/Models/V2/MultiCondition.cs
new file mode 100644
index 0000000..a11bf8c
--- /dev/null
+++ b/Ctoss/Models/V2/MultiCondition.cs
@@ -0,0 +1,6 @@
+namespace Ctoss.Models.V2;
+
+public record MultiCondition : FilterConditionBase
+{
+ public List FilterModels { get; init; } = null!;
+}
\ No newline at end of file
diff --git a/Ctoss/Models/V2/NumberCondition.cs b/Ctoss/Models/V2/NumberCondition.cs
new file mode 100644
index 0000000..e7262da
--- /dev/null
+++ b/Ctoss/Models/V2/NumberCondition.cs
@@ -0,0 +1,10 @@
+using Ctoss.Models.Enums;
+
+namespace Ctoss.Models.V2;
+
+public record NumberCondition : FilterConditionBase
+{
+ public NumberFilterOptions Type { get; init; }
+ public string? Filter { get; init; }
+ public string? FilterTo { get; init; }
+}
\ No newline at end of file
diff --git a/Ctoss/Models/V2/SetCondition.cs b/Ctoss/Models/V2/SetCondition.cs
new file mode 100644
index 0000000..e56101e
--- /dev/null
+++ b/Ctoss/Models/V2/SetCondition.cs
@@ -0,0 +1,6 @@
+namespace Ctoss.Models.V2;
+
+public record SetCondition : FilterConditionBase
+{
+ public List Values { get; init; } = null!;
+}
\ No newline at end of file
diff --git a/Ctoss/Models/V2/TextCondition.cs b/Ctoss/Models/V2/TextCondition.cs
new file mode 100644
index 0000000..634bb71
--- /dev/null
+++ b/Ctoss/Models/V2/TextCondition.cs
@@ -0,0 +1,9 @@
+using Ctoss.Models.Enums;
+
+namespace Ctoss.Models.V2;
+
+public record TextCondition : FilterConditionBase
+{
+ public TextFilterOptions Type { get; init; }
+ public string Filter { get; init; } = null!;
+}
\ No newline at end of file