feat: Add online share functionality for secretaries

- Introduced `online_share_enabled` and `online_share_percent` fields in the `doctor_secretaries` table to manage secretary shares from online appointments.
- Added `bank_account` field in the `profiles` table to store user-level IBANs for settlements.
- Created `secretary_earnings` table to track earnings per secretary from online appointments, including a foreign key relationship with `financial_breakdowns`.
- Implemented `SecretaryEarning` entity and repository for managing secretary earnings.
- Developed `SecretaryShareResolver` service to determine which secretaries earn from online payments.
- Added `UserIbanResolver` service to handle user IBAN retrieval and management.
- Created `HasIbansTrait` for entities to manage IBANs in a JSON format.
- Implemented tests for secretary earnings and API endpoints for managing secretary shares and IBANs.
This commit is contained in:
hamed
2026-07-25 18:34:18 +03:30
parent 73a608c3dd
commit 8d2b0d908a
33 changed files with 2564 additions and 76 deletions
@@ -0,0 +1,39 @@
<?php
namespace App\Secretary\Service;
use App\Payment\Entity\Payment;
use App\Secretary\Repository\DoctorSecretaryRepository;
/**
* منشی‌هایی که از یک نوبت **آنلاین** سهم می‌برند.
*
* «آنلاین» یعنی همین مسیر: تقسیم مالی تنها از `PaymentManager` (پرداخت موفق درگاه)
* صدا زده می‌شود؛ نوبتی که در پنل ثبت و قطعی می‌شود از این مسیر عبور نمی‌کند و سهمی
* نمی‌سازد. انتساب بر پایهٔ محیط نوبت است: کلینیک نوبت، وگرنه خودِ پزشک.
*/
class SecretaryShareResolver
{
public function __construct(
private readonly DoctorSecretaryRepository $secretaryRepo,
) {}
/**
* @return list<array{user: \App\Auth\Entity\User, percent: float, relation_uuid: string}>
*/
public function for(Payment $payment): array
{
$appointment = $payment->getAppointment();
if ($appointment === null) {
return [];
}
$rows = $this->secretaryRepo->findOnlineShareRows($appointment->getDoctor(), $appointment->getClinic());
return array_values(array_map(static fn($row) => [
'user' => $row->getSecretary(),
'percent' => $row->effectiveOnlineSharePercent(),
'relation_uuid' => $row->getUuid(),
], $rows));
}
}