From a0baae2e08c5d4a781a651000926c480bcd77b4f Mon Sep 17 00:00:00 2001
From: paula_rodriguezslash <paula.rodriguez@slashmobility.com>
Date: Sun, 7 Apr 2024 12:55:06 +0100
Subject: [PATCH] first try updated the vals to ask flight service

---
 .../Data/DTO/BookingDTO.cs                    |  4 ++
 .../Data/DTO/FlightCapacityDTO.cs             |  7 +++
 .../FlightBooking.Service/Data/Enums.cs       |  8 ++++
 .../Data/Models/Booking.cs                    |  1 +
 .../FlightBooking.Service.csproj              |  1 +
 .../Services/BookingOrderService.cs           | 44 ++++++++++++++++++-
 .../Services/FlightService.cs                 | 21 ++++++++-
 .../Services/Interfaces/IFlightService.cs     |  1 +
 .../FlightBooking.Service/Startup.cs          |  3 ++
 9 files changed, 87 insertions(+), 3 deletions(-)
 create mode 100644 BookingService/FlightBooking.Service/Data/DTO/FlightCapacityDTO.cs

diff --git a/BookingService/FlightBooking.Service/Data/DTO/BookingDTO.cs b/BookingService/FlightBooking.Service/Data/DTO/BookingDTO.cs
index 8a93333..eaea2ea 100644
--- a/BookingService/FlightBooking.Service/Data/DTO/BookingDTO.cs
+++ b/BookingService/FlightBooking.Service/Data/DTO/BookingDTO.cs
@@ -1,4 +1,6 @@
 using System.ComponentModel.DataAnnotations;
+using FlightBooking.Service.Data;
+
 
 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? ReturnFareId { get; set; }
+
+        public ClassType ClassType { get; set; } 
     }
 }
\ No newline at end of file
diff --git a/BookingService/FlightBooking.Service/Data/DTO/FlightCapacityDTO.cs b/BookingService/FlightBooking.Service/Data/DTO/FlightCapacityDTO.cs
new file mode 100644
index 0000000..8de7630
--- /dev/null
+++ b/BookingService/FlightBooking.Service/Data/DTO/FlightCapacityDTO.cs
@@ -0,0 +1,7 @@
+namespace FlightBooking.Service.Data.DTO{
+    public class FlightCapacityDTO
+    {
+        public int EconomyCapacity { get; set; }
+        public int BusinessCapacity { get; set; }
+    }
+}
diff --git a/BookingService/FlightBooking.Service/Data/Enums.cs b/BookingService/FlightBooking.Service/Data/Enums.cs
index 15a8a62..3101df5 100644
--- a/BookingService/FlightBooking.Service/Data/Enums.cs
+++ b/BookingService/FlightBooking.Service/Data/Enums.cs
@@ -23,6 +23,7 @@
         EntityExist,
         Unprocessable,
         Unauthorized,
+        FullCapacity
     }
 
     public enum SortOrder
@@ -37,4 +38,11 @@
         Confirmed,
         Paid
     }
+
+    public enum ClassType
+    {
+        BUSINESS = 0,
+        ECONOMY = 1
+    }
+
 }
\ No newline at end of file
diff --git a/BookingService/FlightBooking.Service/Data/Models/Booking.cs b/BookingService/FlightBooking.Service/Data/Models/Booking.cs
index 315ea18..085709f 100644
--- a/BookingService/FlightBooking.Service/Data/Models/Booking.cs
+++ b/BookingService/FlightBooking.Service/Data/Models/Booking.cs
@@ -32,5 +32,6 @@ namespace FlightBooking.Service.Data.Models
         //one to one to for seats. one booking at most one seat
 
         public ReservedSeat? ReservedSeat { get; set; }
+        public ClassType ClassType { get; set; }
     }
 }
\ No newline at end of file
diff --git a/BookingService/FlightBooking.Service/FlightBooking.Service.csproj b/BookingService/FlightBooking.Service/FlightBooking.Service.csproj
index 217d79c..0f54507 100644
--- a/BookingService/FlightBooking.Service/FlightBooking.Service.csproj
+++ b/BookingService/FlightBooking.Service/FlightBooking.Service.csproj
@@ -27,6 +27,7 @@
 		</PackageReference>
 		<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="8.0.1" />
 		<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="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="7.3.1" />
 
