< Summary

Information
Class: Services.ApiServices._1CApi.OData.TransferShortageLine
Assembly: Services
File(s): /home/runner/work/Studio2Prod/Studio2Prod/AppRepository/ApiServices/1CApi/OData/OneCTransferShortage.cs
Line coverage
100%
Covered lines: 5
Uncovered lines: 0
Coverable lines: 5
Total lines: 44
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
get_Article()100%11100%
get_Required()100%11100%
get_OnSender()100%11100%
get_Elsewhere()100%11100%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/AppRepository/ApiServices/1CApi/OData/OneCTransferShortage.cs

#LineLine coverage
 1namespace Services.ApiServices._1CApi.OData;
 2
 3/// <summary>Позиция перемещения: сколько нужно и сколько реально лежит на складе-отправителе и на других складах.</summ
 54public sealed record TransferShortageLine(
 35    string Article,
 86    decimal Required,
 87    decimal OnSender,
 108    IReadOnlyList<(string Warehouse, decimal Quantity)> Elsewhere);
 9
 10/// <summary>
 11/// Причина отказа 1С провести перемещение, восстановленная по остаткам. На /Post 1С при нехватке остатка
 12/// отвечает общей фразой «Не удалось провести "…"!», поэтому причину считаем сами по регистру остатков.
 13/// </summary>
 14public static class OneCTransferShortage
 15{
 16    private const int MaxLines = 10;
 17    private const int MaxWarehouses = 5;
 18
 19    /// <summary>Сообщение о нехватке или <c>null</c>, если по остаткам всё в порядке (причина в другом).</summary>
 20    public static string? Build(string senderWarehouse, IReadOnlyList<TransferShortageLine> lines)
 21    {
 22        var lacking = lines.Where(l => l.Required > l.OnSender).ToList();
 23        if (lacking.Count == 0)
 24            return null;
 25
 26        var parts = lacking.Take(MaxLines).Select(l => $"{l.Article} — нужно {Fmt(l.Required)}, есть {Fmt(l.OnSender)} (
 27        var more = lacking.Count > MaxLines ? $"; и ещё {lacking.Count - MaxLines}" : string.Empty;
 28        return $"Не хватает остатка на складе «{senderWarehouse}»: {string.Join("; ", parts)}{more}. " +
 29               "Оприходуйте товар на этом складе или переместите с другого и проведите документ вручную.";
 30    }
 31
 32    private static string Where(TransferShortageLine l)
 33    {
 34        if (l.Elsewhere.Count == 0)
 35            return "нигде нет";
 36
 37        var shown = l.Elsewhere.OrderByDescending(e => e.Quantity).Take(MaxWarehouses)
 38            .Select(e => $"{e.Warehouse}: {Fmt(e.Quantity)}");
 39        var rest = l.Elsewhere.Count > MaxWarehouses ? $", ещё {l.Elsewhere.Count - MaxWarehouses}" : string.Empty;
 40        return $"есть на {string.Join(", ", shown)}{rest}";
 41    }
 42
 43    private static string Fmt(decimal value) => value.ToString("0.###", System.Globalization.CultureInfo.InvariantCultur
 44}