diff --git a/src/webparts/requestPortal/forms/Vacation/VacationForm.tsx b/src/webparts/requestPortal/forms/Vacation/VacationForm.tsx index e45441a..7d56922 100644 --- a/src/webparts/requestPortal/forms/Vacation/VacationForm.tsx +++ b/src/webparts/requestPortal/forms/Vacation/VacationForm.tsx @@ -44,7 +44,7 @@ import { dataListTitle, dataListTitleForListId } from '../../shared/listTitles'; -import { FORM_ID, IFormData, EMPTY_DATA, SetField, MIN_NOTICE_DAYS } from './model'; +import { FORM_ID, IFormData, EMPTY_DATA, SetField, MIN_NOTICE_DAYS, MAX_DAYS } from './model'; import { saveVacationRequest, vacationApprovalService } from './submit'; import { loadVacationRequest } from './load'; import { RequestSection } from './sections/RequestSection'; @@ -202,17 +202,20 @@ const VacationForm: React.FC = ({ // выбрать более раннюю дату, но проверяем и здесь на случай обхода UI. const minStartDate = isoDatePlusDays(MIN_NOTICE_DAYS); const isStartDateValid = !data.StartDate || data.StartDate >= minStartDate; + const isDaysCountTooLarge = Number.isFinite(daysNum) && daysNum > MAX_DAYS; const isValid = !!( data.Employee && data.StartDate && isStartDateValid && Number.isFinite(daysNum) && - daysNum > 0 + daysNum > 0 && + !isDaysCountTooLarge ); const validate = (): string | undefined => { if (data.StartDate && !isStartDateValid) { return `Заявку на отпуск нужно подать не позднее чем за ${MIN_NOTICE_DAYS} дней до даты начала — минимально доступная дата: ${formatIsoDate(minStartDate)}.`; } + if (isDaysCountTooLarge) return `Отпуск — не более ${MAX_DAYS} календарных дней в одной заявке.`; if (!isValid) return 'Заполните обязательные поля: сотрудник, дата начала, количество дней (> 0).'; if (requestTypeIdState.error) return `Не удалось определить тип заявки: ${requestTypeIdState.error}`; if (!requestTypeId) return 'Тип заявки ещё определяется — подождите немного и повторите.'; diff --git a/src/webparts/requestPortal/forms/Vacation/model.ts b/src/webparts/requestPortal/forms/Vacation/model.ts index e220565..2cf15d8 100644 --- a/src/webparts/requestPortal/forms/Vacation/model.ts +++ b/src/webparts/requestPortal/forms/Vacation/model.ts @@ -80,5 +80,7 @@ export const EMPTY_DATA: IFormData = { export const EMPLOYEE_PLACEHOLDER = 'Начните вводить Ф.И.О. сотрудника…'; /** Заявку нужно подавать не позднее чем за столько дней до даты начала отпуска. */ export const MIN_NOTICE_DAYS = 7; +/** Ежегодный трудовой отпуск — не более стольких календарных дней в одной заявке (требование HR). */ +export const MAX_DAYS = 24; /** Плейсхолдер для поля выбора замещающего. */ export const SUBSTITUTE_PLACEHOLDER = 'Начните вводить Ф.И.О. замещающего…'; diff --git a/src/webparts/requestPortal/forms/Vacation/sections/RequestSection.tsx b/src/webparts/requestPortal/forms/Vacation/sections/RequestSection.tsx index 8c2652e..6f9baba 100644 --- a/src/webparts/requestPortal/forms/Vacation/sections/RequestSection.tsx +++ b/src/webparts/requestPortal/forms/Vacation/sections/RequestSection.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { FormGrid, FormField, TextInput, PeopleField, OrganizationTable } from '../../../shared/ui'; import { ProjectPicker } from '../../../shared/dictionary'; -import { ISectionProps, EMPLOYEE_PLACEHOLDER, SUBSTITUTE_PLACEHOLDER, MIN_NOTICE_DAYS } from '../model'; +import { ISectionProps, EMPLOYEE_PLACEHOLDER, SUBSTITUTE_PLACEHOLDER, MIN_NOTICE_DAYS, MAX_DAYS } from '../model'; import { isoDatePlusDays } from '../../../shared/dateUtils'; /** Единственная секция формы «Заявка на отпуск»: сотрудник (должность и подразделение подтягиваются из справочника), даты. */ @@ -38,7 +38,14 @@ export const RequestSection: React.FC = ({ data, set, context, on /> - set('DaysCount', v)} /> + set('DaysCount', v)} + min={1} + max={MAX_DAYS} + />