feat: Implement Magic Wallet functionality
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 8m36s
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 8m36s
- Added ClubMembershipCycle entity and DbSet to IApplicationDbContext. - Updated VAT rate from 9% to 10% in VatCalculator and related areas. - Introduced Magic Wallet settings in SystemConstants. - Enhanced UserWallet entity to support Magic Wallet features. - Updated TransactionType enum to include Magic Wallet transactions. - Configured UserWallet to handle Magic Wallet properties in ApplicationDbContext. - Implemented OrmCommissionCalculationStrategy to exclude Magic Wallet users from commission calculations. - Added Protobuf definitions for Magic Wallet methods and responses. - Created PaymentCallbackController endpoint for handling Magic Wallet charge callbacks. - Updated UserOrderService to manage Magic Wallet state transitions. - Developed UserWalletService to support Magic Wallet operations. - Created ChargeMagicWalletCommand and its handler for initiating Magic Wallet charges. - Implemented VerifyMagicWalletChargeCommand and handler for payment verification. - Added validation for ChargeMagicWalletCommand. - Established ClubMembershipCycle configuration for EF Core. - Introduced WalletMode enum to differentiate between Normal and Magic modes.
This commit is contained in:
@@ -109,6 +109,7 @@ public class ApplicationDbContext : DbContext, IApplicationDbContext
|
||||
public DbSet<ClubFeature> ClubFeatures => Set<ClubFeature>();
|
||||
public DbSet<UserClubFeature> UserClubFeatures => Set<UserClubFeature>();
|
||||
public DbSet<ClubMembershipHistory> ClubMembershipHistories => Set<ClubMembershipHistory>();
|
||||
public DbSet<ClubMembershipCycle> ClubMembershipCycles => Set<ClubMembershipCycle>();
|
||||
|
||||
// Network
|
||||
public DbSet<NetworkWeeklyBalance> NetworkWeeklyBalances => Set<NetworkWeeklyBalance>();
|
||||
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
using CMSMicroservice.Domain.Entities.Club;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace CMSMicroservice.Infrastructure.Persistence.Configurations;
|
||||
|
||||
public class ClubMembershipCycleConfiguration : IEntityTypeConfiguration<ClubMembershipCycle>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<ClubMembershipCycle> builder)
|
||||
{
|
||||
builder.HasQueryFilter(p => !p.IsDeleted);
|
||||
builder.Ignore(entity => entity.DomainEvents);
|
||||
builder.HasKey(entity => entity.Id);
|
||||
builder.Property(entity => entity.Id).UseIdentityColumn();
|
||||
|
||||
builder.Property(entity => entity.UserId).IsRequired();
|
||||
builder.Property(entity => entity.ClubMembershipId).IsRequired();
|
||||
builder.Property(entity => entity.CycleNumber).IsRequired();
|
||||
builder.Property(entity => entity.PackagePurchasedAt).IsRequired();
|
||||
builder.Property(entity => entity.MagicStartedAt).IsRequired(false);
|
||||
builder.Property(entity => entity.MagicCompletedAt).IsRequired(false);
|
||||
builder.Property(entity => entity.PurchaseMethod).IsRequired();
|
||||
builder.Property(entity => entity.PackageAmount).IsRequired();
|
||||
builder.Property(entity => entity.IsCurrentCycle)
|
||||
.IsRequired()
|
||||
.HasDefaultValue(false);
|
||||
|
||||
// Relationships
|
||||
builder.HasOne(entity => entity.User)
|
||||
.WithMany()
|
||||
.HasForeignKey(entity => entity.UserId)
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
builder.HasOne(entity => entity.ClubMembership)
|
||||
.WithMany(cm => cm.Cycles)
|
||||
.HasForeignKey(entity => entity.ClubMembershipId)
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
// Indexes
|
||||
builder.HasIndex(e => new { e.UserId, e.IsCurrentCycle })
|
||||
.HasDatabaseName("IX_ClubMembershipCycle_UserId_IsCurrentCycle");
|
||||
builder.HasIndex(e => e.PackagePurchasedAt)
|
||||
.HasDatabaseName("IX_ClubMembershipCycle_PackagePurchasedAt");
|
||||
}
|
||||
}
|
||||
+14
@@ -1,4 +1,5 @@
|
||||
using CMSMicroservice.Domain.Entities;
|
||||
using CMSMicroservice.Domain.Enums;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
namespace CMSMicroservice.Infrastructure.Persistence.Configurations;
|
||||
@@ -20,5 +21,18 @@ public class UserWalletConfiguration : IEntityTypeConfiguration<UserWallet>
|
||||
builder.Property(entity => entity.NetworkBalance).IsRequired(true);
|
||||
builder.Property(entity => entity.DiscountBalance).IsRequired(true);
|
||||
|
||||
// Magic Wallet
|
||||
builder.Property(entity => entity.WalletMode)
|
||||
.IsRequired()
|
||||
.HasDefaultValue(WalletMode.Normal);
|
||||
builder.Property(entity => entity.MagicTotalDeposited)
|
||||
.IsRequired()
|
||||
.HasDefaultValue(0L);
|
||||
builder.Property(entity => entity.MagicTotalCredited)
|
||||
.IsRequired()
|
||||
.HasDefaultValue(0L);
|
||||
builder.Property(entity => entity.MagicActivatedAt).IsRequired(false);
|
||||
builder.Property(entity => entity.MagicCompletedAt).IsRequired(false);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+11
-4
@@ -56,8 +56,14 @@ public class OrmCommissionCalculationStrategy : ICommissionCalculationStrategy
|
||||
}
|
||||
|
||||
// دریافت همه کاربرانی که عضو فعال باشگاه هستند
|
||||
// ⚠️ Magic Wallet: کاربرهایی که در حالت جادویی هستند از کمیسیون خارج میشن
|
||||
var magicModeUserIds = await _context.UserWallets
|
||||
.Where(w => w.WalletMode == WalletMode.Magic)
|
||||
.Select(w => w.UserId)
|
||||
.ToHashSetAsync(cancellationToken);
|
||||
|
||||
var activeClubMemberUserIds = await _context.ClubMemberships
|
||||
.Where(c => c.IsActive)
|
||||
.Where(c => c.IsActive && !magicModeUserIds.Contains(c.UserId))
|
||||
.Select(c => c.UserId)
|
||||
.ToHashSetAsync(cancellationToken);
|
||||
|
||||
@@ -364,10 +370,11 @@ public class OrmCommissionCalculationStrategy : ICommissionCalculationStrategy
|
||||
}
|
||||
|
||||
var count = 0;
|
||||
var membership = await _context.ClubMemberships
|
||||
.FirstOrDefaultAsync(x => x.UserId == child.Id && x.IsActive, cancellationToken);
|
||||
// ⚠️ از ClubMembershipCycle.PackagePurchasedAt استفاده میکنیم (نه ActivatedAt که overwrite میشد)
|
||||
var currentCycle = await _context.ClubMembershipCycles
|
||||
.FirstOrDefaultAsync(x => x.UserId == child.Id && x.IsCurrentCycle, cancellationToken);
|
||||
|
||||
if (membership?.ActivatedAt >= startDate && membership?.ActivatedAt <= endDate)
|
||||
if (currentCycle?.PackagePurchasedAt >= startDate && currentCycle?.PackagePurchasedAt <= endDate)
|
||||
{
|
||||
count = 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user