gehgassi_backend/gehGassi.Web/Controllers/Api/ApiFavouritesController.cs

397 lines
16 KiB
C#

using AutoMapper;
using gehGassi.Core.Interfaces;
using gehGassi.Core.Services;
using gehGassi.Dto.Ratings;
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.Collections.Generic;
using System.Threading.Tasks;
using System;
using System.Linq;
using gehGassi.Domain.Favourites;
using gehGassi.Dto.Favourites;
using gehGassi.Domain.Ratings;
using gehGassi.Dto.Common;
using gehGassi.Dto.Advertisements;
using gehGassi.Dto.Dogs;
using gehGassi.Dto.Listings;
using gehGassi.Dto.Lookup;
using gehGassi.Web.Auth;
using gehGassi.Domain.Dogs;
using Asp.Versioning;
namespace gehGassi.Web.Controllers.Api
{
/// <summary>
/// Controller der die Verwaltung von Favoriten via Api ermöglicht
/// </summary>
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[ApiController]
[ApiVersion(1)]
[Route("api/favourites")]
[Route("api/v{v:apiVersion}/favourites")]
public class ApiFavouritesController : ApiBaseController
{
public const string FavouriteCategory_Advertisement = "Advertisement";
public const string FavouriteCategory_Partner = "Listing";
public const string FavouriteCategory_Walker = "Walker";
public const string FavouriteCategory_Dog = "Dog";
private readonly IFavouriteService _favouriteService;
private readonly IAdvertisementService _advertisementService;
private readonly IListingService _listingService;
private readonly IDogService _dogService;
/// <summary>
/// Erstellt eine Instanz
/// </summary>
/// <param name="mapper">Instanz eines IMapper</param>
/// <param name="localizationOptions">Instanz von LocalizationOptions</param>
/// <param name="appUserService">Instanz eines IAppUserService</param>
/// <param name="favouriteService">Instanz eines IFavouriteService</param>
/// <param name="advertisementService">Instanz eines IAdvertisementService</param>
/// <param name="listingService">Instanz eines IListingService</param>
/// <param name="dogService">Instanz eines IDogService</param>
public ApiFavouritesController(IMapper mapper, IOptions<LocalizationOptions> localizationOptions, IAppUserService appUserService, IFavouriteService favouriteService,
IAdvertisementService advertisementService, IListingService listingService, IDogService dogService) : base(mapper, localizationOptions, appUserService)
{
_favouriteService = favouriteService;
_advertisementService = advertisementService;
_listingService = listingService;
_dogService = dogService;
}
/// <summary>
/// Abfrage der Favoriten eines AppUsers
/// </summary>
/// <param name="appUserId">Id des AppUsers</param>
/// <param name="lastUpdate">Letztes Update oder null, wenn noch keines</param>
/// <returns>Liste der Favoriten</returns>
[HttpGet]
[Route("GetFavouritesForSync")]
public async Task<IActionResult> GetFavouritesForSync(string appUserId, DateTimeOffset? lastUpdate)
{
var clientOffset = GetClientDateOffset();
if (User?.Identity != null && User.Identity.IsAuthenticated)
{
var favourites = await _favouriteService.GetForSyncAppAsync(appUserId, lastUpdate);
var dtoList = Mapper.Map<List<FavouriteDto>>(favourites);
return Ok(dtoList);
}
return NotFound(CommunicationErrors.Common_NotFound);
}
/// <summary>
/// Anlegen eines Favoriten
/// </summary>
/// <param name="model">FavouriteDto</param>
/// <returns>HTTP 200 OK, Felher sonst</returns>
[HttpPost]
[Route("CreateFavourite")]
public async Task<IActionResult> CreateFavourite(FavouriteDto model)
{
var clientOffset = GetClientDateOffset();
var result = new CreateResponseDto<FavouriteDto>
{
Status = CreateStatusDto.Error,
Value = null
};
if (User?.Identity != null && User.Identity.IsAuthenticated)
{
if (ModelState.IsValid)
{
var existingFavourite = await _favouriteService.GetAsync(model.Id);
if (existingFavourite == null)
{
var favourite = Mapper.Map<Favourite>(model);
_favouriteService.Add(favourite);
await _favouriteService.CommitAsync(User.Identity.Name);
result.Status = CreateStatusDto.Success;
result.Value = Mapper.Map<FavouriteDto>(favourite);
}
else
{
result.Status = CreateStatusDto.Exists;
}
return Ok(result);
}
}
return BadRequest(CommunicationErrors.Common_Model_Invalid);
}
/// <summary>
/// Aktualisieren eines Favoriten
/// </summary>
/// <param name="model">FavouriteDto</param>
/// <returns>HTTP 200 OK, Felher sonst</returns>
[HttpPost]
[Route("UpdateFavourite")]
public async Task<IActionResult> UpdateFavourite(FavouriteDto model)
{
var clientOffset = GetClientDateOffset();
if (User?.Identity != null && User.Identity.IsAuthenticated)
{
if (ModelState.IsValid)
{
var favourite = await _favouriteService.GetAsync(model.Id);
if (favourite != null)
{
if (model.UpdatedAt > favourite.UpdatedAt)
{
Mapper.Map(model, favourite);
await _favouriteService.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 Favoriten
/// </summary>
/// <param name="model">FavouriteDto</param>
/// <param name="appUserId">Id des App-Users</param>
/// <returns>200OK</returns>
[HttpPost]
[Route("DeleteFavourite")]
public async Task<IActionResult> DeleteFavourite(FavouriteDto model, [FromQuery] string appUserId)
{
var clientOffset = GetClientDateOffset();
if (User?.Identity != null && User.Identity.IsAuthenticated)
{
if (ModelState.IsValid)
{
var favourite = await _favouriteService.GetAsync(model.Id);
if (favourite != null)
{
var appUser = await AppUserService.GetAsync(appUserId);
if (appUser != null)
{
if (favourite.AppUserId == appUser.Id)
{
_favouriteService.Remove(favourite);
await _favouriteService.CommitAsync(User.Identity.Name);
return Ok();
}
}
}
return NotFound(CommunicationErrors.Common_NotFound);
}
return BadRequest(CommunicationErrors.Common_Model_Invalid);
}
return NotFound(CommunicationErrors.Common_NotFound);
}
/// <summary>
/// Gibt eine Liste von Favoriten für einen Objekttyp und einen AppUser zurück
/// </summary>
/// <param name="model">Abfragemodel</param>
/// <returns>HTTP 200 wenn erfolgreich</returns>
[Route("GetFavouritesList")]
[HttpPost]
public async Task<IActionResult> GetFavouritesList(FavouriteListQueryDto model)
{
var clientOffset = GetClientDateOffset();
if (User?.Identity != null && User.Identity.IsAuthenticated)
{
var appUserId = User.AppUserId();
var list = new List<FavouriteListItemDto>();
var favourites = await _favouriteService.GetForAppUserAsync(model.AppUserId, model.Table);
if (favourites != null && favourites.Any())
{
foreach (var favourite in favourites.OrderByDescending(c => c.Created))
{
switch (favourite.Table)
{
case FavouriteCategory_Advertisement:
list.Add(await GetAdvertisementAsync(favourite, model.Language));
break;
case FavouriteCategory_Partner:
list.Add(await GetListingAsync(favourite, model.Language));
break;
case FavouriteCategory_Dog:
list.Add(await GetDogAsync(favourite, appUserId));
break;
case FavouriteCategory_Walker:
list.Add(await GetDogWalkerAsync(favourite, appUserId));
break;
}
}
}
return Ok(list);
}
return NotFound(CommunicationErrors.Common_NotFound);
}
#region private
/// <summary>
/// Holt eine Werbung zu einem Favoriten
/// </summary>
/// <param name="favourite">Favorit</param>
/// <param name="language">Gewünschte Sprache</param>
/// <returns>FavouriteListItemDto</returns>
private async Task<FavouriteListItemDto> GetAdvertisementAsync(Favourite favourite, string language)
{
var item = new FavouriteListItemDto
{
NotAvailable = true,
Id = favourite.Id,
UpdatedAt = favourite.UpdatedAt,
Deleted = favourite.Deleted,
AppUserId = favourite.AppUserId,
Key = favourite.Key,
Table = favourite.Table,
Created = favourite.Created
};
var advertisement = await _advertisementService.GetRunningWithNamesAsync(favourite.Key, language, LocalizationOptions.Value.DefaultCulture);
if (advertisement != null)
{
var baseAddress = GetBaseAddress();
item.NotAvailable = advertisement.Deleted;
item.Advertisement = Mapper.Map<AdvertisementDto>(advertisement);
if (!string.IsNullOrWhiteSpace(item.Advertisement.Image))
item.Advertisement.Image = $"{baseAddress}/file/documents/thumbnails/{400}/{item.Advertisement.Image}";
if (!string.IsNullOrWhiteSpace(item.Advertisement.ImageLanguage))
item.Advertisement.ImageLanguage = $"{baseAddress}/file/documents/thumbnails/{400}/{item.Advertisement.ImageLanguage}";
}
return item;
}
/// <summary>
/// Holt eine Listung zu einem Favoriten
/// </summary>
/// <param name="favourite">Favorit</param>
/// <param name="language">Gewünschte Sprache</param>
/// <returns>FavouriteListItemDto</returns>
private async Task<FavouriteListItemDto> GetListingAsync(Favourite favourite, string language)
{
var item = new FavouriteListItemDto
{
NotAvailable = true,
Id = favourite.Id,
UpdatedAt = favourite.UpdatedAt,
Deleted = favourite.Deleted,
AppUserId = favourite.AppUserId,
Key = favourite.Key,
Table = favourite.Table,
Created = favourite.Created
};
var listing = await _listingService.GetRunningWithNamesAsync(favourite.Key, language, LocalizationOptions.Value.DefaultCulture);
if (listing != null)
{
var baseAddress = GetBaseAddress();
item.NotAvailable = listing.Deleted;
item.Listing = Mapper.Map<ListingDto>(listing);
if (!string.IsNullOrWhiteSpace(item.Listing.Image))
item.Listing.Image = $"{baseAddress}/file/documents/thumbnails/{200}/{item.Listing.Image}";
if (!string.IsNullOrWhiteSpace(item.Listing.ImageLanguage))
item.Listing.ImageLanguage = $"{baseAddress}/file/documents/thumbnails/{400}/{item.Listing.ImageLanguage}";
}
return item;
}
/// <summary>
/// Holt einen Hund zu einem Favoriten
/// </summary>
/// <param name="favourite">Favorit</param>
/// <param name="appUserId">Id des AppUsers der die Abfrage durchführt</param>
/// <returns>FavouriteListItemDto</returns>
private async Task<FavouriteListItemDto> GetDogAsync(Favourite favourite, string appUserId)
{
var item = new FavouriteListItemDto
{
NotAvailable = true,
Id = favourite.Id,
UpdatedAt = favourite.UpdatedAt,
Deleted = favourite.Deleted,
AppUserId = favourite.AppUserId,
Key = favourite.Key,
Table = favourite.Table,
Created = favourite.Created
};
var dog = await _dogService.GetAsync(favourite.Key);
if (dog != null)
{
var baseAddress = GetBaseAddress();
item.NotAvailable = dog.Deleted;
item.Dog = Mapper.Map<DogDto>(dog);
item.Dog.Photo = !string.IsNullOrWhiteSpace(item.Dog.Photo) ? $"{baseAddress}/file/documents/thumbnails/{400}/{item.Dog.Photo}" : "";
item.Locked = await AppUserService.IsLockedAsync(dog.AppUserId);
item.Blocked = await AppUserService.IsBlockedAsync(appUserId, dog.AppUserId);
}
return item;
}
/// <summary>
/// Holt einen DogWalker zu einem Favoriten
/// </summary>
/// <param name="favourite">Favorit</param>
/// <param name="appUserId">Id des AppUsers der die Abfrage durchführt</param>
/// <returns>FavouriteListItemDto</returns>
private async Task<FavouriteListItemDto> GetDogWalkerAsync(Favourite favourite, string appUserId)
{
var item = new FavouriteListItemDto
{
NotAvailable = true,
Id = favourite.Id,
UpdatedAt = favourite.UpdatedAt,
Deleted = favourite.Deleted,
AppUserId = favourite.AppUserId,
Key = favourite.Key,
Table = favourite.Table,
Created = favourite.Created
};
var dogWalker = await AppUserService.GetWalkerAsync(favourite.Key);
if (dogWalker != null)
{
var baseAddress = GetBaseAddress();
item.NotAvailable = dogWalker.Deleted;
item.DogWalker = Mapper.Map<DogWalkerLookupDto>(dogWalker);
item.DogWalker.Photo = !string.IsNullOrWhiteSpace(item.DogWalker.Photo) ? $"{baseAddress}/file/documents/thumbnails/{400}/{item.DogWalker.Photo}" : "";
item.Locked = await AppUserService.IsLockedAsync(dogWalker.Id);
item.Blocked = await AppUserService.IsBlockedAsync(appUserId, dogWalker.Id);
}
return item;
}
#endregion
}
}