350 lines
14 KiB
C#
350 lines
14 KiB
C#
using AutoMapper;
|
|
using gehGassi.Core.Interfaces;
|
|
using gehGassi.Core.Services;
|
|
using gehGassi.Domain.Common;
|
|
using gehGassi.Dto.Walks;
|
|
using gehGassi.Dto;
|
|
using gehGassi.Web.Helper;
|
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.Extensions.Options;
|
|
using System.Threading.Tasks;
|
|
using gehGassi.Dto.Ratings;
|
|
using gehGassi.Domain.Walks;
|
|
using gehGassi.Dto.Common;
|
|
using System.Collections.Generic;
|
|
using System;
|
|
using gehGassi.Domain.Ratings;
|
|
using gehGassi.Domain.Dogs;
|
|
using System.Text.Json;
|
|
using gehGassi.Web.Auth;
|
|
using Asp.Versioning;
|
|
|
|
namespace gehGassi.Web.Controllers.Api
|
|
{
|
|
/// <summary>
|
|
/// Controller der die Verwaltung von Ratings via Api ermöglicht
|
|
/// </summary>
|
|
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
|
|
[ApiController]
|
|
[ApiVersion(1)]
|
|
[Route("api/ratings")]
|
|
[Route("api/v{v:apiVersion}/ratings")]
|
|
public class ApiRatingController : ApiBaseController
|
|
{
|
|
private readonly IRatingService _ratingService;
|
|
|
|
/// <summary>
|
|
/// Erstellt eine Instanz
|
|
/// </summary>
|
|
/// <param name="mapper">Instanz eines IMapper</param>
|
|
/// <param name="localizationOptions">Instanz von LocalizationOptions</param>
|
|
/// <param name="appUserService">Instanz eines IDogOwnerService</param>
|
|
/// <param name="ratingService">Instanz eines IRatingService</param>
|
|
public ApiRatingController(IMapper mapper, IOptions<LocalizationOptions> localizationOptions, IAppUserService appUserService, IRatingService ratingService) : base(mapper, localizationOptions, appUserService)
|
|
{
|
|
_ratingService = ratingService;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Abfrage der Ratings eines AppUsers
|
|
/// </summary>
|
|
/// <param name="appUserId">Id des AppUsers</param>
|
|
/// <param name="lastUpdate">Letztes Update oder null, wenn noch keines</param>
|
|
/// <returns>Liste der Anfragen</returns>
|
|
[HttpGet]
|
|
[Route("GetRatingsForSync")]
|
|
public async Task<IActionResult> GetRatingsForSync(string appUserId, DateTimeOffset? lastUpdate)
|
|
{
|
|
var clientOffset = GetClientDateOffset();
|
|
|
|
if (User?.Identity != null && User.Identity.IsAuthenticated)
|
|
{
|
|
var ratings = await _ratingService.GetForSyncAppAsync(appUserId, lastUpdate);
|
|
var dtoList = Mapper.Map<List<RatingDto>>(ratings);
|
|
return Ok(dtoList);
|
|
}
|
|
|
|
return NotFound(CommunicationErrors.Common_NotFound);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Anlegen eines Ratings
|
|
/// </summary>
|
|
/// <param name="model">RatingDto</param>
|
|
/// <returns>HTTP 200 OK, Felher sonst</returns>
|
|
[HttpPost]
|
|
[Route("CreateRating")]
|
|
public async Task<IActionResult> CreateRating(RatingDto model)
|
|
{
|
|
var clientOffset = GetClientDateOffset();
|
|
|
|
var result = new CreateResponseDto<RatingDto>
|
|
{
|
|
Status = CreateStatusDto.Error,
|
|
Value = null
|
|
};
|
|
|
|
if (User?.Identity != null && User.Identity.IsAuthenticated)
|
|
{
|
|
if (ModelState.IsValid)
|
|
{
|
|
var existingRating = await _ratingService.GetAsync(model.Id);
|
|
if (existingRating == null)
|
|
{
|
|
var rating = Mapper.Map<Rating>(model);
|
|
_ratingService.Add(rating);
|
|
await _ratingService.CommitAsync(User.Identity.Name);
|
|
|
|
await _ratingService.UpdateRatingStatisticsAsync(rating.TargetId, rating.TargetType);
|
|
await _ratingService.CommitAsync(User.Identity.Name);
|
|
|
|
result.Status = CreateStatusDto.Success;
|
|
result.Value = Mapper.Map<RatingDto>(rating);
|
|
}
|
|
else
|
|
{
|
|
result.Status = CreateStatusDto.Exists;
|
|
}
|
|
|
|
return Ok(result);
|
|
}
|
|
}
|
|
|
|
return BadRequest(CommunicationErrors.Common_Model_Invalid);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Aktualisieren eines Ratings
|
|
/// </summary>
|
|
/// <param name="model">RatingDto</param>
|
|
/// <returns>HTTP 200 OK, Felher sonst</returns>
|
|
[HttpPost]
|
|
[Route("UpdateRating")]
|
|
public async Task<IActionResult> UpdateRating(RatingDto model)
|
|
{
|
|
var clientOffset = GetClientDateOffset();
|
|
|
|
if (User?.Identity != null && User.Identity.IsAuthenticated)
|
|
{
|
|
if (ModelState.IsValid)
|
|
{
|
|
var rating = await _ratingService.GetAsync(model.Id);
|
|
if (rating != null)
|
|
{
|
|
if (model.UpdatedAt > rating.UpdatedAt)
|
|
{
|
|
Mapper.Map(model, rating);
|
|
|
|
await _ratingService.CommitAsync(User.Identity.Name);
|
|
|
|
await _ratingService.UpdateRatingStatisticsAsync(rating.TargetId, rating.TargetType);
|
|
await _ratingService.CommitAsync(User.Identity.Name);
|
|
}
|
|
|
|
return Ok();
|
|
}
|
|
return NotFound(CommunicationErrors.Common_NotFound);
|
|
}
|
|
return BadRequest(CommunicationErrors.Common_Model_Invalid);
|
|
}
|
|
return NotFound(CommunicationErrors.Common_NotFound);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Löschen eines Ratings
|
|
/// </summary>
|
|
/// <param name="model">RatingDto</param>
|
|
/// <param name="appUserId">Id des App-Users</param>
|
|
/// <returns>200OK</returns>
|
|
[HttpPost]
|
|
[Route("DeleteRating")]
|
|
public async Task<IActionResult> DeleteRating(RatingDto model, [FromQuery] string appUserId)
|
|
{
|
|
var clientOffset = GetClientDateOffset();
|
|
|
|
if (User?.Identity != null && User.Identity.IsAuthenticated)
|
|
{
|
|
if (ModelState.IsValid)
|
|
{
|
|
var rating = await _ratingService.GetAsync(model.Id);
|
|
if (rating != null)
|
|
{
|
|
var appUser = await AppUserService.GetAsync(appUserId);
|
|
if (appUser != null)
|
|
{
|
|
if (rating.FromId == appUser.Id)
|
|
{
|
|
//TODO: Löschen von verbundenen Daten!
|
|
|
|
_ratingService.Remove(rating);
|
|
await _ratingService.CommitAsync(User.Identity.Name);
|
|
|
|
await _ratingService.UpdateRatingStatisticsAsync(rating.TargetId, rating.TargetType);
|
|
await _ratingService.CommitAsync(User.Identity.Name);
|
|
|
|
return Ok();
|
|
}
|
|
}
|
|
}
|
|
return NotFound(CommunicationErrors.Common_NotFound);
|
|
}
|
|
return BadRequest(CommunicationErrors.Common_Model_Invalid);
|
|
}
|
|
return NotFound(CommunicationErrors.Common_NotFound);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt ein Rating basierend auf Abfragekriterien zurück
|
|
/// </summary>
|
|
/// <param name="model">RatingCheckQueryDto</param>
|
|
/// <returns>HTTP 200 OK BOOL, Felher sonst</returns>
|
|
[HttpPost]
|
|
[Route("GetRatingEx")]
|
|
public async Task<IActionResult> GetRatingEx(RatingCheckQueryDto model)
|
|
{
|
|
var clientOffset = GetClientDateOffset();
|
|
|
|
if (User?.Identity != null && User.Identity.IsAuthenticated)
|
|
{
|
|
if (ModelState.IsValid)
|
|
{
|
|
var rating = await _ratingService.GetRatingExAsync(model.FromId, (AppUserType)model.FromType, model.TargetId, (RatingTarget)model.TargetType);
|
|
if (rating != null)
|
|
{
|
|
var ratingDto = Mapper.Map<RatingDto>(rating);
|
|
return Ok(ratingDto);
|
|
}
|
|
else
|
|
return NotFound(CommunicationErrors.Common_NotFound);
|
|
}
|
|
return BadRequest(CommunicationErrors.Common_Model_Invalid);
|
|
}
|
|
return NotFound(CommunicationErrors.Common_NotFound);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Prüft ob eine Bewertung bereits stattgefunden hat
|
|
/// </summary>
|
|
/// <param name="model">RatingCheckQueryDto</param>
|
|
/// <returns>HTTP 200 OK BOOL, Felher sonst</returns>
|
|
[HttpPost]
|
|
[Route("HasRated")]
|
|
public async Task<IActionResult> HasRated(RatingCheckQueryDto model)
|
|
{
|
|
var clientOffset = GetClientDateOffset();
|
|
|
|
if (User?.Identity != null && User.Identity.IsAuthenticated)
|
|
{
|
|
if (ModelState.IsValid)
|
|
{
|
|
var hasRated = await _ratingService.HasRatedAsync(model.FromId, (AppUserType)model.FromType, model.TargetId, (RatingTarget)model.TargetType);
|
|
return Ok(hasRated);
|
|
}
|
|
return BadRequest(CommunicationErrors.Common_Model_Invalid);
|
|
}
|
|
return NotFound(CommunicationErrors.Common_NotFound);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Prüft ob eine Bewertung vorgenommen werden darf
|
|
/// </summary>
|
|
/// <param name="model">RatingCheckQueryDto</param>
|
|
/// <returns>HTTP 200 OK BOOL, Felher sonst</returns>
|
|
[HttpPost]
|
|
[Route("CanRate")]
|
|
public async Task<IActionResult> CanRate(RatingCheckQueryDto model)
|
|
{
|
|
var clientOffset = GetClientDateOffset();
|
|
|
|
if (User?.Identity != null && User.Identity.IsAuthenticated)
|
|
{
|
|
if (ModelState.IsValid)
|
|
{
|
|
var hasRated = await _ratingService.CanRateAsync(model.FromId, (AppUserType)model.FromType, model.TargetId, (RatingTarget)model.TargetType);
|
|
return Ok(hasRated);
|
|
}
|
|
return BadRequest(CommunicationErrors.Common_Model_Invalid);
|
|
}
|
|
return NotFound(CommunicationErrors.Common_NotFound);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Abfragen von Ratings
|
|
/// </summary>
|
|
/// <param name="model">Abfragemodel</param>
|
|
/// <returns>Liste von Ratings</returns>
|
|
[HttpPost]
|
|
[Route("GetRatings")]
|
|
public async Task<IActionResult> GetRatings(RatingsQueryDto model)
|
|
{
|
|
var clientOffset = GetClientDateOffset();
|
|
|
|
if (User?.Identity != null && User.Identity.IsAuthenticated)
|
|
{
|
|
var baseAddress = GetBaseAddress();
|
|
var response = new ListResponseDto<RatingWithNamesDto>();
|
|
|
|
//Geodaten holen.
|
|
//Entweder wurde lat und lng geliefert, oder wir müssen über den benutzer und den app-mode entscheiden
|
|
//var (country, state) = await GetGeoDataAsync(model);
|
|
var sortList = Mapper.Map<List<DynamicSortOrder>>(model.DynamicSortOrder);
|
|
|
|
var appUserId = User.AppUserId();
|
|
var queryResult = await _ratingService.GetWithNamesExAsync(appUserId, model.FromId, (AppUserType?)model.FromType, model.TargetId, (RatingTarget?)model.TargetType, sortList, model.Skip, model.Take);
|
|
|
|
response.Total = queryResult.total;
|
|
var resultList = queryResult.list;
|
|
|
|
var dtoList = Mapper.Map<List<RatingWithNamesDto>>(resultList);
|
|
|
|
foreach (var dtoItem in dtoList)
|
|
{
|
|
if(!string.IsNullOrWhiteSpace(dtoItem.FromPhoto))
|
|
dtoItem.FromPhoto = $"{baseAddress}/file/documents/thumbnails/{200}/{dtoItem.FromPhoto}";
|
|
if(!string.IsNullOrWhiteSpace(dtoItem.TargetPhoto))
|
|
dtoItem.TargetPhoto = $"{baseAddress}/file/documents/thumbnails/{200}/{dtoItem.TargetPhoto}";
|
|
}
|
|
|
|
response.List = dtoList;
|
|
response.Take = model.Take;
|
|
response.Skip = model.Skip;
|
|
|
|
return Ok(response);
|
|
}
|
|
|
|
return NotFound(CommunicationErrors.Common_NotFound);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt ein Rating anhand der Id zurück
|
|
/// </summary>
|
|
/// <param name="ratingId">Id der Bewertung</param>
|
|
/// <returns>200 OK - Rating wenn gefunden, NOTFOUND sonst</returns>
|
|
[HttpGet]
|
|
[Route("GetRating")]
|
|
public async Task<IActionResult> GetRating(string ratingId)
|
|
{
|
|
var clientOffset = GetClientDateOffset();
|
|
|
|
if (User?.Identity != null && User.Identity.IsAuthenticated)
|
|
{
|
|
var baseAddress = GetBaseAddress();
|
|
var rating = await _ratingService.GetWithNamesAsync(ratingId);
|
|
if (rating != null)
|
|
{
|
|
var ratingDto = Mapper.Map<RatingWithNamesDto>(rating);
|
|
if (!string.IsNullOrWhiteSpace(ratingDto.FromPhoto))
|
|
ratingDto.FromPhoto = $"{baseAddress}/file/documents/thumbnails/{400}/{ratingDto.FromPhoto}";
|
|
if (!string.IsNullOrWhiteSpace(ratingDto.TargetPhoto))
|
|
ratingDto.TargetPhoto = $"{baseAddress}/file/documents/thumbnails/{400}/{ratingDto.TargetPhoto}";
|
|
|
|
return Ok(ratingDto);
|
|
}
|
|
}
|
|
return NotFound(CommunicationErrors.Common_NotFound);
|
|
}
|
|
}
|
|
}
|