feat: параметр source во внешней ссылке ТМЦ сохраняется в заявке

Внешняя система (напр. КПС) передаёт source — пишем его в новую колонку
SourceSystem рядом с SourcePositionId, чтобы по заявке было видно, откуда
она пришла и куда отвечать. Запоминание источника вынесено в отдельный
эффект: positionId/source/склад сохраняются и по ссылке без nomenclatureId.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Тимур Городецкий
2026-10-05 12:39:48 +05:00
parent 7f1e36874a
commit 9400f8546e
9 changed files with 59 additions and 13 deletions
@@ -91,7 +91,8 @@ const TmcTransferForm: React.FC<IRequestFormProps> = ({
onCodeLoaded,
positionId,
nomenclatureId,
storeName
storeName,
sourceSystem
}) => {
const [data, setData] = useState<IFormData>(EMPTY_DATA);
const [files, setFiles] = useState<File[]>([]);
@@ -144,18 +145,30 @@ const TmcTransferForm: React.FC<IRequestFormProps> = ({
};
}, [editId, context]);
// Открытие по внешней ссылке (positionId + nomenclatureId в URL): запоминаем
// строку-источник и предзаполняем таблицу остатками номенклатуры по складам.
// Только для новой заявки — при редактировании позиции уже сохранены.
// Открытие по внешней ссылке: запоминаем, откуда пришла заявка — система
// (source), строка-источник (positionId) и склад. Строка нужна при отправке для
// обратной записи ссылки в Dataverse, система — чтобы знать, откуда заявка,
// склад — справочно (см. model.ts). Не зависит от nomenclatureId: ссылка может
// прийти и без товара. Только для новой заявки — у сохранённой всё уже в SP.
useEffect(() => {
if (editId || (!positionId && !storeName && !sourceSystem)) {
return;
}
setData((prev) => ({
...prev,
SourcePositionId: positionId || '',
SourceStoreName: storeName || '',
SourceSystem: sourceSystem || ''
}));
}, [editId, positionId, storeName, sourceSystem]);
// Предзаполнение таблицы остатками номенклатуры по складам (nomenclatureId из
// внешней ссылки). nomenclatureId отдельно в шапке не храним — он едет в каждой
// позиции ItemsJson. Только для новой заявки — при редактировании позиции уже сохранены.
useEffect(() => {
if (editId || !nomenclatureId) {
return;
}
// Строку-источник и склад фиксируем сразу, независимо от ответа справочника:
// строка нужна при отправке для обратной записи ссылки в Dataverse, склад —
// только справочно для пользователя (см. SourceStoreName в model.ts).
// nomenclatureId отдельно в шапке не храним — он едет в каждой позиции ItemsJson.
setData((prev) => ({ ...prev, SourcePositionId: positionId || '', SourceStoreName: storeName || '' }));
let alive = true;
getNomenclature(context, nomenclatureId, storeName)
.then((rows) => {
@@ -175,7 +188,7 @@ const TmcTransferForm: React.FC<IRequestFormProps> = ({
return () => {
alive = false;
};
}, [editId, nomenclatureId, positionId, storeName, context, setSubmitError]);
}, [editId, nomenclatureId, storeName, context, setSubmitError]);
// Проект-получатель («Куда») по той же внешней ссылке: строка-источник в
// Dataverse хранит ID позиции ЛЗК, у которой есть родительская запись LZK
@@ -53,6 +53,7 @@ export async function loadTmcTransferRequest(itemId: number, listId?: string): P
'ContactPhone',
'SourcePositionId',
'SourceStoreName',
'SourceSystem',
'ItemsJson',
'RequestStatus',
'RequestUniqueCode'
@@ -80,6 +81,7 @@ export async function loadTmcTransferRequest(itemId: number, listId?: string): P
ContactPhone: (item.ContactPhone as string) || '',
SourcePositionId: (item.SourcePositionId as string) || '',
SourceStoreName: (item.SourceStoreName as string) || '',
SourceSystem: (item.SourceSystem as string) || '',
Items: parseItems(item.ItemsJson)
};
@@ -68,6 +68,12 @@ export interface IFormData {
* именно списываются ТМЦ. '' — ссылка без фильтра по складу или заявка заведена вручную.
*/
SourceStoreName: string;
/**
* Система, из которой открыли форму по внешней ссылке — параметр `source` в URL
* (напр. 'kps'). Вместе с SourcePositionId однозначно указывает, откуда пришла
* заявка и куда отвечать. '' — заявка заведена вручную или ссылка без source.
*/
SourceSystem: string;
// Табличная часть — позиции ТМЦ (сериализуется в ItemsJson). У строк из
// справочника есть nomenclatureId (см. ILineItem), у дописанных вручную — нет.
@@ -115,5 +121,6 @@ export const EMPTY_DATA: IFormData = {
ContactPhone: '',
SourcePositionId: '',
SourceStoreName: '',
SourceSystem: '',
Items: []
};
@@ -25,6 +25,7 @@
{ "internalName": "SourcePositionId", "title": "Id строки-источника (Dataverse)", "type": "Text" },
{ "internalName": "SourceStoreName", "title": "Склад-источник (внешняя ссылка)", "type": "Text" },
{ "internalName": "SourceSystem", "title": "Система-источник (внешняя ссылка)", "type": "Text" },
{ "internalName": "ItemsJson", "title": "Позиции ТМЦ (JSON)", "type": "Note" }
]