Skip to content

Commit a055504

Browse files
authored
Merge pull request #21 from anycode-pk/FixRating
Fix ratings
2 parents 570539f + 2134981 commit a055504

File tree

7 files changed

+71
-19
lines changed

7 files changed

+71
-19
lines changed

TableBooking.Api/Controllers/RatingController.cs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
namespace TableBooking.Api.Controllers
77
{
8+
using System.Security.Claims;
89

910
[Route("[controller]")]
1011
[ApiController]
@@ -18,9 +19,9 @@ public RatingController(IRatingService ratingService)
1819
}
1920

2021
[HttpGet("GetAllRatings")]
21-
public async Task<IActionResult> GetRatings([FromQuery] Guid restuarantId)
22+
public async Task<IActionResult> GetRatings([FromQuery] Guid restaurantId)
2223
{
23-
return await _ratingService.GetAllRatingsAsync(restuarantId);
24+
return await _ratingService.GetAllRatingsAsync(restaurantId);
2425
}
2526

2627
[HttpGet("GetRating/{id}")]
@@ -32,6 +33,19 @@ public async Task<IActionResult> GetRatingById(Guid id)
3233
[HttpPost("CreateRating")]
3334
public async Task<IActionResult> CreateRating([FromBody] CreateRatingDto createRatingDto)
3435
{
36+
if (createRatingDto.AppUserId.HasValue)
37+
return await _ratingService.CreateRatingAsync(createRatingDto);
38+
39+
var userIdString = User.FindFirstValue(ClaimTypes.NameIdentifier);
40+
41+
if (string.IsNullOrEmpty(userIdString))
42+
return BadRequest("User ID could not be determined from the claims.");
43+
44+
if (!Guid.TryParse(userIdString, out var userId))
45+
return BadRequest("Invalid User ID format in claims.");
46+
47+
createRatingDto.AppUserId = userId;
48+
3549
return await _ratingService.CreateRatingAsync(createRatingDto);
3650
}
3751

TableBooking.Api/Services/RatingService.cs

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
namespace TableBooking.Api.Services
99
{
10+
using Microsoft.AspNetCore.Http.HttpResults;
11+
1012
public class RatingService : IRatingService
1113
{
1214
private IUnitOfWork _unitOfWork;
@@ -19,32 +21,52 @@ public RatingService(IUnitOfWork unitOfWork, IRatingConverter ratingConverter)
1921
}
2022
public async Task<IActionResult> CreateRatingAsync(CreateRatingDto dto)
2123
{
22-
var user = await _unitOfWork.UserRepository.GetByIdAsync(dto.AppUserId);
24+
var user = await _unitOfWork.UserRepository.GetByIdAsync(dto.AppUserId!.Value);
2325
var restaurant = await _unitOfWork.RestaurantRepository.GetByIdAsync(dto.RestaurantId);
24-
if (user == null || restaurant == null) return new BadRequestObjectResult(string.Empty);
26+
27+
if (user == null)
28+
return new NotFoundObjectResult($"User with id {dto.AppUserId.Value} not found.");
29+
30+
if (restaurant == null)
31+
return new NotFoundObjectResult($"Restaurant with id {dto.RestaurantId} not found.");
32+
33+
if (dto.RatingStars < 1 || dto.RatingStars > 5)
34+
{
35+
return new BadRequestObjectResult("Rating must be between 1 and 5.");
36+
}
37+
38+
var existingRating = await _unitOfWork.RatingRepository.GetRatingByUserIdAsync(dto.AppUserId.Value, dto.RestaurantId);
2539

40+
if (existingRating != null)
41+
{
42+
return new BadRequestObjectResult("You have already submitted a review for this restaurant.");
43+
}
44+
2645
var rating = new Rating
2746
{
47+
Id = Guid.NewGuid(),
2848
RatingStars = dto.RatingStars,
29-
Comment = dto.Comment,
30-
DateOfRating = dto.DateOfRating,
49+
Comment = dto.Comment ?? string.Empty,
50+
DateOfRating = DateTime.UtcNow,
3151
RestaurantId = dto.RestaurantId,
32-
AppUserId = dto.AppUserId
52+
AppUserId = dto.AppUserId.Value
3353
};
3454

3555
await _unitOfWork.RatingRepository.InsertAsync(rating);
3656
await _unitOfWork.SaveChangesAsync();
3757
var ratings = await _unitOfWork.RatingRepository.GetRatingsAsync(dto.RestaurantId) ;
38-
var numberOfRaitings = ratings.Count();
39-
var result = 0d;
58+
var enumerable = ratings.ToList();
59+
var numberOfRatings = enumerable.Count;
4060

41-
if (numberOfRaitings > 0 && numberOfRaitings % 5 == 0)
42-
{
43-
result = ratings.Select(x => x.RatingStars).Average();
44-
restaurant.Rating = result;
45-
await _unitOfWork.RestaurantRepository.Update(restaurant);
46-
await _unitOfWork.SaveChangesAsync();
47-
}
61+
if (numberOfRatings <= 0) return new OkObjectResult(_ratingConverter.RatingToRatingDto(rating));
62+
63+
var averageRating = enumerable.Select(x => x.RatingStars).Average();
64+
var roundedRating = Math.Round(averageRating, 0, MidpointRounding.AwayFromZero);
65+
66+
67+
restaurant.Rating = (int)roundedRating;
68+
await _unitOfWork.RestaurantRepository.Update(restaurant);
69+
await _unitOfWork.SaveChangesAsync();
4870

4971
return new OkObjectResult(_ratingConverter.RatingToRatingDto(rating));
5072
}

TableBooking.Logic/Interfaces/IRatingRepository.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ namespace TableBooking.Logic.Interfaces
55
public interface IRatingRepository : IGenericRepository<Rating>
66
{
77
Task<IEnumerable<Rating>> GetRatingsAsync(Guid restaurantId);
8+
Task<Rating?> GetRatingByUserIdAsync(Guid userId, Guid restaurantId);
89
Task<Rating> GetRating(Guid id);
910
}
1011
}

