< Summary

Information
Class: OzonOrdersWeb.Areas.OneCFresh.Controllers.RegisterController
Assembly: OzonOrdersWeb
File(s): /home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/Areas/OneCFresh/Controllers/RegisterController.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 82
Coverable lines: 82
Total lines: 138
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 44
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%
Stock()0%1056320%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/Areas/OneCFresh/Controllers/RegisterController.cs

#LineLine coverage
 1using Microsoft.AspNetCore.Authorization;
 2using Microsoft.AspNetCore.Mvc;
 3using OzonOrdersWeb.Areas.OneCFresh.ViewModels;
 4using Services.ApiServices._1CApi.OData;
 5using Services.ApiServices._1CApi.OData.Models;
 6
 7namespace OzonOrdersWeb.Areas.OneCFresh.Controllers;
 8
 9[Authorize(Roles = "User,Admin")]
 10[Area("OneCFresh")]
 11[Route("OneCFresh/Register/[action]")]
 12public class RegisterController : Controller
 13{
 14    private readonly IOneCODataReferenceService _refService;
 15    private readonly IOneCODataClient _client;
 16    private const int StockPageSize = 500;
 17
 018    public RegisterController(IOneCODataReferenceService refService, IOneCODataClient client)
 19    {
 020        _refService = refService;
 021        _client = client;
 022    }
 23
 24    [HttpGet]
 25    public async Task<IActionResult> Stock(
 26        string? search = null,
 27        Guid? warehouseFilter = null,
 28        bool load = false,
 29        int skip = 0)
 30    {
 031        ViewData["Title"] = "Запасы на складах";
 32
 033        var warehouses = await _refService.GetWarehousesAsync();
 034        var whNames = warehouses.DistinctBy(w => w.RefKey).ToDictionary(w => w.RefKey, w => w.Description);
 35
 036        if (!load)
 37        {
 038            return View(new StockViewModel
 039            {
 040                Search = search,
 041                WarehouseFilter = warehouseFilter,
 042                WarehouseNames = whNames,
 043                NomenclatureNames = new Dictionary<Guid, string?>(),
 044                NomenclatureArticles = new Dictionary<Guid, string?>(),
 045                Items = new List<StockRow>()
 046            });
 47        }
 48
 49        try
 50        {
 051            var records = await _client.GetPageAsync<ODataStockRecord>(
 052                "AccumulationRegister_ЗапасыНаСкладах",
 053                top: StockPageSize,
 054                skip: skip);
 55
 056            var balances = new Dictionary<(Guid nom, Guid wh), (decimal qty, DateTime last)>();
 057            foreach (var record in records)
 58            {
 059                foreach (var row in record.RecordSet ?? Enumerable.Empty<ODataStockMovement>())
 60                {
 061                    if (!DateTime.TryParse(row.Period, out var period)) period = DateTime.MinValue;
 062                    var key = (row.NomenclatureKey, row.WarehouseKey);
 063                    balances.TryGetValue(key, out var existing);
 064                    var delta = row.RecordType == "Receipt" ? row.Quantity : -row.Quantity;
 065                    balances[key] = (existing.qty + delta, period > existing.last ? period : existing.last);
 66                }
 67            }
 68
 069            var rows = balances
 070                .Where(kv => kv.Value.qty != 0)
 071                .Select(kv => new StockRow
 072                {
 073                    NomenclatureKey = kv.Key.nom,
 074                    WarehouseKey = kv.Key.wh,
 075                    Quantity = kv.Value.qty,
 076                    LastMovement = kv.Value.last
 077                })
 078                .Where(r => !warehouseFilter.HasValue || r.WarehouseKey == warehouseFilter.Value)
 079                .OrderByDescending(r => r.LastMovement)
 080                .ToList();
 81
 82            // Загружаем имена только для отображаемых позиций (не всех)
 083            var nomKeys = rows.Select(r => r.NomenclatureKey).Distinct().Take(200).ToHashSet();
 084            var nomNames = new Dictionary<Guid, string?>();
 085            var nomArticles = new Dictionary<Guid, string?>();
 86
 087            var nomPage = await _client.GetPageAsync<ODataNomenclature>(
 088                "Catalog_Номенклатура",
 089                top: 1000,
 090                queryParams: new Dictionary<string, string>
 091                {
 092                    ["$select"] = "Ref_Key,Description,Артикул",
 093                    ["$filter"] = "IsFolder eq false"
 094                });
 95
 096            foreach (var n in nomPage)
 97            {
 098                if (!nomNames.ContainsKey(n.RefKey))
 99                {
 0100                    nomNames[n.RefKey] = n.Description ?? string.Empty;
 0101                    nomArticles[n.RefKey] = n.Article ?? string.Empty;
 102                }
 103            }
 104
 0105            if (!string.IsNullOrWhiteSpace(search))
 106            {
 0107                var s = search.Trim();
 0108                rows = rows.Where(r =>
 0109                    (nomNames.TryGetValue(r.NomenclatureKey, out var name) && (name?.Contains(s, StringComparison.Ordina
 0110                    (nomArticles.TryGetValue(r.NomenclatureKey, out var art) && (art?.Contains(s, StringComparison.Ordin
 111            }
 112
 0113            ViewBag.LoadedRecorders = records.Count;
 0114            ViewBag.NextSkip = skip + StockPageSize;
 0115            ViewBag.HasMore = records.Count == StockPageSize;
 116
 0117            return View(new StockViewModel
 0118            {
 0119                Items = rows,
 0120                Search = search,
 0121                WarehouseFilter = warehouseFilter,
 0122                WarehouseNames = whNames,
 0123                NomenclatureNames = nomNames,
 0124                NomenclatureArticles = nomArticles
 0125            });
 126        }
 0127        catch (Exception ex)
 128        {
 0129            TempData["Error"] = $"Ошибка загрузки остатков: {ex.Message}";
 0130            return View(new StockViewModel
 0131            {
 0132                Search = search,
 0133                WarehouseFilter = warehouseFilter,
 0134                WarehouseNames = whNames
 0135            });
 136        }
 0137    }
 138}