refactor(ServiceRequest): убрать «Ревизия», «Отдел» -> «Подразделение» из справочника #19

Merged
gorbenko.pavel merged 1 commits from service-request-followups into main 2026-09-02 05:22:29 +00:00
5 changed files with 19 additions and 24 deletions
@@ -91,7 +91,10 @@ const ServiceRequestForm: React.FC<IRequestFormProps> = ({
RequesterName: user.displayName || '', RequesterName: user.displayName || '',
RequestDate: prev.RequestDate || today RequestDate: prev.RequestDate || today
})); }));
// Организации/должность заявителя (Employee/ByEmail) — как в TmcTransfer. // Организации/должность/подразделение заявителя (Employee/ByEmail) — как в
// TmcTransfer. Подразделение — только ПРЕДЛАГАЕТСЯ (prev.Department || …),
// как и должность: справочник не всегда точен, дальше поле остаётся
// редактируемым через DepartmentPicker.
let alive = true; let alive = true;
getEmployeeOrganizations(context, requesterEmail) getEmployeeOrganizations(context, requesterEmail)
.then((records) => { .then((records) => {
@@ -99,7 +102,9 @@ const ServiceRequestForm: React.FC<IRequestFormProps> = ({
setData((prev) => ({ setData((prev) => ({
...prev, ...prev,
Organization: formatEmployeeOrganizations(records), Organization: formatEmployeeOrganizations(records),
RequesterJobTitle: prev.RequesterJobTitle || records[0]?.position || '' RequesterJobTitle: prev.RequesterJobTitle || records[0]?.position || '',
Department: prev.Department || records[0]?.section || '',
DepartmentId: prev.DepartmentId || records[0]?.departmentId || ''
})); }));
} }
}) })
@@ -109,7 +114,7 @@ const ServiceRequestForm: React.FC<IRequestFormProps> = ({
}; };
}, [editId, context]); }, [editId, context]);
// Выбор другого заявителя подтягивает его ФИО, должность и организации. // Выбор другого заявителя подтягивает его ФИО, должность, подразделение и организации.
const handleRequesterChange = (login: string): void => { const handleRequesterChange = (login: string): void => {
setData((prev) => ({ ...prev, RequesterEmail: login })); setData((prev) => ({ ...prev, RequesterEmail: login }));
if (!login) { if (!login) {
@@ -122,6 +127,8 @@ const ServiceRequestForm: React.FC<IRequestFormProps> = ({
...prev, ...prev,
RequesterName: records[0]?.fio || prev.RequesterName, RequesterName: records[0]?.fio || prev.RequesterName,
RequesterJobTitle: records[0]?.position || prev.RequesterJobTitle, RequesterJobTitle: records[0]?.position || prev.RequesterJobTitle,
Department: records[0]?.section || prev.Department,
DepartmentId: records[0]?.departmentId || prev.DepartmentId,
Organization: formatEmployeeOrganizations(records) Organization: formatEmployeeOrganizations(records)
})) }))
) )
@@ -20,7 +20,6 @@ const SELECT_FIELDS = [
'Department', 'Department',
'DepartmentId', 'DepartmentId',
'RequestDate', 'RequestDate',
'Revision',
'ProjectName', 'ProjectName',
'ProjectId', 'ProjectId',
'ProjectManager', 'ProjectManager',
@@ -81,7 +80,6 @@ export async function loadServiceRequest(itemId: number, listId?: string): Promi
Department: (item.Department as string) || '', Department: (item.Department as string) || '',
DepartmentId: (item.DepartmentId as string) || '', DepartmentId: (item.DepartmentId as string) || '',
RequestDate: toDateInput(item.RequestDate), RequestDate: toDateInput(item.RequestDate),
Revision: (item.Revision as string) || '',
ProjectName: (item.ProjectName as string) || '', ProjectName: (item.ProjectName as string) || '',
ProjectId: (item.ProjectId as string) || '', ProjectId: (item.ProjectId as string) || '',
ProjectManager: (item.ProjectManager as string) || '', ProjectManager: (item.ProjectManager as string) || '',
@@ -95,14 +95,16 @@ export interface IFormData {
RequesterJobTitle: string; RequesterJobTitle: string;
/** Организации заявителя (`\n`-joined «Компания — должность»), read-only. */ /** Организации заявителя (`\n`-joined «Компания — должность»), read-only. */
Organization: string; Organization: string;
/** Отдел (справочник Dictionary/Departments) — на маршрут не влияет. */ /**
* Подразделение заявителя. Подставляется из его карточки (Employee/ByEmail),
* дальше правится выбором из справочника Dictionary/Departments. На маршрут
* согласования не влияет — он резолвится по проекту.
*/
Department: string; Department: string;
/** Id отдела из справочника; '' — если введён вручную. */ /** Id подразделения из справочника; '' — если введено вручную. */
DepartmentId: string; DepartmentId: string;
/** Дата заявки (YYYY-MM-DD). */ /** Дата заявки (YYYY-MM-DD). */
RequestDate: string; RequestDate: string;
/** Ревизия заявки: бумажная форма живёт ревизиями (00, U01, U02…). */
Revision: string;
// --- Проект и работы --- // --- Проект и работы ---
ProjectName: string; ProjectName: string;
@@ -182,8 +184,6 @@ export interface ISectionProps {
onRemoveAnnexFile?: (rowIndex: number) => void; onRemoveAnnexFile?: (rowIndex: number) => void;
} }
/** Ревизия по умолчанию — как в бумажной форме («Рев:00»). */
export const DEFAULT_REVISION = '00';
export const REQUESTER_PLACEHOLDER = 'Начните вводить Ф.И.О. заявителя…'; export const REQUESTER_PLACEHOLDER = 'Начните вводить Ф.И.О. заявителя…';
export const EMPTY_DATA: IFormData = { export const EMPTY_DATA: IFormData = {
@@ -194,7 +194,6 @@ export const EMPTY_DATA: IFormData = {
Department: '', Department: '',
DepartmentId: '', DepartmentId: '',
RequestDate: '', RequestDate: '',
Revision: DEFAULT_REVISION,
ProjectName: '', ProjectName: '',
ProjectId: '', ProjectId: '',
ProjectManager: '', ProjectManager: '',
@@ -8,10 +8,9 @@
{ "internalName": "RequesterName", "title": "Заявитель (Ф.И.О.)", "type": "Text" }, { "internalName": "RequesterName", "title": "Заявитель (Ф.И.О.)", "type": "Text" },
{ "internalName": "RequesterJobTitle", "title": "Должность заявителя", "type": "Text" }, { "internalName": "RequesterJobTitle", "title": "Должность заявителя", "type": "Text" },
{ "internalName": "Organization", "title": "Организация", "type": "Note" }, { "internalName": "Organization", "title": "Организация", "type": "Note" },
{ "internalName": "Department", "title": "Отдел", "type": "Text" }, { "internalName": "Department", "title": "Подразделение", "type": "Text" },
{ "internalName": "DepartmentId", "title": "Id отдела (справочник)", "type": "Text" }, { "internalName": "DepartmentId", "title": "Id подразделения (справочник)", "type": "Text" },
{ "internalName": "RequestDate", "title": "Дата заявки", "type": "DateTime", "dateOnly": true }, { "internalName": "RequestDate", "title": "Дата заявки", "type": "DateTime", "dateOnly": true },
{ "internalName": "Revision", "title": "Ревизия", "type": "Text" },
{ "internalName": "ProjectName", "title": "Проект", "type": "Text" }, { "internalName": "ProjectName", "title": "Проект", "type": "Text" },
{ "internalName": "ProjectId", "title": "Id проекта", "type": "Text" }, { "internalName": "ProjectId", "title": "Id проекта", "type": "Text" },
@@ -47,7 +47,7 @@ export const HeaderSection: React.FC<ISectionProps> = ({
placeholder="Напр. вед. инженер ПТО" placeholder="Напр. вед. инженер ПТО"
/> />
</FormField> </FormField>
<FormField label="Отдел" htmlFor="Department"> <FormField label="Подразделение" htmlFor="Department">
<DepartmentPicker <DepartmentPicker
id="Department" id="Department"
context={context} context={context}
@@ -67,14 +67,6 @@ export const HeaderSection: React.FC<ISectionProps> = ({
onChange={(v) => set('RequestDate', v)} onChange={(v) => set('RequestDate', v)}
/> />
</FormField> </FormField>
<FormField label="Ревизия" htmlFor="Revision">
<TextInput
id="Revision"
value={data.Revision}
onChange={(v) => set('Revision', v)}
placeholder="00"
/>
</FormField>
<FormField label="Проект" htmlFor="ProjectName" required> <FormField label="Проект" htmlFor="ProjectName" required>
<ProjectPicker <ProjectPicker