Auto approve (#21)
Tests / frontend-test (push) Successful in 46s
Tests / backend-test (push) Successful in 3m39s

Co-authored-by: gorbenko.pavel <gorbenko.pavel@tansu.kz>
Reviewed-on: http://git.tnsu.kz/gorbenko.pavel/tnsu-approval-route/pulls/21
This commit was merged in pull request #21.
This commit is contained in:
2026-09-14 09:01:56 +00:00
parent e2b6227015
commit 2b8fe77fac
24 changed files with 1443 additions and 29 deletions
@@ -47,7 +47,8 @@ function toStepInput(step: TemplateRouteStep): CreateTemplateRouteStepInput {
conditions: step.conditions,
conditionsLogic: step.conditionsLogic,
slaHours: step.slaHours,
askOverdueReason: step.askOverdueReason
askOverdueReason: step.askOverdueReason,
autoApprove: step.autoApprove
};
}
@@ -77,6 +77,7 @@ interface IFormState {
/** Пусто — наследовать SLA от типа заявки; «0» — напоминать сразу. Это разные вещи. */
slaHours: string;
askOverdueReason: TriState;
autoApprove: boolean;
}
const EMPTY_CONDITION: RouteStepCondition = { fieldName: '', operation: ComparisonOperator.GreaterThan, value: '' };
@@ -133,7 +134,8 @@ function toFormState(editing: TemplateRouteStep | undefined, nextOrderNo: number
conditions: [EMPTY_CONDITION],
conditionsLogic: ConditionsLogic.And,
slaHours: '',
askOverdueReason: ''
askOverdueReason: '',
autoApprove: false
};
}
return {
@@ -149,7 +151,8 @@ function toFormState(editing: TemplateRouteStep | undefined, nextOrderNo: number
conditions: editing.conditions.length > 0 ? editing.conditions : [EMPTY_CONDITION],
conditionsLogic: editing.conditionsLogic,
slaHours: slaHoursToInput(editing.slaHours),
askOverdueReason: boolToTriState(editing.askOverdueReason)
askOverdueReason: boolToTriState(editing.askOverdueReason),
autoApprove: editing.autoApprove
};
}
@@ -365,6 +368,14 @@ export const RouteStepFormModal: React.FC<IRouteStepFormModalProps> = ({
submit.fail(texts.routeSteps.validationSlaHours);
return;
}
// Автосогласование отсчитывается от SLA — без него фоновая задача шаг просто
// пропустит (см. AutoApproveService.DeadlineOf), и настройка тихо не сработала
// бы. Пустое поле здесь не значит «нет SLA»: оно значит «взять у типа заявки»,
// поэтому ошибка только когда SLA нет и там.
if (form.autoApprove && parseSlaHours(form.slaHours) === null && requestType?.slaHours === null) {
submit.fail(texts.routeSteps.validationAutoApproveWithoutSla);
return;
}
const payload = {
orderNo,
@@ -379,7 +390,8 @@ export const RouteStepFormModal: React.FC<IRouteStepFormModalProps> = ({
: null,
conditionsLogic: form.conditionsLogic,
slaHours: parseSlaHours(form.slaHours),
askOverdueReason: triStateToBool(form.askOverdueReason)
askOverdueReason: triStateToBool(form.askOverdueReason),
autoApprove: form.autoApprove
};
const request = editing
@@ -505,6 +517,14 @@ export const RouteStepFormModal: React.FC<IRouteStepFormModalProps> = ({
/>
</Field>
<Field label={texts.routeSteps.autoApproveLabel} full hint={texts.routeSteps.autoApproveHint}>
<Checkbox
label={texts.routeSteps.autoApproveCheckbox}
checked={form.autoApprove}
onChange={v => setForm({ ...form, autoApprove: v })}
/>
</Field>
<Field label={texts.routeSteps.conditionLabel} full hint={!hasListId ? texts.routeSteps.conditionDisabledHint : undefined}>
<Checkbox
label={texts.routeSteps.conditionCheckbox}