Skip to content

Commit f665072

Browse files
authored
Merge pull request #23 from anycode-pk/overall-fixes
Overall fixes
2 parents f8a33ee + 084466d commit f665072

File tree

17 files changed

+564
-27
lines changed

17 files changed

+564
-27
lines changed

TableBooking.Api/Controllers/BookingController.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ public async Task<IActionResult> CreateUserBooking([FromBody] CreateBookingDto b
5050

5151
return await _bookingService.CreateBookingAsync(bookingToCreateDto, userId, tableId);
5252
}
53+
54+
[HttpPost("CreateBookingAutomatically/{restaurantId}")]
55+
public async Task<IActionResult> CreateUserBookingAutomaticByRestaurantId([FromBody] CreateBookingDto bookingToCreateDto, Guid restaurantId)
56+
{
57+
var userId = Guid.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier) ?? throw new InvalidOperationException("User ID not found in claims."));
58+
59+
return await _bookingService.CreateAutomaticBookingByRestaurantIdAsync(bookingToCreateDto, userId, restaurantId);
60+
}
5361

5462
[HttpPut("UpdateBooking/{bookingId}")]
5563
public async Task<IActionResult> UpdateUserBooking([FromBody] UpdateBookingDto updateBookingDto, Guid bookingId)

TableBooking.Api/Controllers/RestaurantController.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@ public async Task<IActionResult> GetRestaurantByTableId(Guid tableId)
4242
[Authorize]
4343
public async Task<IActionResult> CreateRestaurant([FromBody] RestaurantShortInfoDto restaurantShortInfoDto)
4444
{
45+
var allowedPrices = Enum.GetValues(typeof(Price)).Cast<Price>();
46+
47+
if (!allowedPrices.Contains(restaurantShortInfoDto.Price))
48+
{
49+
var allowedValues = string.Join(", ", allowedPrices.Select(p => $"{p} = {(int)p}"));
50+
return BadRequest($"Price must be one of the following: {allowedValues}. Request sent: {restaurantShortInfoDto.Price} is wrong.");
51+
}
52+
4553
return await _restaurantService.CreateRestaurantAsync(restaurantShortInfoDto);
4654
}
4755

@@ -56,6 +64,14 @@ public async Task<IActionResult> DeleteRestaurant(Guid restaurantId)
5664
[Authorize]
5765
public async Task<IActionResult> UpdateRestaurant([FromBody] RestaurantShortInfoDto restaurantShortInfoDto, Guid restaurantId)
5866
{
67+
var allowedPrices = Enum.GetValues(typeof(Price)).Cast<Price>();
68+
69+
if (!allowedPrices.Contains(restaurantShortInfoDto.Price))
70+
{
71+
var allowedValues = string.Join(", ", allowedPrices.Select(p => $"{p} = {(int)p}"));
72+
return BadRequest($"Price must be one of the following: {allowedValues}. Request sent: {restaurantShortInfoDto.Price} is wrong.");
73+
}
74+
5975
return await _restaurantService.UpdateRestaurantAsync(restaurantShortInfoDto, restaurantId);
6076
}
6177
}

TableBooking.Api/Interfaces/IBookingService.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ public interface IBookingService
88
public Task<IActionResult> GetAllBookings(Guid userId);
99
public Task<IActionResult> GetBookingByIdAsync(Guid bookingId, Guid userId);
1010
public Task<IActionResult> CreateBookingAsync(CreateBookingDto createBookingDto, Guid userId, Guid tableId);
11+
public Task<IActionResult> CreateAutomaticBookingByRestaurantIdAsync(CreateBookingDto createBookingDto, Guid userId, Guid restaurantId);
1112
public Task<IActionResult> UpdateBookingAsync(UpdateBookingDto updateBookingDto, Guid userId, Guid bookingId);
1213
public Task<IActionResult> DeleteBookingAsync(Guid bookingId, Guid userId);
1314
}

TableBooking.Api/Services/BookingService.cs

Lines changed: 70 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ public async Task<IActionResult> CreateBookingAsync(CreateBookingDto request, Gu
2828
DurationInMinutes = request.DurationInMinutes,
2929
TableId = table.Id,
3030
AppUserId = userId,
31-
AmountOfPeople = request.AmountOfPeople
31+
AmountOfPeople = request.AmountOfPeople,
32+
Id = Guid.NewGuid(),
33+
RestaurantId = table.RestaurantId
3234
};
3335

