<?php
namespace App\Controller\Front;
use App\Constant\BookingStatus;
use App\Constant\DocumentStatus;
use App\Constant\NotificationType;
use App\Constant\PaymentStatus;
use App\Controller\AppController;
use App\Entity\AccommodationOccupancy;
use App\Entity\BookingRoom;
use App\Entity\Inventory;
use App\Entity\Page;
use App\Entity\UserDocument;
use App\Form\Front\UserIdentityType;
use App\Repository\BookingRepository;
use App\Service\DocuSignService;
use App\Service\FileUploader;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Stripe\Charge;
use Stripe\PaymentIntent;
use Stripe\Stripe;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\RouterInterface;
/**
* @Route("/compte", name="front_account_")
* @Security("is_granted('ROLE_USER')")
*/
class AccountController extends AppController
{
/**
* @Route("", name="dashboard", methods={"GET"})
*/
public function dashboard(Request $request)
{
$page = new Page();
$page->setMetaTitle("Espace Client - Citizens");
return $this->render('front/account/dashboard.html.twig', [
'page' => $page,
]);
}
/**
* @Route("/documents", name="documents", methods={"GET"})
*/
public function documents(Request $request)
{
$page = new Page();
$page->setMetaTitle("Documents - Espace Client - Citizens");
return $this->render('front/account/documents.html.twig', [
'page' => $page,
]);
}
/**
* @Route("/informations", name="informations")
*/
public function informations(Request $request)
{
$user = $this->getUser();
$form = $this->createForm(UserIdentityType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$this->em->persist($user);
$this->em->flush();
return $this->redirectToRoute("front_account_informations");
}
$page = new Page();
$page->setMetaTitle("Informations personnelles - Espace Client - Citizens");
return $this->render('front/account/informations.html.twig', [
'page' => $page,
'form' => $form->createView(),
]);
}
/**
* @Route("/loyers", name="rents", methods={"GET"})
*/
public function rents(Request $request, ParameterBagInterface $params)
{
$user = $this->getUser();
Stripe::setApiKey($params->get('stripe_secret_key'));
$payments = Charge::all(["customer" => $user->getStripeId()]);
$page = new Page();
$page->setMetaTitle("Mes loyers - Espace Client - Citizens");
return $this->render('front/account/rents.html.twig', [
'page' => $page,
'payments' => $payments,
]);
}
/**
* @Route("/etat-des-lieux", name="inventory", methods={"GET"})
*/
public function inventory(Request $request)
{
$page = new Page();
$page->setMetaTitle("Mon état des lieux - Espace Client - Citizens");
return $this->render('front/account/inventory.html.twig', [
'page' => $page,
]);
}
/**
* @Route("/reservation/{reference}", name="booking", methods={"GET"})
*/
public function booking(Request $request, $reference, BookingRepository $bookingRepository)
{
$user = $this->getUser();
$booking = $bookingRepository->findOneBy(["user" => $user, "reference" => $reference]);
if(empty($booking)) throw $this->createNotFoundException('Réservation introuvable');
$bookingRoom = $booking->getRoomByUser($user);
$page = new Page();
$page->setMetaTitle("Réservation ".$booking->getReference()." - Espace Client - Citizens");
return $this->render('front/account/booking.html.twig', [
'page' => $page,
'booking' => $booking,
'bookingRoom' => $bookingRoom,
]);
}
/**
* @Route("/{bookingRoom}/payer-caution-premier-loyer", name="first_rent_payment")
*/
public function first_rent_payment(Request $request, BookingRoom $bookingRoom, ParameterBagInterface $params)
{
if(PaymentStatus::SENT !== $bookingRoom->getFirstRentPayment()->getStatus() || ($bookingRoom->getUser()->getId() !== $this->getUser()->getId())) throw $this->createNotFoundException('Not found');
Stripe::setApiKey($params->get('stripe_secret_key'));
$intent = PaymentIntent::retrieve($bookingRoom->getFirstRentPayment()->getStripeId());
if ($intent->status === "succeeded") {
return $this->redirectToRoute("front_account_first_rent_payment_confirm", ["bookingRoom" => $bookingRoom->getId()]);
}
$page = new Page();
$page->setMetaTitle("Paiement de la caution et de mon premier loyer - Espace Client - Citizens");
return $this->render('front/account/first-rent-payment.html.twig', [
'page' => $page,
'bookingRoom' => $bookingRoom,
'stripe' => [
'intent' => $intent,
]
]);
}
/**
* @Route("/{bookingRoom}/payer-caution-premier-loyer/confirmation", name="first_rent_payment_confirm")
*/
public function first_rent_payment_confirm(Request $request, BookingRoom $bookingRoom, ParameterBagInterface $params)
{
if(PaymentStatus::SENT !== $bookingRoom->getFirstRentPayment()->getStatus() || ($bookingRoom->getUser()->getId() !== $this->getUser()->getId())) throw $this->createNotFoundException('Not found');
Stripe::setApiKey($params->get('stripe_secret_key'));
$intent = PaymentIntent::retrieve($bookingRoom->getFirstRentPayment()->getStripeId());
if ($intent->status === "succeeded") {
$bookingRoom->getFirstRentPayment()->setStatus(PaymentStatus::PAID);
// --------------------------------------------
// If all rooms first rent are paid, change booking status
if($bookingRoom->getBooking()->isAllRoomsFirstRentPayed()){
$booking = $bookingRoom->getBooking();
if($booking->getInventory() instanceof Inventory) {
$booking->setStatus(BookingStatus::INVENTORY);
} else {
$booking->setStatus(BookingStatus::INVENTORY_DATE);
}
$this->em->persist($booking);
$this->notifier->admin(NotificationType::ADMIN_BOOKING_DEPOSIT_PAID, ["booking" => $booking]);
}
$this->em->persist($bookingRoom);
$this->em->flush();
}
$page = new Page();
$page->setMetaTitle("Paiement de la caution et de mon premier loyer - Espace Client - Citizens");
return $this->render('front/account/first-rent-payment-confirm.html.twig', [
'page' => $page,
'bookingRoom' => $bookingRoom,
]);
}
/**
* @Route("/lease-signer-redirect/{id}", name="lease_signer_redirect")
*/
public function redirectToLeaseSigningPage(BookingRoom $bookingRoom, DocuSignService $docuSignService)
{
if($bookingRoom->getBooking() && $this->getUser()->getId() === $bookingRoom->getUser()->getId()) {
return $this->redirect($docuSignService->getDocumentSigningPageUrl(
$bookingRoom->getBooking(),
$bookingRoom->getUser(),
$bookingRoom->getBooking()->getLease()->getDocusignEnvelopeId(),
$this->generateUrl('front_account_documents', [], RouterInterface::ABSOLUTE_URL)
));
} else {
return $this->redirectToRoute('front_account_documents');
}
}
/**
* @Route("/sepa-signer-redirect/{id}", name="sepa_signer_redirect")
*/
public function redirectToSepaSigningPage(BookingRoom $bookingRoom, DocuSignService $docuSignService)
{
if($bookingRoom->getBooking() && $this->getUser()->getId() === $bookingRoom->getUser()->getId()) {
return $this->redirect($docuSignService->getDocumentSigningPageUrl(
$bookingRoom->getBooking(),
$bookingRoom->getUser(),
$bookingRoom->getSepa()->getDocusignEnvelopeId(),
$this->generateUrl('front_account_documents', [], RouterInterface::ABSOLUTE_URL)
));
} else {
return $this->redirectToRoute('front_account_documents');
}
}
/**
* @Route("/inventory-signer-redirect/{id}", name="inventory_signer_redirect")
*/
public function redirectToInventorySigningPage(BookingRoom $bookingRoom, DocuSignService $docuSignService)
{
if($bookingRoom->getBooking() && $this->getUser()->getId() === $bookingRoom->getUser()->getId()) {
$inventory = $bookingRoom->getBooking()->getInventory();
return $this->redirect($docuSignService->getInventorySigningPageUrl(
$inventory,
$this->generateUrl('front_inventory_signature_callback', [
"id" => $inventory->getId(),
"token" => $inventory->getToken(),
], RouterInterface::ABSOLUTE_URL)
));
} else {
return $this->redirectToRoute('front_account_documents');
}
}
/**
* @Route("/leave-inventory-signer-redirect/{id}", name="leave_inventory_signer_redirect")
*/
public function redirectToLeavingInventorySigningPage(AccommodationOccupancy $occupancy, DocuSignService $docuSignService)
{
if($occupancy->getLeavingInventory() && $this->getUser()->getId() === $occupancy->getUser()->getId()) {
$inventory = $occupancy->getLeavingInventory();
return $this->redirect($docuSignService->getInventorySigningPageUrl(
$inventory,
$this->generateUrl('front_inventory_signature_callback', [
"id" => $inventory->getId(),
"token" => $inventory->getToken(),
], RouterInterface::ABSOLUTE_URL)
));
} else {
return $this->redirectToRoute('front_account_documents');
}
}
/**
* @Route("/document", name="document", methods={"GET"})
*/
public function document(Request $request)
{
$user = $this->getUser();
$documentType = $request->query->get('type');
$documents = $user->getDocuments()->filter(function(UserDocument $document) use($documentType){
return $document->getType() === $documentType;
});
$html = $this->render("front/_shared/document-upload.html.twig", ["user" => $user, "type" => $documentType])->getContent();
return $this->json([
"html" => $html,
]);
}
/**
* @Route("/document/upload", name="document_upload", methods={"POST"})
*/
public function upload_document(Request $request, FileUploader $fileUploader)
{
$user = $this->getUser();
$attachment = null;
foreach ($request->files as $uploadedFile) {
if($uploadedFile->isValid() && $fileUploader->validTypes($uploadedFile, $request->get("type"))) {
$uploadFolder = UserDocument::uploadFolder();
$fileName = $fileUploader->upload($uploadedFile, $uploadFolder, true);
$attachment = new UserDocument();
$attachment->setPrivate(true);
$attachment->setName($fileName);
$attachment->setCreatedAt(new \DateTime());
$attachment->setUser($user);
$attachment->setType($request->get("type"));
$attachment->setStatus(DocumentStatus::SENT);
$this->em->persist($attachment);
$this->notifier->admin(NotificationType::ADMIN_USER_DOCUMENT_SUBMITTED, ["user" => $user, "document" => $attachment]);
}
}
$this->em->flush();
if($attachment instanceof UserDocument){
$response = new JsonResponse($attachment->toArray());
}
else{
$response = new JsonResponse(['error' => true], 400);
}
return $response;
}
/**
* @Route("/{bookingRoom}/frais-etat-des-lieux", name="previous_room_fees_payment")
*/
public function previous_room_fees_payment(Request $request, BookingRoom $bookingRoom, ParameterBagInterface $params)
{
if(PaymentStatus::SENT !== $bookingRoom->getPreviousRoomPayment()->getStatus() || ($bookingRoom->getUser()->getId() !== $this->getUser()->getId())) throw $this->createNotFoundException('Not found');
Stripe::setApiKey($params->get('stripe_secret_key'));
$intent = PaymentIntent::retrieve($bookingRoom->getPreviousRoomPayment()->getStripeId());
if ($intent->status === "succeeded") {
return $this->redirectToRoute("front_account_previous_room_fees_payment_confirm", ["bookingRoom" => $bookingRoom->getId()]);
}
$page = new Page();
$page->setMetaTitle("Paiement frais état des lieux - Espace Client - Citizens");
return $this->render('front/account/previous-room-fees-payment.html.twig', [
'page' => $page,
'bookingRoom' => $bookingRoom,
'stripe' => [
'intent' => $intent,
]
]);
}
/**
* @Route("/{bookingRoom}/frais-etat-des-lieux/confirmation", name="previous_room_fees_payment_confirm")
*/
public function previous_room_fees_payment_confirm(Request $request, BookingRoom $bookingRoom, ParameterBagInterface $params)
{
dump("test");
if(PaymentStatus::SENT !== $bookingRoom->getPreviousRoomPayment()->getStatus() || ($bookingRoom->getUser()->getId() !== $this->getUser()->getId())) throw $this->createNotFoundException('Not found');
Stripe::setApiKey($params->get('stripe_secret_key'));
$intent = PaymentIntent::retrieve($bookingRoom->getPreviousRoomPayment()->getStripeId());
if ($intent->status === "succeeded") {
$bookingRoom->getPreviousRoomPayment()->setStatus(PaymentStatus::PAID);
$this->em->persist($bookingRoom);
$this->em->flush();
}
$page = new Page();
$page->setMetaTitle("Paiement frais état des lieux - Espace Client - Citizens");
return $this->render('front/account/previous-room-fees-payment-confirm.html.twig', [
'page' => $page,
'bookingRoom' => $bookingRoom,
]);
}
}