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 { /// /// Controller der die Verwaltung von Favoriten via Api ermöglicht /// [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; /// /// Erstellt eine Instanz /// /// Instanz eines IMapper /// Instanz von LocalizationOptions /// Instanz eines IAppUserService /// Instanz eines IFavouriteService /// Instanz eines IAdvertisementService /// Instanz eines IListingService /// Instanz eines IDogService public ApiFavouritesController(IMapper mapper, IOptions localizationOptions, IAppUserService appUserService, IFavouriteService favouriteService, IAdvertisementService advertisementService, IListingService listingService, IDogService dogService) : base(mapper, localizationOptions, appUserService) { _favouriteService = favouriteService; _advertisementService = advertisementService; _listingService = listingService; _dogService = dogService; } /// /// Abfrage der Favoriten eines AppUsers /// /// Id des AppUsers /// Letztes Update oder null, wenn noch keines /// Liste der Favoriten [HttpGet] [Route("GetFavouritesForSync")] public async Task 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>(favourites); return Ok(dtoList); } return NotFound(CommunicationErrors.Common_NotFound); } /// /// Anlegen eines Favoriten /// /// FavouriteDto /// HTTP 200 OK, Felher sonst [HttpPost] [Route("CreateFavourite")] public async Task CreateFavourite(FavouriteDto model) { var clientOffset = GetClientDateOffset(); var result = new CreateResponseDto { 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(model); _favouriteService.Add(favourite); await _favouriteService.CommitAsync(User.Identity.Name); result.Status = CreateStatusDto.Success; result.Value = Mapper.Map(favourite); } else { result.Status = CreateStatusDto.Exists; } return Ok(result); } } return BadRequest(CommunicationErrors.Common_Model_Invalid); } /// /// Aktualisieren eines Favoriten /// /// FavouriteDto /// HTTP 200 OK, Felher sonst [HttpPost] [Route("UpdateFavourite")] public async Task 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); } /// /// Löschen eines Favoriten /// /// FavouriteDto /// Id des App-Users /// 200OK [HttpPost] [Route("DeleteFavourite")] public async Task 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); } /// /// Gibt eine Liste von Favoriten für einen Objekttyp und einen AppUser zurück /// /// Abfragemodel /// HTTP 200 wenn erfolgreich [Route("GetFavouritesList")] [HttpPost] public async Task GetFavouritesList(FavouriteListQueryDto model) { var clientOffset = GetClientDateOffset(); if (User?.Identity != null && User.Identity.IsAuthenticated) { var appUserId = User.AppUserId(); var list = new List(); 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 /// /// Holt eine Werbung zu einem Favoriten /// /// Favorit /// Gewünschte Sprache /// FavouriteListItemDto private async Task 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(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; } /// /// Holt eine Listung zu einem Favoriten /// /// Favorit /// Gewünschte Sprache /// FavouriteListItemDto private async Task 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(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; } /// /// Holt einen Hund zu einem Favoriten /// /// Favorit /// Id des AppUsers der die Abfrage durchführt /// FavouriteListItemDto private async Task 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(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; } /// /// Holt einen DogWalker zu einem Favoriten /// /// Favorit /// Id des AppUsers der die Abfrage durchführt /// FavouriteListItemDto private async Task 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(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 } }