< Summary

Information
Class: OzonOrdersWeb.WebServices.Orders.Grid.OrdersGridSorting
Assembly: OzonOrdersWeb
File(s): /home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/WebServices/Orders/Grid/OrdersGridSorting.cs
Line coverage
95%
Covered lines: 46
Uncovered lines: 2
Coverable lines: 48
Total lines: 83
Line coverage: 95.8%
Branch coverage
71%
Covered branches: 10
Total branches: 14
Branch coverage: 71.4%
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%
Key(...)100%11100%
Supports(...)100%11100%
Apply(...)62.5%9875%
ApplyOne(...)83.33%66100%

File(s)

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

#LineLine coverage
 1using System.Linq.Expressions;
 2using OzonDomains.Models;
 3
 4namespace OzonOrdersWeb.WebServices.Orders.Grid;
 5
 6/// <summary>
 7/// Сортировка по нескольким столбцам (Shift+клик в гриде) и внутри группы: общий конвейер умеет один
 8/// <c>OrderSortState</c>, поэтому цепочка OrderBy/ThenBy строится здесь. Ключи повторяют <c>OrderSortManager</c>.
 9/// </summary>
 10public static class OrdersGridSorting
 11{
 1512    public sealed record SortItem(string ColId, bool Descending);
 13
 114    private static readonly Dictionary<string, LambdaExpression> Keys = new(StringComparer.OrdinalIgnoreCase)
 115    {
 116        ["shipmentNumber"] = Key(o => o.ShipmentNumber),
 117        ["scanit"] = Key(o => o.Scanit),
 118        ["deliveryProvider"] = Key(o => o.Delivery != null && o.Delivery.Provider != null ? o.Delivery.Provider.Name : n
 119        ["ozonClient"] = Key(o => o.OzonClient != null ? o.OzonClient.Name : null),
 120        ["deliveryCity"] = Key(o => o.DeliveryCity),
 121        ["processingDate"] = Key(o => o.ProcessingDate),
 122        ["shippingDate"] = Key(o => o.ShippingDate),
 123        ["deliveryPeriod"] = Key(o => o.DeliveryPeriod),
 124        ["timeLeftDays"] = Key(o => o.ShippingDate),
 125        ["article"] = Key(o => o.ProductKey),
 126        ["manufacturer"] = Key(o => o.EtProducer != null ? o.EtProducer.Name : null),
 127        ["productName"] = Key(o => o.ProductName),
 128        ["clientStatus"] = Key(o => o.ClientStatus != null ? o.ClientStatus.Name : null),
 129        ["appStatus"] = Key(o => o.AppStatus != null ? o.AppStatus.Name : null),
 130        ["shipmentWarehouse"] = Key(o => o.ShipmentWarehouse != null ? o.ShipmentWarehouse.Name : null),
 131        ["lastStatusChangeDate"] = Key(o => o.LastStatusChangeDate),
 132        ["supplier"] = Key(o => o.Supplier != null ? o.Supplier.Name : null),
 133        ["orderNumberToSupplier"] = Key(o => o.OrderNumberToSupplier),
 134        ["category"] = Key(o => o.NewCategory),
 135        ["volumetricWeight"] = Key(o => o.ProductInfo != null ? o.ProductInfo.VolumetricWeight : null),
 136        ["sitePrice"] = Key(o => o.ProductInfo != null ? o.ProductInfo.CurrentPriceWithDiscount : null),
 137        ["quantity"] = Key(o => o.Quantity),
 138        ["price"] = Key(o => o.Price),
 139        ["shipmentAmount"] = Key(o => o.ShipmentAmount),
 140        ["purchasePrice"] = Key(o => o.PurchasePrice),
 141        ["costPrice"] = Key(o => o.CostPrice),
 142        ["ozonCommission"] = Key(o => o.MinOzonCommission),
 143        ["ozonCommissionMax"] = Key(o => o.MaxOzonCommission),
 144        ["profit"] = Key(o => o.MinProfit),
 145        ["discount"] = Key(o => o.MinDiscount)
 146    };
 47
 3048    private static LambdaExpression Key<TKey>(Expression<Func<Order, TKey>> key) => key;
 49
 350    public static bool Supports(string colId) => Keys.ContainsKey(colId);
 51
 52    /// <summary>
 53    /// Добавляет сортировки к запросу: если он уже упорядочен (<paramref name="alreadyOrdered"/>) — как ThenBy,
 54    /// иначе первая становится OrderBy. Неизвестные столбцы пропускаются. Проверять тип на
 55    /// <see cref="IOrderedQueryable{T}"/> нельзя: EF Core и EnumerableQuery реализуют его всегда.
 56    /// </summary>
 57    public static IQueryable<Order> Apply(IQueryable<Order> query, IReadOnlyList<SortItem> sorts, bool alreadyOrdered, o
 58        Func<string, LambdaExpression?>? resolveExtra = null)
 59    {
 360        ordered = alreadyOrdered;
 1261        foreach (var sort in sorts)
 62        {
 363            if (!Keys.TryGetValue(sort.ColId, out var key))
 64            {
 65                // Вычисляемые столбцы: ключ — переведённая формула пользователя.
 066                key = resolveExtra?.Invoke(sort.ColId);
 067                if (key is null) continue;
 68            }
 369            query = ApplyOne(query, key, sort.Descending, ordered);
 370            ordered = true;
 71        }
 72
 373        return query;
 74    }
 75
 76    private static IOrderedQueryable<Order> ApplyOne(IQueryable<Order> query, LambdaExpression key, bool descending, boo
 77    {
 378        var name = then ? (descending ? nameof(Queryable.ThenByDescending) : nameof(Queryable.ThenBy))
 379                        : (descending ? nameof(Queryable.OrderByDescending) : nameof(Queryable.OrderBy));
 380        var call = Expression.Call(typeof(Queryable), name, [typeof(Order), key.ReturnType], query.Expression, Expressio
 381        return (IOrderedQueryable<Order>)query.Provider.CreateQuery<Order>(call);
 82    }
 83}