< Summary

Information
Class: OzonOrdersWeb.WebServices.Orders.Grid.OrdersGridComputedFilters
Assembly: OzonOrdersWeb
File(s): /home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/WebServices/Orders/Grid/OrdersGridComputedFilters.cs
Line coverage
71%
Covered lines: 49
Uncovered lines: 20
Coverable lines: 69
Total lines: 112
Line coverage: 71%
Branch coverage
35%
Covered branches: 34
Total branches: 97
Branch coverage: 35%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_ColId()100%11100%
.cctor()100%11100%
Apply(...)100%44100%
Predicate(...)32.25%4489365.51%
Call()100%11100%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/WebServices/Orders/Grid/OrdersGridComputedFilters.cs

#LineLine coverage
 1using System.Linq.Expressions;
 2using OzonDomains.Models;
 3
 4namespace OzonOrdersWeb.WebServices.Orders.Grid;
 5
 6/// <summary>
 7/// Фильтр AG Grid по вычисляемому столбцу: выражение формулы (<see cref="OrdersGridFormulaTranslator"/>) плюс
 8/// операция и значение из filterModel → <c>Where</c>. Семантика операций та же, что в <see cref="OrdersGridExtraFilters
 9/// </summary>
 10public static class OrdersGridComputedFilters
 11{
 12    /// <summary>Фильтр по колонке: тип операции и значения как пришли из грида (уже разобранные маппером).</summary>
 2413    public sealed record ComputedFilter(string ColId, string Type, string? Text, decimal? Number, decimal? NumberTo, Dat
 14
 115    private static readonly Type Dec = typeof(decimal?);
 116    private static readonly Type Str = typeof(string);
 117    private static readonly Type Dt = typeof(DateTime?);
 118    private static readonly Type Bl = typeof(bool?);
 19
 20    public static IQueryable<Order> Apply(IQueryable<Order> query, IEnumerable<(OrdersGridFormulaTranslator.Translation 
 21    {
 2422        foreach (var (t, f) in filters)
 23        {
 624            var body = Predicate(t.Lambda.Body, f);
 625            if (body is null) continue;
 626            query = query.Where(Expression.Lambda<Func<Order, bool>>(body, t.Lambda.Parameters));
 27        }
 28
 629        return query;
 30    }
 31
 32    /// <summary>Тело предиката (bool) над телом выражения формулы; null — операция не поддерживается.</summary>
 33    public static Expression? Predicate(Expression value, ComputedFilter f)
 34    {
 635        var type = f.Type.ToLowerInvariant();
 636        var nullConst = Expression.Constant(null, value.Type);
 637        if (type == "blank")
 38        {
 139            return value.Type == Str ? Expression.OrElse(Expression.Equal(value, nullConst), Expression.Equal(value, Exp
 40        }
 541        if (type == "notblank")
 42        {
 043            return value.Type == Str ? Expression.AndAlso(Expression.NotEqual(value, nullConst), Expression.NotEqual(val
 44        }
 45
 546        if (value.Type == Dec)
 47        {
 248            if (f.Number is null) return null;
 249            var n = Expression.Constant(f.Number, Dec);
 250            var notNull = Expression.NotEqual(value, nullConst);
 251            return type switch
 252            {
 053                "equals" => Expression.Equal(value, n),
 054                "notequal" => Expression.OrElse(Expression.Equal(value, nullConst), Expression.NotEqual(value, n)),
 155                "greaterthan" => Expression.AndAlso(notNull, Expression.GreaterThan(value, n)),
 056                "greaterthanorequal" => Expression.AndAlso(notNull, Expression.GreaterThanOrEqual(value, n)),
 057                "lessthan" => Expression.AndAlso(notNull, Expression.LessThan(value, n)),
 058                "lessthanorequal" => Expression.AndAlso(notNull, Expression.LessThanOrEqual(value, n)),
 159                "inrange" => f.NumberTo is null ? null
 160                    : Expression.AndAlso(notNull, Expression.AndAlso(Expression.GreaterThanOrEqual(value, n), Expression
 061                _ => null
 262            };
 63        }
 64
 365        if (value.Type == Str)
 66        {
 167            var text = f.Text ?? (f.Values.Count > 0 ? f.Values[0] : null);
 168            if (string.IsNullOrEmpty(text)) return null;
 169            var s = Expression.Constant(text, Str);
 170            var notNull = Expression.NotEqual(value, nullConst);
 171            Expression Call(string method) => Expression.AndAlso(notNull, Expression.Call(value, typeof(string).GetMetho
 172            return type switch
 173            {
 174                "contains" => Call(nameof(string.Contains)),
 075                "notcontains" => Expression.OrElse(Expression.Equal(value, nullConst), Expression.Not(Expression.Call(va
 076                "equals" => Expression.Equal(value, s),
 077                "notequal" => Expression.OrElse(Expression.Equal(value, nullConst), Expression.NotEqual(value, s)),
 078                "startswith" => Call(nameof(string.StartsWith)),
 079                "endswith" => Call(nameof(string.EndsWith)),
 080                _ => null
 181            };
 82        }
 83
 284        if (value.Type == Dt)
 85        {
 186            if (f.DateFrom is null) return null;
 187            var from = Expression.Constant((DateTime?)f.DateFrom.Value.Date, Dt);
 188            var nextDay = Expression.Constant((DateTime?)f.DateFrom.Value.Date.AddDays(1), Dt);
 189            var notNull = Expression.NotEqual(value, nullConst);
 190            return type switch
 191            {
 092                "equals" => Expression.AndAlso(notNull, Expression.AndAlso(Expression.GreaterThanOrEqual(value, from), E
 093                "notequal" => Expression.OrElse(Expression.Equal(value, nullConst), Expression.OrElse(Expression.LessTha
 194                "greaterthan" => Expression.AndAlso(notNull, Expression.GreaterThanOrEqual(value, nextDay)),
 095                "lessthan" => Expression.AndAlso(notNull, Expression.LessThan(value, from)),
 096                "inrange" => f.DateTo is null ? null
 097                    : Expression.AndAlso(notNull, Expression.AndAlso(Expression.GreaterThanOrEqual(value, from), Express
 098                _ => null
 199            };
 100        }
 101
 1102        if (value.Type == Bl)
 103        {
 1104            var raw = f.Values.Count > 0 ? f.Values[0] : f.Text;
 1105            if (raw is null) return null;
 1106            var want = raw.Equals("true", StringComparison.OrdinalIgnoreCase) || raw == "1" || raw.Equals("да", StringCo
 1107            return want ? Expression.Equal(value, Expression.Constant((bool?)true, Bl)) : Expression.NotEqual(value, Exp
 108        }
 109
 0110        return null;
 111    }
 112}