fix: отпуск без содержания — без лимита 5 дней, «Иная причина»
5 дней работодатель обязан дать только при браке/рождении/смерти, сверх — по договорённости, поэтому форма больше не ограничивает число дней. Вариант «В иных случаях» подписан как «Иная причина» — читается как ответ на «Причина»; значение в SP прежнее. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -22,10 +22,11 @@
|
||||
- **Период вводится двумя датами** (с / по), обе обязательны, конец ≥ начала.
|
||||
`DaysCount` считается при сохранении (включительно) для отчётности — в UI не показывается.
|
||||
- **Причина** (`UnpaidLeaveReasonType`, Choice) — обязательна: брак / рождение ребёнка /
|
||||
смерть близких / «В иных случаях». Только при «иных случаях» появляется обязательный
|
||||
смерть близких / «В иных случаях» (в форме подписано «Иная причина», значение в SP прежнее). Только при «иных случаях» появляется обязательный
|
||||
текст причины (`Reason`). У заявок до появления колонки причины нет — их прежний
|
||||
текст из `Reason` по-прежнему показывается (`isReasonTextShown`).
|
||||
- **Не более 5 календарных дней** (`MAX_DAYS`) — при любой причине.
|
||||
- **Количество дней без верхнего предела** — 5 дней работодатель обязан дать при браке /
|
||||
рождении / смерти, остальное — по договорённости, поэтому форма лимит не ставит.
|
||||
- **Правило «не позднее чем за 14 дней»** (`MIN_NOTICE_DAYS`) — только для «иных случаев»
|
||||
(`requiresAdvanceNotice`): брак, рождение и смерть заранее не планируются.
|
||||
- **Подсветка проблемных полей** — `FieldIssuesProvider` + правила в `validation.ts`
|
||||
|
||||
@@ -94,8 +94,6 @@ export const SUBSTITUTE_PLACEHOLDER = 'Начните вводить Ф.И.О.
|
||||
* Действует только для «иных случаев» — см. requiresAdvanceNotice.
|
||||
*/
|
||||
export const MIN_NOTICE_DAYS = 14;
|
||||
/** Отпуск без сохранения заработной платы — не более стольких календарных дней (по любой причине). */
|
||||
export const MAX_DAYS = 5;
|
||||
|
||||
/** Причины отпуска. Значения совпадают с choices колонки UnpaidLeaveReasonType. */
|
||||
export const REASON_MARRIAGE = 'Регистрация брака';
|
||||
@@ -108,7 +106,8 @@ export const UNPAID_LEAVE_REASONS: ISelectOption[] = [
|
||||
{ value: REASON_MARRIAGE, label: REASON_MARRIAGE },
|
||||
{ value: REASON_CHILD_BIRTH, label: REASON_CHILD_BIRTH },
|
||||
{ value: REASON_RELATIVE_DEATH, label: REASON_RELATIVE_DEATH },
|
||||
{ value: REASON_OTHER, label: REASON_OTHER }
|
||||
// Значение в SP остаётся прежним (choices колонки и старые заявки), меняется только подпись.
|
||||
{ value: REASON_OTHER, label: 'Иная причина' }
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
EMPLOYEE_PLACEHOLDER,
|
||||
SUBSTITUTE_PLACEHOLDER,
|
||||
MIN_NOTICE_DAYS,
|
||||
MAX_DAYS,
|
||||
REASON_OTHER,
|
||||
UNPAID_LEAVE_REASONS,
|
||||
requiresAdvanceNotice,
|
||||
@@ -61,14 +60,13 @@ export const RequestSection: React.FC<ISectionProps> = ({ data, set, context, on
|
||||
min={requiresAdvanceNotice(data.ReasonType) ? isoDatePlusDays(MIN_NOTICE_DAYS) : undefined}
|
||||
/>
|
||||
</FormField>
|
||||
<FormField label={`Количество дней (не более ${MAX_DAYS})`} htmlFor="DaysCount" required>
|
||||
<FormField label="Количество дней" htmlFor="DaysCount" required>
|
||||
<TextInput
|
||||
id="DaysCount"
|
||||
type="number"
|
||||
value={data.DaysCount}
|
||||
onChange={(v) => set('DaysCount', v)}
|
||||
min={1}
|
||||
max={MAX_DAYS}
|
||||
/>
|
||||
</FormField>
|
||||
<FormField label="Причина" htmlFor="UnpaidLeaveReasonType" required full>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { IFieldIssue } from '../../shared/ui';
|
||||
import { isoDatePlusDays, formatIsoDate } from '../../shared/dateUtils';
|
||||
import { IFormData, MAX_DAYS, MIN_NOTICE_DAYS, REASON_OTHER, requiresAdvanceNotice } from './model';
|
||||
import { IFormData, MIN_NOTICE_DAYS, REASON_OTHER, requiresAdvanceNotice } from './model';
|
||||
|
||||
/** Дата начала: обязательна, а в «иных случаях» — не раньше чем через MIN_NOTICE_DAYS дней. */
|
||||
function startDateIssue(data: IFormData): IFieldIssue | undefined {
|
||||
@@ -12,17 +12,20 @@ function startDateIssue(data: IFormData): IFieldIssue | undefined {
|
||||
return {
|
||||
field: 'StartDate',
|
||||
label: 'Дата начала',
|
||||
message: `в иных случаях заявление подают не позднее чем за ${MIN_NOTICE_DAYS} дней — не раньше ${formatIsoDate(minStartDate)}`
|
||||
message: `при иной причине заявление подают не позднее чем за ${MIN_NOTICE_DAYS} дней — не раньше ${formatIsoDate(minStartDate)}`
|
||||
};
|
||||
}
|
||||
|
||||
/** Количество дней: обязательно, от 1 до MAX_DAYS. */
|
||||
/**
|
||||
* Количество дней: обязательно, целое и больше нуля. Верхнего предела нет:
|
||||
* сверх 5 дней (обязательных при браке/рождении/смерти) — по договорённости с работодателем.
|
||||
*/
|
||||
function daysCountIssue(data: IFormData): IFieldIssue | undefined {
|
||||
if (!data.DaysCount.trim()) return { field: 'DaysCount', label: 'Количество дней' };
|
||||
|
||||
const days = Number(data.DaysCount);
|
||||
if (Number.isFinite(days) && days > 0 && days <= MAX_DAYS) return undefined;
|
||||
return { field: 'DaysCount', label: 'Количество дней', message: `от 1 до ${MAX_DAYS} календарных дней` };
|
||||
if (Number.isInteger(days) && days > 0) return undefined;
|
||||
return { field: 'DaysCount', label: 'Количество дней', message: 'целое число больше нуля' };
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user