eaf80c6bb4
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
52 lines
2.4 KiB
TypeScript
52 lines
2.4 KiB
TypeScript
/**
|
||
* 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);
|
||
}
|