Контракты до фикса не совпадали с реальными: - Product: unitId/groupId/retailPrice → unitOfMeasureId/productGroupId/prices[], плюс обязательный barcodes[] (генерим валидный EAN-13). - Supply: counterpartyId/docDate/lines.price → supplierId/date/lines.unitPrice, плюс обязательный currencyId. - RetailSale: путь /api/sales/retail-sales 404 → /api/sales/retail; payload обновлён под RetailSaleInput (storeId, currencyId, payment, paidCash и т.п.). Шаги 9-12 теперь полностью проходят (не skip). Добавлены deep-bug-hunt'ы: - Supply без supplierId / с пустым lines[] - двойной post Supply / RetailSale → 409 - stock_movements vs Stocks.Quantity консистентность - RetailPoint с несуществующим storeId - продажа qty>остатка (выявил блокирующий баг — продаёт) - discount на line, отрицательные qty/price - stock_movements.Type = RetailSale (2) Отчёт: tests/e2e/reports/full-cycle-2026-05-08-full-pass.md Финальный счёт 10 ✓ / 2 ✗ / 0 ⚠ / 0 ◯ — две ✗ это РЕАЛЬНЫЕ баги: [HIGH] step11 oversell проходит /post (нужна валидация qty≤stock) [MEDIUM] step08 Supply без supplierId → 500 вместо 400
29 lines
1.2 KiB
TypeScript
29 lines
1.2 KiB
TypeScript
/**
|
||
* EAN-13 generator для e2e: префикс "20" (внутренний магазинный, как и
|
||
* в src/food-market.web/src/lib/barcode.ts), 10 цифр payload + checksum.
|
||
* Использует индекс шага вместо рандома, чтобы прогон был детерминированным
|
||
* и легче отлавливать дубликаты в отчёте.
|
||
*/
|
||
|
||
function ean13Checksum(twelve: string): number {
|
||
let sum = 0
|
||
for (let i = 0; i < 12; i++) {
|
||
const d = twelve.charCodeAt(i) - 48
|
||
sum += i % 2 === 0 ? d : d * 3
|
||
}
|
||
return (10 - (sum % 10)) % 10
|
||
}
|
||
|
||
/**
|
||
* Сгенерировать валидный EAN-13. Префикс "20" — резерв для внутренних
|
||
* штрихкодов магазина (in-store). Тело: timestamp.slice(-7) + index в
|
||
* 3-значной форме, итого 10 цифр payload. Получаем 13-значный код с
|
||
* контрольной суммой.
|
||
*/
|
||
export function generateEan13(index: number): string {
|
||
const ts = Date.now().toString().slice(-7)
|
||
const idx = String(index).padStart(3, '0')
|
||
const body = '20' + ts + idx
|
||
return body + ean13Checksum(body).toString()
|
||
}
|