Commit Graph

4 Commits

Author SHA1 Message Date
gorbenko.pavel 240e5984b1 feat(отчёт): строка на каждый приём + столбец «Ф.И.О. нанимаемого сотрудника»
Tests / frontend-test (pull_request) Successful in 53s
Tests / backend-test (pull_request) Successful in 5m34s
На одну заявку на подбор приходится несколько заявок на приём («Разнорабочий,
4 вакансии» → 4 кандидата), и раньше они схлопывались в одну строку: ФИО не
было вовсе, а «Дата выхода» показывала только САМУЮ ПОЗДНЮЮ из четырёх. Кто
именно вышел и когда — из отчёта было не узнать.

Теперь вакансия занимает столько строк, сколько по ней приёмов. Построчные
колонки — «Дата выхода», новая «Ф.И.О. нанимаемого сотрудника» и «Вместо
сотрудника Ф.И.О.» (у каждого приёма своё «взамен кого»); все остальные общие
и объединяются по вертикали.

Модель: VacancyReportRow.Lines — именно СТРОКИ ЛИСТА, а не «приёмы». У вакансии
без приёмов строка всё равно одна (иначе она пропала бы из отчёта), с пустыми
ФИО и датой, но с «Вместо сотрудника» из причины открытия вакансии — прежнее
поведение сохранено. Реальное число приёмов осталось в ClosedCount.

Отклонённые приёмы теперь отбрасываются целиком, а не только из счётчика:
отдельная строка с ФИО отклонённого кандидата утверждала бы «вот кого приняли».

Объединение заводится только при lineCount > 1 — область 1×1 Excel считает
некорректной и портит файл. Значение общих колонок пишется ТОЛЬКО в первую
строку: у объединённой области Excel хранит его в верхней левой ячейке, а дубли
сломали бы SUM в итогах (посчитал бы вакансию по разу на каждый приём) — на это
есть отдельный тест.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-31 14:29:13 +05:00
gorbenko.pavel 1221b31225 fix: колонки с датами теряли заливку шапки (SetDefaultColumnStyle в NPOI)
Tests / frontend-test (pull_request) Successful in 48s
Tests / backend-test (pull_request) Successful in 2m0s
H1/I1/K1 («Дата подачи заявки», «Дата закрытия вакансии», «Дата
выхода») выходили с форматом даты вместо синей заливки шапки — хотя
код применял ко всей строке 1 один и тот же стиль Header.

Причина — SetDefaultColumnStyle(col, DataDate), вызванный ПОСЛЕ записи
строк: в отличие от чистого OOXML, где стиль колонки уступает явному
стилю ячейки, NPOI этим вызовом переписывает стиль уже существующих
ячеек колонки целиком, включая шапку. Формат даты и так стоит на каждой
конкретной ячейке с датой (SetDate) — вызов просто убран.

Добавлен регрессионный тест (сравнение Index стиля, а не ссылки на
объект — NPOI отдаёт новую обёртку ICellStyle на каждый вызов
CellStyle, ссылки не совпадают даже у идентичного стиля).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 11:33:13 +05:00
gorbenko.pavel 4dac12302c feat: сводный лист «Результаты» с диаграммами в отчёте по вакансиям
Второй лист xlsx по образцу ручного отчёта HR: горизонтальная таблица
по рекрутёрам (всего/в работе %/закрыто %) и две вертикальные таблицы
с долей каждого рекрутёра в общем объёме и в объёме "в работе" — плюс
по круговой диаграмме на каждую (VacancyReportSummary,
VacancyReportWorkbook.BuildSummarySheet).

Библиотека для xlsx сменена с ClosedXML на NPOI: у ClosedXML нет
поддержки Excel-диаграмм вовсе, только у NPOI из бесплатных вариантов
она есть (XSSFChart/DataSources из NPOI.OOXML). Переписан весь
генератор, тесты читают файл обратно тем же NPOI. Заодно запинена
System.Security.Cryptography.Xml до 10.0.11 — версия, которую тянет
NPOI транзитивно (8.0.2), с известной уязвимостью.

Вакансии без рекрутёра сведены в «Без рекрутёра» и всегда идут в
таблицах последними — не участник рейтинга, а технический хвост.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 11:12:45 +05:00
gorbenko.pavel 24d2cd7a6a feat: отчёт по вакансиям в xlsx за период
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>
2026-08-27 18:01:24 +05:00