< Summary

Information
Class: Services.AiAssistant.OrderHistoryFormatter
Assembly: Services
File(s): /home/runner/work/Studio2Prod/Studio2Prod/AppRepository/AiAssistant/OrderHistoryFormatter.cs
Line coverage
100%
Covered lines: 33
Uncovered lines: 0
Coverable lines: 33
Total lines: 63
Line coverage: 100%
Branch coverage
100%
Covered branches: 16
Total branches: 16
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
FormatFieldGlossary()100%11100%
FormatHistoryList(...)100%1010100%
FormatUserActivitySummary(...)100%66100%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/AppRepository/AiAssistant/OrderHistoryFormatter.cs

#LineLine coverage
 1using OzonDomains;
 2using OzonDomains.Models;
 3
 4namespace Services.AiAssistant;
 5
 6/// <summary>
 7/// Форматирование записей orders_history для LLM.
 8/// </summary>
 9public static class OrderHistoryFormatter
 10{
 11    public static string FormatFieldGlossary() =>
 1712        """
 1713        Таблица orders_history (журнал изменений заказа):
 1714        • OrderId — ID заказа
 1715        • ColumnName / ColumnDisplayName — изменённое поле (русское имя в ColumnDisplayName)
 1716        • OldValue / NewValue — было → стало
 1717        • ChangedAt — дата и время изменения (UTC в БД)
 1718        • ChangedBy — логин/имя пользователя, внёсшего изменение
 1719        Типичные поля: AppStatus (статус в отчёте), ClientStatus (статус Ozon), Supplier, ShipmentWarehouse,
 1720        Price, PurchasePrice, Comment, TransactionId (привязка к транзакции).
 1721        """;
 22
 23    public static string FormatHistoryList(
 24        IReadOnlyList<OrderHistory> rows,
 25        IReadOnlyDictionary<int, string?> shipmentByOrderId,
 26        string title)
 27    {
 1528        if (rows.Count == 0)
 129            return $"{title}: записей не найдено.";
 30
 1431        var lines = rows.Select(h =>
 1432        {
 1633            var field = !string.IsNullOrWhiteSpace(h.ColumnDisplayName)
 1634                ? h.ColumnDisplayName
 1635                : h.ColumnName ?? "поле";
 1636            shipmentByOrderId.TryGetValue(h.OrderId, out var shipment);
 1637            var shipPart = !string.IsNullOrWhiteSpace(shipment) ? $" {shipment}" : "";
 1638            return $"  {h.ChangedAt:dd.MM.yyyy HH:mm} | {h.ChangedBy ?? "—"} | " +
 1639                   $"заказ #{h.OrderId}{shipPart} | {field}: «{h.FormattedOldValue}» → «{h.FormattedNewValue}»";
 1440        });
 41
 1442        return $"{title} ({rows.Count} записей):\n" + string.Join("\n", lines);
 43    }
 44
 45    public static string FormatUserActivitySummary(
 46        IEnumerable<(string User, int Count, IReadOnlyList<string> Samples)> groups,
 47        string title)
 48    {
 749        var list = groups.ToList();
 750        if (list.Count == 0)
 151            return $"{title}: действий не найдено.";
 52
 653        var sb = new System.Text.StringBuilder();
 1454        sb.AppendLine($"{title} ({list.Sum(g => g.Count)} изменений, {list.Count} пользователей):");
 3655        foreach (var (user, count, samples) in list.OrderByDescending(g => g.Count))
 56        {
 857            sb.AppendLine($"  • {user}: {count} изменений");
 3458            foreach (var sample in samples.Take(3))
 959                sb.AppendLine($"      {sample}");
 60        }
 661        return sb.ToString().TrimEnd();
 62    }
 63}