/** * Formlarda tutar alanı: kullanıcı metin yazar (`1.250,50`), doğrulama `parseMoney` ile yapılır. * Gönderirken `toKurus(metin)` ile kuruşa çevrilir. */ import { z } from 'zod' import { parseMoney } from './format' /** Backend ile aynı üst sınır (`services/period.rs` → `MAX_AMOUNT`): 100 milyar ₺ */ export const MAX_AMOUNT_KURUS = 10_000_000_000_000 export const moneyMessages = { required: 'Tutarı yazın', invalid: 'Geçerli bir tutar yazın (ör. 1.250,50)', positive: 'Tutar sıfırdan büyük olmalı', negative: 'Tutar eksi olamaz', tooLarge: 'Tutar çok büyük', } /** * - `positive`: 0'dan büyük olmalı (gelir/gider kalemi) * - `optional`: boş bırakılabilir → 0 sayılır (birikim hedefi, bütçe) */ export function moneyText(mode: 'positive' | 'optional') { return z .string() .trim() .superRefine((value, ctx) => { if (value === '') { if (mode === 'positive') ctx.addIssue({ code: 'custom', message: moneyMessages.required }) return } const k = parseMoney(value) if (k === null) return ctx.addIssue({ code: 'custom', message: moneyMessages.invalid }) if (k < 0) return ctx.addIssue({ code: 'custom', message: moneyMessages.negative }) if (mode === 'positive' && k === 0) return ctx.addIssue({ code: 'custom', message: moneyMessages.positive }) if (k > MAX_AMOUNT_KURUS) ctx.addIssue({ code: 'custom', message: moneyMessages.tooLarge }) }) } /** Doğrulanmış metin → kuruş (boş → 0) */ export function toKurus(value: string): number { return parseMoney(value) ?? 0 }