Прибытие в любую точку маршрута — не раньше сегодняшнего дня: прошедшие дни
закрыты в календаре, а набранная вручную или устаревшая в черновике дата
подсвечивается при отправке (черновик сохраняется). «Сегодня» передаётся в
submitIssues параметром — тесты не зависят от текущей даты.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
По просьбе кадров. Иконка — local_taxi (машина с шашкой), чтобы такси
отличалось от служебного и личного автотранспорта.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Город отправления и города точек выбираются из справочника КАТО; в маршруте
хранятся оба названия и код (city/cityKz/cityKato, origin/originKz/originKato
внутри TripRouteJson — новых колонок нет). Везде, включая TripCity/TripRoute и
заголовок, город показывается как «Кульсары (Құлсары)». Введённый вручную
город (село, заграница) сохраняется текстом. README дополнен и описанием
командирующей организации.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Города и посёлки РК (178) из официального КАТО stat.gov.kz — на русском и
казахском, с кодом и областью. Справочник генерируется скриптом
scripts/Build-KatoCities.ps1 и лежит на фронте: внешних API и ключей не нужно.
CityPicker ищет по обоим языкам с учётом раскладки (Құлсары = Кулсары) и
оставляет свой вариант для сёл и заграницы.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Сотрудник может работать в нескольких компаниях, а командирует одна —
теперь её выбирают из организаций сотрудника (Employee/ByEmail), должность
подставляется из выбранной компании. Одна организация выбирается сама.
Выбор хранится в TripCompany + TripCompanyId (id — под будущий маршрут).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Пункт 4.5 — тот же выбор, что 5.6 в заявке на подбор, с «Другое» и ручным
вводом; подставляется из связанного подбора и обязателен для отправки.
Колонка сайта WorkHours общая с подбором (тот же тип, заголовок и варианты),
в список приёма её подключает провизионинг — до деплоя, иначе заявка не
сохранится. «Сдельная оплата труда» сдвинута на 4.6.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Оплачиваемый отпуск и отпуск без сохранения з/п добавлены в UNFROZEN_FORMS:
сохранять черновик и отправлять их теперь могут все, а не только группа
«Тестирование». Формы начали передавать formId в SubmitActions — без него
точечное снятие заморозки не срабатывало.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Проверки обязательных полей вынесены в validation.ts и показываются под
полями через FieldIssuesProvider, как в приёме, подборе и отпуске: форма
прокручивается к первому полю, над кнопками — кликабельный список.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
При виде работ «Дата запрета (открытие/закрытие)» и выбранной базе АТП
остальные базы снимаются и добавить их нельзя — дата запрета по АТП
открывается/закрывается отдельно. Над полем «База 1С» при этом виде работ
показывается предупреждение.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
LeavePrintNotice заменён общим LeaveNotice с заголовком и пунктами из model.ts
каждой формы: в отпуске — примечание HR (ст. 92 ТК РК, срок подачи, подписание
в отделе кадров), в отпуске без содержания — прежняя памятка про печать.
Проверки отпуска вынесены в validation.ts и показываются под полями через
FieldIssuesProvider, как в приёме и подборе.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Кадровый сотрудник и исполнитель в этих маршрутах зависят от компании
сотрудника (Ольга Кудрящова и Айнур — Тансу/КПС/CT, Мольдир Хамит —
остальные), но формы не передавали организацию в расчёт маршрута, и
условные шаги в админке не срабатывали. Теперь названия компаний из поля
«Организация» (Employee/ByEmail) уходят как Organization через пробел — и в
согласование, и в исполнителей; маршрут пересчитывается, когда организация
подгрузится. Общий хелпер — shared/dictionary/organizationRouteFields.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
guard пропускает GetClientSideComponents (без него страница не грузит
SPFx), probe с --local-build запускает Chromium без проверок Local Network
Access, которые режут загрузку https://localhost:4321 с SharePoint.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Сбор условий маршрута (вид работ, база 1С, отдел) и запрос маршрута с
схлопыванием повторов переехали из формы в planRoute.ts. Поведение формы
не меняется; функцию сможет использовать страница «Проверка маршрутов»,
чтобы проверять ровно тот маршрут, что видит заявитель.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
## Что сделано
**Чат заявки: отметки и оповещения**
- В поле ввода «@» открывает подсказку с участниками заявки: инициатор, согласующие и исполнители из маршрута, а также те, кому открыты «Все заявки» этого типа (список из request-type-access).
- Отметка — обычный текст «@ФИО», без штатного упоминания SharePoint, чтобы не уходило его письмо.
- После отправки сообщения портал вызывает поток Power Automate (`FLOW_CHAT_NOTIFY_URL`): отмеченным — «Вас упомянули», инициатору — «Новое сообщение по вашей заявке». Сбой потока не мешает отправке.
- В письмо добавляется строка «Прикреплены файлы: …», чтобы сообщение из одного файла не приходило пустым.
- Свойство веб-части «Чат: уведомлять о своих сообщениях (для теста)», по умолчанию выключено: письма и о своих сообщениях, можно отметить себя.
- Когда пишет сам инициатор с отметками, в `initiatorEmail` уходит первый отмеченный — поток шлёт инициатору всегда, если его нет среди отмеченных, и иначе он получил бы письмо о своём же сообщении.
**Чат включён для:** Обходной лист, заявка на подбор, заявка на приём, заявка в отдел 1С.
**Исправление:** редактор маршрута может удалять исполнителей в Обходном листе, Командировке и заявке в 1С (не передавалось `canRemoveRow`).
**Прочее:** убраны 4 предупреждения линтера (`no-new-null`, `no-script-url`).
## Не проверено на тенанте
- Ответ потока 200 через AadHttpClient и доставка писем.
- Права согласующих на комментарии и на запись в библиотеку «Файлы чата».
- Папки в «Файлы чата» наследуют права библиотеки, а не закрыты на заявку — для подбора и приёма это важно решить до выкладки.
- Если поток вставляет `messageText` в HTML-письмо, перенос строки перед «Прикреплены файлы» может не отобразиться.
---------
Co-authored-by: gorbenko.pavel <gorbenko.pavel@tansu.kz>
Reviewed-on: http://git.tnsu.kz/timur.gorodetskiy/request-portal/pulls/26
База 1С — мультивыбор, поэтому на одном шаге могут сработать сразу
несколько строк матрицы с одним исполнителем (Гульжан и за ЗУП, и за
АТП от финдепа). Он получал бы два уведомления и решал шаг дважды.
Запланированный маршрут теперь оставляет одну строку на человека в
пределах шага; один человек на разных шагах не схлопывается.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Новая матрица маршрута #8 назначает согласующих по выбранной базе
(ЗУП, АТП, ATS), а форма передавала в approval-route только вид работ
и отдел — такие шаги никогда не срабатывали. Теперь DB1C уходит в
fieldValues одной строкой через пробел (мультивыбор, value у API
только строка), и маршрут пересчитывается при смене набора баз.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Раньше дата выхода показывалась только во «Все заявки». Теперь — в любом
разделе (Мои заявки, очереди), когда фильтр по типу оставляет только заявки
на организацию рабочего места.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
После согласования заявление нужно распечатать, подписать и сдать в
отдел кадров — напоминаем об этом в трудовом отпуске и отпуске без
содержания (подача и просмотр). Общий компонент LeavePrintNotice,
на печать не выводится.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Требование HR: ограничение на поле «Количество дней» и проверка при
отправке с понятным сообщением.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
5 дней работодатель обязан дать только при браке/рождении/смерти,
сверх — по договорённости, поэтому форма больше не ограничивает число
дней. Вариант «В иных случаях» подписан как «Иная причина» — читается
как ответ на «Причина»; значение в SP прежнее.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
По просьбе заказчика примечание при отметке «Согласован СБ» больше не
требуется для отправки: поле по-прежнему появляется только при отметке,
но его можно оставить пустым.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Пункт 4.5 в «Условиях оплаты и оформления» — информационная отметка, на
обязательность окладов не влияет. Та же колонка сайта PieceworkPay
(Boolean), что в заявке на подбор, и оттуда же подставляется при связи с
подбором (поле 1.1 и «Оформить приём по этой заявке»).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Просили создавать заявку на приём из самого подбора, а не искать его в
поле 1.1. Под вложениями согласованного подбора — «+ Оформить приём по этой
заявке» со счётчиком «занято X из Y» (и предупреждением, если вакансии
заняты). Новая заявка на приём сразу связана с подбором и заполнена из
него: логика вынесена в selectionPrefill и общая с полем 1.1. Вместе с
rpsource в адресе передаётся партиция подбора (rplist): Id в партициях
повторяются. Приёмы по подбору грузятся один раз на оба блока (useLinkedHires).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Инициатор при подаче отмечает, что кандидат согласован со службой
безопасности; при отметке обязательно примечание СБ (без отметки поле
скрыто и очищается). Поле информационное, на маршрут не влияет. Раздел
«6. Служба безопасности» — перед вложениями, «Примечание для согласующих»
стало разделом 7. Колонки HireSecurityApproved (Boolean), HireSecurityNote (Note).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Search искал заявки подменённого сотрудника, а REST-довесок свежих
черновиков — заявки реальной учётки, поэтому только что созданные
черновики под подменой не находились нигде. Довесок теперь берёт Id
подменённого сотрудника.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Суточные в смете строятся автоматически по точкам и датам маршрута
(в МРП), чтобы инициатор не пересчитывал их вручную; проверки и
сохранение работают с уже пересчитанной сметой. Форма командировки
заодно подключена к перепланированию маршрута пустого черновика.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
У части черновиков не оказалось строк маршрута, и форма показывала пустую
матрицу: отправить такую заявку было некому. Теперь при открытии
черновика без строк маршрут планируется заново (loadRoutePhase), во всех
формах; поданные заявки по-прежнему читают записанные строки. Почему
строки пропали у первоначального случая — пока не выяснено.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Зависимости и навык spfx-qa для проверки портала в браузере (сценарии,
снимки, проверка доступности). Каталоги сессии и отчётов (.auth/,
.qa-reports/) — в .gitignore.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Алтынай Бултурукова (право canEditRoute) просила добавлять участников в уже
поданный маршрут. Новый согласующий или исполнитель встаёт в конец своего
этапа со статусом «Ждёт очереди» (дальше его можно поднять стрелками);
согласующего — пока идёт согласование, исполнителя — пока не завершено
исполнение, без дублей среди ещё не решивших. Заявка «трогается», чтобы
бэкенд выдал новому участнику права на элемент данных.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
По одной дате не различить несколько заявок, поданных в один день, —
теперь в столбце дата и время создания.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
По дате выхода удобнее планировать подготовку рабочих мест. Даты для
сортировки дочитываются для всего списка пачками (предел длины URL),
заявки без даты — всегда в конце.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Столбец «Исполнитель» показывает только текущего держателя, и было не видно,
кто из исполнителей уже отметил «Выполнено». Теперь видно ФИО и время
каждой отметки; столбец появляется, только если на странице есть такие.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Очередь не двигалась, пока на шаге был кто-то активный, поэтому делегат
участника параллельного шага ждал решения второго участника. Текущий шаг
теперь — наименьший order среди нерешённых строк.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Письмо уходило только первому из параллельных согласующих, а после решения
одного из них остальные получали повторное. Теперь шаг оповещается целиком
при старте и не оповещается снова, если кто-то из его участников уже решил.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
filtersStorage импортировал статусы из барреля shared/approval, а тот тянет
@microsoft/sp-http, который в Jest не грузится. Импорт — напрямую из
models/statuses, тип IRequestType — через import type.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Пользователи жаловались, что фильтры постоянно сбрасываются. Тип, статус,
период и сортировка теперь хранятся в localStorage — отдельно на каждого
пользователя и таблицу, с проверкой значений при чтении. Чтобы забытый
фильтр не выглядел как «пропали заявки», над таблицей строка «Включены
фильтры» с чипами, «Сбросить все» (чистит и хранилище) и «Показано X из Y».
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Инициатор пишет примечание, уже заполнив заявку, и сразу видит под ним,
кому оно уйдёт. В просмотре согласующего порядок тот же; плашка вверху
карточки не меняется.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Инициатору нужно передать согласующим важную информацию так, чтобы её не
пропустили. Новый раздел «6. Примечание для согласующих» (текст + «Важное»);
у согласующих и исполнителей заполненное примечание показывается плашкой
над разделами заявки, важное выделено цветом и иконкой. Сделано общим
модулем shared/approverNote, чтобы подключать в другие формы. Колонки
HireApproverNote (Note) и HireApproverNoteImportant (Boolean).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Старый одиночный пикер допускал ручной ввод без выбора из справочника
(пустой ProjectId). Такие заявки открывались с пустым полем «Проект», а
пересохранение (правка всех полей согласующим) стирало текст проекта в
колонке Project. Теперь он читается как проект без Id и сохраняется как есть.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Проект больше не влияет на маршрут (условие по Project убрано в админке),
поэтому поле стало мультивыбором (ProjectPickerMulti). Список хранится в
новой колонке ProjectsJson; старые Project/ProjectId/ProjectCode заполняются
производными значениями для представлений и отчётов, старые заявки читаются
из них. Title и текстовые колонки обрезаются до 255 символов, чтобы длинные
названия не роняли сохранение. Требует провижининга колонки ProjectsJson.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Алтынай Бултурукова (право canEditRoute) просила менять порядок участников
уже поданной заявки. Стрелки у шагов согласования и исполнения: меняются
местами только соседние шаги одной фазы, оба «Ждут очереди» — активный и
пройденные шаги не трогаются, поэтому никто не теряет заявку и оповещать
некого. Строки перечитываются перед записью, StepOrder пишется одним батчем.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Кнопка отправки гасла без объяснения, если, например, указано больше 5 дней.
Форма переходит на общий FieldIssuesProvider: над кнопками список проблем,
по нажатию — подсветка поля с текстом ошибки и прокрутка к нему. Правила
вынесены в validation.ts.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Вместо свободного «В связи с» — обязательный выбор причины (брак, рождение
ребёнка, смерть близких, иные случаи); текст причины нужен только для иных
случаев. Отпуск — не более 5 календарных дней. Подавать за 14 дней нужно
только в иных случаях: остальные события заранее не планируются.
Причина хранится в новой Choice-колонке UnpaidLeaveReasonType.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Отдел кадров переименовал заявки: «Заявление на оплачиваемый ежегодный
трудовой отпуск» и «Заявление на отпуск без сохранения заработной платы».
Меняются плитки и заголовки карточек; имена списков SharePoint и pageUrl
остаются прежними, чтобы не потерять связь с существующими списками.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Отдел 1С передаёт заявки внутри себя: исполнитель с невыполненным шагом
может в поданной заявке заменить или убрать невыполненного исполнителя,
в т.ч. активного и себя. Выполненные шаги не трогаются, последнего
невыполненного — только заменить. Механизм тот же, что в подборе, но
право по роли в маршруте, а не по списку email.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>