| | | 1 | | using System.Linq.Expressions; |
| | | 2 | | using OzonDomains.Models; |
| | | 3 | | |
| | | 4 | | namespace OzonOrdersWeb.WebServices.Orders.Grid; |
| | | 5 | | |
| | | 6 | | /// <summary> |
| | | 7 | | /// Группировка строк грида (AG Grid Community не умеет row grouping): сервер упорядочивает выборку по ключу |
| | | 8 | | /// группы, затем по дате принятия, и помечает первую строку каждой группы в блоке — клиент рисует полосы. |
| | | 9 | | /// Ключ группы — то же поле, что у справочного фильтра (см. <see cref="OrdersGridFacetsService"/>). |
| | | 10 | | /// </summary> |
| | | 11 | | public static class OrdersGridGrouping |
| | | 12 | | { |
| | | 13 | | public const string Shipment = "shipment"; |
| | | 14 | | |
| | 1 | 15 | | private static readonly HashSet<string> Supported = new(StringComparer.OrdinalIgnoreCase) |
| | 1 | 16 | | { |
| | 1 | 17 | | Shipment, "ozonClient", "clientStatus", "appStatus", "shipmentWarehouse", "deliveryProvider", "deliveryName", |
| | 1 | 18 | | "supplier", "manufacturer", "processingDate", "shippingDate", "deliveryCity", "article", "productName", "product |
| | 1 | 19 | | }; |
| | | 20 | | |
| | 6 | 21 | | public static bool Supports(string? groupBy) => !string.IsNullOrWhiteSpace(groupBy) && Supported.Contains(groupBy); |
| | | 22 | | |
| | 29 | 23 | | public static bool IsShipment(string? groupBy) => string.Equals(groupBy, Shipment, StringComparison.OrdinalIgnoreCas |
| | | 24 | | |
| | | 25 | | /// <summary>Порядок по ключу группы; внутри группы — сортировка пользователя (см. <see cref="OrdersGridSorting"/>), |
| | | 26 | | public static IOrderedQueryable<Order> ApplyOrder(IQueryable<Order> query, string groupBy) |
| | | 27 | | { |
| | 0 | 28 | | IOrderedQueryable<Order> ordered = groupBy.ToLowerInvariant() switch |
| | 0 | 29 | | { |
| | 0 | 30 | | "shipment" => query.OrderByDescending(o => o.ShipmentId), |
| | 0 | 31 | | "ozonclient" => ByName(query, o => o.OzonClient != null ? o.OzonClient.Name : null), |
| | 0 | 32 | | "clientstatus" => ByName(query, o => o.ClientStatus != null ? o.ClientStatus.Name : null), |
| | 0 | 33 | | "appstatus" => ByName(query, o => o.AppStatus != null ? o.AppStatus.Name : null), |
| | 0 | 34 | | "shipmentwarehouse" => ByName(query, o => o.ShipmentWarehouse != null ? o.ShipmentWarehouse.Name : null), |
| | 0 | 35 | | "deliveryprovider" => ByName(query, o => o.Delivery != null && o.Delivery.Provider != null ? o.Delivery.Prov |
| | 0 | 36 | | "deliveryname" => ByName(query, o => o.Delivery != null ? o.Delivery.Name : null), |
| | 0 | 37 | | "supplier" => ByName(query, o => o.Supplier != null ? o.Supplier.Name : null), |
| | 0 | 38 | | "manufacturer" => ByName(query, o => o.Manufacturer != null ? o.Manufacturer.Name : null), |
| | 0 | 39 | | "deliverycity" => ByName(query, o => o.DeliveryCity), |
| | 0 | 40 | | "article" => ByName(query, o => o.Article), |
| | 0 | 41 | | "productname" => ByName(query, o => o.ProductName), |
| | 0 | 42 | | "productkey" => ByName(query, o => o.ProductKey), |
| | 0 | 43 | | "processingdate" => query.OrderByDescending(o => o.ProcessingDate!.Value.Date), |
| | 0 | 44 | | "shippingdate" => query.OrderByDescending(o => o.ShippingDate!.Value.Date), |
| | 0 | 45 | | _ => throw new ArgumentOutOfRangeException(nameof(groupBy), groupBy, "Неподдерживаемая группировка.") |
| | 0 | 46 | | }; |
| | | 47 | | |
| | 0 | 48 | | return ordered; |
| | | 49 | | } |
| | | 50 | | |
| | | 51 | | /// <summary>По имени А→Я, пустые значения — в конец (MySQL иначе ставит NULL первым).</summary> |
| | | 52 | | private static IOrderedQueryable<Order> ByName(IQueryable<Order> query, Expression<Func<Order, string?>> key) |
| | | 53 | | { |
| | 0 | 54 | | var isNull = Expression.Lambda<Func<Order, bool>>( |
| | 0 | 55 | | Expression.Equal(key.Body, Expression.Constant(null, typeof(string))), key.Parameters); |
| | 0 | 56 | | return query.OrderBy(isNull).ThenBy(key); |
| | | 57 | | } |
| | | 58 | | |
| | | 59 | | /// <summary>Ключ группы для загруженного заказа — для пометки границ групп в блоке.</summary> |
| | 0 | 60 | | public static string? KeyOf(Order o, string groupBy) => groupBy.ToLowerInvariant() switch |
| | 0 | 61 | | { |
| | 0 | 62 | | "shipment" => o.ShipmentId?.ToString(), |
| | 0 | 63 | | "ozonclient" => o.OzonClient?.Name, |
| | 0 | 64 | | "clientstatus" => o.ClientStatus?.Name, |
| | 0 | 65 | | "appstatus" => o.AppStatus?.Name, |
| | 0 | 66 | | "shipmentwarehouse" => o.ShipmentWarehouse?.Name, |
| | 0 | 67 | | "deliveryprovider" => o.Delivery?.Provider?.Name, |
| | 0 | 68 | | "deliveryname" => o.Delivery?.Name, |
| | 0 | 69 | | "supplier" => o.Supplier?.Name, |
| | 0 | 70 | | "manufacturer" => o.Manufacturer?.Name, |
| | 0 | 71 | | "deliverycity" => o.DeliveryCity, |
| | 0 | 72 | | "article" => o.Article, |
| | 0 | 73 | | "productname" => o.ProductName, |
| | 0 | 74 | | "productkey" => o.ProductKey, |
| | 0 | 75 | | "processingdate" => o.ProcessingDate?.ToString("dd.MM.yyyy"), |
| | 0 | 76 | | "shippingdate" => o.ShippingDate?.ToString("dd.MM.yyyy"), |
| | 0 | 77 | | _ => null |
| | 0 | 78 | | }; |
| | | 79 | | } |