< Summary

Information
Class: Services.FeedPriceServices.FeedOrderRowPicker
Assembly: Services
File(s): /home/runner/work/Studio2Prod/Studio2Prod/AppRepository/FeedPriceServices/FeedOrderRowPicker.cs
Line coverage
100%
Covered lines: 29
Uncovered lines: 0
Coverable lines: 29
Total lines: 100
Line coverage: 100%
Branch coverage
96%
Covered branches: 29
Total branches: 30
Branch coverage: 96.6%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
Pick(...)96.15%2626100%
Result()100%11100%
HasValues(...)100%44100%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/AppRepository/FeedPriceServices/FeedOrderRowPicker.cs

#LineLine coverage
 1using System.Text.Json.Serialization;
 2using OzonDomains.Models;
 3
 4namespace Services.FeedPriceServices;
 5
 6/// <summary>Результат выбора строки фида для заказа.</summary>
 7[JsonConverter(typeof(JsonStringEnumConverter))]
 8public enum FeedOrderState
 9{
 10    /// <summary>Строка найдена, цена есть.</summary>
 11    Ok,
 12
 13    /// <summary>У заказа нет ключа артикула.</summary>
 14    NoKey,
 15
 16    /// <summary>Клиент заказа не сопоставлен с кабинетом фида.</summary>
 17    NoCabinet,
 18
 19    /// <summary>В кабинете клиента нет такого артикула.</summary>
 20    NotInFeed,
 21
 22    /// <summary>Артикул в фиде есть, но ни цены, ни закупки, ни старой цены.</summary>
 23    NoPrice,
 24
 25    /// <summary>Фид-сервис недоступен (используется расшифровкой цены).</summary>
 26    Error
 27}
 28
 29/// <summary>Строка фида, соответствующая клиенту и складу заказа.</summary>
 30public sealed class FeedOrderPick
 31{
 32    public FeedOrderState State { get; init; }
 33    public FeedCurrentRow? Row { get; init; }
 34
 35    /// <summary>Кабинет клиента заказа (ключ фида); null, если клиент не сопоставлен.</summary>
 36    public string? Cabinet { get; init; }
 37
 38    public string? CabinetName => Cabinet is null ? null : FeedCabinets.DisplayName(Cabinet);
 39    public string? Client { get; init; }
 40
 41    /// <summary>Склад отгрузки заказа.</summary>
 42    public string? OrderWarehouse { get; init; }
 43
 44    /// <summary>Склада заказа нет среди складов фида: показана строка склада цены кабинета.</summary>
 45    public bool WarehouseFallback { get; init; }
 46}
 47
 48/// <summary>Выбирает из снимка фида строку по кабинету клиента и складу заказа.</summary>
 49public static class FeedOrderRowPicker
 50{
 51    public static FeedOrderPick Pick(
 52        IReadOnlyCollection<FeedCurrentRow> current,
 53        IReadOnlyCollection<string> articleKeys,
 54        string? clientName,
 55        string? warehouseName)
 56    {
 2157        var cabinet = FeedCabinets.ForClientName(clientName);
 2158        FeedOrderPick Result(FeedOrderState state, FeedCurrentRow? row = null, bool fallback = false) => new()
 2159        {
 2160            State = state,
 2161            Row = row,
 2162            Cabinet = cabinet,
 2163            Client = clientName,
 2164            OrderWarehouse = warehouseName,
 2165            WarehouseFallback = fallback
 2166        };
 67
 2368        if (articleKeys.Count == 0) return Result(FeedOrderState.NoKey);
 2069        if (cabinet is null) return Result(FeedOrderState.NoCabinet);
 70
 71        // Ключей до двух; берём первый, по которому в кабинете есть данные.
 1872        List<FeedCurrentRow> rows = [];
 6273        foreach (var key in articleKeys)
 74        {
 2175            rows = current
 2976                .Where(x => string.Equals(x.Cabinet, cabinet, StringComparison.OrdinalIgnoreCase)
 2977                            && string.Equals(x.Article, key, StringComparison.OrdinalIgnoreCase))
 2178                .ToList();
 3779            if (rows.Count > 0) break;
 80        }
 81
 2082        if (rows.Count == 0) return Result(FeedOrderState.NotInFeed);
 83
 1684        var wanted = WarehouseNameNormalizer.Normalize(warehouseName);
 1685        var exact = wanted is null
 1686            ? null
 3487            : rows.FirstOrDefault(x => string.Equals(WarehouseNameNormalizer.Normalize(x.Warehouse), wanted, StringCompa
 88
 89        // Цена кабинета общая для складов, но у склада без цены строка пустая: тогда берём склад цены.
 2890        if (exact is not null && HasValues(exact)) return Result(FeedOrderState.Ok, exact);
 91
 1292        var fallback = rows.FirstOrDefault(x => x.IsPriceWarehouse && HasValues(x)) ?? rows.FirstOrDefault(HasValues);
 793        if (fallback is not null) return Result(FeedOrderState.Ok, fallback, fallback: true);
 94
 195        return Result(FeedOrderState.NoPrice, exact ?? rows[0], fallback: exact is null);
 96    }
 97
 98    private static bool HasValues(FeedCurrentRow row) =>
 2099        row.PurchasePrice is not null || row.Price is not null || row.OldPrice is not null;
 100}