fix(web): EAN-13 контрольная цифра, валюты в приёмке сканированием, поиск товара на накладной
1) digitsChecksum считал веса слева — для 12-значного тела (EAN-13) чётность
переворачивалась и контрольная цифра была неверной; теперь справа налево
(EAN-8/UPC-A не изменились). 2) SupplyScanPage читал /api/catalog/currencies как
массив, а это PagedResult {items} → список валют пуст (нет KZT). 3) InvoiceReviewPage
слал ?q=, а API ждёт ?search= (PagedRequest.Search).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
839fcaf9fc
commit
009a9d8a50
|
|
@ -6,12 +6,15 @@
|
||||||
import { BarcodeType } from '@/lib/types'
|
import { BarcodeType } from '@/lib/types'
|
||||||
|
|
||||||
function digitsChecksum(first: string, weightAtOdd: number): number {
|
function digitsChecksum(first: string, weightAtOdd: number): number {
|
||||||
// Общая EAN/UPC-подобная формула: сумма с чередующимися весами, остаток от 10.
|
// Контрольная цифра EAN/UPC: веса идут СПРАВА НАЛЕВО (цифра перед контрольной
|
||||||
// Нечётные позиции (с индекса 0) — weightAtOdd, чётные — 1.
|
// имеет вес 3, затем 1,3,1…). Нельзя привязывать вес к индексу слева: для
|
||||||
|
// чётной длины тела (EAN-13 = 12 цифр) чётность переворачивается и check-digit
|
||||||
|
// получается неверным. Для нечётной длины (EAN-8=7, UPC-A=11) результат тот же.
|
||||||
let sum = 0
|
let sum = 0
|
||||||
for (let i = 0; i < first.length; i++) {
|
let w = weightAtOdd
|
||||||
const d = first.charCodeAt(i) - 48
|
for (let i = first.length - 1; i >= 0; i--) {
|
||||||
sum += i % 2 === 0 ? d * weightAtOdd : d
|
sum += (first.charCodeAt(i) - 48) * w
|
||||||
|
w = w === weightAtOdd ? 1 : weightAtOdd
|
||||||
}
|
}
|
||||||
return (10 - (sum % 10)) % 10
|
return (10 - (sum % 10)) % 10
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -595,7 +595,9 @@ function ProductSearchDialog({ q, onClose, onPick }: {
|
||||||
queryKey: ['product-search', query],
|
queryKey: ['product-search', query],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
if (query.trim().length < 2) return []
|
if (query.trim().length < 2) return []
|
||||||
const { data } = await api.get<{ items: ProductSearchHit[] }>(`/api/catalog/products?q=${encodeURIComponent(query)}&pageSize=20`)
|
// API ждёт параметр `search` (PagedRequest.Search), а не `q` — иначе
|
||||||
|
// фильтр игнорируется и поиск товара на экране накладной не работает.
|
||||||
|
const { data } = await api.get<{ items: ProductSearchHit[] }>(`/api/catalog/products?search=${encodeURIComponent(query)}&pageSize=20`)
|
||||||
return data.items ?? []
|
return data.items ?? []
|
||||||
},
|
},
|
||||||
enabled: query.trim().length >= 2,
|
enabled: query.trim().length >= 2,
|
||||||
|
|
|
||||||
|
|
@ -65,8 +65,11 @@ export function SupplyScanPage() {
|
||||||
const main = r.data.items?.find(s => s.isMain) ?? r.data.items?.[0]
|
const main = r.data.items?.find(s => s.isMain) ?? r.data.items?.[0]
|
||||||
if (main) setStoreId(main.id)
|
if (main) setStoreId(main.id)
|
||||||
})
|
})
|
||||||
api.get<Currency[]>('/api/catalog/currencies?pageSize=20').then(r => {
|
// /api/catalog/currencies отдаёт PagedResult {items,...}, а не голый массив —
|
||||||
const list = Array.isArray(r.data) ? r.data : []
|
// раньше Array.isArray(r.data) давал пустой список валют, и черновик приёмки
|
||||||
|
// сканированием не сохранялся (нет currencyId, в т.ч. KZT по умолчанию).
|
||||||
|
api.get<{ items: Currency[] }>('/api/catalog/currencies?pageSize=20').then(r => {
|
||||||
|
const list = r.data?.items ?? []
|
||||||
setCurrencies(list)
|
setCurrencies(list)
|
||||||
const kzt = list.find(c => c.code === 'KZT') ?? list[0]
|
const kzt = list.find(c => c.code === 'KZT') ?? list[0]
|
||||||
if (kzt) setCurrencyId(kzt.id)
|
if (kzt) setCurrencyId(kzt.id)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue