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);
}
}
}