3436
await _unitOfWork.BookingRepository.InsertAsync(newBooking);
@@ -40,11 +42,50 @@ public async Task<IActionResult> CreateBookingAsync(CreateBookingDto request, Gu
4042
Date = newBooking.Date,
4143
DurationInMinutes = newBooking.DurationInMinutes,
4244
AmountOfPeople = newBooking.AmountOfPeople,
43-
AppUserId = userId
45+
AppUserId = userId,
46+
RestaurantId = newBooking.RestaurantId
47+
};
48+
return new CreatedResult(string.Empty, bookingDto);
49+
}
50+
51+
public async Task<IActionResult> CreateAutomaticBookingByRestaurantIdAsync(CreateBookingDto createBookingDto, Guid userId, Guid restaurantId)
52+
{
53+
// TODO: Assign 17:30 and not like 17:36:35Z ...
54+
var availableTable = await _unitOfWork.TableRepository.GetAvailableTableAsync(restaurantId, createBookingDto.AmountOfPeople, createBookingDto.Date);
55+
56+
if (availableTable == null)
57+
{
58+
return new BadRequestObjectResult($"No available table for {createBookingDto.AmountOfPeople} people at restaurant {restaurantId}");
59+
}
60+
61+
var newBooking = new Booking
62+
{
63+
Date = createBookingDto.Date,
64+
DurationInMinutes = createBookingDto.DurationInMinutes,
65+
TableId = availableTable.Id,
66+
AppUserId = userId,
67+
AmountOfPeople = createBookingDto.AmountOfPeople,
68+
Id = Guid.NewGuid(),
69+
RestaurantId = availableTable.RestaurantId
70+
};
71+
72+
await _unitOfWork.BookingRepository.InsertAsync(newBooking);
73+
await _unitOfWork.SaveChangesAsync();
74+
75+
var bookingDto = new BookingDto
76+
{
77+
Id = newBooking.Id,
78+
Date = newBooking.Date,
79+
DurationInMinutes = newBooking.DurationInMinutes,
80+
AmountOfPeople = newBooking.AmountOfPeople,
81+
AppUserId = userId,
82+
RestaurantId = newBooking.RestaurantId
4483
};
84+
4585
return new CreatedResult(string.Empty, bookingDto);
4686
}
4787

