changed name from Apollinare to Zentral
This commit is contained in:
352
src/backend/Zentral.API/Controllers/ModulesController.cs
Normal file
352
src/backend/Zentral.API/Controllers/ModulesController.cs
Normal file
@@ -0,0 +1,352 @@
|
||||
using Zentral.API.Services;
|
||||
using Zentral.Domain.Entities;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Zentral.API.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// Controller per la gestione dei moduli applicativi e delle subscription
|
||||
/// </summary>
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class ModulesController : ControllerBase
|
||||
{
|
||||
private readonly ModuleService _moduleService;
|
||||
private readonly ILogger<ModulesController> _logger;
|
||||
|
||||
public ModulesController(ModuleService moduleService, ILogger<ModulesController> logger)
|
||||
{
|
||||
_moduleService = moduleService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ottiene tutti i moduli disponibili con stato subscription
|
||||
/// </summary>
|
||||
[HttpGet]
|
||||
public async Task<ActionResult<List<ModuleDto>>> GetAllModules()
|
||||
{
|
||||
var modules = await _moduleService.GetAllModulesAsync();
|
||||
return Ok(modules.Select(MapToDto).ToList());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ottiene solo i moduli attivi (per costruzione menu)
|
||||
/// </summary>
|
||||
[HttpGet("active")]
|
||||
public async Task<ActionResult<List<ModuleDto>>> GetActiveModules()
|
||||
{
|
||||
var modules = await _moduleService.GetActiveModulesAsync();
|
||||
return Ok(modules.Select(MapToDto).ToList());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ottiene un modulo specifico per codice
|
||||
/// </summary>
|
||||
[HttpGet("{code}")]
|
||||
public async Task<ActionResult<ModuleDto>> GetModule(string code)
|
||||
{
|
||||
var module = await _moduleService.GetModuleByCodeAsync(code);
|
||||
if (module == null)
|
||||
return NotFound(new { message = $"Modulo '{code}' non trovato" });
|
||||
|
||||
return Ok(MapToDto(module));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifica se un modulo è abilitato
|
||||
/// </summary>
|
||||
[HttpGet("{code}/enabled")]
|
||||
public async Task<ActionResult<ModuleStatusDto>> IsModuleEnabled(string code)
|
||||
{
|
||||
var module = await _moduleService.GetModuleByCodeAsync(code);
|
||||
if (module == null)
|
||||
return NotFound(new { message = $"Modulo '{code}' non trovato" });
|
||||
|
||||
var isEnabled = await _moduleService.IsModuleEnabledAsync(code);
|
||||
var hasValidSubscription = await _moduleService.HasValidSubscriptionAsync(code);
|
||||
|
||||
return Ok(new ModuleStatusDto
|
||||
{
|
||||
Code = code,
|
||||
IsEnabled = isEnabled,
|
||||
HasValidSubscription = hasValidSubscription,
|
||||
IsCore = module.IsCore,
|
||||
DaysRemaining = module.Subscription?.GetDaysRemaining(),
|
||||
IsExpiringSoon = module.Subscription?.IsExpiringSoon() ?? false
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attiva un modulo
|
||||
/// </summary>
|
||||
[HttpPut("{code}/enable")]
|
||||
public async Task<ActionResult<SubscriptionDto>> EnableModule(string code, [FromBody] EnableModuleRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
var subscription = await _moduleService.EnableModuleAsync(
|
||||
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 modulo
|
||||
/// </summary>
|
||||
[HttpPut("{code}/disable")]
|
||||
public async Task<ActionResult> DisableModule(string code)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _moduleService.DisableModuleAsync(code);
|
||||
return Ok(new { message = $"Modulo '{code}' disattivato" });
|
||||
}
|
||||
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<SubscriptionDto>>> GetAllSubscriptions()
|
||||
{
|
||||
var subscriptions = await _moduleService.GetAllSubscriptionsAsync();
|
||||
return Ok(subscriptions.Select(MapSubscriptionToDto).ToList());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Aggiorna la subscription di un modulo
|
||||
/// </summary>
|
||||
[HttpPut("{code}/subscription")]
|
||||
public async Task<ActionResult<SubscriptionDto>> UpdateSubscription(string code, [FromBody] UpdateSubscriptionRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
var subscription = await _moduleService.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 modulo
|
||||
/// </summary>
|
||||
[HttpPost("{code}/subscription/renew")]
|
||||
public async Task<ActionResult<SubscriptionDto>> RenewSubscription(string code, [FromBody] RenewSubscriptionRequest? request = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var subscription = await _moduleService.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 i moduli in scadenza
|
||||
/// </summary>
|
||||
[HttpGet("expiring")]
|
||||
public async Task<ActionResult<List<ModuleDto>>> GetExpiringModules([FromQuery] int daysThreshold = 30)
|
||||
{
|
||||
var modules = await _moduleService.GetExpiringModulesAsync(daysThreshold);
|
||||
return Ok(modules.Select(MapToDto).ToList());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inizializza i moduli di default (per setup iniziale)
|
||||
/// </summary>
|
||||
[HttpPost("seed")]
|
||||
public async Task<ActionResult> SeedDefaultModules()
|
||||
{
|
||||
await _moduleService.SeedDefaultModulesAsync();
|
||||
return Ok(new { message = "Moduli di default inizializzati" });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Forza il controllo delle subscription scadute
|
||||
/// </summary>
|
||||
[HttpPost("check-expired")]
|
||||
public async Task<ActionResult> CheckExpiredSubscriptions()
|
||||
{
|
||||
var count = await _moduleService.CheckExpiredSubscriptionsAsync();
|
||||
return Ok(new { message = $"Controllate le subscription, {count} moduli disattivati per scadenza" });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invalida la cache dei moduli
|
||||
/// </summary>
|
||||
[HttpPost("invalidate-cache")]
|
||||
public ActionResult InvalidateCache()
|
||||
{
|
||||
_moduleService.InvalidateCache();
|
||||
return Ok(new { message = "Cache moduli invalidata" });
|
||||
}
|
||||
|
||||
#region Mapping
|
||||
|
||||
private static ModuleDto MapToDto(AppModule module)
|
||||
{
|
||||
return new ModuleDto
|
||||
{
|
||||
Id = module.Id,
|
||||
Code = module.Code,
|
||||
Name = module.Name,
|
||||
Description = module.Description,
|
||||
Icon = module.Icon,
|
||||
BasePrice = module.BasePrice,
|
||||
MonthlyPrice = module.GetMonthlyPrice(),
|
||||
MonthlyMultiplier = module.MonthlyMultiplier,
|
||||
SortOrder = module.SortOrder,
|
||||
IsCore = module.IsCore,
|
||||
Dependencies = module.GetDependencies().ToList(),
|
||||
RoutePath = module.RoutePath,
|
||||
IsAvailable = module.IsAvailable,
|
||||
IsEnabled = module.IsCore || (module.Subscription?.IsValid() ?? false),
|
||||
Subscription = module.Subscription != null ? MapSubscriptionToDto(module.Subscription) : null
|
||||
};
|
||||
}
|
||||
|
||||
private static SubscriptionDto MapSubscriptionToDto(ModuleSubscription subscription)
|
||||
{
|
||||
return new SubscriptionDto
|
||||
{
|
||||
Id = subscription.Id,
|
||||
ModuleId = subscription.ModuleId,
|
||||
ModuleCode = subscription.Module?.Code,
|
||||
ModuleName = subscription.Module?.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 ModuleDto
|
||||
{
|
||||
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 SubscriptionDto? Subscription { get; set; }
|
||||
}
|
||||
|
||||
public class SubscriptionDto
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int ModuleId { get; set; }
|
||||
public string? ModuleCode { get; set; }
|
||||
public string? ModuleName { 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 ModuleStatusDto
|
||||
{
|
||||
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 EnableModuleRequest
|
||||
{
|
||||
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 UpdateSubscriptionRequest
|
||||
{
|
||||
public SubscriptionType? SubscriptionType { get; set; }
|
||||
public DateTime? EndDate { get; set; }
|
||||
public bool? AutoRenew { get; set; }
|
||||
public string? Notes { get; set; }
|
||||
}
|
||||
|
||||
public class RenewSubscriptionRequest
|
||||
{
|
||||
public decimal? PaidPrice { get; set; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
Reference in New Issue
Block a user