< Summary

Information
Class: Services.SupplierStatusServices.SupplierStatusDirectoryService
Assembly: Services
File(s): /home/runner/work/Studio2Prod/Studio2Prod/AppRepository/SupplierStatusServices/SupplierStatusDirectoryService.cs
Line coverage
100%
Covered lines: 54
Uncovered lines: 0
Coverable lines: 54
Total lines: 118
Line coverage: 100%
Branch coverage
100%
Covered branches: 18
Total branches: 18
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
GetAsync(...)100%44100%
GetProviderKeysAsync(...)100%11100%
GetByIdAsync(...)100%11100%
UpdateAsync()100%66100%
UpdateStatusColorAsync()100%44100%
ResetStatusColorAsync()100%22100%
DeleteAsync()100%22100%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/AppRepository/SupplierStatusServices/SupplierStatusDirectoryService.cs

#LineLine coverage
 1using Microsoft.EntityFrameworkCore;
 2using OzonDomains;
 3using OzonDomains.Models.SupplierStatuses;
 4using OzonRepositories.Context;
 5
 6namespace Services.SupplierStatusServices;
 7
 8public interface ISupplierStatusDirectoryService
 9{
 10    Task<List<SupplierStatus>> GetAsync(string? providerKey, string? statusKind, CancellationToken ct = default);
 11
 12    Task<List<string>> GetProviderKeysAsync(CancellationToken ct = default);
 13
 14    Task<SupplierStatus?> GetByIdAsync(int id, CancellationToken ct = default);
 15
 16    Task UpdateAsync(int id, string name, bool isFinal, int? sortOrder, CancellationToken ct = default);
 17
 18    Task UpdateStatusColorAsync(int id, string colorCode, CancellationToken ct = default);
 19
 20    Task ResetStatusColorAsync(int id, CancellationToken ct = default);
 21
 22    /// <summary>Удаляет статус. Заказы, ссылающиеся на него, теряют только отображение статуса.</summary>
 23    Task<bool> DeleteAsync(int id, CancellationToken ct = default);
 24}
 25
 26/// <summary>Справочник статусов поставщиков: чтение и ручное редактирование администратором.</summary>
 27public sealed class SupplierStatusDirectoryService : ISupplierStatusDirectoryService
 28{
 29    private readonly ApplicationDbContext _db;
 30
 4431    public SupplierStatusDirectoryService(ApplicationDbContext db) => _db = db;
 32
 33    public Task<List<SupplierStatus>> GetAsync(string? providerKey, string? statusKind, CancellationToken ct = default)
 34    {
 535        var query = _db.SupplierStatuses
 536            .Include(x => x.StatusColor)
 537            .Include(x => x.Supplier)
 538            .AsNoTracking()
 539            .AsQueryable();
 40
 541        if (!string.IsNullOrWhiteSpace(providerKey))
 342            query = query.Where(x => x.ProviderKey == providerKey);
 43
 544        if (!string.IsNullOrWhiteSpace(statusKind))
 245            query = query.Where(x => x.StatusKind == statusKind);
 46
 547        return query
 548            .OrderBy(x => x.ProviderKey)
 549            .ThenBy(x => x.StatusKind)
 550            .ThenBy(x => x.SortOrder ?? int.MaxValue)
 551            .ThenBy(x => x.Name)
 552            .ToListAsync(ct);
 53    }
 54
 55    public Task<List<string>> GetProviderKeysAsync(CancellationToken ct = default) =>
 256        _db.SupplierStatuses
 257            .Select(x => x.ProviderKey)
 258            .Distinct()
 259            .OrderBy(x => x)
 260            .ToListAsync(ct);
 61
 62    public Task<SupplierStatus?> GetByIdAsync(int id, CancellationToken ct = default) =>
 263        _db.SupplierStatuses
 264            .Include(x => x.StatusColor)
 265            .Include(x => x.Supplier)
 266            .FirstOrDefaultAsync(x => x.Id == id, ct);
 67
 68    public async Task UpdateAsync(int id, string name, bool isFinal, int? sortOrder, CancellationToken ct = default)
 69    {
 670        var status = await _db.SupplierStatuses.FindAsync([id], ct);
 771        if (status is null) return;
 72
 573        if (!string.IsNullOrWhiteSpace(name))
 274            status.Name = name.Trim().Length > 200 ? name.Trim()[..200] : name.Trim();
 575        status.IsFinal = isFinal;
 576        status.SortOrder = sortOrder;
 577        await _db.SaveChangesAsync(ct);
 678    }
 79
 80    /// <summary>Цвета переиспользуются между всеми справочниками статусов — таблица StatusColors общая.</summary>
 81    public async Task UpdateStatusColorAsync(int id, string colorCode, CancellationToken ct = default)
 82    {
 383        var status = await _db.SupplierStatuses.FindAsync([id], ct);
 484        if (status is null) return;
 85
 286        var color = await _db.StatusColors.FirstOrDefaultAsync(c => c.ColorCode == colorCode, ct);
 287        if (color is null)
 88        {
 189            color = new StatusColor { ColorCode = colorCode };
 190            await _db.StatusColors.AddAsync(color, ct);
 191            await _db.SaveChangesAsync(ct);
 92        }
 93
 294        status.StatusColorId = color.Id;
 295        await _db.SaveChangesAsync(ct);
 396    }
 97
 98    public async Task ResetStatusColorAsync(int id, CancellationToken ct = default)
 99    {
 2100        var status = await _db.SupplierStatuses.FindAsync([id], ct);
 3101        if (status is null) return;
 102
 1103        status.StatusColorId = null;
 1104        await _db.SaveChangesAsync(ct);
 2105    }
 106
 107    public async Task<bool> DeleteAsync(int id, CancellationToken ct = default)
 108    {
 2109        var status = await _db.SupplierStatuses.FindAsync([id], ct);
 3110        if (status is null) return false;
 111
 112        // FK на OrderSupplierStates объявлен как SET NULL: строки состояний остаются,
 113        // просто теряют ссылку и будут переназначены при следующем опросе поставщика.
 1114        _db.SupplierStatuses.Remove(status);
 1115        await _db.SaveChangesAsync(ct);
 1116        return true;
 2117    }
 118}