refactor: Migrate backend and frontend architecture from a module-based to an app-based structure.
This commit is contained in:
105
src/backend/Zentral.Domain/Entities/AppSubscription.cs
Normal file
105
src/backend/Zentral.Domain/Entities/AppSubscription.cs
Normal file
@@ -0,0 +1,105 @@
|
||||
namespace Zentral.Domain.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// Tipo di abbonamento per un'applicazione
|
||||
/// </summary>
|
||||
public enum SubscriptionType
|
||||
{
|
||||
/// <summary>Nessun abbonamento attivo</summary>
|
||||
None = 0,
|
||||
/// <summary>Abbonamento mensile</summary>
|
||||
Monthly = 1,
|
||||
/// <summary>Abbonamento annuale</summary>
|
||||
Annual = 2
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rappresenta lo stato di abbonamento/attivazione di un'applicazione.
|
||||
/// Ogni AppSubscription è collegata 1:1 con un'App.
|
||||
/// </summary>
|
||||
public class AppSubscription : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// ID dell'applicazione associata
|
||||
/// </summary>
|
||||
public int AppId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Se true, l'applicazione è attualmente attiva e accessibile
|
||||
/// </summary>
|
||||
public bool IsEnabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Tipo di abbonamento corrente
|
||||
/// </summary>
|
||||
public SubscriptionType SubscriptionType { get; set; } = SubscriptionType.None;
|
||||
|
||||
/// <summary>
|
||||
/// Data di inizio dell'abbonamento corrente
|
||||
/// </summary>
|
||||
public DateTime? StartDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Data di scadenza dell'abbonamento (null = nessuna scadenza, es. licenza perpetua)
|
||||
/// </summary>
|
||||
public DateTime? EndDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Se true, l'abbonamento si rinnova automaticamente alla scadenza
|
||||
/// </summary>
|
||||
public bool AutoRenew { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Note aggiuntive sull'abbonamento (es. codice ordine, riferimento contratto)
|
||||
/// </summary>
|
||||
public string? Notes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Data dell'ultimo rinnovo effettuato
|
||||
/// </summary>
|
||||
public DateTime? LastRenewalDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Prezzo pagato per l'abbonamento corrente (può differire da BasePrice per sconti)
|
||||
/// </summary>
|
||||
public decimal? PaidPrice { get; set; }
|
||||
|
||||
// Navigation property
|
||||
public App App { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Verifica se l'abbonamento è attualmente valido (attivo e non scaduto)
|
||||
/// </summary>
|
||||
public bool IsValid()
|
||||
{
|
||||
// Se non c'è data di scadenza, è valido (licenza perpetua o core module)
|
||||
if (!EndDate.HasValue)
|
||||
return true;
|
||||
|
||||
return EndDate.Value >= DateTime.UtcNow;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calcola i giorni rimanenti alla scadenza (null se nessuna scadenza)
|
||||
/// </summary>
|
||||
public int? GetDaysRemaining()
|
||||
{
|
||||
if (!EndDate.HasValue)
|
||||
return null;
|
||||
|
||||
var remaining = (EndDate.Value - DateTime.UtcNow).Days;
|
||||
return remaining < 0 ? 0 : remaining;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifica se l'abbonamento sta per scadere (entro i prossimi N giorni)
|
||||
/// </summary>
|
||||
public bool IsExpiringSoon(int daysThreshold = 30)
|
||||
{
|
||||
if (!EndDate.HasValue)
|
||||
return false;
|
||||
|
||||
var daysRemaining = GetDaysRemaining();
|
||||
return daysRemaining.HasValue && daysRemaining.Value <= daysThreshold && daysRemaining.Value > 0;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user