88+
4889
public async Task<IActionResult> DeleteBookingAsync(Guid bookingId, Guid userId)
4990
{
5091
var booking = await _unitOfWork.BookingRepository.GetBookingByIdForSpecificUserAsync(bookingId, userId);
@@ -59,25 +100,46 @@ public async Task<IActionResult> DeleteBookingAsync(Guid bookingId, Guid userId)
59100

60101
public async Task<IActionResult> GetBookingByIdAsync(Guid bookingId, Guid userId)
61102
{
62-
63103
var booking = await _unitOfWork.BookingRepository.GetBookingByIdForSpecificUserAsync(bookingId, userId);
64104

65105
if (booking == null)
66106
return new BadRequestObjectResult("Bad request: no bookings");
107+
108+
if (booking.RestaurantId == Guid.Empty)
109+
{
110+
var restaurantId= await _unitOfWork.TableRepository.GetRestaurantIdByTableIdAsync(booking.TableId);
111+
112+
booking.RestaurantId = restaurantId;
113+
await _unitOfWork.BookingRepository.Update(booking);
114+
}
115+
67116
var bookingDto = new BookingDto
68117
{
69118
Id = booking.Id,
70119
Date = booking.Date,
71120
DurationInMinutes = booking.DurationInMinutes,
72121
AmountOfPeople = booking.AmountOfPeople,
73-
AppUserId = userId
122+
AppUserId = userId,
123+
RestaurantId = booking.RestaurantId
74124
};
75125
return new OkObjectResult(bookingDto);
76126
}
77127

78128
public async Task<IActionResult> GetAllBookings(Guid userId)
79129
{
80130
var bookings = await _unitOfWork.BookingRepository.GetAllBookingsForSpecificUserAsync(userId);
131+
132+
foreach (var booking in bookings)
133+
{
134+
if (booking.RestaurantId == Guid.Empty)
135+
{
136+
137+
var restaurantId= await _unitOfWork.TableRepository.GetRestaurantIdByTableIdAsync(booking.TableId);
138+
139+
booking.RestaurantId = restaurantId;
140+
await _unitOfWork.BookingRepository.Update(booking);
141+
}
142+
}
81143

82144
return new OkObjectResult(bookings);
83145
}
@@ -87,6 +149,8 @@ public async Task<IActionResult> UpdateBookingAsync(UpdateBookingDto updateBooki
87149
var booking = await _unitOfWork.BookingRepository.GetBookingByIdForSpecificUserAsync(bookingId, userId);
88150
if (booking == null)
89151
return new BadRequestObjectResult($"Booking with id {bookingId} doesn't exist.");
152+
153+
// TODO: change tableId when user changed amount of people.
90154

91155
var newBooking = new Booking
92156
{
@@ -95,7 +159,8 @@ public async Task<IActionResult> UpdateBookingAsync(UpdateBookingDto updateBooki
95159
DurationInMinutes = updateBookingDto.DurationInMinutes,
96160
AmountOfPeople = updateBookingDto.AmountOfPeople,
97161
TableId = booking.TableId,
98-
AppUserId = userId
162+
AppUserId = userId,
163+
RestaurantId = booking.RestaurantId
99164
};
100165

101166
await _unitOfWork.BookingRepository.Update(newBooking);

TableBooking.Api/Services/UserService.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,15 @@ public async Task<IActionResult> Register(UserRegisterDto dto)
3636
{
3737
var userExists = await _userManager.FindByNameAsync(dto.Username);
3838
if (userExists != null)
39-
return new BadRequestObjectResult("Bad request: Registration failed");
39+
return new BadRequestObjectResult($"User with the same username found: {dto.Username}.");
40+
41+
var emailExists = await _userManager.FindByEmailAsync(dto.Email);
42+
if (emailExists != null)
43+
return new BadRequestObjectResult($"User with the same email found: {dto.Email}.");
4044

4145
var appUserRole = await _roleManager.FindByIdAsync(UserRoleId);
4246
if (appUserRole == null)
43-
return new BadRequestObjectResult("Bad request: Registration failed");
47+
return new BadRequestObjectResult($"Can't find role by UserRoleId: {UserRoleId}");
4448

4549
var user = new AppUser
4650
{
@@ -51,6 +55,7 @@ public async Task<IActionResult> Register(UserRegisterDto dto)
5155
};
5256

5357
var result = await _userManager.CreateAsync(user, dto.Password);
58+
5459
if (!result.Succeeded)
5560
return new BadRequestObjectResult("Invalid password lenght Or Bad Email");
5661

TableBooking.Logic/Interfaces/ITableRepository.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,7 @@
55
public interface ITableRepository : IGenericRepository<Table>
66
{
77
Task<IEnumerable<Table>> GetTablesByRestaurantIdAsync(Guid restaurantId);
8+
Task<Table?> GetAvailableTableAsync(Guid restaurantId, int amountOfPeople, DateTime bookingDate);
89
Task<Table> GetTableByTableIdAsync(Guid tableId);
10+
Task<Guid> GetRestaurantIdByTableIdAsync(Guid tableId);
911
}

TableBooking.Logic/Repositories/GenericRepository.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,14 @@ public async Task Update(T entity)
5454

5555
if (existingEntity != null)
5656
{
57-
_context.Entry(existingEntity).State = EntityState.Detached;
57+
_context.Entry(existingEntity).CurrentValues.SetValues(entity);
58+
}
59+
else
60+
{
61+
ObjectSet.Add(entity);
5862
}
5963

60-
ObjectSet.Update(entity);
64+
await _context.SaveChangesAsync();
6165
}
6266

6367
private object[] GetKeyValues(T entity)

TableBooking.Logic/Repositories/TableRepository.cs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,21 @@ public async Task<IEnumerable<Table>> GetTablesByRestaurantIdAsync(Guid restaura
1717
.ToListAsync();
1818
}
1919

20+
public async Task<Table?> GetAvailableTableAsync(Guid restaurantId, int amountOfPeople, DateTime bookingDate)
21+
{
22+
return await ObjectSet.Where(t =>
23+
t.Bookings != null && t.RestaurantId == restaurantId && t.NumberOfSeats >= amountOfPeople && t.Bookings.All(b => b.Date != bookingDate)).FirstOrDefaultAsync();
24+
}
25+
2026
public async Task<Table> GetTableByTableIdAsync(Guid tableId)
2127
{
22-
return (await ObjectSet.FirstOrDefaultAsync(t => t.Id == tableId))!;
23-
}
28+
return (await ObjectSet.FirstOrDefaultAsync(t => t.Id == tableId))!;
29+
}
30+
31+
public async Task<Guid> GetRestaurantIdByTableIdAsync(Guid tableId)
32+
{
33+
var table = await ObjectSet.FirstOrDefaultAsync(t => t.Id == tableId);
34+
35+
return table?.RestaurantId ?? Guid.Empty;
36+
}
2437
}

TableBooking.Model/Dtos/BookingDtos/BookingDto.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ public class BookingDto
77
public int DurationInMinutes { get; set; }
88
public int AmountOfPeople { get; set; }
99
public Guid AppUserId { get; set; }
10+
public Guid RestaurantId { get; set; }
1011
}

0 commit comments

Comments
 (0)