SharePoint хранит поле «только дата» как полночь по поясу сайта (UTC+5)
в UTC: «05.10» приходит из REST как 2026-10-04T19:00:00Z. Формы брали
первые 10 символов и показывали 04.10, а каждое пересохранение (полное
право, исполнитель, повторная отправка) записывало дату ещё на день раньше.
Чтение всех дат идёт через spDateOnlyToIso (округление до ближайшей
полуночи UTC), «сегодня» — через todayIsoDate вместо toISOString, который
до 05:00 давал вчерашнее число. Уже сдвинутые записи в SP не исправляются.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Внешняя система (напр. КПС) передаёт source — пишем его в новую колонку
SourceSystem рядом с SourcePositionId, чтобы по заявке было видно, откуда
она пришла и куда отвечать. Запоминание источника вынесено в отдельный
эффект: positionId/source/склад сохраняются и по ссылке без nomenclatureId.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Владельцы внешней системы указали другую колонку строки заявки
(cr498_cree9_tmctransferurl) вместо прежней cr498_portalrequesturl.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Права на заявку новым участникам маршрута выдаёт бэкенд по вебхуку на
изменение элемента списка данных. Делегирование и замена/удаление
исполнителя меняли только список согласования — вебхук не приходил, и
новый человек видел «Элемент не найден». Теперь после этих действий
заявка перезаписывается с тем же статусом: значение не меняется, но
появляется новая версия элемента и срабатывает вебхук.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Цифровая версия бумажной заявки на командировку (отдел кадров). Можно
подать за другого сотрудника; маршрут — лентой точек (город + объект из
справочника проектов + даты) с видом транспорта на каждом участке и
вторым видом «Схема» (SVG, как схема метро). Задание — список задач.
Смета — карточками статей (суточные, проезд, проживание, страховка,
виза, другие расходы) с позициями, привязанными к точкам и участкам
маршрута; суммы только вручную, итог с долями и разбивкой по объектам.
Печать — без шапки с адресатом.
Плитка пока только для тестировщиков (comingSoon): списки SharePoint
не провизионированы, тип заявки и маршрут в админке не заведены.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Хук, который грузит маршрут согласования отдельно по фазам «Согласование»
и «Исполнение», был в папке «Объяснительной по СКУД». Он понадобился и
заявке на командировку, поэтому перенесён в shared/approval под общим
именем. Поведение СКУД не меняется — поменялись только импорты.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
В маршруте №8 есть шаг «Исполнение», но форма 1С запрашивала только
согласование и записывала пустой список исполнителей: после согласования
заявка навсегда оставалась «Согласовано», без исполнителя и даты исполнения.
Теперь исполнитель берётся из маршрута с теми же условиями, заявка идёт
«Выполнение» → «Закрыта», а карточка Planner создаётся при переходе в
исполнение (в т.ч. сразу при отправке, если согласование не требуется).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Если в Teams закреплена обычная страница SharePoint, SPFx не передаёт
веб-части Teams-контекст, и объявление «открывайте в браузере» не
показывалось. Теперь Teams определяется ещё по фрейму и User-Agent.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
В приложении Teams часть функций портала работает ограниченно. На главной
в Teams теперь показывается объявление со ссылкой на страницу портала,
которая открывается во внешнем браузере. В браузере объявление не показывается.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
В подборе и реферале черновик хранил дату первого сохранения, и через
несколько дней заявка уходила на согласование со старой датой подачи.
Теперь при отправке дата подачи всегда сегодняшняя, а открытый черновик
сразу показывает сегодня (как уже было в объяснительной по СКУД). В реферале
дату больше нельзя поправить руками. Общая логика — shared/submitDate.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Пользователи не понимали, почему кнопка «Отправить на согласование» серая.
Теперь в заявках на приём и подбор кнопки активны: нажатие при незаполненных
или неверных полях ничего не сохраняет, а подсвечивает эти поля с подсказкой
под ними и прокручивает к первому. Над кнопками — список проблем, пункты ведут
к полю. Механизм общий (FieldIssuesProvider + FormField), остальные формы
пока работают по-старому и переводятся по тому же паттерну.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Сотрудник пишет объяснительную за дни без отметок СКУД, выбирая их кликом
в календаре «Мой СКУД» (перенесён из portal-main-page: те же цвета и
правила, проходы Hikvision текущего пользователя, праздники из
«Производственного календаря»). Текст записки собирается автоматически,
в просмотре печатается бланк объяснительной.
- выбираются прошедшие дни < 8 ч, с одной записью или без отметок и
сегодня без отметок; только текущий и прошлый месяц;
- дни сохраняются снимком (JSON), т.к. согласующий чужой СКУД не видит;
- защита от повторов: дни из уже поданных объяснительных помечены ✓ и
не выбираются, перед отправкой список перечитывается;
- маршрут в две фазы: согласование + исполнение (кадры);
- дата подачи ставится автоматически.
Плитка пока только для тестировщиков (comingSoon): списки SP
провизионированы, тип и маршрут заведены, осталась проверка e2e.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Над списком вложений (от двух файлов) — кнопка «Скачать все»: файлы
скачиваются по очереди, без архива, через download.aspx SharePoint, чтобы
PDF и картинки не открывались в просмотре. Обёртка над AttachmentList
из ui-kit подменена в shared/ui, поэтому кнопка появилась во всех формах
и карточках без правок в них; в чате выключена.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
При доработке и повторной отправке writeRoute раньше удалял все строки
маршрута и создавал заново — кто вернул или отклонил заявку и с каким
комментарием, терялось. Теперь маршрут пересохраняется патчем
(planRoutePatch + ApprovalListService.patchSteps): строки, что остаются в
маршруте, обновляются на месте, и их прошлые решения лежат в истории
версий; недостающие шаги создаются, выпавшие и строки делегатов уходят в
корзину. Всё одним пакетом. Проверено пилотами на увольнении и рабочем
месте (обе фазы, уход в корзину). Аварийный откат для всех форм —
ROUTE_PATCH_ENABLED = false.
Из версий строк маршрута и заявки собирается лента «История
согласования» (shared/approval/history): отправки, решения с
комментариями и временем на шаге, делегирование, замена исполнителя,
у кого заявка сейчас. Свёрнутый раздел в карточке и в форме доработки
всех форм, грузится только при раскрытии.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
После возврата заявки с одним согласующим каждый добавленный на доработке
шаг показывался «Возвращена на доработку»: statusForNewRow копировал общий
статус строк. Решения (согласовано/возвращено/отклонено/выполнено) больше
не копируются — новый шаг показывается с «—». В SharePoint это не
попадало: writeRoute и раньше писал всем строкам «Ждёт очереди».
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Фильтр SharePoint substringof по Title пользователей сайта для кириллицы
чувствителен к регистру: «тимур» не находил «Тимур Городецкий». Теперь
ищутся сразу несколько написаний (как введено, строчными, с заглавной
каждого слова) и по email. Касается всех полей выбора сотрудника в
маршруте: делегирование, добавление согласующего, замена исполнителя.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Начальник отдела подбора (routeEditRights) назначает исполнителей, но
сама в исполнении не стоит. В матрице «Исполнение» заявки на подбор у
шагов «Ждёт очереди» и «На исполнении» появились кнопки «Заменить» и
«Удалить»:
- замена меняет только человека в шаге, активный шаг сразу переходит
к новому исполнителю, ему уходит оповещение;
- при удалении активного очередь переходит к следующему исполнителю;
- выполненные шаги не трогаются, последнего невыполненного исполнителя
можно только заменить — иначе заявка закрылась бы без исполнения.
Остальные формы не затронуты: кнопки включаются пропсами ApprovalMatrix
(canReplaceRow/onReplaceRow) только в RecruitingSelectionView.
notifyActiveStep получил необязательный rowId, чтобы на параллельном
шаге письмо ушло именно новому исполнителю.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Тип заявки и так виден в колонке «Тип», префикс в названии только
удлинял его:
- подбор: «Должность — Проект»;
- приём: «ФИО — Должность — Проект».
Уже созданные заявки сохраняют старое название до пересохранения.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
employeeCompanies() нужен теперь не только подбору, но и заявке на рабочее
место — одна реализация вместо копий в каждой форме.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
«Виды работ», «Организация» и «База 1С» теперь читаются из колонок списка
(общий хук shared/fieldChoices), а не из констант: новый пункт добавляется
в параметрах столбца без правки кода и деплоя. Пилот — на форме 1С, при
успехе переводим остальные формы. В стартовые варианты provisioning.json
добавлен «Маршруты в ДО».
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- СЗ на перемещение ТМЦ: поле «Куда» предзаполняется проектом-получателем
по строке-источнику Dataverse (cree9_demandline -> lzk position -> LZK ->
project id), см. shared/dataverse/lzkPosition.service.ts
- Заявка 1С досрочно разморожена для всех пользователей (UNFROZEN_FORMS
в SubmitActions), остальные формы остаются замороженными
- Поле «Отдел» в заявке 1С сделано read-only
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Провижининг (Provision-Lists.ps1 читает эти манифесты) теперь заводит колонку
«Автосогласование» (AutoApprove, Да/Нет) в каждом из 12 списков согласования —
рядом с уже существующими SLAhours/AskOverdueReason.
Значение приходит из resolve (approval-route API, шаг маршрута настраивается
только в админке — портал само значение не выбирает, только переносит его в
строку списка при отправке заявки/сохранении черновика, тем же путём, что и
slaHours/askOverdueReason). Фактическое автосогласование по истечении SLA
делает фоновая задача бэкенда (Hangfire), не портал.
В ApprovalMatrix добавлена пометка «(авто)» рядом со значением SLA — чисто
информативно, чтобы участник видел, что решение по шагу может принять не
только человек.
Примечание: ServiceRequest и TmcTransfer не передают ни slaHours/
askOverdueReason, ни (теперь) autoApprove из resolve в строку — это
существовавший пробел (SLA на уровне шага у этих двух форм и раньше не
работал), автосогласование для них наследует только это же ограничение.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
---------
Co-authored-by: gorbenko.pavel <gorbenko.pavel@tansu.kz>
Reviewed-on: http://git.tnsu.kz/timur.gorodetskiy/request-portal/pulls/20
Пункт меню виден только заданному списку почт (Тришина, Городецкий,
Горбенко) — группы HR в SharePoint пока нет, добавили TODO завести
проверку по ней отдельно (reportsAccess.ts). Скрыт из меню совсем, а
не показан неактивным, и прямой переход по ?rpnav=reports у остальных
редиректит на «Новую заявку».
Раздел — форма периода (С/По) и кнопка «Скачать xlsx», дергает
GET api/reports/vacancies через тот же AadHttpClient, что и остальные
вызовы approval-route API. Имя файла собирается на фронте по формату
бэкенда (VacancyReportWorkbook.FileName), а не читается из
Content-Disposition — approval-route не объявляет заголовок в
Access-Control-Expose-Headers, браузер бы его не отдал.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
---------
Co-authored-by: gorbenko.pavel <gorbenko.pavel@tansu.kz>
Reviewed-on: http://git.tnsu.kz/timur.gorodetskiy/request-portal/pulls/17
- Печать доступна только после согласования (Отдел рекрутинга); выбор
организации и логотип-шапка для форм с несколькими юрлицами
- «СЗ на перемещение ТМЦ»: заявителя можно выбрать (подача за другого),
маршрут резолвится на выбранного
- «Реферальная рекомендация»: организация вакансии (мультивыбор) и
подразделение/проект вакансии
- Поле «Подразделение» (справочник) — Vacation, UnpaidLeave, Clearance,
WorkplaceSetup, RecruitingHire, RecruitingSelection, TmcTransfer
- Поле «Проект» — Vacation, UnpaidLeave, Clearance
Обсуждение заявки поверх штатных комментариев SharePoint (PnPjs
item.comments) — без новых колонок и провижининга, права на переписку
раздаёт сам SharePoint по правам на элемент.
Встроено в ApproveFeature и EditFeature (единственные входы в просмотр
заявки для всех типов), поэтому доступно автору, всем согласующим
(включая уже решивших и ещё не дошедших до своего шага) и исполнителям,
а не только текущему шагу маршрута, как DecisionPanel.
Автора комментария всегда ставит реальная учётка — отладочная подмена
личности на запись в SharePoint не влияет, в UI есть предупреждение.
---------
Co-authored-by: gorbenko.pavel <gorbenko.pavel@tansu.kz>
Reviewed-on: http://git.tnsu.kz/timur.gorodetskiy/request-portal/pulls/14