< Summary

Information
Class: AspNetCoreGeneratedDocument.Areas_Studio2_Views_TransactionJobs_Edit
Assembly: OzonOrdersWeb
File(s): /home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/Areas/Studio2/Views/TransactionJobs/Edit.cshtml
Line coverage
0%
Covered lines: 0
Uncovered lines: 11
Coverable lines: 11
Total lines: 239
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 48
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%4260%
<ExecuteAsync()0%1806420%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/Areas/Studio2/Views/TransactionJobs/Edit.cshtml

#LineLine coverage
 1@model OzonDomains.Models.BackgroundJobSchedule
 2@{
 03    ViewData["Title"] = "Редактировать расписание";
 4}
 5
 6<link rel="stylesheet" href="~/css/Studio2/TransactionJobs/transaction-jobs.css" asp-append-version="true"/>
 7
 8<div class="container py-3 tj-form-page">
 9    <div class="mb-3">
 10        <a asp-action="Index" class="text-muted small text-decoration-none"><i class="fas fa-arrow-left me-1"></i>К спис
 11    </div>
 12    <div class="tj-intro mb-3">
 13        <i class="fas fa-circle-info"></i>
 14        <div class="tj-intro-text">
 15            Изменение cron или типа задания перерегистрирует recurring job в Hangfire. Снятие галочки «Активировать» уда
 16        </div>
 17    </div>
 18    <div class="row">
 19        <div class="col-lg-10 offset-lg-1">
 20            <div class="card">
 21                <div class="card-header">
 22                    <h3 class="h5 mb-0">
 23                        <i class="fas fa-edit me-2"></i>
 024                        Редактировать расписание #@Model.Id
 25                    </h3>
 26                </div>
 27                <div class="card-body">
 28                    <form method="post" action="@Url.Action("Edit", new { id = Model.Id })">
 029                        @Html.AntiForgeryToken()
 30                        <input type="hidden" name="Id" value="@Model.Id" />
 31                        <input type="hidden" name="CreatedAt" value="@Model.CreatedAt.ToString("o")" />
 32                        <input type="hidden" name="UpdatedAt" value="@Model.UpdatedAt.ToString("o")" />
 033                        @if (Model.LastRunTime.HasValue)
 34                        {
 35                            <input type="hidden" name="LastRunTime" value="@Model.LastRunTime.Value.ToString("o")" />
 36                        }
 037                        @if (Model.NextRunTime.HasValue)
 38                        {
 39                            <input type="hidden" name="NextRunTime" value="@Model.NextRunTime.Value.ToString("o")" />
 40                        }
 41
 42                        <div class="mb-3">
 43                            <label for="Name" class="form-label">Название</label>
 44                            <div class="input-group">
 45                                <input type="text" class="form-control" id="Name" name="Name" value="@Model.Name" placeh
 46                                <button type="button" class="btn btn-outline-secondary" id="btnRegenerateName" title="Сг
 47                                    <i class="fas fa-sync-alt"></i>
 48                                </button>
 49                            </div>
 50                            <div class="form-text">
 51                                <i class="fas fa-magic me-1"></i>Название генерируется автоматически. Нажмите <i class="
 52                            </div>
 53                        </div>
 54
 55                        <div class="mb-3">
 56                            <label for="OzonClientId" class="form-label">Ozon Client <span class="text-danger">*</span><
 57                            <select class="form-select" id="OzonClientId" name="OzonClientId" required>
 058                                @foreach (var item in ViewBag.OzonClients)
 59                                {
 060                                    <option value="@item.Value" selected="@(Model.OzonClientId.ToString() == item.Value)
 61                                }
 62                            </select>
 63                        </div>
 64
 65                        <div class="mb-3">
 66                            <label for="JobType" class="form-label">Тип задания <span class="text-danger">*</span></labe
 67                            <select class="form-select" id="JobType" name="JobType" required>
 068                                @foreach (var item in ViewBag.JobTypes)
 69                                {
 070                                    <option value="@item.Value" selected="@(Model.JobType == item.Value)">@item.Text</op
 71                                }
 72                            </select>
 73                            <div class="form-text mt-2">
 74                                <span class="badge bg-secondary" id="jobTypePreviewBadge">
 75                                    <i class="fas fa-cog me-1"></i>Тип не выбран
 76                                </span>
 77                            </div>
 78                        </div>
 79
 80                        <div class="mb-3">
 81                            <label for="CronExpression" class="form-label">Cron выражение <span class="text-danger">*</s
 82                            <input type="text" class="form-control" id="CronExpression" name="CronExpression" value="@Mo
 83                            <div class="form-text">
 84                                <strong>Примеры:</strong><br>
 85                                <code>0 2 * * *</code> - каждый день в 02:00<br>
 86                                <code>0 */6 * * *</code> - каждые 6 часов<br>
 87                                <a href="https://crontab.guru/" target="_blank">Проверить выражение</a>
 88                            </div>
 89                        </div>
 90
 91                        <div class="mb-3">
 92                            <label class="form-label">День отбора заказов</label>
 93                            <p class="form-control-plaintext mb-1">
 94                                <strong>Вчера</strong> (календарный день, часовой пояс MSK)
 95                            </p>
 96                            <input type="hidden" name="DaysBack" value="1" />
 97                            <div class="form-text">
 98                                Всегда «вчера» по Москве: строки отчёта отбираются по столбцу даты за этот день
 99                                (аналог одной отмеченной даты в предпросмотре на странице загрузки файла).
 100                            </div>
 101                        </div>
 102
 0103                        @await Html.PartialAsync("_ProcessingPipelineHelp")
 104
 105                        <div class="mb-3 form-check">
 0106                            <input type="checkbox" class="form-check-input" id="IsActive" name="IsActive" value="true" @
 107                            <label class="form-check-label" for="IsActive">
 108                                Активировать расписание
 109                            </label>
 110                        </div>
 111
 112                        <div class="d-flex justify-content-between form-actions-sticky">
 113                            <a href="@Url.Action("Index")" class="btn btn-secondary">
 114                                <i class="fas fa-arrow-left me-2"></i>Назад
 115                            </a>
 116                            <button type="submit" class="btn btn-primary">
 117                                <i class="fas fa-save me-2"></i>Сохранить изменения
 118                            </button>
 119                        </div>
 120                    </form>
 121                </div>
 122            </div>
 123        </div>
 124    </div>
 125</div>
 126
 127@section Scripts {
 128<script>
 129    $(document).ready(function() {
 130        // Auto-generate name based on settings
 131        function generateName() {
 132            const clientId = $('#OzonClientId').val();
 133            const clientText = $('#OzonClientId option:selected').text();
 134            const jobType = $('#JobType').val();
 135            const jobTypeText = $('#JobType option:selected').text();
 136            const cronExpr = $('#CronExpression').val().trim();
 137            if (!clientId || !jobType || !cronExpr) {
 138                return '';
 139            }
 140
 141            const cronDesc = parseCronExpression(cronExpr);
 142            const periodText = 'за вчера';
 143
 144            // Build name
 145            const name = `${jobTypeText} ${periodText} для ${clientText} (${cronDesc})`;
 146            return name;
 147        }
 148
 149        function parseCronExpression(cron) {
 150            if (!cron) return '';
 151
 152            const parts = cron.split(' ').filter(p => p.length > 0);
 153            if (parts.length < 5) return cron;
 154
 155            const [minute, hour, dayOfMonth, month, dayOfWeek] = parts;
 156
 157            // Daily patterns
 158            if (dayOfMonth === '*' && month === '*' && dayOfWeek === '*') {
 159                if (hour.startsWith('*/')) {
 160                    const hourInterval = hour.substring(2);
 161                    return `каждые ${hourInterval}ч`;
 162                } else if (hour !== '*') {
 163                    return `ежедневно в ${hour.padStart(2, '0')}:${minute.padStart(2, '0')}`;
 164                } else {
 165                    return 'каждый час';
 166                }
 167            }
 168
 169            // Weekly patterns
 170            if (dayOfWeek !== '*' && dayOfMonth === '*') {
 171                const dayNames = ['Вс', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб'];
 172                const dayName = dayNames[parseInt(dayOfWeek)] || dayOfWeek;
 173                return `${dayName} в ${hour.padStart(2, '0')}:${minute.padStart(2, '0')}`;
 174            }
 175
 176            // Monthly patterns
 177            if (dayOfMonth !== '*' && month === '*') {
 178                return `${dayOfMonth}-го числа в ${hour.padStart(2, '0')}:${minute.padStart(2, '0')}`;
 179            }
 180
 181            return cron;
 182        }
 183
 184        function updateName(force = false) {
 185            const currentName = $('#Name').val();
 186            const newName = generateName();
 187
 188            if (force) {
 189                $('#Name').val(newName);
 190            }
 191        }
 192
 193        function updateJobTypePreview() {
 194            const value = $('#JobType').val();
 195            const badge = $('#jobTypePreviewBadge');
 196            badge.removeClass('bg-secondary bg-primary bg-warning text-dark bg-success');
 197
 198            $('.job-type-help').addClass('d-none');
 199            $('.job-help-commissioner, .job-help-return').addClass('d-none');
 200            $('#helpJobTypePlaceholder').removeClass('d-none');
 201
 202            if (value === 'ShippedToCommissioner') {
 203                badge.addClass('bg-primary').html('<i class="fas fa-truck-loading me-1"></i>Отгружен комиссионеру');
 204                $('#helpShippedToCommissioner').removeClass('d-none');
 205                $('.job-help-commissioner').removeClass('d-none');
 206                $('#helpJobTypePlaceholder').addClass('d-none');
 207                return;
 208            }
 209
 210            if (value === 'CustomerReturn') {
 211                badge.addClass('bg-warning text-dark').html('<i class="fas fa-undo-alt me-1"></i>Возврат покупателя');
 212                $('#helpCustomerReturn').removeClass('d-none');
 213                $('.job-help-return').removeClass('d-none');
 214                $('#helpJobTypePlaceholder').addClass('d-none');
 215                return;
 216            }
 217
 218            badge.addClass('bg-secondary').html('<i class="fas fa-cog me-1"></i>' + ($('#JobType option:selected').text(
 219        }
 220
 221        // Manual regeneration button
 222        $('#btnRegenerateName').on('click', function() {
 223            updateName(true);
 224        });
 225
 226        $('#OzonClientId, #JobType, #CronExpression').on('change input', function() {
 227            updateJobTypePreview();
 228        });
 229
 230        // Optional: show preview on hover
 231        $('#btnRegenerateName').on('mouseenter', function() {
 232            const preview = generateName();
 233            $(this).attr('title', 'Новое название: ' + preview);
 234        });
 235
 236        updateJobTypePreview();
 237    });
 238</script>
 239}

Methods/Properties

ExecuteAsync()
<ExecuteAsync()