2d2194047b
Четыре независимых доработки поверх связки «Заявление на увольнение» ↔ «Обходной лист»: 1. Совместители (несколько компаний у одного сотрудника): approval-route уже резолвит директора/должностного эквивалента КАЖДОЙ компании отдельным шагом маршрута (HeadType.CompanyDirectors, шаблон route 17: Chief → CompanyDirectors). Organization на форме подачи заявления теперь интерактивная таблица (OrganizationsTable) вместо read-only списка — строку компании можно убрать, если сотрудник реально не увольняется отовсюду сразу; убранная компания сразу снимается и из уже спланированной матрицы (matrix.remove) — искать нужную строку вручную не надо. Новый shared/dictionary/employeeLookup.service.ts зеркалит DirectorPositionByCompany бэкенда (KazpromService → Главный механик, СТ Global → Генеральный директор, иначе Директор) и Employee/Manager (managerType=chief) — используется и здесь, и в следующем пункте. 2. Печать заявления заблокирована, пока парный обходной лист не согласован (статус читается напрямую по ClearanceUrl, без отдельного поля-дублёра). 3. «Лицо, принимающее ОС/НМА» (AssetsAcceptor, People) — обязательное поле, которое заполняет НЕ заявитель, а непосредственный руководитель увольняемого (identity-check по Employee/Manager, а не по должности, как в approverRights «Обходного листа») прямо перед своим решением (DecisionPanel.onBeforeDecide); пустое поле блокирует решение. 4. В обходном листе — 4 независимые пары «сумма к списанию + обязательный комментарий» (ОС/СИЗ/подотчёт, обучение, НМА, ТМЦ), отдельно от уже существующего TrainingAmount. Заполнить может любой активный согласующий (не только профильный), но как только сумма введена — пара блокируется навсегда для всех (лок по снимку на момент загрузки, не реактивно от текущего ввода — иначе поле блокировалось бы прямо во время набора цифр). Списки на /sites/requests обновлены: AssetsAcceptor (Заявление на увольнение), 8 колонок WriteOff* (Обходной лист). tsc --noEmit и heft test (build+lint+179 тестов) чистые. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
54 lines
6.7 KiB
Markdown
54 lines
6.7 KiB
Markdown
# Формы портала заявок — индекс
|
||
|
||
Каждая форма живёт в своей папке `src/webparts/requestPortal/forms/<Форма>/` и имеет
|
||
рядом **`README.md`** — карточку с её **бизнес-поведением** (то, что не видно из кода
|
||
с первого взгляда). Здесь — общий индекс.
|
||
|
||
## Правило (при добавлении формы)
|
||
1. Папка `forms/<Форма>/` + `README.md` по [шаблону](./form-readme-template.md).
|
||
2. Строка в индексе ниже.
|
||
3. Строка в `forms/registry.ts` (ленивая форма) и, если есть режим согласующего,
|
||
в `forms/viewRegistry.ts`.
|
||
4. Плитка в `data/requests.ts`.
|
||
|
||
## Формы больше не хардкодят RequestTypeId
|
||
Числовой id типа заявки во внешнем approval-route API (`GET /api/request-types`)
|
||
выдаётся сервером при регистрации типа в админке и непредсказуем заранее (в
|
||
старой pto-tracker у «отпуска» было 1, при заведении типа в новой админке он
|
||
получил id 11). Раньше каждая форма хардкодила это число константой вида
|
||
`VACATION_REQUEST_TYPE_ID = 11`; теперь — резолвит его в рантайме по своему
|
||
`pageUrl` (тот же rptype, что и `id` в `data/requests.ts`) через
|
||
`useRequestTypeId(context, pageUrl)` (`shared/approval`). Результат кешируется
|
||
на уровне модуля на время сессии (см. `getRequestTypeIdByPageUrl` в
|
||
`approvalRoute.service.ts`) — повторный вызов из другой формы не бьёт по сети заново.
|
||
- Форма подачи знает свой `pageUrl` из пропа `requestType.id`.
|
||
- Режим согласующего (`<Форма>View`) получает его пропом `formKey` (см.
|
||
`IApprovalViewProps` в `forms/viewRegistry.ts` и `ApproveFeature.tsx`).
|
||
|
||
## Что НЕ дублируем в карточке (лежит в других местах)
|
||
- Колонки списков → `forms/<Форма>/provisioning.json`.
|
||
- Параметры ссылок (rptype/rpmode/rpid/rpsource) → [`routing.md`](./routing.md).
|
||
- Как обращаться к спискам SP из кода → [`sp-lists-frontend.md`](./sp-lists-frontend.md).
|
||
- Общий жизненный цикл (черновик/upsert/блокировка/статусы), согласование, исполнение,
|
||
печать — **одинаковы для всех форм** (общие примитивы `shared/ui` и `shared/approval`).
|
||
|
||
Карточка — только про то, чем **эта** форма отличается.
|
||
|
||
---
|
||
|
||
## Индекс форм
|
||
|
||
| Ключ (rptype) | Форма | Категория | Согл. | Исп. | Просмотр | Фишки | Готово |
|
||
| --- | --- | --- | :---: | :---: | :---: | --- | :---: |
|
||
| [`recruiting-selection`](../src/webparts/requestPortal/forms/RecruitingSelection/README.md) | Заявка на подбор | Рекрутинг | нет | нет | нет | много полей (~42), поля-люди (в т.ч. мульти) | ✅ |
|
||
| [`recruiting-hire`](../src/webparts/requestPortal/forms/RecruitingHire/README.md) | Заявка на прием | Рекрутинг | да | да | да | маска телефона, деньги, условное «взамен кого», источник для орг. места | ✅ |
|
||
| [`recruiting-referral`](../src/webparts/requestPortal/forms/Referral/README.md) | Реферальная рекомендация | Рекрутинг | да | да | да | кандидат — внешний (текстовые поля, не People); маршрут по рекомендателю; исполнитель переназначает на реального; условное уточнение «откуда знаете» | ✅ |
|
||
| [`it-workplace-setup`](../src/webparts/requestPortal/forms/WorkplaceSetup/README.md) | Организация рабочего места | IT | да | да | да | префилл из «прием», поля ПО/доступы правит руководитель | ✅ |
|
||
| [`it-1c-ticket`](../src/webparts/requestPortal/forms/Ticket1C/README.md) | Заявка в отдел 1С | IT | да | нет | да | контакты предзаполняются из Graph (/me); вместо фазы исполнения — карточка в Microsoft Planner (согласовано/сразу без согласования — рабочий бакет, отклонено — отдельный бакет) | ✅ |
|
||
| [`clearance-form`](../src/webparts/requestPortal/forms/Clearance/README.md) | Обходной лист | Отдел кадров | да | нет | да | подаётся HR за увольняемого (People-picker) либо создаётся сам по согласованному «Заявлению на увольнение»; условие «IsManager» резолвится по должности из самой заявки; да/нет-поля (парковка, СКУД); 4 независимые пары «сумма к списанию + комментарий» (ОС/СИЗ/подотчёт, обучение, НМА, ТМЦ) — вводит любой активный согласующий, блокируется навсегда после первого ввода | ✅ |
|
||
| [`hr-dismissal`](../src/webparts/requestPortal/forms/Dismissal/README.md) | Заявление на увольнение | Отдел кадров | да | нет | да | совместители — таблица компаний с удалением строки (снимает и согласующего из матрицы); должность/организация из справочника; **после согласования сам создаёт обходной лист**; печать заблокирована до согласования обходного листа; «Лицо, принимающее ОС/НМА» — заполняет только непосредственный руководитель | ✅ |
|
||
| `hr-transfer` | Перемещение сотрудников | Отдел кадров | — | — | — | — | ⏳ заглушка (плитка есть, форма не сделана) |
|
||
|
||
Легенда: **Согл.** — есть фаза согласования; **Исп.** — есть фаза исполнения;
|
||
**Просмотр** — есть режим согласующего (`<Форма>View`).
|