From 179999c02a6c23e527e5e955d1528d9ac4fe7cfb Mon Sep 17 00:00:00 2001 From: "gorbenko.pavel" Date: Tue, 25 Aug 2026 17:20:26 +0500 Subject: [PATCH] =?UTF-8?q?feat:=20=D0=9E=D0=A1,=20=D0=A1=D0=98=D0=97=20?= =?UTF-8?q?=D0=B8=20=D0=BF=D0=BE=D0=B4=D0=BE=D1=82=D1=87=D1=91=D1=82=D0=BD?= =?UTF-8?q?=D0=B0=D1=8F=20=D1=81=D1=83=D0=BC=D0=BC=D0=B0=20=E2=80=94=20?= =?UTF-8?q?=D0=BE=D1=82=D0=B4=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B=D0=B5=20=D1=81?= =?UTF-8?q?=D1=83=D0=BC=D0=BC=D1=8B=20=D0=BA=20=D1=81=D0=BF=D0=B8=D1=81?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Было одной парой «ОС/СИЗ/подотчётная сумма» — стало тремя независимыми, всего 6 категорий (ОС, СИЗ, подотчётная сумма, обучение, НМА, ТМЦ). Списывают их разные подразделения и за разное, поэтому и сумма с комментарием у каждой своя, и блокируется каждая отдельно (правило «введено — больше не меняется» работает на пару, а не на весь блок). Существующая колонка WriteOffAssetsAmount/Comment переиспользована под «ОС» (данных по ней ещё нет), добавлены WriteOffPpe* и WriteOffAccountable*. Список типов полей теперь выводится из WriteOffFieldKey — IWriteOffFields в submit.ts больше не дублирует их перечислением. На тенанте: 4 новые колонки созданы провижинером; отображаемые имена ОС-пары досинхронизированы отдельно — Provision-Lists.ps1 колонки только СОЗДАЁТ и переименование в манифесте существующей колонке не применяет. Co-Authored-By: Claude Opus 5 --- docs/forms.md | 2 +- .../requestPortal/forms/Clearance/README.md | 6 ++-- .../requestPortal/forms/Clearance/load.ts | 8 ++++++ .../requestPortal/forms/Clearance/model.ts | 28 ++++++++++++++----- .../forms/Clearance/provisioning.json | 8 ++++-- .../Clearance/sections/RequestSection.tsx | 2 +- .../requestPortal/forms/Clearance/submit.ts | 16 ++--------- 7 files changed, 43 insertions(+), 27 deletions(-) diff --git a/docs/forms.md b/docs/forms.md index 370d402..d09ca26 100644 --- a/docs/forms.md +++ b/docs/forms.md @@ -45,7 +45,7 @@ | [`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 независимые пары «сумма к списанию + комментарий» (ОС/СИЗ/подотчёт, обучение, НМА, ТМЦ) — вводит любой активный согласующий, блокируется навсегда после первого ввода | ✅ | +| [`clearance-form`](../src/webparts/requestPortal/forms/Clearance/README.md) | Обходной лист | Отдел кадров | да | нет | да | подаётся HR за увольняемого (People-picker) либо создаётся сам по согласованному «Заявлению на увольнение»; условие «IsManager» резолвится по должности из самой заявки; да/нет-поля (парковка, СКУД); 6 независимых пар «сумма к списанию + комментарий» (ОС, СИЗ, подотчётная сумма, обучение, НМА, ТМЦ) — вводит любой активный согласующий, блокируется навсегда после первого ввода | ✅ | | [`hr-dismissal`](../src/webparts/requestPortal/forms/Dismissal/README.md) | Заявление на увольнение | Отдел кадров | да | нет | да | совместители — таблица компаний с удалением строки (снимает и согласующего из матрицы); должность/организация из справочника; **после согласования сам создаёт обходной лист**; печать заблокирована до согласования обходного листа; «Лицо, принимающее ОС/НМА» — заполняет только непосредственный руководитель | ✅ | | `hr-transfer` | Перемещение сотрудников | Отдел кадров | — | — | — | — | ⏳ заглушка (плитка есть, форма не сделана) | diff --git a/src/webparts/requestPortal/forms/Clearance/README.md b/src/webparts/requestPortal/forms/Clearance/README.md index 351ddaa..e943790 100644 --- a/src/webparts/requestPortal/forms/Clearance/README.md +++ b/src/webparts/requestPortal/forms/Clearance/README.md @@ -55,9 +55,9 @@ RequestTypeId» в `docs/forms.md`). Тип уже зарегистрирова заведённых руками, ссылки нет и поле не рендерится. ## Суммы к списанию (согласование) -4 НЕЗАВИСИМЫЕ пары «сумма + обязательный комментарий (за что конкретно)», колонки -`WriteOff{Assets,Training,Nma,Tmc}{Amount,Comment}` (см. `model.ts -WRITE_OFF_CATEGORIES`): «ОС / СИЗ / подотчётная сумма», «Обучение», «НМА», «ТМЦ». +6 НЕЗАВИСИМЫХ пар «сумма + обязательный комментарий (за что конкретно)», колонки +`WriteOff{Assets,Ppe,Accountable,Training,Nma,Tmc}{Amount,Comment}` (см. `model.ts +WRITE_OFF_CATEGORIES`): «ОС», «СИЗ», «Подотчётная сумма», «Обучение», «НМА», «ТМЦ». - **Не привязаны к должности**, в отличие от отметок выше: заполнить может ЛЮБОЙ согласующий, у которого сейчас активный шаг (`ClearanceView.canEditWriteOffs`, diff --git a/src/webparts/requestPortal/forms/Clearance/load.ts b/src/webparts/requestPortal/forms/Clearance/load.ts index f9a21d7..8e95326 100644 --- a/src/webparts/requestPortal/forms/Clearance/load.ts +++ b/src/webparts/requestPortal/forms/Clearance/load.ts @@ -40,6 +40,10 @@ export async function loadClearanceRequest(itemId: number, listId?: string): Pro 'DismissalUrl', 'WriteOffAssetsAmount', 'WriteOffAssetsComment', + 'WriteOffPpeAmount', + 'WriteOffPpeComment', + 'WriteOffAccountableAmount', + 'WriteOffAccountableComment', 'WriteOffTrainingAmount', 'WriteOffTrainingComment', 'WriteOffNmaAmount', @@ -71,6 +75,10 @@ export async function loadClearanceRequest(itemId: number, listId?: string): Pro DismissalUrl: (item.DismissalUrl as { Url?: string } | undefined)?.Url || '', WriteOffAssetsAmount: numberField(item.WriteOffAssetsAmount), WriteOffAssetsComment: (item.WriteOffAssetsComment as string) || '', + WriteOffPpeAmount: numberField(item.WriteOffPpeAmount), + WriteOffPpeComment: (item.WriteOffPpeComment as string) || '', + WriteOffAccountableAmount: numberField(item.WriteOffAccountableAmount), + WriteOffAccountableComment: (item.WriteOffAccountableComment as string) || '', WriteOffTrainingAmount: numberField(item.WriteOffTrainingAmount), WriteOffTrainingComment: (item.WriteOffTrainingComment as string) || '', WriteOffNmaAmount: numberField(item.WriteOffNmaAmount), diff --git a/src/webparts/requestPortal/forms/Clearance/model.ts b/src/webparts/requestPortal/forms/Clearance/model.ts index 9a9f937..2270ba0 100644 --- a/src/webparts/requestPortal/forms/Clearance/model.ts +++ b/src/webparts/requestPortal/forms/Clearance/model.ts @@ -39,7 +39,7 @@ export interface IFormData { DismissalUrl: string; /** - * Суммы к списанию по обходному листу — 4 независимые пары (сумма + + * Суммы к списанию по обходному листу — 6 независимых пар (сумма + * обязательный комментарий, «за что конкретно»), см. WRITE_OFF_CATEGORIES. * «Сырые» цифры без пробелов, как TrainingAmount (см. MoneyInput). Пусто = * не заполнено. КАЖДАЯ пара — независимая: заполнить может любой активный @@ -49,6 +49,10 @@ export interface IFormData { */ WriteOffAssetsAmount: string; WriteOffAssetsComment: string; + WriteOffPpeAmount: string; + WriteOffPpeComment: string; + WriteOffAccountableAmount: string; + WriteOffAccountableComment: string; WriteOffTrainingAmount: string; WriteOffTrainingComment: string; WriteOffNmaAmount: string; @@ -57,10 +61,14 @@ export interface IFormData { WriteOffTmcComment: string; } -/** Имена всех 8 строковых полей сумм/комментариев к списанию — см. IFormData.WriteOff*. */ +/** Имена всех 12 строковых полей сумм/комментариев к списанию — см. IFormData.WriteOff*. */ export type WriteOffFieldKey = | 'WriteOffAssetsAmount' | 'WriteOffAssetsComment' + | 'WriteOffPpeAmount' + | 'WriteOffPpeComment' + | 'WriteOffAccountableAmount' + | 'WriteOffAccountableComment' | 'WriteOffTrainingAmount' | 'WriteOffTrainingComment' | 'WriteOffNmaAmount' @@ -69,7 +77,7 @@ export type WriteOffFieldKey = | 'WriteOffTmcComment'; /** - * Одна из 4 независимых категорий списания — см. IFormData.WriteOff*. + * Одна из 6 независимых категорий списания — см. IFormData.WriteOff*. * amountField/commentField сужены до WriteOffFieldKey (а не keyof IFormData * целиком): у IFormData есть и булевы поля (ParkingCard/AccessCard), и * `data[cat.amountField]` должен типизироваться строго строкой — иначе @@ -83,11 +91,13 @@ export interface IWriteOffCategory { } export const WRITE_OFF_CATEGORIES: IWriteOffCategory[] = [ + { key: 'assets', label: 'ОС', amountField: 'WriteOffAssetsAmount', commentField: 'WriteOffAssetsComment' }, + { key: 'ppe', label: 'СИЗ', amountField: 'WriteOffPpeAmount', commentField: 'WriteOffPpeComment' }, { - key: 'assets', - label: 'ОС / СИЗ / подотчётная сумма', - amountField: 'WriteOffAssetsAmount', - commentField: 'WriteOffAssetsComment' + key: 'accountable', + label: 'Подотчётная сумма', + amountField: 'WriteOffAccountableAmount', + commentField: 'WriteOffAccountableComment' }, { key: 'training', @@ -126,6 +136,10 @@ export const EMPTY_DATA: IFormData = { DismissalUrl: '', WriteOffAssetsAmount: '', WriteOffAssetsComment: '', + WriteOffPpeAmount: '', + WriteOffPpeComment: '', + WriteOffAccountableAmount: '', + WriteOffAccountableComment: '', WriteOffTrainingAmount: '', WriteOffTrainingComment: '', WriteOffNmaAmount: '', diff --git a/src/webparts/requestPortal/forms/Clearance/provisioning.json b/src/webparts/requestPortal/forms/Clearance/provisioning.json index 98d33de..964aaea 100644 --- a/src/webparts/requestPortal/forms/Clearance/provisioning.json +++ b/src/webparts/requestPortal/forms/Clearance/provisioning.json @@ -16,8 +16,12 @@ { "internalName": "DismissalUrl", "title": "Ссылка на заявление на увольнение", "type": "Url" }, - { "internalName": "WriteOffAssetsAmount", "title": "Сумма к списанию: ОС/СИЗ/подотчёт", "type": "Number", "decimals": 2 }, - { "internalName": "WriteOffAssetsComment", "title": "Комментарий: ОС/СИЗ/подотчёт", "type": "Note" }, + { "internalName": "WriteOffAssetsAmount", "title": "Сумма к списанию: ОС", "type": "Number", "decimals": 2 }, + { "internalName": "WriteOffAssetsComment", "title": "Комментарий: ОС", "type": "Note" }, + { "internalName": "WriteOffPpeAmount", "title": "Сумма к списанию: СИЗ", "type": "Number", "decimals": 2 }, + { "internalName": "WriteOffPpeComment", "title": "Комментарий: СИЗ", "type": "Note" }, + { "internalName": "WriteOffAccountableAmount", "title": "Сумма к списанию: подотчётная сумма", "type": "Number", "decimals": 2 }, + { "internalName": "WriteOffAccountableComment", "title": "Комментарий: подотчётная сумма", "type": "Note" }, { "internalName": "WriteOffTrainingAmount", "title": "Сумма к списанию: обучение", "type": "Number", "decimals": 2 }, { "internalName": "WriteOffTrainingComment", "title": "Комментарий: обучение", "type": "Note" }, { "internalName": "WriteOffNmaAmount", "title": "Сумма к списанию: НМА", "type": "Number", "decimals": 2 }, diff --git a/src/webparts/requestPortal/forms/Clearance/sections/RequestSection.tsx b/src/webparts/requestPortal/forms/Clearance/sections/RequestSection.tsx index cf44b89..e8d33e2 100644 --- a/src/webparts/requestPortal/forms/Clearance/sections/RequestSection.tsx +++ b/src/webparts/requestPortal/forms/Clearance/sections/RequestSection.tsx @@ -98,7 +98,7 @@ export const RequestSection: React.FC = ({ readOnly={hrRecordsEditable ? false : undefined} /> - {/* Суммы к списанию — 4 независимые пары (сумма + обязательный комментарий, + {/* Суммы к списанию — 6 независимых пар (сумма + обязательный комментарий, за что конкретно). Каждую может заполнить ЛЮБОЙ активный согласующий (не только профильный, в отличие от отметок выше) — но как только сумма указана, пара блокируется навсегда для всех, поэтому у незаблокированных diff --git a/src/webparts/requestPortal/forms/Clearance/submit.ts b/src/webparts/requestPortal/forms/Clearance/submit.ts index 71723f1..2e4c73b 100644 --- a/src/webparts/requestPortal/forms/Clearance/submit.ts +++ b/src/webparts/requestPortal/forms/Clearance/submit.ts @@ -1,20 +1,10 @@ import { ApprovalListService, IApproverToWrite, approvalServiceFor, writeRoute } from '../../shared/approval'; import { ISaveItemResult, resolveDataList, saveRequestItem } from '../../shared/dataList'; import { ensureEmployee } from '../../shared/employee'; -import { FORM_ID, IFormData } from './model'; +import { FORM_ID, IFormData, WriteOffFieldKey } from './model'; -/** Одна из 8 колонок сумм/комментариев к списанию — см. model.ts WRITE_OFF_CATEGORIES. */ -export type IWriteOffFields = Pick< - IFormData, - | 'WriteOffAssetsAmount' - | 'WriteOffAssetsComment' - | 'WriteOffTrainingAmount' - | 'WriteOffTrainingComment' - | 'WriteOffNmaAmount' - | 'WriteOffNmaComment' - | 'WriteOffTmcAmount' - | 'WriteOffTmcComment' ->; +/** Одна из 12 колонок сумм/комментариев к списанию — см. model.ts WRITE_OFF_CATEGORIES. */ +export type IWriteOffFields = Pick; /** * Записать сумму(ы)/комментарий(и) к списанию. Пишет РОВНО переданные поля —