using System; using SZUAbsolventenverein.Module.PremiumArea.Models; using SZUAbsolventenverein.Module.PremiumArea.Repository; using Oqtane.Infrastructure; using Oqtane.Shared; using Oqtane.Modules; using Oqtane.Enums; namespace SZUAbsolventenverein.Module.PremiumArea.Services { public interface IPremiumService { bool IsPremium(int userId); DateTime? GetPremiumUntil(int userId); void GrantPremium(int userId, int durationMonths, string source, string referenceId = null); } public class PremiumService : IPremiumService, ITransientService { private readonly IUserPremiumRepository _userPremiumRepository; private readonly ILogManager _logger; public PremiumService(IUserPremiumRepository userPremiumRepository, ILogManager logger) { _userPremiumRepository = userPremiumRepository; _logger = logger; } public bool IsPremium(int userId) { var premium = _userPremiumRepository.GetUserPremium(userId); return premium != null && premium.PremiumUntil.HasValue && premium.PremiumUntil.Value > DateTime.UtcNow; } public DateTime? GetPremiumUntil(int userId) { var premium = _userPremiumRepository.GetUserPremium(userId); return premium?.PremiumUntil; } public void GrantPremium(int userId, int durationMonths, string source, string referenceId = null) { var current = _userPremiumRepository.GetUserPremium(userId); var now = DateTime.UtcNow; DateTime startBase = now; if (current != null && current.PremiumUntil.HasValue && current.PremiumUntil.Value > now) { startBase = current.PremiumUntil.Value; } var newUntil = startBase.AddMonths(durationMonths); // delta days for audit int deltaDays = (newUntil - (current?.PremiumUntil ?? now)).Days; // correction: actually we want to know how many days we ADDED to the existing flow. // If they had 0 days separately, we added durationMonths * 30 approx. // If they had existing time, we added durationMonths. // Audit Log usually tracks "What did this action add?". It added 1 year. // But let's calculate days added relative to "previous state". // If expired: Added (NewUntil - Now) days. // If active: Added (NewUntil - OldUntil) = durationMonths roughly. // Simpler: Just store the DurationMonths converted to days roughly, or the stored delta. int addedDays = (newUntil - startBase).Days; if (current == null) { current = new UserPremium { UserId = userId, CreatedOn = now, ModifiedOn = now }; } current.PremiumUntil = newUntil; current.Source = source; current.ModifiedOn = now; _userPremiumRepository.SaveUserPremium(current); // Audit var audit = new PremiumEvent { UserId = userId, DeltaDays = addedDays, Source = source, ReferenceId = referenceId, CreatedOn = now, ModifiedOn = now }; _userPremiumRepository.AddPremiumEvent(audit); _logger.Log(LogLevel.Information, this, LogFunction.Update, "Granted Premium for User {UserId} until {Until}", userId, newUntil); } } }