Files
clinicpro/docs/new_feture/taskes/task-08-pricing-snapshot/task.md
T
hamed 021d0eb6b2 feat: implement cancellation policy, no-show tracking, and waitlist management
- Add implementation notes for cancellation and waitlist features.
- Create task documentation outlining goals, current status, and acceptance criteria for cancellation policy and resource utilization reporting.
- Establish architecture for domain events and outbox pattern to ensure reliable event publishing.
- Define database schema for domain events and necessary queries for resource utilization and plan accuracy reports.
- Implement detailed implementation notes covering edge cases, testing strategies, and documentation requirements.
2026-07-30 11:43:58 +03:30

4.6 KiB
Raw Blame History

تسک ۰۸ — لیست قیمت بازه‌دار و snapshot فاکتور

فاز: ۱ (هسته) · وابستگی: ۰۴، ۰۷ · زمان: ۱۲-۱۴ ساعت


هدف

مستند بند ۱۲: قیمت یک لایهٔ جداست با زندگی خودش (تاریخ اعتبار، مالیات، بیمه، بیعانه) و قانون پنجم: تغییر قیمت هرگز نوبت‌های ثبت‌شده را عوض نمی‌کند.

وضعیت فعلی

زنجیرهٔ قیمت امروز واقعاً وجود دارد و کار می‌کند:

ServiceItem.price_rials
  → Tariff (سال‌محور: findForServiceYear)
  → TenantServiceCoverage / TenantInsurance (بیمهٔ پایه و تکمیلی)
  → DiscountRule + DiscountEngine
  → Invoice / InvoiceItem
  → Payment

روی نوبت هم visit_price_rials, deposit_required, deposit_amount_rials, insurance_base_id, insurance_supplementary_id هست.

دو شکاف:

  1. Tariff فقط سال دارد، بازهٔ دقیق تاریخ ندارد. تغییر تعرفه وسط سال قابل بیان نیست.
  2. visit_price_rials یک عدد است. فاکتور تفکیک‌شده روی نوبت ذخیره نمی‌شود، پس بعد از تغییر قیمت یا تخفیف، نمی‌شود گفت آن ۲٬۴۰۰٬۰۰۰ ریال از چه تشکیل شده بود.

دامنه

هست:

  • PriceList (بازهٔ تاریخ + شعبه) و PriceListItem
  • PriceSnapshot — فاکتور تفکیک‌شدهٔ لحظهٔ ثبت نوبت
  • PricingEngine — زنجیرهٔ هفت‌مرحله‌ای مستند بند ۱۲
  • سیاست بیعانه per سرویس/محیط
  • اتصال به BookingService::confirm() (قلاب مرحلهٔ ۶ تسک ۰۷)

نیست: پکیج و دفتر اعتبار (تسک ۱۱)، قوانین قیمت پیشرفته (تسک ۰۹ — DiscountRule موجود فعلاً کافی است).

Endpoint ها

متد مسیر توضیح
GET/POST /api/v1/price-lists لیست قیمت با بازهٔ تاریخ
GET/PATCH/DELETE /api/v1/price-list/{uuid}
PUT /api/v1/price-list/{uuid}/items قیمت سرویس‌ها و آیتم‌ها
POST /api/v1/price-list/{uuid}/activate فعال‌سازی (بررسی تداخل بازه)
POST /api/v1/pricing/quote محاسبهٔ قیمت بدون ثبت
GET /api/v1/appointment/{uuid}/price-snapshot فاکتور تفکیک‌شدهٔ نوبت

معیار پذیرش

  • موفق: لیست قیمت «نیمهٔ دوم ۱۴۰۵» با بازهٔ ۱۴۰۵/۰۷/۰۱ تا ۱۴۰۵/۱۲/۲۹ فعال می‌شود؛ POST /pricing/quote برای تاریخ مهر قیمت جدید و برای شهریور قیمت قبلی می‌دهد.
  • موفق: confirm نوبت → price_snapshots یک ردیف با تفکیک کامل دارد: قیمت پایه، جمع آیتم‌ها، تخفیف‌های اعمال‌شده (با نام و مبلغ هر کدام)، سهم بیمهٔ پایه، سهم تکمیلی، مالیات، مبلغ نهایی، بیعانه.
  • موفق (قانون پنجم): بعد از ثبت نوبت، قیمت سرویس دو برابر می‌شود → GET /appointment/{uuid}/price-snapshot همان اعداد قبلی را می‌دهد.
  • موفق: قیمت override شعبه (تسک ۰۴) بر لیست قیمت محیط اولویت دارد.
  • خطا: دو لیست قیمت فعال با بازهٔ هم‌پوشان برای یک شعبه → 422 هنگام activate.
  • خطا: quote با سرویس محیط دیگر → 404.
  • ⚠️ مرزی: تاریخی که هیچ لیست قیمتی نمی‌پوشاند → fallback به Tariff سال، بعد به ServiceItem.price_rials. هرگز صفر یا خطا.
  • ⚠️ مرزی: تخفیف بیشتر از مبلغ → مبلغ نهایی صفر، نه منفی.
  • ⚠️ مرزی: سقف جمع تخفیف‌ها (max_total_discount_percent per محیط) → اعمال شود.
  • ⚠️ مرزی: بیعانه بیشتر از مبلغ نهایی → 422 هنگام تنظیم سیاست.
  • ⚠️ مرزی: نوبت بدون سرویس (نوبت ویزیت ساده در حالت slot) → snapshot با visit_price_rials موجود ساخته شود، نه خالی.

خروجی

  • src/Pricing/
  • assets/admin/pages/PriceListsPage.tsx + PriceListFormPage.tsx
  • docs/api/pricing.md
  • به‌روزرسانی docs/architecture/insurance-billing-system.md