< Summary

Information
Class: AspNetCoreGeneratedDocument.Areas_Studio2_Views_Partials_Orders__IndexTable
Assembly: OzonOrdersWeb
File(s): /home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/Areas/Studio2/Views/Partials/Orders/_IndexTable.cshtml
Line coverage
0%
Covered lines: 0
Uncovered lines: 279
Coverable lines: 279
Total lines: 1109
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 740
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%600240%
L()100%210%
<ExecuteAsync()0%3975306300%
<ExecuteAsync()100%210%
<ExecuteAsync()100%210%
<ExecuteAsync()100%210%
<ExecuteAsync()100%210%
<ExecuteAsync()100%210%
<ExecuteAsync()100%210%
<ExecuteAsync()100%210%
<ExecuteAsync()100%210%
<ExecuteAsync()100%210%
<ExecuteAsync()100%210%
<ExecuteAsync()100%210%
<ExecuteAsync()100%210%
<ExecuteAsync()100%210%
<ExecuteAsync()100%210%
<ExecuteAsync()100%210%
<ExecuteAsync()100%210%
<ExecuteAsync()100%210%
<ExecuteAsync()100%210%
<ExecuteAsync()100%210%
<ExecuteAsync()100%210%
<ExecuteAsync()100%210%
<ExecuteAsync()100%210%
<ExecuteAsync()100%210%
<ExecuteAsync()100%210%
<ExecuteAsync()100%210%
<ExecuteAsync()100%210%
<ExecuteAsync()100%210%
<ExecuteAsync()100%210%
<ExecuteAsync()100%210%
GetPriceTextColorClass(...)0%210140%
GetClientTooltip(...)0%210140%
GetIndexColor(...)0%2040%
GetColorIndexHex(...)0%210140%
GetColorIndexDescription(...)0%210140%
GetPriceTooltip(...)0%7280%
GetPurchasePriceTooltip(...)0%110100%

File(s)

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

