using System; using Asp.Versioning; using AutoMapper; using gehGassi.Core.Interfaces; 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.Threading.Tasks; using gehGassi.Dto.Common; using gehGassi.Dto; using System.Collections.Generic; using gehGassi.Domain.Common; using gehGassi.Dto.Subscriptions; using gehGassi.Web.Auth; namespace gehGassi.Web.Controllers.Api { /// /// Controller für die Verwaltung von Abonnements /// [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] [ApiController] [ApiVersion(1)] [Route("api/subscriptions")] [Route("api/v{v:apiVersion}/subscriptions")] public class ApiSubscriptionController : ApiBaseController { private readonly ILogger _logger; private readonly ISubscriptionService _subscriptionService; /// /// Erstellt eine Instanz /// /// Instanz eines IMapper /// Instanz eines ILogger /// Instanz von LocalizationOptions /// Instanz eines IAppUserService /// Instanz eines ISubscriptionService public ApiSubscriptionController(IMapper mapper, ILogger logger, IOptions localizationOptions, IAppUserService appUserService, ISubscriptionService subscriptionService) : base(mapper, localizationOptions, appUserService) { _logger = logger; _subscriptionService = subscriptionService; } /// /// Gibt alle Abonnements zurück für einen AppMode /// /// AppMode /// Sprache /// HTTP 200 OK wenn erfolgreich [HttpGet] [Route("GetAll")] public async Task GetSubscriptions(AppModeDto appMode, string language) { var clientOffset = GetClientDateOffset(); if (User?.Identity != null && User.Identity.IsAuthenticated) { var subscriptions = await _subscriptionService.GetAllAsync((AppMode)appMode, language, LocalizationOptions.Value.DefaultCulture); var subscriptionsDto = Mapper.Map>(subscriptions); return Ok(subscriptionsDto); } return NotFound(CommunicationErrors.Common_NotFound); } /// /// Gibt alle Abonnement-Buchungen für einen AppUser zurück /// /// Sprache /// HTTP 200 OK wenn erfolgreich [HttpGet] [Route("GetMy")] public async Task GetMySubscriptions(string language) { var clientOffset = GetClientDateOffset(); if (User?.Identity != null && User.Identity.IsAuthenticated) { var appUserId = User.AppUserId(); var subscriptions = await _subscriptionService.GetAllAppUserSubscriptionsAsync(appUserId, language, LocalizationOptions.Value.DefaultCulture); var subscriptionsDto = Mapper.Map>(subscriptions); return Ok(subscriptionsDto); } return NotFound(CommunicationErrors.Common_NotFound); } /// /// Gibt alle Abonnement-Buchungen für einen AppUser zurück /// /// Sprache /// HTTP 200 OK wenn erfolgreich [HttpGet] [Route("GetMy/active")] public async Task GetMyActiveSubscriptions(string language) { var clientOffset = GetClientDateOffset(); if (User?.Identity != null && User.Identity.IsAuthenticated) { var appUserId = User.AppUserId(); var subscriptions = await _subscriptionService.GetAllAppUserSubscriptionsValidAsync(appUserId, language, LocalizationOptions.Value.DefaultCulture); var subscriptionsDto = Mapper.Map>(subscriptions); return Ok(subscriptionsDto); } return NotFound(CommunicationErrors.Common_NotFound); } /// /// Anlegen einer Abonnement-Buchung /// /// AppUserCreateSubscriptionDto /// HTTP 200 OK, Felher sonst [HttpPost] [Route("Create")] public async Task CreateSubscription(AppUserCreateSubscriptionDto model) { var clientOffset = GetClientDateOffset(); var result = new CreateResponseDto { Status = CreateStatusDto.Error, Value = null }; if (User?.Identity != null && User.Identity.IsAuthenticated) { if (ModelState.IsValid) { var appUserId = User.AppUserId(); if (appUserId == model.AppUserId) { var subscription = await _subscriptionService.GetAsync(model.SubscriptionId); if (subscription != null) { //Prüfen ob der Benutzer bereits ein Abonnement hat var hasExistingBooking = await _subscriptionService.AppUserHasActiveBookingAsync(appUserId, subscription.AppMode); if (!hasExistingBooking) { var appUserSubscription = _subscriptionService.CreateAppUserSubscription(); appUserSubscription.AppUserId = model.AppUserId; appUserSubscription.SubscriptionId = model.SubscriptionId; appUserSubscription.IsValid = true; if (model.ExpirationDateToSet.HasValue) { appUserSubscription.ExpirationDate = subscription.GetExpiration(model.ExpirationDateToSet.Value); appUserSubscription.ExpirationDateWithGrace = subscription.GetExpirationWithGrace(model.ExpirationDateToSet.Value); } else { appUserSubscription.ExpirationDate = subscription.GetExpiration(DateTimeOffset.UtcNow); appUserSubscription.ExpirationDateWithGrace = subscription.GetExpirationWithGrace(DateTimeOffset.UtcNow); } appUserSubscription.Manual = false; appUserSubscription.Platform = (Platform)model.Platform; appUserSubscription.InAppBillingPurchaseJson = model.InAppBillingPurchaseJson; appUserSubscription.CreatedBy = User.Identity.Name; appUserSubscription.Created = DateTimeOffset.UtcNow; _subscriptionService.AddAppUserSubscription(appUserSubscription); await _subscriptionService.CommitAsync(User.Identity.Name); var addedBooking = await _subscriptionService.GetAppUserSubscriptionAsync(appUserSubscription.Id, model.Language, LocalizationOptions.Value.DefaultCulture); var addedBookingDto = Mapper.Map(addedBooking); result.Status = CreateStatusDto.Success; result.Value = addedBookingDto; } else { result.Status = CreateStatusDto.Exists; } return Ok(result); } } } } return BadRequest(CommunicationErrors.Common_Model_Invalid); } /// /// Wechseln eines Abonnements /// /// AppUserSwitchSubscriptionDto /// HTTP 200 OK, Felher sonst [HttpPost] [Route("Switch")] public async Task SwitchSubscription(AppUserSwitchSubscriptionDto model) { var clientOffset = GetClientDateOffset(); if (User?.Identity != null && User.Identity.IsAuthenticated) { if (ModelState.IsValid) { var booking = await _subscriptionService.GetAppUserSubscriptionAsync(model.BookingId); if (booking != null) { if (booking.IsValid) { var currentSubscription = await _subscriptionService.GetAsync(booking.SubscriptionId); var subscription = await _subscriptionService.GetAsync(model.SubscriptionId); if (subscription != null && currentSubscription != null) { if (subscription.Id != currentSubscription.Id) { if (subscription.AppMode == currentSubscription.AppMode) { booking.SubscriptionId = model.SubscriptionId; booking.ExpirationDate = subscription.GetExpiration(DateTimeOffset.UtcNow); booking.LastRenewalDate = DateTimeOffset.UtcNow; booking.LastUpdate = DateTimeOffset.UtcNow; await _subscriptionService.CommitAsync(User.Identity.Name); var changedBooking = await _subscriptionService.GetAppUserSubscriptionAsync(booking.Id, model.Language, LocalizationOptions.Value.DefaultCulture); var changedBookingDto = Mapper.Map(changedBooking); return Ok(changedBookingDto); } return BadRequest(CommunicationErrors.Subscription_AppModeMismatch); } return BadRequest(CommunicationErrors.Subscription_NoChange); } return NotFound(CommunicationErrors.Subscription_NotFound); } return BadRequest(CommunicationErrors.Subscription_Invalid); } return NotFound(CommunicationErrors.Common_NotFound); } return BadRequest(CommunicationErrors.Common_Model_Invalid); } return NotFound(CommunicationErrors.Common_NotFound); } /// /// Stornieren eines Abonnements /// /// AppUserCancelSubscriptionDto /// HTTP 200 OK, Felher sonst [HttpPost] [Route("Cancel")] public async Task CancelSubscription(AppUserCancelSubscriptionDto model) { var clientOffset = GetClientDateOffset(); if (User?.Identity != null && User.Identity.IsAuthenticated) { if (ModelState.IsValid) { var booking = await _subscriptionService.GetAppUserSubscriptionAsync(model.BookingId); if (booking != null) { if (booking.IsValid && booking.Platform == (Platform)model.Platform) { booking.IsValid = false; booking.LastUpdate = DateTimeOffset.UtcNow; booking.ExpirationDate = DateTimeOffset.UtcNow; booking.ExpirationDateWithGrace = DateTimeOffset.UtcNow; await _subscriptionService.CommitAsync(User.Identity.Name); var changedBooking = await _subscriptionService.GetAppUserSubscriptionAsync(booking.Id, model.Language, LocalizationOptions.Value.DefaultCulture); var changedBookingDto = Mapper.Map(changedBooking); return Ok(changedBookingDto); } return BadRequest(CommunicationErrors.Subscription_Invalid); } return NotFound(CommunicationErrors.Common_NotFound); } return BadRequest(CommunicationErrors.Common_Model_Invalid); } return NotFound(CommunicationErrors.Common_NotFound); } /// /// Verlängern eines Abonnements /// /// AppUserRenewSubscriptionDto /// HTTP 200 OK, Felher sonst [HttpPost] [Route("Renew")] public async Task RenewSubscription(AppUserRenewSubscriptionDto model) { var clientOffset = GetClientDateOffset(); if (User?.Identity != null && User.Identity.IsAuthenticated) { if (ModelState.IsValid) { var booking = await _subscriptionService.GetAppUserSubscriptionAsync(model.BookingId); if (booking != null) { if (booking.IsValid && booking.Platform == (Platform)model.Platform) { var subscription = await _subscriptionService.GetAsync(booking.SubscriptionId); if (subscription != null) { booking.LastUpdate = DateTimeOffset.UtcNow; booking.LastRenewalDate = DateTimeOffset.UtcNow; booking.ExpirationDate = subscription.GetExpiration(DateTimeOffset.UtcNow); await _subscriptionService.CommitAsync(User.Identity.Name); var changedBooking = await _subscriptionService.GetAppUserSubscriptionAsync(booking.Id, model.Language, LocalizationOptions.Value.DefaultCulture); var changedBookingDto = Mapper.Map(changedBooking); return Ok(changedBookingDto); } return BadRequest(CommunicationErrors.Subscription_NotFound); } return BadRequest(CommunicationErrors.Subscription_Invalid); } return NotFound(CommunicationErrors.Common_NotFound); } return BadRequest(CommunicationErrors.Common_Model_Invalid); } return NotFound(CommunicationErrors.Common_NotFound); } } }