feat(barcode): авто-генерация EAN-13 при добавлении штрихкода
Новый штрихкод в товаре сразу получает валидный EAN-13 с префиксом "2" (зарезервирован под внутренние штрихкоды магазина, не конфликтует с GTIN производителей). Пользователь может заменить на реальный считанный — поле остаётся редактируемым. Утилита lib/barcode.ts::generateEan13InternalPrefix2() генерирует 11 случайных цифр после "2" и дописывает контрольную сумму EAN-13. Уникальность штрихкода в организации уже обеспечивает IX_product_barcodes_OrganizationId_Code. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
1227fbdfa5
commit
42a3d2aa50
21
src/food-market.web/src/lib/barcode.ts
Normal file
21
src/food-market.web/src/lib/barcode.ts
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
// EAN-13 утилиты.
|
||||
//
|
||||
// Внутренние штрихкоды магазина начинаются с "2" — это зарезервированный
|
||||
// префикс для in-store use, он не пересекается с GTIN реальных товаров
|
||||
// от производителей.
|
||||
|
||||
function ean13Checksum(first12: string): number {
|
||||
let sum = 0
|
||||
for (let i = 0; i < 12; i++) {
|
||||
const d = first12.charCodeAt(i) - 48
|
||||
sum += i % 2 === 0 ? d : d * 3
|
||||
}
|
||||
return (10 - (sum % 10)) % 10
|
||||
}
|
||||
|
||||
/** Сгенерировать внутренний EAN-13 с префиксом "2" и случайной серединой. */
|
||||
export function generateEan13InternalPrefix2(): string {
|
||||
let body = '2'
|
||||
for (let i = 0; i < 11; i++) body += Math.floor(Math.random() * 10).toString()
|
||||
return body + ean13Checksum(body).toString()
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@ import {
|
|||
import { useOrgSettings } from '@/lib/useOrgSettings'
|
||||
import { BarcodeType, Packaging, type Product } from '@/lib/types'
|
||||
import { ProductImageGallery } from '@/components/ProductImageGallery'
|
||||
import { generateEan13InternalPrefix2 } from '@/lib/barcode'
|
||||
|
||||
interface PriceRow { id?: string; priceTypeId: string; amount: number; currencyId: string }
|
||||
interface BarcodeRow { id?: string; code: string; type: BarcodeType; isPrimary: boolean }
|
||||
|
|
@ -167,7 +168,7 @@ export function ProductEditPage() {
|
|||
setForm({ ...form, prices: form.prices.map((p, ix) => ix === i ? { ...p, ...patch } : p) })
|
||||
|
||||
const addBarcode = () => setForm({ ...form, barcodes: [...form.barcodes, {
|
||||
code: '', type: BarcodeType.Ean13, isPrimary: form.barcodes.length === 0,
|
||||
code: generateEan13InternalPrefix2(), type: BarcodeType.Ean13, isPrimary: form.barcodes.length === 0,
|
||||
}] })
|
||||
const removeBarcode = (i: number) =>
|
||||
setForm({ ...form, barcodes: form.barcodes.filter((_, ix) => ix !== i) })
|
||||
|
|
|
|||
Loading…
Reference in a new issue