#LineLine coverage
 1@using OzonDomains
 2@using OzonDomains.Models
 3@using Services.FiltersServices.SortModels
 4@using OzonOrdersWeb.ViewModels.OrderViewModels
 5@using OzonOrdersWeb.Areas.Studio2.ViewHelpers
 6@using Microsoft.AspNetCore.Html
 7@using System.Net
 8
 9@model OrderPageViewModel<Order, OServices.FiltersServices.FilterModels.OrderFilterModel>
 10
 11<script src="~/js/copyArticle.js"></script>
 12<script src="~/js/Studio2/Orders/generateLabel.js"></script>
 13
 14@{
 15    // Текущий sortOrder для определения активной колонки
 016    var currentSort = ViewBag.CurrentSortOrder as OrderSortState? ?? OrderSortState.StandardState;
 17
 18    // Хелпер для получения текста с условной стрелкой. Возвращает IHtmlContent — Razor рендерит
 19    // его как есть (без повторного экранирования), поэтому подсветку активного столбца сортировки
 20    // можно включить прямо здесь одним местом, без правки ~30 мест вызова: оборачиваем текст+стрелку
 21    // в <span class="sort-col-active">, а CSS :has() уже подсвечивает содержащий th/cell-row/pair —
 22    // источник истины — серверный currentSort, а не клиентский клик+кука (те были рассинхронизированы,
 23    // т.к. большинство th/wrapper вообще без id).
 024    Func<string, OrderSortState, OrderSortState, IHtmlContent> getSortText = (text, ascState, descState) =>
 025    {
 026        var encoded = WebUtility.HtmlEncode(text);
 027        if (currentSort == ascState)
 028            return new HtmlString($"<span class=\"sort-col-active\">{encoded}<span class=\"sort-col-arrow\">↑</span></sp
 029        if (currentSort == descState)
 030            return new HtmlString($"<span class=\"sort-col-active\">{encoded}<span class=\"sort-col-arrow\">↓</span></sp
 031        return new HtmlString(encoded);
 032    };
 33
 034    Func<string?, string> truncateStatus = text =>
 035    {
 036        if (string.IsNullOrEmpty(text)) return text ?? "";
 037        return text.Length > 20 ? text.Substring(0, 20) + "..." : text;
 038    };
 39
 040    var readMap = Model.OrderListFieldReadAccess;
 041    var u = Model.User;
 042    bool L(string field, string leg) => OrderListColumnGate.CanShowOrderColumn(u, readMap, field, leg);
 043    var indexAction = ViewData["IndexAction"] as string ?? "Index";
 044    var isReturnsPage = string.Equals(indexAction, "Returns", StringComparison.OrdinalIgnoreCase);
 045    var returnVisualStatusOptions = ViewBag.ReturnVisualStatusOptions as Dictionary<string, string> ?? new Dictionary<st
 046    var clientStatusColors = ViewBag.ClientStatusColors as Dictionary<string, string> ?? new Dictionary<string, string>(
 047    var labelExistsMap = ViewData["LabelExistsByShipmentNumber"] as Dictionary<string, bool>
 048                         ?? new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
 49}
 50
 51<div id="filterEnterHint" class="filter-enter-hint" role="status" hidden>
 52    <i class="fas fa-keyboard" aria-hidden="true"></i>
 53    <span>Нажмите Enter для применения фильтра</span>
 54    <button type="button" class="filter-enter-hint-dismiss" aria-label="Закрыть">&times;</button>
 55</div>
 56
 57<div class="table-container table-edge-flush">
 58    <table class="table orders-index-table transaction-table@(Model.Items.Any() ? "" : " orders-index-table--empty")" id
 59
 60        <!-- Каркас для колонок (будет перестроен JavaScript на основе видимых th) -->
 61        <colgroup id="tableColgroup">
 62        </colgroup>
 63
 064        <form id="filterForm" asp-action="@indexAction" method="post" data-no-loading>
 065            @Html.AntiForgeryToken()
 66            <!-- Скрытые поля для синхронизации состояния фильтров из навигации -->
 67            <input type="hidden" id="includeArchivedFilterHidden" name="IncludeArchived"
 68                   value="@(Model.FilterModel.IncludeArchived ? "true" : "false")">
 69            <!-- Скрытое поле для авто-синхронизации статусов клиента -->
 70            <input type="hidden" id="syncClientStatusesHidden" name="SyncClientStatusesOnLoad"
 71                   value="@(Model.FilterModel.SyncClientStatusesOnLoad ? "true" : "false")">
 72            <!-- Скрытое поле для сканера штрих-кодов -->
 73            <input type="text" id="barcode" name="barcode"
 74                   style="position: fixed; left: -9999px; top: 0; width: 1px; height: 1px; opacity: 0;"
 75                   autocomplete="off" tabindex="-1"/>
 76            <!-- Скрытое поле для фильтрации по штрихкоду -->
 77            <input type="hidden" id="barcodeFilter" name="Barcode" value="@Model.FilterModel.Barcode"/>
 78            <input type="hidden" id="globalSearchFilterHidden" name="Search" value="@Model.FilterModel.Search"/>
 79            <!-- Скрытое поле для точного поиска по артикулу -->
 80            <input type="hidden" id="articleExactMatchFilter" name="ArticleExactMatch"
 81                   value="@(Model.FilterModel.ArticleExactMatch ? "true" : "false")"/>
 82            <!-- Скрытое поле для группировки по ShipmentId -->
 83            <input type="hidden" id="groupByShipmentFilterHidden" name="GroupByShipment"
 84                   value="@(Model.FilterModel.GroupByShipment ? "true" : "false")"/>
 85            <!-- Скрытое поле для фильтра "Только засыл" -->
 86            <input type="hidden" id="onlyWithZasylFilterHidden" name="OnlyWithZasyl"
 87                   value="@(Model.FilterModel.OnlyWithZasyl ? "true" : "false")"/>
 88            <!-- Скрытое поле для фильтра "Только возвраты" -->
 89            <input type="hidden" id="onlyWithReturnsFilterHidden" name="OnlyWithReturns"
 90                   value="@(Model.FilterModel.OnlyWithReturns ? "true" : "false")"/>
 91            <!-- Скрытое поле для фильтра по штрихкоду возврата -->
 92            <input type="hidden" id="returnLogisticBarcodeFilterHidden"
 93                   value="@Model.FilterModel.ReturnLogisticBarcode"/>
 94            <!-- Скрытое поле для фильтра "Только с трек-номером" -->
 95            <input type="hidden" id="onlyWithTrackingNumberFilterHidden" name="OnlyWithTrackingNumber"
 96                   value="@(Model.FilterModel.OnlyWithTrackingNumber ? "true" : "false")"/>
 97            <!-- Скрытые поля для фильтров, перенесённых в navbar dropdown -->
 98            <input type="hidden" id="deliveryNameFilterHidden" name="DeliveryName"
 99                   value="@(Model.FilterModel.DeliveryName ?? "")"/>
 100            <input type="hidden" id="trackingNumberFilterHidden" name="TrackingNumber"
 101                   value="@(Model.FilterModel.TrackingNumber ?? "")"/>
 102            <input type="hidden" id="supplierStatusIdFilterHidden" name="SupplierStatusId"
 103                   value="@(Model.FilterModel.SupplierStatusId?.ToString() ?? "")"/>
 104            <input type="hidden" id="hasOzonPromotionFilterHidden" name="HasOzonPromotion"
 105                   value="@(Model.FilterModel.HasOzonPromotion?.ToString().ToLowerInvariant() ?? "")"/>
 106            <thead>
 107            <tr>
 0108                @if ((L("ShipmentNumber", "Номер заказа") || L("Delivery", "Номер заказа") || L("DeliveryType", "Номер з
 109                {
 110                    <th id="thShipmentNumber" data-column="shipmentNumber">
 111                        <div class="two-row-cell">
 0112                            @if (L("ShipmentNumber", "Номер заказа"))
 113                            {
 114                                <div id="thShipmentNumberSort" class="cell-row">
 0115                                    <a class="text-dark" asp-action="@indexAction"
 0116                                       asp-route-sortOrder="@ViewBag.ShipmentNumberSort">
 0117                                        <small>@getSortText("Номер заказа", OrderSortState.ShipmentNumberAsc, OrderSortS
 118                                    </a>
 119                                    <div class="shipment-drop-zone" title="Перетащите PDF/Excel с номерами отправлений">
 120                                        <input asp-for="@Model.FilterModel.ShipmentNumber" id="shipmentNumberFilter"
 121                                               name="ShipmentNumber" class="form-control form-control-sm"
 122                                               autocomplete="off"/>
 123                                        <button type="button" id="shipmentAttachBtn" class="shipment-attach-btn" title="
 124                                            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="current
 125                                                <path d="M4.5 3a2.5 2.5 0 0 1 5 0v9a1.5 1.5 0 0 1-3 0V5a.5.5 0 0 1 1 0v7
 126                                            </svg>
 127                                        </button>
 128                                    </div>
 129                                </div>
 130                            }
 0131                            @if (L("Delivery", "Номер заказа"))
 132                            {
 133                                <div id="thDeliverySort" class="cell-row">
 0134                                    <a class="text-muted" asp-action="@indexAction" asp-route-sortOrder="@ViewBag.Delive
 0135                                        <small>@getSortText("Доставка", OrderSortState.DeliveryAsc, OrderSortState.Deliv
 136                                    </a>
 137                                    <div class="position-relative w-100">
 138                                        <input asp-for="@Model.FilterModel.Provider"
 139                                               id="deliveryFilter"
 140                                               name="Provider"
 141                                               class="form-control form-control-sm"
 142                                               autocomplete="off" readonly style="cursor:pointer"/>
 143                                        <span class="filter-chevron">▾</span>
 144                                        <ul id="deliveryDropdown" class="dropdown-menu filter-dropdown-list"
 145                                            style="display:none; z-index:9999; min-width:160px; max-height:200px; overfl
 146                                            <li><a href="#" data-value="Все" style="font-weight: normal;">&nbsp;Все</a><
 0147                                            @foreach (var wh in ViewBag.Providers)
 148                                            {
 149                                                <li>
 0150                                                    <a href="#" data-value="@wh.Text"
 0151                                                       style="font-weight: normal;">&nbsp;@wh.Text</a></li>
 152                                            }
 153                                        </ul>
 154                                    </div>
 155                                </div>
 156                            }
 157                        </div>
 158                    </th>
 0159                    @if (L("ShipmentNumber", "Номер заказа"))
 160                    {
 161                        <th data-column="shipmentActions" class="orders-shipment-actions-col" aria-label="Действия"></th
 162                    }
 163                }
 164                <th data-column="client">
 165                    <div class="two-row-cell">
 0166                        @if (L("OzonClient", "Клиент"))
 167                        {
 168                            <div id="thOzonClient" class="cell-row">
 0169                                <a class="text-dark" asp-action="@indexAction" asp-route-sortOrder="@ViewBag.OzonClient"
 0170                                    <small>@getSortText("Клиент", OrderSortState.OzonClientAsc, OrderSortState.OzonClien
 171                                </a>
 172                                <div class="position-relative w-100">
 173                                    <input asp-for="@Model.FilterModel.OzonClient" id="ozonClientFilterInput"
 174                                           name="OzonClient"
 175                                           class="form-control form-control-sm" autocomplete="off" readonly style="curso
 176                                    <span class="filter-chevron">▾</span>
 177                                    <ul id="ozonClientDropdown" class="dropdown-menu filter-dropdown-list"
 178                                        style="display:none; z-index:9999; min-width:160px; max-height:200px; overflow-y
 179                                        <li><a href="#" data-value="Все" style="font-weight: normal;">&nbsp;Все</a></li>
 0180                                        @foreach (var client in ViewBag.Clients)
 181                                        {
 182                                            <li>
 0183                                                <a href="#" data-value="@client.Value"
 0184                                                   style="font-weight: normal;">&nbsp;@client.Text</a></li>
 185                                        }
 186                                    </ul>
 187                                </div>
 188                            </div>
 189                        }
 0190                        @if (L("DeliveryCity", "Город доставки"))
 191                        {
 192                            <div id="thDeliveryCity" class="cell-row">
 0193                                <a class="text-muted" asp-action="@indexAction"
 0194                                   asp-route-sortOrder="@ViewBag.DeliveryCitySort">
 0195                                    <small>@getSortText("Город доставки", OrderSortState.DeliveryCityAsc, OrderSortState
 196                                </a>
 197                                <div class="position-relative w-100">
 198                                    <input asp-for="@Model.FilterModel.DeliveryCity" id="deliveryCityFilter"
 199                                           name="DeliveryCity"
 200                                           class="form-control form-control-sm" autocomplete="off"/>
 201                                    <ul id="deliveryCityDropdown" class="dropdown-menu filter-dropdown-list"
 202                                        style="display: none;"></ul>
 203                                </div>
 204                            </div>
 205                        }
 0206                        @if (isReturnsPage)
 207                        {
 208                            <div id="thReturnBarcodeFilter" class="cell-row">
 209                                <input asp-for="@Model.FilterModel.ReturnLogisticBarcode" id="returnLogisticBarcodeInlin
 210                                       name="ReturnLogisticBarcode"
 211                                       class="form-control form-control-sm w-100" autocomplete="off"
 212                                       placeholder="Штрихкод возврата"/>
 213                            </div>
 214                        }
 215                    </div>
 216                </th>
 217                <th data-column="dates">
 218                    <div class="two-row-cell">
 0219                        @if (L("ProcessingDate", "Принят в обработку"))
 220                        {
 221                            <div id="thProcessingDate" class="cell-row">
 0222                                <a class="text-dark" asp-action="@indexAction"
 0223                                   asp-route-sortOrder="@ViewBag.ProcessingDateSort">
 0224                                    <small>@getSortText("Принят", OrderSortState.ProcessingDateAsc, OrderSortState.Proce
 225                                </a>
 226                                <div class="orders-date-filter" data-orders-date-field="ProcessingDate">
 227                                    <input id="processingDateFilter" name="ProcessingDate" form="filterForm"
 228                                           class="form-control form-control-sm" type="text" readonly data-orders-date-in
 229                                           value="@(Model.FilterModel.ProcessingDate?.ToString("yyyy-MM-dd") ?? "")" ari
 230                                    <button type="button" class="orders-date-calendar-toggle" aria-label="Выбрать дату п
 231                                    <div class="orders-date-calendar" hidden></div>
 232                                </div>
 233                            </div>
 234                        }
 0235                        @if (L("ShippingDate", "Дата отгрузки"))
 236                        {
 237                            <div id="thShippingDate" class="cell-row">
 0238                                <a class="text-muted" asp-action="@indexAction" asp-route-sortOrder="@ViewBag.ShippingDa
 0239                                    <small>@getSortText("Дата отгр.", OrderSortState.ShippingDateAsc, OrderSortState.Shi
 240                                </a>
 241                                <div class="orders-date-filter" data-orders-date-field="ShippingDate">
 242                                    <input id="shippingDateFilter" name="ShippingDate" form="filterForm"
 243                                           class="form-control form-control-sm" type="text" readonly data-orders-date-in
 244                                           value="@(Model.FilterModel.ShippingDate?.ToString("yyyy-MM-dd") ?? "")" aria-
 245                                    <button type="button" class="orders-date-calendar-toggle" aria-label="Выбрать дату о
 246                                    <div class="orders-date-calendar" hidden></div>
 247                                </div>
 248                            </div>
 249                        }
 0250                        @if (isReturnsPage)
 251                        {
 252                            <div id="thShippingDate" class="cell-row">
 253                                <a class="text-muted">
 254                                    <small>Дата изм.</small>
 255                                </a>
 256                                <input asp-for="@Model.FilterModel.ReturnStatusChangeDate"
 257                                       id="shippingDateFilter"
 258                                       name="ReturnStatusChangeDate"
 259                                       class="form-control form-control-sm" type="date"/>
 260                            </div>
 261                        }
 262                    </div>
 263                </th>
 264
 265                <th data-column="period">
 266                    <div class="two-row-cell">
 0267                        @if (L("DeliveryPeriod", "Срок доставки"))
 268                        {
 269                            <div id="thDeliveryPeriod" class="cell-row">
 0270                                <a class="text-dark" asp-action="@indexAction"
 0271                                   asp-route-sortOrder="@ViewBag.DeliveryPeriodSort" data-full-title="Срок доставки">
 0272                                    <small>@getSortText("Срок.", OrderSortState.DeliveryPeriodAsc, OrderSortState.Delive
 273                                </a>
 274                                <input asp-for="@Model.FilterModel.DeliveryPeriod" name="DeliveryPeriod"
 275                                       id="deliveryPeriodInput" class="form-control form-control-sm" type="text"
 276                                       placeholder="1 д. 1 ч."/>
 277                                <script>
 278                                    document.getElementById('deliveryPeriodInput').addEventListener('input', function (e
 279                                        let input = e.target.value;
 280
 281                                        // Проверка и добавление "д." после первой цифры и пробела
 282                                        if (input.length > 0 && !input.includes('д.') && input.match(/^\d+ $/)) {
 283                                            e.target.value = input.trim() + ' д. ';
 284                                        }
 285
 286                                        // Проверка и добавление "ч." после второй цифры и пробела
 287                                        const regexDay = /^\d+ д\. \d+ $/;
 288                                        if (regexDay.test(input) && !input.includes('ч.')) {
 289                                            e.target.value = input.trim() + ' ч.';
 290                                        }
 291
 292                                        // Валидация формата
 293                                        const pattern = /^\d+ д\. \d+ ч\.$/;
 294                                        if (!pattern.test(e.target.value)) {
 295                                            e.target.setCustomValidity('Неверный формат. Используйте формат: X д. Y ч.')
 296                                        } else {
 297                                            e.target.setCustomValidity('');
 298                                        }
 299                                    });
 300                                </script>
 301                            </div>
 302                        }
 0303                        @if (L("DeliveryPeriod", "Срок доставки"))
 304                        {
 305                            <div id="thDeliveryPeriod" class="cell-row">
 0306                                <a class="text-muted" asp-action="@indexAction" asp-route-sortOrder="@ViewBag.TimeLeftSo
 0307                                    <small>@getSortText("Остал.", OrderSortState.TimeLeftAsc, OrderSortState.TimeLeftDes
 308                                </a>
 309                                <input asp-for="@Model.FilterModel.TimeLeftDay" name="TimeLeftDay" id="timeLeftDayInput"
 310                                       class="form-control form-control-sm" type="number" placeholder="1 д."/>
 311                            </div>
 312                        }
 313                    </div>
 314                </th>
 315                <th class="orders-product-col" data-column="productInfo">
 316                    <div class="two-row-cell w-100">
 317                        <div class="cell-row orders-product-head-row1">
 318                            <div id="thArticle" class="orders-product-pair">
 0319                                @if (L("ProductKey", "Key"))
 320                                {
 0321                                    <a class="text-dark w-100" asp-action="@indexAction"
 0322                                       asp-route-sortOrder="@ViewBag.ArticleSort">
 0323                                        <small>@getSortText("Key", OrderSortState.ArticleAsc, OrderSortState.ArticleDesc
 324                                    </a>
 325                                    <div class="position-relative w-100">
 326                                        <input asp-for="@Model.FilterModel.Article" id="articleFilter" name="Article"
 327                                               class="form-control form-control-sm" autocomplete="off"/>
 328                                        <ul id="articleDropdown" class="dropdown-menu filter-dropdown-list"
 329                                            style="display: none;"></ul>
 330                                    </div>
 331                                }
 332                            </div>
 333                            <div id="thManufacturer" class="orders-product-pair orders-product-pair-center">
 0334                                @if (L("Manufacturer", "Производитель"))
 335                                {
 0336                                    <a class="text-dark w-100" asp-action="@indexAction"
 0337                                       asp-route-sortOrder="@ViewBag.ManufacturerSort">
 0338                                        <small>@getSortText("Производитель", OrderSortState.ManufacturerAsc, OrderSortSt
 339                                    </a>
 340                                    <div class="position-relative w-100">
 341                                        <input asp-for="@Model.FilterModel.Manufacturer" id="manufacturerFilter"
 342                                               name="Manufacturer" class="form-control form-control-sm"
 343                                               autocomplete="off"/>
 344                                        <ul id="manufacturerDropdown" class="dropdown-menu filter-dropdown-list"
 345                                            style="display: none;"></ul>
 346                                    </div>
 347                                }
 348                            </div>
 349                            <div id="thArticle2" class="orders-product-pair orders-product-pair-end">
 0350                                @if (L("Article", "Артикул"))
 351                                {
 0352                                    <a class="text-dark w-100" asp-action="@indexAction"
 0353                                       asp-route-sortOrder="@ViewBag.ArticleSort">
 0354                                        <small>@getSortText("Код товара", OrderSortState.ArticleAsc, OrderSortState.Arti
 355                                    </a>
 356                                    <div class="position-relative w-100">
 357                                        <input id="articleFilter2"
 358                                               name="Article2"
 359                                               type="text"
 360                                               value="@Model.FilterModel.Article"
 361                                               class="form-control form-control-sm"
 362                                               autocomplete="off"
 363                                               data-sync-target="articleFilter"/>
 364                                        <ul id="article2Dropdown" class="dropdown-menu filter-dropdown-list"
 365                                            style="display: none;"></ul>
 366                                    </div>
 367                                }
 368                            </div>
 369                        </div>
 370
 371                        <div id="thProductName" class="cell-row">
 0372                            @if (L("ProductName", "Наименование товара"))
 373                            {
 0374                                <a class="text-muted w-100" asp-action="@indexAction"
 0375                                   asp-route-sortOrder="@ViewBag.ProductNameSort">
 0376                                    <small>@getSortText("Наименование товара", OrderSortState.ProductNameAsc, OrderSortS
 377                                </a>
 378                                <div class="position-relative w-100">
 379                                    <input asp-for="@Model.FilterModel.ProductName" id="productNameFilter"
 380                                           name="ProductName" class="form-control form-control-sm"
 381                                           autocomplete="off"/>
 382                                    <ul id="productNameDropdown" class="dropdown-menu filter-dropdown-list"
 383                                        style="display: none;"></ul>
 384                                </div>
 385                            }
 386                        </div>
 387                    </div>
 388                </th>
 389                <th data-column="checkboxActions" class="checkbox-actions-head">
 390                    <div class="two-row-cell checkbox-column checkbox-actions-stack">
 391                        <div class="cell-row checkbox-actions-top">
 392                            <button type="button" class="btn btn-link hover-btn checkbox-actions-btn"
 393                                    onclick="clearForm()" title="Очистить все фильтры">
 394                                <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor"
 395                                     class="bi bi-funnel" viewBox="0 0 16 16" aria-hidden="true">
 396                                    <path
 397                                        d="M1.5 1.5A.5.5 0 0 1 2 1h12a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-.128.334L10 8.692V13.
 398                                </svg>
 399                                <span class="visually-hidden">Очистить все фильтры</span>
 400                            </button>
 401                        </div>
 402                        <div class="cell-row checkbox-actions-middle">
 403                            <div class="dropdown">
 404                                <button type="button" class="btn btn-link hover-btn checkbox-actions-btn"
 405                                        id="filterHistoryBtn" data-bs-toggle="dropdown" aria-expanded="false"
 406                                        title="История фильтров">
 407                                    <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor"
 408                                         class="bi bi-clock-history" viewBox="0 0 16 16" aria-hidden="true">
 409                                        <path
 410                                            d="M8.515 1.019A7 7 0 0 0 8 1V0a8 8 0 0 1 .589.022l-.074.997zm2.004.45a7.003
 411                                        <path d="M8 1a7 7 0 1 0 4.95 11.95l.707.707A8.001 8.001 0 1 1 8 0z"/>
 412                                        <path
 413                                            d="M7.5 3a.5.5 0 0 1 .5.5v5.21l3.248 1.856a.5.5 0 0 1-.496.868l-3.5-2A.5.5 0
 414                                    </svg>
 415                                    <span class="visually-hidden">История фильтров</span>
 416                                </button>
 417                                <ul class="dropdown-menu dropdown-menu-end" id="filterHistoryDropdown"
 418                                    style="min-width: 300px; max-height: 400px; overflow-y: auto;">
 419                                    <li><h6 class="dropdown-header">История фильтров</h6></li>
 420                                    <li>
 421                                        <div id="filterHistoryList" class="px-2 py-2">
 422                                            <small class="text-muted">История пуста</small>
 423                                        </div>
 424                                    </li>
 425                                    <li>
 426                                        <hr class="dropdown-divider">
 427                                    </li>
 428                                    <li>
 429                                        <div class="px-2 py-1">
 430                                            <small class="text-muted" id="activeFiltersList">Активных фильтров: 0</small
 431                                        </div>
 432                                    </li>
 433                                </ul>
 434                            </div>
 435                        </div>
 436                        <div class="cell-row form-check checkbox-actions-select">
 437                            <input class="form-check-input" type="checkbox" id="select-all" aria-label="Выбрать все">
 438                        </div>
 439                    </div>
 440                </th>
 441                <th class="status-column-head" data-column="status">
 442                    <div class="two-row-cell">
 0443                        @if (L("ClientStatus", "Статус клиента"))
 444                        {
 445                            <div id="thStatusOzon" class="cell-row">
 0446                                <a class="text-dark" asp-action="@indexAction" asp-route-sortOrder="@ViewBag.StatusSort"
 0447                                    <small>@getSortText("Статус клиента", OrderSortState.StatusAsc, OrderSortState.Statu
 448                                </a>
 449                                <div class="position-relative w-100">
 450                                    <input asp-for="@Model.FilterModel.Status" id="statusFilter" name="Status"
 451                                           class="form-control form-control-sm" autocomplete="off" readonly style="curso
 452                                    <span class="filter-chevron">▾</span>
 453                                    <ul id="statusDropdown" class="dropdown-menu filter-dropdown-list"
 454                                        style="display:none; z-index:9999; min-width:160px; max-height:200px; overflow-y
 455                                        <li><a href="#" data-value="Все" style="font-weight: normal;">&nbsp;Все</a></li>
 0456                                        @foreach (var stat in ViewBag.Statuses)
 457                                        {
 0458                                            var isFinal = ViewBag.StatusesIsFinal != null && ViewBag.StatusesIsFinal[sta
 0459                                            string? clientStatusColor = null;
 0460                                            clientStatusColors.TryGetValue(stat.Value, out clientStatusColor);
 461
 462                                            <li>
 463                                                <a href="#"
 0464                                                   data-value="@stat.Value"
 0465                                                   data-color="@clientStatusColor"
 466                                                   class="@(isFinal ? "final-status-item" : "")"
 467                                                   style="font-weight:@(isFinal ? "600" : "normal");">
 0468                                                    @if (isFinal)
 469                                                    {
 470                                                        <i class="fas fa-flag-checkered me-1 text-warning"></i>
 471                                                    }
 0472                                                    @stat.Text
 473                                                </a>
 474                                            </li>
 475                                        }
 476                                    </ul>
 477                                </div>
 478                            </div>
 479                        }
 0480                        @if (L("AppStatus", "Статус"))
 481                        {
 482                            <div id="thStatus" class="cell-row">
 0483                                <a class="text-muted" asp-action="@indexAction" asp-route-sortOrder="@ViewBag.AppStatusI
 0484                                    <small>@getSortText("Статус", OrderSortState.AppStatusIdAsc, OrderSortState.AppStatu
 485                                </a>
 486                                <div class="position-relative w-100">
 487                                    <input asp-for="@Model.FilterModel.AppStatus" id="appStatusFilterInput"
 488                                           name="AppStatus"
 489                                           class="form-control form-control-sm" autocomplete="off" readonly style="curso
 490                                    <span class="filter-chevron">▾</span>
 491                                    <ul id="appStatusDropdown" class="dropdown-menu filter-dropdown-list"
 492                                        style="display:none; z-index:9999; min-width:160px; max-height:200px; overflow-y
 493                                        <li><a href="#" data-value="Все" style="font-weight: normal;">&nbsp;Все</a></li>
 0494                                        @foreach (var status in ViewBag.AppStatuses)
 495                                        {
 0496                                            var color = ViewBag.StatusColors != null ? ViewBag.StatusColors[status.Value
 0497                                            var isFinal = ViewBag.AppStatusIsFinal != null && ViewBag.AppStatusIsFinal[s
 498
 499                                            <li>
 500                                                <a href="#"
 0501                                                   data-value="@status.Value"
 0502                                                   data-color="@color"
 503                                                   class="@(isFinal ? "final-status-item" : "")"
 504                                                   style="font-weight:@(isFinal ? "600" : "normal");">
 0505                                                    @if (isFinal)
 506                                                    {
 507                                                        <i class="fas fa-flag-checkered me-1 text-warning"></i>
 508                                                    }
 0509                                                    @status.Text
 510                                                </a>
 511                                            </li>
 512                                        }
 513
 514                                    </ul>
 515                                </div>
 516                            </div>
 517                        }
 0518                        @if (isReturnsPage)
 519                        {
 520                            <div id="thReturnStatus" class="cell-row">
 521                                <a class="text-muted">
 522                                    <small>Статус возврата</small>
 523                                </a>
 524                                <div class="position-relative w-100">
 525                                    @{
 0526                                        var returnStatusDisplayValue = "";
 0527                                        if (!string.IsNullOrWhiteSpace(Model.FilterModel.ReturnStatusSysName))
 528                                        {
 0529                                            if (returnVisualStatusOptions.TryGetValue(Model.FilterModel.ReturnStatusSysN
 530                                            {
 0531                                                returnStatusDisplayValue = displayValue;
 532                                            }
 533                                            else
 534                                            {
 0535                                                returnStatusDisplayValue = Model.FilterModel.ReturnStatusSysName;
 536                                            }
 537                                        }
 538                                    }
 539                                    <input id="returnStatusFilterInput"
 540                                           class="form-control form-control-sm" autocomplete="off"
 541                                           value="@returnStatusDisplayValue"/>
 542                                    <input type="hidden" id="returnStatusSysNameHidden" name="ReturnStatusSysName"
 543                                           value="@Model.FilterModel.ReturnStatusSysName"/>
 544                                    <ul id="returnStatusDropdown" class="dropdown-menu filter-dropdown-list"
 545                                        style="display: none; max-height: 200px; overflow-y: auto; position: absolute; z
 546                                        <li><a href="#" data-value="Все" style="font-weight: normal;">&nbsp;Все</a></li>
 0547                                        @foreach (var kv in returnVisualStatusOptions.OrderBy(k => k.Value))
 548                                        {
 549                                            <li>
 0550                                                <a href="#" data-value="@kv.Key" style="font-weight: normal; white-space
 551                                            </li>
 552                                        }
 553                                    </ul>
 554                                </div>
 555                                <script>
 556                                    $(document).ready(function () {
 557                                        $('#returnStatusFilterInput').focus(function () {
 558                                            $('#returnStatusDropdown').show();
 559                                        });
 560
 561                                        $('#returnStatusDropdown').on('click', 'a', function (e) {
 562                                            e.preventDefault();
 563                                            var selectedValue = $(this).data('value');
 564                                            var selectedText = $(this).text().trim();
 565                                            if (selectedValue === 'Все') {
 566                                                $('#returnStatusFilterInput').val('');
 567                                                $('#returnStatusSysNameHidden').val('');
 568                                            } else {
 569                                                $('#returnStatusFilterInput').val(selectedText);
 570                                                $('#returnStatusSysNameHidden').val(selectedValue);
 571                                            }
 572                                            $('#returnStatusFilterInput').focus();
 573                                            $('#returnStatusDropdown').hide();
 574                                            updateFilterHighlighting();
 575                                        });
 576
 577                                        $(document).on('click', function (e) {
 578                                            if (!$(e.target).closest('#returnStatusFilterInput').length && !$(e.target).
 579                                                $('#returnStatusDropdown').hide();
 580                                            }
 581                                        });
 582
 583                                        // Если пользователь печатает вручную, пытаемся преобразовать display_name -> sy
 584                                        $('#returnStatusFilterInput').on('input', function () {
 585                                            var currentText = ($(this).val() || '').trim();
 586                                            if (!currentText) {
 587                                                $('#returnStatusSysNameHidden').val('');
 588                                                return;
 589                                            }
 590                                            var matched = false;
 591                                            $('#returnStatusDropdown a[data-value]').each(function () {
 592                                                var optionText = ($(this).text() || '').trim();
 593                                                var optionValue = ($(this).data('value') || '').toString().trim();
 594                                                if (currentText === optionText) {
 595                                                    $('#returnStatusSysNameHidden').val(optionValue);
 596                                                    matched = true;
 597                                                    return false;
 598                                                }
 599                                            });
 600                                            if (!matched) {
 601                                                // Разрешаем и прямой ввод sys_name.
 602                                                $('#returnStatusSysNameHidden').val(currentText);
 603                                            }
 604                                        });
 605                                    });
 606                                </script>
 607                            </div>
 608                        }
 609                    </div>
 610                </th>
 611                <th data-column="warehouse">
 612                    <div class="two-row-cell">
 0613                        @if (L("ShipmentWarehouse", "Склад отгрузки"))
 614                        {
 615                            <div id="thShipmentWarehouse" class="cell-row">
 0616                                <a class="text-dark" asp-action="@indexAction"
 0617                                   asp-route-sortOrder="@ViewBag.ShipmentWarehouseSort">
 0618                                    <small>@getSortText("Склад отгрузки", OrderSortState.ShipmentWarehouseIdAsc, OrderSo
 619                                </a>
 620                                <div class="position-relative w-100">
 621                                    <input asp-for="@Model.FilterModel.ShipmentWarehouse" id="shipmentWarehouseFilter"
 622                                           name="ShipmentWarehouse" class="form-control form-control-sm"
 623                                           autocomplete="off" readonly style="cursor:pointer"/>
 624                                    <span class="filter-chevron">▾</span>
 625                                    <ul id="shipmentWarehouseDropdown" class="dropdown-menu filter-dropdown-list"
 626                                        style="display:none; z-index:9999; min-width:160px; max-height:200px; overflow-y
 627                                        <li><a href="#" data-value="Все" style="font-weight: normal;">&nbsp;Все</a></li>
 0628                                        @foreach (var warehous in ViewBag.Warehouses)
 629                                        {
 630                                            <li>
 0631                                                <a href="#" data-value="@warehous.Value"
 0632                                                   style="font-weight: normal;">&nbsp;@warehous.Text</a></li>
 633                                        }
 634                                    </ul>
 635                                </div>
 636                            </div>
 637                        }
 0638                        @if (L("LastStatusChangeDate", "Срок доставки"))
 639                        {
 640                            <div id="thDeliveryPeriod" class="cell-row">
 0641                                <a class="text-muted" asp-action="@indexAction"
 0642                                   asp-route-sortOrder="@ViewBag.LastStatusChangeDateSort" data-full-title="Дата изменен
 0643                                    <small>@getSortText("Дата изм. статуса", OrderSortState.LastStatusChangeDateAsc, Ord
 644                                </a>
 645                                <div class="orders-date-filter" data-orders-date-field="LastStatusChangeDate">
 646                                    <input id="lastStatusChangeDateFilter" name="LastStatusChangeDate" form="filterForm"
 647                                           class="form-control form-control-sm" type="text" readonly data-orders-date-in
 648                                           value="@(Model.FilterModel.LastStatusChangeDate?.ToString("yyyy-MM-dd") ?? ""
 649                                    <button type="button" class="orders-date-calendar-toggle" aria-label="Выбрать дату и
 650                                    <div class="orders-date-calendar" hidden></div>
 651                                </div>
 652                            </div>
 653                        }
 0654                        @if (isReturnsPage)
 655                        {
 656                            <div id="thReturnWarehouseFilter" class="cell-row">
 657                                <a class="text-muted">
 658                                    <small>Склад возврата</small>
 659                                </a>
 660                                <div class="position-relative w-100">
 661                                    <input asp-for="@Model.FilterModel.ReturnWarehouseName" id="returnWarehouseFilter"
 662                                           name="ReturnWarehouseName"
 663                                           class="form-control form-control-sm" autocomplete="off" readonly style="curso
 664                                    <span class="filter-chevron">▾</span>
 665                                    <ul id="returnWarehouseDropdown" class="dropdown-menu filter-dropdown-list"
 666                                        style="display:none; z-index:9999; min-width:160px; max-height:200px; overflow-y
 667                                        <li><a href="#" data-value="Все" style="font-weight: normal;">&nbsp;Все</a></li>
 0668                                        @foreach (var warehouse in (IEnumerable<string>)(ViewBag.ReturnWarehouseOptions 
 669                                        {
 670                                            <li>
 0671                                                <a href="#" data-value="@warehouse" style="font-weight: normal;">&nbsp;@
 672                                            </li>
 673                                        }
 674                                    </ul>
 675                                </div>
 676                            </div>
 677                        }
 678                    </div>
 679                </th>
 680                <th data-column="supplier">
 681                    <div class="two-row-cell">
 0682                        @if (L("Supplier", "Поставщик"))
 683                        {
 684                            <div id="thSupplier" class="cell-row">
 0685                                <a class="text-info" asp-action="@indexAction" asp-route-sortOrder="@ViewBag.SupplierSor
 0686                                    <small>@getSortText("Поставщик", OrderSortState.SupplierAsc, OrderSortState.Supplier
 687                                </a>
 688                                <div class="position-relative w-100">
 689                                    <input asp-for="@Model.FilterModel.Supplier" id="supplierFilter" name="Supplier"
 690                                           class="form-control form-control-sm" autocomplete="off" readonly style="curso
 691                                    <span class="filter-chevron">▾</span>
 692                                    <ul id="supplierDropdown" class="dropdown-menu filter-dropdown-list"
 693                                        style="display:none; z-index:9999; min-width:160px; max-height:200px; overflow-y
 694                                        <li><a href="#" data-value="Все" style="font-weight: normal;">&nbsp;Все</a></li>
 0695                                        @foreach (var supplier in ViewBag.Suppliers)
 696                                        {
 697                                            <li>
 0698                                                <a href="#" data-value="@supplier.Value"
 0699                                                   style="font-weight: normal;">&nbsp;@supplier.Text</a></li>
 700                                        }
 701                                    </ul>
 702                                </div>
 703                            </div>
 704                        }
 0705                        @if (L("SupplierOrderNumber", "Номер заказа поставщику"))
 706                        {
 707                            <div id="thOrderNumberToSupplierSort" class="cell-row">
 0708                                <a class="text-info" asp-action="@indexAction"
 0709                                   asp-route-sortOrder="@ViewBag.OrderNumberToSupplierSort" data-full-title="Номер заказ
 0710                                    <small>@getSortText("Номер заказа п.", OrderSortState.OrderNumberToSupplierAsc, Orde
 711                                </a>
 712                                <input asp-for="@Model.FilterModel.OrderNumberToSupplier"
 713                                       id="orderNumberToSupplierFilter"
 714                                       name="OrderNumberToSupplier" class="form-control form-control-sm"/>
 715                            </div>
 716                        }
 717                    </div>
 718                </th>
 719                <th data-column="category">
 720                    <div class="two-row-cell">
 0721                        @if (L("Category", "Категория"))
 722                        {
 723                            <div id="thCategory" class="cell-row">
 0724                                <a class="text-dark" asp-action="@indexAction" asp-route-sortOrder="@ViewBag.CategorySor
 0725                                    <small>@getSortText("Категория", OrderSortState.CategoryAsc, OrderSortState.Category
 726                                </a>
 727                                <div class="position-relative w-100">
 728                                    <input asp-for="@Model.FilterModel.CommercialCategory" id="commercialCategoryFilter"
 729                                           name="CommercialCategory" class="form-control form-control-sm" autocomplete="
 730                                           placeholder="Введите для поиска…" data-lazy-commercial-categories="true"/>
 731                                    <span class="filter-chevron">▾</span>
 732                                    <ul id="commercialCategoryDropdown" class="dropdown-menu filter-dropdown-list"
 733                                        style="display:none; z-index:9999; min-width:200px; max-height:240px; overflow-y
 734                                        <li class="dropdown-item-text text-muted px-2 py-1"><small>Загрузка…</small></li
 735                                    </ul>
 736                                </div>
 737                            </div>
 738                        }
 0739                        @if (L("VolumeWeight", "Объемный вес"))
 740                        {
 741                            <div id="thVolume" class="cell-row">
 0742                                <a class="text-muted" asp-action="@indexAction" asp-route-sortOrder="@ViewBag.VolumeSort
 0743                                    <small>@getSortText("Вес V", OrderSortState.VolumeAsc, OrderSortState.VolumeDesc)</s
 744                                </a>
 745                                <input asp-for="@Model.FilterModel.VolumetricWeight" id="volumetricWeightFilter"
 746                                       name="VolumetricWeight" class="form-control form-control-sm"/>
 747                            </div>
 748                        }
 749                    </div>
 750                </th>
 751                <th data-column="sitePrice">
 752                    <div class="two-row-cell">
 0753                        @if (L("SitePrice", "Цена сайта"))
 754                        {
 755                            <div id="thPurchasePrice" class="cell-row">
 0756                                <a class="text-dark" asp-action="@indexAction" asp-route-sortOrder="@ViewBag.CurrentPric
 0757                                    <small>@getSortText("Цена с.", OrderSortState.CurrentPriceAsc, OrderSortState.Curren
 758                                </a>
 759                                <input asp-for="@Model.FilterModel.CurrentPriceWithDiscount"
 760                                       id="currentPriceWithDiscountFilter" name="CurrentPriceWithDiscount"
 761                                       class="form-control form-control-sm"/>
 762                            </div>
 763                        }
 0764                        @if (L("Quantity", "Количество"))
 765                        {
 766                            <div id="thQuantity" class="cell-row">
 0767                                <a class="text-muted" asp-action="@indexAction" asp-route-sortOrder="@ViewBag.QuantitySo
 0768                                    <small>@getSortText("Кол.", OrderSortState.QuantityAsc, OrderSortState.QuantityDesc)
 769                                </a>
 770                                <input asp-for="@Model.FilterModel.Quantity" id="quantityFilter" name="Quantity"
 771                                       class="form-control form-control-sm"/>
 772                            </div>
 773                        }
 774                    </div>
 775                </th>
 776                <th data-column="price">
 777                    <div class="two-row-cell">
 0778                        @if (L("Price", "Цена"))
 779                        {
 780                            <div id="thPrice" class="cell-row">
 0781                                <a class="text-dark" asp-action="@indexAction" asp-route-sortOrder="@ViewBag.PriceSort">
 0782                                    <small>@getSortText("Цена", OrderSortState.PriceAsc, OrderSortState.PriceDesc)</smal
 783                                </a>
 784                                <input asp-for="@Model.FilterModel.Price" id="priceFilter" name="Price"
 785                                       class="form-control form-control-sm"/>
 786                            </div>
 787                        }
 788
 0789                        @if (L("ShipmentTotal", "Сумма отправления"))
 790                        {
 791                            <div id="thShipmentAmount" class="cell-row">
 0792                                <a class="text-muted" asp-action="@indexAction"
 0793                                   asp-route-sortOrder="@ViewBag.ShipmentAmountSort" data-full-title="Сумма отправления"
 0794                                    <small>@getSortText("Сумма о.", OrderSortState.ShipmentAmountAsc, OrderSortState.Shi
 795                                </a>
 796                                <input asp-for="@Model.FilterModel.ShipmentAmount" id="shipmentAmountFilter"
 797                                       name="ShipmentAmount" class="form-control form-control-sm"/>
 798                            </div>
 799                        }
 800                    </div>
 801                </th>
 802                <th data-column="purchasePrice">
 803                    <div class="two-row-cell">
 0804                        @if (L("PurchasePrice", "Цена закупки"))
 805                        {
 806                            <div id="thCurrentPrice" class="cell-row">
 0807                                <a class="text-info" asp-action="@indexAction" asp-route-sortOrder="@ViewBag.PurchasePri
 0808                                    <small>@getSortText("Цена зак.", OrderSortState.PurchasePriceAsc, OrderSortState.Pur
 809                                </a>
 810                                <input asp-for="@Model.FilterModel.PurchasePrice" id="purchasePriceFilter"
 811                                       name="PurchasePrice" class="form-control form-control-sm"/>
 812                            </div>
 813                        }
 0814                        @if (L("Cost", "Себестоимость"))
 815                        {
 816                            <div id="thCostPriceсе" class="cell-row">
 0817                                <a class="text-muted" asp-action="@indexAction" asp-route-sortOrder="@ViewBag.CostPriceс
 0818                                    <small>@getSortText("Себест.", OrderSortState.CostPriceAsc, OrderSortState.CostPrice
 819                                </a>
 820                                <input asp-for="@Model.FilterModel.CostPrice" id="costPriceFilter" name="CostPrice"
 821                                       class="form-control form-control-sm"/>
 822                            </div>
 823                        }
 824                    </div>
 825                </th>
 0826                @if (L("OzonCommission", "Комиссия ОЗОН"))
 827                {
 828                    <th id="thOzonCommission" data-column="commission">
 829                        <div class="two-row-cell">
 830                            <div class="cell-row">
 0831                                <a class="text-dark" asp-action="@indexAction" asp-route-sortOrder="@ViewBag.OzonCommiss
 0832                                    <small>@getSortText("Комис.", OrderSortState.MinOzonCommissionAsc, OrderSortState.Mi
 833                                </a>
 834                            </div>
 835                            <div class="cell-row">
 836                                <div style="font-size: 10px;" class="text-muted d-flex gap-1">
 837                                    <small>min</small><small>/</small><small>max</small>
 838                                </div>
 839                                <input asp-for="@Model.FilterModel.OzonCommission" id="ozonCommissionFilter"
 840                                       name="OzonCommission" class="form-control form-control-sm"/>
 841                            </div>
 842                        </div>
 843                    </th>
 844                }
 0845                @if (L("Profit", "Прибыль"))
 846                {
 847                    <th id="thProfit" data-column="profit">
 848                        <div class="two-row-cell">
 849                            <div class="cell-row">
 0850                                <a class="text-dark" asp-action="@indexAction" asp-route-sortOrder="@ViewBag.ProfitSort"
 0851                                    <small>@getSortText("Приб.", OrderSortState.ProfitAsc, OrderSortState.ProfitDesc)</s
 852                                </a>
 853                            </div>
 854                            <div class="cell-row">
 855                                <div style="font-size: 10px;" class="text-muted d-flex gap-1">
 856                                    <small>min</small><small>/</small><small>max</small>
 857                                </div>
 858                                <input asp-for="@Model.FilterModel.Profit" id="profitFilter" name="Profit"
 859                                       class="form-control form-control-sm"/>
 860                            </div>
 861                        </div>
 862                    </th>
 863                }
 0864                @if (L("MarkupPercent", "Наценка %"))
 865                {
 866                    <th id="thDiscount" data-column="markup">
 867                        <div class="two-row-cell">
 868                            <div class="cell-row">
 0869                                <a class="text-dark" asp-action="@indexAction" asp-route-sortOrder="@ViewBag.DiscountSor
 0870                                    <small>@getSortText("Нацен.%", OrderSortState.DiscountAsc, OrderSortState.DiscountDe
 871                                </a>
 872                            </div>
 873                            <div class="cell-row">
 874                                <div style="font-size: 10px;" class="text-muted d-flex gap-1">
 875                                    <small>min</small><small>/</small><small>max</small>
 876                                </div>
 877                                <input asp-for="@Model.FilterModel.Discount" id="discountFilter" name="Discount"
 878                                       class="form-control form-control-sm"/>
 879                            </div>
 880                        </div>
 881                    </th>
 882                }
 883
 884
 885            </tr>
 886            </thead>
 887            <button type="submit" id="submitFilterButton" style="display:none;"></button>
 888            <!-- Скрытая кнопка для отправки формы -->
 889        </form>
 890        <partial name="~/Areas/Studio2/Views/Partials/Orders/_IndexTableBody.cshtml" model="Model" />
 891    </table>
 892</div>
 893
 894<script>
 895    function setArticleFilter(article) {
 896        var input = document.getElementById('articleFilter');
 897        if (input) { input.value = article; }
 898        if (typeof window.submitFilterForm === 'function') {
 899            window.submitFilterForm();
 900        } else {
 901            var btn = document.getElementById('submitFilterButton');
 902            if (btn) btn.click();
 903        }
 904    }
 905
 906    function setDeliveryCityFilter(city) {
 907        var input = document.getElementById('deliveryCityFilter');
 908        if (input) { input.value = city; }
 909        if (typeof window.submitFilterForm === 'function') {
 910            window.submitFilterForm();
 911        } else {
 912            var btn = document.getElementById('submitFilterButton');
 913            if (btn) btn.click();
 914        }
 915    }
 916</script>
 917
 918@functions {
 919
 920    public string GetPriceTextColorClass(string? colorIndex)
 921    {
 0922        return colorIndex?.ToUpper() switch
 0923        {
 0924            "SUPER" => "text-success fw-bold",
 0925            "GREEN" => "text-success",
 0926            "YELLOW" => "text-warning",
 0927            "RED" => "text-danger",
 0928            "INDEX" => "text-secondary",
 0929            "UNSPECIFIED" => "text-muted",
 0930            _ => ""
 0931        };
 932    }
 933
 934    public string GetClientTooltip(OzonClient? client)
 935    {
 0936        if (client == null)
 0937            return "Информация о клиенте отсутствует";
 938
 0939        var tooltipLines = new List<string>();
 940
 941        // Тип клиента
 0942        string clientTypeText = client.ClientType switch
 0943        {
 0944            ClientType.OZON => "Ozon",
 0945            ClientType.YANDEX => "Yandex",
 0946            _ => "Другое"
 0947        };
 948
 0949        string clientTypeColor = client.ClientType switch
 0950        {
 0951            ClientType.OZON => "#007bff",
 0952            ClientType.YANDEX => "#dc3545",
 0953            _ => "#6c757d"
 0954        };
 955
 0956        tooltipLines.Add($"<div style='font-weight: bold; margin-bottom: 8px;'>Тип клиента: <span style='color: {clientT
 957
 958        // ИНН
 0959        if (!string.IsNullOrEmpty(client.INNCode))
 960        {
 0961            tooltipLines.Add($"<div style='margin: 4px 0;'><b>ИНН:</b> {System.Net.WebUtility.HtmlEncode(client.INNCode)
 962        }
 963        else
 964        {
 0965            tooltipLines.Add($"<div style='margin: 4px 0; color: #6c757d;'><b>ИНН:</b> не указан</div>");
 966        }
 967
 968        // Склад
 0969        if (!string.IsNullOrEmpty(client.WarehouseName))
 970        {
 0971            tooltipLines.Add($"<div style='margin: 4px 0;'><b>Склад:</b> {System.Net.WebUtility.HtmlEncode(client.Wareho
 972        }
 973        else
 974        {
 0975            tooltipLines.Add($"<div style='margin: 4px 0; color: #6c757d;'><b>Склад:</b> не указан</div>");
 976        }
 977
 978        // Валюта
 0979        tooltipLines.Add($"<div style='margin: 4px 0;'><b>Валюта:</b> {client.CurrencyCode}</div>");
 980
 981        // Обертка для светлого фона и ширины
 0982        return $@"
 0983                <div style='
 0984
 0985                    background: white;
 0986                    color: #333;
 0987                    padding: 12px;
 0988                    border-radius: 6px;
 0989                    border: 1px solid #ddd;
 0990                    box-shadow: 0 4px 12px rgba(0,0,0,0.15);
 0991                    min-width: 200px;
 0992                    font-family: Arial, sans-serif;
 0993                    font-size: 13px;
 0994                    line-height: 1.4;
 0995                '>
 0996                    {string.Join("", tooltipLines)}
 0997                </div>";
 998    }
 999
 1000
 1001    // Метод для получения цвета индекса на основе значения
 1002    public string GetIndexColor(decimal indexValue)
 1003    {
 01004        return indexValue switch
 01005        {
 01006            > 1.2m => "#28a745", // Зеленый - выгодно
 01007            > 0.8m => "#ffc107", // Желтый - умеренно
 01008            _ => "#dc3545" // Красный - невыгодно
 01009        };
 1010    }
 1011
 1012    // Метод для получения HEX цвета индекса
 1013    public string GetColorIndexHex(string? colorIndex)
 1014    {
 01015        return colorIndex?.ToUpper() switch
 01016        {
 01017            "SUPER" => "#198754", // Темно-зеленый
 01018            "GREEN" => "#28a745", // Зеленый
 01019            "YELLOW" => "#ffc107", // Желтый
 01020            "RED" => "#dc3545", // Красный
 01021            "INDEX" => "#6c757d", // Серый
 01022            "UNSPECIFIED" => "#6c757d", // Серый
 01023            _ => "#6c757d" // Серый по умолчанию
 01024        };
 1025    }
 1026
 1027
 1028    public string GetColorIndexDescription(string? colorIndex)
 1029    {
 01030        return colorIndex?.ToUpper() switch
 01031        {
 01032            "SUPER" => "Супервыгодный",
 01033            "GREEN" => "Выгодный",
 01034            "YELLOW" => "Умеренный",
 01035            "RED" => "Невыгодный",
 01036            "INDEX" => "Отсутствует",
 01037            "UNSPECIFIED" => "Не определён",
 01038            _ => "Не определён"
 01039        };
 1040    }
 1041
 1042    public string GetPriceTooltip(PriceIndexes? priceIndexes)
 1043    {
 01044        if (priceIndexes == null)
 01045            return "Информация о ценовом индексе отсутствует";
 1046
 01047        var tooltipLines = new List<string>();
 1048
 1049        // Добавляем цветовой индекс с соответствующим цветом
 01050        tooltipLines.Add($"<div style='font-weight: bold; margin-bottom: 8px;'>Ценовой индекс: <span style='color: {GetC
 1051
 1052        // Добавляем информацию о конкурентах Ozon
 01053        if (priceIndexes.OzonMinPrice > 0)
 1054        {
 01055            tooltipLines.Add($"<div style='margin: 4px 0;'><b>Ozon:</b></div>");
 01056            tooltipLines.Add($"<div style='margin-left: 12px;'>Минимальная цена: <b>{priceIndexes.OzonMinPrice:N0} {pric
 01057            tooltipLines.Add($"<div style='margin-left: 12px; margin-bottom: 8px;'>Индекс: <span style='color: {GetIndex
 1058        }
 1059
 1060        // Добавляем информацию о внешних конкурентах
 01061        if (priceIndexes.ExternalMinPrice > 0)
 1062        {
 01063            tooltipLines.Add($"<div style='margin: 4px 0;'><b>Внешние конкуренты:</b></div>");
 01064            tooltipLines.Add($"<div style='margin-left: 12px;'>Минимальная цена: <b>{priceIndexes.ExternalMinPrice:N0} {
 01065            tooltipLines.Add($"<div style='margin-left: 12px; margin-bottom: 8px;'>Индекс: <span style='color: {GetIndex
 1066        }
 1067
 1068        // Добавляем информацию о собственных маркетплейсах
 01069        if (priceIndexes.SelfMarketplacesMinPrice > 0)
 1070        {
 01071            tooltipLines.Add($"<div style='margin: 4px 0;'><b>Собственные маркетплейсы:</b></div>");
 01072            tooltipLines.Add($"<div style='margin-left: 12px;'>Минимальная цена: <b>{priceIndexes.SelfMarketplacesMinPri
 01073            tooltipLines.Add($"<div style='margin-left: 12px;'>Индекс: <span style='color: {GetIndexColor(priceIndexes.S
 1074        }
 1075
 1076        // Обертка для светлого фона и ширины
 01077        return $@"
 01078                 <div  class='tooltip-box'>
 01079                    {string.Join("", tooltipLines)}
 01080                </div>";
 1081    }
 1082
 1083    public string GetPurchasePriceTooltip(Order item)
 1084    {
 01085        if (item == null)
 01086            return "Цена закупки недоступна";
 1087
 01088        if (item.Supplier?.CurrencyCode == CurrencyCode.RUB)
 01089            return "Цена закупки в рублях";
 1090
 01091        var tooltipLines = new List<string>();
 01092        var supplierCurrency = item.Supplier?.CurrencyCode.ToString() ?? "RUB";
 01093        var originalPurchasePrice = item.OriginalPurchasePrice ?? 0m;
 1094
 01095        tooltipLines.Add($"<div style='font-weight: bold; margin-bottom: 8px;'>Цена закупки: </div>");
 1096
 01097        tooltipLines.Add($@"
 01098        <div style='margin-left: 12px;'>
 01099            <b>{originalPurchasePrice:N2} {supplierCurrency}</b>
 01100        </div>
 01101    ");
 1102
 01103        return $@"
 01104        <div  class='tooltip-box'>
 01105            {string.Join("", tooltipLines)}
 01106        </div>";
 1107    }
 1108
 1109}