Spaces:
Sleeping
Sleeping
File size: 7,247 Bytes
4433399 da13799 068485b 1a7e978 068485b da13799 ec76476 7fe61c9 068485b da13799 1a7e978 068485b da13799 068485b 1a7e978 068485b 7fe61c9 25f925e 068485b da13799 068485b da13799 b8cc5e6 da13799 7fe61c9 b8cc5e6 7fe61c9 25f925e 7fe61c9 b8cc5e6 7fe61c9 ec76476 7fe61c9 b8cc5e6 7fe61c9 b8cc5e6 7fe61c9 ec76476 068485b 25f925e 068485b 25f925e 068485b 25f925e 068485b 25f925e 068485b 25f925e ec76476 068485b 1a7e978 ec76476 1a7e978 ec76476 1a7e978 068485b 7fe61c9 068485b 7fe61c9 068485b ec76476 068485b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 | using LibraryManagement.Shared.Models;
using DbConnect.Data;
using DbConnect.Entities;
using Microsoft.EntityFrameworkCore;
using Backend.Features.Loyalty;
namespace Backend.Features.Subscriptions
{
public interface ISubscriptionService
{
Task<IEnumerable<MembershipDto>> GetMembershipsAsync();
Task<SubscriptionDto?> GetUserSubscriptionAsync(Guid userId);
Task<IEnumerable<SubscriptionDto>> GetUserAllSubscriptionsAsync(Guid userId);
Task<bool> HandleLoyaltyRedemptionAsync(Guid userId, string rewardId, string rewardName, string redemptionId);
Task<SubscriptionDto> SubscribeUserAsync(Guid userId, int membershipId, string? redemptionId = null);
Task<IEnumerable<SubscriptionDto>> GetAllSubscriptionsAsync();
}
public class SubscriptionService : ISubscriptionService
{
private readonly AppDbContext _context;
private readonly ILoyaltyService _loyaltyService;
public SubscriptionService(AppDbContext context, ILoyaltyService loyaltyService)
{
_context = context;
_loyaltyService = loyaltyService;
}
public async Task<IEnumerable<MembershipDto>> GetMembershipsAsync()
{
return await _context.Memberships
.Select(m => new MembershipDto
{
Id = m.Id,
Type = m.Type,
MaxBooks = m.MaxBooks,
BorrowingDays = m.BorrowingDays,
Price = m.Price,
DurationMonths = m.DurationMonths,
RewardId = m.RewardId
}).ToListAsync();
}
public async Task<SubscriptionDto?> GetUserSubscriptionAsync(Guid userId)
{
var subscription = await _context.UserSubscriptions
.Include(s => s.Membership)
.Where(s => s.UserId == userId && s.IsActive)
.OrderByDescending(s => s.StartDate)
.FirstOrDefaultAsync();
if (subscription == null) return null;
return MapToDto(subscription);
}
public async Task<IEnumerable<SubscriptionDto>> GetUserAllSubscriptionsAsync(Guid userId)
{
var subscriptions = await _context.UserSubscriptions
.Include(s => s.Membership)
.Include(s => s.User)
.Where(s => s.UserId == userId && s.IsActive)
.OrderBy(s => s.StartDate)
.ToListAsync();
return subscriptions.Select(MapToDto);
}
public async Task<bool> HandleLoyaltyRedemptionAsync(Guid userId, string rewardId, string rewardName, string redemptionId)
{
try
{
var allMemberships = await _context.Memberships.ToListAsync();
Membership? membership = null;
if (!string.IsNullOrEmpty(rewardId))
{
membership = allMemberships.FirstOrDefault(m => m.RewardId == rewardId);
}
if (membership == null && !string.IsNullOrEmpty(rewardName))
{
var normalizedRewardName = rewardName.ToLowerInvariant();
membership = allMemberships.FirstOrDefault(m =>
{
var typeWords = m.Type.ToLowerInvariant().Split(' ', StringSplitOptions.RemoveEmptyEntries);
return typeWords.All(w => normalizedRewardName.Contains(w));
});
}
if (membership == null)
{
System.Diagnostics.Debug.WriteLine($"No membership matched for rewardId='{rewardId}', rewardName='{rewardName}'");
return false;
}
await SubscribeUserAsync(userId, membership.Id, redemptionId);
return true;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"HandleLoyaltyRedemptionAsync error: {ex.Message}");
return false;
}
}
public async Task<SubscriptionDto> SubscribeUserAsync(Guid userId, int membershipId, string? redemptionId = null)
{
var membership = await _context.Memberships.FindAsync(membershipId);
if (membership == null) throw new Exception("Membership plan not found.");
var latestSubscription = await _context.UserSubscriptions
.Where(s => s.UserId == userId && s.IsActive)
.OrderByDescending(s => s.ExpiryDate)
.FirstOrDefaultAsync();
DateTime startDate = DateTime.UtcNow;
if (latestSubscription != null && latestSubscription.ExpiryDate > startDate)
{
startDate = latestSubscription.ExpiryDate;
}
var subscription = new UserSubscription
{
UserId = userId,
MembershipId = membershipId,
StartDate = startDate,
ExpiryDate = startDate.AddMonths(membership.DurationMonths),
IsActive = true,
ExternalRedemptionId = redemptionId,
Status = "Active"
};
_context.UserSubscriptions.Add(subscription);
await _context.SaveChangesAsync();
await _context.Entry(subscription).Reference(s => s.Membership).LoadAsync();
await _context.Entry(subscription).Reference(s => s.User).LoadAsync();
await _loyaltyService.ProcessEventAsync(
externalUserId: userId.ToString(),
eventKey: "SUBSCRIBE",
eventValue: (double)membership.Price,
referenceId: $"SUB-{subscription.Id}",
description: $"Purchased Membership: {membership.Type}",
email: subscription.User?.Email ?? "No Email",
mobile: subscription.User?.PhoneNumber ?? "0000000000"
);
return MapToDto(subscription);
}
public async Task<IEnumerable<SubscriptionDto>> GetAllSubscriptionsAsync()
{
var subscriptions = await _context.UserSubscriptions
.Include(s => s.Membership)
.Include(s => s.User)
.OrderByDescending(s => s.StartDate)
.ToListAsync();
return subscriptions.Select(MapToDto);
}
private static SubscriptionDto MapToDto(UserSubscription subscription)
{
return new SubscriptionDto
{
Id = subscription.Id,
UserId = subscription.UserId,
MembershipId = subscription.MembershipId,
MembershipType = subscription.Membership.Type,
UserEmail = subscription.User?.Email ?? "Unknown",
UserName = subscription.User?.FullName ?? "Unknown",
StartDate = subscription.StartDate,
ExpiryDate = subscription.ExpiryDate,
IsActive = subscription.IsActive,
ExternalRedemptionId = subscription.ExternalRedemptionId
};
}
}
}
|