146 lines
4.2 KiB
PHP
146 lines
4.2 KiB
PHP
<?php
|
|
|
|
namespace App\Service;
|
|
|
|
use App\DataObjects\TicketData;
|
|
use App\DataObjects\TicketFormData;
|
|
use App\Entity\Customer;
|
|
use App\Entity\Payment;
|
|
use App\Entity\Ticket;
|
|
use App\Enum\TicketData as TicketEnum;
|
|
use App\Repository\PaymentRepository;
|
|
use Doctrine\ORM\EntityManagerInterface;
|
|
use Stripe\Checkout\Session;
|
|
use Stripe\Stripe;
|
|
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
|
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
|
|
|
class TicketService
|
|
{
|
|
public function __construct(
|
|
private readonly UrlGeneratorInterface $generator,
|
|
private readonly EntityManagerInterface $em,
|
|
private readonly PaymentRepository $paymentRepository,
|
|
private readonly TicketEmailService $emailService,
|
|
#[Autowire(env: 'STRIPE_SECRET_KEY')]
|
|
string $stripeKey
|
|
) {
|
|
Stripe::setApiKey($stripeKey);
|
|
}
|
|
|
|
public function handleTicketData(TicketFormData $data): Session
|
|
{
|
|
$session = $this->createSession($this->getLineItems($data->tickets, $data->personal->donation), $data->personal->email);
|
|
|
|
$this->saveTicketData($data, $session->id);
|
|
|
|
return $session;
|
|
}
|
|
|
|
public function completePayment(string $sessionId): bool
|
|
{
|
|
if (!$payment = $this->paymentRepository->findOneBy(['sessionId' => $sessionId])) {
|
|
return false;
|
|
}
|
|
|
|
$payment->setCompleted(true);
|
|
$this->em->flush();
|
|
|
|
$this->emailService->sendSuccessEmail($payment);
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
private function saveTicketData(TicketFormData $data, string $sessionId): void
|
|
{
|
|
$payment = (new Payment())
|
|
->setSessionId($sessionId)
|
|
->setCompleted(false)
|
|
->setCustomer($this->createEntityFromData($data))
|
|
->setDonation($data->personal->donation);
|
|
|
|
$this->em->persist($payment);
|
|
$this->em->flush();
|
|
}
|
|
|
|
private function getLineItems(array $tickets, float $donation = null): array
|
|
{
|
|
$lineItems = [];
|
|
|
|
if ($donation) {
|
|
$lineItems[] = [
|
|
'price_data' => [
|
|
'currency' => 'eur',
|
|
'product_data' => [
|
|
'name' => 'Spende',
|
|
],
|
|
'unit_amount' => $donation * 100,
|
|
],
|
|
'quantity' => 1,
|
|
];
|
|
}
|
|
|
|
foreach ($tickets as $ticket) {
|
|
$ticketData = TicketEnum::TICKET_DATA[$ticket->ticketType];
|
|
$lineItems[] = [
|
|
'price_data' => [
|
|
'currency' => 'eur',
|
|
'product_data' => [
|
|
'name' => $ticketData['name'],
|
|
],
|
|
'unit_amount' => $ticketData['price'] * 100,
|
|
],
|
|
'quantity' => 1,
|
|
];
|
|
}
|
|
|
|
return $lineItems;
|
|
}
|
|
|
|
private function createSession(array $lineItems, string $email): Session
|
|
{
|
|
return Session::create([
|
|
'line_items' => $lineItems,
|
|
'mode' => 'payment',
|
|
'customer_email' => $email,
|
|
'success_url' => $this->generator->generate('app_order_success', [], 0) . '?session_id={CHECKOUT_SESSION_ID}',
|
|
'cancel_url' => $this->generator->generate('app_cancelled', [], 0),
|
|
]);
|
|
}
|
|
|
|
private function createEntityFromData(TicketFormData $ticketData): Customer
|
|
{
|
|
$personalData = $ticketData->personal;
|
|
|
|
$entity = (new Customer())
|
|
->setFirstname($personalData->firstname)
|
|
->setLastname($personalData->lastname)
|
|
->setEmail($personalData->email)
|
|
->setPhone($personalData->phone);
|
|
|
|
$entity->addTickets($this->createTicketEntities($ticketData->tickets));
|
|
|
|
$this->em->persist($entity);
|
|
$this->em->flush();
|
|
|
|
return $entity;
|
|
}
|
|
|
|
/**
|
|
* @param TicketData[] $tickets
|
|
*/
|
|
private function createTicketEntities(array $tickets): array
|
|
{
|
|
$entities = [];
|
|
|
|
foreach ($tickets as $ticket) {
|
|
$entities[] = (new Ticket())
|
|
->setType($ticket->ticketType)
|
|
->setFoodType($ticket->foodType)
|
|
->setNote($ticket->note);
|
|
}
|
|
|
|
return $entities;
|
|
}
|
|
} |