diff --git a/src/webparts/stroyBot/pages/works/useWorkEditor.ts b/src/webparts/stroyBot/pages/works/useWorkEditor.ts index 86abfcc..73b7f3c 100644 --- a/src/webparts/stroyBot/pages/works/useWorkEditor.ts +++ b/src/webparts/stroyBot/pages/works/useWorkEditor.ts @@ -1,6 +1,6 @@ import * as React from 'react'; import { buildWorkBody, IWorksRepository } from './worksRepository'; -import { isTitleValid, needsClearParent, resetFormKeepParent, workToForm } from './worksRules'; +import { isDateRangeValid, isTitleValid, needsClearParent, resetFormKeepParent, workToForm } from './worksRules'; import { EMPTY_WORK_FORM, IWork, IWorkForm, WorkModalMode } from './worksTypes'; import { WORKS_TEXTS } from './texts'; @@ -63,6 +63,11 @@ export function useWorkEditor({ repository, objectId, reloadWorks }: IEditorDeps titleInputRef.current?.focus(); return; } + // В старом stroy-bot-works проверки не было — исправлено при ручной проверке (T-WRK). + if (!isDateRangeValid(form)) { + setState((prev) => ({ ...prev, isTitleInvalid: false, saveError: WORKS_TEXTS.modal.dateRangeError })); + return; + } setState((prev) => ({ ...prev, isTitleInvalid: false, isSaving: true, saveError: undefined })); try { const parentNavProperty = form.parentId.trim() ? await repository.getParentNavProperty() : ''; diff --git a/src/webparts/stroyBot/pages/works/worksRules.test.ts b/src/webparts/stroyBot/pages/works/worksRules.test.ts index 2c04c98..e5df3b4 100644 --- a/src/webparts/stroyBot/pages/works/worksRules.test.ts +++ b/src/webparts/stroyBot/pages/works/worksRules.test.ts @@ -2,6 +2,7 @@ import { buildWorkTree, formatDateRange, formatVolume, + isDateRangeValid, isTitleValid, needsClearParent, parentOptions, @@ -80,6 +81,13 @@ describe('форма', () => { }); }); + it('окончание не раньше начала; пустые даты не проверяются (баг старого кода исправлен)', () => { + expect(isDateRangeValid({ ...EMPTY_WORK_FORM, start: '2026-10-19', finish: '2026-10-16' })).toBe(false); + expect(isDateRangeValid({ ...EMPTY_WORK_FORM, start: '2026-10-19', finish: '2026-10-19' })).toBe(true); + expect(isDateRangeValid({ ...EMPTY_WORK_FORM, start: '2026-10-19', finish: '' })).toBe(true); + expect(isDateRangeValid({ ...EMPTY_WORK_FORM, start: '', finish: '2026-10-16' })).toBe(true); + }); + it('наименование обязательно (пробелы не считаются)', () => { expect(isTitleValid({ ...EMPTY_WORK_FORM, title: ' ' })).toBe(false); expect(isTitleValid({ ...EMPTY_WORK_FORM, title: 'Бетон' })).toBe(true); diff --git a/src/webparts/stroyBot/pages/works/worksRules.ts b/src/webparts/stroyBot/pages/works/worksRules.ts index 1ec03a5..52dc0df 100644 --- a/src/webparts/stroyBot/pages/works/worksRules.ts +++ b/src/webparts/stroyBot/pages/works/worksRules.ts @@ -84,6 +84,11 @@ export function resetFormKeepParent(form: IWorkForm): IWorkForm { return { title: '', unit: '', volume: '', parentId: form.parentId, start: '', finish: '' }; } +/** Окончание не раньше начала (даты YYYY-MM-DD сравниваются строками). Пустые даты не проверяются. */ +export function isDateRangeValid(form: IWorkForm): boolean { + return !form.start || !form.finish || form.start <= form.finish; +} + export function isTitleValid(form: IWorkForm): boolean { return form.title.trim() !== ''; }