TableBooking.Logic/Interfaces/IRestaurantRepository.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ namespace TableBooking.Logic.Interfaces
55
public interface IRestaurantRepository : IGenericRepository<Restaurant>
66
{
77
public Task<IEnumerable<Restaurant>> GetRestaurantsAsync(string? restaurantName, Price? price);
8+
public Task<IEnumerable<Guid>> GetAllRestaurantIds();
89
}
910
}

TableBooking.Logic/Repositories/RatingRepository.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@ public async Task<IEnumerable<Rating>> GetRatingsAsync(Guid restaurantId)
1818
.Where(x => x.RestaurantId.Equals(restaurantId)).ToListAsync();
1919
}
2020

21+
public async Task<Rating?> GetRatingByUserIdAsync(Guid userId, Guid restaurantId)
22+
{
23+
return await _objectSet
24+
.Include(x => x.Restaurant)
25+
.Include(x => x.AppUser)
26+
.FirstOrDefaultAsync(x => x.AppUserId == userId && x.RestaurantId == restaurantId);
27+
}
28+
2129
public async Task<Rating> GetRating(Guid id)
2230
{
2331
return await _objectSet

TableBooking.Logic/Repositories/RestaurantRepository.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,12 @@ public async Task<IEnumerable<Restaurant>> GetRestaurantsAsync(string? restauran
1818
.FilterByPrice(price)
1919
.ToListAsync();
2020
}
21+
22+
public async Task<IEnumerable<Guid>> GetAllRestaurantIds()
23+
{
24+
return await _objectSet
25+
.Select(r => r.Id)
26+
.ToListAsync();
27+
}
2128
}
2229
}

TableBooking.Model/Dtos/RatingDtos/CreateRatingDto.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@
33
public class CreateRatingDto
44
{
55
public int RatingStars { get; set; }
6-
public string Comment { get; set; }
7-
public DateTime DateOfRating { get; set; }
6+
public string? Comment { get; set; } = string.Empty;
87
public Guid RestaurantId { get; set; }
9-
public Guid AppUserId { get; set; }
8+
public Guid? AppUserId { get; set; }
109
}
1110
}

0 commit comments

Comments
 (0)