Files
butcem/src/shared/quantity.ts
T
2026-11-05 02:57:58 +03:00

52 lines
2.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 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);
}