< Summary

Information
Class: OzonOrdersWeb.WebServices.Transactions.SupplierQueueOrderIds
Assembly: OzonOrdersWeb
File(s): /home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/WebServices/Transactions/SupplierVerificationDto.cs
Line coverage
90%
Covered lines: 27
Uncovered lines: 3
Coverable lines: 30
Total lines: 128
Line coverage: 90%
Branch coverage
90%
Covered branches: 29
Total branches: 32
Branch coverage: 90.6%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%11100%
ExtractProviderByOrder(...)100%66100%
ProviderKeyFromQueuePrefix(...)66.66%6683.33%
Extract(...)95%212087.5%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/WebServices/Transactions/SupplierVerificationDto.cs

#LineLine coverage
 1using System.Net;
 2using System.Text.Json;
 3using OzonOrdersWeb.WebServices.OrderHistory;
 4using Services.SupplierStatusServices;
 5
 6namespace OzonOrdersWeb.WebServices.Transactions;
 7
 8/// <summary>Строка сводки проверки заказа у поставщика для клиента (диалог на /Studio2/OrdersGrid).</summary>
 9public sealed record SupplierVerificationRowDto(
 10    int OrderId,
 11    string? ShipmentNumber,
 12    string? Article,
 13    string? ProductName,
 14    string ProviderKey,
 15    string ProviderName,
 16    string? LogoUrl,
 17    string StageName,
 18    string Status,
 19    string StatusTitle,
 20    string Tone,
 21    string Summary,
 22    string? SupplierOrderNumber,
 23    string? SupplierStatusName,
 24    IReadOnlyList<string> Checks);
 25
 26/// <summary>Сводка проверки поставщиков после проведения: считается на сервере, клиент только рисует.</summary>
 27public sealed record SupplierVerificationDto(
 28    bool HasProblems,
 29    int Confirmed,
 30    int Problems,
 31    int NotVerifiable,
 32    string ShortText,
 33    IReadOnlyList<SupplierVerificationRowDto> Rows)
 34{
 35    public static SupplierVerificationDto? From(SupplierVerificationSummary? summary)
 36    {
 37        if (summary is null || summary.IsEmpty) return null;
 38        var rows = summary.Rows.Select(row => new SupplierVerificationRowDto(
 39            row.OrderId, row.ShipmentNumber, row.Article, row.ProductName, row.ProviderKey, row.ProviderName,
 40            OrderHistoryGridRows.SupplierProviderLogoUrl(row.ProviderKey),
 41            OrderHistoryGridRows.SupplierStageName(row.Stage), row.Status,
 42            SupplierVerificationStatus.Title(row.Status), Tone(row.Status), row.Summary,
 43            row.SupplierOrderNumber, row.SupplierStatusName, row.Checks)).ToList();
 44        return new SupplierVerificationDto(summary.HasProblems, summary.ConfirmedCount, summary.ProblemCount,
 45            summary.NotVerifiableCount, summary.ToShortText(), rows);
 46    }
 47
 48    /// <summary>HTML-блок для карточки результата проведения (toast классического потока и SummaryHtml нового).</summar
 49    public static string? ToHtmlBlock(SupplierVerificationSummary? summary)
 50    {
 51        if (summary is null || summary.IsEmpty) return null;
 52        var cls = summary.HasProblems ? "alert-danger" : "alert-success";
 53        var icon = summary.HasProblems ? "fa-triangle-exclamation" : "fa-circle-check";
 54        var problemRows = summary.Rows.Where(x => x.IsProblem).Take(10)
 55            .Select(x => $"<li><b>{WebUtility.HtmlEncode(x.ProviderName)}</b> · {WebUtility.HtmlEncode(x.ShipmentNumber 
 56        var list = summary.HasProblems ? $"<ul class='mb-0 small'>{string.Join(string.Empty, problemRows)}</ul>" : strin
 57        return $"<div class='alert {cls} mb-0'><div class='fw-semibold'><i class='fas {icon} me-1'></i>{WebUtility.HtmlE
 58    }
 59
 60    public static string Tone(string status) => status switch
 61    {
 62        SupplierVerificationStatus.Confirmed => "success",
 63        SupplierVerificationStatus.NotVerifiable => "muted",
 64        SupplierVerificationStatus.ApiError => "warning",
 65        _ => "danger"
 66    };
 67}
 68
 69/// <summary>Достаёт Id заказов Studio2 из клиентских очередей поставщиков (JSON-массивы с полем OrderId).</summary>
 70public static class SupplierQueueOrderIds
 71{
 172    private static readonly string[] QueueSuffixes = { "BasketQueueJson", "CheckoutQueueJson" };
 73
 74    /// <summary>Заказ → поставщик по ключам очередей (<c>NikeiCheckoutQueueJson</c> → <c>Nikei</c>), для заказов без за
 75    public static Dictionary<int, string> ExtractProviderByOrder(IReadOnlyDictionary<string, string> queues)
 76    {
 177        var result = new Dictionary<int, string>();
 1278        foreach (var (key, json) in queues)
 79        {
 1380            var suffix = QueueSuffixes.FirstOrDefault(x => key.EndsWith(x, StringComparison.OrdinalIgnoreCase));
 581            if (suffix is null) continue;
 482            var providerKey = ProviderKeyFromQueuePrefix(key[..^suffix.Length]);
 1783            foreach (var id in Extract(new[] { json })) result.TryAdd(id, providerKey);
 84        }
 85
 186        return result;
 87    }
 88
 4089    public static string ProviderKeyFromQueuePrefix(string prefix) => prefix.ToLowerInvariant() switch
 4090    {
 291        "mikado" => "MikadoMskHod20",
 092        "moskvorechie" => "MoskvorechieIstra",
 3893        _ => prefix.Length == 0 ? prefix : char.ToUpperInvariant(prefix[0]) + prefix[1..]
 4094    };
 95
 96    public static HashSet<int> Extract(IEnumerable<string?> queueJsons)
 97    {
 498        var ids = new HashSet<int>();
 1699        foreach (var json in queueJsons)
 100        {
 4101            if (string.IsNullOrWhiteSpace(json)) continue;
 102            try
 103            {
 4104                using var document = JsonDocument.Parse(json);
 4105                if (document.RootElement.ValueKind != JsonValueKind.Array) continue;
 14106                foreach (var item in document.RootElement.EnumerateArray())
 107                {
 3108                    if (item.ValueKind != JsonValueKind.Object) continue;
 12109                    foreach (var property in item.EnumerateObject())
 110                    {
 3111                        if (string.Equals(property.Name, "OrderId", StringComparison.OrdinalIgnoreCase)
 3112                            && property.Value.ValueKind == JsonValueKind.Number
 3113                            && property.Value.TryGetInt32(out var id) && id > 0)
 114                        {
 3115                            ids.Add(id);
 116                        }
 117                    }
 118                }
 4119            }
 0120            catch (JsonException)
 121            {
 122                // Битая очередь уже отклонена при разборе в процессоре корзин; для проверки она просто пуста.
 0123            }
 124        }
 125
 4126        return ids;
 127    }
 128}