Skip to content
This repository has been archived by the owner on Nov 18, 2020. It is now read-only.

Commit

Permalink
Добавить команду создания брони комнаты
Browse files Browse the repository at this point in the history
  • Loading branch information
nzour committed Dec 7, 2019
1 parent 48b069f commit 545f85f
Show file tree
Hide file tree
Showing 11 changed files with 155 additions and 49 deletions.
12 changes: 12 additions & 0 deletions lib/Common/Extensions/ExpressionExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;

namespace Common.Extensions
{
public static class ExpressionExtension
{
public static bool Between(this DateTime @this, DateTime left, DateTime right)
{
return left <= @this && @this <= right;
}
}
}
39 changes: 0 additions & 39 deletions lib/Common/Extensions/NullAwareExtension.cs

This file was deleted.

1 change: 1 addition & 0 deletions src/Application/Application.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

<ItemGroup>
<PackageReference Include="EmptyConstructor.Fody" Version="2.1.0" />
<PackageReference Include="JetBrains.Annotations" Version="2019.1.3" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0-rc4" />
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Application.CQS.Reservation.Exception;
using Common.Extensions;
using Domain;
using Domain.Entities;
using JetBrains.Annotations;
using NHibernate.Linq;

namespace Application.CQS.Reservation.Command
{
public class CreateReservationCommand : IUserAware
{
public UserEntity? CurrentUser { get; set; }
private IRepository<ReservationEntity> ReservationRepository { get; }
private IRepository<RoomEntity> RoomRepository { get; }
private IRepository<ServiceEntity> ServiceRepository { get; }

public CreateReservationCommand(
IRepository<ReservationEntity> reservationRepository,
IRepository<RoomEntity> roomRepository,
IRepository<ServiceEntity> serviceRepository
)
{
ReservationRepository = reservationRepository;
RoomRepository = roomRepository;
ServiceRepository = serviceRepository;
}

public async Task ExecuteAsync(ReservationInput input)
{
AssertRentDatesValid(input);
await AssertRentDatesNotBusyAsync(input);

var services = await ServiceRepository.FindAll()
.Where(service => input.ServiceIds.Contains(service.Id))
.ToListAsync();

var room = await RoomRepository.GetAsync(input.RoomId);

var reservation = new ReservationEntity(CurrentUser!, room, input.ReservedFrom, input.ReservedTo, services);

await ReservationRepository.SaveAndFlushAsync(reservation);
}

[AssertionMethod]
private void AssertRentDatesValid(ReservationInput input)
{
if (DateTime.Now > input.ReservedTo)
{
throw CreateReservationException.DateToCantBeInPast();
}

if (input.ReservedFrom <= input.ReservedTo)
{
throw CreateReservationException.InvalidDateValues();
}
}

[AssertionMethod]
private async Task AssertRentDatesNotBusyAsync(ReservationInput input)
{
var reservations = ReservationRepository
.FindAll()
.Where(r => input.RoomId == r.Room.Id
&& (input.ReservedFrom.Between(r.ReservedFrom, r.ReservedTo)
|| input.ReservedTo.Between(r.ReservedFrom, r.ReservedTo)));

if (0 != await reservations.CountAsync())
{
throw CreateReservationException.DatesAreBusy();
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Threading.Tasks;
using Application.CQS.Reservation.Exception;
using Domain;
using Domain.Entities;

Expand Down Expand Up @@ -29,7 +30,7 @@ public async Task ExecuteAsync(Guid reservationId)
throw ReservationException.AlreadyExpired();
}

await ReservationRepository.DeleteAsync(reservation);
await ReservationRepository.DeleteAndFlushAsync(reservation);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
namespace Application.CQS.Reservation.Exception
{
public class CreateReservationException : System.Exception
{
public CreateReservationException(string message): base(message)
{
}

public static CreateReservationException DateToCantBeInPast()
{
return new CreateReservationException("Reservatoin date 'From' can't be in past.");
}

public static CreateReservationException InvalidDateValues()
{
return new CreateReservationException("Reservation date 'From' must me smaller than date 'To'.");
}

public static CreateReservationException DatesAreBusy()
{
return new CreateReservationException("Specified rent dates are busy.");
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System;

namespace Application.CQS.Reservation
namespace Application.CQS.Reservation.Exception
{
public class ReservationException : System.Exception
{
Expand Down
21 changes: 21 additions & 0 deletions src/Application/CQS/Reservation/ReservationInput.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;

namespace Application.CQS.Reservation
{
public class ReservationInput
{
public Guid RoomId { get; set; }
public DateTime ReservedFrom { get; set; }
public DateTime ReservedTo { get; set; }
public IEnumerable<Guid> ServiceIds { get; set; }

public ReservationInput(Guid roomId, DateTime reservedFrom, DateTime reservedTo, IEnumerable<Guid> serviceIds)
{
RoomId = roomId;
ReservedFrom = reservedFrom;
ReservedTo = reservedTo;
ServiceIds = serviceIds;
}
}
}
7 changes: 6 additions & 1 deletion src/Domain/Exceptions/ReservationException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,14 @@ public ReservationException(string message): base(message)

public static void AssertDatesValid(DateTime from, DateTime to)
{
if (to < DateTime.Now)
{
throw new ReservationException("Reservation date 'from' can't be in past.");
}

if (from >= to)
{
throw new ReservationException($"Reservation date 'from' must be greater than date 'to'.");
throw new ReservationException("Reservation date 'from' must be greater than date 'to'.");
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/Domain/IRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ public interface IRepository<TEntity> where TEntity : class
TEntity Get(object id);
Task<TEntity> GetAsync(object id);

void Delete(object id);
Task DeleteAsync(object id);
void DeleteAndFlush(object id);
Task DeleteAndFlushAsync(object id);

IQueryable<TEntity> FindAll();
}
Expand Down
13 changes: 10 additions & 3 deletions src/Infrastructure/NHibernate/Repository/Repository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,23 @@ public TEntity Get(object id)

public async Task<TEntity> GetAsync(object id)
{
return await Session.GetAsync<TEntity>(id);
var entity = await Session.GetAsync<TEntity>(id);

if (null == entity)
{
throw new EntityNotFoundException<TEntity>(id);
}

return entity;
}

public void Delete(object id)
public void DeleteAndFlush(object id)
{
Session.Delete(id);
Session.Flush();
}

public async Task DeleteAsync(object id)
public async Task DeleteAndFlushAsync(object id)
{
await Session.DeleteAsync(id);
await Session.FlushAsync();
Expand Down

0 comments on commit 545f85f

Please sign in to comment.