CRUD ended with enum

WORK-WebAPI
David D'ALMEIDA 1 year ago
parent 224f16110f
commit cc255de979

@ -0,0 +1,19 @@
namespace Dto;
public class ActivityDto
{
public int Id { get; set; }
public string Name { get; set; }
public string Type { get; set; }
public DateTime Date { get; set; }
public TimeSpan Duration { get; set; }
public float Distance { get; set; }
public float Elevation { get; set; }
public float AverageSpeed { get; set; }
public int AverageHeartRate { get; set; }
public int Calories { get; set; }
public string Description { get; set; }
public string? Gpx { get; set; }
public string? Image { get; set; }
public int AthleteId { get; set; }
}

@ -0,0 +1,98 @@
using Dto;
using HeartTrackAPI.Request;
using HeartTrackAPI.Responce;
using Microsoft.AspNetCore.Mvc;
using Shared;
using Model;
/*
namespace HeartTrackAPI.Controllers;
[ApiController]
[Route("api/activities")]
public class ActivityController : Controller
{
private readonly IActivityService _activityService;
private readonly ILogger<ActivityController> _logger;
public ActivityController(IActivityService activityService, ILogger<ActivityController> logger)
{
_activityService = activityService;
_logger = logger;
}
[HttpGet]
[ProducesResponseType(typeof(PageResponse<ActivityDto>), 200)]
[ProducesResponseType(400)]
[ProducesResponseType(500)]
public async Task<ActionResult<PageResponse<ActivityDto>>> GetActivities([FromQuery] PageRequest pageRequest)
{
try
{
var totalCount = await _activityService.GetNbItems();
if (pageRequest.Count * pageRequest.Index >= totalCount)
{
_logger.LogError("To many object is asked the max is {totalCount} but the request is superior of ", totalCount);
return BadRequest("To many object is asked the max is : " + totalCount);
}
_logger.LogInformation("Executing {Action} with parameters: {Parameters}", nameof(GetActivities), pageRequest);
// request.OrderingPropertyName
var activities = await _activityService.GetActivities(pageRequest.Index, pageRequest.Count, ActivityOrderCriteria.None, pageRequest.Descending ?? false);
var pageResponse = new PageResponse<UserDto>(pageRequest.Index, pageRequest.Count, totalCount, activities.Select(a => a.ToDto()));
return Ok(pageResponse);
}
catch (Exception e)
{
_logger.LogError(e, "Error while getting all activities");
return StatusCode(500);
}
}
/*
[HttpGet("{id}")]
public async Task<ActionResult<ActivityDto>> GetActivity(int id)
{
var activity = await _activityService.GetActivityByIdAsync(id);
if (activity == null)
{
return NotFound();
}
return Ok(activity.ToDto());
}
[HttpPost]
public async Task<ActionResult<ActivityDto>> PostActivity(ActivityDto activityDto)
{
var activity = activityDto.ToModel();
var result = await _activityService.AddActivity(activity);
if (result == null)
{
return BadRequest();
}
return CreatedAtAction(nameof(GetActivity), new { id = result.Id }, result.ToDto());
}
[HttpPut("{id}")]
public async Task<IActionResult> PutActivity(int id, ActivityDto activityDto)
{
if (id != activityDto.Id)
{
return BadRequest();
}
var activity = activityDto.ToModel();
var result = await _activityService.UpdateActivity(id, activity);
if (result == null)
{
return NotFound();
}
return NoContent();
}
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteActivity(int id)
{
var result = await _activityService.DeleteActivity(id);
if (!result)
{
return NotFound();
}
return NoContent();
}
}*/

