Skip to content
Snippets Groups Projects
Commit a0baae2e authored by paula_rodriguezslash's avatar paula_rodriguezslash
Browse files

first try updated the vals to ask flight service

parent 4bb5fa2c
No related branches found
No related tags found
No related merge requests found
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using FlightBooking.Service.Data;
namespace FlightBooking.Service.Data.DTO namespace FlightBooking.Service.Data.DTO
{ {
...@@ -52,5 +54,7 @@ namespace FlightBooking.Service.Data.DTO ...@@ -52,5 +54,7 @@ namespace FlightBooking.Service.Data.DTO
public int OutboundFareId { get; set; } //We are keeping Fare per booking to allow flexibility e.g Adult in Economy and Child in Business class public int OutboundFareId { get; set; } //We are keeping Fare per booking to allow flexibility e.g Adult in Economy and Child in Business class
public int? ReturnFareId { get; set; } public int? ReturnFareId { get; set; }
public ClassType ClassType { get; set; }
} }
} }
\ No newline at end of file
namespace FlightBooking.Service.Data.DTO{
public class FlightCapacityDTO
{
public int EconomyCapacity { get; set; }
public int BusinessCapacity { get; set; }
}
}
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
EntityExist, EntityExist,
Unprocessable, Unprocessable,
Unauthorized, Unauthorized,
FullCapacity
} }
public enum SortOrder public enum SortOrder
...@@ -37,4 +38,11 @@ ...@@ -37,4 +38,11 @@
Confirmed, Confirmed,
Paid Paid
} }
public enum ClassType
{
BUSINESS = 0,
ECONOMY = 1
}
} }
\ No newline at end of file
...@@ -32,5 +32,6 @@ namespace FlightBooking.Service.Data.Models ...@@ -32,5 +32,6 @@ namespace FlightBooking.Service.Data.Models
//one to one to for seats. one booking at most one seat //one to one to for seats. one booking at most one seat
public ReservedSeat? ReservedSeat { get; set; } public ReservedSeat? ReservedSeat { get; set; }
public ClassType ClassType { get; set; }
} }
} }
\ No newline at end of file
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="8.0.1" /> <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="8.0.1" />
<PackageReference Include="MySqlConnector" Version="2.3.5" /> <PackageReference Include="MySqlConnector" Version="2.3.5" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="NLog.Web.AspNetCore" Version="5.3.8" /> <PackageReference Include="NLog.Web.AspNetCore" Version="5.3.8" />
<PackageReference Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="7.3.1" /> <PackageReference Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="7.3.1" />
......
...@@ -12,21 +12,25 @@ namespace FlightBooking.Service.Services ...@@ -12,21 +12,25 @@ namespace FlightBooking.Service.Services
{ {
private readonly IGenericRepository<BookingOrder> _orderRepo; private readonly IGenericRepository<BookingOrder> _orderRepo;
private readonly IGenericRepository<FlightInformation> _flightRepo; private readonly IGenericRepository<FlightInformation> _flightRepo;
private readonly IGenericRepository<Booking> _bookingRepo;
private readonly IGenericRepository<FlightFare> _flightFareRepo; private readonly IGenericRepository<FlightFare> _flightFareRepo;
private readonly IStripeService _stripeService; private readonly IStripeService _stripeService;
private readonly IFlightService _flightService;
private readonly ILogger<BookingOrderService> _logger; private readonly ILogger<BookingOrderService> _logger;
private List<FlightFare> allFlightFares = new List<FlightFare>(); //declare once so we can use it throughout private List<FlightFare> allFlightFares = new List<FlightFare>(); //declare once so we can use it throughout
public BookingOrderService(IGenericRepository<BookingOrder> orderRepo, IGenericRepository<FlightInformation> flightRepo, public BookingOrderService(IGenericRepository<BookingOrder> orderRepo, IGenericRepository<FlightInformation> flightRepo, IGenericRepository<Booking> bookingRepo,
IGenericRepository<FlightFare> flightFareRepo, IStripeService stripeService, ILogger<BookingOrderService> logger) IGenericRepository<FlightFare> flightFareRepo, IStripeService stripeService, ILogger<BookingOrderService> logger, IFlightService flightService)
{ {
_orderRepo = orderRepo; _orderRepo = orderRepo;
_flightRepo = flightRepo; _flightRepo = flightRepo;
_bookingRepo = bookingRepo;
_flightFareRepo = flightFareRepo; _flightFareRepo = flightFareRepo;
_stripeService = stripeService; _stripeService = stripeService;
_logger = logger; _logger = logger;
_flightService = flightService;
} }
public async Task<ServiceResponse<BookingResponseDTO?>> CreateBookingOrderAsync(BookingOrderDTO order) public async Task<ServiceResponse<BookingResponseDTO?>> CreateBookingOrderAsync(BookingOrderDTO order)
...@@ -108,6 +112,42 @@ namespace FlightBooking.Service.Services ...@@ -108,6 +112,42 @@ namespace FlightBooking.Service.Services
return new ServiceResponse<BookingResponseDTO?>(null, InternalCode.Unprocessable, "The number of flights exceed number of available seats"); return new ServiceResponse<BookingResponseDTO?>(null, InternalCode.Unprocessable, "The number of flights exceed number of available seats");
} }
// Retrieve flight information to get the flight ID for capacity check
var flightInfo = await _flightRepo.Query().FirstOrDefaultAsync(f => f.FlightNumber == order.OutboundFlightNumber);
if (flightInfo == null)
{
// Handle flight not found scenario
return new ServiceResponse<BookingResponseDTO?>(null, InternalCode.Unprocessable, "Flight not found.");
}
// Retrieve flight capacity
var flightCapacity = await _flightService.GetFlightCapacityAsync(flightInfo.Id);
if (flightCapacity == null)
{
// Handle capacity fetch error
return new ServiceResponse<BookingResponseDTO?>(null, InternalCode.Unprocessable, "Unable to retrieve flight capacity.");
}
// Calculate existing bookings for each class type
var existingBookings = await _bookingRepo.Query().Where(b => b.FlightId == flightInfo.Id).ToListAsync();
int existingEconomyBookings = existingBookings.Count(b => b.ClassType == ClassType.ECONOMY);
int existingBusinessBookings = existingBookings.Count(b => b.ClassType == ClassType.BUSINESS);
// Compare against capacity
foreach (var bookingRequest in order.Bookings)
{
if (bookingRequest.ClassType == ClassType.Economy && existingEconomyBookings >= flightCapacity.EconomyCapacity)
{
return new ServiceResponse<BookingResponseDTO?>(null, InternalCode.FullCapacity, "Economy class is fully booked.");
}
if (bookingRequest.ClassType == ClassType.Business && existingBusinessBookings >= flightCapacity.BusinessCapacity)
{
return new ServiceResponse<BookingResponseDTO?>(null, InternalCode.FullCapacity, "Business class is fully booked.");
}
}
//if all checks passed, lets reduce number of available seats. //if all checks passed, lets reduce number of available seats.
//If Checks are passed, set status as InProgress and reduce available seats to avoid overbooking the flight //If Checks are passed, set status as InProgress and reduce available seats to avoid overbooking the flight
//We hold a seat for N mins max(N is set in config). Use a background job to return UnbookedSeats back into the Pool //We hold a seat for N mins max(N is set in config). Use a background job to return UnbookedSeats back into the Pool
......
...@@ -5,6 +5,8 @@ using FlightBooking.Service.Data.Models; ...@@ -5,6 +5,8 @@ using FlightBooking.Service.Data.Models;
using FlightBooking.Service.Data.Repository; using FlightBooking.Service.Data.Repository;
using FlightBooking.Service.Services.Interfaces; using FlightBooking.Service.Services.Interfaces;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
namespace FlightBooking.Service.Services namespace FlightBooking.Service.Services
{ {
...@@ -13,11 +15,13 @@ namespace FlightBooking.Service.Services ...@@ -13,11 +15,13 @@ namespace FlightBooking.Service.Services
{ {
private readonly IGenericRepository<FlightInformation> _flightRepo; private readonly IGenericRepository<FlightInformation> _flightRepo;
private readonly IMapper _mapper; private readonly IMapper _mapper;
private readonly HttpClient _httpClient;
public FlightService(IGenericRepository<FlightInformation> flightRepo, IMapper mapper) public FlightService(IGenericRepository<FlightInformation> flightRepo, IMapper mapper, IHttpClientFactory httpClientFactory)
{ {
_mapper = mapper; _mapper = mapper;
_flightRepo = flightRepo; _flightRepo = flightRepo;
_httpClient = httpClientFactory.CreateClient("FlightServiceClient");
} }
public async Task<ServiceResponse<FlightInformationDTO?>> GetFlightInformationAsync(string flightNumber) public async Task<ServiceResponse<FlightInformationDTO?>> GetFlightInformationAsync(string flightNumber)
...@@ -43,5 +47,20 @@ namespace FlightBooking.Service.Services ...@@ -43,5 +47,20 @@ namespace FlightBooking.Service.Services
return new ServiceResponse<string>(string.Empty, (InternalCode)result); return new ServiceResponse<string>(string.Empty, (InternalCode)result);
} }
public async Task<FlightCapacityDTO> GetFlightCapacityAsync(int flightId)
{
var response = await _httpClient.GetAsync($"api/Flight/{flightId}/capacity");
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStringAsync();
var capacity = JsonConvert.DeserializeObject<FlightCapacityDTO>(content);
if (capacity == null)
{
throw new InvalidOperationException("The flight capacity data could not be retrieved.");
}
return capacity;
}
} }
} }
\ No newline at end of file
...@@ -10,6 +10,7 @@ namespace FlightBooking.Service.Services.Interfaces ...@@ -10,6 +10,7 @@ namespace FlightBooking.Service.Services.Interfaces
/// <param name="flightNumber"></param> /// <param name="flightNumber"></param>
/// <returns></returns> /// <returns></returns>
Task<ServiceResponse<FlightInformationDTO?>> GetFlightInformationAsync(string flightNumber); Task<ServiceResponse<FlightInformationDTO?>> GetFlightInformationAsync(string flightNumber);
Task<FlightCapacityDTO> GetFlightCapacityAsync(int flightId);
/// <summary> /// <summary>
/// Updates the flight capacity /// Updates the flight capacity
......
...@@ -3,6 +3,7 @@ using FlightBooking.Service.Data.Configs; ...@@ -3,6 +3,7 @@ using FlightBooking.Service.Data.Configs;
using FlightBooking.Service.Data.Repository; using FlightBooking.Service.Data.Repository;
using FlightBooking.Service.Middleware; using FlightBooking.Service.Middleware;
using FlightBooking.Service.Services; using FlightBooking.Service.Services;
using FlightBooking.Service.Services.Interfaces; // Adjust this to the correct namespace where IFlightService is located
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
...@@ -93,6 +94,8 @@ namespace FlightBooking.Service ...@@ -93,6 +94,8 @@ namespace FlightBooking.Service
//Add our custom services //Add our custom services
services.AddRepository(); services.AddRepository();
services.AddServices(); services.AddServices();
services.AddScoped<IFlightService, FlightService>();
services.AddEndpointsApiExplorer(); services.AddEndpointsApiExplorer();
services.AddSwaggerGen(options => services.AddSwaggerGen(options =>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment