Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ public async Task<CreateReservationOutput> Handle(
?? throw new InvalidOperationException("Guest not found");

var period = new DateRange(request.StartDate, request.EndDate);
// Lock pessimista: bloquear os registros de disponibilidade até que a transação seja comitada
var inventories = await roomTypeInventoryRepository.GetInventoryForPeriodAsync(
request.HotelId, request.RoomTypeId, period, cancellationToken);

if (!HasSufficientInventory(inventories, period, request.RoomQuantity))
{
throw new InvalidOperationException("Not enough rooms available for the requested period");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@

namespace FC4.HotelReservation.Reservations.Domain.Entities;

public class RoomTypeInventory : AggregateRoot
public class RoomTypeInventory : AggregateRoot, IVersioned
{
public Guid HotelId { get; private set; }
public Guid RoomTypeId { get; private set; }
public DateTime Date { get; private set; }
public int TotalInventory { get; private set; }
public int TotalReserved { get; private set; }
public int Version { get; private set; }

private RoomTypeInventory()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,17 @@ public async Task<List<RoomTypeInventory>> GetInventoryForPeriodAsync(
DateRange period,
CancellationToken cancellationToken)
{
var dates = period.GetDates().ToList();
var dates = period.GetDates().Select(d => d.ToString("yyyy-MM-dd")).ToList();
var datesLiteral = string.Join(", ", dates.Select(d => $"'{d}'::date"));

var sql = $@"SELECT * FROM room_type_inventory
WHERE hotel_id = {{0}}
AND room_type_id = {{1}}
AND date IN ({datesLiteral})";

return await context.RoomTypeInventories
.Where(i => i.HotelId == hotelId &&
i.RoomTypeId == roomTypeId &&
dates.Contains(i.Date))
.FromSqlRaw(sql, hotelId, roomTypeId)
.AsTracking()
.ToListAsync(cancellationToken);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
namespace FC4.HotelReservation.Shared.Application.Exceptions;

public class ConflictException(string message, Exception innerException) : Exception(message, innerException);
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace FC4.HotelReservation.Shared.Domain;

public interface IVersioned
{
int Version { get; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ public void Configure(EntityTypeBuilder<RoomTypeInventory> builder)
builder.Property(rti => rti.TotalReserved)
.HasColumnName("total_reserved")
.IsRequired();

builder.Property(rti => rti.Version)
.HasColumnName("version")
.IsConcurrencyToken();

builder.HasOne<Hotel>()
.WithMany()
Expand Down
Loading