Files
clinicpro/docs/tasks/task-18-settlement/database.md
T
hamed de1a78a235 feat: Implement SMS sending functionality with KavehNegar and Rangineh providers
- Add SendSmsMessage class for encapsulating SMS message data.
- Create KavehNegarProvider and RanginehProvider classes implementing SmsProviderInterface for sending SMS.
- Implement SmsLogRepository and SmsTemplateRepository for managing SMS logs and templates.
- Develop SendSmsHandler for handling SMS sending messages.
- Create SmsService to manage SMS dispatching and logging.
- Add UserProfileController for managing user profiles with CRUD operations.
- Implement UserProfile entity and repository for user profile data management.
- Update symfony.lock and bootstrap.php for project dependencies and environment setup.
2026-06-09 22:00:34 +03:30

3.7 KiB
Raw Blame History

پایگاه داده — تسک ۱۸: تسویه نماینده

جدول: wallet_transactions (تراکنش‌های کیف پول)

ستون نوع توضیح
id INT UNSIGNED AUTO_INCREMENT PK
uuid CHAR(36) UNIQUE NOT NULL
representation_id INT FK → representations.id NOT NULL نماینده
type VARCHAR(10) NOT NULL credit (واریز) یا debit (برداشت)
amount INT NOT NULL مبلغ به ریال
source VARCHAR(20) NOT NULL appointment یا subscription یا settlement
source_id INT NULL FK به payments.id یا subscription_payments.id یا settlements.id
description VARCHAR(255) NULL توضیح تراکنش
created_at INT NOT NULL Unix timestamp
CREATE INDEX idx_wallet_representation ON wallet_transactions(representation_id);
CREATE INDEX idx_wallet_type ON wallet_transactions(representation_id, type);
CREATE INDEX idx_wallet_source ON wallet_transactions(source, source_id);

جدول: settlements (درخواست‌های تسویه)

ستون نوع توضیح
id INT UNSIGNED AUTO_INCREMENT PK
uuid CHAR(36) UNIQUE NOT NULL
representation_id INT FK → representations.id NOT NULL نماینده درخواست‌دهنده
amount INT NOT NULL مبلغ درخواستی (ریال)
card_number VARCHAR(25) NOT NULL شماره کارت بانکی برداشت
bank_name VARCHAR(50) NOT NULL نام بانک
status VARCHAR(10) DEFAULT 'pending' pending / approved / rejected
description VARCHAR(255) NULL توضیح نماینده
admin_note VARCHAR(255) NULL یادداشت ادمین هنگام تأیید/رد
requested_at INT NOT NULL Unix timestamp — زمان درخواست
resolved_at INT NULL Unix timestamp — زمان تأیید/رد
created_at INT NOT NULL Unix timestamp
updated_at INT NOT NULL Unix timestamp
CREATE INDEX idx_settlements_representation ON settlements(representation_id);
CREATE INDEX idx_settlements_status ON settlements(status);
CREATE UNIQUE INDEX idx_settlements_pending ON settlements(representation_id, status)
  WHERE status = 'pending';
-- این index یکتایی یک pending در هر زمان را enforce می‌کند

فیلد balance در representations

جدول representations باید یک فیلد balance داشته باشد:

ستون نوع توضیح
balance INT DEFAULT 0 موجودی کیف پول (ریال) — همیشه sync با wallet_transactions

نکته: balance باید همزمان با هر تراکنش در wallet_transactions آپدیت شود تا query موجودی سریع باشد (بدون SUM روی wallet_transactions).


فلوی واریز کمیسیون (هنگام پرداخت موفق)

payments.status → 'received'
    ↓
commission = payments.amount × (representation.commission_percent / 100)
    ↓
INSERT INTO wallet_transactions (representation_id, type='credit', amount=commission, source='appointment', source_id=payment.id)
    ↓
UPDATE representations SET balance = balance + commission WHERE id = representation_id

فلوی تسویه (هنگام تأیید ادمین)

PATCH /api/v1/settlement/{uuid}/approve
    ↓
بررسی: representations.balance >= settlements.amount
    ↓
INSERT INTO wallet_transactions (type='debit', amount=settlement.amount, source='settlement', source_id=settlement.id)
    ↓
UPDATE representations SET balance = balance - settlement.amount
    ↓
UPDATE settlements SET status='approved', resolved_at=NOW(), admin_note=...