diff --git a/src/food-market.web/src/lib/types.ts b/src/food-market.web/src/lib/types.ts index aa8bdaf..1792c01 100644 --- a/src/food-market.web/src/lib/types.ts +++ b/src/food-market.web/src/lib/types.ts @@ -94,6 +94,8 @@ export interface SupplyLineDto { id: string | null; productId: string; productName: string | null; productArticle: string | null; unitName: string | null; quantity: number; unitPrice: number; lineTotal: number; sortOrder: number; + retailPriceManuallyOverridden: boolean; retailPriceOverride: number | null; + currentRetailPrice: number | null; } export interface SupplyDto { diff --git a/src/food-market.web/src/pages/SupplyEditPage.tsx b/src/food-market.web/src/pages/SupplyEditPage.tsx index c596725..7ea83c0 100644 --- a/src/food-market.web/src/pages/SupplyEditPage.tsx +++ b/src/food-market.web/src/pages/SupplyEditPage.tsx @@ -18,6 +18,11 @@ interface LineRow { unitName: string | null quantity: number unitPrice: number + // Розничная цена с карточки товара на момент загрузки документа + // (read-only baseline). Используется как placeholder для ручного override. + currentRetailPrice: number | null + retailPriceManuallyOverridden: boolean + retailPriceOverride: number | null } interface Form { @@ -81,6 +86,9 @@ export function SupplyEditPage() { unitName: l.unitName, quantity: l.quantity, unitPrice: l.unitPrice, + currentRetailPrice: l.currentRetailPrice ?? null, + retailPriceManuallyOverridden: l.retailPriceManuallyOverridden ?? false, + retailPriceOverride: l.retailPriceOverride ?? null, })), }) } @@ -121,7 +129,13 @@ export function SupplyEditPage() { supplierInvoiceNumber: form.supplierInvoiceNumber || null, supplierInvoiceDate: form.supplierInvoiceDate ? new Date(form.supplierInvoiceDate).toISOString() : null, notes: form.notes || null, - lines: form.lines.map((l) => ({ productId: l.productId, quantity: l.quantity, unitPrice: l.unitPrice })), + lines: form.lines.map((l) => ({ + productId: l.productId, + quantity: l.quantity, + unitPrice: l.unitPrice, + retailPriceManuallyOverridden: l.retailPriceManuallyOverridden, + retailPriceOverride: l.retailPriceManuallyOverridden ? l.retailPriceOverride : null, + })), } if (isNew) { return (await api.post('/api/purchases/supplies', payload)).data @@ -167,6 +181,7 @@ export function SupplyEditPage() { const onSubmit = (e: FormEvent) => { e.preventDefault(); save.mutate() } const addLineFromProduct = (p: Product) => { + const defaultRetail = p.prices?.[0]?.amount ?? null setForm({ ...form, lines: [...form.lines, { @@ -175,7 +190,10 @@ export function SupplyEditPage() { productArticle: p.article, unitName: p.unitName, quantity: 1, - unitPrice: p.referencePrice ?? 0, + unitPrice: p.referencePrice ?? p.cost ?? 0, + currentRetailPrice: defaultRetail, + retailPriceManuallyOverridden: false, + retailPriceOverride: null, }], }) } @@ -299,6 +317,7 @@ export function SupplyEditPage() { Ед. Количество Цена + Розничная (карточка) Сумма @@ -324,6 +343,18 @@ export function SupplyEditPage() { currencySymbol={currencies.data?.find((c) => c.id === form.currencyId)?.symbol} /> + + updateLine(i, { + retailPriceManuallyOverridden: true, + retailPriceOverride: n, + })} + currencyCode={currencies.data?.find((c) => c.id === form.currencyId)?.code} + currencySymbol={currencies.data?.find((c) => c.id === form.currencyId)?.symbol} + placeholder={l.currentRetailPrice != null ? String(l.currentRetailPrice) : '—'} + /> + {lineTotal(l).toLocaleString('ru', { maximumFractionDigits: 2 })} @@ -339,7 +370,7 @@ export function SupplyEditPage() { - + Итого: