<?php
namespace App\Bus;
use App\Entity\Bus\BookingMpesa;
use App\Entity\Bus\BookingSeat;
use App\Entity\Bus\Reservation;
use App\Entity\Bus\RouteFareRule;
use App\Entity\Bus\Seat;
use App\Entity\Bus\Stop;
use App\Entity\Bus\Trip;
use App\Entity\Bus\TripVehicle;
use App\Entity\Mpesa;
use App\Entity\MpesaAuth;
use App\Entity\MpesaPayment;
use App\Entity\User;
use App\Entity\UserStation;
use App\Entity\Vehicle;
use App\Entity\WayBill;
use App\Form\Bus\BookingType;
use App\Form\Bus\ReserveType;
use App\Form\Bus\RouteeType;
use App\Form\Bus\TripType;
use DateTime;
use Doctrine\DBAL\Exception;
use Doctrine\Persistence\ManagerRegistry;
use Doctrine\Persistence\ObjectManager;
use JMS\Serializer\SerializationContext;
use JMS\Serializer\SerializerBuilder;
use Mpdf\Output\Destination;
use Mpdf\QrCode\Output\Png;
use Mpdf\QrCode\QrCode;
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule;
use Sasedev\MpdfBundle\Factory\MpdfFactory;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\FormError;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class BookingController extends AbstractController{
private ManagerRegistry $registry;
private ObjectManager $entityManager;
private RequestStack $requestStack;
public function __construct(ManagerRegistry $registry, RequestStack $requestStack)
{
$this->entityManager = $registry->getManager();
$this->requestStack = $requestStack;
}
/** @Route("/routes", name="routesHome") */
public function routesHome(Request $request)
{
$em = $this->entityManager;
/** @var UserStation $userTown */
$userTown = $em->getRepository(UserStation::class)->findOneBy([
'user' => $this->getUser(),
'isActive' => true
], ['id' => 'DESC']);
$route = new \App\Entity\Bus\Route();
$route->setCreatedAt(new DateTime());
$route->setCreatedBy($this->getUser());
$routeForm = $this->createForm(RouteeType::class, $route);
$routeForm->handleRequest($request);
if ($routeForm->isSubmitted() && $routeForm->isValid()) {
dump($route);
$this->entityManager->persist($route);
$this->entityManager->flush();
return $this->redirectToRoute('routesHome');
}
/** @var \App\Entity\Bus\Route[] $routes */
$routes = $this->entityManager->getRepository(\App\Entity\Bus\Route::class)->findAll();
return $this->render('bus/routes.html.twig', [
'user_town' => $userTown,
'routes' => $routes,
'routeForm' => $routeForm->createView()
]);
}
/** @Route("/routes/{route}/edit", name="routesEdit") */
public function routesEdit(Request $request, \App\Entity\Bus\Route $route)
{
$em = $this->entityManager;
/** @var UserStation $userTown */
$userTown = $em->getRepository(UserStation::class)->findOneBy([
'user' => $this->getUser(),
'isActive' => true
], ['id' => 'DESC']);
$routeForm = $this->createForm(RouteeType::class, $route);
$routeForm->handleRequest($request);
if ($routeForm->isSubmitted() && $routeForm->isValid()) {
// $route->setStops($route->getStops());
$this->entityManager->persist($route);
$this->entityManager->flush();
$this->addFlash('success', 'Route updated successfully');
return $this->redirectToRoute('routesHome');
}
/** @var \App\Entity\Bus\Route[] $routes */
$routes = $this->entityManager->getRepository(\App\Entity\Bus\Route::class)->findAll();
return $this->render('bus/routes_edit.html.twig', [
'user_town' => $userTown,
'routes' => $routes,
'routeForm' => $routeForm->createView()
]);
}
/** @Route("/", name="tripsHome") */
public function tripsHome(Request $request)
{
$em = $this->entityManager;
$date = $request->get('trip_date');
$today = new \DateTimeImmutable();
if (!$date) {
$date = $today->format('Y-m-d');
}
/** @var UserStation $userTown */
$userTown = $em->getRepository(UserStation::class)->findOneBy([
'user' => $this->getUser(),
'isActive' => true
], ['id' => 'DESC']);
$stationId = $userTown->getStation()->getId();
// MOMBASA and MERU scenario 1
/* if a station origin is in current station show bus route */
// $sql = "SELECT a.id, a.route_name FROM bus_route a WHERE origin = {$stationId}";
// EMBU scenario 2
/* if a station is a stop in a main route and not the destination */
$sql = "SELECT a.id, a.route_name FROM bus_route a
JOIN bus_stop b ON b.route_id = a.id
WHERE b.station_id = {$stationId}
AND b.route_type = 'MAIN'
AND a.destination != {$stationId} GROUP BY a.id";
$conn = $this->entityManager->getConnection();
$availableRoutes = null;
try {
$stmt = $conn->prepare($sql);
$availableRoutes = $stmt->executeQuery()->fetchAllAssociative();
} catch (\Exception $e) {
}
/** @var Trip[] $trips */
$trips = $this->entityManager->getRepository(Trip::class)->findActiveTrips($date, $userTown->getStation()->getId(), 'MAIN');
if($trips){
return $this->render('bus/trips.html.twig', [
'user_town' => $userTown,
'trips' => $trips,
'date' => $date
]);
}else {
foreach ($availableRoutes as $index => $availableRoute) {
$route = $em->getRepository(\App\Entity\Bus\Route::class)->findOneBy([
'id' => $availableRoute['id']
]);
$this->addTrip($route, $date);
}
}
/** @var Trip[] $trips */
$trips = $this->entityManager->getRepository(Trip::class)->findActiveTrips($date, $userTown->getStation()->getId(), 'MAIN');
return $this->render('bus/trips.html.twig', [
'user_town' => $userTown,
'trips' => $trips,
'date' => $date
]);
}
/** @Route("/trips/new", name="newTrip") */
public function newTrip(Request $request)
{
$em = $this->entityManager;
/** @var UserStation $userTown */
$userTown = $em->getRepository(UserStation::class)->findOneBy([
'user' => $this->getUser(),
'isActive' => true
], ['id' => 'DESC']);
$trip = new Trip();
$tripForm = $this->createForm(TripType::class, $trip);
$tripForm->handleRequest($request);
if ($tripForm->isSubmitted() && $tripForm->isValid()) {
$date = $trip->getTripDate();
$d = $date->format('Y-m-d');
$sql = "SELECT count(*) total FROM bus_trip a WHERE a.route_id = {$trip->getRoute()->getId()}
AND DATE(a.trip_date) = CAST('{$d}' as date)";
$conn = $this->entityManager->getConnection();
$stmt = $conn->prepare($sql);
$thisDaysTrips = $stmt->executeQuery()->fetchAssociative();
$sameRouteTrips = $thisDaysTrips['total'];
$trip->setTripIndex($sameRouteTrips + 1);
$trip->setCreatedBy($this->getUser());
$trip->setCreatedAt(new DateTime());
/** @var Vehicle $vehicle */
$vehicle = $tripForm->get('vehicle')->getData();
$seats = [];
for ($i = 1; $i <= $vehicle->getPassengerCapacity(); $i++) {
$seat = new Seat();
$seat->setStatus('AVAILABLE');
$seat->setSeatNumber($i);
$seat->setTrip($trip);
$seat->setIsBooked(false);
$seat->setCreatedAt(new DateTime());
$seats[] = $seat;
}
$trip->setSeats($seats);
$tripVehicle = new TripVehicle();
$tripVehicle->setCreatedAt(new DateTime());
$tripVehicle->setTrip($trip);
$tripVehicle->setCreatedBy($this->getUser());
$tripVehicle->setIsCancelled(false);
$tripVehicle->setVehicle($vehicle);
// $this->entityManager->persist($tripVehicle);
// $this->entityManager->persist($trip);
// $this->entityManager->flush();
return $this->redirectToRoute('tripsHome');
}
return $this->render('bus/new_trip.html.twig', [
'tripForm' => $tripForm->createView(),
'user_town' => $userTown
]);
}
/** @Route("/trip/{trip}", name="viewTrip") */
public function bookingTrip(Request $request, Trip $trip)
{
$currentSeat = $request->get('currentSeat') ? $request->get('currentSeat') : -1;
$numberOfSeats = 49;
$doorRow = 0;
$lastRow = 12;
// $seats = [];
$rows = 0;
/** @var UserStation $userTown */
$userTown = $this->entityManager->getRepository(UserStation::class)->findOneBy([
'user' => $this->getUser(),
'isActive' => true
], ['id' => 'DESC']);
// dump($userTown);
$stop = $this->entityManager->getRepository(Stop::class)->findCurrentStop($trip->getRoute(), $userTown->getStation());
// dump($stop);
// die;
$currentStop = null;
if ($stop) {
$currentStop = $this->entityManager->getRepository(Stop::class)->findOneBy([
'id' => $stop['id']
]);
}
if (!$currentStop) {
return $this->redirectToRoute('tripsHome');
}
$seats = $this->entityManager->getRepository(BookingSeat::class)->findAllSeats($trip, $currentStop);
// dump($seats);
// dump('currentSeat',$currentSeat);
return $this->render('bus/booking.html.twig', [
'seats' => $seats,
'rows' => $rows,
'doorRow' => $doorRow,
'lastRow' => $lastRow,
'workingSeat' => $currentSeat,
'trip' => $trip
]);
}
/** @Route("/trip/{trip}/json", name="viewJsonTrip") */
public function getTripSeatsJson(Request $request, Trip $trip)
{
$context = new SerializationContext();
$context->setSerializeNull(true);
$page = $request->request->get('page') > 1 ? $request->request->get('page') : 1;
$rows = $request->request->get('rows') > 1 ? $request->request->get('rows') : 50;
$offset = ($page - 1) * $rows;
$serializer = SerializerBuilder::create()->build();
$filterRules = $request->request->get('filterRules');
$seats = $this->entityManager->getRepository(BookingSeat::class)->findAllTripSeats($filterRules, $offset, $rows, $trip);
return new JsonResponse($seats);
}
/** @Route("/trip/{trip}/manifest/pdf", name="viewTripManifest") */
public function getManifestBySearch(Request $request, Trip $trip, MpdfFactory $mpdfFactory)
{
$context = new SerializationContext();
$context->setSerializeNull(true);
$page = $request->request->get('page') > 1 ? $request->request->get('page') : 1;
$rows = $request->request->get('rows') > 1 ? $request->request->get('rows') : 50;
$offset = ($page - 1) * $rows;
$filterRules = $request->request->get('filterRules');
$seats = $this->entityManager->getRepository(BookingSeat::class)->findAllTripSeats($filterRules, $offset, $rows, $trip);
$data = $this->jsonTestData();
// dump($fontData);die;
$mPdf = $mpdfFactory->createMpdfObject([
'format' => [80, 500],
'margin_header' => 5,
'margin_footer' => 5,
'margin_left' => 5,
'margin_right' => 5,
'margin_top' => 0,
'margin_bottom' => 0,
'autoPageBreak' => false,
'orientation' => 'P'
]);
$date = new DateTime();
$time = $date->getTimestamp();
try {
$receiptType = 'MANIFEST';
$logoImage = file_get_contents('../public/bus/bus_1.png');
$logoBase64 = base64_encode($logoImage);
$mPdf->WriteHTML($this->renderView('bus/manifest/manifest.html.twig', [
'passengers' => $seats,
'trip' => $trip,
'busLogo' => $logoBase64
]));
$file = "../manifests/manifest_.pdf";
// return $MpdfFactory->createDownloadResponse($mPdf, "ticket_{$ticketId}.pdf", Response::HTTP_OK, ["Set-Cookie", "fileDownload=true; path=/"]);
return $mpdfFactory->createInlineResponse($mPdf, $file);
} catch (\Exception $e) {
return new Response($e->getMessage(), Response::HTTP_BAD_REQUEST);
}
// return new JsonResponse($seats);
}
/** @Route("/trip/{trip}/stops", name="viewTripStopsSearchCombo") */
public function getTripStops(Trip $trip)
{
$em = $this->entityManager;
/** @var \App\Entity\Bus\Route $route */
$route = $em->getRepository(\App\Entity\Bus\Route::class)->findOneBy([
'id' => $trip->getRoute()->getId()
]);
$sql = "SELECT a.id,b.station_name FROM bus_stop a
JOIN station b ON b.id = a.station_id
WHERE a.route_id = {$route->getId()}";
$conn = $em->getConnection();
$stmt = $conn->prepare($sql);
$stops = $stmt->executeQuery()->fetchAllAssociative();
array_push($stops, ['id' => '', 'station_name' => 'ALL STOPS']);
return new JsonResponse($stops);
}
/** @Route("/trip/{trip}/seat/{seat}", name="viewTripSeat") */
public function bookingTripSeat(Request $request, $seat, Trip $trip)
{
$em = $this->entityManager;
/** @var Seat $busSeat */
$busSeat = $em->getRepository(Seat::class)->findOneBy([
'trip' => $trip,
'seatNumber' => $seat
]);
$seatBooking = $em->getRepository(BookingSeat::class)->findOneBy([
'seat' => $busSeat
]);
$bookingUserStation = null;
if ($seatBooking) {
/** @var UserStation $userTown */
$bookingUserStation = $this->entityManager->getRepository(UserStation::class)->findOneBy([
'user' => $seatBooking->getCreatedBy(),
'isActive' => true
], ['id' => 'DESC']);
}
/** @var User $user */
$user = $this->getUser();
/** @var UserStation $userStation */
$userStation = $em->getRepository(UserStation::class)->findOneBy([
'user' => $user,
'isActive' => true
]);
$mpesaAuth = $em->getRepository(MpesaAuth::class)->findOneBy([
'station' => $userStation->getStation(),
'shortCodeType' => 'IMANI'
]);
if (!$mpesaAuth) {
$mpesaAuth = $em->getRepository(MpesaAuth::class)->findOneBy([
'station' => 2,
'shortCodeType' => 'IMANI'
]);
}
$reserve = $em->getRepository(Reservation::class)->findOneBy([
'seat' => $busSeat
]);
$booking = new BookingSeat();
$booking->setCreatedBy($this->getUser());
$booking->setCreatedAt(new DateTime());
$booking->setSeat($busSeat);
// if ($bookingUserStation) {
// $booking->setDepartureTime($bookingUserStation->getDepartureTime());
// }
$bookingForm = $this->createForm(BookingType::class, $booking, [
'trip' => $trip,
'shortCode' => $mpesaAuth->getPaybill(),
'action' => $this->generateUrl('viewTripSeat', ['seat' => $seat, 'trip' => $trip->getId()])
]);
$bookingForm->handleRequest($request);
if ($bookingForm->isSubmitted()) {
dump($request->getMethod());
if ($bookingForm->has('mpesa')) {
if ($bookingForm->get('mpesa') && $bookingForm->get('mpesa')->getData()) {
/** @var Mpesa $mpesa */
$mpesa = $bookingForm->get('mpesa')->getData();
if ($booking->getPaidVia() == 'MPESA') {
dump($mpesa);
if ($booking->getAmount() > $mpesa->getTransactionAmount()) {
$bookingForm->get('amount')->addError(new FormError('Mpesa amount not enough'));
}
} else if ($booking->getPaidVia() == 'CASH_MPESA') {
if ($mpesa->getTransactionAmount() >= $booking->getAmount()) {
$bookingForm->get('amount')->addError(new FormError('Please check the amounts'));
}
}
}
}
if ($bookingForm->isValid()) {
if ($bookingForm->has('mpesa') && $bookingForm->get('mpesa') && $bookingForm->get('mpesa')->getData()) {
// dump($bookingForm->get('mpesa')->getData());
/** @var Mpesa $mpesa */
$mpesa = $bookingForm->get('mpesa')->getData();
$bookingMpesa = new BookingMpesa();
$bookingMpesa->setBooking($booking);
$bookingMpesa->setCreatedAt(new DateTime());
$bookingMpesa->setCreatedBy($this->getUser());
$bookingMpesa->setAmount($booking->getAmount());
$bookingMpesa->setBalance(0);
$bookingMpesa->setMpesa($mpesa);
$mpesa->setIsUsed(true);
$this->entityManager->persist($bookingMpesa);
}
$departureTime = $booking->getOrigin()->getDepartureTime();
$eta = $booking->getOrigin()->getEta();
$booking->setDepartureTime($departureTime);
$booking->setEta($eta);
$booking->getSeat()->setStatus('booked');
$this->entityManager->persist($booking);
$this->entityManager->flush();
// return $this->redirectToRoute("@viewTrip?currentSeat={$seat}", ['trip' => $trip->getId()]);
return $this->redirect("/bus/trip/{$trip->getId()}?currentSeat={$seat}");
}
}
return $this->render('bus/seat_detail.html.twig', [
'seat' => $busSeat,
'trip' => $trip,
'booking' => $seatBooking,
'bookingForm' => $bookingForm->createView(),
'bookingStation' => $bookingUserStation,
'reservation' => $reserve,
'user_station' => $userStation
]);
}
/** @Route("/trip/{trip}/seat/{seat}/book_reserve_opt", name="viewReserveBookOpt") */
public function bookingReserveOption(Request $request, $seat, Trip $trip)
{
$em = $this->entityManager;
/** @var Seat $busSeat */
$busSeat = $em->getRepository(Seat::class)->findOneBy([
'trip' => $trip,
'seatNumber' => $seat
]);
$reserve = $em->getRepository(Reservation::class)->findOneBy([
'seat' => $busSeat,
'canceledAt' => null
]);
$seatBooking = $em->getRepository(BookingSeat::class)->findOneBy([
'seat' => $busSeat,
]);
if ($seatBooking || $reserve) {
return $this->redirectToRoute('viewTripSeat', ['trip' => $trip->getId(), 'seat' => $busSeat->getSeatNumber()]);
}
return $this->render('bus/book_reserve.html.twig', [
'seat' => $busSeat,
'trip' => $trip,
'booking' => $seatBooking
]);
}
/** @Route("/trip/{trip}/seat/{seat}/cancel_reservation", name="cancelReservation") */
public function cancelReservation(Request $request, $seat, Trip $trip)
{
$em = $this->entityManager;
/** @var Seat $busSeat */
$busSeat = $em->getRepository(Seat::class)->findOneBy([
'trip' => $trip,
'seatNumber' => $seat
]);
$seatBooking = $em->getRepository(BookingSeat::class)->findOneBy([
'seat' => $busSeat
]);
$reserve = $em->getRepository(Reservation::class)->findOneBy([
'seat' => $busSeat,
'canceledAt' => null
]);
$busSeat->setStatus('AVAILABLE');
$reserve->setCanceledAt(new DateTime());
$reserve->setCanceledBy($this->getUser());
$em->flush();
return $this->redirectToRoute('viewTrip', ['trip' => $trip->getId()]);
}
/** @Route("/trip/{trip}/seat/{seat}/reserve", name="viewReserve") */
public function reserve(Request $request, $seat, Trip $trip)
{
$em = $this->entityManager;
/** @var UserStation $userStation */
$userStation = $em->getRepository(UserStation::class)->findOneBy([
'user' => $this->getUser(),
'isActive' => true
]);
/** @var Seat $busSeat */
$busSeat = $em->getRepository(Seat::class)->findOneBy([
'trip' => $trip,
'seatNumber' => $seat
]);
$seatBooking = $em->getRepository(BookingSeat::class)->findOneBy([
'seat' => $busSeat
]);
$reservation = new Reservation();
$reservation->setReservedAt(new DateTime());
$reservation->setReservedBy($this->getUser());
$reservation->setReservingStation($userStation->getStation());
$reservation->setSeat($busSeat);
$reserveForm = $this->createForm(ReserveType::class, $reservation);
$reserveForm->handleRequest($request);
if ($reserveForm->isSubmitted() && $reserveForm->isValid()) {
$em->persist($reservation);
$busSeat->setStatus('RESERVED');
$em->flush();
return $this->redirectToRoute('viewTrip', ['trip' => $trip->getId()]);
}
return $this->render('bus/reserve.html.twig', [
'seat' => $busSeat,
'trip' => $trip,
'booking' => $seatBooking,
'reserveForm' => $reserveForm->createView(),
'action' => $this->generateUrl('viewReserve', ['trip' => $trip->getId(), 'seat' => $busSeat->getSeatNumber()])
]);
}
/**
* @Route("/ticket/{ticketId}", methods={"GET"}, name="generateTicket")
*/
public function generateTicket(Request $request, $ticketId, MpdfFactory $MpdfFactory): Response
{
$em = $this->entityManager;
$booking = $em->getRepository(BookingSeat::class)->findOneBy([
'id' => $ticketId
]);
$payment = null;
if ($booking->getPaidVia() == 'MPESA' || $booking->getPaidVia() == 'CASH_MPESA') {
/** @var BookingMpesa $payment */
$payment = $em->getRepository(BookingMpesa::class)->findOneBy([
'booking' => $booking
]);
}
$defaultConfig = $MpdfFactory->getDefaultConfigVariables();
$fontDirs = $defaultConfig['fontDir'];
$defaultFontConfig = $MpdfFactory->getDefaultFontVariables();
$fontData = $defaultFontConfig['fontdata'];
// dump($fontData);die;
$mPdf = $MpdfFactory->createMpdfObject([
/* 'fontDir' => array_merge($fontDirs, [
'../../public/fos/fonts/Tangerine',
'../../public/fos/fonts/OdibeeSans',
'../../public/fos/fonts/Mogra',
'../../public/fos/fonts/Libre_Baskerville',
]),
'fontdata' => $fontData + [
'tangerine' => [
'B' => 'Tangerine-Bold.ttf',
'R' => 'Tangerine-Regular.ttf'
],
'odibeesans' => [
'R' => 'OdibeeSans-Regular.ttf',
'I' => 'OdibeeSans-Regular.ttf'
],
'mogra' => [
'R' => 'Mogra-Bold.ttf',
'I' => 'Mogra-Regular.ttf',
],
'librebaskerville' => [
'R' => 'LibreBaskerville-Regular.ttf',
'B' => 'LibreBaskerville-Bold.ttf',
'I' => 'LibreBaskerville-Italic.ttf',
]
],*/
'mode' => 'utf-8',
'format' => [80, 250],
'margin_header' => 5,
'margin_footer' => 5,
'orientation' => 'P'
]);
$date = new DateTime();
$time = $date->getTimestamp();
// $mPdf->SetTopMargin("1");
// $qrCode = new QrCode('');
try {
$receiptType = 'TICKET';
/* $timsQRCode = 'ticket';
$timsqrCode = new QrCode($timsQRCode);
$output = new Png();
$data = $output->output($qrCode, 100, [255, 255, 255], [0, 0, 0]);
$timsQRCodeData = $output->output($timsqrCode, 150, [255, 255, 255], [0, 0, 0]);
file_put_contents('assets/qrcode/qrcode.png', $data);
file_put_contents('assets/qrcode/timsQRCode.png', $timsQRCodeData);*/
dump($payment);
$idBase64 = base64_encode($booking->getId());
$logoImage = file_get_contents('../public/bus/bus_1.png');
$logoBase64 = base64_encode($logoImage);
$mPdf->WriteHTML($this->renderView('bus/ticket/ticket.html.twig', [
'booking' => $booking,
'receiptType' => $receiptType,
'payment' => $payment,
'id' => $idBase64,
'logo' => $logoBase64
]));
$file = "../tickets/ticket_{$ticketId}.pdf";
// return $MpdfFactory->createDownloadResponse($mPdf, "ticket_{$ticketId}.pdf", Response::HTTP_OK, ["Set-Cookie", "fileDownload=true; path=/"]);
return $MpdfFactory->createInlineResponse($mPdf, $file);
} catch (\Exception $e) {
return new Response($e->getMessage(), Response::HTTP_BAD_REQUEST);
}
// return new Response("error occurred");
}
/**
* @Route("/daily_account", methods={"GET","POST"}, name="busDailyAccount")
*/
public function dailyAccount(Request $request): Response
{
if ($request->isMethod('POST')) {
$em = $this->entityManager;
$today = new \DateTimeImmutable();
$date = $today->format('Y-m-d');
$user_id = $this->getUser()->getId();
/** @var UserStation $userTown */
$userTown = $this->entityManager->getRepository(UserStation::class)->findOneBy([
'user' => $this->getUser(),
'isActive' => true
], ['id' => 'DESC']);
$sql = " SELECT d.route_name,a.paid_via,sum(a.amount) amount,c.trip_date FROM bus_booking_seat a
JOIN bus_seat b ON b.id = a.seat_id
JOIN bus_trip c ON c.id = b.trip_id
JOIN bus_route d ON d.id = c.route_id
WHERE date(a.created_at) = cast('2026-02-06' as date)
GROUP BY paid_via, d.id,b.trip_id";
$sqlTotal = "SELECT sum(a.amount) as total FROM bus_booking_seat a
WHERE a.created_by = {$user_id} AND date(a.created_at) = cast('2026-02-06' as date)";
$conn = $em->getConnection();
try {
$stmt = $conn->prepare($sql);
$amounts = $stmt->executeQuery()->fetchAllAssociative();
$stmtTotal = $conn->prepare($sqlTotal);
$total = $stmtTotal->executeQuery()->fetchAssociative();
return $this->render('bus/daily_account.html.twig', [
'date' => $date,
'amounts' => $amounts,
'total' => $total,
'user_town' => $userTown
]);
} catch (Exception $e) {
}
}
return $this->render('bus/daily_account.html.twig');
}
private function addTrip(\App\Entity\Bus\Route $route, string $date)
{
$em = $this->entityManager;
/** @var Stop[] $destinations */
/*$destinations = $em->getRepository(Stop::class)->findBy([
'route' => $route
]);*/
dump($route);
$dateTime = datetime::createfromformat('Y-m-d', $date);
/** @var RouteFareRule $fareRule */
$fareRule = $em->getRepository(RouteFareRule::class)->findOneBy([
'route' => $route,
]);
$trip = new Trip();
$trip->setCreatedBy($this->getUser());
$trip->setCreatedAt(new DateTime());
$trip->setTripDate($dateTime);
$trip->setRoute($route);
$trip->setDestination($route->getDestination());
$trip->setOrigin($route->getOrigin());
$trip->setTripIndex(1);
$trip->setFare($fareRule->getNormalFare());
$departureStored = $route->getDepartureTime();
$arrivalStored = $route->getEta();
// Today base
$today = new \DateTime('today');
// Build departure with today's date + original time
$departure = (clone $today)->setTime(
(int)$departureStored->format('H'),
(int)$departureStored->format('i'),
(int)$departureStored->format('s')
);
// Build arrival with today's date + original time
$arrival = (clone $today)->setTime(
(int)$arrivalStored->format('H'),
(int)$arrivalStored->format('i'),
(int)$arrivalStored->format('s')
);
// If arrival is earlier than departure → it's next day
if ($arrival <= $departure) {
$arrival->modify('+1 day');
}
$trip->setDepartureTime($departure);
$trip->setEta($arrival);
/** @var Vehicle $vehicle */
$vehicle = $em->getRepository(Vehicle::class)->findOneBy([
'regNumber' => 'KCE990Q'
]);
$seats = [];
for ($i = 1; $i <= $vehicle->getPassengerCapacity(); $i++) {
$seat = new Seat();
$seat->setStatus('AVAILABLE');
$seat->setSeatNumber($i);
$seat->setTrip($trip);
$seat->setIsBooked(false);
$seat->setCreatedAt(new DateTime());
$seats[] = $seat;
}
$trip->setSeats($seats);
$trip->setVehicle($vehicle);
$tripVehicle = new TripVehicle();
$tripVehicle->setCreatedAt(new DateTime());
$tripVehicle->setTrip($trip);
$tripVehicle->setCreatedBy($this->getUser());
$tripVehicle->setIsCancelled(false);
$tripVehicle->setVehicle($vehicle);
$this->entityManager->persist($tripVehicle);
$this->entityManager->persist($trip);
$this->entityManager->flush();
}
private
function jsonTestData()
{
$jsonData = '[{
"id": 741421,
"account_date": "2023-10-09",
"expenses": 0,
"created_at": "2023-10-09 19:59:54",
"station_name": "MOMBASA",
"sender_name": "patrick kinyua",
"sender_phone_number": "0727 044 524",
"receiver_name": "luke njoroge",
"receiver_phone_number": "0705 179 108",
"amount": 2100,
"is_cancelled": 0
},
{
"id": 741405,
"account_date": "2023-10-09",
"expenses": 0,
"created_at": "2023-10-09 19:19:03",
"station_name": "MERU",
"sender_name": "phineas kirimi",
"sender_phone_number": "0791 713 924",
"receiver_name": "patrick munoru",
"receiver_phone_number": "0720 949 054",
"amount": 200,
"is_cancelled": 0
},
{
"id": 741395,
"account_date": "2023-10-09",
"expenses": 0,
"created_at": "2023-10-09 19:09:05",
"station_name": "kitui",
"sender_name": "scout shop",
"sender_phone_number": "0712 907 877",
"receiver_name": "winfred ndolo",
"receiver_phone_number": "0724 528 806",
"amount": 200,
"is_cancelled": 0
},
{
"id": 741393,
"account_date": "2023-10-09",
"expenses": 0,
"created_at": "2023-10-09 19:07:04",
"station_name": "SIAKAGO",
"sender_name": "james gichuki",
"sender_phone_number": "0722 352 992",
"receiver_name": "richard waitherero",
"receiver_phone_number": "0728 454 129",
"amount": 300,
"is_cancelled": 0
},
{
"id": 741378,
"account_date": "2023-10-09",
"expenses": 0,
"created_at": "2023-10-09 18:55:25",
"station_name": "NAIROBI",
"sender_name": "denis munene",
"sender_phone_number": "0740 270 344",
"receiver_name": "tom ochieng",
"receiver_phone_number": "0715 553 018",
"amount": 200,
"is_cancelled": 0
},
{
"id": 741370,
"account_date": "2023-10-09",
"expenses": 0,
"created_at": "2023-10-09 18:43:13",
"station_name": "NAIROBI",
"sender_name": "peter njagi",
"sender_phone_number": "0722 883 774",
"receiver_name": "jackson kanambiu",
"receiver_phone_number": "0714 203 693",
"amount": 200,
"is_cancelled": 0
},
{
"id": 741355,
"account_date": "2023-10-09",
"expenses": 0,
"created_at": "2023-10-09 18:32:02",
"station_name": "MOMBASA",
"sender_name": "mary mbugi",
"sender_phone_number": "0727 897 097",
"receiver_name": "elizabeth nyawira",
"receiver_phone_number": "0706 221 351",
"amount": 300,
"is_cancelled": 0
},
{
"id": 741351,
"account_date": "2023-10-09",
"expenses": 0,
"created_at": "2023-10-09 18:25:01",
"station_name": "NAIROBI",
"sender_name": "david thairu",
"sender_phone_number": "0722 280 846",
"receiver_name": "daniel kimondo",
"receiver_phone_number": "0724 215 522",
"amount": 200,
"is_cancelled": 0
},
{
"id": 741330,
"account_date": "2023-10-09",
"expenses": 0,
"created_at": "2023-10-09 17:58:08",
"station_name": "NAIROBI",
"sender_name": "karen karimi",
"sender_phone_number": "0714 509 299",
"receiver_name": "victor muthoni",
"receiver_phone_number": "0710 329 231",
"amount": 200,
"is_cancelled": 0
},
{
"id": 741328,
"account_date": "2023-10-09",
"expenses": 0,
"created_at": "2023-10-09 17:56:42",
"station_name": "KATHWANA",
"sender_name": "samwel",
"sender_phone_number": "0722 595 844",
"receiver_name": "dirangu ndungu",
"receiver_phone_number": "0721 207 371",
"amount": 250,
"is_cancelled": 0
},
{
"id": 741301,
"account_date": "2023-10-09",
"expenses": 0,
"created_at": "2023-10-09 17:35:27",
"station_name": "MOMBASA",
"sender_name": "edith kimani",
"sender_phone_number": "0714 567 205",
"receiver_name": "okumu",
"receiver_phone_number": "0714 567 205",
"amount": 300,
"is_cancelled": 0
},
{
"id": 741289,
"account_date": "2023-10-09",
"expenses": 0,
"created_at": "2023-10-09 17:26:09",
"station_name": "MTWAPA",
"sender_name": "caroline waweru",
"sender_phone_number": "0712 353 926",
"receiver_name": "GLADYS WAWERU",
"receiver_phone_number": "0723 950 679",
"amount": 300,
"is_cancelled": 0
},
{
"id": 741270,
"account_date": "2023-10-09",
"expenses": 0,
"created_at": "2023-10-09 17:03:24",
"station_name": "MWEA",
"sender_name": "FOCUS EMBU",
"sender_phone_number": "0716 447 206",
"receiver_name": "FOCUS MWEA",
"receiver_phone_number": "0721 606 746",
"amount": 150,
"is_cancelled": 0
},
{
"id": 741266,
"account_date": "2023-10-09",
"expenses": 0,
"created_at": "2023-10-09 16:58:43",
"station_name": "THIKA",
"sender_name": "KIMATHI KELVIN",
"sender_phone_number": "0726 116 760",
"receiver_name": "JAMES NGINGI",
"receiver_phone_number": "0728 171 491",
"amount": 200,
"is_cancelled": 0
},
{
"id": 741261,
"account_date": "2023-10-09",
"expenses": 0,
"created_at": "2023-10-09 16:54:46",
"station_name": "NAIROBI",
"sender_name": "ROSALINE WAWIRA",
"sender_phone_number": "0728 288 950",
"receiver_name": "eras karimi",
"receiver_phone_number": "0724 867 838",
"amount": 200,
"is_cancelled": 0
},
{
"id": 741248,
"account_date": "2023-10-09",
"expenses": 0,
"created_at": "2023-10-09 16:47:18",
"station_name": "MOMBASA",
"sender_name": "jemmimah",
"sender_phone_number": "0711 485 954",
"receiver_name": "rose khaidi",
"receiver_phone_number": "0706 749 991",
"amount": 300,
"is_cancelled": 0
},
{
"id": 741209,
"account_date": "2023-10-09",
"expenses": 0,
"created_at": "2023-10-09 16:05:38",
"station_name": "kitui",
"sender_name": "eunice mambiro",
"sender_phone_number": "0720 997 508",
"receiver_name": "samwel muturi",
"receiver_phone_number": "0715 143 362",
"amount": 200,
"is_cancelled": 0
},
{
"id": 741185,
"account_date": "2023-10-09",
"expenses": 0,
"created_at": "2023-10-09 15:49:11",
"station_name": "NAIROBI",
"sender_name": "johnson njeru",
"sender_phone_number": "0724 586 321",
"receiver_name": "jane njoki njeru",
"receiver_phone_number": "0722 398 853",
"amount": 300,
"is_cancelled": 0
},
{
"id": 741175,
"account_date": "2023-10-09",
"expenses": 0,
"created_at": "2023-10-09 15:36:39",
"station_name": "NAIROBI",
"sender_name": "alexande david",
"sender_phone_number": "0795 762 309",
"receiver_name": "peter aunga",
"receiver_phone_number": "0715 044 187",
"amount": 200,
"is_cancelled": 0
},
{
"id": 741172,
"account_date": "2023-10-09",
"expenses": 0,
"created_at": "2023-10-09 15:33:17",
"station_name": "NAIROBI",
"sender_name": "j kimondo",
"sender_phone_number": "0722 830 014",
"receiver_name": "fred muiruri",
"receiver_phone_number": "0705 945 561",
"amount": 200,
"is_cancelled": 0
}
]';
$arrayedFromJson = json_decode($jsonData, true);
return $arrayedFromJson;
}
}