diff --git a/BookingService_Old/.gitignore b/BookingService_Old/.gitignore deleted file mode 100644 index 1242aad84b43939c4860165458c6b3d8ab4716d9..0000000000000000000000000000000000000000 --- a/BookingService_Old/.gitignore +++ /dev/null @@ -1,263 +0,0 @@ -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. - -# User-specific files -*.suo -*.user -*.userosscache -*.sln.docstates - -# User-specific files (MonoDevelop/Xamarin Studio) -*.userprefs - -# Build results -[Dd]ebug/ -[Dd]ebugPublic/ -[Rr]elease/ -[Rr]eleases/ -x64/ -x86/ -bld/ -[Bb]in/ -[Oo]bj/ -[Ll]og/ - -# Visual Studio 2015 cache/options directory -.vs/ -# Uncomment if you have tasks that create the project's static files in wwwroot -#wwwroot/ - -# MSTest test Results -[Tt]est[Rr]esult*/ -[Bb]uild[Ll]og.* - -# NUNIT -*.VisualState.xml -TestResult.xml - -# Build Results of an ATL Project -[Dd]ebugPS/ -[Rr]eleasePS/ -dlldata.c - -# DNX -project.lock.json -project.fragment.lock.json -artifacts/ - -*_i.c -*_p.c -*_i.h -*.ilk -*.meta -*.obj -*.pch -*.pdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.tmp_proj -*.log -*.vspscc -*.vssscc -.builds -*.pidb -*.svclog -*.scc - -# Chutzpah Test files -_Chutzpah* - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opendb -*.opensdf -*.sdf -*.cachefile -*.VC.db -*.VC.VC.opendb - -# Visual Studio profiler -*.psess -*.vsp -*.vspx -*.sap - -# TFS 2012 Local Workspace -$tf/ - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper*/ -*.[Rr]e[Ss]harper -*.DotSettings.user - -# JustCode is a .NET coding add-in -.JustCode - -# TeamCity is a build add-in -_TeamCity* - -# DotCover is a Code Coverage Tool -*.dotCover - -# NCrunch -_NCrunch_* -.*crunch*.local.xml -nCrunchTemp_* - -# MightyMoose -*.mm.* -AutoTest.Net/ - -# Web workbench (sass) -.sass-cache/ - -# Installshield output folder -[Ee]xpress/ - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish/ - -# Publish Web Output -*.[Pp]ublish.xml -*.azurePubxml -# TODO: Comment the next line if you want to checkin your web deploy settings -# but database connection strings (with potential passwords) will be unencrypted -#*.pubxml -*.publishproj - -# Microsoft Azure Web App publish settings. Comment the next line if you want to -# checkin your Azure Web App publish settings, but sensitive information contained -# in these scripts will be unencrypted -PublishScripts/ - -# NuGet Packages -*.nupkg -# The packages folder can be ignored because of Package Restore -**/packages/* -# except build/, which is used as an MSBuild target. -!**/packages/build/ -# Uncomment if necessary however generally it will be regenerated when needed -#!**/packages/repositories.config -# NuGet v3's project.json files produces more ignoreable files -*.nuget.props -*.nuget.targets - -# Microsoft Azure Build Output -csx/ -*.build.csdef - -# Microsoft Azure Emulator -ecf/ -rcf/ - -# Windows Store app package directories and files -AppPackages/ -BundleArtifacts/ -Package.StoreAssociation.xml -_pkginfo.txt - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!*.[Cc]ache/ - -# Others -ClientBin/ -~$* -*~ -*.dbmdl -*.dbproj.schemaview -*.jfm -*.pfx -*.publishsettings -node_modules/ -orleans.codegen.cs - -# Since there are multiple workflows, uncomment next line to ignore bower_components -# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) -#bower_components/ - -# RIA/Silverlight projects -Generated_Code/ - -# Backup & report files from converting an old project file -# to a newer Visual Studio version. Backup files are not needed, -# because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -UpgradeLog*.htm - -# SQL Server files -*.mdf -*.ldf - -# Business Intelligence projects -*.rdl.data -*.bim.layout -*.bim_*.settings - -# Microsoft Fakes -FakesAssemblies/ - -# GhostDoc plugin setting file -*.GhostDoc.xml - -# Node.js Tools for Visual Studio -.ntvs_analysis.dat - -# Visual Studio 6 build log -*.plg - -# Visual Studio 6 workspace options file -*.opt - -# Visual Studio LightSwitch build output -**/*.HTMLClient/GeneratedArtifacts -**/*.DesktopClient/GeneratedArtifacts -**/*.DesktopClient/ModelManifest.xml -**/*.Server/GeneratedArtifacts -**/*.Server/ModelManifest.xml -_Pvt_Extensions - -# Paket dependency manager -.paket/paket.exe -paket-files/ - -# FAKE - F# Make -.fake/ - -# JetBrains Rider -.idea/ -*.sln.iml - -# CodeRush -.cr/ - -# Python Tools for Visual Studio (PTVS) -__pycache__/ -*.pyc -/WellaHealthApiCore/Generated -/WellahealthCore.AzureFunctions diff --git a/BookingService_Old/FlightBooking.Service.Tests/FlightBooking.Service.Tests.csproj b/BookingService_Old/FlightBooking.Service.Tests/FlightBooking.Service.Tests.csproj deleted file mode 100644 index 78b328aefd3a040945634a37f6d84b87e561ed89..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service.Tests/FlightBooking.Service.Tests.csproj +++ /dev/null @@ -1,37 +0,0 @@ -<Project Sdk="Microsoft.NET.Sdk"> - - <PropertyGroup> - <TargetFramework>net8.0</TargetFramework> - <ImplicitUsings>enable</ImplicitUsings> - <Nullable>enable</Nullable> - - <IsPackable>false</IsPackable> - <IsTestProject>true</IsTestProject> - </PropertyGroup> - <PropertyGroup> - <EnableNETAnalyzers>true</EnableNETAnalyzers> - </PropertyGroup> - <ItemGroup> - <PackageReference Include="coverlet.collector" Version="6.0.1"> - <PrivateAssets>all</PrivateAssets> - <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> - </PackageReference> - <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" /> - <PackageReference Include="xunit" Version="2.5.3" /> - <PackageReference Include="xunit.runner.visualstudio" Version="2.5.7"> - <PrivateAssets>all</PrivateAssets> - <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> - </PackageReference> - <PackageReference Include="MockQueryable.Moq" Version="7.0.0" /> - <PackageReference Include="Moq" Version="4.18.4" /> - </ItemGroup> - - <ItemGroup> - <ProjectReference Include="..\FlightBooking.Service\FlightBooking.Service.csproj" /> - </ItemGroup> - - <ItemGroup> - <Using Include="Xunit" /> - </ItemGroup> - -</Project> diff --git a/BookingService_Old/FlightBooking.Service.Tests/UnitTest1.cs b/BookingService_Old/FlightBooking.Service.Tests/UnitTest1.cs deleted file mode 100644 index 127caef0f8fb524181ec652ba30c1324b6b76b60..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service.Tests/UnitTest1.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace FlightBooking.Service.Tests -{ - public class UnitTest1 - { - [Fact] - public void Test1() - { - } - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service.sln b/BookingService_Old/FlightBooking.Service.sln deleted file mode 100644 index 2a079f38ba238be39114cdc4fd397aa41de7549b..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service.sln +++ /dev/null @@ -1,31 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.9.34622.214 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FlightBooking.Service", "FlightBooking.Service\FlightBooking.Service.csproj", "{0043031F-8453-4554-90A8-DA1921F95235}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FlightBooking.Service.Tests", "FlightBooking.Service.Tests\FlightBooking.Service.Tests.csproj", "{C7FCD62C-5D7D-44BB-8A38-821BEBE2BBC9}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {0043031F-8453-4554-90A8-DA1921F95235}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0043031F-8453-4554-90A8-DA1921F95235}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0043031F-8453-4554-90A8-DA1921F95235}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0043031F-8453-4554-90A8-DA1921F95235}.Release|Any CPU.Build.0 = Release|Any CPU - {C7FCD62C-5D7D-44BB-8A38-821BEBE2BBC9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C7FCD62C-5D7D-44BB-8A38-821BEBE2BBC9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C7FCD62C-5D7D-44BB-8A38-821BEBE2BBC9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C7FCD62C-5D7D-44BB-8A38-821BEBE2BBC9}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {1CCB1631-8F04-4C14-AC4D-9CFC54B609B7} - EndGlobalSection -EndGlobal diff --git a/BookingService_Old/FlightBooking.Service/Controllers/BookingsController.cs b/BookingService_Old/FlightBooking.Service/Controllers/BookingsController.cs deleted file mode 100644 index d9d2de405db28a1495766a7dc5b70ede07c602d6..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Controllers/BookingsController.cs +++ /dev/null @@ -1,88 +0,0 @@ -using FlightBooking.Service.Data.DTO; -using FlightBooking.Service.Services; -using FlightBooking.Service.Services.Interfaces; -using Microsoft.AspNetCore.Mvc; -using System.Net.Mime; - -namespace FlightBooking.Service.Controllers -{ - [Route("api/[controller]")] - [ApiController] - public class BookingsController : ControllerBase - { - private readonly IBookingService _bookingService; - private readonly IBookingOrderService _bookingOrderService; - - public BookingsController(IBookingService bookingService, IBookingOrderService bookingOrderService) - { - _bookingService = bookingService; - _bookingOrderService = bookingOrderService; - } - - [HttpGet("bookingNumber/{bookingNumber}")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(BookingDTO))] - [ProducesResponseType(StatusCodes.Status404NotFound, Type = typeof(ProblemDetails))] - [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ProblemDetails))] - public async Task<IActionResult> GetBookingsByBookingNumber([FromRoute] string bookingNumber) - { - ServiceResponse<BookingDTO?> result = await _bookingService.GetBookingByBookingNumberAsync(bookingNumber); - - return result.FormatResponse(); - } - - [HttpGet("email/{email}")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IEnumerable<BookingDTO>))] - [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ProblemDetails))] - public IActionResult GetBookingsByEmail([FromRoute] string email) - { - ServiceResponse<IEnumerable<BookingDTO>?> result = _bookingService.GetBookingsByEmail(email); - - return result.FormatResponse(); - } - - [HttpGet("orderNumber/{orderNumber}")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IEnumerable<BookingDTO>))] - [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ProblemDetails))] - public IActionResult GetBookingsByOrderNumber([FromRoute] string orderNumber) - { - ServiceResponse<IEnumerable<BookingDTO>?> result = _bookingService.GetBookingsByOrderNumber(orderNumber); - - return result.FormatResponse(); - } - - [HttpGet("id/{bookingId}")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(BookingDTO))] - [ProducesResponseType(StatusCodes.Status404NotFound, Type = typeof(ProblemDetails))] - public async Task<IActionResult> GetBookingById([FromRoute] int bookingId) - { - ServiceResponse<BookingDTO?> result = await _bookingService.GetBookingByBookingId(bookingId); - - return result.FormatResponse(); - } - - [HttpPost] - [Consumes(MediaTypeNames.Application.Json)] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(BookingResponseDTO))] - [ProducesResponseType(StatusCodes.Status422UnprocessableEntity, Type = typeof(ProblemDetails))] - [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ProblemDetails))] - [ProducesResponseType(StatusCodes.Status500InternalServerError, Type = typeof(ProblemDetails))] - public async Task<IActionResult> PostBooking([FromBody] BookingOrderDTO bookingOrderDTO) - { - ServiceResponse<BookingResponseDTO?> result = await _bookingOrderService.CreateBookingOrderAsync(bookingOrderDTO); - - return result.FormatResponse(); - } - - [HttpGet("payment/{orderNumber}")] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(BookingResponseDTO))] - [ProducesResponseType(StatusCodes.Status404NotFound, Type = typeof(ProblemDetails))] - [ProducesResponseType(StatusCodes.Status422UnprocessableEntity, Type = typeof(ProblemDetails))] - [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ProblemDetails))] - public async Task<IActionResult> GetBookingPayment([FromRoute] string orderNumber) - { - ServiceResponse<BookingResponseDTO?> result = await _bookingOrderService.GetCheckoutUrlAsync(orderNumber); - - return result.FormatResponse(); - } - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Controllers/SeatsController.cs b/BookingService_Old/FlightBooking.Service/Controllers/SeatsController.cs deleted file mode 100644 index a6ca8bb54ae688f0060fd3551b898dd99b61a8f7..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Controllers/SeatsController.cs +++ /dev/null @@ -1,42 +0,0 @@ -using FlightBooking.Service.Data.DTO; -using FlightBooking.Service.Services; -using FlightBooking.Service.Services.Interfaces; -using Microsoft.AspNetCore.Mvc; -using System.Net.Mime; - -namespace FlightBooking.Service.Controllers -{ - [Route("api/[controller]")] - [ApiController] - public class SeatsController : ControllerBase - { - private readonly IReservedSeatService _service; - - public SeatsController(IReservedSeatService service) - { - _service = service; - } - - [HttpGet] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IEnumerable<ReservedSeatDTO>))] - [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ProblemDetails))] - public IActionResult GetAvailableSeats([FromQuery] string flightNumber) - { - ServiceResponse<IEnumerable<ReservedSeatDTO>> result = _service.GetAvailableSeatsByFlightNumber(flightNumber); - - return result.FormatResponse(); - } - - [HttpPost] - [Consumes(MediaTypeNames.Application.Json)] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status422UnprocessableEntity, Type = typeof(ProblemDetails))] - [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ProblemDetails))] - public async Task<IActionResult> ReserveSeat([FromBody] ReservedSeatRequestDTO requestDTO) - { - ServiceResponse<string> result = await _service.ReserveSeatAsync(requestDTO); - - return result.FormatResponse(); - } - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Controllers/StripeController.cs b/BookingService_Old/FlightBooking.Service/Controllers/StripeController.cs deleted file mode 100644 index 0f9bf55d73401f9e463b38e26b917a523de71957..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Controllers/StripeController.cs +++ /dev/null @@ -1,69 +0,0 @@ -using FlightBooking.Service.Data.Configs; -using FlightBooking.Service.Services; -using FlightBooking.Service.Services.Interfaces; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.Options; -using Stripe; -using System.Text; - -namespace FlightBooking.Service.Controllers -{ - [Route("api/[controller]")] - [ApiController] - public class StripeController : ControllerBase - { - private readonly StripeConfig _stripeConfig; - private readonly IStripeService _stripeService; - private readonly ILogger<StripeController> _logger; - - public StripeController(IOptionsMonitor<StripeConfig> options, IStripeService stripeService, ILogger<StripeController> logger) - { - _stripeConfig = options.CurrentValue; - _stripeService = stripeService; - _logger = logger; - } - - //webhook for stripe to verify payment - [HttpPost] - public async Task<IActionResult> NotificationWebhookAsync() - { - //var json = await new StreamReader(HttpContext.Request.Body).ReadToEndAsync(); - - string requestBody; - using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8)) - { - requestBody = await reader.ReadToEndAsync(); - } - - if (string.IsNullOrEmpty(requestBody)) - { - //_logger.LogInformation("Event object is empty", eventObject); - return BadRequest(); - } - - string stripeSigningKey = _stripeConfig.SigningSecret; - - Event stripeEvent; - - try - { - stripeEvent = EventUtility.ConstructEvent(requestBody, Request.Headers["Stripe-Signature"], stripeSigningKey, throwOnApiVersionMismatch: false); - } - catch (StripeException exception) - { - _logger.LogError(exception.ToString()); - return BadRequest(); - } - - //Since this is the only event we are handling. - if (stripeEvent.Type == Events.CheckoutSessionCompleted) - { - var response = await _stripeService.ProcessPayment(stripeEvent); - - return response.FormatResponse(); - } - - return Ok(); - } - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Data/Configs/ConfigSettings.cs b/BookingService_Old/FlightBooking.Service/Data/Configs/ConfigSettings.cs deleted file mode 100644 index 72ff348b15776926609d4182391c61d8a14306de..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Data/Configs/ConfigSettings.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace FlightBooking.Service.Data.Configs -{ - public class ConfigSettings - { - } - - public class StripeConfig - { - public const string ConfigName = nameof(StripeConfig); - - public string SecretKey { get; set; } = null!; - public string PublicKey { get; set; } = null!; - public string SigningSecret { get; set; } = null!; - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Data/Configs/ConfigSettingsModule.cs b/BookingService_Old/FlightBooking.Service/Data/Configs/ConfigSettingsModule.cs deleted file mode 100644 index 21c0d09183ecca2df9ec48a1bbcb4543c094c946..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Data/Configs/ConfigSettingsModule.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace FlightBooking.Service.Data.Configs -{ - public static class ConfigSettingsModule - { - public static void AddConfigSettings(this IServiceCollection services, IConfiguration configuration) - { - services.Configure<StripeConfig>(configuration.GetSection(StripeConfig.ConfigName)); - } - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Data/Constants.cs b/BookingService_Old/FlightBooking.Service/Data/Constants.cs deleted file mode 100644 index ff8ff81ab5323e78ee37f76423f5dae22528158c..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Data/Constants.cs +++ /dev/null @@ -1,38 +0,0 @@ -namespace FlightBooking.Service.Data -{ - public class Constants - { - } - - internal static class RepositoryConstants - { - public const string LoggingStarted = "Started logging"; - public const string CreateNullError = "Attempt to insert empty entity. Type of Entity : {0}"; - public const string DeleteNullError = "Could not find entity for deleting. type of Entity : {0}"; - public const string BulkDeleteNullError = "Attempt to Delete empty list of entities. Type of Entity : {0}"; - public const string BulkCreateNullError = "Attempt to insert empty list of entities. Type of Entity : {0}"; - public const string EmptySaveInfo = "No changes was written to underlying database."; - public const string UpdateException = "Update Exception"; - public const string UpdateConcurrencyException = "Update Concurrency Exception"; - public const string SaveChangesException = "Generic Error in Generic Repo Update method"; - } - - internal static class ServiceErrorMessages - { - public const string Success = "The operation was successful"; - public const string Failed = "An unhandled errror has occured while processing your request"; - public const string UpdateError = "There was an error carrying out operation"; - public const string MisMatch = "The entity Id does not match the supplied Id"; - public const string EntityIsNull = "Supplied entity is null or supplied list of entities is empty. Check our docs"; - public const string EntityNotFound = "The requested resource was not found. Verify that the supplied Id is correct"; - public const string Incompleted = "Some actions may not have been successfully processed"; - public const string EntityExist = "An entity of the same name or id exists"; - public const string InvalidParam = "A supplied parameter or model is invalid. Check the docs"; - public const string UnprocessableEntity = "The action cannot be processed"; - public const string InternalServerError = "An internal server error and request could not processed"; - public const string OperationFailed = "Operation failed"; - - public const string ParameterEmptyOrNull = "The parameter list is null or empty"; - public const string RequestIdRequired = "Request Id is required"; - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Data/DTO/BookingDTO.cs b/BookingService_Old/FlightBooking.Service/Data/DTO/BookingDTO.cs deleted file mode 100644 index 8a933331d7639d615f0ef640bd9b94834d64f31f..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Data/DTO/BookingDTO.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace FlightBooking.Service.Data.DTO -{ - public class BookingDTO - { - public int Id { get; set; } - public string FirstName { get; set; } = null!; - public string LastName { get; set; } = null!; - public string PhoneNumber { get; set; } = null!; - public string Email { get; set; } = null!; - public string Address { get; set; } = null!; - public DateOnly DateOfBirth { get; set; } - - [EnumDataType(typeof(Gender))] - public Gender Gender { get; set; } - public DateTime CreatedAt { get; set; } - - public string BookingNumber { get; set; } = null!; - public int BookingOrderId { get; set; } - - [EnumDataType(typeof(BookingStatus))] - public BookingStatus BookingStatus { get; set; } = BookingStatus.Pending; - public string? SeatNumber { get; set; } - - public BookingFlightInformationDTO FlightInformation { get; set; } = null!; - public BookingFlightFareDTO FlightFare { get; set; } = null!; - } - - public class BookingRequestDTO - { - [Required] - public string FirstName { get; set; } = null!; - - [Required] - public string LastName { get; set; } = null!; - - public string PhoneNumber { get; set; } = null!; - public string? Email { get; set; } - - [Required] - public string Address { get; set; } = null!; - - [Required] - public DateOnly DateOfBirth { get; set; } - - [EnumDataType(typeof(Gender))] - public Gender Gender { get; set; } = Gender.PreferNotToSay; - - [Required] - [Range(1, int.MaxValue)] - 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; } - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Data/DTO/BookingOrderDTO.cs b/BookingService_Old/FlightBooking.Service/Data/DTO/BookingOrderDTO.cs deleted file mode 100644 index 80a6ee1a7ff81a645f723738e626853c0671e564..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Data/DTO/BookingOrderDTO.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace FlightBooking.Service.Data.DTO -{ - public class BookingOrderDTO - { - [Required] - public string Email { get; set; } = null!; - - [Required] - public string OutboundFlightNumber { get; set; } = null!; - - public string? ReturnFlightNumber { get; set; } - - [Required] - public List<BookingRequestDTO> Bookings { get; set; } = new List<BookingRequestDTO>(); - } - - public class BookingResponseDTO - { - public string OrderNumber { get; set; } = null!; - public string PaymentLink { get; set; } = null!; - public DateTime OrderExpiration { get; set; } = DateTime.UtcNow.AddHours(1); - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Data/DTO/FlightFareDTO.cs b/BookingService_Old/FlightBooking.Service/Data/DTO/FlightFareDTO.cs deleted file mode 100644 index ae7db016b2ccd6973066e39811147794062ad37c..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Data/DTO/FlightFareDTO.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace FlightBooking.Service.Data.DTO -{ - public class FlightFareDTO : BookingFlightFareDTO - { - public int Id { get; set; } - public decimal AvailableSeats { get; set; } - } - - public class BookingFlightFareDTO - { - public string FareCode { get; set; } = null!; - public string FareName { get; set; } = null!; - public decimal Price { get; set; } - public string FlightNumber { get; set; } = null!; - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Data/DTO/FlightInformationDTO.cs b/BookingService_Old/FlightBooking.Service/Data/DTO/FlightInformationDTO.cs deleted file mode 100644 index eb8acdadf51ec0dd635768c710605e9f16f8ee0b..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Data/DTO/FlightInformationDTO.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace FlightBooking.Service.Data.DTO -{ - public class FlightInformationDTO : BookingFlightInformationDTO - { - public int Id { get; set; } - public int SeatCapacity { get; set; } - public int AvailableSeats { get; set; } - } - - public class BookingFlightInformationDTO - { - public string FlightNumber { get; set; } = null!; - public string Origin { get; set; } = null!; - public string Destination { get; set; } = null!; - public DateTime DepartureDate { get; set; } - public DateTime ArrivalDate { get; set; } - public string Airline { get; set; } = null!; - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Data/DTO/ReservedSeatDTO.cs b/BookingService_Old/FlightBooking.Service/Data/DTO/ReservedSeatDTO.cs deleted file mode 100644 index 862b363a860ae893d8d404ac56c5705937bbf60c..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Data/DTO/ReservedSeatDTO.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace FlightBooking.Service.Data.DTO -{ - public class ReservedSeatDTO - { - public string SeatNumber { get; set; } = null!; // e.g 1A, 33B - - public string FlightNumber { get; set; } = null!; - - public bool IsReserved { get; set; } - } - - public class ReservedSeatRequestDTO - { - public string SeatNumber { get; set; } = null!; // e.g 1A, 33B - public string BookingNumber { get; set; } = null!; - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Data/DTO/StripeDataDTO.cs b/BookingService_Old/FlightBooking.Service/Data/DTO/StripeDataDTO.cs deleted file mode 100644 index b6ca8686745e2745b7d8032fbc36c021da592515..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Data/DTO/StripeDataDTO.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace FlightBooking.Service.Data.DTO -{ - public class StripeDataDTO - { - [Required] - public string SuccessUrl { get; set; } = null!; - - [Required] - public string CancelUrl { get; set; } = null!; - - [Required] - public string ProductName { get; set; } = null!; - - [Required] - public string ProductDescription { get; set; } = null!; - - [Required] - [Range(0.5, double.MaxValue)] //minimum of 50 cents - public decimal Amount { get; set; } - - [Required] - public string CustomerEmail { get; set; } = null!; - - [Required] - public string CurrencyCode { get; set; } = "USD"; - - [Required] - public string OrderNumber { get; set; } = null!; - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Data/DatabaseSeeding.cs b/BookingService_Old/FlightBooking.Service/Data/DatabaseSeeding.cs deleted file mode 100644 index bd275966c7d42fd736f41371dbca64fb9141c7e1..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Data/DatabaseSeeding.cs +++ /dev/null @@ -1,158 +0,0 @@ -using FlightBooking.Service.Data.Models; -using Microsoft.EntityFrameworkCore; - -namespace FlightBooking.Service.Data -{ - public static class DatabaseSeeding - { - public static void Initialize(IServiceProvider serviceProvider) - { - using (var context = new FlightBookingContext(serviceProvider.GetRequiredService<DbContextOptions<FlightBookingContext>>())) - { - if (context.FlightInformation.Any()) - { - return; - } - - string flightA = Guid.NewGuid().ToString("N")[..4].ToUpper(); - string flightB = Guid.NewGuid().ToString("N")[..4].ToUpper(); - List<FlightFare> flightFaresA = new List<FlightFare> - { - new FlightFare - { - FareName = "Economy class", - FareCode = "Eco-1", - Price = 4000, - SeatCapacity = 30, - SeatReserved = 0, - CreatedAt = DateTime.UtcNow, - UpdatedAt = DateTime.UtcNow, - }, - new FlightFare - { - FareName = "Business class", - FareCode = "Biz-1", - Price = 4000, - SeatCapacity = 30, - SeatReserved = 0, - CreatedAt = DateTime.UtcNow, - UpdatedAt = DateTime.UtcNow, - }, - }; - - List<FlightFare> flightFaresB = new List<FlightFare> - { - new FlightFare - { - FareName = "Economy class", - FareCode = "Eco-11", - Price = 5000, - SeatCapacity = 20, - SeatReserved = 0, - CreatedAt = DateTime.UtcNow, - UpdatedAt = DateTime.UtcNow, - }, - new FlightFare - { - FareName = "Business class", - FareCode = "Biz-11", - Price = 4000, - SeatCapacity = 10, - SeatReserved = 0, - CreatedAt = DateTime.UtcNow, - UpdatedAt = DateTime.UtcNow, - }, - }; - - //Create available seats - var reservedSeatsA = GenerateSeats(flightA, 60); - var reservedSeatsB = GenerateSeats(flightB, 60); - - List<FlightInformation> flights = new List<FlightInformation> - { - new FlightInformation - { - SeatCapacity = 60, - DepartureDate = DateTime.UtcNow.AddMonths(3), - ArrivalDate = DateTime.UtcNow.AddMonths(3).AddHours(4), - Airline = "Emirates", - SeatReserved = 0, - Destination = "London", - Origin = "Lagos", - FlightNumber = flightA, - CreatedAt = DateTime.UtcNow, - UpdatedAt = DateTime.UtcNow, - FlightFares = flightFaresA, - ReservedSeats = reservedSeatsA, - }, - new FlightInformation - { - SeatCapacity = 40, - DepartureDate = DateTime.UtcNow.AddMonths(3).AddDays(7), - ArrivalDate = DateTime.UtcNow.AddMonths(3).AddDays(7).AddHours(4), - Airline = "Emirates", - SeatReserved = 0, - Destination = "Lagos", - Origin = "London", - FlightNumber = flightB, - CreatedAt = DateTime.UtcNow, - UpdatedAt = DateTime.UtcNow, - FlightFares = flightFaresB, - ReservedSeats = reservedSeatsB - } - }; - - context.FlightInformation.AddRange(flights); - - context.SaveChanges(); - - context.Database.EnsureCreated(); - } - } - - private static List<ReservedSeat> GenerateSeats(string flightNumber, int flightCapacity) - { - //assume seats are in group of 4 Alphabets e.g 1A, 1B, 1C, 1D - - Dictionary<int, string> SeatMaps = new Dictionary<int, string> - { - {1, "A" }, - {2, "B" }, - {3, "C" }, - {4, "D" } - }; - - int seatId = 1; - int seatCount = 1; - - List<string> seatNumbers = new List<string>(); - - for (int i = 1; i < flightCapacity + 1; i++) - { - if (seatCount > 4) - { - seatId++; - seatCount = 1; - } - - seatNumbers.Add(seatId + SeatMaps[seatCount]); - seatCount++; - } - - List<ReservedSeat> reservedSeats = new List<ReservedSeat>(); - - foreach (var seatNumber in seatNumbers) - { - reservedSeats.Add(new ReservedSeat - { - BookingNumber = null, - FlightNumber = flightNumber, - IsReserved = false, - SeatNumber = seatNumber - }); - } - - return reservedSeats; - } - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Data/Enums.cs b/BookingService_Old/FlightBooking.Service/Data/Enums.cs deleted file mode 100644 index 15a8a628fd9ad1691dbfcb8458227115ad77c3bb..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Data/Enums.cs +++ /dev/null @@ -1,40 +0,0 @@ -namespace FlightBooking.Service.Data -{ - public enum Gender - { - Female = 1, - Male, - Transgender, - Fluid, - PreferNotToSay - } - - public enum InternalCode - { - UpdateError = -1, - Failed, - Success, - EntityIsNull, - EntityNotFound, - Mismatch, - InvalidParam, - Incompleted, - ListEmpty, - EntityExist, - Unprocessable, - Unauthorized, - } - - public enum SortOrder - { - ASC = 1, - DESC = 2 - } - - public enum BookingStatus - { - Pending = 1, - Confirmed, - Paid - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Data/FlightBookingContext.cs b/BookingService_Old/FlightBooking.Service/Data/FlightBookingContext.cs deleted file mode 100644 index ecdf63e93b35d7da98e11fa731bd2c0f5dd3b30e..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Data/FlightBookingContext.cs +++ /dev/null @@ -1,70 +0,0 @@ -using FlightBooking.Service.Data.ModelConfigurations; -using FlightBooking.Service.Data.Models; -using Microsoft.EntityFrameworkCore; - -namespace FlightBooking.Service.Data -{ - public class FlightBookingContext : DbContext - { - public FlightBookingContext(DbContextOptions<FlightBookingContext> options) : base(options) - { - } - - public DbSet<Booking> Bookings { get; set; } - public DbSet<BookingOrder> BookingOrders { get; set; } - public DbSet<ReservedSeat> ReservedSeats { get; set; } - public DbSet<Payment> Payments { get; set; } - public DbSet<FlightFare> FlightFares { get; set; } - public DbSet<FlightInformation> FlightInformation { get; set; } - - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - base.OnModelCreating(modelBuilder); - - //configure each model - - modelBuilder.ApplyConfiguration(new FlightInformationConfiguration()); - modelBuilder.ApplyConfiguration(new FlightFareConfiguration()); - modelBuilder.ApplyConfiguration(new BookingConfiguration()); - modelBuilder.ApplyConfiguration(new BookingOrderConfiguration()); - modelBuilder.ApplyConfiguration(new PaymentConfiguration()); - modelBuilder.ApplyConfiguration(new ReservedSeatConfiguration()); - - ////Ensure all dates are saved as UTC and read as UTC: - ////https://github.com/dotnet/efcore/issues/4711#issuecomment-481215673 - - foreach (var entityType in modelBuilder.Model.GetEntityTypes()) - { - foreach (var property in entityType.GetProperties()) - { - if (property.ClrType == typeof(DateTime)) - { - modelBuilder.Entity(entityType.ClrType) - .Property<DateTime>(property.Name) - .HasConversion( - v => v.ToUniversalTime(), - v => DateTime.SpecifyKind(v, DateTimeKind.Utc)); - } - else if (property.ClrType == typeof(DateTime?)) - { - modelBuilder.Entity(entityType.ClrType) - .Property<DateTime?>(property.Name) - .HasConversion( - v => v.HasValue ? v.Value.ToUniversalTime() : v, - v => v.HasValue ? DateTime.SpecifyKind(v.Value, DateTimeKind.Utc) : v); - } - } - } - } - - public override Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default) - { - return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken); - } - - //protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - //{ - // base.OnConfiguring(optionsBuilder); - //} - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Data/ModelConfigurations/BookingConfiguration.cs b/BookingService_Old/FlightBooking.Service/Data/ModelConfigurations/BookingConfiguration.cs deleted file mode 100644 index a07fc63af5f3f747088ab8dcab01455d6882bd23..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Data/ModelConfigurations/BookingConfiguration.cs +++ /dev/null @@ -1,27 +0,0 @@ -using FlightBooking.Service.Data.Models; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; - -namespace FlightBooking.Service.Data.ModelConfigurations -{ - public class BookingConfiguration : IEntityTypeConfiguration<Booking> - { - public void Configure(EntityTypeBuilder<Booking> entity) - { - entity.HasOne(d => d.BookingOrder).WithMany(p => p.Bookings) - .HasPrincipalKey(p => p.Id) - .HasForeignKey(d => d.BookingOrderId) - .OnDelete(DeleteBehavior.ClientSetNull); - - entity.HasOne(d => d.FlightInformation).WithMany(p => p.Bookings) - .HasPrincipalKey(p => p.Id) - .HasForeignKey(d => d.FlightId) - .OnDelete(DeleteBehavior.ClientSetNull); - - entity.HasOne(d => d.FlightFare).WithMany(p => p.Bookings) - .HasPrincipalKey(p => p.Id) - .HasForeignKey(d => d.FlightFareId) - .OnDelete(DeleteBehavior.ClientSetNull); - } - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Data/ModelConfigurations/BookingOrderConfiguration.cs b/BookingService_Old/FlightBooking.Service/Data/ModelConfigurations/BookingOrderConfiguration.cs deleted file mode 100644 index 7ab617095a05ea7f4491ad106f8a7f7c0c6a7561..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Data/ModelConfigurations/BookingOrderConfiguration.cs +++ /dev/null @@ -1,13 +0,0 @@ -using FlightBooking.Service.Data.Models; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; - -namespace FlightBooking.Service.Data.ModelConfigurations -{ - public class BookingOrderConfiguration : IEntityTypeConfiguration<BookingOrder> - { - public void Configure(EntityTypeBuilder<BookingOrder> entity) - { - } - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Data/ModelConfigurations/FlightFareConfiguration.cs b/BookingService_Old/FlightBooking.Service/Data/ModelConfigurations/FlightFareConfiguration.cs deleted file mode 100644 index 298a02f84eab1e9ee44e9e5d2e268bc1a6937cad..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Data/ModelConfigurations/FlightFareConfiguration.cs +++ /dev/null @@ -1,17 +0,0 @@ -using FlightBooking.Service.Data.Models; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; - -namespace FlightBooking.Service.Data.ModelConfigurations -{ - public class FlightFareConfiguration : IEntityTypeConfiguration<FlightFare> - { - public void Configure(EntityTypeBuilder<FlightFare> entity) - { - entity.HasOne(d => d.FlightInformation).WithMany(p => p.FlightFares) - .HasPrincipalKey(p => p.Id) - .HasForeignKey(d => d.FlightInformationId) - .OnDelete(DeleteBehavior.ClientSetNull); - } - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Data/ModelConfigurations/FlightInformationConfiguration.cs b/BookingService_Old/FlightBooking.Service/Data/ModelConfigurations/FlightInformationConfiguration.cs deleted file mode 100644 index 2af41e5de7a079bb7886b7420c5da5ab10cf2191..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Data/ModelConfigurations/FlightInformationConfiguration.cs +++ /dev/null @@ -1,13 +0,0 @@ -using FlightBooking.Service.Data.Models; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; - -namespace FlightBooking.Service.Data.ModelConfigurations -{ - public class FlightInformationConfiguration : IEntityTypeConfiguration<FlightInformation> - { - public void Configure(EntityTypeBuilder<FlightInformation> entity) - { - } - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Data/ModelConfigurations/PaymentConfiguration.cs b/BookingService_Old/FlightBooking.Service/Data/ModelConfigurations/PaymentConfiguration.cs deleted file mode 100644 index 5b132341148c5b31b01a7af5c3de867190d9cf1d..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Data/ModelConfigurations/PaymentConfiguration.cs +++ /dev/null @@ -1,17 +0,0 @@ -using FlightBooking.Service.Data.Models; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; - -namespace FlightBooking.Service.Data.ModelConfigurations -{ - public class PaymentConfiguration : IEntityTypeConfiguration<Payment> - { - public void Configure(EntityTypeBuilder<Payment> entity) - { - entity.HasOne(d => d.BookingOrder).WithMany(p => p.Payments) - .HasPrincipalKey(p => p.Id) - .HasForeignKey(d => d.BookingOrderId) - .OnDelete(DeleteBehavior.ClientSetNull); - } - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Data/ModelConfigurations/ReservedSeatConfiguration.cs b/BookingService_Old/FlightBooking.Service/Data/ModelConfigurations/ReservedSeatConfiguration.cs deleted file mode 100644 index 9ca62f100a2cda976b82863a2f25f9613decb55b..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Data/ModelConfigurations/ReservedSeatConfiguration.cs +++ /dev/null @@ -1,17 +0,0 @@ -using FlightBooking.Service.Data.Models; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; - -namespace FlightBooking.Service.Data.ModelConfigurations -{ - public class ReservedSeatConfiguration : IEntityTypeConfiguration<ReservedSeat> - { - public void Configure(EntityTypeBuilder<ReservedSeat> entity) - { - entity.HasOne(d => d.FlightInformation).WithMany(p => p.ReservedSeats) - .HasPrincipalKey(p => p.Id) - .HasForeignKey(d => d.FlightInformationId) - .OnDelete(DeleteBehavior.ClientSetNull); - } - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Data/Models/Booking.cs b/BookingService_Old/FlightBooking.Service/Data/Models/Booking.cs deleted file mode 100644 index 315ea18be1d8aa0cb1aaef39de96b04e88f00bad..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Data/Models/Booking.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace FlightBooking.Service.Data.Models -{ - public class Booking - { - [Key] - public int Id { get; set; } - - public string FirstName { get; set; } = null!; - public string LastName { get; set; } = null!; - public string PhoneNumber { get; set; } = null!; - public string? Email { get; set; } - public string Address { get; set; } = null!; - public DateOnly? DateOfBirth { get; set; } - public Gender Gender { get; set; } - - public string BookingNumber { get; set; } = null!; - public int BookingOrderId { get; set; } - - public BookingStatus BookingStatus { get; set; } = BookingStatus.Pending; - - public int FlightId { get; set; } - public int FlightFareId { get; set; } - public DateTime CreatedAt { get; set; } = DateTime.UtcNow; - public DateTime UpdatedAt { get; set; } = DateTime.UtcNow; - - public virtual FlightInformation FlightInformation { get; set; } = null!; - public virtual FlightFare FlightFare { get; set; } = null!; - public virtual BookingOrder BookingOrder { get; set; } = null!; - - //one to one to for seats. one booking at most one seat - - public ReservedSeat? ReservedSeat { get; set; } - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Data/Models/BookingOrder.cs b/BookingService_Old/FlightBooking.Service/Data/Models/BookingOrder.cs deleted file mode 100644 index 5dce348a6e7708e951022eef22cb60aa4271252f..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Data/Models/BookingOrder.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using System.ComponentModel.DataAnnotations; - -namespace FlightBooking.Service.Data.Models -{ - public class BookingOrder - { - [Key] - public int Id { get; set; } - - public string OrderNumber { get; set; } = null!; - public string Email { get; set; } = null!; - - [Precision(19, 4)] - public decimal TotalAmount { get; set; } - - public BookingStatus OrderStatus { get; set; } = BookingStatus.Pending; - public int NumberOfAdults { get; set; } - public int NumberOfChildren { get; set; } - public DateTime CreatedAt { get; set; } = DateTime.UtcNow; - public DateTime UpdatedAt { get; set; } = DateTime.UtcNow; - - public ICollection<Booking> Bookings { get; set; } = new List<Booking>(); - public ICollection<Payment> Payments { get; set; } = new List<Payment>(); - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Data/Models/FlightFare.cs b/BookingService_Old/FlightBooking.Service/Data/Models/FlightFare.cs deleted file mode 100644 index 9dfca35a6849135bcd65a5bbf3de96113dafabdd..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Data/Models/FlightFare.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using System.ComponentModel.DataAnnotations; - -namespace FlightBooking.Service.Data.Models -{ - public class FlightFare - { - [Key] - public int Id { get; set; } - - public int FlightInformationId { get; set; } - public string FareCode { get; set; } = null!; - public string FareName { get; set; } = null!; - - [Precision(19, 4)] - public decimal Price { get; set; } - - public int SeatCapacity { get; set; } - public int SeatReserved { get; set; } - - public DateTime CreatedAt { get; set; } = DateTime.UtcNow; - public DateTime UpdatedAt { get; set; } = DateTime.UtcNow; - - public ICollection<Booking> Bookings { get; set; } = new List<Booking>(); - - public virtual FlightInformation FlightInformation { get; set; } = null!; - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Data/Models/FlightInformation.cs b/BookingService_Old/FlightBooking.Service/Data/Models/FlightInformation.cs deleted file mode 100644 index ed01d2e26d2731ca4fdc3a13d133e367ca8b6195..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Data/Models/FlightInformation.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace FlightBooking.Service.Data.Models -{ - public class FlightInformation - { - [Key] - public int Id { get; set; } - - public string FlightNumber { get; set; } = null!; - public string Origin { get; set; } = null!; - public string Destination { get; set; } = null!; - public DateTime DepartureDate { get; set; } - public DateTime ArrivalDate { get; set; } - public string Airline { get; set; } = null!; - public int SeatCapacity { get; set; } - public int SeatReserved { get; set; } - public DateTime CreatedAt { get; set; } = DateTime.UtcNow; - public DateTime UpdatedAt { get; set; } = DateTime.UtcNow; - - public ICollection<Booking> Bookings { get; set; } = new List<Booking>(); - public ICollection<FlightFare> FlightFares { get; set; } = new List<FlightFare>(); - public ICollection<ReservedSeat> ReservedSeats { get; set; } = new List<ReservedSeat>(); - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Data/Models/PassengerInformation.cs b/BookingService_Old/FlightBooking.Service/Data/Models/PassengerInformation.cs deleted file mode 100644 index 1bcb85141c988c21a69145b38e6d33ad832dd484..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Data/Models/PassengerInformation.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace FlightBooking.Service.Data.Models -{ - public class PassengerInformation - { - [Key] - public int Id { get; set; } - - public string FirstName { get; set; } = null!; - public string LastName { get; set; } = null!; - public string? PhoneNumber { get; set; } - public string? Email { get; set; } - public string Address { get; set; } = null!; - public DateOnly DateOfBirth { get; set; } - public Gender Gender { get; set; } - public DateTime CreatedAt { get; set; } = DateTime.UtcNow; - public DateTime UpdatedAt { get; set; } = DateTime.UtcNow; - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Data/Models/Payment.cs b/BookingService_Old/FlightBooking.Service/Data/Models/Payment.cs deleted file mode 100644 index 4e9e2cb9ed35370da2d3e7683b309bdd244ef1a1..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Data/Models/Payment.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using System.ComponentModel.DataAnnotations; - -namespace FlightBooking.Service.Data.Models -{ - public class Payment - { - [Key] - public int Id { get; set; } - - public string CustomerEmail { get; set; } = null!; - - [Precision(19, 4)] - public decimal TransactionAmount { get; set; } - - public string PaymentReference { get; set; } = null!; - public string OrderNumber { get; set; } = null!; - public string CurrencyCode { get; set; } = null!; - public string PaymentChannel { get; set; } = null!; - public string PaymentStatus { get; set; } = null!; - public int BookingOrderId { get; set; } - public DateTime TransactionDate { get; set; } - public string? MetaData { get; set; } - - public DateTime CreatedAt { get; set; } = DateTime.UtcNow; - public DateTime UpdatedAt { get; set; } = DateTime.UtcNow; - - public virtual BookingOrder BookingOrder { get; set; } = null!; - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Data/Models/ReservedSeat.cs b/BookingService_Old/FlightBooking.Service/Data/Models/ReservedSeat.cs deleted file mode 100644 index 6f6fb691507908b491412220cbe86c2cac5aef29..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Data/Models/ReservedSeat.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace FlightBooking.Service.Data.Models -{ - public class ReservedSeat - { - [Key] - public int Id { get; set; } - - public string SeatNumber { get; set; } = null!; // e.g 1A, 33B - public string? BookingNumber { get; set; } - public int? BookingId { get; set; } //FK to Booking - public string FlightNumber { get; set; } = null!; - public int FlightInformationId { get; set; } - public bool IsReserved { get; set; } = false; - public DateTime CreatedAt { get; set; } = DateTime.UtcNow; - public DateTime UpdatedAt { get; set; } = DateTime.UtcNow; - - public virtual FlightInformation FlightInformation { get; set; } = null!; - public virtual Booking? Booking { get; set; } - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Data/Repository/GenericRepository.cs b/BookingService_Old/FlightBooking.Service/Data/Repository/GenericRepository.cs deleted file mode 100644 index 584354a1e8df7d1628f6876bddb32e78b5a232cc..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Data/Repository/GenericRepository.cs +++ /dev/null @@ -1,257 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using System.Linq.Expressions; - -namespace FlightBooking.Service.Data.Repository -{ - public class GenericRepository<T> : IGenericRepository<T> where T : class, new() - { - //Responses: failed=0, success=1 - - //IEnumerable iterates over an in-memory collection while IQueryable does so on the DB - // call to .ToList to enable instant query against DB - - protected FlightBookingContext _db; - protected ILogger _logger; - - public GenericRepository(FlightBookingContext db, ILogger<GenericRepository<T>> logger) - { - _logger = logger; - _db = db; - } - - public IQueryable<T> GetAll() - { - return _db.Set<T>(); - } - - public DbSet<T> GetDbSet() - { - return _db.Set<T>(); - } - - public IQueryable<T> Query() - { - return _db.Set<T>().AsQueryable(); - } - - #region Async Methods - - public async Task<T?> GetByIdAsync(int id) - { - var entity = await _db.Set<T>().FindAsync(id); - - return entity; - } - - public async Task<T?> GetByGuidAsync(Guid id) - { - var entity = await _db.Set<T>().FindAsync(id); - - return entity; - } - - public async Task<int> CreateAsync(T entity, bool isSave = true) - { - if (entity == null) - { - _logger.LogError(RepositoryConstants.CreateNullError, typeof(T).Name); - return (int)InternalCode.EntityIsNull; - } - - _db.Set<T>().Add(entity); - - if (isSave) - { - return await SaveChangesToDbAsync(); - } - - return (int)InternalCode.Success; - } - - public async Task<int> UpdateAsync(T entity, bool isSave = true) - { - //Check for this in each overriding implementation or services - //var prev = await GetById(id); - - //if (prev == null) - //{ - // return 0; - //} - - _db.Set<T>().Update(entity); - - if (isSave) - { - return await SaveChangesToDbAsync(); - } - - return (int)InternalCode.Success; - } - - public async Task<int> DeleteAsync(int id, bool isSave = true) - { - T? entity = await GetByIdAsync(id); - - if (entity == null) - { - _logger.LogError(RepositoryConstants.DeleteNullError, typeof(T).Name); - return (int)InternalCode.EntityNotFound; - } - - _db.Set<T>().Remove(entity); - - if (isSave) - { - return await SaveChangesToDbAsync(); - } - - return (int)InternalCode.Success; - } - - public async Task<int> BulkDeleteAsync(IEnumerable<int> entityId, bool isSave = true) - { - if (entityId == null || !entityId.Any()) - { - _logger.LogError(RepositoryConstants.BulkDeleteNullError, typeof(T).Name); - return (int)InternalCode.EntityIsNull; - } - - DbSet<T> table = _db.Set<T>(); - - foreach (int id in entityId) - { - T? entity = await GetByIdAsync(id); - if (entity != null) - { - table.Remove(entity); - } - } - - if (isSave) - { - return await SaveChangesToDbAsync(); - } - - return (int)InternalCode.Success; - } - - public async Task<int> BulkCreateAsync(IEnumerable<T> entities, bool isSave = true) - { - if (entities == null || !entities.Any()) - { - _logger.LogError(RepositoryConstants.BulkCreateNullError, typeof(T).Name); - return (int)InternalCode.EntityIsNull; - } - - DbSet<T> table = _db.Set<T>(); - - table.AddRange(entities); - - if (isSave) - { - return await SaveChangesToDbAsync(); - } - - return (int)InternalCode.Success; - } - - //calling this once works since we are using just one DbContext - //TODO: returning 0 should not lead to 500 error. 0 means no entries were added which may be because all entries have been added already - //fix this after tests have been writing for projects - public async Task<int> SaveChangesToDbAsync() - { - _logger.LogInformation(RepositoryConstants.LoggingStarted); - int saveResult; - - try - { - int tempResult = await _db.SaveChangesAsync(); //give numbers of entries updated in db. in some cases e.g Update, when no data changes, this method returns 0 - if (tempResult == 0) - { - _logger.LogInformation(RepositoryConstants.EmptySaveInfo); - } - saveResult = (int)InternalCode.Success; //means atleast one entry was made. 1 is InternalCode.Success. - //saveResult = tempResult > 0 ? 1 : 0; //means atleast one entry was made. 1 is InternalCode.Success - } - catch (DbUpdateConcurrencyException ex) - { - _logger.LogError(ex, RepositoryConstants.UpdateConcurrencyException); - saveResult = (int)InternalCode.UpdateError; - throw; - } - catch (DbUpdateException ex) - { - _logger.LogError(ex, RepositoryConstants.UpdateException); - saveResult = (int)InternalCode.UpdateError; - throw; - } - catch (Exception ex) - { - _logger.LogError(ex, RepositoryConstants.SaveChangesException); - saveResult = (int)InternalCode.UpdateError; - throw; - } - return saveResult; - } - - public async Task<bool> EntityExistsAsync(int id) - { - T? entityFound = await _db.Set<T>().FindAsync(id); - if (entityFound == null) - { - return false; - } - - return true; - } - - #endregion Async Methods - - public IQueryable<T> OrderByText(IQueryable<T> data, SortOrder order, Expression<Func<T, string>> expression) - { - IQueryable<T> orderedData; - if (order == SortOrder.ASC) - { - orderedData = data.OrderBy(expression); - } - else - { - orderedData = data.OrderByDescending(expression); - } - - return orderedData; - } - - public IQueryable<T> OrderByDate(IQueryable<T> data, SortOrder order, Expression<Func<T, DateTime>> expression) - { - IQueryable<T> orderedData; - if (order == SortOrder.ASC) - { - orderedData = data.OrderBy(expression); - } - else - { - orderedData = data.OrderByDescending(expression); - } - - return orderedData; - } - - public async Task<List<T>> TakeAndSkipAsync(IQueryable<T> data, int pageSize, int pageIndex) - { - //List<T> paginatedList = new List<T>(); - - //if (data == null || data.Count() <= 0) - // return paginatedList; - - //if (pageSize == 0 && pageIndex == 0) - // return paginatedList; - - int numRowSkipped = pageSize * (pageIndex - 1); - - List<T> paginated = await data.Skip(numRowSkipped).Take(pageSize).ToListAsync(); - - return paginated; - } - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Data/Repository/IGenericRepository.cs b/BookingService_Old/FlightBooking.Service/Data/Repository/IGenericRepository.cs deleted file mode 100644 index 74e90c859cd23a16a7eac64dbe93a2ab7f8a32a5..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Data/Repository/IGenericRepository.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using System.Linq.Expressions; - -namespace FlightBooking.Service.Data.Repository -{ - public interface IGenericRepository<T> where T : class - { - Task<int> BulkCreateAsync(IEnumerable<T> entities, bool isSave = true); - - Task<int> BulkDeleteAsync(IEnumerable<int> ids, bool isSave = true); - - Task<int> CreateAsync(T entity, bool isSave = true); - - Task<int> DeleteAsync(int id, bool isSave = true); - - Task<bool> EntityExistsAsync(int id); - - Task<T?> GetByIdAsync(int id); - - Task<T?> GetByGuidAsync(Guid id); - - Task<int> UpdateAsync(T entity, bool isSave = true); - - Task<int> SaveChangesToDbAsync(); - - DbSet<T> GetDbSet(); - - IQueryable<T> Query(); - - Task<List<T>> TakeAndSkipAsync(IQueryable<T> data, int pageSize, int pageIndex); - - IQueryable<T> OrderByText(IQueryable<T> data, SortOrder order, Expression<Func<T, string>> expression); - - IQueryable<T> OrderByDate(IQueryable<T> data, SortOrder order, Expression<Func<T, DateTime>> expression); - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Data/Repository/RepositoryModule.cs b/BookingService_Old/FlightBooking.Service/Data/Repository/RepositoryModule.cs deleted file mode 100644 index 90b6c0ecd46573181b22b6c0812453513fd89104..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Data/Repository/RepositoryModule.cs +++ /dev/null @@ -1,17 +0,0 @@ -using FlightBooking.Service.Data.Models; - -namespace FlightBooking.Service.Data.Repository -{ - public static class RepositoryModule - { - public static void AddRepository(this IServiceCollection services) - { - services.AddScoped<IGenericRepository<Booking>, GenericRepository<Booking>>(); - services.AddScoped<IGenericRepository<FlightInformation>, GenericRepository<FlightInformation>>(); - services.AddScoped<IGenericRepository<FlightFare>, GenericRepository<FlightFare>>(); - services.AddScoped<IGenericRepository<Payment>, GenericRepository<Payment>>(); - services.AddScoped<IGenericRepository<BookingOrder>, GenericRepository<BookingOrder>>(); - services.AddScoped<IGenericRepository<ReservedSeat>, GenericRepository<ReservedSeat>>(); - } - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/FlightBooking.Service.csproj b/BookingService_Old/FlightBooking.Service/FlightBooking.Service.csproj deleted file mode 100644 index 217d79c9aa3c8e30a20af8912fb29b1e0b9be963..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/FlightBooking.Service.csproj +++ /dev/null @@ -1,45 +0,0 @@ -<Project Sdk="Microsoft.NET.Sdk.Web"> - - <PropertyGroup> - <TargetFramework>net8.0</TargetFramework> - <Nullable>enable</Nullable> - <ImplicitUsings>enable</ImplicitUsings> - </PropertyGroup> - <PropertyGroup> - <EnableNETAnalyzers>true</EnableNETAnalyzers> - <UserSecretsId>b1b4ccfd-9fcb-4702-b4e5-c4e88d0bc805</UserSecretsId> - </PropertyGroup> - - <ItemGroup> - <PackageReference Include="AutoMapper" Version="13.0.1" /> - <PackageReference Include="Azure.Identity" Version="1.10.4" /> - <PackageReference Include="libphonenumber-csharp" Version="8.13.30" /> - <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.2" /> - <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.2" /> - <PackageReference Include="Microsoft.Data.SqlClient" Version="5.1.5" /> - <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.2"> - <PrivateAssets>all</PrivateAssets> - <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> - </PackageReference> - <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.2"> - <PrivateAssets>all</PrivateAssets> - <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> - </PackageReference> - <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="8.0.1" /> - <PackageReference Include="MySqlConnector" Version="2.3.5" /> - <PackageReference Include="NLog.Web.AspNetCore" Version="5.3.8" /> - <PackageReference Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="7.3.1" /> - - <PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.2" /> - <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.2" /> - <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" /> - <PackageReference Include="Microsoft.IdentityModel.JsonWebTokens" Version="7.3.1" /> - <PackageReference Include="NuGet.Common" Version="6.9.1" /> - <PackageReference Include="NuGet.Protocol" Version="6.9.1" /> - <PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="8.0.1" /> - <PackageReference Include="Stripe.net" Version="43.18.0" /> - <PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" /> - <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.3.1" /> - </ItemGroup> - -</Project> diff --git a/BookingService_Old/FlightBooking.Service/FlightBooking.Service.http b/BookingService_Old/FlightBooking.Service/FlightBooking.Service.http deleted file mode 100644 index 045f70b4b3efb3716860cf654699c759ef728cdf..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/FlightBooking.Service.http +++ /dev/null @@ -1,6 +0,0 @@ -@FlightBooking.Service_HostAddress = http://localhost:5000 - -GET {{FlightBooking.Service_HostAddress}}/weatherforecast/ -Accept: application/json - -### diff --git a/BookingService_Old/FlightBooking.Service/Middleware/ErrorHandlingMiddleware.cs b/BookingService_Old/FlightBooking.Service/Middleware/ErrorHandlingMiddleware.cs deleted file mode 100644 index 1510d26e45fde58df949f75a8f5965a902d00227..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Middleware/ErrorHandlingMiddleware.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace FlightBooking.Service.Middleware -{ - public class ErrorHandlingMiddleware - { - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Middleware/MiddlewareExtensions.cs b/BookingService_Old/FlightBooking.Service/Middleware/MiddlewareExtensions.cs deleted file mode 100644 index 6b50b9388e8b0af3068a7c4f71b69ee86a4d7476..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Middleware/MiddlewareExtensions.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace FlightBooking.Service.Middleware -{ - public static class MiddlewareExtensions - { - public static IApplicationBuilder UseErrorHandlingMiddleware(this IApplicationBuilder builder) - { - return builder.UseMiddleware<ErrorHandlingMiddleware>(); - } - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Program.cs b/BookingService_Old/FlightBooking.Service/Program.cs deleted file mode 100644 index 041f1b1795fe3de8b53c6693047c19e475694640..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Program.cs +++ /dev/null @@ -1,63 +0,0 @@ -using FlightBooking.Service.Data; -using NLog; -using NLog.Web; - -namespace FlightBooking.Service -{ - public class Program - { - public static void Main(string[] args) - { - var logger = LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger(); - - try - { - logger.Debug("init main"); - - var host = CreateHostBuilder(args).Build(); - - using (var scope = host.Services.CreateScope()) - { - var services = scope.ServiceProvider; - - try - { - DatabaseSeeding.Initialize(services); - } - catch (Exception ex) - { - logger.Error(ex, "An error occurred seeding the DB."); - } - } - - host.Run(); - } - catch (Exception exception) - { - //NLog: catch setup errors - logger.Error(exception, "Stopped program because of exception"); - throw; - } - finally - { - // Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux) - LogManager.Shutdown(); - } - } - - public static IHostBuilder CreateHostBuilder(string[] args) - { - return Host.CreateDefaultBuilder(args) - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.UseStartup<Startup>(); - }) - .ConfigureLogging(logging => - { - logging.ClearProviders(); - logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Information); - }) - .UseNLog(); // NLog: Setup NLog for Dependency injection - } - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Properties/launchSettings.json b/BookingService_Old/FlightBooking.Service/Properties/launchSettings.json deleted file mode 100644 index 434256cccf1cee91e2a84219b2a8a1e813d4c7cd..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Properties/launchSettings.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "$schema": "http://json.schemastore.org/launchsettings.json", - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:37680", - "sslPort": 44321 - } - }, - "profiles": { - "http": { - "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": true, - "launchUrl": "swagger", - "applicationUrl": "http://localhost:5000", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "https": { - "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": true, - "launchUrl": "swagger", - "applicationUrl": "https://localhost:7287;http://localhost:5000", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "launchUrl": "swagger", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Services/BookingOrderService.cs b/BookingService_Old/FlightBooking.Service/Services/BookingOrderService.cs deleted file mode 100644 index f1d70bd5a6829dd9eceaaa29886018ca598128ca..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Services/BookingOrderService.cs +++ /dev/null @@ -1,391 +0,0 @@ -using FlightBooking.Service.Data; -using FlightBooking.Service.Data.DTO; -using FlightBooking.Service.Data.Models; -using FlightBooking.Service.Data.Repository; -using FlightBooking.Service.Services.Interfaces; -using Microsoft.EntityFrameworkCore; - -namespace FlightBooking.Service.Services -{ - ///<inheritdoc /> - public class BookingOrderService : IBookingOrderService - { - private readonly IGenericRepository<BookingOrder> _orderRepo; - private readonly IGenericRepository<FlightInformation> _flightRepo; - private readonly IGenericRepository<FlightFare> _flightFareRepo; - private readonly IStripeService _stripeService; - - 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) - { - _orderRepo = orderRepo; - _flightRepo = flightRepo; - _flightFareRepo = flightFareRepo; - _stripeService = stripeService; - _logger = logger; - } - - public async Task<ServiceResponse<BookingResponseDTO?>> CreateBookingOrderAsync(BookingOrderDTO order) - { - if (order == null) - { - return new ServiceResponse<BookingResponseDTO?>(null, InternalCode.InvalidParam); - } - - /* - Checks: - - outbound and return flights cannot be same - - Check if all the flights are available - - Check if the fares have available seats - - If Checks are not passed, return 422 - */ - - bool hasReturnFlight = !string.IsNullOrWhiteSpace(order.ReturnFlightNumber); - - //Outbound and Return flights cannot be the same - if (hasReturnFlight && order.ReturnFlightNumber == order.OutboundFlightNumber) - { - return new ServiceResponse<BookingResponseDTO?>(null, InternalCode.Unprocessable, "Outbound and return flights cannot be the same"); - } - - int totalFlights = order.Bookings.Count; - - FlightInformation outboundFlightInfo = new FlightInformation(); - FlightInformation returnFlightInfo = new FlightInformation(); - - //Check if the outbound flight is valid and if seats are available - var outboundFlight = CheckAvailableFlight(order.OutboundFlightNumber, totalFlights); - - //If flight not valid, return false - if (outboundFlight.FlightInformation == null) - { - return new ServiceResponse<BookingResponseDTO?>(null, InternalCode.Unprocessable, "The selected flight is not valid"); - } - - //if it's booked to Max, return error - if (outboundFlight.IsBookedToMax) - { - return new ServiceResponse<BookingResponseDTO?>(null, InternalCode.Unprocessable, "The number of flights exceed number of available seats"); - } - - outboundFlightInfo = outboundFlight.FlightInformation; - - //Check if Return flight available and not booked to max - - if (hasReturnFlight) - { - //If none of the Booking - - var returnFlight = CheckAvailableFlight(order.ReturnFlightNumber!, totalFlights); - - if (returnFlight.FlightInformation == null) - { - return new ServiceResponse<BookingResponseDTO?>(null, InternalCode.Unprocessable, "The selected flight is not valid"); - } - - if (returnFlight.IsBookedToMax) - { - return new ServiceResponse<BookingResponseDTO?>(null, InternalCode.Unprocessable, "The number of flights exceed number of available seats"); - } - - returnFlightInfo = returnFlight.FlightInformation; - } - - //Check if the selected Fares for each flight is valid and seats are available - var (IsAllFareExists, IsAnyFareMaxedOut, FareCodes) = CheckIfAnyFareIsMaxedOut(order, hasReturnFlight); - - if (!IsAllFareExists) - { - return new ServiceResponse<BookingResponseDTO?>(null, InternalCode.Unprocessable, "Some selected fare do not exist. Please check that all fare exists"); - } - - if (IsAnyFareMaxedOut) - { - return new ServiceResponse<BookingResponseDTO?>(null, InternalCode.Unprocessable, "The number of flights exceed 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 - //We hold a seat for N mins max(N is set in config). Use a background job to return UnbookedSeats back into the Pool - - await UpdateAvailableSeats(order, FareCodes); - - string orderReference = Guid.NewGuid().ToString("N")[..10].ToUpper(); - - //Create all the bookings - List<Booking> bookings = new List<Booking>(); - - decimal totalAmount = 0; - foreach (var booking in order.Bookings) - { - //TODO: Use AutoMapper - bookings.Add(new Booking - { - FirstName = booking.FirstName, - LastName = booking.LastName, - PhoneNumber = booking.PhoneNumber, - Email = booking.Email, - DateOfBirth = booking.DateOfBirth, - Address = booking.Address, - Gender = booking.Gender, - BookingNumber = Guid.NewGuid().ToString("N")[..10].ToUpper(), - BookingStatus = BookingStatus.Confirmed, - FlightId = outboundFlightInfo.Id, - FlightFareId = booking.OutboundFareId, - CreatedAt = DateTime.UtcNow - }); - - totalAmount += allFlightFares.FirstOrDefault(x => x.Id == booking.OutboundFareId)!.Price; - - //If return flight, add a seperate booking - if (hasReturnFlight) - { - bookings.Add(new Booking - { - FirstName = booking.FirstName, - LastName = booking.LastName, - PhoneNumber = booking.PhoneNumber, - Email = booking.Email, - DateOfBirth = booking.DateOfBirth, - Address = booking.Address, - Gender = booking.Gender, - BookingNumber = Guid.NewGuid().ToString("N")[..10].ToUpper(), - BookingStatus = BookingStatus.Confirmed, - FlightId = returnFlightInfo.Id, - FlightFareId = (int)booking.ReturnFareId!, - CreatedAt = DateTime.UtcNow - }); - - totalAmount += allFlightFares.FirstOrDefault(x => x.Id == booking.ReturnFareId)!.Price; - } - } - - //Sum all cost as part of Order - - BookingOrder bookingOrder = new BookingOrder - { - Bookings = bookings, - Email = order.Email, - OrderStatus = BookingStatus.Confirmed, - TotalAmount = totalAmount, - OrderNumber = orderReference, - CreatedAt = DateTime.UtcNow, - NumberOfAdults = 1, - NumberOfChildren = 1, - }; - - int result = await _orderRepo.CreateAsync(bookingOrder); - - if (result != 1) - { - return new ServiceResponse<BookingResponseDTO?>(null, (InternalCode)result); - } - - //Generate payment link with the cost if payment successful - - /* - Return Order Number, Payment Link, Payment Expiry - */ - StripeDataDTO stripeData = new StripeDataDTO - { - SuccessUrl = "https://localhost:44321/success", - CancelUrl = "https://localhost:44321/cancel", - ProductDescription = $"Booking for {orderReference}", - Amount = totalAmount, - CurrencyCode = "USD", - CustomerEmail = order.Email, - ProductName = "Flight Booking Service", - OrderNumber = orderReference, - }; - - var stripeResponse = _stripeService.GetStripeCheckoutUrl(stripeData); - - BookingResponseDTO bookingResponse = new BookingResponseDTO - { - OrderNumber = orderReference, - PaymentLink = stripeResponse.Data - }; - - return new ServiceResponse<BookingResponseDTO?>(bookingResponse, InternalCode.Success); - } - - public async Task<ServiceResponse<BookingResponseDTO?>> GetCheckoutUrlAsync(string orderNumber) - { - if (string.IsNullOrWhiteSpace(orderNumber)) - { - return new ServiceResponse<BookingResponseDTO?>(null, InternalCode.InvalidParam, "Order reference not supplied"); - } - - //gett the order details - var orderDetails = await _orderRepo.Query() - .FirstOrDefaultAsync(x => x.OrderNumber == orderNumber); - - if (orderDetails == null) - { - return new ServiceResponse<BookingResponseDTO?>(null, InternalCode.EntityNotFound, "The order with the supplied order number was not found"); - } - - if (orderDetails.OrderStatus == BookingStatus.Paid) - { - return new ServiceResponse<BookingResponseDTO?>(null, InternalCode.Unprocessable, "This order has already been paid for"); - } - - StripeDataDTO stripeData = new StripeDataDTO - { - SuccessUrl = "https://localhost:44321/success", - CancelUrl = "https://localhost:44321/cancel", - ProductDescription = $"Booking for Order : {orderDetails.OrderNumber}", - Amount = orderDetails.TotalAmount, - CurrencyCode = "USD", - CustomerEmail = orderDetails.Email, - ProductName = "Flight Booking Service", - OrderNumber = orderNumber - }; - - var stripeResponse = _stripeService.GetStripeCheckoutUrl(stripeData); - - BookingResponseDTO bookingResponse = new BookingResponseDTO - { - OrderNumber = orderNumber, - PaymentLink = stripeResponse.Data - }; - - return new ServiceResponse<BookingResponseDTO?>(bookingResponse, InternalCode.Success); - } - - private (FlightInformation? FlightInformation, bool IsBookedToMax) CheckAvailableFlight(string flightNumber, int totalFlights) - { - FlightInformation? flightInformation = _flightRepo.Query() - .FirstOrDefault(x => x.FlightNumber == flightNumber); - - //If flight not valid, return false - if (flightInformation == null) - { - return (flightInformation, false); - } - - int availableFlightCapacity = flightInformation.SeatCapacity - flightInformation.SeatReserved; - - return (flightInformation, totalFlights > availableFlightCapacity); - } - - private (bool IsAllFareExists, bool IsAnyFareMaxedOut, List<int> FareCodes) CheckIfAnyFareIsMaxedOut(BookingOrderDTO order, bool hasReturnFlight) - { - //get all flight fares for all the list ID. We can then use throughout the booking process - var validFlightFares = _flightFareRepo.Query() - .Include(x => x.FlightInformation) - .Where(x => x.FlightInformation.FlightNumber == order.OutboundFlightNumber); - - //if return flight, then add the fares - if (hasReturnFlight) - { - validFlightFares = _flightFareRepo.Query() - .Include(x => x.FlightInformation) - .Where(x => x.FlightInformation.FlightNumber == order.OutboundFlightNumber - || x.FlightInformation.FlightNumber == order.ReturnFlightNumber); - } - - //we get all the flight fares and save to the variable so we can reuse - allFlightFares = validFlightFares.ToList(); - - List<int> fareIds = new List<int>(); - - //get all fare Id - var outboundFares = order.Bookings - .Select(x => x.OutboundFareId) - .ToList(); - - //Add to a list - fareIds.AddRange(outboundFares); - - //we check if all fares are valid for that flight - var isAllFareValid = allFlightFares.Any(x => outboundFares.Contains(x.Id) - && x.FlightInformation.FlightNumber == order.OutboundFlightNumber); - - //if atleast one of the fare in the outbound flight is invalid, return false - if (!isAllFareValid) - { - return (false, true, new List<int>()); - } - - //check the codes for the return flights are also valid - if (hasReturnFlight) - { - var returnFares = order.Bookings - .Select(x => (int)x.ReturnFareId!) - .ToList(); - - fareIds.AddRange(returnFares); - - isAllFareValid = allFlightFares.Any(x => returnFares.Contains(x.Id) - && x.FlightInformation.FlightNumber == order.ReturnFlightNumber); - - if (!isAllFareValid) - { - return (false, true, new List<int>()); - } - } - - var flightFares = allFlightFares - .Select(y => new - { - y.Id, - y.FareCode, - AvailableSeats = y.SeatCapacity - y.SeatReserved - }).ToList(); - - //group the fares by Id - var fareGroup = fareIds.GroupBy(x => x).ToList(); - - bool isAnyFareMaxedOut = true; - - //for each fare, check if the seats are available - foreach (var group in fareGroup) - { - isAnyFareMaxedOut = flightFares.Any(x => x.Id == group.Key && group.Count() > x.AvailableSeats); - - //if any fare is maxed out, terminate the loop - if (isAnyFareMaxedOut) - { - break; - } - } - - return (true, isAnyFareMaxedOut, fareIds); - } - - private async Task UpdateAvailableSeats(BookingOrderDTO order, List<int> fareCodes) - { - int totalFlights = order.Bookings.Count; - - int result = await _flightRepo.Query() - .Where(x => x.FlightNumber == order.OutboundFlightNumber) - .ExecuteUpdateAsync(x => x.SetProperty(y => y.SeatReserved, y => y.SeatReserved + totalFlights)); - - //If a return is booked, reduce the seats too - if (!string.IsNullOrWhiteSpace(order.ReturnFlightNumber)) - { - result = await _flightRepo.Query() - .Where(x => x.FlightNumber == order.ReturnFlightNumber) - .ExecuteUpdateAsync(x => x.SetProperty(y => y.SeatReserved, y => y.SeatReserved + totalFlights)); - } - - //update fare capacity. includes all fares, initial and return - var grouped = fareCodes - .GroupBy(x => x).ToList(); - - foreach (var fare in grouped) - { - result = await _flightFareRepo.Query() - .Where(x => x.Id == fare.Key) - .ExecuteUpdateAsync(x => x.SetProperty(y => y.SeatReserved, y => y.SeatReserved + fare.Count())); - } - - return; - } - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Services/BookingService.cs b/BookingService_Old/FlightBooking.Service/Services/BookingService.cs deleted file mode 100644 index 9dd41fe760428835b979c9dcc30f7f288a760e8a..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Services/BookingService.cs +++ /dev/null @@ -1,101 +0,0 @@ -using AutoMapper; -using AutoMapper.QueryableExtensions; -using FlightBooking.Service.Data; -using FlightBooking.Service.Data.DTO; -using FlightBooking.Service.Data.Models; -using FlightBooking.Service.Data.Repository; -using FlightBooking.Service.Services.Interfaces; -using Microsoft.EntityFrameworkCore; - -namespace FlightBooking.Service.Services -{ - ///<inheritdoc /> - public class BookingService : IBookingService - { - private readonly IGenericRepository<Booking> _bookingRepo; - private readonly IMapper _mapper; - - public BookingService(IGenericRepository<Booking> bookingRepo, IMapper mapper) - { - _bookingRepo = bookingRepo; - _mapper = mapper; - } - - public async Task<ServiceResponse<BookingDTO?>> GetBookingByBookingNumberAsync(string bookingNumber) - { - if (string.IsNullOrWhiteSpace(bookingNumber)) - { - return new ServiceResponse<BookingDTO?>(null, InternalCode.InvalidParam, "No booking number supplied"); - } - - var booking = await _bookingRepo.Query() - .Include(x => x.FlightFare) - .Include(x => x.FlightInformation) - .Include(x => x.ReservedSeat) - .FirstOrDefaultAsync(x => x.BookingNumber == bookingNumber); - - if (booking == null) - { - return new ServiceResponse<BookingDTO?>(null, InternalCode.EntityNotFound, "No booking with that booking number exists"); - } - - var bookingDTO = _mapper.Map<Booking, BookingDTO>(booking); - - return new ServiceResponse<BookingDTO?>(bookingDTO, InternalCode.Success); - } - - public async Task<ServiceResponse<BookingDTO?>> GetBookingByBookingId(int bookingId) - { - var booking = await _bookingRepo.Query() - .Include(x => x.FlightFare) - .Include(x => x.FlightInformation) - .Include(x => x.ReservedSeat) - .FirstOrDefaultAsync(x => x.Id == bookingId); - - if (booking == null) - { - return new ServiceResponse<BookingDTO?>(null, InternalCode.EntityNotFound, "No booking with that booking ID exists"); - } - - var bookingDTO = _mapper.Map<Booking, BookingDTO>(booking); - - return new ServiceResponse<BookingDTO?>(bookingDTO, InternalCode.Success); - } - - public ServiceResponse<IEnumerable<BookingDTO>?> GetBookingsByEmail(string email) - { - if (string.IsNullOrWhiteSpace(email)) - { - return new ServiceResponse<IEnumerable<BookingDTO>?>(null, InternalCode.InvalidParam, "No email supplied"); - } - - var bookings = _bookingRepo.Query() - .Include(x => x.FlightFare) - .Include(x => x.FlightInformation) - .Include(x => x.ReservedSeat) - .Where(x => x.Email == email) - .ProjectTo<BookingDTO>(_mapper.ConfigurationProvider) - .ToList(); - - return new ServiceResponse<IEnumerable<BookingDTO>?>(bookings, InternalCode.Success); - } - - public ServiceResponse<IEnumerable<BookingDTO>?> GetBookingsByOrderNumber(string orderNumber) - { - if (string.IsNullOrWhiteSpace(orderNumber)) - { - return new ServiceResponse<IEnumerable<BookingDTO>?>(null, InternalCode.InvalidParam, "No order number supplied"); - } - - var bookings = _bookingRepo.Query() - .Include(x => x.FlightFare) - .Include(x => x.FlightInformation) - .Include(x => x.ReservedSeat) - .Where(x => x.BookingOrder.OrderNumber == orderNumber) - .ProjectTo<BookingDTO>(_mapper.ConfigurationProvider) - .ToList(); - - return new ServiceResponse<IEnumerable<BookingDTO>?>(bookings, InternalCode.Success); - } - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Services/FlightBookingProfile.cs b/BookingService_Old/FlightBooking.Service/Services/FlightBookingProfile.cs deleted file mode 100644 index 4a7d890344bb2640f474347debefa2304fb92099..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Services/FlightBookingProfile.cs +++ /dev/null @@ -1,29 +0,0 @@ -using AutoMapper; -using FlightBooking.Service.Data.DTO; -using FlightBooking.Service.Data.Models; - -namespace FlightBooking.Service.Services -{ - public class FlightBookingProfile : Profile - { - public FlightBookingProfile() - { - CreateMap<FlightFare, FlightFareDTO>() - .ForMember(dest => dest.AvailableSeats, opt => opt.MapFrom(src => src.SeatCapacity - src.SeatReserved)) - .ForMember(dest => dest.FlightNumber, opt => opt.MapFrom(src => src.FlightInformation.FlightNumber)); - - CreateMap<ReservedSeat, ReservedSeatDTO>(); - - CreateMap<FlightInformation, FlightInformationDTO>() - .ForMember(dest => dest.AvailableSeats, opt => opt.MapFrom(src => src.SeatCapacity - src.SeatReserved)); - - CreateMap<FlightInformation, BookingFlightInformationDTO>(); - - CreateMap<FlightFare, BookingFlightFareDTO>() - .ForMember(dest => dest.FlightNumber, opt => opt.MapFrom(src => src.FlightInformation.FlightNumber)); - - CreateMap<Booking, BookingDTO>() - .ForMember(dest => dest.SeatNumber, opt => opt.MapFrom(src => src.ReservedSeat != null ? src.ReservedSeat.SeatNumber : null)); - } - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Services/FlightFareService.cs b/BookingService_Old/FlightBooking.Service/Services/FlightFareService.cs deleted file mode 100644 index 33bb18c338e64cdc5330a09fe245cec6b5fc789e..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Services/FlightFareService.cs +++ /dev/null @@ -1,44 +0,0 @@ -using AutoMapper; -using AutoMapper.QueryableExtensions; -using FlightBooking.Service.Data; -using FlightBooking.Service.Data.DTO; -using FlightBooking.Service.Data.Models; -using FlightBooking.Service.Data.Repository; -using FlightBooking.Service.Services.Interfaces; -using Microsoft.EntityFrameworkCore; - -namespace FlightBooking.Service.Services -{ - ///<inheritdoc /> - public class FlightFareService : IFlightFareService - { - private readonly IGenericRepository<FlightFare> _fareRepository; - private readonly IMapper _mapper; - - public FlightFareService(IMapper mapper, IGenericRepository<FlightFare> fareRepository) - { - _mapper = mapper; - _fareRepository = fareRepository; - } - - public ServiceResponse<IEnumerable<FlightFareDTO>?> GetFaresByFlightNumber(string flightNumber) - { - var fares = _fareRepository.Query() - .Include(x => x.FlightInformation) - .Where(x => x.FlightInformation.FlightNumber == flightNumber) - .ProjectTo<FlightFareDTO>(_mapper.ConfigurationProvider) - .ToList(); - - return new ServiceResponse<IEnumerable<FlightFareDTO>?>(fares, InternalCode.Success); - } - - public async Task<ServiceResponse<string>> UpdateFlightFareCapacityAsync(int fareId) - { - int result = await _fareRepository.Query() - .Where(x => x.Id == fareId) - .ExecuteUpdateAsync(x => x.SetProperty(y => y.SeatReserved, y => y.SeatReserved + 1)); - - return new ServiceResponse<string>(string.Empty, (InternalCode)result); - } - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Services/FlightService.cs b/BookingService_Old/FlightBooking.Service/Services/FlightService.cs deleted file mode 100644 index f7f4e13c2326cbb16622424f4357ca299b38ad96..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Services/FlightService.cs +++ /dev/null @@ -1,47 +0,0 @@ -using AutoMapper; -using FlightBooking.Service.Data; -using FlightBooking.Service.Data.DTO; -using FlightBooking.Service.Data.Models; -using FlightBooking.Service.Data.Repository; -using FlightBooking.Service.Services.Interfaces; -using Microsoft.EntityFrameworkCore; - -namespace FlightBooking.Service.Services -{ - ///<inheritdoc /> - public class FlightService : IFlightService - { - private readonly IGenericRepository<FlightInformation> _flightRepo; - private readonly IMapper _mapper; - - public FlightService(IGenericRepository<FlightInformation> flightRepo, IMapper mapper) - { - _mapper = mapper; - _flightRepo = flightRepo; - } - - public async Task<ServiceResponse<FlightInformationDTO?>> GetFlightInformationAsync(string flightNumber) - { - FlightInformation? flight = await _flightRepo.Query() - .FirstOrDefaultAsync(x => x.FlightNumber == flightNumber); - - if (flight == null) - { - return new ServiceResponse<FlightInformationDTO?>(null, InternalCode.EntityNotFound, "flight not found"); - } - - FlightInformationDTO flightDto = _mapper.Map<FlightInformation, FlightInformationDTO>(flight); - - return new ServiceResponse<FlightInformationDTO?>(flightDto, InternalCode.Success); - } - - public async Task<ServiceResponse<string>> UpdateFlightCapacityAsync(string flightNumber, int bookedSeats) - { - int result = await _flightRepo.Query() - .Where(x => x.FlightNumber == flightNumber) - .ExecuteUpdateAsync(x => x.SetProperty(y => y.SeatReserved, y => y.SeatReserved + bookedSeats)); - - return new ServiceResponse<string>(string.Empty, (InternalCode)result); - } - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Services/Interfaces/IBookingOrderService.cs b/BookingService_Old/FlightBooking.Service/Services/Interfaces/IBookingOrderService.cs deleted file mode 100644 index 7e1b124edb5df21db71d9ce06cd4ced52f9a8536..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Services/Interfaces/IBookingOrderService.cs +++ /dev/null @@ -1,21 +0,0 @@ -using FlightBooking.Service.Data.DTO; - -namespace FlightBooking.Service.Services.Interfaces -{ - public interface IBookingOrderService - { - /// <summary> - /// Create a new order with a list of booking. Accepts one-way, two and multiple bookings per order - /// </summary> - /// <param name="order"></param> - /// <returns>Returns an object containing payment reference and order number</returns> - Task<ServiceResponse<BookingResponseDTO?>> CreateBookingOrderAsync(BookingOrderDTO order); - - /// <summary> - /// Creates a Stripe payment link using the order number to search for the particular order - /// </summary> - /// <param name="orderNumber"></param> - /// <returns>Returns an object containing payment reference and order number</returns> - Task<ServiceResponse<BookingResponseDTO?>> GetCheckoutUrlAsync(string orderNumber); - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Services/Interfaces/IBookingService.cs b/BookingService_Old/FlightBooking.Service/Services/Interfaces/IBookingService.cs deleted file mode 100644 index 47c5aae0247c4c4bbe0d37646e67e4257fe5195d..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Services/Interfaces/IBookingService.cs +++ /dev/null @@ -1,35 +0,0 @@ -using FlightBooking.Service.Data.DTO; - -namespace FlightBooking.Service.Services.Interfaces -{ - public interface IBookingService - { - /// <summary> - /// Get booking information using booking ID - /// </summary> - /// <param name="bookingId"></param> - /// <returns></returns> - Task<ServiceResponse<BookingDTO?>> GetBookingByBookingId(int bookingId); - - /// <summary> - /// Get booking information using booking number - /// </summary> - /// <param name="bookingNumber"></param> - /// <returns></returns> - Task<ServiceResponse<BookingDTO?>> GetBookingByBookingNumberAsync(string bookingNumber); - - /// <summary> - /// Get all bookings for an email address - /// </summary> - /// <param name="email"></param> - /// <returns></returns> - ServiceResponse<IEnumerable<BookingDTO>?> GetBookingsByEmail(string email); - - /// <summary> - /// Get all booking for an order - /// </summary> - /// <param name="orderNumber"></param> - /// <returns></returns> - ServiceResponse<IEnumerable<BookingDTO>?> GetBookingsByOrderNumber(string orderNumber); - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Services/Interfaces/IFlightFareService.cs b/BookingService_Old/FlightBooking.Service/Services/Interfaces/IFlightFareService.cs deleted file mode 100644 index 34e4545563f4920e336608961cb63ba9372bc998..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Services/Interfaces/IFlightFareService.cs +++ /dev/null @@ -1,21 +0,0 @@ -using FlightBooking.Service.Data.DTO; - -namespace FlightBooking.Service.Services.Interfaces -{ - public interface IFlightFareService - { - /// <summary> - /// Get all the fares for a flight using flight number - /// </summary> - /// <param name="flightNumber"></param> - /// <returns></returns> - ServiceResponse<IEnumerable<FlightFareDTO>?> GetFaresByFlightNumber(string flightNumber); - - /// <summary> - /// Update the flight capacity - /// </summary> - /// <param name="fareId"></param> - /// <returns></returns> - Task<ServiceResponse<string>> UpdateFlightFareCapacityAsync(int fareId); - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Services/Interfaces/IFlightService.cs b/BookingService_Old/FlightBooking.Service/Services/Interfaces/IFlightService.cs deleted file mode 100644 index 290f5d247d3c85854228536bddd12be50fbcfeb7..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Services/Interfaces/IFlightService.cs +++ /dev/null @@ -1,22 +0,0 @@ -using FlightBooking.Service.Data.DTO; - -namespace FlightBooking.Service.Services.Interfaces -{ - public interface IFlightService - { - /// <summary> - /// Gets the flight information for a flight - /// </summary> - /// <param name="flightNumber"></param> - /// <returns></returns> - Task<ServiceResponse<FlightInformationDTO?>> GetFlightInformationAsync(string flightNumber); - - /// <summary> - /// Updates the flight capacity - /// </summary> - /// <param name="flightNumber"></param> - /// <param name="bookedSeats"></param> - /// <returns></returns> - Task<ServiceResponse<string>> UpdateFlightCapacityAsync(string flightNumber, int bookedSeats); - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Services/Interfaces/IReservedSeatService.cs b/BookingService_Old/FlightBooking.Service/Services/Interfaces/IReservedSeatService.cs deleted file mode 100644 index c0f70557c739824a7fc7f872dd1a170cfe8cb509..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Services/Interfaces/IReservedSeatService.cs +++ /dev/null @@ -1,29 +0,0 @@ -using FlightBooking.Service.Data.DTO; - -namespace FlightBooking.Service.Services.Interfaces -{ - public interface IReservedSeatService - { - /// <summary> - /// Gets all available seats for a flight - /// </summary> - /// <param name="flightNumber"></param> - /// <returns></returns> - ServiceResponse<IEnumerable<ReservedSeatDTO>> GetAvailableSeatsByFlightNumber(string flightNumber); - - /// <summary> - /// Creates a seat reservation for a valid booking - /// </summary> - /// <param name="requestDTO"></param> - /// <returns></returns> - Task<ServiceResponse<string>> ReserveSeatAsync(ReservedSeatRequestDTO requestDTO); - - /// <summary> - /// Generates seat numbers for a flight based on flight capacity - /// </summary> - /// <param name="flightNumber"></param> - /// <param name="flightCapacity"></param> - /// <returns></returns> - Task<ServiceResponse<string>> GenerateSeatNumbersAsync(string flightNumber, int flightCapacity); - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Services/Interfaces/IStripeService.cs b/BookingService_Old/FlightBooking.Service/Services/Interfaces/IStripeService.cs deleted file mode 100644 index abfb0f0fb9864a3dbda4f38ba2bd2f07db97fb4e..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Services/Interfaces/IStripeService.cs +++ /dev/null @@ -1,22 +0,0 @@ -using FlightBooking.Service.Data.DTO; -using Stripe; - -namespace FlightBooking.Service.Services.Interfaces -{ - public interface IStripeService - { - /// <summary> - /// Creates a Stripe payment link - /// </summary> - /// <param name="stripeDataDTO"></param> - /// <returns>Payment link</returns> - ServiceResponse<string> GetStripeCheckoutUrl(StripeDataDTO stripeDataDTO); - - /// <summary> - /// Processes Stripe events when a checkout (payment) is completed - /// </summary> - /// <param name="stripeEvent"></param> - /// <returns></returns> - Task<ServiceResponse<string>> ProcessPayment(Event stripeEvent); - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Services/PaymentService.cs b/BookingService_Old/FlightBooking.Service/Services/PaymentService.cs deleted file mode 100644 index b66d125e813677ea35afef3ec8d9c1b7c154210b..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Services/PaymentService.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace FlightBooking.Service.Services -{ - public class PaymentService - { - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Services/ReservedSeatService.cs b/BookingService_Old/FlightBooking.Service/Services/ReservedSeatService.cs deleted file mode 100644 index 16126d17e4e94c58796ae0d3e1af122ac508b47f..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Services/ReservedSeatService.cs +++ /dev/null @@ -1,127 +0,0 @@ -using AutoMapper; -using AutoMapper.QueryableExtensions; -using FlightBooking.Service.Data; -using FlightBooking.Service.Data.DTO; -using FlightBooking.Service.Data.Models; -using FlightBooking.Service.Data.Repository; -using FlightBooking.Service.Services.Interfaces; -using Microsoft.EntityFrameworkCore; - -namespace FlightBooking.Service.Services -{ - ///<inheritdoc /> - public class ReservedSeatService : IReservedSeatService - { - private readonly IGenericRepository<ReservedSeat> _seatRepo; - private readonly IGenericRepository<Booking> _bookingRepo; - private readonly IMapper _mapper; - - public ReservedSeatService(IGenericRepository<ReservedSeat> seatRepository, IGenericRepository<Booking> bookingRepo, - IMapper mapper) - { - _seatRepo = seatRepository; - _bookingRepo = bookingRepo; - _mapper = mapper; - } - - public async Task<ServiceResponse<string>> ReserveSeatAsync(ReservedSeatRequestDTO requestDTO) - { - if (requestDTO == null) - { - return new ServiceResponse<string>(string.Empty, InternalCode.InvalidParam); - } - - //check if booking is valid - Booking? booking = await _bookingRepo.Query() - .Include(x => x.FlightInformation) - .FirstOrDefaultAsync(x => x.BookingNumber == requestDTO.BookingNumber); - - if (booking == null) - { - return new ServiceResponse<string>(string.Empty, InternalCode.EntityNotFound, "Booking not found for the supplied booking number"); - } - - //check if seat is available - ReservedSeat? existingSeat = await _seatRepo.Query() - .Include(x => x.FlightInformation) - .FirstOrDefaultAsync(x => x.FlightNumber == booking.FlightInformation.FlightNumber - && x.SeatNumber == requestDTO.SeatNumber); - - if (existingSeat == null) - { - return new ServiceResponse<string>(string.Empty, InternalCode.Unprocessable, "The selected seat number does not exist"); - } - - if (existingSeat.IsReserved) - { - return new ServiceResponse<string>(string.Empty, InternalCode.Unprocessable, "The selected seat has already been reserved"); - } - - //reserve the seat - existingSeat.IsReserved = true; - existingSeat.BookingNumber = booking.BookingNumber; - existingSeat.BookingId = booking.Id; - - int result = await _seatRepo.SaveChangesToDbAsync(); - - return new ServiceResponse<string>(string.Empty, (InternalCode)result); - } - - public ServiceResponse<IEnumerable<ReservedSeatDTO>> GetAvailableSeatsByFlightNumber(string flightNumber) - { - List<ReservedSeatDTO> seats = _seatRepo.Query() - .Where(x => x.FlightNumber == flightNumber && !x.IsReserved) - .ProjectTo<ReservedSeatDTO>(_mapper.ConfigurationProvider) - .ToList(); - - return new ServiceResponse<IEnumerable<ReservedSeatDTO>>(seats, InternalCode.Success); - } - - public async Task<ServiceResponse<string>> GenerateSeatNumbersAsync(string flightNumber, int flightCapacity) - { - //assume seats are in group of 4 Alphabets e.g 1A, 1B, 1C, 1D - - Dictionary<int, string> SeatMaps = new Dictionary<int, string> - { - {1, "A" }, - {2, "B" }, - {3, "C" }, - {4, "D" } - }; - - int seatId = 1; - int seatCount = 1; - - List<string> seatNumbers = new List<string>(); - - for (int i = 1; i < flightCapacity + 1; i++) - { - if (seatCount > 4) - { - seatId++; - seatCount = 1; - } - - seatNumbers.Add(seatId + SeatMaps[seatCount]); - seatCount++; - } - - List<ReservedSeat> reservedSeats = new List<ReservedSeat>(); - - foreach (var seatNumber in seatNumbers) - { - reservedSeats.Add(new ReservedSeat - { - BookingNumber = null, - FlightNumber = flightNumber, - IsReserved = false, - SeatNumber = seatNumber - }); - } - - int result = await _seatRepo.BulkCreateAsync(reservedSeats); - - return new ServiceResponse<string>(string.Empty, (InternalCode)result); - } - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Services/ResponseFormatter.cs b/BookingService_Old/FlightBooking.Service/Services/ResponseFormatter.cs deleted file mode 100644 index 504c41820df3c87e6e6b7026f8181382cab22ed9..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Services/ResponseFormatter.cs +++ /dev/null @@ -1,176 +0,0 @@ -using FlightBooking.Service.Data; -using Microsoft.AspNetCore.Mvc; - -namespace FlightBooking.Service.Services -{ - public static class FormatResponseExtension - { - public static ActionResult FormatResponse<T>(this ServiceResponse<T> serviceResponse) - { - ObjectResult response; - ProblemDetails problemDetails; - - if (serviceResponse == null) - { - problemDetails = new ProblemDetails - { - Status = 500, - Title = ServiceErrorMessages.OperationFailed, - Type = "https://tools.ietf.org/html/rfc7231#section-6.6" - }; - return new ObjectResult(problemDetails) - { - StatusCode = 500 - }; - } - - switch (serviceResponse.ServiceCode) - { - case InternalCode.Failed: - problemDetails = new ProblemDetails - { - Status = 500, - Title = ServiceErrorMessages.OperationFailed, - Detail = serviceResponse.Message, - Type = "https://tools.ietf.org/html/rfc7231#section-6.6" - }; - response = new ObjectResult(problemDetails) - { - StatusCode = 500 - }; - - return response; - - case InternalCode.Success: - - if (serviceResponse.Data != null) - { - Type dataType = serviceResponse.Data.GetType(); - - if (dataType == typeof(string)) - { - string? data = serviceResponse!.Data as string; - if (string.IsNullOrEmpty(data)) - { - return new OkResult(); - } - } - } - - return new OkObjectResult(serviceResponse.Data); - - case InternalCode.UpdateError: - problemDetails = new ProblemDetails - { - Status = 500, - Title = ServiceErrorMessages.InternalServerError, - Detail = serviceResponse.Message, - Type = "https://tools.ietf.org/html/rfc7231#section-6.6" - }; - response = new ObjectResult(problemDetails) - { - StatusCode = 500, - }; - return response; - - case InternalCode.Mismatch: - problemDetails = new ProblemDetails - { - Status = 400, - Title = ServiceErrorMessages.MisMatch, - Detail = serviceResponse.Message, - Type = "https://tools.ietf.org/html/rfc7231#section-6.5.1" - }; - return new BadRequestObjectResult(problemDetails); - - case InternalCode.EntityIsNull: - problemDetails = new ProblemDetails - { - Status = 400, - Title = ServiceErrorMessages.EntityIsNull, - Detail = serviceResponse.Message, - Type = "https://tools.ietf.org/html/rfc7231#section-6.5.1" - }; - return new BadRequestObjectResult(problemDetails); - - case InternalCode.InvalidParam: - problemDetails = new ProblemDetails - { - Status = 400, - Title = ServiceErrorMessages.InvalidParam, - Detail = serviceResponse.Message, - Type = "https://tools.ietf.org/html/rfc7231#section-6.5.1" - }; - return new BadRequestObjectResult(problemDetails); - - case InternalCode.EntityNotFound: - problemDetails = new ProblemDetails - { - Status = 404, - Title = ServiceErrorMessages.EntityNotFound, - Detail = string.IsNullOrEmpty(serviceResponse.Message) ? "The requested resource was not found" : serviceResponse.Message, - Type = "https://tools.ietf.org/html/rfc7231#section-6.5.4" - }; - return new NotFoundObjectResult(problemDetails); - - case InternalCode.Incompleted: - return new AcceptedResult("", serviceResponse.Data); - - case InternalCode.ListEmpty: - problemDetails = new ProblemDetails - { - Status = 400, - Title = ServiceErrorMessages.EntityIsNull, - Detail = serviceResponse.Message, - Type = "https://tools.ietf.org/html/rfc7231#section-6.5.1" - }; - return new BadRequestObjectResult(problemDetails); - - case InternalCode.EntityExist: - problemDetails = new ProblemDetails - { - Status = 409, - Title = ServiceErrorMessages.EntityExist, - Detail = string.IsNullOrEmpty(serviceResponse.Message) ? $"An entity of the type exists" : serviceResponse.Message, - Type = "https://tools.ietf.org/html/rfc7231#section-6.5.8" - }; - return new ConflictObjectResult(problemDetails); - - case InternalCode.Unprocessable: - problemDetails = new ProblemDetails - { - Status = 422, - Title = ServiceErrorMessages.UnprocessableEntity, - Detail = string.IsNullOrEmpty(serviceResponse.Message) ? "The request cannot be processed" : serviceResponse.Message - }; - return new UnprocessableEntityObjectResult(problemDetails); - - case InternalCode.Unauthorized: - problemDetails = new ProblemDetails - { - Status = 401, - Title = "Unathorized request", - Detail = "The supplied credentials is invalid." - }; - return new UnauthorizedObjectResult(problemDetails); - - default: - return new OkObjectResult(serviceResponse.Data); - } - } - } - - public class ServiceResponse<T> - { - public InternalCode ServiceCode { get; set; } = InternalCode.Failed; - public T Data { get; set; } - public string Message { get; set; } - - public ServiceResponse(T data, InternalCode serviceCode = InternalCode.Failed, string message = "") - { - Message = message; - ServiceCode = serviceCode; - Data = data; - } - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Services/ServicesModule.cs b/BookingService_Old/FlightBooking.Service/Services/ServicesModule.cs deleted file mode 100644 index 30710dcf1366aea965037c89bdd0e022901cab64..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Services/ServicesModule.cs +++ /dev/null @@ -1,17 +0,0 @@ -using FlightBooking.Service.Services.Interfaces; - -namespace FlightBooking.Service.Services -{ - public static class ServicesModule - { - public static void AddServices(this IServiceCollection services) - { - services.AddScoped<IBookingService, BookingService>(); - services.AddScoped<IBookingOrderService, BookingOrderService>(); - services.AddScoped<IReservedSeatService, ReservedSeatService>(); - services.AddScoped<IFlightFareService, FlightFareService>(); - services.AddScoped<IFlightService, FlightService>(); - services.AddScoped<IStripeService, StripeService>(); - } - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Services/StripeService.cs b/BookingService_Old/FlightBooking.Service/Services/StripeService.cs deleted file mode 100644 index ab7557149e2e9fd3765d8123d0e5a2ecd83b7ed8..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Services/StripeService.cs +++ /dev/null @@ -1,147 +0,0 @@ -using FlightBooking.Service.Data; -using FlightBooking.Service.Data.Configs; -using FlightBooking.Service.Data.DTO; -using FlightBooking.Service.Data.Models; -using FlightBooking.Service.Data.Repository; -using FlightBooking.Service.Services.Interfaces; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Options; -using Newtonsoft.Json; -using Stripe; -using Stripe.Checkout; - -namespace FlightBooking.Service.Services -{ - ///<inheritdoc /> - public class StripeService : IStripeService - { - private readonly StripeConfig _stripeConfig; - private readonly IGenericRepository<Payment> _paymentRepo; - private readonly IGenericRepository<BookingOrder> _orderRepo; - - private readonly ILogger<StripeService> _logger; - - public StripeService(IOptionsMonitor<StripeConfig> options, IGenericRepository<Payment> paymentRepo, - IGenericRepository<BookingOrder> orderRepo, ILogger<StripeService> logger) - { - _stripeConfig = options.CurrentValue; - _paymentRepo = paymentRepo; - _orderRepo = orderRepo; - _logger = logger; - } - - public ServiceResponse<string> GetStripeCheckoutUrl(StripeDataDTO stripeDataDTO) - { - if (stripeDataDTO == null) - { - return new ServiceResponse<string>(string.Empty, InternalCode.InvalidParam, "Invalid Data"); - } - - string checkoutUrl = string.Empty; - - try - { - StripeConfiguration.ApiKey = _stripeConfig.SecretKey; - - var amountInCents = stripeDataDTO.Amount * 100; - - var options = new SessionCreateOptions - { - LineItems = new List<SessionLineItemOptions> - { - new SessionLineItemOptions - { - PriceData = new SessionLineItemPriceDataOptions - { - Currency = stripeDataDTO.CurrencyCode, - UnitAmountDecimal = amountInCents, //in cents - ProductData = new SessionLineItemPriceDataProductDataOptions - { - Name = stripeDataDTO.ProductName, - Description = stripeDataDTO.ProductDescription - }, - }, - Quantity = 1, - }, - }, - Mode = "payment", - SuccessUrl = stripeDataDTO.SuccessUrl, - CancelUrl = stripeDataDTO.CancelUrl, - ClientReferenceId = stripeDataDTO.OrderNumber, - CustomerEmail = stripeDataDTO.CustomerEmail, - }; - var service = new SessionService(); - Session session = service.Create(options); - checkoutUrl = session.Url; - } - catch (Exception ex) - { - _logger.LogCritical(ex.ToString()); - } - - return new ServiceResponse<string>(checkoutUrl, InternalCode.Success); - } - - public async Task<ServiceResponse<string>> ProcessPayment(Event stripeEvent) - { - if (stripeEvent == null) - { - return new ServiceResponse<string>(string.Empty, InternalCode.InvalidParam); - } - - var session = stripeEvent.Data.Object as Session; - - //check if payment already saved, if yes, return - bool isPaymentSaved = _paymentRepo.Query() - .Any(x => x.OrderNumber == session!.ClientReferenceId); - - if (isPaymentSaved) - { - return new ServiceResponse<string>(string.Empty, InternalCode.Success); - } - - string orderNumber = session!.ClientReferenceId; - - var bookingOrder = await _orderRepo.Query() - .Include(x => x.Bookings) - .FirstOrDefaultAsync(x => x.OrderNumber == orderNumber); - - if (bookingOrder == null) - { - _logger.LogCritical("Payment made for a booking that doesn't exist"); - return new ServiceResponse<string>(string.Empty, InternalCode.Success); - } - - //save payment - Payment payment = new Payment - { - TransactionDate = session!.Created, - OrderNumber = orderNumber, - MetaData = JsonConvert.SerializeObject(session), - BookingOrderId = bookingOrder.Id, - CurrencyCode = session.Currency, - CustomerEmail = session.CustomerEmail, - PaymentReference = Guid.NewGuid().ToString("N").ToUpper(), - PaymentStatus = session.PaymentStatus, - CreatedAt = DateTime.UtcNow, - TransactionAmount = (decimal)session.AmountTotal!, - PaymentChannel = "Stripe", - }; - - await _paymentRepo.CreateAsync(payment); - - //update flight and booking information - - bookingOrder.OrderStatus = BookingStatus.Paid; - - foreach (var booking in bookingOrder.Bookings) - { - booking.BookingStatus = BookingStatus.Paid; - } - - await _orderRepo.SaveChangesToDbAsync(); - - return new ServiceResponse<string>(string.Empty, InternalCode.Success); - } - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/Startup.cs b/BookingService_Old/FlightBooking.Service/Startup.cs deleted file mode 100644 index 540cfff397cf962eba9d196c05dbf08806ecc1a6..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/Startup.cs +++ /dev/null @@ -1,162 +0,0 @@ -using FlightBooking.Service.Data; -using FlightBooking.Service.Data.Configs; -using FlightBooking.Service.Data.Repository; -using FlightBooking.Service.Middleware; -using FlightBooking.Service.Services; -using Microsoft.AspNetCore.Authentication.JwtBearer; -using Microsoft.EntityFrameworkCore; -using Microsoft.IdentityModel.Tokens; -using Microsoft.OpenApi.Models; -using Newtonsoft.Json.Converters; -using System.Text; - -namespace FlightBooking.Service -{ - public class Startup - { - public static readonly LoggerFactory _myLoggerFactory = - new LoggerFactory(new[] - { - new Microsoft.Extensions.Logging.Debug.DebugLoggerProvider() - }); - - public Startup(IConfiguration configuration) - { - Configuration = configuration; - } - - public IConfiguration Configuration { get; } - - // This method gets called by the runtime. Use this method to add services to the container. - public void ConfigureServices(IServiceCollection services) - { - //we keep using NewtonSoft so that serialization of reference loop can be ignored, especially because of EFCore - services.AddControllers() - .AddNewtonsoftJson(x => x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore) - .AddNewtonsoftJson(x => x.SerializerSettings.Converters.Add(new StringEnumConverter())); - - services.AddAutoMapper(typeof(Startup)); - - //Configuration for SQL Servr and MySql - string mysqlConnectionString = Configuration.GetConnectionString("FlightBookingServiceDb_Mysql")!; - var mySqlServerVersion = new MySqlServerVersion(new Version(8, 0, 36)); - - services.AddDbContext<FlightBookingContext>(options => - { - //options.UseLoggerFactory(_myLoggerFactory).EnableSensitiveDataLogging(); //DEV: ENABLE TO SEE SQL Queries - - //To Use Sql Server - //options.UseSqlServer(Configuration.GetConnectionString("FlightBookingServiceDb")); - - //To Use MySql - options.UseMySql(mysqlConnectionString, mySqlServerVersion, opt => opt.EnableRetryOnFailure()) - .LogTo(Console.WriteLine, LogLevel.Warning) - .EnableSensitiveDataLogging() - .EnableDetailedErrors(); - }); - - services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options => - { - //For OpenId Connect tokens - options.Authority = Configuration["JWTConfig:Issuer"]; - options.Audience = Configuration["JWTConfig:Issuer"]; - options.SaveToken = true; - - options.TokenValidationParameters = new TokenValidationParameters - { - ValidateIssuer = true, - ValidateAudience = false, - ValidateLifetime = true, - ValidateIssuerSigningKey = true, - ValidIssuers = [Configuration["JWTConfig:Issuer"], Configuration["JWTConfig:Issuer"]], - IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JWTConfig:Key"]!)), - }; - }); - - services.AddCors(option => - { - option.AddDefaultPolicy( - builder => - { - builder - .AllowAnyOrigin() - .SetIsOriginAllowedToAllowWildcardSubdomains() - .AllowAnyHeader() - .AllowAnyMethod(); - }); - }); - - services.AddSignalR(); - services.AddHttpClient(); - services.AddHttpContextAccessor(); - - //Add our custom services - services.AddRepository(); - services.AddServices(); - - services.AddEndpointsApiExplorer(); - services.AddSwaggerGen(options => - { - options.SwaggerDoc("v1", new OpenApiInfo { Title = "Flight Booking API", Version = "v1" }); - }); - - //Add our configs - services.AddConfigSettings(Configuration); - } - - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) - { - //https://docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-8.0 - //The following Startup.Configure method adds middleware components for common app scenarios: - - //1. Exception / error handling (HTTP Strict Transport Security Protocol in prod) - //2. HTTPS redirection - //3. Static File Middleware - //4. Cookie Policy Middleware - //5. Routing Middleware (UseRouting) to route requests. - //5. Cors - //5. Custom route - //6. Authentication Middleware - //7. Authorization Middleware - //8. Session Middleware - //9. Endpoint Routing Middleware (UseEndpoints - - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - //app.UseDatabaseErrorPage(); - } - else - { - // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. - app.UseHsts(); - app.UseErrorHandlingMiddleware(); //custom error handler - //app.UseExceptionHandler(); - } - - app.UseHttpsRedirection(); - - app.UseRouting(); - - app.UseCors();//this was moved here since the BasicAuthMiddleware below is also authentication and cors must come before authentication. - - if (env.IsDevelopment() || env.IsStaging()) - { - app.UseSwagger(); - app.UseSwaggerUI(opt => - { - opt.SwaggerEndpoint("/swagger/v1/swagger.json", "Flight Booking API"); - }); - } - - app.UseAuthentication(); - app.UseAuthorization(); - - app.UseEndpoints(endpoints => - { - endpoints.MapControllers(); - }); - } - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/appsettings.Development.json b/BookingService_Old/FlightBooking.Service/appsettings.Development.json deleted file mode 100644 index 14d2ada275401963af066006c415ad4c6f6f5632..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/appsettings.Development.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - }, - "ConnectionStrings": { - "FlightBookingServiceDb": "Server=.;Database=FlightBooking_Db;User ID=sa;Password=beforwardj!;Trusted_Connection=False;Encrypt=False;Connection Timeout=180;", - "FlightBookingServiceDb_Mysql": "Server=localhost;Database=FlightBooking_Db;User=root;Password=P@ss1ord" - }, - "JWTConfig": { - "Key": "28298659-1c10-4f2e-b045-42698ab4b02b", - "Issuer": "https://localhost:44321" - }, - "StripeConfig": { - "PublicKey": "", - "SecretKey": "", - "SigningSecret": "" - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/appsettings.json b/BookingService_Old/FlightBooking.Service/appsettings.json deleted file mode 100644 index 31a3e8d4be37041572b3f732452c32cece264feb..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/appsettings.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - }, - "AllowedHosts": "*", - "ConnectionStrings": { - "FlightBookingServiceDb": "Server=.;Database=FlightBooking_Db;User ID=sa;Password=beforwardj!;Trusted_Connection=False;Encrypt=False;Connection Timeout=180;", - "FlightBookingServiceDb_Mysql": "Server=localhost;Database=FlightBooking_Db;User=root;Password=P@ss1ord" - }, - "JWTConfig": { - "Key": "28298659-1c10-4f2e-b045-42698ab4b02b", - "Issuer": "https://localhost:44321" - }, - "StripeConfig": { - "PublicKey": "", - "SecretKey": "", - "SigningSecret": "" - } -} \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/nlog.config b/BookingService_Old/FlightBooking.Service/nlog.config deleted file mode 100644 index 1967321ff68e857eb426ef25973180f849964756..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/nlog.config +++ /dev/null @@ -1,40 +0,0 @@ -<?xml version="1.0" encoding="utf-8" ?> -<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - autoReload="true" - internalLogLevel="Info" - internalLogFile=".\log\internal-nlog.txt"> - - <!-- enable asp.net core layout renderers --> - <extensions> - <add assembly="NLog.Web.AspNetCore" /> - </extensions> - - <!-- the targets to write to --> - <targets> - <!-- write logs to file --> - <target xsi:type="File" name="allfile" fileName=".\log\nlog-all-${shortdate}.log" - layout="${longdate}|${event-properties:item=EventId_Id:whenEmpty=0}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}" /> - <!-- another file log, only own logs. Uses some ASP.NET core renderers --> - <target xsi:type="File" name="ownFile-web" fileName=".\log\nlog-own-${shortdate}.log" - layout="${longdate}|${event-properties:item=EventId_Id:whenEmpty=0}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}|${callsite}| body: ${aspnet-request-posted-body}" /> - - <!--Console Target for hosting lifetime messages to improve Docker / Visual Studio startup detection --> - <target xsi:type="Console" name="lifetimeConsole" layout="${level:truncate=4:lowercase=true}: ${logger}[0]${newline} ${message}${exception:format=tostring}" /> - </targets> - - <!-- rules to map from logger name to target --> - <rules> - <!--All logs, including from Microsoft--> - <logger name="*" minlevel="Trace" writeTo="allfile" /> - - <!--Output hosting lifetime messages to console target for faster startup detection --> - <logger name="Microsoft.Hosting.Lifetime" minlevel="Info" writeTo="lifetimeConsole, ownFile-web" final="true" /> - - <!--Skip non-critical Microsoft logs and so log only own logs (BlackHole) --> - <logger name="Microsoft.*" maxlevel="Info" final="true" /> - <logger name="System.Net.Http.*" maxlevel="Info" final="true" /> - - <logger name="*" minlevel="Trace" writeTo="ownFile-web" /> - </rules> -</nlog> \ No newline at end of file diff --git a/BookingService_Old/FlightBooking.Service/readme.md b/BookingService_Old/FlightBooking.Service/readme.md deleted file mode 100644 index 77617ad64dd70c1dcf44caaa9bf2264cabcb785f..0000000000000000000000000000000000000000 --- a/BookingService_Old/FlightBooking.Service/readme.md +++ /dev/null @@ -1,385 +0,0 @@ -Libraries Used: - -1. NLog. We used NLog for logging. By default all logs with level Informational are saved. This setting can be changed in the appsettings.json - -nlog.config contains the file that is used to configure our NLog. - -2. Automapper: This is a great utility tool that allows mapping one model or DTO (Data Transfer Object) to another. It helps to us avoid repetitve code. - To use, we first add a line in the `ConfigureServices` method of our `Startup.cs`: - - `services.AddAutoMapper(typeof(Startup));` - - The we declare a class that contains our mappings: - ``` - public class FlightBookingProfile : Profile - { - public FlightBookingProfile() - { - CreateMap<FlightFare, FlightFareDTO>() - .ForMember(dest => dest.AvailableSeats, opt => opt.MapFrom(src => src.SeatCapacity - src.SeatReserved)) - .ForMember(dest => dest.FlightNumber, opt => opt.MapFrom(src => src.FlightInformation.FlightNumber)); - } - } - ``` - - -3. We also installed NewtonSoftJson library for working with Json input and output. - -4. Swashbuckle was also installed so we can generate Swagger documentation from our controllers. - -5. Some libraries for using Jwt for authentication were also added. - - -## Program Flow. - -Controller -> Services -> Repository -> EntityFramework -> Data - - -### Controllers - -They represent our endpoints based on the MVC pattern. -Each controller has been decorated with attributes that makes it easy to read what input and output to expect. -For example, our `ReservedSeatController`: - -``` - [Route("api/[controller]")] - [ApiController] - public class SeatsController : ControllerBase - { - private readonly IReservedSeatService _service; - - public SeatsController(IReservedSeatService service) - { - _service = service; - } - - [HttpGet] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IEnumerable<ReservedSeatDTO>))] - [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ProblemDetails))] - public IActionResult GetAvailableSeats([FromQuery] string flightNumber) - { - ServiceResponse<IEnumerable<ReservedSeatDTO>> result = _service.GetAvailableSeatsByFlightNumber(flightNumber); - - return result.FormatResponse(); - } - - [HttpPost] - [Consumes(MediaTypeNames.Application.Json)] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status422UnprocessableEntity, Type = typeof(ProblemDetails))] - [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ProblemDetails))] - public async Task<IActionResult> ReserveSeat([FromBody] ReservedSeatRequestDTO requestDTO) - { - ServiceResponse<string> result = await _service.ReserveSeatAsync(requestDTO); - - return result.FormatResponse(); - } - } -``` - -In the above, we have to methods in the controller which corresponds to 2 endpoints. - -First, we inject our `IReservedSeatService` into the controller. - -The first endpoint is a GET endpoint: -And the attributes show that it can return a 200, 400 and 422 response. The 400 and 422 responses are in types of ProblemDetails which is a specification for returning API responses. - -This part: `([FromQuery] string flightNumber)` indicates that a query string named ``flightNumber`` is passed to the endpoint generated by this method. - -The `_service` returns a type of `ServiceResponse` which is then formatted to return the appropriate response. More on this later - - -The second endpoint is a POST endpoint: -The attributes show it accepts a body (`[FromBody]`) of type application/json (`MediaTypeNames.Application.Json`) and response produced are 200, 422, 400. - - - -### Services -They represent the logic for our app. We this pattern to make it easy to test the services. -By abstracting the services to use Interfaces, we can easily write tests that can be flexible. - -We rely on the built-in Dependency Injection framework to resolve service dependencies. - -In each service, we inject Repository classes and other Services. - -The services also have to be registered and we do this by declaring a static class that will do the registration: - -``` -public static class ServicesModule -{ - public static void AddServices(this IServiceCollection services) - { - services.AddScoped<IBookingService, BookingService>(); - services.AddScoped<IBookingOrderService, BookingOrderService>(); - services.AddScoped<IReservedSeatService, ReservedSeatService>(); - services.AddScoped<IFlightFareService, FlightFareService>(); - services.AddScoped<IFlightService, FlightService>(); - services.AddScoped<IStripeService, StripeService>(); - } -} -``` -Here: We register each service as a Scoped dependency. Scoped means that the service will only be active for the duration of a request (i.e Http Request). - -Then we call the method in our Startup.cs: -` services.AddServices();` - -Each service also returns a type `ServiceResponse<T>` where T is a class - -The `ServiceResponse<T>` is declared in the `ResponseFormatter.cs` - -``` -public class ServiceResponse<T> -{ - public InternalCode ServiceCode { get; set; } = InternalCode.Failed; - public T Data { get; set; }// = null; - public string Message { get; set; } - - public ServiceResponse(T data, InternalCode serviceCode = InternalCode.Failed, string message = "") - { - Message = message; - ServiceCode = serviceCode; - Data = data; - } -} -``` -We declare the `ServiceResponse` to be a generic class. It's properties are: -`InternalCode` that indicates the status. InternalCode is an enum -`Data`: which is a type of `T` -`Message`: optional message - -The `FormatResponse` is an extension method that accepts a `ServiceResponse<T>` and then checks the Internal Code and uses that to -return an appropriate response. - -This makes it easy for us to return a uniform type of response. -2xx responses return a simple 2xx and an optional data -4xx and 5xx responses return a type of `ProblemDetails`. -The helps to give more context to the nature of the response. - - -### Repository - -We use a Repository pattern that wraps EntityFramework unit of work pattern. The class is declared as a Generic class so that we can pass any model to it. -We then declare helper methods that in turn call EntityFramework methods: - -``` - public class GenericRepository<T> : IGenericRepository<T> where T : class, new() - { - //Responses: failed=0, success=1 - - //IEnumerable iterates over an in-memory collection while IQueryable does so on the DB - // call to .ToList to enable instant query against DB - - protected FlightBookingContext _db; - protected ILogger _logger; - - //...omitted for brevity - - public async Task<T?> GetByGuidAsync(Guid id) - { - var entity = await _db.Set<T>().FindAsync(id); - return entity; - } - -} -``` - -In the aboved, we pass a type of `DbContext` and a `Logger`. -In the `GetByGuidAsync()` method, we use the `_db` of that model to find the data. - -We must also inject the Repository of each model so we can use anywhere in our project: -``` -public static class RepositoryModule -{ - public static void AddRepository(this IServiceCollection services) - { - services.AddScoped<IGenericRepository<Booking>, GenericRepository<Booking>>(); - services.AddScoped<IGenericRepository<FlightInformation>, GenericRepository<FlightInformation>>(); - services.AddScoped<IGenericRepository<FlightFare>, GenericRepository<FlightFare>>(); - services.AddScoped<IGenericRepository<Payment>, GenericRepository<Payment>>(); - services.AddScoped<IGenericRepository<BookingOrder>, GenericRepository<BookingOrder>>(); - services.AddScoped<IGenericRepository<ReservedSeat>, GenericRepository<ReservedSeat>>(); - } -} -``` -Just like in the Services, we also add the dependencies as a Scoped service. - -This is important because we want to quickly use a DbContext which in turn holds a connection to the database. If we use it and quickly return it to the connection pool, we can avoid issues with resource exhaustion. - - -### Data - -We are using MySql. So we must install the following MySqlConnector and the Pomelo.EntityFramework.MySql libraries. -Let's add these 2 lines to our Package reference. - -1. `<PackageReference Include="MySqlConnector" Version="2.3.5" />` -2. `<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="8.0.1" />` - - -To use our model, we use classes to represent our data. Each class in the model is used to create tables in the database. - -We declare properties of the class and also configure relationships. - -The models are in `Model` folder. - -We also wish to do some relations that are not automatically done by the framework. - -These configurations are applied to the model and is used to configure how the tables should be created during table creation: -e.g: -``` -public class BookingConfiguration : IEntityTypeConfiguration<Booking> - { - public void Configure(EntityTypeBuilder<Booking> entity) - { - entity.HasOne(d => d.BookingOrder).WithMany(p => p.Bookings) - .HasPrincipalKey(p => p.Id) - .HasForeignKey(d => d.BookingOrderId) - .OnDelete(DeleteBehavior.ClientSetNull); - - entity.HasOne(d => d.FlightInformation).WithMany(p => p.Bookings) - .HasPrincipalKey(p => p.Id) - .HasForeignKey(d => d.FlightId) - .OnDelete(DeleteBehavior.ClientSetNull); - - entity.HasOne(d => d.FlightFare).WithMany(p => p.Bookings) - .HasPrincipalKey(p => p.Id) - .HasForeignKey(d => d.FlightFareId) - .OnDelete(DeleteBehavior.ClientSetNull); - } - } -``` - The above code for the `Booking.cs` model configures the foreign key relationship. - - -To make use of our models, we create a `FlightBookingDbContext.cs` where we declare all our models and also apply the configurations: - -We also added a change in the `OnModelCreating()` method of the `FlightDbContext` to make sure that when a model (data in the database) is updated, the `UpdatedAt` and `CreatedAt` is saved as `UTC`. - -``` -foreach (var entityType in modelBuilder.Model.GetEntityTypes()) - { - foreach (var property in entityType.GetProperties()) - { - if (property.ClrType == typeof(DateTime)) - { - modelBuilder.Entity(entityType.ClrType) - .Property<DateTime>(property.Name) - .HasConversion( - v => v.ToUniversalTime(), - v => DateTime.SpecifyKind(v, DateTimeKind.Utc)); - } - else if (property.ClrType == typeof(DateTime?)) - { - modelBuilder.Entity(entityType.ClrType) - .Property<DateTime?>(property.Name) - .HasConversion( - v => v.HasValue ? v.Value.ToUniversalTime() : v, - v => v.HasValue ? DateTime.SpecifyKind(v.Value, DateTimeKind.Utc) : v); - } - } - } -``` - - -To get our database schema updated: - -Once we have configured our models, and added the `FlightBookingContext`. -We also configure the `FlightBookingContext` in the `ConfigureService` method in our `Startup.cs` and initialize it. - -``` - string mysqlConnectionString = Configuration.GetConnectionString("FlightBookingServiceDb_Mysql")!; - var mySqlServerVersion = new MySqlServerVersion(new Version(8, 0, 36)); - services.AddDbContext<FlightBookingContext>(options => - { - options.UseMySql(mysqlConnectionString, mySqlServerVersion, opt => opt.EnableRetryOnFailure()) - .LogTo(Console.WriteLine, LogLevel.Warning) - .EnableSensitiveDataLogging() - .EnableDetailedErrors(); - }); - -``` -The code indicates that we get our connection string from appsettings.json -To get the version of MySql, run this on the MySql server: - -> SELECT VERSION(); - -Once we have our models, configuration and DbContext ready, we need to run Migrations. - -Migrations take a snapshot of our models and configuration and defines how they will be used to updated the database schema at that point in time. - -To run migrations, open the Package Manager Console and run: - -> Add-Migration InitialCreate - -This will create a migration named `InitialCreateMysql`. - -We then run - ->Update-Database - -This will configure the database with the code generated in `InitialCreateMysql`. - -Whenever we make a change to our models and configuration, we must create a new migration and update our database so that the database schema is kept updated - -If we wish to use a different database, we first configure the DbContext. E.g if using Sql Server: - -``` - services.AddDbContext<FlightBookingContext>(options => - { - options.UseSqlServer(Configuration.GetConnectionString("FlightBookingServiceDb")); - }); - -``` - -Then we must create a new migration. __It is important to note that Migrations are scoped to a database. So we need a new migration when we switched to a different database__ - -To run migrations, open the Package Manager Console and run: - -> Add-Migration InitialCreateMysql - -This will create a migration named `InitialCreateMysql`. - -We then run - ->Update-Database - - -The `ConfigSettings` contains a strongly type mapping of the content of appsettings.json and helps to avoid errors - -Our DTO folder contains DTOs for models. These are basically data structure we use to transfer data around - - -## Running this Project - -1. Open the solution in Visual Studio. Automatically, nugets are installed. - -2. Start your MySql Server. The project currently uses MySql version 8.0.36. If you wish to use a different version, update the version in ``Startup.cs` - -``` - var mySqlServerVersion = new MySqlServerVersion(new Version(8, 0, 36)); -``` - -3. Add your database connection string in appsettings.json and appsettings.Development.json - -3. In Visual Studio, go to Tools -> Nuget Package Manager -> Package Manager Console. Click the Package Manager Console and it open at the bottom - -4. In the Package Manager Console, Run - > Update-Database - - The Database and all tables will be created using the `InitialMysqlMigration` that is included in the Migrations folder. - -5. Press F5 or run the project by clicking the play button. - -6. Included in the project in the `Program.cs` is a method that seeds the database with some default data. The `DatabaseSeeding.cs` contains the code that adds `FlightInformation`, `FlightFares` and `ReservedSeats` - Once you run the project for the first time, if all goes well, the data is added to the database. - - - -Useful Links: -https://github.com/PomeloFoundation/Pomelo.EntityFrameworkCore.MySql -https://learn.microsoft.com/en-us/ef/core/managing-schemas/migrations/providers?tabs=dotnet-core-cli -https://learn.microsoft.com/en-us/ef/core/modeling/relationships -https://learn.microsoft.com/en-us/ef/ef6/fundamentals/working-with-dbcontext - - - - diff --git a/Templates/login-register/login.html b/Templates/login-register/login.html deleted file mode 100644 index 092908ccc5f9ce4e7c31f84b25ec6bd3f07dd3a2..0000000000000000000000000000000000000000 --- a/Templates/login-register/login.html +++ /dev/null @@ -1,31 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -<head> - <meta charset="UTF-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>Airline Booking - Login</title> - <link rel="stylesheet" href="login_register_style.css"> - <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"> - <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script> - <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script> -</head> -<body> - <div class="container"> - <form> - <div class="form-group"> - <label for="exampleInputEmail1">Email address</label> - <input type="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Enter email"> - </div> - <div class="form-group"> - <label for="exampleInputPassword1">Password</label> - <input type="password" class="form-control" id="exampleInputPassword1" placeholder="Password"> - </div> - <div class="form-group form-check"> - <!-- <input type="checkbox" class="form-check-input" id="exampleCheck1"> --> - <!-- <label class="form-check-label" for="exampleCheck1">Check me out</label> --> - </div> - <button type="submit" class="btn btn-primary">Submit</button> - </form> - </div> -</body> -</html> \ No newline at end of file diff --git a/Templates/login-register/login_register_style.css b/Templates/login-register/login_register_style.css deleted file mode 100644 index 51fe1c5f4cf17c3b25ed2b1397b08be2a1046dad..0000000000000000000000000000000000000000 --- a/Templates/login-register/login_register_style.css +++ /dev/null @@ -1,15 +0,0 @@ -form { - width: 30%; - border: 1px solid #ccc; /* Example border: 1px solid with color #ccc */ - padding: 20px; - border-radius: 5px; /* Optional: if you want rounded corners */ - background-color: #ffffff; - -} - -.container { - display: flex; - justify-content: center; - align-items: center; - height: 100vh; -} \ No newline at end of file diff --git a/Templates/login-register/register.html b/Templates/login-register/register.html deleted file mode 100644 index 88252690fc4f234f0faa3399d12a9a320effc4e0..0000000000000000000000000000000000000000 --- a/Templates/login-register/register.html +++ /dev/null @@ -1,36 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -<head> - <meta charset="UTF-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>Airline Booking - Register</title> - <link rel="stylesheet" href="login_register_style.css"> - <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"> - <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script> - <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script> - <script src="register.js"></script> -</head> -<body> - <div class="container"> - <form onsubmit="return checkPasswords()"> - <div class="form-group"> - <label for="inputFullName">Full name</label> - <input type="text" class="form-control" id="inputFullName" placeholder="Full name"> - </div> - <div class="form-group"> - <label for="inputEmail">Email address</label> - <input type="email" class="form-control" id="inputEmail" placeholder="Enter email"> - </div> - <div class="form-group"> - <label for="inputPassword">Password</label> - <input type="password" class="form-control" id="inputPassword" placeholder="Password"> - </div> - <div class="form-group"> - <label for="inputConfirmPassword">Confirm password</label> - <input type="password" class="form-control" id="inputConfirmPassword" placeholder="Confirm Password"> - </div> - <button type="submit" class="btn btn-primary">Submit</button> - </form> - </div> -</body> -</html> \ No newline at end of file diff --git a/Templates/login-register/register.js b/Templates/login-register/register.js deleted file mode 100644 index a4f443ddbcb5f90f6b395c532028511aa0b5ea74..0000000000000000000000000000000000000000 --- a/Templates/login-register/register.js +++ /dev/null @@ -1,15 +0,0 @@ -function checkPasswords() { - var password = document.getElementById('inputPassword').value; - var confirmPassword = document.getElementById('inputConfirmPassword').value; - - if (password === confirmPassword) { - // The passwords match - // You can add code here to handle the form submission - return true; // return true to submit the form - } else { - // The passwords do not match - // Alert the user - alert("The passwords do not match!"); - return false; // return false to prevent form submission - } -} \ No newline at end of file diff --git a/Templates/user_profile/avatar.jpg b/Templates/user_profile/avatar.jpg deleted file mode 100644 index 6cc1140f400c6e47c6ac1ddf985ee188f92c4ae2..0000000000000000000000000000000000000000 Binary files a/Templates/user_profile/avatar.jpg and /dev/null differ diff --git a/Templates/user_profile/profile.css b/Templates/user_profile/profile.css deleted file mode 100644 index 44709d293b4e4371a128b360ee799ddb76f9813c..0000000000000000000000000000000000000000 --- a/Templates/user_profile/profile.css +++ /dev/null @@ -1,53 +0,0 @@ -body{ - margin-top:20px; - color: #1a202c; - text-align: left; - background-color: #e2e8f0; -} -.main-body { - padding: 15px; -} -.card { - box-shadow: 0 1px 3px 0 rgba(0,0,0,.1), 0 1px 2px 0 rgba(0,0,0,.06); -} - -.card { - position: relative; - display: flex; - flex-direction: column; - min-width: 0; - word-wrap: break-word; - background-color: #fff; - background-clip: border-box; - border: 1px solid #ddd; /* Light grey border */ - border-radius: 4px; -} - -.card-body { - flex: 1 1 auto; - min-height: 1px; - padding: 1rem; -} - -.gutters-sm { - margin-right: -8px; - margin-left: -8px; -} - -.gutters-sm>.col, .gutters-sm>[class*=col-] { - padding-right: 8px; - padding-left: 8px; -} -.mb-3, .my-3 { - margin-bottom: 1rem!important; -} - -.bg-gray-300 { - background-color: #e2e8f0; -} -.h-100 { - height: 100%!important; -} -.shadow-none { - box-shadow: none!important; -} \ No newline at end of file diff --git a/Templates/user_profile/profile.html b/Templates/user_profile/profile.html deleted file mode 100644 index 68302e72d1107e459360f835062c811d8b6eab52..0000000000000000000000000000000000000000 --- a/Templates/user_profile/profile.html +++ /dev/null @@ -1,158 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -<head> - <meta charset="UTF-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>Airline Booking - Profile</title> - <link rel="stylesheet" href="profile.css"> - <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"> - <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script> - <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script> - <script src="profile_script.js"></script> -</head> -<body> - <div class="container"> - <div class="main-body"> - - <div class="row gutters-sm"> - <div class="col-md-4 mb-3"> - <div class="card"> - <div class="card-body"> - <div class="d-flex flex-column align-items-center text-center"> - <img src="avatar.jpg" alt="Admin" class="rounded-circle" width="150"> - <div class="mt-3"> - <h4 id="profileName">Illya Globa</h4> - <p class="text-secondary mb-1">Loyal Customer</p> - <p class="text-muted font-size-sm">Guildford</p> - - </div> - </div> - </div> - </div> - </div> - <div class="col-md-8"> - <div class="card mb-3"> - <div class="card-body"> - <div class="row"> - <div class="col-sm-3"> - <h6 class="mb-0">Full Name</h6> - </div> - <div class="col-sm-9 text-secondary"> - <input type="text" id="fullName" class="form-control" value="Illya Globa" readonly> - </div> - </div> - <hr> - <div class="row"> - <div class="col-sm-3"> - <h6 class="mb-0">Email</h6> - </div> - <div class="col-sm-9 text-secondary"> - <input type="email" id="email" class="form-control" value="ig@surrey.ac.uk" readonly> - </div> - </div> - <hr> - <div class="row"> - <div class="col-sm-3"> - <h6 class="mb-0">Password</h6> - </div> - <div class="col-sm-9 text-secondary"> - <input type="password" id="password" class="form-control" value="password" readonly> - </div> - </div> - <hr> - <div class="row"> - <div class="col-sm-12"> - <button class="btn btn-primary" onclick="editProfile()">Edit</button> - </div> - </div> - </div> - </div> - </div> - - </div> - - </div> - <div class="row"> - <div class="col-md-12"> - <h3>Upcoming Flights</h3> - </div> - <div class="col-md-3"> - <div class="card" style="width: 25rem;"> - <div class="card-body"> - <h5 class="card-title">Flight number</h5> - <h6 class="card-subtitle mb-2 text-muted">LTN - MLG</h6> - <p class="card-text">London(LTN) - Spain(MLG)</p> - <a href="#" class="card-link">Card link</a> - <a href="#" class="card-link">Another link</a> - </div> - </div> - </div> - <div class="col-md-3"> - <div class="card" style="width: 25rem;"> - <div class="card-body"> - <h5 class="card-title">Flight number</h5> - <h6 class="card-subtitle mb-2 text-muted">LTN - MLG</h6> - <p class="card-text">London(LTN) - Spain(MLG)</p> - <a href="#" class="card-link">Card link</a> - <a href="#" class="card-link">Another link</a> - </div> - </div> - </div> - <div class="col-md-3"> - <div class="card" style="width: 25rem;"> - <div class="card-body"> - <h5 class="card-title">Flight number</h5> - <h6 class="card-subtitle mb-2 text-muted">LTN - MLG</h6> - <p class="card-text">London(LTN) - Spain(MLG)</p> - <a href="#" class="card-link">Card link</a> - <a href="#" class="card-link">Another link</a> - </div> - </div> - </div> - <!-- If you have another flight card add it here as another .col-md-6 --> - </div> - - <div class="row" style="margin-top: 20px;"> - <div class="col-md-12"> - <h3>Flights History</h3> - </div> - <div class="col-md-3"> - <div class="card" style="width: 25rem;"> - <div class="card-body"> - <h5 class="card-title">Flight number</h5> - <h6 class="card-subtitle mb-2 text-muted">LTN - MLG</h6> - <p class="card-text">London(LTN) - Spain(MLG)</p> - <a href="#" class="card-link">Card link</a> - <a href="#" class="card-link">Another link</a> - </div> - </div> - </div> - <div class="col-md-3"> - <div class="card" style="width: 25rem;"> - <div class="card-body"> - <h5 class="card-title">Flight number</h5> - <h6 class="card-subtitle mb-2 text-muted">LTN - MLG</h6> - <p class="card-text">London(LTN) - Spain(MLG)</p> - <a href="#" class="card-link">Card link</a> - <a href="#" class="card-link">Another link</a> - </div> - </div> - </div> - <div class="col-md-3"> - <div class="card" style="width: 25rem;"> - <div class="card-body"> - <h5 class="card-title">Flight number</h5> - <h6 class="card-subtitle mb-2 text-muted">LTN - MLG</h6> - <p class="card-text">London(LTN) - Spain(MLG)</p> - <a href="#" class="card-link">Card link</a> - <a href="#" class="card-link">Another link</a> - </div> - </div> - </div> - <!-- If you have another flight card add it here as another .col-md-6 --> - </div> - <button style="margin-top: 10px;" type="submit" class="btn btn-primary">View more</button> - </div> - </div> -</body> -</html> \ No newline at end of file diff --git a/Templates/user_profile/profile_script.js b/Templates/user_profile/profile_script.js deleted file mode 100644 index 0a70508a83911d2a9ea0943f159c7e5d093a0580..0000000000000000000000000000000000000000 --- a/Templates/user_profile/profile_script.js +++ /dev/null @@ -1,19 +0,0 @@ -function editProfile() { - // Get the input fields - var fullNameField = document.getElementById('fullName'); - var emailField = document.getElementById('email'); - var passwordField = document.getElementById('password'); - - // Check if the input fields are readonly - if so, make them editable - if (fullNameField.readOnly === true) { - fullNameField.readOnly = false; - emailField.readOnly = false; - passwordField.readOnly = false; - fullNameField.focus(); // Set focus on the name field to start editing - } else { - fullNameField.readOnly = true; - emailField.readOnly = true; - passwordField.readOnly = true; - // Here you can also add an AJAX call to save the data if needed - } -} \ No newline at end of file diff --git a/Templates/user_profile/user.png b/Templates/user_profile/user.png deleted file mode 100644 index 063717636aec642b496d4c65e975311aa01fd429..0000000000000000000000000000000000000000 Binary files a/Templates/user_profile/user.png and /dev/null differ