mirror of
https://github.com/serty2005/rmser.git
synced 2026-02-04 19:02:33 -06:00
3001-фух.это был сильный спринт.
сервис стал сильно лучше черновики сохраняются одним запросом дто черновиков вынесен отдельно
This commit is contained in:
@@ -34,6 +34,7 @@ import ExcelPreviewModal from "../common/ExcelPreviewModal";
|
||||
import { useActiveDraftStore } from "../../stores/activeDraftStore";
|
||||
import type {
|
||||
DraftItem,
|
||||
UpdateDraftRequest,
|
||||
CommitDraftRequest,
|
||||
ReorderDraftItemsRequest,
|
||||
} from "../../services/types";
|
||||
@@ -65,6 +66,7 @@ export const DraftEditor: React.FC<DraftEditorProps> = ({
|
||||
addItem,
|
||||
reorderItems,
|
||||
resetDirty,
|
||||
markAsDirty,
|
||||
} = useActiveDraftStore();
|
||||
|
||||
// Отслеживаем текущий draftId для инициализации стора
|
||||
@@ -168,44 +170,29 @@ export const DraftEditor: React.FC<DraftEditorProps> = ({
|
||||
|
||||
// --- ЭФФЕКТЫ ---
|
||||
|
||||
// Инициализация стора при загрузке черновика
|
||||
// Инициализация данных при загрузке черновика
|
||||
useEffect(() => {
|
||||
if (draft && draft.items) {
|
||||
// Инициализируем стор только если изменился draftId или стор пуст
|
||||
if (draft) {
|
||||
// Инициализируем только если изменился draftId или стор пуст
|
||||
if (currentDraftIdRef.current !== draft.id || items.length === 0) {
|
||||
setItems(draft.items);
|
||||
// 1. Инициализация строк (Store)
|
||||
setItems(draft.items || []);
|
||||
|
||||
// 2. Инициализация шапки (Form)
|
||||
form.setFieldsValue({
|
||||
store_id: draft.store_id,
|
||||
supplier_id: draft.supplier_id,
|
||||
comment: draft.comment,
|
||||
incoming_document_number: draft.incoming_document_number,
|
||||
date_incoming: draft.date_incoming
|
||||
? dayjs(draft.date_incoming)
|
||||
: dayjs(),
|
||||
});
|
||||
|
||||
currentDraftIdRef.current = draft.id;
|
||||
}
|
||||
}
|
||||
}, [draft, items.length, setItems]);
|
||||
|
||||
useEffect(() => {
|
||||
if (draft) {
|
||||
const currentValues = form.getFieldsValue();
|
||||
if (!currentValues.store_id && draft.store_id)
|
||||
form.setFieldValue("store_id", draft.store_id);
|
||||
if (!currentValues.supplier_id && draft.supplier_id)
|
||||
form.setFieldValue("supplier_id", draft.supplier_id);
|
||||
if (!currentValues.comment && draft.comment)
|
||||
form.setFieldValue("comment", draft.comment);
|
||||
|
||||
// Инициализация входящего номера
|
||||
if (
|
||||
!currentValues.incoming_document_number &&
|
||||
draft.incoming_document_number
|
||||
)
|
||||
form.setFieldValue(
|
||||
"incoming_document_number",
|
||||
draft.incoming_document_number
|
||||
);
|
||||
|
||||
if (!currentValues.date_incoming)
|
||||
form.setFieldValue(
|
||||
"date_incoming",
|
||||
draft.date_incoming ? dayjs(draft.date_incoming) : dayjs()
|
||||
);
|
||||
}
|
||||
}, [draft, form]);
|
||||
}, [draft, items.length, setItems, form]);
|
||||
|
||||
// --- ХЕЛПЕРЫ ---
|
||||
const totalSum = useMemo(() => {
|
||||
@@ -230,8 +217,8 @@ export const DraftEditor: React.FC<DraftEditorProps> = ({
|
||||
// Собираем значения формы для обновления шапки черновика
|
||||
const formValues = form.getFieldsValue();
|
||||
|
||||
// Подготавливаем payload для обновления мета-данных черновика
|
||||
const draftPayload: Partial<CommitDraftRequest> = {
|
||||
// Формируем единый payload для пакетного обновления (шапка + элементы)
|
||||
const payload: UpdateDraftRequest = {
|
||||
store_id: formValues.store_id,
|
||||
supplier_id: formValues.supplier_id,
|
||||
comment: formValues.comment || "",
|
||||
@@ -239,24 +226,18 @@ export const DraftEditor: React.FC<DraftEditorProps> = ({
|
||||
date_incoming: formValues.date_incoming
|
||||
? formValues.date_incoming.format("YYYY-MM-DD")
|
||||
: undefined,
|
||||
};
|
||||
|
||||
// Сохраняем все измененные элементы
|
||||
const savePromises = items.map((item) =>
|
||||
api.updateDraftItem(draftId, item.id, {
|
||||
product_id: item.product_id ?? null,
|
||||
container_id: item.container_id ?? null,
|
||||
items: items.map((item) => ({
|
||||
id: item.id,
|
||||
product_id: item.product_id ?? "",
|
||||
container_id: item.container_id ?? "",
|
||||
quantity: Number(item.quantity),
|
||||
price: Number(item.price),
|
||||
sum: Number(item.sum),
|
||||
})
|
||||
);
|
||||
})),
|
||||
};
|
||||
|
||||
// Параллельно сохраняем шапку и строки
|
||||
await Promise.all([
|
||||
api.updateDraft(draftId, draftPayload),
|
||||
...savePromises,
|
||||
]);
|
||||
// Отправляем единый запрос на сервер
|
||||
await api.updateDraft(draftId, payload);
|
||||
|
||||
// После успешного сохранения обновляем данные с сервера
|
||||
await queryClient.invalidateQueries({ queryKey: ["draft", draftId] });
|
||||
@@ -540,7 +521,7 @@ export const DraftEditor: React.FC<DraftEditorProps> = ({
|
||||
<Form
|
||||
form={form}
|
||||
layout="vertical"
|
||||
initialValues={{ date_incoming: dayjs() }}
|
||||
onValuesChange={() => markAsDirty()}
|
||||
>
|
||||
<Row gutter={[8, 8]}>
|
||||
<Col span={12}>
|
||||
|
||||
@@ -18,6 +18,7 @@ import type {
|
||||
DraftInvoice,
|
||||
DraftItem,
|
||||
UpdateDraftItemRequest,
|
||||
UpdateDraftRequest,
|
||||
CommitDraftRequest,
|
||||
ReorderDraftItemsRequest,
|
||||
ProductSearchResult,
|
||||
@@ -213,7 +214,7 @@ export const api = {
|
||||
return data;
|
||||
},
|
||||
|
||||
updateDraft: async (id: string, payload: Partial<CommitDraftRequest>): Promise<DraftInvoice> => {
|
||||
updateDraft: async (id: string, payload: UpdateDraftRequest): Promise<DraftInvoice> => {
|
||||
const { data } = await apiClient.patch<DraftInvoice>(`/drafts/${id}`, payload);
|
||||
return data;
|
||||
},
|
||||
|
||||
@@ -229,6 +229,7 @@ export interface DraftInvoice {
|
||||
|
||||
// DTO для обновления строки
|
||||
export interface UpdateDraftItemRequest {
|
||||
id?: UUID; // ID элемента для идентификации при пакетном обновлении
|
||||
product_id?: UUID | null;
|
||||
container_id?: UUID | null;
|
||||
quantity?: number;
|
||||
@@ -237,6 +238,16 @@ export interface UpdateDraftItemRequest {
|
||||
edited_field?: string; // ('quantity' | 'price' | 'sum')
|
||||
}
|
||||
|
||||
// DTO для пакетного обновления черновика (шапка + элементы)
|
||||
export interface UpdateDraftRequest {
|
||||
date_incoming?: string;
|
||||
store_id?: UUID;
|
||||
supplier_id?: UUID;
|
||||
comment?: string;
|
||||
incoming_document_number?: string;
|
||||
items?: UpdateDraftItemRequest[];
|
||||
}
|
||||
|
||||
// DTO для коммита
|
||||
export interface CommitDraftRequest {
|
||||
date_incoming: string;
|
||||
|
||||
@@ -65,6 +65,12 @@ interface ActiveDraftStore {
|
||||
* Используется после успешного сохранения изменений на сервер
|
||||
*/
|
||||
resetDirty: () => void;
|
||||
|
||||
/**
|
||||
* Устанавливает флаг isDirty в true
|
||||
* Используется для пометки черновика как измененного
|
||||
*/
|
||||
markAsDirty: () => void;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -181,5 +187,14 @@ export const useActiveDraftStore = create<ActiveDraftStore>()(
|
||||
set((state) => {
|
||||
state.isDirty = false;
|
||||
}),
|
||||
|
||||
/**
|
||||
* Устанавливает флаг isDirty в true
|
||||
* Используется для пометки черновика как измененного
|
||||
*/
|
||||
markAsDirty: () =>
|
||||
set((state) => {
|
||||
state.isDirty = true;
|
||||
}),
|
||||
}))
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user