< Summary

Information
Class: AspNetCoreGeneratedDocument.Areas_Studio2_Views_Orders_Index
Assembly: OzonOrdersWeb
File(s): /home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/Areas/Studio2/Views/Orders/Index.cshtml
Line coverage
0%
Covered lines: 0
Uncovered lines: 123
Coverable lines: 123
Total lines: 563
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 298
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
ExecuteAsync()0%578402400%
<ExecuteAsync()0%1332360%
GetSupplierProviderName()0%110100%
GetSupplierProviderLogoUrl()0%110100%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/Areas/Studio2/Views/Orders/Index.cshtml

#LineLine coverage
 1@using System.Text
 2@using OServices.FiltersServices.FilterModels
 3@using OzonDomains
 4@using OzonDomains.Models
 5@using OzonDomains.Models.SupplierStatuses
 6@using OzonOrdersWeb.Areas.Studio2.ViewHelpers
 7@using OzonOrdersWeb.ViewModels.OrderViewModels
 8@using Services.FiltersServices.SortModels
 9
 10@model OrderPageViewModel<Order, OrderFilterModel>
 11
 12@{
 13    // Текущий sortOrder для определения активной колонки
 014    var currentSort = ViewBag.CurrentSortOrder as OrderSortState? ?? OrderSortState.StandardState;
 15
 16    // Хелпер для получения текста с условной стрелкой
 017    Func<string, OrderSortState, OrderSortState, string> getSortText = (text, ascState, descState) =>
 018    {
 019        if (currentSort == ascState) return text + "↑";
 020        if (currentSort == descState) return text + "↓";
 021        return text;
 022    };
 23}
 24
 25<link rel="stylesheet" href="~/css/orderIndex.css" asp-append-version="true"/>
 26<link rel="stylesheet" href="~/css/Studio2/Orders/TransactionsTable.css" asp-append-version="true"/>
 27<link rel="stylesheet" href="~/css/Studio2/Orders/productImageCell.css" asp-append-version="true"/>
 28<link rel="stylesheet" href="~/css/Studio2/Orders/ozon-cancellation-info.css" asp-append-version="true"/>
 29<link rel="stylesheet" href="~/css/Studio2/Orders/orders-index-redesign.css" asp-append-version="true"/>
 30<link rel="stylesheet" href="~/css/table.css" asp-append-version="true"/>
 31<!-- Закрепленный счетчик выделенных заказов -->
 32<div id="selectedOrdersCounterFixed" class="selected-orders-counter">
 33    <i class="fas fa-check-circle text-primary"></i>
 34    <span id="selectedCountFixed">0</span>
 35    <span class="text-muted">выделено</span>
 36    <button type="button" id="viewSelectedBtnFixed" class="btn btn-sm"
 37            onclick="showSelectedOrdersModal()">
 38        <i class="fas fa-list me-1"></i>Показать
 39    </button>
 40    <button type="button" id="clearSelectedBtnFixed" class="btn btn-sm"
 41            onclick="clearSelectedIdsSession()" title="Очистить выделение">
 42        <i class="fas fa-trash-alt"></i>
 43    </button>
 44</div>
 45
 46<script src="~/js/copyArticle.js"></script>
 47<script src="~/js/clearForm.js"></script>
 48<!-- JsBarcode CDN -->
 49<script src="https://cdn.jsdelivr.net/npm/jsbarcode@3.11.6/dist/JsBarcode.all.min.js"></script>
 50
 51<meta charset="UTF-8">
 52
 53@{
 054    ViewData["Title"] = "Список заказов";
 055    Layout = "~/Views/Shared/_Layout.cshtml";
 56}
 57
 58@{
 059    var uploadResult = ViewData["UploadResult"] as int[];
 060    string uploadResultPeriod = ViewData["UploadResultPeriod"] as string ?? "";
 61    // Приоритетно берём сообщение из TempData, как в других представлениях, с падением обратно в ViewData
 062    string? transactionResult = TempData["TransactionResult"] as string ?? ViewData["TransactionResult"] as string;
 063    string? erorrResult = TempData["ErorrResult"] as string ?? ViewData["ErorrResult"] as string;
 064    string? ordersNotFoundInOzone = ViewData["OrdersNotFoundInOzone"] as string;
 65    // Транзакция прошла, но часть работы сознательно не выполнена (например, документ 1С не создан
 66    // из-за нехватки остатка). Ни «Успешно», ни «Ошибка операции» тут не подходят.
 067    string? transactionWarning = TempData["TransactionWarning"] as string ?? ViewData["TransactionWarning"] as string;
 068    bool? multipleShipmentNumberSearch = (bool?)TempData["MultipleShipmentNumberSearch"];
 069    int? foundOrdersCountForShipmentNumbers = (int?)TempData["FoundOrdersCountForShipmentNumbers"];
 070    int? shipmentNumbersSearchedCount = (int?)TempData["ShipmentNumbersSearchedCount"];
 071    var shipmentNumbersFoundRaw = TempData["ShipmentNumbersFound"] as string;
 072    var shipmentNumbersNotFoundRaw = TempData["ShipmentNumbersNotFound"] as string;
 073    var shipmentNumbersFound = string.IsNullOrEmpty(shipmentNumbersFoundRaw) ? new List<string>() : shipmentNumbersFound
 074    var shipmentNumbersNotFound = string.IsNullOrEmpty(shipmentNumbersNotFoundRaw) ? new List<string>() : shipmentNumber
 75}
 76
 077@if (uploadResult != null)
 78{
 79    <div class="alert alert-dismissible alert-success">
 80        <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
 81        <p>Файл успешно загружен! <br/>Результат:
 082            <br/>Добавлено @uploadResult[0] строк.<br/>Обновлено @uploadResult[1] строк.</p>
 083        @if (uploadResultPeriod != null)
 84        {
 085            <p>Период @Html.Raw(@uploadResultPeriod)</p>
 86        }
 87    </div>
 88}
 89
 090@if (!string.IsNullOrWhiteSpace(ordersNotFoundInOzone))
 91{
 92    <script type="application/json" data-app-toast-seed>
 093        @Html.Raw(System.Text.Json.JsonSerializer.Serialize(new[]
 094        {
 095            new { variant = "danger", title = "Нужна проверка", message = ordersNotFoundInOzone, detailsHtml = (string?)
 096        }))
 97    </script>
 98}
 99
 0100@if (ViewData["GlobalSearchQuery"] is string globalSearchQuery && !string.IsNullOrWhiteSpace(globalSearchQuery))
 101{
 102    <div class="alert alert-dismissible alert-info mb-2 py-2">
 103        <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Закрыть"></button>
 104        <i class="fas fa-search me-2"></i>
 0105        <strong>Быстрый поиск:</strong> «@globalSearchQuery» — номер заказа, артикул или название
 106    </div>
 107}
 108
 0109@if (multipleShipmentNumberSearch == true && foundOrdersCountForShipmentNumbers.HasValue)
 110{
 111    <div class="alert alert-dismissible alert-info mb-2 py-2">
 112        <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
 113        <i class="fas fa-search me-2"></i>
 114        <strong>Результат поиска по номерам заказов:</strong>
 0115        найдено <strong>@foundOrdersCountForShipmentNumbers</strong> из <strong>@(shipmentNumbersSearchedCount ?? foundO
 0116        @if (shipmentNumbersNotFound.Count > 0)
 117        {
 0118            <span class="text-danger ms-2">не найдено: <strong>@shipmentNumbersNotFound.Count</strong></span>
 119        }
 120        <a class="ms-2" data-bs-toggle="collapse" href="#shipmentSearchDetails" role="button" aria-expanded="false">
 121            <small>подробнее ▾</small>
 122        </a>
 123        <div class="collapse mt-2" id="shipmentSearchDetails">
 124            <div class="row g-2">
 0125                @if (shipmentNumbersFound.Count > 0)
 126                {
 127                    <div class="col-auto">
 0128                        <strong class="text-success">Найдены (@shipmentNumbersFound.Count):</strong><br/>
 0129                        <small>@string.Join(", ", shipmentNumbersFound)</small>
 130                    </div>
 131                }
 0132                @if (shipmentNumbersNotFound.Count > 0)
 133                {
 134                    <div class="col-auto">
 0135                        <strong class="text-danger">Не найдены (@shipmentNumbersNotFound.Count):</strong><br/>
 0136                        <small>@string.Join(", ", shipmentNumbersNotFound)</small>
 137                    </div>
 138                }
 139            </div>
 140        </div>
 141    </div>
 142}
 143
 144@{
 0145    var buttonState = ViewData["ButtonState"] as string ?? "";
 0146    var allowedEndpointsList = ViewBag.AllowedEndpoints as List<string> ?? new List<string>();
 0147    var hasEndpointPermissionsFlag = ViewBag.HasEndpointPermissions != null && (bool)ViewBag.HasEndpointPermissions;
 0148    var isAdminFlag = ViewBag.IsAdmin != null && (bool)ViewBag.IsAdmin;
 0149    var appPageTxPaths = ViewBag.AppPageTransactionPaths as List<string> ?? new List<string>();
 0150    var useAppPageTx = ViewBag.UseAppPageTransactionMenu != null && (bool)ViewBag.UseAppPageTransactionMenu;
 0151    var appPageCtxPaths = ViewBag.AppPageContextMenuPaths as List<string> ?? new List<string>();
 0152    var useAppPageCtx = ViewBag.UseAppPageContextMenu != null && (bool)ViewBag.UseAppPageContextMenu;
 0153    var isAppSuperAdmin = ViewBag.IsAppSuperAdmin != null && (bool)ViewBag.IsAppSuperAdmin;
 0154    var allAppPageTx = Studio2RolePageMenuCatalog.AllTransactionDropdownMvcPaths;
 0155    var allAppPageCtx = Studio2OrderContextMenuCatalog.AllContextMenuMvcPaths;
 156}
 157
 158<script>
 159    // URL для LinkReplacementProduct (index.js — статический файл, Razor не обрабатывается)
 0160    window.linkReplacementProductUrl = '@Url.Action("LinkReplacementProduct", "Products", new { area = "Studio2" })';
 161    // Список разрешённых эндпоинтов для текущего пользователя (делаем глобальными для доступа из других функций)
 0162    window.allowedEndpoints = @Html.Raw(Json.Serialize(allowedEndpointsList));
 0163    window.hasEndpointPermissions = @Json.Serialize(hasEndpointPermissionsFlag);
 0164    window.isAdmin = @Json.Serialize(isAdminFlag);
 0165    window.isAppSuperAdmin = @Json.Serialize(isAppSuperAdmin);
 0166    window.appPageTransactionPaths = @Html.Raw(Json.Serialize(appPageTxPaths));
 0167    window.useAppPageTransactionMenu = @Json.Serialize(useAppPageTx);
 0168    window.allAppPageTransactionPaths = @Html.Raw(Json.Serialize(allAppPageTx));
 0169    window.appPageContextMenuPaths = @Html.Raw(Json.Serialize(appPageCtxPaths));
 0170    window.useAppPageContextMenu = @Json.Serialize(useAppPageCtx);
 0171    window.allAppPageContextMenuPaths = @Html.Raw(Json.Serialize(allAppPageCtx));
 172
 173    // Отладочная информация
 174    console.log('Allowed endpoints:', window.allowedEndpoints);
 175    console.log('Allowed endpoints count:', window.allowedEndpoints ? window.allowedEndpoints.length : 0);
 176    console.log('Has endpoint permissions:', window.hasEndpointPermissions);
 177    console.log('Is Admin:', window.isAdmin);
 0178    console.log('Raw ViewBag.AllowedEndpoints:', @Html.Raw(Json.Serialize(ViewBag.AllowedEndpoints ?? new List<string>()
 179
 0180    window.ordersIndexAjaxUrl = '@Url.Action("IndexTableAjax", "Orders", new { area = "Studio2" })';
 0181    window.ordersIndexDateCalendarUrl = '@Url.Action("IndexDateCalendarAjax", "Orders", new { area = "Studio2" })';
 182    window.ordersIndexAjaxEnabled = true;
 0183    window.searchCommercialCategoriesUrl = '@Url.Action("SearchCommercialCategories", "OrderLookup", new { area = "Studi
 0184    window.statusColors = @Html.Raw(Json.Serialize(ViewBag.StatusColors ?? new Dictionary<string, string>()));
 0185    window.clientStatusColors = @Html.Raw(Json.Serialize(ViewBag.ClientStatusColors ?? new Dictionary<string, string>())
 186    var statusColors = window.statusColors;
 187
 188    // Подсказки для пунктов меню транзакций (из StatusTransition), ключ = (int)TransactionType
 0189    window.transactionTooltipsJs = @Html.Raw(Json.Serialize(ViewBag.TransactionTooltips ?? new Dictionary<int, string>()
 190    // Правила переходов для всплывающей подсказки выделения заказов
 0191    window.transactionTransitionRulesJs = @Html.Raw(Json.Serialize(ViewBag.TransactionTransitionRules ?? new List<object
 192</script>
 193
 194<partial name="~/Areas/Studio2/Views/Partials/Orders/_IndexTable.cshtml" model="Model"/>
 195
 196<div class="dropdown" id="contextMenu" style="display: none;">
 197    <ul class="dropdown-menu" aria-labelledby="dropdownMenuButton">
 198        <li><a class="dropdown-item" id="editAction">Изменить</a></li>
 199        <li><a class="dropdown-item" id="deleteAction">Удалить</a></li>
 200    </ul>
 201</div>
 202
 203<div class="modal fade" id="historyModal" tabindex="-1" aria-labelledby="historyModalLabel" aria-hidden="true">
 204    <div class="modal-dialog modal-dialog-centered modal-fullscreen">
 205        <div class="modal-content orders-modal orders-modal--neutral">
 206            <div class="modal-header">
 207                <h5 class="modal-title" id="historyModalLabel">
 208                    <i class="fas fa-clock-rotate-left" aria-hidden="true"></i>История заказа
 209                </h5>
 210                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Закрыть"></button>
 211            </div>
 212            <div class="modal-body">
 213                <div id="historyContent"></div>
 214            </div>
 215        </div>
 216    </div>
 217</div>
 218
 219
 220<partial name="~/Areas/Studio2/Views/Partials/Orders/Modals/_OrderShipmentTotalsModal.cshtml"/>
 221<ul id="infoWindow" class="dropdown-menu"></ul>
 222
 223<!-- Скрытое поле для передачи текущего номера страницы в index.js -->
 224<input type="hidden" id="currentPageNumber" value="@Model.PageNumber"
 0225       data-orders-total-pages="@Model.TotalPages" data-orders-page-size="@Model.PageSize"/>
 226
 227<!-- Модальное окно подтверждения экспорта в Excel -->
 228<partial name="~/Areas/Studio2/Views/Partials/Orders/Modals/_ExcelExportConfirm.cshtml"/>
 229
 230<!-- Модальное окно фильтров печати для клиента -->
 231<partial name="~/Areas/Studio2/Views/Partials/Orders/Modals/_ClientPrintFilters.cshtml"/>
 232
 233<!-- Оверлей прогресса печати -->
 234<partial name="~/Areas/Studio2/Views/Partials/Orders/_IndexPrintProgressOverlay.cshtml"/>
 235
 236<!-- Модальное окно подтверждения при нескольких товарах в заказе -->
 237<partial name="~/Areas/Studio2/Views/Partials/Orders/Modals/_MultipleItemsConfirm.cshtml"/>
 238
 239<!-- Модальное окно для подтверждения печати этикетки -->
 240<partial name="~/Areas/Studio2/Views/Partials/Orders/Modals/_LabelPrintConfirm.cshtml"/>
 241
 242<!-- Модальное окно печати этикетки Яндекс.Маркет -->
 243<partial name="~/Areas/Studio2/Views/Partials/Orders/Modals/_YandexMarketLabelPrint.cshtml"/>
 244
 245<!-- Модальное окно для подтверждения архивации -->
 246<partial name="~/Areas/Studio2/Views/Partials/Orders/Modals/_ArchiveConfirm.cshtml"/>
 247
 248<!-- Модальное окно для подтверждения разархивации -->
 249<partial name="~/Areas/Studio2/Views/Partials/Orders/Modals/_UnarchiveConfirm.cshtml"/>
 250
 251<!-- Модальное окно для подтверждения удаления -->
 252<partial name="~/Areas/Studio2/Views/Partials/Orders/Modals/_DeleteConfirm.cshtml"/>
 253
 254<br/>
 255<div id="ordersIndexPaginationBar" class="orders-index-pagination-bar d-flex align-items-center justify-content-between 
 256    <!-- Размер страницы -->
 257    <form method="post"
 258          asp-area="Studio2"
 259          asp-controller="Orders"
 260          asp-action="SetPageSizeForV2"
 261          class="orders-page-size-form d-flex align-items-center gap-2"
 262          data-no-loading>
 263
 264        <label class="orders-page-size-label" for="pageSize">Строк на стр.</label>
 265        <input type="number"
 266               id="pageSize"
 267               name="size"
 268               class="form-control form-control-sm orders-page-size-input"
 269               placeholder="@OzonOrdersWeb.Controllers.OrdersController.MaxOrdersPageSize"
 270               min="1"
 271               max="@OzonOrdersWeb.Controllers.OrdersController.MaxOrdersPageSize"
 272               title="Максимум @(OzonOrdersWeb.Controllers.OrdersController.MaxOrdersPageSize) строк; больше — кнопкой «
 273               required>
 274
 275        <button class="orders-page-size-btn" type="submit">
 276            <i class="fas fa-check" aria-hidden="true"></i>
 277            <span>Ввод</span>
 278        </button>
 279    </form>
 280
 281    <!-- Пагинация по центру -->
 282    @{
 0283        ViewData["UseOrdersIndexAjax"] = true;
 284    }
 285    <partial name="~/Areas/Studio2/Views/Partials/Orders/_IndexPagination.cshtml" model="Model"/>
 286
 287    <!-- Пустой элемент справа для симметрии -->
 288    <div class="orders-page-size-spacer" aria-hidden="true"></div>
 289</div>
 290
 291@* «Показать ещё» — дозагрузка следующей страницы строк в тот же tbody через AJAX,
 292   без full reload. Скрыта, если текущая страница последняя (управляется orders-index-ajax.js). *@
 293<div id="ordersLoadMoreBar" class="orders-load-more-bar d-flex justify-content-center mb-3"
 0294     @(Model.PageNumber >= Model.TotalPages ? "hidden" : null)>
 295    <button type="button" id="ordersLoadMoreBtn" class="btn btn-outline-primary btn-sm" data-orders-load-more>
 296        <i class="fas fa-chevron-down me-1" aria-hidden="true"></i>
 0297        <span>Показать ещё @Model.PageSize</span>
 298    </button>
 299</div>
 300
 301@* Передача данных поиска по EAN в index.js *@
 0302@if (ViewData["SearchByBarcode"] is true)
 303{
 304    <div id="barcodeSearchData"
 0305         data-barcode="@ViewData["BarcodeValue"]"
 0306         data-found="@ViewData["FoundOrdersCount"]">
 307    </div>
 308}
 309
 310<!-- Модальное окно для связывания продуктов -->
 311<partial name="~/Areas/Studio2/Views/Partials/Orders/Modals/_BindProducts.cshtml"/>
 312
 313@section Scripts {
 314<script src="~/js/Studio2/Labels/ozonLabelPrintCore.js"></script>
 315<script src="~/js/shared/header-page-dropdown.js" asp-append-version="true"></script>
 316<script src="~/js/Studio2/Orders/orders-index-ajax.js" asp-append-version="true"></script>
 317<script src="~/js/Studio2/Orders/index.js" asp-append-version="true"></script>
 318<script src="~/js/Studio2/Orders/orders-filter-dropdowns.js" asp-append-version="true"></script>
 319<script src="~/js/Studio2/Orders/orders-index-feedback.js" asp-append-version="true"></script>
 320}
 321
 322@section HeaderActions {
 323@{
 0324    var supplierStatuses = ViewBag.SupplierStatuses as List<SupplierStatus> ?? [];
 0325    var selectedSupplierStatus = supplierStatuses.FirstOrDefault(status => status.Id == Model.FilterModel.SupplierStatus
 0326    var selectedSupplierStatusLabel = selectedSupplierStatus is null
 0327        ? string.Empty
 0328        : $"{GetSupplierProviderName(selectedSupplierStatus.ProviderKey)} · {selectedSupplierStatus.Name}";
 329
 0330    string GetSupplierProviderName(string providerKey) => providerKey switch
 0331    {
 0332        "Armtek" => "Армтек RU",
 0333        "ArmtekBy" => "Армтек РБ",
 0334        "Avd" => "АВД",
 0335        "MlAuto" => "ML-Auto РБ",
 0336        "MlAutoRu" => "ML-Auto RU",
 0337        _ => providerKey
 0338    };
 339
 0340    string? GetSupplierProviderLogoUrl(string providerKey) => providerKey switch
 0341    {
 0342        "Armtek" or "ArmtekBy" => "/images/armtek-logo.svg",
 0343        "Avd" => "/images/avd-logo.svg",
 0344        "MlAuto" => "https://www.ml-auto.by/media/files/settings/inside-placeholder-logo-mobile.png",
 0345        "MlAutoRu" => "https://ml-auto.ru/media/files/settings/inside-placeholder-logo-mobile.png",
 0346        _ => null
 0347    };
 348}
 349<div class="header-page-actions">
 350    <span class="header-page-actions-sep"></span>
 351
 352    <!-- Настройки поиска -->
 353    <div class="btn-group">
 354        <button id="searchSettingsDropdown" type="button"
 355                class="hpa-btn" aria-expanded="false" aria-haspopup="true">
 356            <i class="fas fa-sliders-h"></i><span class="hpa-label">Поиск</span>
 357        </button>
 358        <ul id="searchSettingsDropdownMenu" class="dropdown-menu hpa-search-menu hpa-fixed-dropdown p-3" style="display:
 359            <li class="mb-2">
 360                <div class="form-check form-switch">
 361                    <input class="form-check-input" type="checkbox" id="includeArchivedFilter"
 0362                           data-initial-checked="@(Model.FilterModel.IncludeArchived.ToString().ToLower())">
 363                    <label class="form-check-label" for="includeArchivedFilter">
 364                        <i class="fas fa-archive me-1 text-primary"></i> Включая архив
 365                    </label>
 366                </div>
 367            </li>
 368            <li class="mb-2">
 369                <div class="form-check form-switch">
 370                    <input class="form-check-input" type="checkbox" id="filterListsByDataFilter"
 371                           data-initial-checked="false">
 372                    <label class="form-check-label" for="filterListsByDataFilter">
 373                        <i class="fas fa-filter me-1 text-info"></i> Фильтры по данным
 374                    </label>
 375                </div>
 376            </li>
 377            <li class="mb-2">
 378                <div class="form-check form-switch">
 379                    <input class="form-check-input" type="checkbox" id="groupByShipmentFilter"
 0380                           data-initial-checked="@(Model.FilterModel.GroupByShipment.ToString().ToLower())">
 381                    <label class="form-check-label" for="groupByShipmentFilter">
 382                        <i class="fas fa-boxes me-1 text-success"></i> Группировать по отправлению
 383                    </label>
 384                </div>
 385            </li>
 386            <li class="mb-2">
 387                <div class="form-check form-switch">
 388                    <input class="form-check-input" type="checkbox" id="syncClientStatusesFilter"
 0389                           data-initial-checked="@(Model.FilterModel.SyncClientStatusesOnLoad.ToString().ToLower())">
 390                    <label class="form-check-label" for="syncClientStatusesFilter">
 391                        <i class="fas fa-sync-alt me-1 text-primary"></i> Синхр. статусы клиента
 392                    </label>
 393                </div>
 394            </li>
 395            <li class="mb-2">
 396                <div class="form-check form-switch">
 397                    <input class="form-check-input" type="checkbox" id="onlyWithZasylFilter"
 0398                           data-initial-checked="@(Model.FilterModel.OnlyWithZasyl.ToString().ToLower())">
 399                    <label class="form-check-label" for="onlyWithZasylFilter">
 400                        <i class="fas fa-tag me-1 text-warning"></i> Только засыл
 401                    </label>
 402                </div>
 403            </li>
 404            <li class="mb-2">
 405                <div class="form-check form-switch">
 406                    <input class="form-check-input" type="checkbox" id="onlyWithReturnsFilter"
 0407                           data-initial-checked="@(Model.FilterModel.OnlyWithReturns.ToString().ToLower())">
 408                    <label class="form-check-label" for="onlyWithReturnsFilter">
 409                        <i class="fas fa-undo me-1 text-info"></i> Только возвраты
 410                    </label>
 411                </div>
 412            </li>
 413            <li class="mb-2">
 414                <div class="form-check form-switch">
 415                    <input class="form-check-input" type="checkbox" id="onlyWithTrackingNumberFilter"
 0416                           data-initial-checked="@(Model.FilterModel.OnlyWithTrackingNumber.ToString().ToLower())">
 417                    <label class="form-check-label" for="onlyWithTrackingNumberFilter">
 418                        <i class="fas fa-truck me-1 text-secondary"></i> С трек-номером
 419                    </label>
 420                </div>
 421            </li>
 422            <li class="mb-2">
 423                <label for="supplierStatusDropdownFilter" class="hpa-search-label">
 424                    <i class="fas fa-truck-loading me-1 text-success"></i> Статус поставщика
 425                </label>
 426                <div class="hpa-supplier-status-filter">
 427                    <button type="button" id="supplierStatusDropdownFilter"
 428                            class="form-control form-control-sm hpa-supplier-status-trigger"
 429                            data-placeholder="Все статусы поставщиков"
 430                            value="@selectedSupplierStatusLabel"
 431                            aria-expanded="false">
 0432                        <span class="hpa-supplier-status-trigger-text">@(string.IsNullOrEmpty(selectedSupplierStatusLabe
 433                        <i class="fas fa-chevron-down" aria-hidden="true"></i>
 434                    </button>
 435                    <div id="supplierStatusDropdown" class="hpa-supplier-status-dropdown" hidden>
 436                        <div class="hpa-supplier-status-search-wrap">
 437                            <i class="fas fa-search" aria-hidden="true"></i>
 438                            <input type="search" id="supplierStatusDropdownSearch" class="form-control form-control-sm"
 439                                   placeholder="Поиск по статусу или поставщику" autocomplete="off">
 440                        </div>
 441                        <div class="hpa-supplier-status-options">
 442                            <button type="button" class="hpa-supplier-status-option hpa-supplier-status-option--all"
 443                                    data-supplier-status-id="" data-supplier-status-label="Все статусы поставщиков">
 444                                <span>Все статусы поставщиков</span>
 445                            </button>
 0446                            @foreach (var supplierStatus in supplierStatuses)
 447                            {
 0448                                var providerName = GetSupplierProviderName(supplierStatus.ProviderKey);
 0449                                var logoUrl = GetSupplierProviderLogoUrl(supplierStatus.ProviderKey);
 0450                                var backgroundColor = supplierStatus.GetStatusColor();
 0451                                var foregroundColor = StatusColorContrast.GetTextColor(backgroundColor);
 0452                                var stageName = supplierStatus.StatusKind == SupplierStatusKind.Cart ? "Корзина" : "Зака
 0453                                var optionLabel = $"{providerName} · {supplierStatus.Name}";
 454
 455                            <button type="button" class="hpa-supplier-status-option"
 0456                                    data-supplier-status-id="@supplierStatus.Id"
 0457                                    data-supplier-status-label="@optionLabel"
 0458                                    data-supplier-status-search="@($"{providerName} {supplierStatus.Name} {stageName}")"
 459                                    style="--supplier-status-bg:@backgroundColor; --supplier-status-fg:@foregroundColor;
 460                                <span class="hpa-supplier-status-provider-logo" aria-hidden="true">
 0461                                    @if (logoUrl is not null)
 462                                    {
 463                                        <img src="@logoUrl" alt=""/>
 464                                    }
 0465                                    @if (supplierStatus.ProviderKey == "ArmtekBy")
 466                                    {
 467                                        <b>BY</b>
 468                                    }
 469                                </span>
 470                                <span class="hpa-supplier-status-option-main">
 0471                                    <span class="hpa-supplier-status-badge">@supplierStatus.Name</span>
 0472                                    <span class="hpa-supplier-status-meta">@providerName · @stageName</span>
 473                                </span>
 474                            </button>
 475                            }
 476                        </div>
 477                    </div>
 478                </div>
 479            </li>
 480            <li><hr class="dropdown-divider my-2"></li>
 481            <li class="mb-2">
 482                <label for="returnLogisticBarcodeFilter" class="hpa-search-label">
 483                    <i class="fas fa-barcode me-1 text-info"></i> Штрихкод возврата
 484                </label>
 485                <input type="text" class="form-control form-control-sm" id="returnLogisticBarcodeFilter"
 486                       placeholder="Введите штрихкод..." autocomplete="off">
 487            </li>
 488            <li class="mb-2">
 489                <label for="deliveryNameDropdownFilter" class="hpa-search-label">
 490                    <i class="fas fa-shipping-fast me-1 text-secondary"></i> Тип доставки
 491                </label>
 492                <input type="text" class="form-control form-control-sm" id="deliveryNameDropdownFilter"
 493                       placeholder="Тип доставки..." autocomplete="off">
 494            </li>
 495            <li class="mb-2">
 496                <label for="hasOzonPromotionFilter" class="hpa-search-label">
 497                    <i class="fas fa-tags me-1 text-warning"></i> Участие в акции
 498                </label>
 499                <select id="hasOzonPromotionFilter" class="form-select form-select-sm"
 500                        aria-label="Участие товара в акции Ozon на момент загрузки">
 501                    <option value="" selected="@(Model.FilterModel.HasOzonPromotion == null ? "selected" : null)">Все то
 502                    <option value="true" selected="@(Model.FilterModel.HasOzonPromotion == true ? "selected" : null)">В 
 503                    <option value="false" selected="@(Model.FilterModel.HasOzonPromotion == false ? "selected" : null)">
 504                </select>
 505            </li>
 506            <li>
 507                <label for="trackingNumberDropdownFilter" class="hpa-search-label">
 508                    <i class="fas fa-hashtag me-1 text-secondary"></i> Трек-номер
 509                </label>
 510                <input type="text" class="form-control form-control-sm" id="trackingNumberDropdownFilter"
 511                       placeholder="Трек-номер..." autocomplete="off">
 512            </li>
 513        </ul>
 514    </div>
 515
 516    <!-- Провести документ -->
 517    <div class="btn-group">
 518        <button id="uniqueDropdownToggle" type="button"
 519                class="hpa-btn hpa-btn--conduct" aria-expanded="false" aria-haspopup="true">
 520            <i class="fas fa-file-invoice"></i><span class="hpa-label">Провести</span>
 521        </button>
 522        <ul id="uniqueDropdownMenu" class="dropdown-menu dropdown-menu-start hpa-fixed-dropdown" aria-labelledby="unique
 523    </div>
 524
 525    <!-- Действия -->
 526    <div class="btn-group" id="actions-nav-item">
 527        <button id="headerActionsDropdown" type="button" class="hpa-btn" aria-expanded="false" aria-haspopup="true">
 528            <i class="fas fa-bolt"></i><span class="hpa-label">Действия</span>
 529        </button>
 530        <ul id="headerActionsDropdownMenu" class="dropdown-menu dropdown-menu-start hpa-fixed-dropdown" style="display:n
 531            <div class="file-action-btn-wrapper" style="display: block;">
 532                <li><a href="#" onclick="showPrintExcelModal(); return false;"
 533                       class="dropdown-item excel-export-btn" data-endpoint="/Studio2/Orders/PrintOrdersExcelV2">
 534                    <i class="fas fa-file-excel text-success me-2"></i>Экспорт в Excel
 535                </a></li>
 536            </div>
 537            <div class="file-action-btn-wrapper" style="display: block;">
 538                <li><a href="/Studio2/Percentage/UploadFile" class="dropdown-item file-upload-btn"
 539                       data-endpoint="/Studio2/Percentage/UploadFile">
 540                    <i class="fas fa-file-import text-secondary me-2"></i>Загрузить данные из файла
 541                </a></li>
 542            </div>
 543            <div class="file-action-btn-wrapper" style="display: block;">
 544                <li><a href="/Studio2/Orders/UploadFile" class="dropdown-item file-upload-btn"
 545                       data-endpoint="/Studio2/Orders/UploadFile">
 546                    <i class="fas fa-file-upload text-primary me-2"></i>Загрузить заказы из файла
 547                </a></li>
 548            </div>
 549            <div class="file-action-btn-wrapper" style="display: block;">
 550                <li><a href="/Studio2/Orders/Create" class="dropdown-item create-order-btn"
 551                       data-endpoint="/Studio2/Orders/Create" data-requires-admin="true">
 552                    <i class="fas fa-plus-circle text-success me-2"></i>Создать заказ
 553                </a></li>
 554            </div>
 555            <div class="file-action-btn-wrapper" style="display: block;">
 556                <li><a href="/Studio2/AssemblyList" class="dropdown-item">
 557                    <i class="fas fa-list-alt text-primary me-2"></i>Лист подбора
 558                </a></li>
 559            </div>
 560        </ul>
 561    </div>
 562</div>
 563}