src/Bus/BookingController.php line 472

Open in your IDE?
  1. <?php
  2. namespace App\Bus;
  3. use App\Entity\Bus\BookingMpesa;
  4. use App\Entity\Bus\BookingSeat;
  5. use App\Entity\Bus\Reservation;
  6. use App\Entity\Bus\RouteFareRule;
  7. use App\Entity\Bus\Seat;
  8. use App\Entity\Bus\Stop;
  9. use App\Entity\Bus\Trip;
  10. use App\Entity\Bus\TripVehicle;
  11. use App\Entity\Mpesa;
  12. use App\Entity\MpesaAuth;
  13. use App\Entity\MpesaPayment;
  14. use App\Entity\User;
  15. use App\Entity\UserStation;
  16. use App\Entity\Vehicle;
  17. use App\Entity\WayBill;
  18. use App\Form\Bus\BookingType;
  19. use App\Form\Bus\ReserveType;
  20. use App\Form\Bus\RouteeType;
  21. use App\Form\Bus\TripType;
  22. use DateTime;
  23. use Doctrine\DBAL\Exception;
  24. use Doctrine\Persistence\ManagerRegistry;
  25. use Doctrine\Persistence\ObjectManager;
  26. use JMS\Serializer\SerializationContext;
  27. use JMS\Serializer\SerializerBuilder;
  28. use Mpdf\Output\Destination;
  29. use Mpdf\QrCode\Output\Png;
  30. use Mpdf\QrCode\QrCode;
  31. use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule;
  32. use Sasedev\MpdfBundle\Factory\MpdfFactory;
  33. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  34. use Symfony\Component\Form\FormError;
  35. use Symfony\Component\HttpFoundation\JsonResponse;
  36. use Symfony\Component\HttpFoundation\Request;
  37. use Symfony\Component\HttpFoundation\RequestStack;
  38. use Symfony\Component\HttpFoundation\Response;
  39. use Symfony\Component\Routing\Annotation\Route;
  40. class BookingController extends AbstractController{
  41. private ManagerRegistry $registry;
  42. private ObjectManager $entityManager;
  43. private RequestStack $requestStack;
  44. public function __construct(ManagerRegistry $registry, RequestStack $requestStack)
  45. {
  46. $this->entityManager = $registry->getManager();
  47. $this->requestStack = $requestStack;
  48. }
  49. /** @Route("/routes", name="routesHome") */
  50. public function routesHome(Request $request)
  51. {
  52. $em = $this->entityManager;
  53. /** @var UserStation $userTown */
  54. $userTown = $em->getRepository(UserStation::class)->findOneBy([
  55. 'user' => $this->getUser(),
  56. 'isActive' => true
  57. ], ['id' => 'DESC']);
  58. $route = new \App\Entity\Bus\Route();
  59. $route->setCreatedAt(new DateTime());
  60. $route->setCreatedBy($this->getUser());
  61. $routeForm = $this->createForm(RouteeType::class, $route);
  62. $routeForm->handleRequest($request);
  63. if ($routeForm->isSubmitted() && $routeForm->isValid()) {
  64. dump($route);
  65. $this->entityManager->persist($route);
  66. $this->entityManager->flush();
  67. return $this->redirectToRoute('routesHome');
  68. }
  69. /** @var \App\Entity\Bus\Route[] $routes */
  70. $routes = $this->entityManager->getRepository(\App\Entity\Bus\Route::class)->findAll();
  71. return $this->render('bus/routes.html.twig', [
  72. 'user_town' => $userTown,
  73. 'routes' => $routes,
  74. 'routeForm' => $routeForm->createView()
  75. ]);
  76. }
  77. /** @Route("/routes/{route}/edit", name="routesEdit") */
  78. public function routesEdit(Request $request, \App\Entity\Bus\Route $route)
  79. {
  80. $em = $this->entityManager;
  81. /** @var UserStation $userTown */
  82. $userTown = $em->getRepository(UserStation::class)->findOneBy([
  83. 'user' => $this->getUser(),
  84. 'isActive' => true
  85. ], ['id' => 'DESC']);
  86. $routeForm = $this->createForm(RouteeType::class, $route);
  87. $routeForm->handleRequest($request);
  88. if ($routeForm->isSubmitted() && $routeForm->isValid()) {
  89. // $route->setStops($route->getStops());
  90. $this->entityManager->persist($route);
  91. $this->entityManager->flush();
  92. $this->addFlash('success', 'Route updated successfully');
  93. return $this->redirectToRoute('routesHome');
  94. }
  95. /** @var \App\Entity\Bus\Route[] $routes */
  96. $routes = $this->entityManager->getRepository(\App\Entity\Bus\Route::class)->findAll();
  97. return $this->render('bus/routes_edit.html.twig', [
  98. 'user_town' => $userTown,
  99. 'routes' => $routes,
  100. 'routeForm' => $routeForm->createView()
  101. ]);
  102. }
  103. /** @Route("/", name="tripsHome") */
  104. public function tripsHome(Request $request)
  105. {
  106. $em = $this->entityManager;
  107. $date = $request->get('trip_date');
  108. $today = new \DateTimeImmutable();
  109. if (!$date) {
  110. $date = $today->format('Y-m-d');
  111. }
  112. /** @var UserStation $userTown */
  113. $userTown = $em->getRepository(UserStation::class)->findOneBy([
  114. 'user' => $this->getUser(),
  115. 'isActive' => true
  116. ], ['id' => 'DESC']);
  117. $stationId = $userTown->getStation()->getId();
  118. // MOMBASA and MERU scenario 1
  119. /* if a station origin is in current station show bus route */
  120. // $sql = "SELECT a.id, a.route_name FROM bus_route a WHERE origin = {$stationId}";
  121. // EMBU scenario 2
  122. /* if a station is a stop in a main route and not the destination */
  123. $sql = "SELECT a.id, a.route_name FROM bus_route a
  124. JOIN bus_stop b ON b.route_id = a.id
  125. WHERE b.station_id = {$stationId}
  126. AND b.route_type = 'MAIN'
  127. AND a.destination != {$stationId} GROUP BY a.id";
  128. $conn = $this->entityManager->getConnection();
  129. $availableRoutes = null;
  130. try {
  131. $stmt = $conn->prepare($sql);
  132. $availableRoutes = $stmt->executeQuery()->fetchAllAssociative();
  133. } catch (\Exception $e) {
  134. }
  135. /** @var Trip[] $trips */
  136. $trips = $this->entityManager->getRepository(Trip::class)->findActiveTrips($date, $userTown->getStation()->getId(), 'MAIN');
  137. if($trips){
  138. return $this->render('bus/trips.html.twig', [
  139. 'user_town' => $userTown,
  140. 'trips' => $trips,
  141. 'date' => $date
  142. ]);
  143. }else {
  144. foreach ($availableRoutes as $index => $availableRoute) {
  145. $route = $em->getRepository(\App\Entity\Bus\Route::class)->findOneBy([
  146. 'id' => $availableRoute['id']
  147. ]);
  148. $this->addTrip($route, $date);
  149. }
  150. }
  151. /** @var Trip[] $trips */
  152. $trips = $this->entityManager->getRepository(Trip::class)->findActiveTrips($date, $userTown->getStation()->getId(), 'MAIN');
  153. return $this->render('bus/trips.html.twig', [
  154. 'user_town' => $userTown,
  155. 'trips' => $trips,
  156. 'date' => $date
  157. ]);
  158. }
  159. /** @Route("/trips/new", name="newTrip") */
  160. public function newTrip(Request $request)
  161. {
  162. $em = $this->entityManager;
  163. /** @var UserStation $userTown */
  164. $userTown = $em->getRepository(UserStation::class)->findOneBy([
  165. 'user' => $this->getUser(),
  166. 'isActive' => true
  167. ], ['id' => 'DESC']);
  168. $trip = new Trip();
  169. $tripForm = $this->createForm(TripType::class, $trip);
  170. $tripForm->handleRequest($request);
  171. if ($tripForm->isSubmitted() && $tripForm->isValid()) {
  172. $date = $trip->getTripDate();
  173. $d = $date->format('Y-m-d');
  174. $sql = "SELECT count(*) total FROM bus_trip a WHERE a.route_id = {$trip->getRoute()->getId()}
  175. AND DATE(a.trip_date) = CAST('{$d}' as date)";
  176. $conn = $this->entityManager->getConnection();
  177. $stmt = $conn->prepare($sql);
  178. $thisDaysTrips = $stmt->executeQuery()->fetchAssociative();
  179. $sameRouteTrips = $thisDaysTrips['total'];
  180. $trip->setTripIndex($sameRouteTrips + 1);
  181. $trip->setCreatedBy($this->getUser());
  182. $trip->setCreatedAt(new DateTime());
  183. /** @var Vehicle $vehicle */
  184. $vehicle = $tripForm->get('vehicle')->getData();
  185. $seats = [];
  186. for ($i = 1; $i <= $vehicle->getPassengerCapacity(); $i++) {
  187. $seat = new Seat();
  188. $seat->setStatus('AVAILABLE');
  189. $seat->setSeatNumber($i);
  190. $seat->setTrip($trip);
  191. $seat->setIsBooked(false);
  192. $seat->setCreatedAt(new DateTime());
  193. $seats[] = $seat;
  194. }
  195. $trip->setSeats($seats);
  196. $tripVehicle = new TripVehicle();
  197. $tripVehicle->setCreatedAt(new DateTime());
  198. $tripVehicle->setTrip($trip);
  199. $tripVehicle->setCreatedBy($this->getUser());
  200. $tripVehicle->setIsCancelled(false);
  201. $tripVehicle->setVehicle($vehicle);
  202. // $this->entityManager->persist($tripVehicle);
  203. // $this->entityManager->persist($trip);
  204. // $this->entityManager->flush();
  205. return $this->redirectToRoute('tripsHome');
  206. }
  207. return $this->render('bus/new_trip.html.twig', [
  208. 'tripForm' => $tripForm->createView(),
  209. 'user_town' => $userTown
  210. ]);
  211. }
  212. /** @Route("/trip/{trip}", name="viewTrip") */
  213. public function bookingTrip(Request $request, Trip $trip)
  214. {
  215. $currentSeat = $request->get('currentSeat') ? $request->get('currentSeat') : -1;
  216. $numberOfSeats = 49;
  217. $doorRow = 0;
  218. $lastRow = 12;
  219. // $seats = [];
  220. $rows = 0;
  221. /** @var UserStation $userTown */
  222. $userTown = $this->entityManager->getRepository(UserStation::class)->findOneBy([
  223. 'user' => $this->getUser(),
  224. 'isActive' => true
  225. ], ['id' => 'DESC']);
  226. // dump($userTown);
  227. $stop = $this->entityManager->getRepository(Stop::class)->findCurrentStop($trip->getRoute(), $userTown->getStation());
  228. // dump($stop);
  229. // die;
  230. $currentStop = null;
  231. if ($stop) {
  232. $currentStop = $this->entityManager->getRepository(Stop::class)->findOneBy([
  233. 'id' => $stop['id']
  234. ]);
  235. }
  236. if (!$currentStop) {
  237. return $this->redirectToRoute('tripsHome');
  238. }
  239. $seats = $this->entityManager->getRepository(BookingSeat::class)->findAllSeats($trip, $currentStop);
  240. // dump($seats);
  241. // dump('currentSeat',$currentSeat);
  242. return $this->render('bus/booking.html.twig', [
  243. 'seats' => $seats,
  244. 'rows' => $rows,
  245. 'doorRow' => $doorRow,
  246. 'lastRow' => $lastRow,
  247. 'workingSeat' => $currentSeat,
  248. 'trip' => $trip
  249. ]);
  250. }
  251. /** @Route("/trip/{trip}/json", name="viewJsonTrip") */
  252. public function getTripSeatsJson(Request $request, Trip $trip)
  253. {
  254. $context = new SerializationContext();
  255. $context->setSerializeNull(true);
  256. $page = $request->request->get('page') > 1 ? $request->request->get('page') : 1;
  257. $rows = $request->request->get('rows') > 1 ? $request->request->get('rows') : 50;
  258. $offset = ($page - 1) * $rows;
  259. $serializer = SerializerBuilder::create()->build();
  260. $filterRules = $request->request->get('filterRules');
  261. $seats = $this->entityManager->getRepository(BookingSeat::class)->findAllTripSeats($filterRules, $offset, $rows, $trip);
  262. return new JsonResponse($seats);
  263. }
  264. /** @Route("/trip/{trip}/manifest/pdf", name="viewTripManifest") */
  265. public function getManifestBySearch(Request $request, Trip $trip, MpdfFactory $mpdfFactory)
  266. {
  267. $context = new SerializationContext();
  268. $context->setSerializeNull(true);
  269. $page = $request->request->get('page') > 1 ? $request->request->get('page') : 1;
  270. $rows = $request->request->get('rows') > 1 ? $request->request->get('rows') : 50;
  271. $offset = ($page - 1) * $rows;
  272. $filterRules = $request->request->get('filterRules');
  273. $seats = $this->entityManager->getRepository(BookingSeat::class)->findAllTripSeats($filterRules, $offset, $rows, $trip);
  274. $data = $this->jsonTestData();
  275. // dump($fontData);die;
  276. $mPdf = $mpdfFactory->createMpdfObject([
  277. 'format' => [80, 500],
  278. 'margin_header' => 5,
  279. 'margin_footer' => 5,
  280. 'margin_left' => 5,
  281. 'margin_right' => 5,
  282. 'margin_top' => 0,
  283. 'margin_bottom' => 0,
  284. 'autoPageBreak' => false,
  285. 'orientation' => 'P'
  286. ]);
  287. $date = new DateTime();
  288. $time = $date->getTimestamp();
  289. try {
  290. $receiptType = 'MANIFEST';
  291. $logoImage = file_get_contents('../public/bus/bus_1.png');
  292. $logoBase64 = base64_encode($logoImage);
  293. $mPdf->WriteHTML($this->renderView('bus/manifest/manifest.html.twig', [
  294. 'passengers' => $seats,
  295. 'trip' => $trip,
  296. 'busLogo' => $logoBase64
  297. ]));
  298. $file = "../manifests/manifest_.pdf";
  299. // return $MpdfFactory->createDownloadResponse($mPdf, "ticket_{$ticketId}.pdf", Response::HTTP_OK, ["Set-Cookie", "fileDownload=true; path=/"]);
  300. return $mpdfFactory->createInlineResponse($mPdf, $file);
  301. } catch (\Exception $e) {
  302. return new Response($e->getMessage(), Response::HTTP_BAD_REQUEST);
  303. }
  304. // return new JsonResponse($seats);
  305. }
  306. /** @Route("/trip/{trip}/stops", name="viewTripStopsSearchCombo") */
  307. public function getTripStops(Trip $trip)
  308. {
  309. $em = $this->entityManager;
  310. /** @var \App\Entity\Bus\Route $route */
  311. $route = $em->getRepository(\App\Entity\Bus\Route::class)->findOneBy([
  312. 'id' => $trip->getRoute()->getId()
  313. ]);
  314. $sql = "SELECT a.id,b.station_name FROM bus_stop a
  315. JOIN station b ON b.id = a.station_id
  316. WHERE a.route_id = {$route->getId()}";
  317. $conn = $em->getConnection();
  318. $stmt = $conn->prepare($sql);
  319. $stops = $stmt->executeQuery()->fetchAllAssociative();
  320. array_push($stops, ['id' => '', 'station_name' => 'ALL STOPS']);
  321. return new JsonResponse($stops);
  322. }
  323. /** @Route("/trip/{trip}/seat/{seat}", name="viewTripSeat") */
  324. public function bookingTripSeat(Request $request, $seat, Trip $trip)
  325. {
  326. $em = $this->entityManager;
  327. /** @var Seat $busSeat */
  328. $busSeat = $em->getRepository(Seat::class)->findOneBy([
  329. 'trip' => $trip,
  330. 'seatNumber' => $seat
  331. ]);
  332. $seatBooking = $em->getRepository(BookingSeat::class)->findOneBy([
  333. 'seat' => $busSeat
  334. ]);
  335. $bookingUserStation = null;
  336. if ($seatBooking) {
  337. /** @var UserStation $userTown */
  338. $bookingUserStation = $this->entityManager->getRepository(UserStation::class)->findOneBy([
  339. 'user' => $seatBooking->getCreatedBy(),
  340. 'isActive' => true
  341. ], ['id' => 'DESC']);
  342. }
  343. /** @var User $user */
  344. $user = $this->getUser();
  345. /** @var UserStation $userStation */
  346. $userStation = $em->getRepository(UserStation::class)->findOneBy([
  347. 'user' => $user,
  348. 'isActive' => true
  349. ]);
  350. $mpesaAuth = $em->getRepository(MpesaAuth::class)->findOneBy([
  351. 'station' => $userStation->getStation(),
  352. 'shortCodeType' => 'IMANI'
  353. ]);
  354. if (!$mpesaAuth) {
  355. $mpesaAuth = $em->getRepository(MpesaAuth::class)->findOneBy([
  356. 'station' => 2,
  357. 'shortCodeType' => 'IMANI'
  358. ]);
  359. }
  360. $reserve = $em->getRepository(Reservation::class)->findOneBy([
  361. 'seat' => $busSeat
  362. ]);
  363. $booking = new BookingSeat();
  364. $booking->setCreatedBy($this->getUser());
  365. $booking->setCreatedAt(new DateTime());
  366. $booking->setSeat($busSeat);
  367. // if ($bookingUserStation) {
  368. // $booking->setDepartureTime($bookingUserStation->getDepartureTime());
  369. // }
  370. $bookingForm = $this->createForm(BookingType::class, $booking, [
  371. 'trip' => $trip,
  372. 'shortCode' => $mpesaAuth->getPaybill(),
  373. 'action' => $this->generateUrl('viewTripSeat', ['seat' => $seat, 'trip' => $trip->getId()])
  374. ]);
  375. $bookingForm->handleRequest($request);
  376. if ($bookingForm->isSubmitted()) {
  377. dump($request->getMethod());
  378. if ($bookingForm->has('mpesa')) {
  379. if ($bookingForm->get('mpesa') && $bookingForm->get('mpesa')->getData()) {
  380. /** @var Mpesa $mpesa */
  381. $mpesa = $bookingForm->get('mpesa')->getData();
  382. if ($booking->getPaidVia() == 'MPESA') {
  383. dump($mpesa);
  384. if ($booking->getAmount() > $mpesa->getTransactionAmount()) {
  385. $bookingForm->get('amount')->addError(new FormError('Mpesa amount not enough'));
  386. }
  387. } else if ($booking->getPaidVia() == 'CASH_MPESA') {
  388. if ($mpesa->getTransactionAmount() >= $booking->getAmount()) {
  389. $bookingForm->get('amount')->addError(new FormError('Please check the amounts'));
  390. }
  391. }
  392. }
  393. }
  394. if ($bookingForm->isValid()) {
  395. if ($bookingForm->has('mpesa') && $bookingForm->get('mpesa') && $bookingForm->get('mpesa')->getData()) {
  396. // dump($bookingForm->get('mpesa')->getData());
  397. /** @var Mpesa $mpesa */
  398. $mpesa = $bookingForm->get('mpesa')->getData();
  399. $bookingMpesa = new BookingMpesa();
  400. $bookingMpesa->setBooking($booking);
  401. $bookingMpesa->setCreatedAt(new DateTime());
  402. $bookingMpesa->setCreatedBy($this->getUser());
  403. $bookingMpesa->setAmount($booking->getAmount());
  404. $bookingMpesa->setBalance(0);
  405. $bookingMpesa->setMpesa($mpesa);
  406. $mpesa->setIsUsed(true);
  407. $this->entityManager->persist($bookingMpesa);
  408. }
  409. $departureTime = $booking->getOrigin()->getDepartureTime();
  410. $eta = $booking->getOrigin()->getEta();
  411. $booking->setDepartureTime($departureTime);
  412. $booking->setEta($eta);
  413. $booking->getSeat()->setStatus('booked');
  414. $this->entityManager->persist($booking);
  415. $this->entityManager->flush();
  416. // return $this->redirectToRoute("@viewTrip?currentSeat={$seat}", ['trip' => $trip->getId()]);
  417. return $this->redirect("/bus/trip/{$trip->getId()}?currentSeat={$seat}");
  418. }
  419. }
  420. return $this->render('bus/seat_detail.html.twig', [
  421. 'seat' => $busSeat,
  422. 'trip' => $trip,
  423. 'booking' => $seatBooking,
  424. 'bookingForm' => $bookingForm->createView(),
  425. 'bookingStation' => $bookingUserStation,
  426. 'reservation' => $reserve,
  427. 'user_station' => $userStation
  428. ]);
  429. }
  430. /** @Route("/trip/{trip}/seat/{seat}/book_reserve_opt", name="viewReserveBookOpt") */
  431. public function bookingReserveOption(Request $request, $seat, Trip $trip)
  432. {
  433. $em = $this->entityManager;
  434. /** @var Seat $busSeat */
  435. $busSeat = $em->getRepository(Seat::class)->findOneBy([
  436. 'trip' => $trip,
  437. 'seatNumber' => $seat
  438. ]);
  439. $reserve = $em->getRepository(Reservation::class)->findOneBy([
  440. 'seat' => $busSeat,
  441. 'canceledAt' => null
  442. ]);
  443. $seatBooking = $em->getRepository(BookingSeat::class)->findOneBy([
  444. 'seat' => $busSeat,
  445. ]);
  446. if ($seatBooking || $reserve) {
  447. return $this->redirectToRoute('viewTripSeat', ['trip' => $trip->getId(), 'seat' => $busSeat->getSeatNumber()]);
  448. }
  449. return $this->render('bus/book_reserve.html.twig', [
  450. 'seat' => $busSeat,
  451. 'trip' => $trip,
  452. 'booking' => $seatBooking
  453. ]);
  454. }
  455. /** @Route("/trip/{trip}/seat/{seat}/cancel_reservation", name="cancelReservation") */
  456. public function cancelReservation(Request $request, $seat, Trip $trip)
  457. {
  458. $em = $this->entityManager;
  459. /** @var Seat $busSeat */
  460. $busSeat = $em->getRepository(Seat::class)->findOneBy([
  461. 'trip' => $trip,
  462. 'seatNumber' => $seat
  463. ]);
  464. $seatBooking = $em->getRepository(BookingSeat::class)->findOneBy([
  465. 'seat' => $busSeat
  466. ]);
  467. $reserve = $em->getRepository(Reservation::class)->findOneBy([
  468. 'seat' => $busSeat,
  469. 'canceledAt' => null
  470. ]);
  471. $busSeat->setStatus('AVAILABLE');
  472. $reserve->setCanceledAt(new DateTime());
  473. $reserve->setCanceledBy($this->getUser());
  474. $em->flush();
  475. return $this->redirectToRoute('viewTrip', ['trip' => $trip->getId()]);
  476. }
  477. /** @Route("/trip/{trip}/seat/{seat}/reserve", name="viewReserve") */
  478. public function reserve(Request $request, $seat, Trip $trip)
  479. {
  480. $em = $this->entityManager;
  481. /** @var UserStation $userStation */
  482. $userStation = $em->getRepository(UserStation::class)->findOneBy([
  483. 'user' => $this->getUser(),
  484. 'isActive' => true
  485. ]);
  486. /** @var Seat $busSeat */
  487. $busSeat = $em->getRepository(Seat::class)->findOneBy([
  488. 'trip' => $trip,
  489. 'seatNumber' => $seat
  490. ]);
  491. $seatBooking = $em->getRepository(BookingSeat::class)->findOneBy([
  492. 'seat' => $busSeat
  493. ]);
  494. $reservation = new Reservation();
  495. $reservation->setReservedAt(new DateTime());
  496. $reservation->setReservedBy($this->getUser());
  497. $reservation->setReservingStation($userStation->getStation());
  498. $reservation->setSeat($busSeat);
  499. $reserveForm = $this->createForm(ReserveType::class, $reservation);
  500. $reserveForm->handleRequest($request);
  501. if ($reserveForm->isSubmitted() && $reserveForm->isValid()) {
  502. $em->persist($reservation);
  503. $busSeat->setStatus('RESERVED');
  504. $em->flush();
  505. return $this->redirectToRoute('viewTrip', ['trip' => $trip->getId()]);
  506. }
  507. return $this->render('bus/reserve.html.twig', [
  508. 'seat' => $busSeat,
  509. 'trip' => $trip,
  510. 'booking' => $seatBooking,
  511. 'reserveForm' => $reserveForm->createView(),
  512. 'action' => $this->generateUrl('viewReserve', ['trip' => $trip->getId(), 'seat' => $busSeat->getSeatNumber()])
  513. ]);
  514. }
  515. /**
  516. * @Route("/ticket/{ticketId}", methods={"GET"}, name="generateTicket")
  517. */
  518. public function generateTicket(Request $request, $ticketId, MpdfFactory $MpdfFactory): Response
  519. {
  520. $em = $this->entityManager;
  521. $booking = $em->getRepository(BookingSeat::class)->findOneBy([
  522. 'id' => $ticketId
  523. ]);
  524. $payment = null;
  525. if ($booking->getPaidVia() == 'MPESA' || $booking->getPaidVia() == 'CASH_MPESA') {
  526. /** @var BookingMpesa $payment */
  527. $payment = $em->getRepository(BookingMpesa::class)->findOneBy([
  528. 'booking' => $booking
  529. ]);
  530. }
  531. $defaultConfig = $MpdfFactory->getDefaultConfigVariables();
  532. $fontDirs = $defaultConfig['fontDir'];
  533. $defaultFontConfig = $MpdfFactory->getDefaultFontVariables();
  534. $fontData = $defaultFontConfig['fontdata'];
  535. // dump($fontData);die;
  536. $mPdf = $MpdfFactory->createMpdfObject([
  537. /* 'fontDir' => array_merge($fontDirs, [
  538. '../../public/fos/fonts/Tangerine',
  539. '../../public/fos/fonts/OdibeeSans',
  540. '../../public/fos/fonts/Mogra',
  541. '../../public/fos/fonts/Libre_Baskerville',
  542. ]),
  543. 'fontdata' => $fontData + [
  544. 'tangerine' => [
  545. 'B' => 'Tangerine-Bold.ttf',
  546. 'R' => 'Tangerine-Regular.ttf'
  547. ],
  548. 'odibeesans' => [
  549. 'R' => 'OdibeeSans-Regular.ttf',
  550. 'I' => 'OdibeeSans-Regular.ttf'
  551. ],
  552. 'mogra' => [
  553. 'R' => 'Mogra-Bold.ttf',
  554. 'I' => 'Mogra-Regular.ttf',
  555. ],
  556. 'librebaskerville' => [
  557. 'R' => 'LibreBaskerville-Regular.ttf',
  558. 'B' => 'LibreBaskerville-Bold.ttf',
  559. 'I' => 'LibreBaskerville-Italic.ttf',
  560. ]
  561. ],*/
  562. 'mode' => 'utf-8',
  563. 'format' => [80, 250],
  564. 'margin_header' => 5,
  565. 'margin_footer' => 5,
  566. 'orientation' => 'P'
  567. ]);
  568. $date = new DateTime();
  569. $time = $date->getTimestamp();
  570. // $mPdf->SetTopMargin("1");
  571. // $qrCode = new QrCode('');
  572. try {
  573. $receiptType = 'TICKET';
  574. /* $timsQRCode = 'ticket';
  575. $timsqrCode = new QrCode($timsQRCode);
  576. $output = new Png();
  577. $data = $output->output($qrCode, 100, [255, 255, 255], [0, 0, 0]);
  578. $timsQRCodeData = $output->output($timsqrCode, 150, [255, 255, 255], [0, 0, 0]);
  579. file_put_contents('assets/qrcode/qrcode.png', $data);
  580. file_put_contents('assets/qrcode/timsQRCode.png', $timsQRCodeData);*/
  581. dump($payment);
  582. $idBase64 = base64_encode($booking->getId());
  583. $logoImage = file_get_contents('../public/bus/bus_1.png');
  584. $logoBase64 = base64_encode($logoImage);
  585. $mPdf->WriteHTML($this->renderView('bus/ticket/ticket.html.twig', [
  586. 'booking' => $booking,
  587. 'receiptType' => $receiptType,
  588. 'payment' => $payment,
  589. 'id' => $idBase64,
  590. 'logo' => $logoBase64
  591. ]));
  592. $file = "../tickets/ticket_{$ticketId}.pdf";
  593. // return $MpdfFactory->createDownloadResponse($mPdf, "ticket_{$ticketId}.pdf", Response::HTTP_OK, ["Set-Cookie", "fileDownload=true; path=/"]);
  594. return $MpdfFactory->createInlineResponse($mPdf, $file);
  595. } catch (\Exception $e) {
  596. return new Response($e->getMessage(), Response::HTTP_BAD_REQUEST);
  597. }
  598. // return new Response("error occurred");
  599. }
  600. /**
  601. * @Route("/daily_account", methods={"GET","POST"}, name="busDailyAccount")
  602. */
  603. public function dailyAccount(Request $request): Response
  604. {
  605. if ($request->isMethod('POST')) {
  606. $em = $this->entityManager;
  607. $today = new \DateTimeImmutable();
  608. $date = $today->format('Y-m-d');
  609. $user_id = $this->getUser()->getId();
  610. /** @var UserStation $userTown */
  611. $userTown = $this->entityManager->getRepository(UserStation::class)->findOneBy([
  612. 'user' => $this->getUser(),
  613. 'isActive' => true
  614. ], ['id' => 'DESC']);
  615. $sql = " SELECT d.route_name,a.paid_via,sum(a.amount) amount,c.trip_date FROM bus_booking_seat a
  616. JOIN bus_seat b ON b.id = a.seat_id
  617. JOIN bus_trip c ON c.id = b.trip_id
  618. JOIN bus_route d ON d.id = c.route_id
  619. WHERE date(a.created_at) = cast('2026-02-06' as date)
  620. GROUP BY paid_via, d.id,b.trip_id";
  621. $sqlTotal = "SELECT sum(a.amount) as total FROM bus_booking_seat a
  622. WHERE a.created_by = {$user_id} AND date(a.created_at) = cast('2026-02-06' as date)";
  623. $conn = $em->getConnection();
  624. try {
  625. $stmt = $conn->prepare($sql);
  626. $amounts = $stmt->executeQuery()->fetchAllAssociative();
  627. $stmtTotal = $conn->prepare($sqlTotal);
  628. $total = $stmtTotal->executeQuery()->fetchAssociative();
  629. return $this->render('bus/daily_account.html.twig', [
  630. 'date' => $date,
  631. 'amounts' => $amounts,
  632. 'total' => $total,
  633. 'user_town' => $userTown
  634. ]);
  635. } catch (Exception $e) {
  636. }
  637. }
  638. return $this->render('bus/daily_account.html.twig');
  639. }
  640. private function addTrip(\App\Entity\Bus\Route $route, string $date)
  641. {
  642. $em = $this->entityManager;
  643. /** @var Stop[] $destinations */
  644. /*$destinations = $em->getRepository(Stop::class)->findBy([
  645. 'route' => $route
  646. ]);*/
  647. dump($route);
  648. $dateTime = datetime::createfromformat('Y-m-d', $date);
  649. /** @var RouteFareRule $fareRule */
  650. $fareRule = $em->getRepository(RouteFareRule::class)->findOneBy([
  651. 'route' => $route,
  652. ]);
  653. $trip = new Trip();
  654. $trip->setCreatedBy($this->getUser());
  655. $trip->setCreatedAt(new DateTime());
  656. $trip->setTripDate($dateTime);
  657. $trip->setRoute($route);
  658. $trip->setDestination($route->getDestination());
  659. $trip->setOrigin($route->getOrigin());
  660. $trip->setTripIndex(1);
  661. $trip->setFare($fareRule->getNormalFare());
  662. $departureStored = $route->getDepartureTime();
  663. $arrivalStored = $route->getEta();
  664. // Today base
  665. $today = new \DateTime('today');
  666. // Build departure with today's date + original time
  667. $departure = (clone $today)->setTime(
  668. (int)$departureStored->format('H'),
  669. (int)$departureStored->format('i'),
  670. (int)$departureStored->format('s')
  671. );
  672. // Build arrival with today's date + original time
  673. $arrival = (clone $today)->setTime(
  674. (int)$arrivalStored->format('H'),
  675. (int)$arrivalStored->format('i'),
  676. (int)$arrivalStored->format('s')
  677. );
  678. // If arrival is earlier than departure → it's next day
  679. if ($arrival <= $departure) {
  680. $arrival->modify('+1 day');
  681. }
  682. $trip->setDepartureTime($departure);
  683. $trip->setEta($arrival);
  684. /** @var Vehicle $vehicle */
  685. $vehicle = $em->getRepository(Vehicle::class)->findOneBy([
  686. 'regNumber' => 'KCE990Q'
  687. ]);
  688. $seats = [];
  689. for ($i = 1; $i <= $vehicle->getPassengerCapacity(); $i++) {
  690. $seat = new Seat();
  691. $seat->setStatus('AVAILABLE');
  692. $seat->setSeatNumber($i);
  693. $seat->setTrip($trip);
  694. $seat->setIsBooked(false);
  695. $seat->setCreatedAt(new DateTime());
  696. $seats[] = $seat;
  697. }
  698. $trip->setSeats($seats);
  699. $trip->setVehicle($vehicle);
  700. $tripVehicle = new TripVehicle();
  701. $tripVehicle->setCreatedAt(new DateTime());
  702. $tripVehicle->setTrip($trip);
  703. $tripVehicle->setCreatedBy($this->getUser());
  704. $tripVehicle->setIsCancelled(false);
  705. $tripVehicle->setVehicle($vehicle);
  706. $this->entityManager->persist($tripVehicle);
  707. $this->entityManager->persist($trip);
  708. $this->entityManager->flush();
  709. }
  710. private
  711. function jsonTestData()
  712. {
  713. $jsonData = '[{
  714. "id": 741421,
  715. "account_date": "2023-10-09",
  716. "expenses": 0,
  717. "created_at": "2023-10-09 19:59:54",
  718. "station_name": "MOMBASA",
  719. "sender_name": "patrick kinyua",
  720. "sender_phone_number": "0727 044 524",
  721. "receiver_name": "luke njoroge",
  722. "receiver_phone_number": "0705 179 108",
  723. "amount": 2100,
  724. "is_cancelled": 0
  725. },
  726. {
  727. "id": 741405,
  728. "account_date": "2023-10-09",
  729. "expenses": 0,
  730. "created_at": "2023-10-09 19:19:03",
  731. "station_name": "MERU",
  732. "sender_name": "phineas kirimi",
  733. "sender_phone_number": "0791 713 924",
  734. "receiver_name": "patrick munoru",
  735. "receiver_phone_number": "0720 949 054",
  736. "amount": 200,
  737. "is_cancelled": 0
  738. },
  739. {
  740. "id": 741395,
  741. "account_date": "2023-10-09",
  742. "expenses": 0,
  743. "created_at": "2023-10-09 19:09:05",
  744. "station_name": "kitui",
  745. "sender_name": "scout shop",
  746. "sender_phone_number": "0712 907 877",
  747. "receiver_name": "winfred ndolo",
  748. "receiver_phone_number": "0724 528 806",
  749. "amount": 200,
  750. "is_cancelled": 0
  751. },
  752. {
  753. "id": 741393,
  754. "account_date": "2023-10-09",
  755. "expenses": 0,
  756. "created_at": "2023-10-09 19:07:04",
  757. "station_name": "SIAKAGO",
  758. "sender_name": "james gichuki",
  759. "sender_phone_number": "0722 352 992",
  760. "receiver_name": "richard waitherero",
  761. "receiver_phone_number": "0728 454 129",
  762. "amount": 300,
  763. "is_cancelled": 0
  764. },
  765. {
  766. "id": 741378,
  767. "account_date": "2023-10-09",
  768. "expenses": 0,
  769. "created_at": "2023-10-09 18:55:25",
  770. "station_name": "NAIROBI",
  771. "sender_name": "denis munene",
  772. "sender_phone_number": "0740 270 344",
  773. "receiver_name": "tom ochieng",
  774. "receiver_phone_number": "0715 553 018",
  775. "amount": 200,
  776. "is_cancelled": 0
  777. },
  778. {
  779. "id": 741370,
  780. "account_date": "2023-10-09",
  781. "expenses": 0,
  782. "created_at": "2023-10-09 18:43:13",
  783. "station_name": "NAIROBI",
  784. "sender_name": "peter njagi",
  785. "sender_phone_number": "0722 883 774",
  786. "receiver_name": "jackson kanambiu",
  787. "receiver_phone_number": "0714 203 693",
  788. "amount": 200,
  789. "is_cancelled": 0
  790. },
  791. {
  792. "id": 741355,
  793. "account_date": "2023-10-09",
  794. "expenses": 0,
  795. "created_at": "2023-10-09 18:32:02",
  796. "station_name": "MOMBASA",
  797. "sender_name": "mary mbugi",
  798. "sender_phone_number": "0727 897 097",
  799. "receiver_name": "elizabeth nyawira",
  800. "receiver_phone_number": "0706 221 351",
  801. "amount": 300,
  802. "is_cancelled": 0
  803. },
  804. {
  805. "id": 741351,
  806. "account_date": "2023-10-09",
  807. "expenses": 0,
  808. "created_at": "2023-10-09 18:25:01",
  809. "station_name": "NAIROBI",
  810. "sender_name": "david thairu",
  811. "sender_phone_number": "0722 280 846",
  812. "receiver_name": "daniel kimondo",
  813. "receiver_phone_number": "0724 215 522",
  814. "amount": 200,
  815. "is_cancelled": 0
  816. },
  817. {
  818. "id": 741330,
  819. "account_date": "2023-10-09",
  820. "expenses": 0,
  821. "created_at": "2023-10-09 17:58:08",
  822. "station_name": "NAIROBI",
  823. "sender_name": "karen karimi",
  824. "sender_phone_number": "0714 509 299",
  825. "receiver_name": "victor muthoni",
  826. "receiver_phone_number": "0710 329 231",
  827. "amount": 200,
  828. "is_cancelled": 0
  829. },
  830. {
  831. "id": 741328,
  832. "account_date": "2023-10-09",
  833. "expenses": 0,
  834. "created_at": "2023-10-09 17:56:42",
  835. "station_name": "KATHWANA",
  836. "sender_name": "samwel",
  837. "sender_phone_number": "0722 595 844",
  838. "receiver_name": "dirangu ndungu",
  839. "receiver_phone_number": "0721 207 371",
  840. "amount": 250,
  841. "is_cancelled": 0
  842. },
  843. {
  844. "id": 741301,
  845. "account_date": "2023-10-09",
  846. "expenses": 0,
  847. "created_at": "2023-10-09 17:35:27",
  848. "station_name": "MOMBASA",
  849. "sender_name": "edith kimani",
  850. "sender_phone_number": "0714 567 205",
  851. "receiver_name": "okumu",
  852. "receiver_phone_number": "0714 567 205",
  853. "amount": 300,
  854. "is_cancelled": 0
  855. },
  856. {
  857. "id": 741289,
  858. "account_date": "2023-10-09",
  859. "expenses": 0,
  860. "created_at": "2023-10-09 17:26:09",
  861. "station_name": "MTWAPA",
  862. "sender_name": "caroline waweru",
  863. "sender_phone_number": "0712 353 926",
  864. "receiver_name": "GLADYS WAWERU",
  865. "receiver_phone_number": "0723 950 679",
  866. "amount": 300,
  867. "is_cancelled": 0
  868. },
  869. {
  870. "id": 741270,
  871. "account_date": "2023-10-09",
  872. "expenses": 0,
  873. "created_at": "2023-10-09 17:03:24",
  874. "station_name": "MWEA",
  875. "sender_name": "FOCUS EMBU",
  876. "sender_phone_number": "0716 447 206",
  877. "receiver_name": "FOCUS MWEA",
  878. "receiver_phone_number": "0721 606 746",
  879. "amount": 150,
  880. "is_cancelled": 0
  881. },
  882. {
  883. "id": 741266,
  884. "account_date": "2023-10-09",
  885. "expenses": 0,
  886. "created_at": "2023-10-09 16:58:43",
  887. "station_name": "THIKA",
  888. "sender_name": "KIMATHI KELVIN",
  889. "sender_phone_number": "0726 116 760",
  890. "receiver_name": "JAMES NGINGI",
  891. "receiver_phone_number": "0728 171 491",
  892. "amount": 200,
  893. "is_cancelled": 0
  894. },
  895. {
  896. "id": 741261,
  897. "account_date": "2023-10-09",
  898. "expenses": 0,
  899. "created_at": "2023-10-09 16:54:46",
  900. "station_name": "NAIROBI",
  901. "sender_name": "ROSALINE WAWIRA",
  902. "sender_phone_number": "0728 288 950",
  903. "receiver_name": "eras karimi",
  904. "receiver_phone_number": "0724 867 838",
  905. "amount": 200,
  906. "is_cancelled": 0
  907. },
  908. {
  909. "id": 741248,
  910. "account_date": "2023-10-09",
  911. "expenses": 0,
  912. "created_at": "2023-10-09 16:47:18",
  913. "station_name": "MOMBASA",
  914. "sender_name": "jemmimah",
  915. "sender_phone_number": "0711 485 954",
  916. "receiver_name": "rose khaidi",
  917. "receiver_phone_number": "0706 749 991",
  918. "amount": 300,
  919. "is_cancelled": 0
  920. },
  921. {
  922. "id": 741209,
  923. "account_date": "2023-10-09",
  924. "expenses": 0,
  925. "created_at": "2023-10-09 16:05:38",
  926. "station_name": "kitui",
  927. "sender_name": "eunice mambiro",
  928. "sender_phone_number": "0720 997 508",
  929. "receiver_name": "samwel muturi",
  930. "receiver_phone_number": "0715 143 362",
  931. "amount": 200,
  932. "is_cancelled": 0
  933. },
  934. {
  935. "id": 741185,
  936. "account_date": "2023-10-09",
  937. "expenses": 0,
  938. "created_at": "2023-10-09 15:49:11",
  939. "station_name": "NAIROBI",
  940. "sender_name": "johnson njeru",
  941. "sender_phone_number": "0724 586 321",
  942. "receiver_name": "jane njoki njeru",
  943. "receiver_phone_number": "0722 398 853",
  944. "amount": 300,
  945. "is_cancelled": 0
  946. },
  947. {
  948. "id": 741175,
  949. "account_date": "2023-10-09",
  950. "expenses": 0,
  951. "created_at": "2023-10-09 15:36:39",
  952. "station_name": "NAIROBI",
  953. "sender_name": "alexande david",
  954. "sender_phone_number": "0795 762 309",
  955. "receiver_name": "peter aunga",
  956. "receiver_phone_number": "0715 044 187",
  957. "amount": 200,
  958. "is_cancelled": 0
  959. },
  960. {
  961. "id": 741172,
  962. "account_date": "2023-10-09",
  963. "expenses": 0,
  964. "created_at": "2023-10-09 15:33:17",
  965. "station_name": "NAIROBI",
  966. "sender_name": "j kimondo",
  967. "sender_phone_number": "0722 830 014",
  968. "receiver_name": "fred muiruri",
  969. "receiver_phone_number": "0705 945 561",
  970. "amount": 200,
  971. "is_cancelled": 0
  972. }
  973. ]';
  974. $arrayedFromJson = json_decode($jsonData, true);
  975. return $arrayedFromJson;
  976. }
  977. }