feat: ОС, СИЗ и подотчётная сумма — отдельные суммы к списанию
Было одной парой «ОС/СИЗ/подотчётная сумма» — стало тремя независимыми, всего 6 категорий (ОС, СИЗ, подотчётная сумма, обучение, НМА, ТМЦ). Списывают их разные подразделения и за разное, поэтому и сумма с комментарием у каждой своя, и блокируется каждая отдельно (правило «введено — больше не меняется» работает на пару, а не на весь блок). Существующая колонка WriteOffAssetsAmount/Comment переиспользована под «ОС» (данных по ней ещё нет), добавлены WriteOffPpe* и WriteOffAccountable*. Список типов полей теперь выводится из WriteOffFieldKey — IWriteOffFields в submit.ts больше не дублирует их перечислением. На тенанте: 4 новые колонки созданы провижинером; отображаемые имена ОС-пары досинхронизированы отдельно — Provision-Lists.ps1 колонки только СОЗДАЁТ и переименование в манифесте существующей колонке не применяет. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+1
-1
@@ -45,7 +45,7 @@
|
|||||||
| [`recruiting-referral`](../src/webparts/requestPortal/forms/Referral/README.md) | Реферальная рекомендация | Рекрутинг | да | да | да | кандидат — внешний (текстовые поля, не People); маршрут по рекомендателю; исполнитель переназначает на реального; условное уточнение «откуда знаете» | ✅ |
|
| [`recruiting-referral`](../src/webparts/requestPortal/forms/Referral/README.md) | Реферальная рекомендация | Рекрутинг | да | да | да | кандидат — внешний (текстовые поля, не People); маршрут по рекомендателю; исполнитель переназначает на реального; условное уточнение «откуда знаете» | ✅ |
|
||||||
| [`it-workplace-setup`](../src/webparts/requestPortal/forms/WorkplaceSetup/README.md) | Организация рабочего места | IT | да | да | да | префилл из «прием», поля ПО/доступы правит руководитель | ✅ |
|
| [`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 (согласовано/сразу без согласования — рабочий бакет, отклонено — отдельный бакет) | ✅ |
|
| [`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-dismissal`](../src/webparts/requestPortal/forms/Dismissal/README.md) | Заявление на увольнение | Отдел кадров | да | нет | да | совместители — таблица компаний с удалением строки (снимает и согласующего из матрицы); должность/организация из справочника; **после согласования сам создаёт обходной лист**; печать заблокирована до согласования обходного листа; «Лицо, принимающее ОС/НМА» — заполняет только непосредственный руководитель | ✅ |
|
||||||
| `hr-transfer` | Перемещение сотрудников | Отдел кадров | — | — | — | — | ⏳ заглушка (плитка есть, форма не сделана) |
|
| `hr-transfer` | Перемещение сотрудников | Отдел кадров | — | — | — | — | ⏳ заглушка (плитка есть, форма не сделана) |
|
||||||
|
|
||||||
|
|||||||
@@ -55,9 +55,9 @@ RequestTypeId» в `docs/forms.md`). Тип уже зарегистрирова
|
|||||||
заведённых руками, ссылки нет и поле не рендерится.
|
заведённых руками, ссылки нет и поле не рендерится.
|
||||||
|
|
||||||
## Суммы к списанию (согласование)
|
## Суммы к списанию (согласование)
|
||||||
4 НЕЗАВИСИМЫЕ пары «сумма + обязательный комментарий (за что конкретно)», колонки
|
6 НЕЗАВИСИМЫХ пар «сумма + обязательный комментарий (за что конкретно)», колонки
|
||||||
`WriteOff{Assets,Training,Nma,Tmc}{Amount,Comment}` (см. `model.ts
|
`WriteOff{Assets,Ppe,Accountable,Training,Nma,Tmc}{Amount,Comment}` (см. `model.ts
|
||||||
WRITE_OFF_CATEGORIES`): «ОС / СИЗ / подотчётная сумма», «Обучение», «НМА», «ТМЦ».
|
WRITE_OFF_CATEGORIES`): «ОС», «СИЗ», «Подотчётная сумма», «Обучение», «НМА», «ТМЦ».
|
||||||
|
|
||||||
- **Не привязаны к должности**, в отличие от отметок выше: заполнить может ЛЮБОЙ
|
- **Не привязаны к должности**, в отличие от отметок выше: заполнить может ЛЮБОЙ
|
||||||
согласующий, у которого сейчас активный шаг (`ClearanceView.canEditWriteOffs`,
|
согласующий, у которого сейчас активный шаг (`ClearanceView.canEditWriteOffs`,
|
||||||
|
|||||||
@@ -40,6 +40,10 @@ export async function loadClearanceRequest(itemId: number, listId?: string): Pro
|
|||||||
'DismissalUrl',
|
'DismissalUrl',
|
||||||
'WriteOffAssetsAmount',
|
'WriteOffAssetsAmount',
|
||||||
'WriteOffAssetsComment',
|
'WriteOffAssetsComment',
|
||||||
|
'WriteOffPpeAmount',
|
||||||
|
'WriteOffPpeComment',
|
||||||
|
'WriteOffAccountableAmount',
|
||||||
|
'WriteOffAccountableComment',
|
||||||
'WriteOffTrainingAmount',
|
'WriteOffTrainingAmount',
|
||||||
'WriteOffTrainingComment',
|
'WriteOffTrainingComment',
|
||||||
'WriteOffNmaAmount',
|
'WriteOffNmaAmount',
|
||||||
@@ -71,6 +75,10 @@ export async function loadClearanceRequest(itemId: number, listId?: string): Pro
|
|||||||
DismissalUrl: (item.DismissalUrl as { Url?: string } | undefined)?.Url || '',
|
DismissalUrl: (item.DismissalUrl as { Url?: string } | undefined)?.Url || '',
|
||||||
WriteOffAssetsAmount: numberField(item.WriteOffAssetsAmount),
|
WriteOffAssetsAmount: numberField(item.WriteOffAssetsAmount),
|
||||||
WriteOffAssetsComment: (item.WriteOffAssetsComment as string) || '',
|
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),
|
WriteOffTrainingAmount: numberField(item.WriteOffTrainingAmount),
|
||||||
WriteOffTrainingComment: (item.WriteOffTrainingComment as string) || '',
|
WriteOffTrainingComment: (item.WriteOffTrainingComment as string) || '',
|
||||||
WriteOffNmaAmount: numberField(item.WriteOffNmaAmount),
|
WriteOffNmaAmount: numberField(item.WriteOffNmaAmount),
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ export interface IFormData {
|
|||||||
DismissalUrl: string;
|
DismissalUrl: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Суммы к списанию по обходному листу — 4 независимые пары (сумма +
|
* Суммы к списанию по обходному листу — 6 независимых пар (сумма +
|
||||||
* обязательный комментарий, «за что конкретно»), см. WRITE_OFF_CATEGORIES.
|
* обязательный комментарий, «за что конкретно»), см. WRITE_OFF_CATEGORIES.
|
||||||
* «Сырые» цифры без пробелов, как TrainingAmount (см. MoneyInput). Пусто =
|
* «Сырые» цифры без пробелов, как TrainingAmount (см. MoneyInput). Пусто =
|
||||||
* не заполнено. КАЖДАЯ пара — независимая: заполнить может любой активный
|
* не заполнено. КАЖДАЯ пара — независимая: заполнить может любой активный
|
||||||
@@ -49,6 +49,10 @@ export interface IFormData {
|
|||||||
*/
|
*/
|
||||||
WriteOffAssetsAmount: string;
|
WriteOffAssetsAmount: string;
|
||||||
WriteOffAssetsComment: string;
|
WriteOffAssetsComment: string;
|
||||||
|
WriteOffPpeAmount: string;
|
||||||
|
WriteOffPpeComment: string;
|
||||||
|
WriteOffAccountableAmount: string;
|
||||||
|
WriteOffAccountableComment: string;
|
||||||
WriteOffTrainingAmount: string;
|
WriteOffTrainingAmount: string;
|
||||||
WriteOffTrainingComment: string;
|
WriteOffTrainingComment: string;
|
||||||
WriteOffNmaAmount: string;
|
WriteOffNmaAmount: string;
|
||||||
@@ -57,10 +61,14 @@ export interface IFormData {
|
|||||||
WriteOffTmcComment: string;
|
WriteOffTmcComment: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Имена всех 8 строковых полей сумм/комментариев к списанию — см. IFormData.WriteOff*. */
|
/** Имена всех 12 строковых полей сумм/комментариев к списанию — см. IFormData.WriteOff*. */
|
||||||
export type WriteOffFieldKey =
|
export type WriteOffFieldKey =
|
||||||
| 'WriteOffAssetsAmount'
|
| 'WriteOffAssetsAmount'
|
||||||
| 'WriteOffAssetsComment'
|
| 'WriteOffAssetsComment'
|
||||||
|
| 'WriteOffPpeAmount'
|
||||||
|
| 'WriteOffPpeComment'
|
||||||
|
| 'WriteOffAccountableAmount'
|
||||||
|
| 'WriteOffAccountableComment'
|
||||||
| 'WriteOffTrainingAmount'
|
| 'WriteOffTrainingAmount'
|
||||||
| 'WriteOffTrainingComment'
|
| 'WriteOffTrainingComment'
|
||||||
| 'WriteOffNmaAmount'
|
| 'WriteOffNmaAmount'
|
||||||
@@ -69,7 +77,7 @@ export type WriteOffFieldKey =
|
|||||||
| 'WriteOffTmcComment';
|
| 'WriteOffTmcComment';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Одна из 4 независимых категорий списания — см. IFormData.WriteOff*.
|
* Одна из 6 независимых категорий списания — см. IFormData.WriteOff*.
|
||||||
* amountField/commentField сужены до WriteOffFieldKey (а не keyof IFormData
|
* amountField/commentField сужены до WriteOffFieldKey (а не keyof IFormData
|
||||||
* целиком): у IFormData есть и булевы поля (ParkingCard/AccessCard), и
|
* целиком): у IFormData есть и булевы поля (ParkingCard/AccessCard), и
|
||||||
* `data[cat.amountField]` должен типизироваться строго строкой — иначе
|
* `data[cat.amountField]` должен типизироваться строго строкой — иначе
|
||||||
@@ -83,11 +91,13 @@ export interface IWriteOffCategory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const WRITE_OFF_CATEGORIES: IWriteOffCategory[] = [
|
export const WRITE_OFF_CATEGORIES: IWriteOffCategory[] = [
|
||||||
|
{ key: 'assets', label: 'ОС', amountField: 'WriteOffAssetsAmount', commentField: 'WriteOffAssetsComment' },
|
||||||
|
{ key: 'ppe', label: 'СИЗ', amountField: 'WriteOffPpeAmount', commentField: 'WriteOffPpeComment' },
|
||||||
{
|
{
|
||||||
key: 'assets',
|
key: 'accountable',
|
||||||
label: 'ОС / СИЗ / подотчётная сумма',
|
label: 'Подотчётная сумма',
|
||||||
amountField: 'WriteOffAssetsAmount',
|
amountField: 'WriteOffAccountableAmount',
|
||||||
commentField: 'WriteOffAssetsComment'
|
commentField: 'WriteOffAccountableComment'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'training',
|
key: 'training',
|
||||||
@@ -126,6 +136,10 @@ export const EMPTY_DATA: IFormData = {
|
|||||||
DismissalUrl: '',
|
DismissalUrl: '',
|
||||||
WriteOffAssetsAmount: '',
|
WriteOffAssetsAmount: '',
|
||||||
WriteOffAssetsComment: '',
|
WriteOffAssetsComment: '',
|
||||||
|
WriteOffPpeAmount: '',
|
||||||
|
WriteOffPpeComment: '',
|
||||||
|
WriteOffAccountableAmount: '',
|
||||||
|
WriteOffAccountableComment: '',
|
||||||
WriteOffTrainingAmount: '',
|
WriteOffTrainingAmount: '',
|
||||||
WriteOffTrainingComment: '',
|
WriteOffTrainingComment: '',
|
||||||
WriteOffNmaAmount: '',
|
WriteOffNmaAmount: '',
|
||||||
|
|||||||
@@ -16,8 +16,12 @@
|
|||||||
|
|
||||||
{ "internalName": "DismissalUrl", "title": "Ссылка на заявление на увольнение", "type": "Url" },
|
{ "internalName": "DismissalUrl", "title": "Ссылка на заявление на увольнение", "type": "Url" },
|
||||||
|
|
||||||
{ "internalName": "WriteOffAssetsAmount", "title": "Сумма к списанию: ОС/СИЗ/подотчёт", "type": "Number", "decimals": 2 },
|
{ "internalName": "WriteOffAssetsAmount", "title": "Сумма к списанию: ОС", "type": "Number", "decimals": 2 },
|
||||||
{ "internalName": "WriteOffAssetsComment", "title": "Комментарий: ОС/СИЗ/подотчёт", "type": "Note" },
|
{ "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": "WriteOffTrainingAmount", "title": "Сумма к списанию: обучение", "type": "Number", "decimals": 2 },
|
||||||
{ "internalName": "WriteOffTrainingComment", "title": "Комментарий: обучение", "type": "Note" },
|
{ "internalName": "WriteOffTrainingComment", "title": "Комментарий: обучение", "type": "Note" },
|
||||||
{ "internalName": "WriteOffNmaAmount", "title": "Сумма к списанию: НМА", "type": "Number", "decimals": 2 },
|
{ "internalName": "WriteOffNmaAmount", "title": "Сумма к списанию: НМА", "type": "Number", "decimals": 2 },
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ export const RequestSection: React.FC<IRequestSectionProps> = ({
|
|||||||
readOnly={hrRecordsEditable ? false : undefined}
|
readOnly={hrRecordsEditable ? false : undefined}
|
||||||
/>
|
/>
|
||||||
</FormField>
|
</FormField>
|
||||||
{/* Суммы к списанию — 4 независимые пары (сумма + обязательный комментарий,
|
{/* Суммы к списанию — 6 независимых пар (сумма + обязательный комментарий,
|
||||||
за что конкретно). Каждую может заполнить ЛЮБОЙ активный согласующий
|
за что конкретно). Каждую может заполнить ЛЮБОЙ активный согласующий
|
||||||
(не только профильный, в отличие от отметок выше) — но как только сумма
|
(не только профильный, в отличие от отметок выше) — но как только сумма
|
||||||
указана, пара блокируется навсегда для всех, поэтому у незаблокированных
|
указана, пара блокируется навсегда для всех, поэтому у незаблокированных
|
||||||
|
|||||||
@@ -1,20 +1,10 @@
|
|||||||
import { ApprovalListService, IApproverToWrite, approvalServiceFor, writeRoute } from '../../shared/approval';
|
import { ApprovalListService, IApproverToWrite, approvalServiceFor, writeRoute } from '../../shared/approval';
|
||||||
import { ISaveItemResult, resolveDataList, saveRequestItem } from '../../shared/dataList';
|
import { ISaveItemResult, resolveDataList, saveRequestItem } from '../../shared/dataList';
|
||||||
import { ensureEmployee } from '../../shared/employee';
|
import { ensureEmployee } from '../../shared/employee';
|
||||||
import { FORM_ID, IFormData } from './model';
|
import { FORM_ID, IFormData, WriteOffFieldKey } from './model';
|
||||||
|
|
||||||
/** Одна из 8 колонок сумм/комментариев к списанию — см. model.ts WRITE_OFF_CATEGORIES. */
|
/** Одна из 12 колонок сумм/комментариев к списанию — см. model.ts WRITE_OFF_CATEGORIES. */
|
||||||
export type IWriteOffFields = Pick<
|
export type IWriteOffFields = Pick<IFormData, WriteOffFieldKey>;
|
||||||
IFormData,
|
|
||||||
| 'WriteOffAssetsAmount'
|
|
||||||
| 'WriteOffAssetsComment'
|
|
||||||
| 'WriteOffTrainingAmount'
|
|
||||||
| 'WriteOffTrainingComment'
|
|
||||||
| 'WriteOffNmaAmount'
|
|
||||||
| 'WriteOffNmaComment'
|
|
||||||
| 'WriteOffTmcAmount'
|
|
||||||
| 'WriteOffTmcComment'
|
|
||||||
>;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Записать сумму(ы)/комментарий(и) к списанию. Пишет РОВНО переданные поля —
|
* Записать сумму(ы)/комментарий(и) к списанию. Пишет РОВНО переданные поля —
|
||||||
|
|||||||
Reference in New Issue
Block a user