Skip to content
Snippets Groups Projects
Commit eef983c5 authored by Abdelsamad, Mouaz R (UG - SISC)'s avatar Abdelsamad, Mouaz R (UG - SISC)
Browse files

remove these......

parent dfb49f2b
No related branches found
No related tags found
No related merge requests found
Showing
with 0 additions and 1063 deletions
## 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
<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>
namespace FlightBooking.Service.Tests
{
public class UnitTest1
{
[Fact]
public void Test1()
{
}
}
}
\ No newline at end of file

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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment