353 lines
11 KiB
C#
353 lines
11 KiB
C#
using Zentral.API.Services;
|
|
using Zentral.Domain.Entities;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
namespace Zentral.API.Controllers;
|
|
|
|
/// <summary>
|
|
/// Controller per la gestione delle applicazioni e delle subscription
|
|
/// </summary>
|
|
[ApiController]
|
|
[Route("api/[controller]")]
|
|
public class AppsController : ControllerBase
|
|
{
|
|
private readonly AppService _appService;
|
|
private readonly ILogger<AppsController> _logger;
|
|
|
|
public AppsController(AppService appService, ILogger<AppsController> logger)
|
|
{
|
|
_appService = appService;
|
|
_logger = logger;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ottiene tutte le applicazioni disponibili con stato subscription
|
|
/// </summary>
|
|
[HttpGet]
|
|
public async Task<ActionResult<List<AppDto>>> GetAllApps()
|
|
{
|
|
var apps = await _appService.GetAllAppsAsync();
|
|
return Ok(apps.Select(MapToDto).ToList());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ottiene solo le applicazioni attive (per costruzione menu)
|
|
/// </summary>
|
|
[HttpGet("active")]
|
|
public async Task<ActionResult<List<AppDto>>> GetActiveApps()
|
|
{
|
|
var apps = await _appService.GetActiveAppsAsync();
|
|
return Ok(apps.Select(MapToDto).ToList());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ottiene un'applicazione specifica per codice
|
|
/// </summary>
|
|
[HttpGet("{code}")]
|
|
public async Task<ActionResult<AppDto>> GetApp(string code)
|
|
{
|
|
var app = await _appService.GetAppByCodeAsync(code);
|
|
if (app == null)
|
|
return NotFound(new { message = $"Applicazione '{code}' non trovata" });
|
|
|
|
return Ok(MapToDto(app));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Verifica se un'applicazione è abilitata
|
|
/// </summary>
|
|
[HttpGet("{code}/enabled")]
|
|
public async Task<ActionResult<AppStatusDto>> IsAppEnabled(string code)
|
|
{
|
|
var app = await _appService.GetAppByCodeAsync(code);
|
|
if (app == null)
|
|
return NotFound(new { message = $"Applicazione '{code}' non trovata" });
|
|
|
|
var isEnabled = await _appService.IsAppEnabledAsync(code);
|
|
var hasValidSubscription = await _appService.HasValidSubscriptionAsync(code);
|
|
|
|
return Ok(new AppStatusDto
|
|
{
|
|
Code = code,
|
|
IsEnabled = isEnabled,
|
|
HasValidSubscription = hasValidSubscription,
|
|
IsCore = app.IsCore,
|
|
DaysRemaining = app.Subscription?.GetDaysRemaining(),
|
|
IsExpiringSoon = app.Subscription?.IsExpiringSoon() ?? false
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// Attiva un'applicazione
|
|
/// </summary>
|
|
[HttpPut("{code}/enable")]
|
|
public async Task<ActionResult<AppSubscriptionDto>> EnableApp(string code, [FromBody] EnableAppRequest request)
|
|
{
|
|
try
|
|
{
|
|
var subscription = await _appService.EnableAppAsync(
|
|
code,
|
|
request.SubscriptionType,
|
|
request.StartDate,
|
|
request.EndDate,
|
|
request.AutoRenew,
|
|
request.PaidPrice,
|
|
request.Notes);
|
|
|
|
return Ok(MapSubscriptionToDto(subscription));
|
|
}
|
|
catch (ArgumentException ex)
|
|
{
|
|
return NotFound(new { message = ex.Message });
|
|
}
|
|
catch (InvalidOperationException ex)
|
|
{
|
|
return BadRequest(new { message = ex.Message });
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Disattiva un'applicazione
|
|
/// </summary>
|
|
[HttpPut("{code}/disable")]
|
|
public async Task<ActionResult> DisableApp(string code)
|
|
{
|
|
try
|
|
{
|
|
await _appService.DisableAppAsync(code);
|
|
return Ok(new { message = $"Applicazione '{code}' disattivata" });
|
|
}
|
|
catch (ArgumentException ex)
|
|
{
|
|
return NotFound(new { message = ex.Message });
|
|
}
|
|
catch (InvalidOperationException ex)
|
|
{
|
|
return BadRequest(new { message = ex.Message });
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ottiene tutte le subscription
|
|
/// </summary>
|
|
[HttpGet("subscriptions")]
|
|
public async Task<ActionResult<List<AppSubscriptionDto>>> GetAllAppSubscriptions()
|
|
{
|
|
var subscriptions = await _appService.GetAllSubscriptionsAsync();
|
|
return Ok(subscriptions.Select(MapSubscriptionToDto).ToList());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Aggiorna la subscription di un'applicazione
|
|
/// </summary>
|
|
[HttpPut("{code}/subscription")]
|
|
public async Task<ActionResult<AppSubscriptionDto>> UpdateAppSubscription(string code, [FromBody] UpdateAppSubscriptionRequest request)
|
|
{
|
|
try
|
|
{
|
|
var subscription = await _appService.UpdateSubscriptionAsync(
|
|
code,
|
|
request.SubscriptionType,
|
|
request.EndDate,
|
|
request.AutoRenew,
|
|
request.Notes);
|
|
|
|
return Ok(MapSubscriptionToDto(subscription));
|
|
}
|
|
catch (ArgumentException ex)
|
|
{
|
|
return NotFound(new { message = ex.Message });
|
|
}
|
|
catch (InvalidOperationException ex)
|
|
{
|
|
return BadRequest(new { message = ex.Message });
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Rinnova la subscription di un'applicazione
|
|
/// </summary>
|
|
[HttpPost("{code}/subscription/renew")]
|
|
public async Task<ActionResult<AppSubscriptionDto>> RenewAppSubscription(string code, [FromBody] RenewAppSubscriptionRequest? request = null)
|
|
{
|
|
try
|
|
{
|
|
var subscription = await _appService.RenewSubscriptionAsync(code, request?.PaidPrice);
|
|
return Ok(MapSubscriptionToDto(subscription));
|
|
}
|
|
catch (ArgumentException ex)
|
|
{
|
|
return NotFound(new { message = ex.Message });
|
|
}
|
|
catch (InvalidOperationException ex)
|
|
{
|
|
return BadRequest(new { message = ex.Message });
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ottiene le applicazioni in scadenza
|
|
/// </summary>
|
|
[HttpGet("expiring")]
|
|
public async Task<ActionResult<List<AppDto>>> GetExpiringApps([FromQuery] int daysThreshold = 30)
|
|
{
|
|
var apps = await _appService.GetExpiringAppsAsync(daysThreshold);
|
|
return Ok(apps.Select(MapToDto).ToList());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Inizializza le applicazioni di default (per setup iniziale)
|
|
/// </summary>
|
|
[HttpPost("seed")]
|
|
public async Task<ActionResult> SeedDefaultApps()
|
|
{
|
|
await _appService.SeedDefaultAppsAsync();
|
|
return Ok(new { message = "Applicazioni di default inizializzate" });
|
|
}
|
|
|
|
/// <summary>
|
|
/// Forza il controllo delle subscription scadute
|
|
/// </summary>
|
|
[HttpPost("check-expired")]
|
|
public async Task<ActionResult> CheckExpiredAppSubscriptions()
|
|
{
|
|
var count = await _appService.CheckExpiredSubscriptionsAsync();
|
|
return Ok(new { message = $"Controllate le subscription, {count} applicazioni disattivate per scadenza" });
|
|
}
|
|
|
|
/// <summary>
|
|
/// Invalida la cache delle applicazioni
|
|
/// </summary>
|
|
[HttpPost("invalidate-cache")]
|
|
public ActionResult InvalidateAppsCache()
|
|
{
|
|
_appService.InvalidateCache();
|
|
return Ok(new { message = "Cache applicazioni invalidata" });
|
|
}
|
|
|
|
#region Mapping
|
|
|
|
private static AppDto MapToDto(App app)
|
|
{
|
|
return new AppDto
|
|
{
|
|
Id = app.Id,
|
|
Code = app.Code,
|
|
Name = app.Name,
|
|
Description = app.Description,
|
|
Icon = app.Icon,
|
|
BasePrice = app.BasePrice,
|
|
MonthlyPrice = app.GetMonthlyPrice(),
|
|
MonthlyMultiplier = app.MonthlyMultiplier,
|
|
SortOrder = app.SortOrder,
|
|
IsCore = app.IsCore,
|
|
Dependencies = app.GetDependencies().ToList(),
|
|
RoutePath = app.RoutePath,
|
|
IsAvailable = app.IsAvailable,
|
|
IsEnabled = app.IsCore || ((app.Subscription?.IsEnabled ?? false) && (app.Subscription?.IsValid() ?? false)),
|
|
Subscription = app.Subscription != null ? MapSubscriptionToDto(app.Subscription) : null
|
|
};
|
|
}
|
|
|
|
private static AppSubscriptionDto MapSubscriptionToDto(AppSubscription subscription)
|
|
{
|
|
return new AppSubscriptionDto
|
|
{
|
|
Id = subscription.Id,
|
|
AppId = subscription.AppId,
|
|
AppCode = subscription.App?.Code,
|
|
AppName = subscription.App?.Name,
|
|
IsEnabled = subscription.IsEnabled,
|
|
SubscriptionType = subscription.SubscriptionType,
|
|
SubscriptionTypeName = subscription.SubscriptionType.ToString(),
|
|
StartDate = subscription.StartDate,
|
|
EndDate = subscription.EndDate,
|
|
AutoRenew = subscription.AutoRenew,
|
|
Notes = subscription.Notes,
|
|
LastRenewalDate = subscription.LastRenewalDate,
|
|
PaidPrice = subscription.PaidPrice,
|
|
IsValid = subscription.IsValid(),
|
|
DaysRemaining = subscription.GetDaysRemaining(),
|
|
IsExpiringSoon = subscription.IsExpiringSoon()
|
|
};
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
#region DTOs
|
|
|
|
public class AppDto
|
|
{
|
|
public int Id { get; set; }
|
|
public string Code { get; set; } = string.Empty;
|
|
public string Name { get; set; } = string.Empty;
|
|
public string? Description { get; set; }
|
|
public string? Icon { get; set; }
|
|
public decimal BasePrice { get; set; }
|
|
public decimal MonthlyPrice { get; set; }
|
|
public decimal MonthlyMultiplier { get; set; }
|
|
public int SortOrder { get; set; }
|
|
public bool IsCore { get; set; }
|
|
public List<string> Dependencies { get; set; } = new();
|
|
public string? RoutePath { get; set; }
|
|
public bool IsAvailable { get; set; }
|
|
public bool IsEnabled { get; set; }
|
|
public AppSubscriptionDto? Subscription { get; set; }
|
|
}
|
|
|
|
public class AppSubscriptionDto
|
|
{
|
|
public int Id { get; set; }
|
|
public int AppId { get; set; }
|
|
public string? AppCode { get; set; }
|
|
public string? AppName { get; set; }
|
|
public bool IsEnabled { get; set; }
|
|
public SubscriptionType SubscriptionType { get; set; }
|
|
public string SubscriptionTypeName { get; set; } = string.Empty;
|
|
public DateTime? StartDate { get; set; }
|
|
public DateTime? EndDate { get; set; }
|
|
public bool AutoRenew { get; set; }
|
|
public string? Notes { get; set; }
|
|
public DateTime? LastRenewalDate { get; set; }
|
|
public decimal? PaidPrice { get; set; }
|
|
public bool IsValid { get; set; }
|
|
public int? DaysRemaining { get; set; }
|
|
public bool IsExpiringSoon { get; set; }
|
|
}
|
|
|
|
public class AppStatusDto
|
|
{
|
|
public string Code { get; set; } = string.Empty;
|
|
public bool IsEnabled { get; set; }
|
|
public bool HasValidSubscription { get; set; }
|
|
public bool IsCore { get; set; }
|
|
public int? DaysRemaining { get; set; }
|
|
public bool IsExpiringSoon { get; set; }
|
|
}
|
|
|
|
public class EnableAppRequest
|
|
{
|
|
public SubscriptionType SubscriptionType { get; set; } = SubscriptionType.Annual;
|
|
public DateTime? StartDate { get; set; }
|
|
public DateTime? EndDate { get; set; }
|
|
public bool AutoRenew { get; set; }
|
|
public decimal? PaidPrice { get; set; }
|
|
public string? Notes { get; set; }
|
|
}
|
|
|
|
public class UpdateAppSubscriptionRequest
|
|
{
|
|
public SubscriptionType? SubscriptionType { get; set; }
|
|
public DateTime? EndDate { get; set; }
|
|
public bool? AutoRenew { get; set; }
|
|
public string? Notes { get; set; }
|
|
}
|
|
|
|
public class RenewAppSubscriptionRequest
|
|
{
|
|
public decimal? PaidPrice { get; set; }
|
|
}
|
|
|
|
#endregion
|