refactor: расчёт маршрута заявки в 1С вынесен в planRoute
Сбор условий маршрута (вид работ, база 1С, отдел) и запрос маршрута с схлопыванием повторов переехали из формы в planRoute.ts. Поведение формы не меняется; функцию сможет использовать страница «Проверка маршрутов», чтобы проверять ровно тот маршрут, что видит заявитель. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -21,7 +21,6 @@ import {
|
||||
ApprovalHistory,
|
||||
StatusBadge,
|
||||
useMatrixEditor,
|
||||
getPlannedMatrix,
|
||||
loadRoutePhase,
|
||||
isOpenedRouteReady,
|
||||
resolveWriteListId,
|
||||
@@ -57,7 +56,7 @@ import { RequestSection } from './sections/RequestSection';
|
||||
import { ContactSection } from './sections/ContactSection';
|
||||
import { useStableCallback } from '../../shared/useStableCallback';
|
||||
import { applyManagerOverride, managerEmail } from './managerOverride';
|
||||
import { dedupeRouteRows } from './dedupeRoute';
|
||||
import { planTicket1CPhase, ticket1cRouteFieldValues } from './planRoute';
|
||||
import { handoffToPlanner } from './plannerHandoff';
|
||||
import { submitStatus } from './submitStatus';
|
||||
|
||||
@@ -174,27 +173,19 @@ const Ticket1CForm: React.FC<IRequestFormProps> = ({
|
||||
// см. fieldValues), а не выбирается заявителем. Поэтому матрица здесь ВСЕГДА
|
||||
// нередактируема (editable=false) — заявитель только видит, кто согласует, без
|
||||
// возможности добавить/убрать/переставить согласующего.
|
||||
// Базы 1С — мультивыбор, а approval-route принимает value только строкой:
|
||||
// передаём все выбранные базы одной записью через пробел (как CompaniesJson в
|
||||
// RecruitingHire), условия в админке — «База 1С содержит ЗУП/АТП/ATS».
|
||||
const databasesFieldValue = data.DB1C.slice().sort().join(' ');
|
||||
// Расчёт маршрута вынесен в planRoute.ts — им же пользуется страница
|
||||
// «Проверка маршрутов», чтобы проверять ровно то, что видит заявитель.
|
||||
const fieldValues = useMemo(
|
||||
() => [
|
||||
{ fieldName: 'WorkType', value: data.WorkType },
|
||||
{ fieldName: 'DB1C', value: databasesFieldValue },
|
||||
{ fieldName: 'Department', value: data.Department }
|
||||
],
|
||||
[data.WorkType, databasesFieldValue, data.Department]
|
||||
() => ticket1cRouteFieldValues({ WorkType: data.WorkType, DB1C: data.DB1C, Department: data.Department }),
|
||||
[data.WorkType, data.DB1C, data.Department]
|
||||
);
|
||||
const matrixKey = `${userEmail}-${editId ?? 'new'}-${data.WorkType}-${databasesFieldValue}-${data.Department}`;
|
||||
const matrixKey = [userEmail, editId ?? 'new', ...fieldValues.map((f) => f.value)].join('-');
|
||||
const matrixReady =
|
||||
isOpenedRouteReady(editId, requestStatus, requestTypeId) && (!!editId || (!!data.WorkType && !!requestTypeId));
|
||||
const loadMatrix = useCallback(
|
||||
() =>
|
||||
loadRoutePhase(approval, editId, requestStatus, 'Approval', async () =>
|
||||
dedupeRouteRows(
|
||||
await getPlannedMatrix(context, requestTypeId as number, userEmail, approval, 'Approval', null, fieldValues)
|
||||
)
|
||||
loadRoutePhase(approval, editId, requestStatus, 'Approval', () =>
|
||||
planTicket1CPhase(context, requestTypeId as number, userEmail, approval, 'Approval', fieldValues)
|
||||
),
|
||||
[context, userEmail, approval, editId, requestStatus, fieldValues, requestTypeId]
|
||||
);
|
||||
@@ -204,10 +195,8 @@ const Ticket1CForm: React.FC<IRequestFormProps> = ({
|
||||
// в карточке Planner, в портале отмечает «Выполнено» (см. plannerHandoff.ts).
|
||||
const loadExecutors = useCallback(
|
||||
() =>
|
||||
loadRoutePhase(approval, editId, requestStatus, 'Execution', async () =>
|
||||
dedupeRouteRows(
|
||||
await getPlannedMatrix(context, requestTypeId as number, userEmail, approval, 'Execution', null, fieldValues)
|
||||
)
|
||||
loadRoutePhase(approval, editId, requestStatus, 'Execution', () =>
|
||||
planTicket1CPhase(context, requestTypeId as number, userEmail, approval, 'Execution', fieldValues)
|
||||
),
|
||||
[context, userEmail, approval, editId, requestStatus, fieldValues, requestTypeId]
|
||||
);
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
import { WebPartContext } from '@microsoft/sp-webpart-base';
|
||||
import {
|
||||
ApprovalListService,
|
||||
ApprovalStatus,
|
||||
getPlannedMatrix,
|
||||
IMatrixRow,
|
||||
IResolveFieldValue
|
||||
} from '../../shared/approval';
|
||||
import { IFormData } from './model';
|
||||
import { dedupeRouteRows } from './dedupeRoute';
|
||||
|
||||
/** Поля заявки, от которых зависит маршрут 1С (условия шагов в админке маршрута #8). */
|
||||
export type Ticket1CRouteInput = Pick<IFormData, 'WorkType' | 'DB1C' | 'Department'>;
|
||||
|
||||
/**
|
||||
* Значения полей для условных шагов маршрута (fieldValues при resolve).
|
||||
*
|
||||
* Базы 1С — мультивыбор, а approval-route принимает value только строкой:
|
||||
* все выбранные базы уходят одной записью через пробел (как CompaniesJson в
|
||||
* RecruitingHire), условия в админке — «DB1C содержит ЗУП/АТП/ATS».
|
||||
*/
|
||||
export function ticket1cRouteFieldValues(input: Ticket1CRouteInput): IResolveFieldValue[] {
|
||||
return [
|
||||
{ fieldName: 'WorkType', value: input.WorkType },
|
||||
{ fieldName: 'DB1C', value: input.DB1C.slice().sort().join(' ') },
|
||||
{ fieldName: 'Department', value: input.Department }
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Запланированный маршрут одной фазы заявки в 1С. Один источник для формы и для
|
||||
* страницы «Проверка маршрутов» — проверка должна видеть ровно то, что увидит
|
||||
* пользователь, включая схлопывание повторов на шаге.
|
||||
*/
|
||||
export async function planTicket1CPhase(
|
||||
context: WebPartContext,
|
||||
requestTypeId: number,
|
||||
userEmail: string,
|
||||
approval: ApprovalListService,
|
||||
phase: ApprovalStatus,
|
||||
fieldValues: IResolveFieldValue[]
|
||||
): Promise<IMatrixRow[]> {
|
||||
const rows = await getPlannedMatrix(context, requestTypeId, userEmail, approval, phase, null, fieldValues);
|
||||
return dedupeRouteRows(rows);
|
||||
}
|
||||
Reference in New Issue
Block a user