diff --git a/BookingService/FlightBooking.Service/Services/BookingOrderService.cs b/BookingService/FlightBooking.Service/Services/BookingOrderService.cs
index f1d70bd..57674c3 100644
--- a/BookingService/FlightBooking.Service/Services/BookingOrderService.cs
+++ b/BookingService/FlightBooking.Service/Services/BookingOrderService.cs
@@ -12,21 +12,25 @@ namespace FlightBooking.Service.Services
     {
         private readonly IGenericRepository<BookingOrder> _orderRepo;
         private readonly IGenericRepository<FlightInformation> _flightRepo;
+        private readonly IGenericRepository<Booking> _bookingRepo;
         private readonly IGenericRepository<FlightFare> _flightFareRepo;
         private readonly IStripeService _stripeService;
+        private readonly IFlightService _flightService;
 
         private readonly ILogger<BookingOrderService> _logger;
 
         private List<FlightFare> allFlightFares = new List<FlightFare>(); //declare once so we can use it throughout
 
-        public BookingOrderService(IGenericRepository<BookingOrder> orderRepo, IGenericRepository<FlightInformation> flightRepo,
-            IGenericRepository<FlightFare> flightFareRepo, IStripeService stripeService, ILogger<BookingOrderService> logger)
+        public BookingOrderService(IGenericRepository<BookingOrder> orderRepo, IGenericRepository<FlightInformation> flightRepo, IGenericRepository<Booking> bookingRepo,
+            IGenericRepository<FlightFare> flightFareRepo, IStripeService stripeService, ILogger<BookingOrderService> logger, IFlightService flightService)
         {
             _orderRepo = orderRepo;
             _flightRepo = flightRepo;
+            _bookingRepo = bookingRepo;
             _flightFareRepo = flightFareRepo;
             _stripeService = stripeService;
             _logger = logger;
+            _flightService = flightService;
         }
 
         public async Task<ServiceResponse<BookingResponseDTO?>> CreateBookingOrderAsync(BookingOrderDTO order)
@@ -108,6 +112,42 @@ namespace FlightBooking.Service.Services
                 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 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
diff --git a/BookingService/FlightBooking.Service/Services/FlightService.cs b/BookingService/FlightBooking.Service/Services/FlightService.cs
index f7f4e13..d0f9e65 100644
--- a/BookingService/FlightBooking.Service/Services/FlightService.cs
+++ b/BookingService/FlightBooking.Service/Services/FlightService.cs
@@ -5,6 +5,8 @@ using FlightBooking.Service.Data.Models;
 using FlightBooking.Service.Data.Repository;
 using FlightBooking.Service.Services.Interfaces;
 using Microsoft.EntityFrameworkCore;
+using Newtonsoft.Json;
+
 
 namespace FlightBooking.Service.Services
 {
@@ -13,11 +15,13 @@ namespace FlightBooking.Service.Services
     {
         private readonly IGenericRepository<FlightInformation> _flightRepo;
         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;
             _flightRepo = flightRepo;
+            _httpClient = httpClientFactory.CreateClient("FlightServiceClient");
         }
 
         public async Task<ServiceResponse<FlightInformationDTO?>> GetFlightInformationAsync(string flightNumber)
@@ -43,5 +47,20 @@ namespace FlightBooking.Service.Services
 
             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
diff --git a/BookingService/FlightBooking.Service/Services/Interfaces/IFlightService.cs b/BookingService/FlightBooking.Service/Services/Interfaces/IFlightService.cs
index 290f5d2..5e54b08 100644
--- a/BookingService/FlightBooking.Service/Services/Interfaces/IFlightService.cs
+++ b/BookingService/FlightBooking.Service/Services/Interfaces/IFlightService.cs
@@ -10,6 +10,7 @@ namespace FlightBooking.Service.Services.Interfaces
         /// <param name="flightNumber"></param>
         /// <returns></returns>
         Task<ServiceResponse<FlightInformationDTO?>> GetFlightInformationAsync(string flightNumber);
+        Task<FlightCapacityDTO> GetFlightCapacityAsync(int flightId);
 
         /// <summary>
         /// Updates the flight capacity
diff --git a/BookingService/FlightBooking.Service/Startup.cs b/BookingService/FlightBooking.Service/Startup.cs
index 540cfff..68702c8 100644
--- a/BookingService/FlightBooking.Service/Startup.cs
+++ b/BookingService/FlightBooking.Service/Startup.cs
@@ -3,6 +3,7 @@ using FlightBooking.Service.Data.Configs;
 using FlightBooking.Service.Data.Repository;
 using FlightBooking.Service.Middleware;
 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.EntityFrameworkCore;
 using Microsoft.IdentityModel.Tokens;
@@ -93,6 +94,8 @@ namespace FlightBooking.Service
             //Add our custom services
             services.AddRepository();
             services.AddServices();
+            services.AddScoped<IFlightService, FlightService>();
+
 
             services.AddEndpointsApiExplorer();
             services.AddSwaggerGen(options =>
-- 
GitLab