feat: implement staff management and subscription system
- Added StaffController for managing clinic staff, including listing, creating, updating, and toggling staff status. - Created ClinicStaff entity and repository for staff data handling. - Developed SubscriptionController to manage subscription plans and periods, including trial subscriptions. - Introduced SubscriptionPlan, SubscriptionPeriod, and ClinicSubscription entities for subscription management. - Implemented SubscriptionService for handling subscription logic, including trial activation and subscription creation from payments. - Added necessary repositories for subscription entities to facilitate data access and manipulation.
This commit is contained in:
@@ -5,6 +5,8 @@ namespace App\Payment\Controller;
|
||||
use App\Appointment\Entity\Appointment;
|
||||
use App\Appointment\Repository\AppointmentRepository;
|
||||
use App\Auth\Entity\User;
|
||||
use App\Clinic\Repository\ClinicRepository;
|
||||
use App\Doctor\Repository\DoctorRepository;
|
||||
use App\Payment\Entity\Payment;
|
||||
use App\Payment\Gateway\MellatGateway;
|
||||
use App\Payment\Gateway\SepGateway;
|
||||
@@ -12,6 +14,8 @@ use App\Payment\Repository\PaymentRepository;
|
||||
use App\Payment\Service\CircuitBreakerService;
|
||||
use App\Shared\Constant\ErrorCodes;
|
||||
use App\Shared\Controller\BaseController;
|
||||
use App\Sms\Service\SmsWalletService;
|
||||
use App\Subscription\Service\SubscriptionService;
|
||||
use OpenApi\Attributes as OA;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
@@ -35,6 +39,10 @@ class PaymentController extends BaseController
|
||||
private readonly MellatGateway $mellat,
|
||||
private readonly SepGateway $sep,
|
||||
private readonly CircuitBreakerService $circuitBreaker,
|
||||
private readonly SubscriptionService $subscriptionService,
|
||||
private readonly SmsWalletService $smsWalletService,
|
||||
private readonly DoctorRepository $doctorRepo,
|
||||
private readonly ClinicRepository $clinicRepo,
|
||||
private readonly string $appBaseUrl,
|
||||
private readonly string $allowedFrontendHosts = '',
|
||||
) {}
|
||||
@@ -256,6 +264,12 @@ class PaymentController extends BaseController
|
||||
$payment->setReferenceId($result->referenceId);
|
||||
$this->paymentRepo->save($payment);
|
||||
|
||||
if ($payment->getType() === Payment::TYPE_SUBSCRIPTION) {
|
||||
$this->handleSubscriptionActivation($payment);
|
||||
} elseif ($payment->getType() === Payment::TYPE_SMS_WALLET) {
|
||||
$this->handleSmsWalletCharge($payment);
|
||||
}
|
||||
|
||||
return $this->redirectToFrontend($payment, true);
|
||||
}
|
||||
|
||||
@@ -380,7 +394,11 @@ class PaymentController extends BaseController
|
||||
return $this->error(ErrorCodes::ERR_PAYMENT_001, ErrorCodes::message(ErrorCodes::ERR_PAYMENT_001), 503);
|
||||
}
|
||||
|
||||
$payment = new Payment($user, $amountRials, $gatewayName, Payment::TYPE_SUBSCRIPTION, $frontendAddress);
|
||||
$periodUuid = trim($data['period_uuid'] ?? '');
|
||||
$payment = new Payment($user, $amountRials, $gatewayName, Payment::TYPE_SUBSCRIPTION, $frontendAddress);
|
||||
if ($periodUuid !== '') {
|
||||
$payment->setMetadata(['period_uuid' => $periodUuid]);
|
||||
}
|
||||
$this->paymentRepo->save($payment);
|
||||
|
||||
$callbackUrl = $this->appBaseUrl . '/api/v1/subscription-payment/callback/' . $gatewayName . '?order_id=' . $payment->getOrderId();
|
||||
@@ -540,6 +558,41 @@ class PaymentController extends BaseController
|
||||
return false;
|
||||
}
|
||||
|
||||
private function handleSmsWalletCharge(Payment $payment): void
|
||||
{
|
||||
$meta = $payment->getMetadata() ?? [];
|
||||
$entityType = $meta['entity_type'] ?? null;
|
||||
$entityId = isset($meta['entity_id']) ? (int) $meta['entity_id'] : null;
|
||||
|
||||
if ($entityType === null || $entityId === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$wallet = $this->smsWalletService->getOrCreate($entityType, $entityId);
|
||||
$this->smsWalletService->charge($wallet, $payment->getAmountRials(), $payment);
|
||||
}
|
||||
|
||||
private function handleSubscriptionActivation(Payment $payment): void
|
||||
{
|
||||
$meta = $payment->getMetadata() ?? [];
|
||||
$periodUuid = $meta['period_uuid'] ?? null;
|
||||
if ($periodUuid === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$user = $payment->getUser();
|
||||
$doctor = $this->doctorRepo->findByUser($user);
|
||||
if ($doctor !== null) {
|
||||
$this->subscriptionService->createFromPayment($payment, 'doctor', $doctor->getId(), $periodUuid);
|
||||
return;
|
||||
}
|
||||
|
||||
$clinic = $this->clinicRepo->findByUser($user);
|
||||
if ($clinic !== null) {
|
||||
$this->subscriptionService->createFromPayment($payment, 'clinic', $clinic->getId(), $periodUuid);
|
||||
}
|
||||
}
|
||||
|
||||
private function redirectToFrontend(Payment $payment, bool $success): \Symfony\Component\HttpFoundation\Response
|
||||
{
|
||||
$base = $payment->getFrontendAddress();
|
||||
|
||||
Reference in New Issue
Block a user