@ -12,7 +12,6 @@ namespace HeartTrackAPI.Controllers;
[Route("api/users")] [Route("api/users")]
public class UsersController : Controller public class UsersController : Controller
{ {
// For the moment only support user who are athletes next handle user that are coach or athlete
private readonly ILogger<UsersController> _logger; private readonly ILogger<UsersController> _logger;
private readonly IUserService _userService; private readonly IUserService _userService;
public UsersController(ILogger<UsersController> logger, IUserService usersService) public UsersController(ILogger<UsersController> logger, IUserService usersService)
@ -22,7 +21,7 @@ public class UsersController : Controller
} }
[HttpGet] [HttpGet]
[ProducesResponseType(typeof(IEnumerable<UserDto>), 200)] [ProducesResponseType(typeof(PageResponse<UserDto>), 200)]
[ProducesResponseType(400)] [ProducesResponseType(400)]
[ProducesResponseType(500)] [ProducesResponseType(500)]
public async Task<ActionResult<PageResponse<UserDto>>> GetAllAthletes([FromQuery] PageRequest request) public async Task<ActionResult<PageResponse<UserDto>>> GetAllAthletes([FromQuery] PageRequest request)
@ -35,9 +34,10 @@ public class UsersController : Controller
_logger.LogError("To many object is asked the max is {totalCount} but the request is superior of ", totalCount); _logger.LogError("To many object is asked the max is {totalCount} but the request is superior of ", totalCount);
return BadRequest("To many object is asked the max is : " + totalCount); return BadRequest("To many object is asked the max is : " + totalCount);
} }
_logger.LogInformation("Executing {Action} with parameters: {Parameters}", nameof(GetAllAthletes), null); _logger.LogInformation("Executing {Action} with parameters: {Parameters}", nameof(GetAllAthletes), null);
// request.OrderingPropertyName
var athletes = await _userService.GetUsers(request.Index, request.Count, AthleteOrderCriteria.None, request.Descending ?? false); var athletes = await _userService.GetUsers(request.Index, request.Count, Enum.TryParse(request.OrderingPropertyName, out AthleteOrderCriteria result) ? result : AthleteOrderCriteria.None, request.Descending ?? false);
var pageResponse = new PageResponse<UserDto>(request.Index, request.Count, totalCount, athletes.Select(a => a.ToDto())); var pageResponse = new PageResponse<UserDto>(request.Index, request.Count, totalCount, athletes.Select(a => a.ToDto()));
return Ok(pageResponse); return Ok(pageResponse);
} }
@ -95,7 +95,6 @@ public class UsersController : Controller
[ProducesResponseType(typeof(UserDto), 200)] [ProducesResponseType(typeof(UserDto), 200)]
[ProducesResponseType(404)] [ProducesResponseType(404)]
[ProducesResponseType(500)] [ProducesResponseType(500)]
// need to adapt with coach
public async Task<ActionResult<UserDto>> UpdateUser(int id, [FromBody] UserDto user) public async Task<ActionResult<UserDto>> UpdateUser(int id, [FromBody] UserDto user)
{ {
try try

@ -20,4 +20,10 @@
<ProjectReference Include="..\StubAPI\StubAPI.csproj" /> <ProjectReference Include="..\StubAPI\StubAPI.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json">
<HintPath>..\..\..\..\..\.nuget\packages\newtonsoft.json\13.0.1\lib\netstandard2.0\Newtonsoft.Json.dll</HintPath>
</Reference>
</ItemGroup>
</Project> </Project>

@ -1,9 +1,14 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json.Converters;
using Shared;
namespace HeartTrackAPI.Request; namespace HeartTrackAPI.Request;
public class PageRequest public class PageRequest
{ {
public string? OrderingPropertyName { get; set; } = null;// need to be map on the dto OrderCriteria public string? OrderingPropertyName { get; set; } = null;// need to be map on the dto OrderCriteria
public bool? Descending { get; set; } = false; public bool? Descending { get; set; } = false;
public int Index { get; set; } = 0; public int Index { get; set; } = 0;
public int Count { get; set; } = 5; public int Count { get; set; } = 5;
} }

@ -0,0 +1,68 @@
using System.ComponentModel.DataAnnotations;
namespace Model;
public class Activity
{
public int IdActivity { get; private set; }
public string Type { get; set; }
public DateTime Date { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
private int _effort;
[Range(0, 5)]
public int Effort
{
get => _effort;
set
{
if (value < 0 || value > 5)
{
throw new ArgumentException("Effort must be between 0 and 5.");
}
_effort = value;
}
}
public float Variability { get; set; }
public float Variance { get; set; }
public float StandardDeviation { get; set; }
public float Average { get; set; }
public int Maximum { get; set; }
public int Minimum { get; set; }
public float AverageTemperature { get; set; }
public bool HasAutoPause { get; set; }
public Activity(int idActivity ,string type, DateTime date, DateTime startTime, DateTime endTime,
int effort, float variability, float variance, float standardDeviation,
float average, int maximum, int minimum, float averageTemperature, bool hasAutoPause)
{
IdActivity = idActivity;
Type = type;
Date = date;
StartTime = startTime;
EndTime = endTime;
Effort = effort;
Variability = variability;
Variance = variance;
StandardDeviation = standardDeviation;
Average = average;
Maximum = maximum;
Minimum = minimum;
AverageTemperature = averageTemperature;
HasAutoPause = hasAutoPause;
}
public Activity(){}
public override string ToString()
{
return $"Activity #{IdActivity}: {Type} on {Date:d/M/yyyy} from {StartTime:HH:mm:ss} to {EndTime:HH:mm:ss}" +
$" with an effort of {Effort}/5 and an average temperature of {AverageTemperature}°C" +
$" and a heart rate variability of {Variability} bpm" +
$" and a variance of {Variance} bpm" +
$" and a standard deviation of {StandardDeviation} bpm" +
$" and an average of {Average} bpm" +
$" and a maximum of {Maximum} bpm" +
$" and a minimum of {Minimum} bpm" +
$" and auto pause is {(HasAutoPause ? "enabled" : "disabled")}.";
}
}

@ -0,0 +1,13 @@
using Shared;
namespace Model;
public interface IActivityService
{
public Task<IEnumerable<Activity>> GetActivities(int index, int count, ActivityOrderCriteria criteria, bool descending = false);
public Task<Activity?> GetActivityByIdAsync(int id);
public Task<Activity?> AddActivity(Activity activity);
public Task<Activity?> UpdateActivity(int id, Activity activity);
public Task<bool> DeleteActivity(int id);
public Task<int> GetNbItems();
}

@ -12,5 +12,4 @@ public interface IUserService
public Task<User?> UpdateUser(int id, User user); public Task<User?> UpdateUser(int id, User user);
public Task<bool> DeleteUser(int id); public Task<bool> DeleteUser(int id);
public Task<int> GetNbItems(); public Task<int> GetNbItems();
} }

@ -0,0 +1,16 @@
namespace Shared;
public enum ActivityOrderCriteria
{
None,
ByName,
ByType,
ByDate,
ByDuration,
ByDistance,
ByElevation,
ByAverageSpeed,
ByAverageHeartRate,
ByCalories,
ByDescription
}

@ -16,3 +16,30 @@
} }
/*public AthleteOrderCriteria MapToAthleteOrderCriteria(string orderingPropertyName)
{
switch (orderingPropertyName)
{
case nameof(User.Username):
return AthleteOrderCriteria.ByUsername;
case nameof(User.FirstName):
return AthleteOrderCriteria.ByFirstName;
case nameof(User.LastName):
return AthleteOrderCriteria.ByLastName;
case nameof(User.Sexe):
return AthleteOrderCriteria.BySexe;
case nameof(User.Length):
return AthleteOrderCriteria.ByLength;
case nameof(User.Weight):
return AthleteOrderCriteria.ByWeight;
case nameof(User.DateOfBirth):
return AthleteOrderCriteria.ByDateOfBirth;
case nameof(User.Email):
return AthleteOrderCriteria.ByEmail;
case nameof(User.IsCoach):
return AthleteOrderCriteria.ByIsCoach;
default:
return AthleteOrderCriteria.None;
}
}*/

