feat: add multi-city representation support and domain context resolution

- Created migration to add representation_cities table and domain, is_global fields to representations.
- Implemented SiteContextController to resolve domain to site context (city | representation | unknown).
- Developed DomainContext and DomainContextResolver services for domain mapping.
- Added tests for DomainContextResolver and commission logic based on domain ownership.
This commit is contained in:
hamed
2026-07-09 07:26:58 +03:30
parent 59559e2e31
commit 0750bc9812
56 changed files with 4297 additions and 1600 deletions
+15 -3
View File
@@ -40,10 +40,20 @@ final class PaymentManager
private readonly DoctorRepository $doctorRepo,
private readonly ClinicRepository $clinicRepo,
private readonly CommissionService $commissionService,
private readonly \App\Representation\Service\DomainContextResolver $domainResolver,
private readonly JalaliDateService $jalali,
private readonly string $appBaseUrl,
) {}
/**
* نماینده‌ی مالکِ دامنه‌ای که خرید از آن انجام شده — مبنای کمیسیون دامنه‌محور.
* frontend_address هنگام initiate با allow-list دامنه‌ها validate شده است.
*/
private function bookingRepresentationIdFor(Payment $payment): ?int
{
return $this->domainResolver->resolve($payment->getFrontendAddress())->representationId();
}
/**
* درگاه را برای یک پرداخت pending init می‌کند (ارتباط با بانک).
* موفق → PaymentInitResult؛ ناموفق → false (پرداخت failed و ذخیره‌شده).
@@ -306,7 +316,7 @@ final class PaymentManager
$this->commissionService->processAppointment(
$payment,
$doctor->getRepresentationId(),
$appointment->getBookingRepresentationId(),
$this->bookingRepresentationIdFor($payment),
$doctor->getId(),
);
@@ -339,16 +349,18 @@ final class PaymentManager
$user = $payment->getUser();
$doctor = $this->doctorRepo->findByUser($user);
$bookingRepId = $this->bookingRepresentationIdFor($payment);
if ($doctor !== null) {
$this->subscriptionService->createFromPayment($payment, 'doctor', $doctor->getId(), $periodUuid);
$this->commissionService->processSubscription($payment, $doctor->getRepresentationId(), $doctor->getId(), null);
$this->commissionService->processSubscription($payment, $doctor->getRepresentationId(), $bookingRepId, $doctor->getId(), null);
return;
}
$clinic = $this->clinicRepo->findByUser($user);
if ($clinic !== null) {
$this->subscriptionService->createFromPayment($payment, 'clinic', $clinic->getId(), $periodUuid);
$this->commissionService->processSubscription($payment, $clinic->getRepresentationId(), null, $clinic->getId());
$this->commissionService->processSubscription($payment, $clinic->getRepresentationId(), $bookingRepId, null, $clinic->getId());
}
}