test(inventory): full-chain шаг 10 — проверка новой модели МойСклада
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run

Добавлена проверка: создать инвентаризацию → завершить (остаток не меняется) →
создать оприходование излишков «на основании» → виден связанный документ → провести
оприходование (остаток +3) → в оприходовании ссылка «на основании инвентаризации №…».
Старый путь /post (мобильная совместимость) по-прежнему проверяется. 16/16 зелёный на стенде.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
nns 2026-10-08 20:44:21 +05:00
parent b4bd0e41d4
commit b036050c15

View file

@ -1153,6 +1153,36 @@ export async function step10_warehouse_ops({ ctx, step, report }: StepCtx) {
if (!approxEq(uncountedNow, uncountedBefore)) report.bug({ step: '10', severity: 'critical', title: 'Инвентаризация обнулила непосчитанный товар', detail: `было ${uncountedBefore} стало ${uncountedNow}` }) if (!approxEq(uncountedNow, uncountedBefore)) report.bug({ step: '10', severity: 'critical', title: 'Инвентаризация обнулила непосчитанный товар', detail: `было ${uncountedBefore} стало ${uncountedNow}` })
} }
// ── Новая модель МойСклада: завершить (без движений) → создать оприходование
// «на основании» → провести его (вот тогда меняются остатки) ──────────────
const nmProd = invProds[0]
const nmBefore = await stockOf(api, ctx.storeId, nmProd.id)
const nmInv = await api.post('/api/inventory/inventories', {
date: new Date().toISOString(), storeId: ctx.storeId, notes: 'Новая модель: излишек',
lines: [{ productId: nmProd.id, actualQty: round2(nmBefore + 3) }],
})
const nmId = nmInv.data?.id
if (nmId) {
const compl = await api.post(`/api/inventory/inventories/${nmId}/complete`, {})
rec(step, 'api', 'Инвентаризация завершена (Completed)', compl.status === 204, '204', `${compl.status}`)
const midStock = await stockOf(api, ctx.storeId, nmProd.id)
rec(step, 'api', 'После завершения остаток НЕ изменился', approxEq(midStock, nmBefore), nmBefore, midStock)
const ce = await api.post(`/api/inventory/inventories/${nmId}/create-enter`, {})
const nmEnterId = ce.data?.enterId as string | undefined
rec(step, 'api', 'Создано оприходование излишков', ce.status === 200 && !!nmEnterId, '200+enterId', `${ce.status}`)
const invGet = await api.get(`/api/inventory/inventories/${nmId}`)
const relOk = ((invGet.data?.related ?? []) as { kind: string }[]).some((r) => r.kind === 'enter')
rec(step, 'api', 'В инвентаризации виден связанный документ', relOk, true, relOk)
if (nmEnterId) {
const pe = await api.post(`/api/inventory/enters/${nmEnterId}/post`, {})
rec(step, 'api', 'Оприходование проведено', pe.status === 204 || pe.status === 200, '204', `${pe.status}`)
const nmAfter = await stockOf(api, ctx.storeId, nmProd.id)
rec(step, 'api', 'Излишек применён оприходованием (+3)', approxEq(nmAfter - nmBefore, 3), 3, round2(nmAfter - nmBefore))
const enterGet = await api.get(`/api/inventory/enters/${nmEnterId}`)
rec(step, 'api', 'Оприходование «на основании инвентаризации №…»', !!enterGet.data?.inventoryNumber, 'инв.№', enterGet.data?.inventoryNumber ?? '—')
}
}
await capture(ctx, step, '/inventory/enters', '10-oprihodovanie', 'Оприходование излишка (+8)') await capture(ctx, step, '/inventory/enters', '10-oprihodovanie', 'Оприходование излишка (+8)')
await capture(ctx, step, '/inventory/losses', '10-spisanie-braka', 'Списание брака (−2)') await capture(ctx, step, '/inventory/losses', '10-spisanie-braka', 'Списание брака (−2)')
await capture(ctx, step, '/inventory/inventories', '10-inventarizaciya', 'Инвентаризация (часть товаров): расхождения', { fullPage: true }) await capture(ctx, step, '/inventory/inventories', '10-inventarizaciya', 'Инвентаризация (часть товаров): расхождения', { fullPage: true })