/** * Miktar yardımcıları (stok, gram altın, döviz, adet). * * KURAL: Tüm miktarlar birimin BİNDE BİRİ cinsinden tamsayı saklanır (QUANTITY_SCALE = 1000): * 1,5 kg → 1500 · 5 gr altın → 5000 · 2 adet çeyrek → 2000 · 0,125 lt → 125 · 100 USD → 100000 * Böylece 3 ondalık hassasiyet sağlanır, toplama/çıkarma tamsayıdır. Birimler arası dönüşüm * (kg↔g, lt↔ml) aynı boyuttaki birimler için tanımlıdır; özel birimler ("yıkama", "tablet") * ürün bazında dönüşüm oranıyla (Faz 12) çevrilir. */ export const QUANTITY_SCALE = 1000; export const UNITS = { g: { label: "g", dimension: "mass", factor: 1 }, kg: { label: "kg", dimension: "mass", factor: 1000 }, ml: { label: "ml", dimension: "volume", factor: 1 }, lt: { label: "lt", dimension: "volume", factor: 1000 }, adet: { label: "adet", dimension: "count", factor: 1 }, } as const; export type Unit = keyof typeof UNITS; /** "1,5" / "1.5" / "2" / "0,125" → binde bir tamsayı. En fazla 3 ondalık; geçersizse null. */ export function parseQuantity(input: string): number | null { const s = input.trim().replace(/\s/g, ""); const m = /^(\d+)(?:[.,](\d{1,3}))?$/.exec(s); if (!m) return null; const value = Number(m[1]) * QUANTITY_SCALE + Number((m[2] ?? "").padEnd(3, "0")); return Number.isSafeInteger(value) ? value : null; } /** 1500 → "1,5"; 5000 → "5"; 125 → "0,125" (gereksiz sıfırlar atılır). */ export function formatQuantity(quantity: number, unit?: string): string { if (!Number.isSafeInteger(quantity)) throw new TypeError(`Miktar tamsayı olmalı: ${quantity}`); const sign = quantity < 0 ? "-" : ""; const abs = Math.abs(quantity); const int = Math.trunc(abs / QUANTITY_SCALE).toLocaleString("tr-TR"); const frac = (abs % QUANTITY_SCALE).toString().padStart(3, "0").replace(/0+$/, ""); const text = `${sign}${int}${frac ? `,${frac}` : ""}`; return unit ? `${text} ${unit}` : text; } /** Aynı boyuttaki birimler arasında dönüşüm (kg → g vb.). Uyumsuz birimde hata. */ export function convertQuantity(quantity: number, from: Unit, to: Unit): number { const a = UNITS[from]; const b = UNITS[to]; if (a.dimension !== b.dimension) throw new RangeError(`${from} → ${to} dönüştürülemez`); const result = (quantity * a.factor) / b.factor; // Hassasiyet kaybı olursa (ör. 1 ml → lt = 0,001 lt = 1) yuvarlanır; 3 ondalık sınırı. return Math.round(result); }