Files
clinicpro/.claude/prompt/currency-toman-display-admin.md
T

110 lines
8.1 KiB
Markdown
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.
# واحد پول = تومان در پنل ادمین (نمایش ÷۱۰ / ورودی ×۱۰) — ذخیره و درگاه ریال می‌ماند
## پروژه
`clinicpro` (admin frontend — React). **cross-repo:** پرامپت همتا برای سایت عمومی: `nobat724_front/.claude/prompt/currency-toman-display-front.md`.
## زمینه
واحد پول در **نمایشِ کل محصول باید تومان** باشد، ولی طبق تصمیم:
- **ذخیره‌سازی DB و API و ارسال به درگاه پرداخت همچنان ریال می‌ماند** (بدون migration، نام ستون/فیلدهای `*_rials` ثابت). درگاه ملت ریال می‌خواهد و مقدارِ ذخیره‌شده درست است.
- فقط **لایهٔ نمایش** مقدار ریال را ÷۱۰ کرده و با برچسب «تومان» نشان دهد، و **فرم‌های ورودیِ پول** مقدارِ تومانِ واردشده را ×۱۰ کرده و به‌صورت ریال ذخیره کنند.
الان ناهماهنگ است: `formatRial` عددِ **ریال** را می‌گیرد ولی برچسب «تومان» می‌چسباند (پس ۱۰ برابر نشان می‌دهد)، و فرم‌های قیمت با برچسب «(ریال)» مقدار را مستقیم ریال ذخیره می‌کنند.
## مشکل / هدف
در پنل ادمین، همهٔ مبالغ **به تومان** نمایش داده و دریافت شوند؛ تبدیل تومان↔ریال فقط در لایهٔ UI (نمایش/فرم) انجام شود. DB/API/درگاه تغییری نکنند.
## فایل‌های مرتبط
| فایل | نقش |
|------|-----|
| `clinicpro/assets/admin/lib/utils.ts` | helper مرکزی تبدیل + `formatRial` (نمایش تومان) |
| `clinicpro/assets/admin/lib/utils.test.ts` | به‌روزرسانی انتظار تست |
| `clinicpro/assets/admin/pages/SettingsPage.tsx` | ۳ ورودی قیمت (appointment_fee/sms_panel_fee/sms_price) تومان |
| `clinicpro/assets/admin/components/FreeVisitPrice.tsx` | ورودی قیمت تومان |
| `clinicpro/assets/admin/components/ServiceTariffModal.tsx` | ورودی تعرفه تومان |
| `clinicpro/assets/admin/components/TenantInsuranceContracts.tsx` | ورودی فرانشیز/سقف تعهد تومان |
| `clinicpro/assets/admin/pages/SmsWalletPage.tsx` | مبلغ شارژ (ورودی) + نمایش قیمت هر پیامک |
| (در صورت وجود) صفحهٔ تسویه/برداشت که `amount_rials` ورودی می‌گیرد | ورودی مبلغ تومان |
> نمایش‌های دیگر (Payments، Subscription، RepresentationFinance، Dashboard و…) از `formatRial` استفاده می‌کنند؛ با اصلاح مرکزی خودکار تومان می‌شوند (۲۲ مصرف `formatRial`).
## وضعیت فعلی
### `lib/utils.ts`
```ts
export function formatRial(amount: number): string {
return new Intl.NumberFormat('fa-IR').format(amount) + ' تومان';
}
```
عدد ریال را بدون تبدیل، با برچسب «تومان» نشان می‌دهد → ۱۰ برابر.
### `SettingsPage.tsx` (ورودی‌ها ریال ذخیره می‌شوند)
```tsx
appointment_fee_rials: s.appointment_fee_rials ?? '150000',
sms_panel_fee_rials: s.sms_panel_fee_rials ?? '1500000',
sms_price_rials: s.sms_price_rials ?? '500',
// ...
<input {...register('appointment_fee_rials')} ... placeholder="150000" />
```
مقدار مستقیم به‌صورت ریال در `site_config` PATCH می‌شود.
### نمونهٔ نمایش (Subscription)
```tsx
{formatRial(period.price_rials)} // price_rials ریال است
```
## وظایف
### ۱. helperهای تبدیل + اصلاح `formatRial` (utils.ts)
```ts
export const RIAL_PER_TOMAN = 10;
export const rialToToman = (rial: number): number => Math.round((Number(rial) || 0) / RIAL_PER_TOMAN);
export const tomanToRial = (toman: number): number => Math.round((Number(toman) || 0) * RIAL_PER_TOMAN);
// ورودی همچنان «مقدار ریال» است (سازگاری با ۲۲ فراخوانی)، ولی خروجی به تومان نمایش داده می‌شود.
export function formatRial(rial: number): string {
return new Intl.NumberFormat('fa-IR').format(rialToToman(rial)) + ' تومان';
}
```
> نام `formatRial` را برای سازگاری با تمام مصرف‌کننده‌ها نگه دار (فقط رفتارش تومان‌نمایش می‌شود). اگر خواستی برای خوانایی `formatToman` را هم به‌عنوان alias صادر کن.
### ۲. فرم‌های ورودی پول — تومان بگیر، ریال ذخیره کن
الگوی کلی: مقدار ذخیره‌شده (ریال) را با `rialToToman` در فرم نشان بده؛ هنگام submit با `tomanToRial` به ریال تبدیل کن؛ برچسب واحد را «تومان» کن.
**`SettingsPage.tsx`:**
- `defaultValues`: `appointment_fee_rials: String(rialToToman(Number(s.appointment_fee_rials ?? 1500000)))` و مشابه برای `sms_panel_fee_rials`، `sms_price_rials` (پیش‌فرض‌ها را هم به تومان تبدیل کن: مثلاً `150000` ریال → نمایش `15000`).
- هنگام ذخیره (onSubmit/PATCH): این سه فیلد را `tomanToRial(...)` کن و سپس بفرست، تا `site_config` همچنان ریال بگیرد.
- placeholder/برچسب‌ها را از ریال به تومان به‌روز کن (مثلاً placeholder «15000»).
**`FreeVisitPrice.tsx` / `ServiceTariffModal.tsx` / `TenantInsuranceContracts.tsx`:**
- برچسب‌های «قیمت (ریال)»، «تعرفه (ریال)»، «فرانشیز (ریال)»، «سقف تعهد (ریال)» → «(تومان)».
- مقدار پیش‌فرضِ فرم = `rialToToman(storedRial)`؛ هنگام ذخیره = `tomanToRial(inputToman)` قبل از ارسال به API.
**`SmsWalletPage.tsx`:**
- مبلغ شارژ که کاربر وارد می‌کند = تومان → قبل از ارسال `tomanToRial`.
- نمایش «قیمت هر پیامک» و موجودی کیف‌پول از `formatRial` استفاده کند (خودکار تومان).
**صفحهٔ تسویه/برداشت (اگر `amount_rials` را از ورودی می‌گیرد):** مقدار تومانِ واردشده را `tomanToRial` کن و بفرست؛ نمایش موجودی/سقف با `formatRial`.
### ۳. برچسب‌های ثابت «ریال» در JSX
هر جای UI که رشتهٔ «ریال» به‌صورت ثابت کنار عدد آمده (نه از طریق `formatRial`) به «تومان» تغییر کند و عددش اگر خام ریال است با `rialToToman` تبدیل شود. (با `grep -rn "ریال" assets/admin` پیدا کن.)
### ۴. تست
`lib/utils.test.ts`: انتظار `formatRial` را به تومان به‌روز کن (مثلاً ورودی `150000` ریال → خروجی شامل `15,000` و «تومان»).
## نکات مهم
- **DB/API/درگاه دست نخورد:** هیچ کلید `*_rials`، هیچ endpoint، و `MellatGateway`/`PaymentManager` تغییر نمی‌کند. مقدارِ رفته به درگاه همان ریالِ ذخیره‌شده است (درست).
- **تبدیل فقط در مرز UI:** نمایش `rialToToman`، ورودی `tomanToRial`. هیچ مقدارِ تبدیل‌شده‌ای نباید در API/DB ذخیره شود مگر بعد از `tomanToRial` (که دوباره ریال است).
- **گرد کردن:** قیمت‌ها مضرب ۱۰ ریال‌اند؛ `Math.round` امن است. اگر مقداری مضرب ۱۰ نبود، تومانِ گردشده نمایش داده می‌شود (پذیرفتنی).
- **دوباره‌تبدیل نشود:** مراقب باش جایی که قبلاً `formatRial` اعمال شده دوباره ÷۱۰ نکنی (double convert).
- تست‌ها: `ddev exec npx tsc --noEmit`، `ddev exec yarn dev` بدون خطا؛ سپس چشمی: Settings (قیمت‌ها تومان و ذخیره درست)، Payments/Subscription/Dashboard (اعداد ۱۰ برابر کوچک‌تر از قبل و برچسب تومان).
- backend docs تغییری ندارد (واحد API ریال می‌ماند).