Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
BookingController.cs 5.93 KiB
using BookingMicroservice.Exceptions;
using BookingMicroservice.Models;
using BookingMicroservice.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using System.Security.Claims;
using Stripe.Checkout;
using Stripe;



namespace BookingMicroservice.Controllers
{
    [ApiController]
    [Route("api/[Controller]")]
    public class BookingController : ControllerBase
    {
        private readonly IReservationComplianceService reservationComplianceService;
        private readonly IBookingService bookingService;
        private readonly IStripeService stripeService;

        private readonly IConfiguration configuration;

        public BookingController(IReservationComplianceService reservationComplianceService, IBookingService bookingService,  IStripeService stripeService, IConfiguration configuration)
        {
            this.reservationComplianceService = reservationComplianceService;
            this.bookingService = bookingService;
            this.stripeService = stripeService;
            this.configuration = configuration;
        }

        [Authorize]
        [HttpGet()]
        public IActionResult GetBookings(int? flightId = null, int? userId = null, BookingClass? bookingClass = null) 
        {
            List<Booking> bookings = bookingService.GetBookings(flightId, userId, bookingClass);
            if (bookings == null)
                return BadRequest("Unable to get bookings");

            return Ok(bookings);
        }

        [Authorize]
        [HttpGet("{id}")]
        public IActionResult GetBooking([FromRoute] int id) 
        {
            Booking? booking = bookingService.GetBooking(id);
            if(booking == null)
                return NotFound($"Could not find booking with id: {id}");
        
            return Ok(booking);
        }

        [Authorize]
        [HttpPost()]
        public async Task<IActionResult> MakeBooking([FromBody] BookingCreation bookingCreationModel)
        {
            
            string? userIdValue = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
            if (!int.TryParse(userIdValue, out int userId))
                return BadRequest("Unable to get User Id from Token");

            try
            {
                bool isPaymentSuccessful = await stripeService.VerifyPaymentIntent(bookingCreationModel.PaymentIntentId);
                if (!isPaymentSuccessful)
                {
                    return BadRequest("Payment verification failed.");
                }

                Booking? booking = await reservationComplianceService.TryCreateBookingAsync(bookingCreationModel.FlightId, userId, bookingCreationModel.BookingClass, bookingCreationModel.SeatId);
                if (booking == null)
                    return BadRequest("Error in creating booking");

                return Ok(booking);
            } 
            catch (InvalidOperationException exception)
            {
                return BadRequest(exception.Message);
            } 
            catch (BookingException exception)
            {
                return BadRequest(exception.Message);
            }
        }

        [Authorize]
        [HttpPut("{bookingId}")]
        public async Task<IActionResult> UpdatedBookingSeat([FromRoute] int bookingId, [FromBody] BookingUpdate bookingUpdateModel)
        {
            try
            {
                await reservationComplianceService.TryBookSeatAsync(bookingId, bookingUpdateModel.SeatId);
                return Ok(new { BookedSeat = true, Message = "Seat booked successfully." });
            } 
            catch (InvalidOperationException exception)
            {
                return BadRequest(exception.Message);
            } 
            catch (BookingException exception)
            {
                return Ok(new { BookedSeat = false, Message = exception.Message });
            }
        }

        [Authorize]
        [HttpGet("upcoming")]
        public async Task<IActionResult> GetUpcomingFlightBookings()
        {
            string? userIdValue = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
            if (!int.TryParse(userIdValue, out int userId))
                return BadRequest("Unable to get User Id from Token");

            try
            {
                IEnumerable<FlightBookingInfo> flights = await reservationComplianceService.TryGetUpcomingFlightsAsync(userId);
                return Ok(flights);
            } 
            catch(InvalidOperationException exception)
            {
                return BadRequest(exception.Message);
            }
        }

        [Authorize]
        [HttpGet("history")]
        public async Task<IActionResult> GetPreviousFlightBookings()
        {
            string? userIdValue = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
            if (!int.TryParse(userIdValue, out int userId))
                return BadRequest("Unable to get User Id from Token");

            try
            {
                IEnumerable<FlightBookingInfo> flights = await reservationComplianceService.TryGetPreviousFlightsAsync(userId);
                return Ok(flights);
            }
            catch (InvalidOperationException exception)
            {
                return BadRequest(exception.Message);
            }
        }

        [HttpPost("create-payment-intent")]
        public async Task<IActionResult> CreatePaymentIntent([FromBody] PaymentIntentCreateRequest request)
        {
            var paymentIntentService = new PaymentIntentService();
            var paymentIntent = paymentIntentService.Create(new PaymentIntentCreateOptions
            {
                Amount = stripeService.CalculateOrderAmount(request.Items),
                Currency = "eur",
                AutomaticPaymentMethods = new PaymentIntentAutomaticPaymentMethodsOptions
                {
                    Enabled = true,
                },
            });

            return new JsonResult(new { clientSecret = paymentIntent.ClientSecret });
        }

    }
}