Skip to content

Commit

Permalink
feat: allow for reserving
Browse files Browse the repository at this point in the history
  • Loading branch information
kirinnee committed Dec 18, 2023
1 parent 2ddf421 commit d35424f
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 1 deletion.
14 changes: 14 additions & 0 deletions App/Modules/Bookings/API/V1/BookingController.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Net.Mime;
using App.Error.V1;
using App.Modules.Common;
using App.Modules.Timings.API.V1;
using App.StartUp.Registry;
using App.StartUp.Services.Auth;
using App.Utility;
Expand All @@ -21,6 +22,7 @@ public class BookingController(
IBookingService service,
CreateBookingReqValidator createBookingReqValidator,
BookingSearchQueryValidator bookingSearchQueryValidator,
ReserveBookingQueryValidator reserveBookingQueryValidator,
IAuthHelper authHelper,
ILogger<BookingController> logger,
IBookingImageEnricher enrich
Expand All @@ -39,6 +41,18 @@ public async Task<ActionResult<IEnumerable<BookingPrincipalRes>>> Search([FromQu
return this.ReturnResult(x);
}

[Authorize(Policy = AuthPolicies.AdminOrTin)]
[HttpGet("reserve/{Direction}/{Date}/{Time}")]
public async Task<ActionResult<BookingPrincipalRes>> Reserve([FromRoute] ReserveBookingQuery query)
{
var book = await reserveBookingQueryValidator.ValidateAsyncResult(query, "Invalid ReserveBookingQuery")
.ThenAwait(q => service.Reserve(
q.Direction.DirectionToDomain(), q.Date.ToDate(), q.Time.ToTime()))
.Then(x => x?.ToRes(), Errors.MapAll)
.ThenAwait(x => Utils.ToNullableTaskResultOr(x, r => enrich.Enrich(r)));
return this.ReturnNullableResult(book, new EntityNotFound("Booking not found", typeof(Booking), $"{query.Direction}-{query.Date}-{query.Time}"));
}

[Authorize, HttpGet("{userId}/{id:guid}")]
public async Task<ActionResult<BookingRes>> Get(string userId, Guid id)
{
Expand Down
2 changes: 2 additions & 0 deletions App/Modules/Bookings/API/V1/BookingModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ namespace App.Modules.Bookings.API.V1;

public record SearchBookingQuery(string? Date, string? Direction, string? Time, string? UserId, int? Limit, int? Skip);

public record ReserveBookingQuery(string Date, string Direction, string Time);

// REQ
public record BookingPassengerReq(string FullName, string Gender, string PassportExpiry, string PassportNumber);

Expand Down
14 changes: 14 additions & 0 deletions App/Modules/Bookings/API/V1/BookingValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,17 @@ public BookingSearchQueryValidator()
.Skip();
}
}

public class ReserveBookingQueryValidator : AbstractValidator<ReserveBookingQuery>
{
public ReserveBookingQueryValidator()
{
this.RuleFor(x => x.Date)
.DateValid();
this.RuleFor(x => x.Time)
.TimeValid();
this.RuleFor(x => x.Direction)
.NotNull()
.TrainDirectionValid();
}
}
27 changes: 27 additions & 0 deletions App/Modules/Bookings/Data/BookingRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using App.Utility;
using CSharp_Result;
using Domain.Booking;
using Domain.Timings;
using EntityFramework.Exceptions.Common;
using Microsoft.EntityFrameworkCore;

Expand Down Expand Up @@ -156,6 +157,32 @@ public async Task<Result<BookingPrincipal>> Create(string userId, BookingRecord
}
}

public async Task<Result<BookingPrincipal?>> Reserve(TrainDirection direction, DateOnly date, TimeOnly time)
{
try
{
logger.LogInformation("Reserve Booking '{direction}' '{Date}' '{Time}'", direction, date, time);

var v1 = await db.Bookings
.Where(x =>
x.Direction == direction.ToData()
&& x.Date == date
&& x.Time == time
&& x.Status == (int)BookStatus.Pending
)
.OrderBy(x => x.CreatedAt)
.FirstOrDefaultAsync();
return v1?.ToPrincipal();
}

catch (Exception e)
{
logger.LogError(e, "Failed to reserve Booking '{direction}' '{Date}' '{Time}'", direction,
date, time);
return e;
}
}

public async Task<Result<Unit?>> Delete(string? userId, Guid id)
{
try
Expand Down
3 changes: 3 additions & 0 deletions Domain/Booking/IService.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using CSharp_Result;
using Domain.Timings;

namespace Domain.Booking;

Expand All @@ -12,6 +13,8 @@ public interface IBookingService

Task<Result<BookingPrincipal?>> Update(string? userId, Guid id, BookingRecord record);

Task<Result<BookingPrincipal?>> Reserve(TrainDirection direction, DateOnly date, TimeOnly time);

Task<Result<BookingPrincipal?>> Buying(Guid id);

Task<Result<BookingPrincipal?>> Complete(Guid id, Stream ticketFile);
Expand Down
2 changes: 2 additions & 0 deletions Domain/Booking/Model.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ public enum BookStatus
Cancelled = 3,
}



public record BookingSearch
{
public DateOnly? Date { get; init; }
Expand Down
6 changes: 5 additions & 1 deletion Domain/Booking/Repository.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using CSharp_Result;
using Domain.Timings;

namespace Domain.Booking;

Expand All @@ -10,7 +11,10 @@ public interface IBookingRepository

Task<Result<BookingPrincipal>> Create(string userId, BookingRecord record);

Task<Result<BookingPrincipal?>> Update(string? userId, Guid id, BookingStatus? status, BookingRecord? record, BookingComplete? complete);
Task<Result<BookingPrincipal?>> Update(string? userId, Guid id, BookingStatus? status, BookingRecord? record,
BookingComplete? complete);

Task<Result<BookingPrincipal?>> Reserve(TrainDirection direction, DateOnly date, TimeOnly Time);

Task<Result<Unit?>> Delete(string? userId, Guid id);

Expand Down
6 changes: 6 additions & 0 deletions Domain/Booking/Service.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using CSharp_Result;
using Domain.Timings;
using Microsoft.Extensions.Logging;

namespace Domain.Booking;
Expand Down Expand Up @@ -26,6 +27,11 @@ public Task<Result<BookingPrincipal>> Create(string userId, BookingRecord record
return repo.Update(userId, id, null, record, null);
}

public Task<Result<BookingPrincipal?>> Reserve(TrainDirection direction, DateOnly date, TimeOnly time)
{
return repo.Reserve(direction, date, time);
}

public Task<Result<BookingPrincipal?>> Buying(Guid id)
{
return repo.Update(null, id, new BookingStatus() { Status = BookStatus.Buying, CompletedAt = null }, null, null);
Expand Down

0 comments on commit d35424f

Please sign in to comment.