24d2cd7a6a
GET api/reports/vacancies?from=&to= отдаёт лист «Список вакансий (все)» по образцу ручного отчёта HR: те же шестнадцать колонок, разделители по объектам, двойная нумерация, итоги формулами. Данные — из двух форм портала: «Заявка на подбор» даёт вакансию, «Приём на работу» — её закрытие (связь по SelectionRequestId + SelectionRequestListId). Рекрутёр и дата закрытия берутся из фазы «Исполнение» парного списка «— согласование»: в самой заявке их нет. Период отбирает заявки по «Дате подачи заявки» с откатом на Created — поле заполняется руками и часто пустое. Заявки на приём периодом не ограничены: приём по вакансии из начала интервала мог оформляться уже после его конца. Колонка «Комментарии» остаётся пустой — в ручном отчёте это пометки рекрутёра, которым в заявках пока негде храниться. Генерация — ClosedXML (MIT): нужны стили, формулы и autofilter, а EPPlus с v5 под Polyform Noncommercial. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
45 lines
2.1 KiB
C#
45 lines
2.1 KiB
C#
using System.Text.Json;
|
|
|
|
namespace Tnsu.ApprovalRoute.Application.Reports;
|
|
|
|
/// <summary>
|
|
/// Строка ФАЗЫ ИСПОЛНЕНИЯ из списка «Заявка на подбор — согласование». Отчёту она
|
|
/// даёт две колонки, которых нет в самой заявке: рекрутёр (исполнитель шага) и
|
|
/// дата закрытия вакансии.
|
|
///
|
|
/// Дата закрытия — это колонка Date выполненной строки: request-portal
|
|
/// перезаписывает её в момент решения по шагу (см. setDecision в
|
|
/// shared/approval/approvalList.service.ts), так что у строки со статусом
|
|
/// «Выполнено» там именно дата закрытия, а не дата получения шага в работу.
|
|
/// </summary>
|
|
internal sealed record ExecutionRow(
|
|
int TicketId,
|
|
int StepOrder,
|
|
string Status,
|
|
string? ExecutorName,
|
|
DateOnly? Date)
|
|
{
|
|
public const string Select =
|
|
$"$select=Id,TicketId,ApprovalStatus,StepOrder,Date,TansuSiteApprover/Title" +
|
|
$"&$expand=TansuSiteApprover&$filter=Phase eq '{Phase}'&$top=5000";
|
|
|
|
private const string Phase = "Исполнение";
|
|
|
|
/// <summary>Статус выполненной строки исполнения — по нему считаем вакансию закрытой.</summary>
|
|
public const string Done = "Выполнено";
|
|
|
|
public static ExecutionRow? TryParse(JsonElement item)
|
|
{
|
|
// TicketId — Lookup на заявку; без него строку не с чем связать.
|
|
var ticketId = SharePointJson.Int(item, "TicketId");
|
|
if (ticketId is null) return null;
|
|
|
|
return new ExecutionRow(
|
|
ticketId.Value,
|
|
SharePointJson.Int(item, "StepOrder") ?? 0,
|
|
SharePointJson.String(item, "ApprovalStatus") ?? string.Empty,
|
|
SharePointJson.PersonTitle(item, "TansuSiteApprover"),
|
|
SharePointJson.Date(item, "Date"));
|
|
}
|
|
}
|