@ -9,21 +9,21 @@ public class UserService : IUserService
[ [
new User new User
{ {
Id = 1, Username = "Athlete1", ProfilePicture = "default.png", FirstName = "First1", LastName = "Last1", Id = 1, Username = "DoeDoe", ProfilePicture = "https://images.unsplash.com/photo-1682687982134-2ac563b2228b?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D", FirstName = "John", LastName = "Doe",
Sexe = "M", Lenght = 180, Weight = 70, DateOfBirth = new DateTime(1990, 1, 1), Sexe = "M", Lenght = 180, Weight = 70, DateOfBirth = new DateTime(1990, 1, 1),
Email = "athlete1@example.com", Role = new Athlete() Email = "john.doe@example.com", Role = new Athlete()
}, },
new User new User
{ {
Id = 2, Username = "Athlete2", ProfilePicture = "default.png", FirstName = "First2", LastName = "Last2", Id = 2, Username = "SmithSmith", ProfilePicture = "https://images.unsplash.com/photo-1709507779917-242b560288be?q=80&w=2080&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D", FirstName = "Jane", LastName = "Smith",
Sexe = "F", Lenght = 170, Weight = 60, DateOfBirth = new DateTime(1992, 2, 2), Sexe = "F", Lenght = 170, Weight = 60, DateOfBirth = new DateTime(1992, 2, 2),
Email = "athlete2@example.com", Role = new Coach() Email = "athlete2@example.com", Role = new Coach()
}, },
new User new User
{ {
Id = 3, Username = "Athlete3", ProfilePicture = "default.png", FirstName = "First3", LastName = "Last3", Id = 3, Username = "Athlete3", ProfilePicture = "https://plus.unsplash.com/premium_photo-1705091981693-6006f8a20479?q=80&w=1974&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D", FirstName = "First3", LastName = "Last3",
Sexe = "M", Lenght = 190, Weight = 80, DateOfBirth = new DateTime(1994, 3, 3), Email = "ath@ex.fr", Sexe = "M", Lenght = 190, Weight = 80, DateOfBirth = new DateTime(1994, 3, 3), Email = "ath@ex.fr",
Role = new Athlete() Role = new Athlete()
} }
@ -32,9 +32,7 @@ public class UserService : IUserService
public async Task<IEnumerable<User>> GetUsers(int index, int count, AthleteOrderCriteria criteria, public async Task<IEnumerable<User>> GetUsers(int index, int count, AthleteOrderCriteria criteria,
bool descending = false) bool descending = false)
{ => athletes.GetItemsWithFilterAndOrdering(c=>true,index, count, criteria != AthleteOrderCriteria.None ? criteria: null , descending);
throw new NotImplementedException();
}
public async Task<User?> GetUserByIdAsync(int id) public async Task<User?> GetUserByIdAsync(int id)
{ {

@ -36,5 +36,35 @@ public static class Extensions
collection.Add(newItem!); collection.Add(newItem!);
return Task.FromResult<T?>(newItem); return Task.FromResult<T?>(newItem);
} }
public static IEnumerable<T> GetItemsWithFilterAndOrdering<T>(this IEnumerable<T> list, Func<T, bool> filter, int index, int count, Enum? orderCriterium, bool descending = false ) where T : class
{
var filteredList = list.Where(filter);
if(orderCriterium != null)
{
filteredList = filteredList.OrderByCriteria(orderCriterium, descending);
}
return filteredList
.Skip(index * count)
.Take(count);
}
public static IOrderedEnumerable<T> OrderByCriteria<T>(this IEnumerable<T> list, Enum orderCriterium, bool descending = false ) where T : class
{
var orderCriteriumString = orderCriterium.ToString();
if (orderCriteriumString.StartsWith("By"))
{
orderCriteriumString = orderCriteriumString.Substring(2);
}
var propertyInfo = typeof(T).GetProperty(orderCriteriumString);
if (propertyInfo == null)
{
throw new ArgumentException($"No property {orderCriterium} in type {typeof(T)}");
}
return descending ? list.OrderByDescending(x => propertyInfo.GetValue(x)) : list.OrderBy(x => propertyInfo.GetValue(x));
}
} }
Loading…
Cancel
Save