From b036050c1537db8ef36c360aac79907b2c3976db Mon Sep 17 00:00:00 2001 From: nns Date: Thu, 8 Oct 2026 20:44:21 +0500 Subject: [PATCH] =?UTF-8?q?test(inventory):=20full-chain=20=D1=88=D0=B0?= =?UTF-8?q?=D0=B3=2010=20=E2=80=94=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=BD=D0=BE=D0=B2=D0=BE=D0=B9=20=D0=BC=D0=BE?= =?UTF-8?q?=D0=B4=D0=B5=D0=BB=D0=B8=20=D0=9C=D0=BE=D0=B9=D0=A1=D0=BA=D0=BB?= =?UTF-8?q?=D0=B0=D0=B4=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Добавлена проверка: создать инвентаризацию → завершить (остаток не меняется) → создать оприходование излишков «на основании» → виден связанный документ → провести оприходование (остаток +3) → в оприходовании ссылка «на основании инвентаризации №…». Старый путь /post (мобильная совместимость) по-прежнему проверяется. 16/16 зелёный на стенде. Co-Authored-By: Claude Opus 5.5 --- tests/e2e/scenarios/full-chain.steps.ts | 30 +++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/e2e/scenarios/full-chain.steps.ts b/tests/e2e/scenarios/full-chain.steps.ts index 4d7ea53..99041f1 100644 --- a/tests/e2e/scenarios/full-chain.steps.ts +++ b/tests/e2e/scenarios/full-chain.steps.ts @@ -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}` }) } + // ── Новая модель МойСклада: завершить (без движений) → создать оприходование + // «на основании» → провести его (вот тогда меняются остатки) ────────────── + 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/losses', '10-spisanie-braka', 'Списание брака (−2)') await capture(ctx, step, '/inventory/inventories', '10-inventarizaciya', 'Инвентаризация (часть товаров): расхождения', { fullPage: true })