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
+14
View File
@@ -3,6 +3,7 @@
namespace App\UserProfile\Entity;
use App\Auth\Entity\User;
use App\Shared\Entity\HasIbansTrait;
use Doctrine\ORM\Mapping as ORM;
use App\UserProfile\Repository\UserProfileRepository;
use Symfony\Component\Uid\Uuid;
@@ -13,6 +14,8 @@ use Symfony\Component\Uid\Uuid;
#[ORM\UniqueConstraint(name: 'uniq_profiles_national_code', columns: ['national_code'])]
class UserProfile
{
use HasIbansTrait;
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
@@ -103,6 +106,14 @@ class UserProfile
#[ORM\Column(type: 'string', length: 255, nullable: true)]
private ?string $avatar = null;
/**
* ۰ تا ۲ شماره شبای کاربر برای تسویه — همان ساختار نماینده
* ({@see \App\Shared\Entity\HasIbansTrait}). محلِ درستِ شبا کاربر است نه نقش،
* چون یک کاربر می‌تواند چند رابطهٔ منشی داشته باشد.
*/
#[ORM\Column(name: 'bank_account', type: 'json', nullable: true)]
private ?array $bankAccount = null;
#[ORM\Column(name: 'created_at', type: 'integer')]
private int $createdAt;
@@ -177,6 +188,9 @@ class UserProfile
public function setDescription(?string $v): self { $this->description = $v; $this->touch(); return $this; }
public function setAvatar(?string $v): self { $this->avatar = $v; $this->touch(); return $this; }
public function getBankAccount(): ?array { return $this->bankAccount; }
public function setBankAccount(?array $v): self { $this->bankAccount = $v; $this->touch(); return $this; }
private function touch(): void { $this->updatedAt = time(); }
public function toArray(): array