diff --git a/src/food-market.web/src/pages/ProductEditPage.tsx b/src/food-market.web/src/pages/ProductEditPage.tsx index a00265b..a982e61 100644 --- a/src/food-market.web/src/pages/ProductEditPage.tsx +++ b/src/food-market.web/src/pages/ProductEditPage.tsx @@ -166,7 +166,10 @@ export function ProductEditPage() { qc.invalidateQueries({ queryKey: ['/api/catalog/products'] }) navigate(created ? `/catalog/products/${created.id}` : '/catalog/products') }, - onError: (e: Error) => setError(e.message), + onError: (e: Error) => { + const msg = (e as { response?: { data?: { error?: string } } }).response?.data?.error ?? e.message + setError(msg) + }, }) const remove = useMutation({ @@ -190,10 +193,21 @@ export function ProductEditPage() { const updateBarcode = (i: number, patch: Partial) => setForm({ ...form, barcodes: form.barcodes.map((b, ix) => ix === i ? { ...b, ...patch } : b) }) + // У каждого PriceType с IsRequired=true должна быть запись в form.prices + // с Amount > 0. Сервер делает ту же проверку (400 иначе), но дублируем + // на фронте чтобы кнопка Save не клатилась с непонятным «Request failed with status 400». + const missingRequiredPrices = (priceTypes.data ?? []) + .filter((pt) => pt.isRequired) + .filter((pt) => { + const row = form.prices.find((p) => p.priceTypeId === pt.id) + return !row || row.amount <= 0 + }) + const canSave = form.name.trim().length > 0 && !!form.unitOfMeasureId && !!form.productGroupId && form.barcodes.length > 0 + && missingRequiredPrices.length === 0 return (
@@ -447,6 +461,11 @@ export function ProductEditPage() { {priceTypes.data?.length === 0 && (
Нет ни одного типа цен. Создай в «Настройки → Типы цен».
)} + {missingRequiredPrices.length > 0 && ( +
+ Заполни обязательные цены: {missingRequiredPrices.map((pt) => `«${pt.name}»`).join(', ')} (значение должно быть больше 0). +
+ )}