using System; using AutoMapper; using gehGassi.Core.Interfaces; using gehGassi.Core.Services; using gehGassi.Dto.Common; using gehGassi.Dto.Listings; using gehGassi.Dto; using gehGassi.Web.Helper; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using System.Collections.Generic; using System.Threading.Tasks; using gehGassi.Domain.Common; using gehGassi.Dto.Banners; using gehGassi.Web.Auth; using Asp.Versioning; namespace gehGassi.Web.Controllers.Api { /// /// Controller der Zugriff auf News via API ermöglicht /// [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] [ApiController] [ApiVersion(1)] [Route("api/banners")] [Route("api/v{v:apiVersion}/banners")] public class ApiBannerController : ApiBaseController { private readonly ILogger _logger; private readonly IGeoLocationService _geoLocationService; private readonly IBannerService _bannerService; /// /// Erstellt eine Instanz /// /// Instanz eines IMapper /// Instanz eines ILogger /// Instanz von LocalizationOptions /// Instanz eines IDogOwnerService /// Instanz eines IGeoLocationService /// Instanz eines IBannerService public ApiBannerController(IMapper mapper, ILogger logger, IOptions localizationOptions, IAppUserService appUserService, IGeoLocationService geoLocationService, IBannerService bannerService) : base(mapper, localizationOptions, appUserService) { _logger = logger; _geoLocationService = geoLocationService; _bannerService = bannerService; } /// /// Gibt einen Banner für eine Banner-Platzierung zurück /// /// Abfragemodel /// HTTP 200 wenn erfolgreich [Route("GetBanner")] [HttpPost] public async Task GetBanner(BannerQueryDto model) { var clientOffset = GetClientDateOffset(); System.Diagnostics.Debug.WriteLine($"Get Banner Called"); if (User?.Identity != null && User.Identity.IsAuthenticated) { var response = new BannerDto(); //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 bannerFound = await _bannerService.GetBannerForLocationAsync((BannerLocation)model.BannerLocation, model.CurrentBannerId, country, state, model.Location.Lat.Value, model.Location.Lng.Value, model.Language, LocalizationOptions.Value.DefaultCulture); if (bannerFound != null) { var count = await _bannerService.AddViewsAsync(bannerFound.Id, 1, (AppMode)model.AppMode, model.Language, country, state); await _bannerService.CommitAsync("System"); response = Mapper.Map(bannerFound); var baseAddress = GetBaseAddress(); response.Image = $"{baseAddress}/file/documents/{bannerFound.Image}"; return Ok(response); } } return NotFound(CommunicationErrors.Common_NotFound); } /// /// Hinzufügen von Klicks zu einem Banner /// /// Model /// true wenn Klicks hinzugefügt und Banner noch laufend, false wenn der Banner abgelaufen ist, Notfound wenn der Banner nicht gefunden wurde oder nicht mehr läuft [Route("ClickBanner")] [HttpPost] public async Task ClickBanner(BannerClickDto model) { var clientOffset = GetClientDateOffset(); if (User?.Identity != null && User.Identity.IsAuthenticated) { var banner = await _bannerService.GetAsync(model.Id); if (banner != null) { if (banner.Status == BannerStatus.Running) { //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); await _bannerService.AddClicksAsync(banner.Id, model.ClickCount, (AppMode)model.AppMode, model.Language, country, state); await _bannerService.CommitAsync("System"); return Ok(true); } return Ok(false); } } return NotFound(CommunicationErrors.Common_NotFound); } /// /// Hinzufügen von Klicks zu einem Banner /// /// Model /// true wenn Klicks hinzugefügt und Banner noch laufend, false wenn der Banner abgelaufen ist, Notfound wenn der Banner nicht gefunden wurde oder nicht mehr läuft [Route("ViewBanner")] [HttpPost] public async Task ViewBanner(BannerViewDto model) { var clientOffset = GetClientDateOffset(); if (User?.Identity != null && User.Identity.IsAuthenticated) { var banner = await _bannerService.GetAsync(model.Id); if (banner != null) { if (banner.Status == BannerStatus.Running) { //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); await _bannerService.AddViewsAsync(banner.Id, model.ViewCount, (AppMode)model.AppMode, model.Language, country, state).ConfigureAwait(false); await _bannerService.CommitAsync("System"); return Ok(true); } return Ok(false); } } return NotFound(CommunicationErrors.Common_NotFound); } #region Private /// /// Hilfsmethode die aus einer Anfrage Daten für die Geo-Einschränkung von Daten holt. /// Wenn Land oder Bundesland nicht gesendet wurde, dann werden diese vom DogOwner oder DogWalker geholt /// /// Anfrage mit Geo-Info /// Land und Bundesland oder leere strings, wenn nicht möglich internal async Task<(string, string)> GetGeoDataAsync(BannerClickDto model) { var country = model.Location.CountryCode; var state = model.Location.StateCode; if (string.IsNullOrWhiteSpace(model.Location.CountryCode) || string.IsNullOrWhiteSpace(model.Location.StateCode)) { var appUser = await AppUserService.GetAsync(User.AppUserId()); country = appUser.Address.CountryCode; state = appUser.Address.State; } return (country, state); } /// /// Hilfsmethode die aus einer Anfrage Daten für die Geo-Einschränkung von Daten holt. /// Wenn Land oder Bundesland nicht gesendet wurde, dann werden diese vom DogOwner oder DogWalker geholt /// /// Anfrage mit Geo-Info /// Land und Bundesland oder leere strings, wenn nicht möglich internal async Task<(string, string)> GetGeoDataAsync(BannerViewDto model) { var country = model.Location.CountryCode; var state = model.Location.StateCode; if (string.IsNullOrWhiteSpace(model.Location.CountryCode) || string.IsNullOrWhiteSpace(model.Location.StateCode)) { var appUser = await AppUserService.GetAsync(User.AppUserId()); country = appUser.Address.CountryCode; state = appUser.Address.State; } return (country, state); } #endregion } }