< Summary

Information
Class: OzonOrdersWeb.WebServices.Transactions.Grid.Preview.ShipToSellerOneCPlanner
Assembly: OzonOrdersWeb
File(s): /home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/WebServices/Transactions/Grid/Preview/ShipToSellerOneCPlanner.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 55
Coverable lines: 55
Total lines: 127
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 6
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%210%
CreateTransitHelper()100%210%
BuildAsync()0%7280%
CheckStockAsync(...)100%210%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/WebServices/Transactions/Grid/Preview/ShipToSellerOneCPlanner.cs

#LineLine coverage
 1using Microsoft.EntityFrameworkCore;
 2using OzonDomains.Models;
 3using OzonOrdersWeb.Areas.Studio2.Helpers;
 4using OzonRepositories.Context;
 5using Services.ApiServices._1CApi;
 6using Services.ApiServices._1CApi.Stock;
 7using Services.DataServices;
 8using Services.StockSyncServices;
 9
 10namespace OzonOrdersWeb.WebServices.Transactions.Grid.Preview;
 11
 12/// <summary>Исходные данные проверки «Отгружен реализатору»: количества в штуках заказа, засыл и транзитные (qty = 0) з
 13public sealed record ShipToSellerPlanRequest(
 14    IReadOnlyCollection<int> MainOrderIds,
 15    IReadOnlyDictionary<int, decimal> Quantities,
 16    IReadOnlyDictionary<int, string?> ZasylRaw,
 17    IReadOnlyCollection<int> ZeroOrderIds,
 18    IReadOnlyDictionary<int, string>? ManufacturerByOrderId);
 19
 20/// <summary>Результат построения плана: строки проверки остатков 1С и всё, что нужно показать на панели.</summary>
 21public sealed class ShipToSellerPlan
 22{
 23    public List<Order> MainOrders { get; init; } = new();
 24
 25    /// <summary>Перечитанные из БД заказы с qty = 0 (транзит «Утерян реализатором»).</summary>
 26    public List<Order> ZeroOrders { get; init; } = new();
 27
 28    public List<WarehouseMapping>? Mappings { get; init; }
 29
 30    /// <summary>Заказ → склад 1С по засылу (заказы без засыла не попадают в карту).</summary>
 31    public Dictionary<int, string> SenderMap { get; init; } = new();
 32
 33    /// <summary>Остаток WS, который уйдёт в транзит, по заказу.</summary>
 34    public Dictionary<int, decimal> ZeroOverrides { get; init; } = new();
 35
 36    /// <summary>Транзитные заказы без остатка WS — получат «Утерян (без транзита)», в 1С не идут.</summary>
 37    public HashSet<int> ZeroStockIds { get; init; } = new();
 38
 39    public List<StockCheckLine> Lines { get; init; } = new();
 40}
 41
 42/// <summary>
 43/// Общий для предпросмотра панели и шага проведения расчёт «что и с какого склада проверять в 1С» для
 44/// «Отгружен реализатору». Повторяет классический <c>ShippedToSellerTransactionController</c>:
 45/// склад основных строк — по засылу и связям складов (<see cref="ShippedToSellerZasylResolver"/>),
 46/// транзитные строки (qty = 0) — остаток WS на транзитное перемещение.
 47/// </summary>
 48public sealed class ShipToSellerOneCPlanner
 49{
 50    private readonly ApplicationDbContext _context;
 51    private readonly WarehouseMappingDataServices _mappings;
 52    private readonly AppStatusDataServices _appStatuses;
 53    private readonly IWarehouseStockLookupService _stockLookup;
 54    private readonly OneCTransferManager? _transfer;
 55    private readonly IOneCStockAvailabilityService? _availability;
 56
 057    public ShipToSellerOneCPlanner(
 058        ApplicationDbContext context,
 059        WarehouseMappingDataServices mappings,
 060        AppStatusDataServices appStatuses,
 061        IWarehouseStockLookupService stockLookup,
 062        OneCTransferManager? transfer = null,
 063        IOneCStockAvailabilityService? availability = null)
 64    {
 065        _context = context;
 066        _mappings = mappings;
 067        _appStatuses = appStatuses;
 068        _stockLookup = stockLookup;
 069        _transfer = transfer;
 070        _availability = availability;
 071    }
 72
 73    public LostByCommissionerTransitHelper CreateTransitHelper()
 074        => new(_context, _appStatuses, _mappings, _transfer, _stockLookup);
 75
 76    public async Task<ShipToSellerPlan> BuildAsync(ShipToSellerPlanRequest request, CancellationToken ct = default)
 77    {
 078        var mappings = await _mappings.GetWarehouseMappings();
 79
 080        var mainOrders = request.MainOrderIds.Count > 0
 081            ? await TransactionStockCheckLineBuilder.LoadForStockCheckAsync(_context, request.MainOrderIds)
 082            : new List<Order>();
 083        var senderMap = ShippedToSellerZasylResolver.BuildSenderMap(mainOrders, mappings, request.ZasylRaw);
 084        var senderOrNull = senderMap.Count > 0 ? new Dictionary<int, string>(senderMap) : null;
 85
 086        var lines = TransactionStockCheckLineBuilder
 087            .FromWarehouseMappings(mainOrders, mappings, senderOrNull, request.Quantities)
 088            .ToList();
 89
 090        var zeroOrders = new List<Order>();
 091        var zeroOverrides = new Dictionary<int, decimal>();
 092        var zeroStockIds = new HashSet<int>();
 093        if (request.ZeroOrderIds.Count > 0)
 94        {
 095            var zeroIds = request.ZeroOrderIds.ToList();
 096            zeroOrders = await _context.Orders.AsNoTracking()
 097                .Include(o => o.OzonClient)
 098                .Include(o => o.ShipmentWarehouse)
 099                .Include(o => o.OrderExtensions)
 0100                .Include(o => o.EtProducer)
 0101                .Include(o => o.Manufacturer)
 0102                .Where(o => zeroIds.Contains(o.Id))
 0103                .ToListAsync(ct);
 104
 0105            var helper = CreateTransitHelper();
 0106            var manufacturers = request.ManufacturerByOrderId?.ToDictionary(kv => kv.Key, kv => kv.Value);
 0107            (zeroOverrides, zeroStockIds) = await helper.BuildStockQtyAsync(zeroOrders, manufacturers);
 108
 0109            var transitOrders = zeroOrders.Where(o => !zeroStockIds.Contains(o.Id));
 0110            lines.AddRange(await helper.BuildTransitStockCheckLinesAsync(transitOrders, zeroOverrides));
 0111        }
 112
 0113        return new ShipToSellerPlan
 0114        {
 0115            MainOrders = mainOrders,
 0116            ZeroOrders = zeroOrders,
 0117            Mappings = mappings,
 0118            SenderMap = senderMap,
 0119            ZeroOverrides = zeroOverrides,
 0120            ZeroStockIds = zeroStockIds,
 0121            Lines = lines
 0122        };
 0123    }
 124
 125    public Task<StockCheckResult> CheckStockAsync(ShipToSellerPlan plan)
 0126        => OneCStockGate.RunAsync(_availability, plan.Lines);
 127}