refactor: rename UserWalletChangeLog→UserWalletHistory, add History interceptor & migration
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 9m11s

- Rename UserWalletChangeLog to UserWalletHistory across 54+ files (entities, configs, DTOs, commands, queries, protos, services)
- Rename 34 files and 11 directories accordingly
- Rename proto file userwalletchangelog.proto → userwallethistory.proto
- Add IHasHistory<T> generic interface for history auto-tracking
- Implement IHasHistory<PackageHistory> on Package entity
- Add HistoryTrackingSaveChangesInterceptor (reflection-based, auto-fills Old* values from OriginalValues)
- Wire interceptor in DI and ApplicationDbContext
- Add EF migration Q27_HistoryTables_And_RenameWalletHistory:
  * RenameTable UserWalletChangeLogs → UserWalletHistories (preserves data)
  * Rename PK, FK constraints and indexes via sp_rename
  * CreateTable ClubMembershipCycleHistories + PackageHistories
This commit is contained in:
masoodafar-web
2026-02-27 06:22:15 +03:30
parent fdbb91d2e1
commit 10d2ca20d1
86 changed files with 6255 additions and 472 deletions
@@ -192,7 +192,7 @@ public class CalculateWeeklyCommissionPoolCommandHandler : IRequestHandler<Calcu
.ToDictionaryAsync(w => w.UserId, cancellationToken); .ToDictionaryAsync(w => w.UserId, cancellationToken);
var newWallets = new List<UserWallet>(); var newWallets = new List<UserWallet>();
var walletLogs = new List<UserWalletChangeLog>(); var walletLogs = new List<UserWalletHistory>();
foreach (var payout in payouts) foreach (var payout in payouts)
{ {
@@ -241,7 +241,7 @@ public class CalculateWeeklyCommissionPoolCommandHandler : IRequestHandler<Calcu
wallet.NetworkBalance += payout.TotalAmount; wallet.NetworkBalance += payout.TotalAmount;
// ایجاد لاگ تغییر کیف پول // ایجاد لاگ تغییر کیف پول
var walletLog = new UserWalletChangeLog var walletLog = new UserWalletHistory
{ {
WalletId = wallet.Id, WalletId = wallet.Id,
CurrentBalance = wallet.Balance, CurrentBalance = wallet.Balance,
@@ -258,7 +258,7 @@ public class CalculateWeeklyCommissionPoolCommandHandler : IRequestHandler<Calcu
} }
// ذخیره تغییرات کیف پول و لاگ‌ها // ذخیره تغییرات کیف پول و لاگ‌ها
await _context.UserWalletChangeLogs.AddRangeAsync(walletLogs, cancellationToken); await _context.UserWalletHistories.AddRangeAsync(walletLogs, cancellationToken);
await _context.SaveChangesAsync(cancellationToken); await _context.SaveChangesAsync(cancellationToken);
} }
@@ -271,7 +271,7 @@ public class CalculateWeeklyCommissionPoolCommandHandler : IRequestHandler<Calcu
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
// پیدا کردن لاگ‌های کیف پول مرتبط با پرداخت‌های قبلی // پیدا کردن لاگ‌های کیف پول مرتبط با پرداخت‌های قبلی
var oldWalletLogs = await _context.UserWalletChangeLogs var oldWalletLogs = await _context.UserWalletHistories
.Where(l => l.RefrenceId.HasValue && oldPayoutIds.Contains(l.RefrenceId.Value)) .Where(l => l.RefrenceId.HasValue && oldPayoutIds.Contains(l.RefrenceId.Value))
.ToListAsync(cancellationToken); .ToListAsync(cancellationToken);
@@ -300,7 +300,7 @@ public class CalculateWeeklyCommissionPoolCommandHandler : IRequestHandler<Calcu
} }
// حذف لاگ‌های قبلی // حذف لاگ‌های قبلی
_context.UserWalletChangeLogs.RemoveRange(oldWalletLogs); _context.UserWalletHistories.RemoveRange(oldWalletLogs);
await _context.SaveChangesAsync(cancellationToken); await _context.SaveChangesAsync(cancellationToken);
} }
@@ -32,7 +32,7 @@ public interface IApplicationDbContext
DbSet<OrderVAT> OrderVATs { get; } DbSet<OrderVAT> OrderVATs { get; }
DbSet<UserPackagePurchase> UserPackagePurchases { get; } DbSet<UserPackagePurchase> UserPackagePurchases { get; }
DbSet<UserWallet> UserWallets { get; } DbSet<UserWallet> UserWallets { get; }
DbSet<UserWalletChangeLog> UserWalletChangeLogs { get; } DbSet<UserWalletHistory> UserWalletHistories { get; }
DbSet<ManualPayment> ManualPayments { get; } DbSet<ManualPayment> ManualPayments { get; }
DbSet<PaymentTransaction> PaymentTransactions { get; } DbSet<PaymentTransaction> PaymentTransactions { get; }
DbSet<PublicMessage> PublicMessages { get; } DbSet<PublicMessage> PublicMessages { get; }
@@ -1,16 +0,0 @@
using CMSMicroservice.Application.UserWalletChangeLogCQ.Queries.GetAllUserWalletChangeLogByFilter;
using CMSMicroservice.Application.UserWalletChangeLogCQ.Queries.GetUserWalletChangeLog;
namespace CMSMicroservice.Application.Common.Mappings;
public class UserWalletChangeLogProfile : IRegister
{
void IRegister.Register(TypeAdapterConfig config)
{
config.NewConfig<UserWalletChangeLog,GetAllUserWalletChangeLogByFilterResponseModel>()
.Map(dest => dest.CreatedAt, src => src.Created);
config.NewConfig<UserWalletChangeLog, GetUserWalletChangeLogResponseDto>()
.Map(dest => dest.CreatedAt, src => src.Created);
}
}
@@ -0,0 +1,16 @@
using CMSMicroservice.Application.UserWalletHistoryCQ.Queries.GetAllUserWalletHistoryByFilter;
using CMSMicroservice.Application.UserWalletHistoryCQ.Queries.GetUserWalletHistory;
namespace CMSMicroservice.Application.Common.Mappings;
public class UserWalletHistoryProfile : IRegister
{
void IRegister.Register(TypeAdapterConfig config)
{
config.NewConfig<UserWalletHistory,GetAllUserWalletHistoryByFilterResponseModel>()
.Map(dest => dest.CreatedAt, src => src.Created);
config.NewConfig<UserWalletHistory, GetUserWalletHistoryResponseDto>()
.Map(dest => dest.CreatedAt, src => src.Created);
}
}
@@ -223,7 +223,7 @@ public class CheckAndProcessDayaLoansCommandHandler : IRequestHandler<CheckAndPr
// 3. شارژ کیف پول عادی // 3. شارژ کیف پول عادی
wallet.Balance += package.Price; wallet.Balance += package.Price;
var mainLog = new UserWalletChangeLog var mainLog = new UserWalletHistory
{ {
WalletId = wallet.Id, WalletId = wallet.Id,
CurrentBalance = 0, CurrentBalance = 0,
@@ -233,13 +233,13 @@ public class CheckAndProcessDayaLoansCommandHandler : IRequestHandler<CheckAndPr
IsIncrease = true, IsIncrease = true,
RefrenceId = transaction.Id RefrenceId = transaction.Id
}; };
await _context.UserWalletChangeLogs.AddAsync(mainLog, cancellationToken); await _context.UserWalletHistories.AddAsync(mainLog, cancellationToken);
// 4. شارژ کیف پول تخفیف // 4. شارژ کیف پول تخفیف
var discountAmount = (long)(package.Price * package.DiscountMultiplier); var discountAmount = (long)(package.Price * package.DiscountMultiplier);
wallet.DiscountBalance += discountAmount; wallet.DiscountBalance += discountAmount;
var discountLog = new UserWalletChangeLog var discountLog = new UserWalletHistory
{ {
WalletId = wallet.Id, WalletId = wallet.Id,
CurrentBalance = wallet.Balance, CurrentBalance = wallet.Balance,
@@ -251,7 +251,7 @@ public class CheckAndProcessDayaLoansCommandHandler : IRequestHandler<CheckAndPr
IsIncrease = true, IsIncrease = true,
RefrenceId = transaction.Id RefrenceId = transaction.Id
}; };
await _context.UserWalletChangeLogs.AddAsync(discountLog, cancellationToken); await _context.UserWalletHistories.AddAsync(discountLog, cancellationToken);
// 5. به‌روزرسانی کاربر // 5. به‌روزرسانی کاربر
user.HasReceivedDayaCredit = true; user.HasReceivedDayaCredit = true;
@@ -67,7 +67,7 @@ public class CompleteOrderPaymentCommandHandler : IRequestHandler<CompleteOrderP
userWallet.DiscountBalance -= order.DiscountBalanceUsed; userWallet.DiscountBalance -= order.DiscountBalanceUsed;
// ثبت لاگ تغییرات کیف پول // ثبت لاگ تغییرات کیف پول
_context.UserWalletChangeLogs.Add(new Domain.Entities.UserWalletChangeLog _context.UserWalletHistories.Add(new Domain.Entities.UserWalletHistory
{ {
WalletId = userWallet.Id, WalletId = userWallet.Id,
CurrentBalance = userWallet.Balance, CurrentBalance = userWallet.Balance,
@@ -279,7 +279,7 @@ public class PlaceOrderCommandHandler : IRequestHandler<PlaceOrderCommand, Place
walletForDeduct.DiscountBalance -= actualDiscountBalanceUsed; walletForDeduct.DiscountBalance -= actualDiscountBalanceUsed;
// ثبت لاگ تغییرات کیف پول // ثبت لاگ تغییرات کیف پول
_context.UserWalletChangeLogs.Add(new Domain.Entities.UserWalletChangeLog _context.UserWalletHistories.Add(new Domain.Entities.UserWalletHistory
{ {
WalletId = walletForDeduct.Id, WalletId = walletForDeduct.Id,
CurrentBalance = walletForDeduct.Balance, CurrentBalance = walletForDeduct.Balance,
@@ -108,7 +108,7 @@ public class ApproveManualPaymentCommandHandler : IRequestHandler<ApproveManualP
wallet.DiscountBalance += manualPayment.Amount; wallet.DiscountBalance += manualPayment.Amount;
// لاگ Balance // لاگ Balance
await _context.UserWalletChangeLogs.AddAsync(new UserWalletChangeLog await _context.UserWalletHistories.AddAsync(new UserWalletHistory
{ {
WalletId = wallet.Id, WalletId = wallet.Id,
CurrentBalance = wallet.Balance, CurrentBalance = wallet.Balance,
@@ -122,7 +122,7 @@ public class ApproveManualPaymentCommandHandler : IRequestHandler<ApproveManualP
}, cancellationToken); }, cancellationToken);
// لاگ DiscountBalance // لاگ DiscountBalance
await _context.UserWalletChangeLogs.AddAsync(new UserWalletChangeLog await _context.UserWalletHistories.AddAsync(new UserWalletHistory
{ {
WalletId = wallet.Id, WalletId = wallet.Id,
CurrentBalance = wallet.Balance, CurrentBalance = wallet.Balance,
@@ -139,7 +139,7 @@ public class ApproveManualPaymentCommandHandler : IRequestHandler<ApproveManualP
case ManualPaymentType.DiscountWalletCharge: case ManualPaymentType.DiscountWalletCharge:
wallet.DiscountBalance += manualPayment.Amount; wallet.DiscountBalance += manualPayment.Amount;
await _context.UserWalletChangeLogs.AddAsync(new UserWalletChangeLog await _context.UserWalletHistories.AddAsync(new UserWalletHistory
{ {
WalletId = wallet.Id, WalletId = wallet.Id,
CurrentBalance = wallet.Balance, CurrentBalance = wallet.Balance,
@@ -156,7 +156,7 @@ public class ApproveManualPaymentCommandHandler : IRequestHandler<ApproveManualP
case ManualPaymentType.NetworkWalletCharge: case ManualPaymentType.NetworkWalletCharge:
wallet.NetworkBalance += manualPayment.Amount; wallet.NetworkBalance += manualPayment.Amount;
await _context.UserWalletChangeLogs.AddAsync(new UserWalletChangeLog await _context.UserWalletHistories.AddAsync(new UserWalletHistory
{ {
WalletId = wallet.Id, WalletId = wallet.Id,
CurrentBalance = wallet.Balance, CurrentBalance = wallet.Balance,
@@ -183,7 +183,7 @@ public class ApproveManualPaymentCommandHandler : IRequestHandler<ApproveManualP
wallet.DiscountBalance -= manualPayment.Amount; wallet.DiscountBalance -= manualPayment.Amount;
} }
await _context.UserWalletChangeLogs.AddAsync(new UserWalletChangeLog await _context.UserWalletHistories.AddAsync(new UserWalletHistory
{ {
WalletId = wallet.Id, WalletId = wallet.Id,
CurrentBalance = wallet.Balance, CurrentBalance = wallet.Balance,
@@ -201,7 +201,7 @@ public class ApproveManualPaymentCommandHandler : IRequestHandler<ApproveManualP
// Other یا سایر موارد - فقط Balance // Other یا سایر موارد - فقط Balance
wallet.Balance += manualPayment.Amount; wallet.Balance += manualPayment.Amount;
await _context.UserWalletChangeLogs.AddAsync(new UserWalletChangeLog await _context.UserWalletHistories.AddAsync(new UserWalletHistory
{ {
WalletId = wallet.Id, WalletId = wallet.Id,
CurrentBalance = wallet.Balance, CurrentBalance = wallet.Balance,
@@ -120,7 +120,7 @@ public class CreateManualPaymentCommandHandler : IRequestHandler<CreateManualPay
wallet.DiscountBalance += discountBalanceAmount; wallet.DiscountBalance += discountBalanceAmount;
// 8. ثبت لاگ کیف پول // 8. ثبت لاگ کیف پول
var walletLog = new UserWalletChangeLog var walletLog = new UserWalletHistory
{ {
WalletId = wallet.Id, WalletId = wallet.Id,
CurrentBalance = 0, CurrentBalance = 0,
@@ -133,7 +133,7 @@ public class CreateManualPaymentCommandHandler : IRequestHandler<CreateManualPay
RefrenceId = transaction.Id RefrenceId = transaction.Id
}; };
await _context.UserWalletChangeLogs.AddAsync(walletLog, cancellationToken); await _context.UserWalletHistories.AddAsync(walletLog, cancellationToken);
// 9. تنظیم روش خرید پکیج // 9. تنظیم روش خرید پکیج
user.PackagePurchaseMethod = PackagePurchaseMethod.DirectPurchase; user.PackagePurchaseMethod = PackagePurchaseMethod.DirectPurchase;
@@ -104,7 +104,7 @@ public class ProcessManualMembershipPaymentCommandHandler : IRequestHandler<Proc
wallet.DiscountBalance += request.Amount; wallet.DiscountBalance += request.Amount;
// 8. ثبت لاگ Balance // 8. ثبت لاگ Balance
var balanceLog = new UserWalletChangeLog var balanceLog = new UserWalletHistory
{ {
WalletId = wallet.Id, WalletId = wallet.Id,
CurrentBalance = wallet.Balance, CurrentBalance = wallet.Balance,
@@ -116,7 +116,7 @@ public class ProcessManualMembershipPaymentCommandHandler : IRequestHandler<Proc
IsIncrease = true, IsIncrease = true,
RefrenceId = transaction.Id RefrenceId = transaction.Id
}; };
await _context.UserWalletChangeLogs.AddAsync(balanceLog, cancellationToken); await _context.UserWalletHistories.AddAsync(balanceLog, cancellationToken);
user.PackagePurchaseMethod = PackagePurchaseMethod.DirectPurchase; user.PackagePurchaseMethod = PackagePurchaseMethod.DirectPurchase;
// 10. به‌روزرسانی ManualPayment با TransactionId // 10. به‌روزرسانی ManualPayment با TransactionId
@@ -60,7 +60,7 @@ public class CancelOrderByAdminCommandHandler : IRequestHandler<CancelOrderByAdm
var wallet = order.User.UserWallets.FirstOrDefault(); var wallet = order.User.UserWallets.FirstOrDefault();
if (wallet != null) if (wallet != null)
{ {
var walletLog = new UserWalletChangeLog var walletLog = new UserWalletHistory
{ {
WalletId = wallet.Id, WalletId = wallet.Id,
CurrentBalance = wallet.Balance, CurrentBalance = wallet.Balance,
@@ -74,7 +74,7 @@ public class CancelOrderByAdminCommandHandler : IRequestHandler<CancelOrderByAdm
wallet.Balance += order.Amount; wallet.Balance += order.Amount;
await _context.UserWalletChangeLogs.AddAsync(walletLog, cancellationToken); await _context.UserWalletHistories.AddAsync(walletLog, cancellationToken);
_logger.LogInformation( _logger.LogInformation(
"Refund processed. OrderId: {OrderId}, Amount: {Amount}, UserId: {UserId}", "Refund processed. OrderId: {OrderId}, Amount: {Amount}, UserId: {UserId}",
@@ -129,7 +129,7 @@ public class VerifyPackagePurchaseCommandHandler
await _context.SaveChangesAsync(cancellationToken); await _context.SaveChangesAsync(cancellationToken);
// 6. ثبت لاگ تغییر Balance // 6. ثبت لاگ تغییر Balance
var balanceLog = new UserWalletChangeLog var balanceLog = new UserWalletHistory
{ {
WalletId = wallet.Id, WalletId = wallet.Id,
CurrentBalance = wallet.Balance, CurrentBalance = wallet.Balance,
@@ -141,10 +141,10 @@ public class VerifyPackagePurchaseCommandHandler
IsIncrease = true, IsIncrease = true,
RefrenceId = transaction.Id RefrenceId = transaction.Id
}; };
await _context.UserWalletChangeLogs.AddAsync(balanceLog, cancellationToken); await _context.UserWalletHistories.AddAsync(balanceLog, cancellationToken);
// 7. ثبت لاگ تغییر DiscountBalance // 7. ثبت لاگ تغییر DiscountBalance
var discountLog = new UserWalletChangeLog var discountLog = new UserWalletHistory
{ {
WalletId = wallet.Id, WalletId = wallet.Id,
CurrentBalance = wallet.Balance, CurrentBalance = wallet.Balance,
@@ -156,7 +156,7 @@ public class VerifyPackagePurchaseCommandHandler
IsIncrease = true, IsIncrease = true,
RefrenceId = transaction.Id RefrenceId = transaction.Id
}; };
await _context.UserWalletChangeLogs.AddAsync(discountLog, cancellationToken); await _context.UserWalletHistories.AddAsync(discountLog, cancellationToken);
// 8. ثبت UserPackagePurchase // 8. ثبت UserPackagePurchase
if (order.PackageId.HasValue) if (order.PackageId.HasValue)
@@ -60,7 +60,7 @@ public class GetCustomerReferralsQueryHandler : IRequestHandler<GetCustomerRefer
// Calculate this month's commission from wallet changelog // Calculate this month's commission from wallet changelog
var startOfMonth = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1); var startOfMonth = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
var thisMonthCommission = await _context.UserWalletChangeLogs var thisMonthCommission = await _context.UserWalletHistories
.AsNoTracking() .AsNoTracking()
.Include(x => x.Wallet) .Include(x => x.Wallet)
.Where(x => x.Wallet.UserId == userId && x.Created >= startOfMonth) .Where(x => x.Wallet.UserId == userId && x.Created >= startOfMonth)
@@ -1,6 +1,6 @@
namespace CMSMicroservice.Application.UserWalletCQ.Queries.GetCustomerWalletChangeLog; namespace CMSMicroservice.Application.UserWalletCQ.Queries.GetCustomerWalletHistory;
public class GetCustomerWalletChangeLogQuery : IRequest<List<GetCustomerWalletChangeLogResponseDto>> public class GetCustomerWalletHistoryQuery : IRequest<List<GetCustomerWalletHistoryResponseDto>>
{ {
/// <summary> /// <summary>
/// فیلتر بر اساس شناسه ارجاع (اختیاری) /// فیلتر بر اساس شناسه ارجاع (اختیاری)
@@ -1,11 +1,11 @@
namespace CMSMicroservice.Application.UserWalletCQ.Queries.GetCustomerWalletChangeLog; namespace CMSMicroservice.Application.UserWalletCQ.Queries.GetCustomerWalletHistory;
public class GetCustomerWalletChangeLogQueryHandler : IRequestHandler<GetCustomerWalletChangeLogQuery, List<GetCustomerWalletChangeLogResponseDto>> public class GetCustomerWalletHistoryQueryHandler : IRequestHandler<GetCustomerWalletHistoryQuery, List<GetCustomerWalletHistoryResponseDto>>
{ {
private readonly IApplicationDbContext _context; private readonly IApplicationDbContext _context;
private readonly ICurrentUserService _currentUser; private readonly ICurrentUserService _currentUser;
public GetCustomerWalletChangeLogQueryHandler( public GetCustomerWalletHistoryQueryHandler(
IApplicationDbContext context, IApplicationDbContext context,
ICurrentUserService currentUser) ICurrentUserService currentUser)
{ {
@@ -13,8 +13,8 @@ public class GetCustomerWalletChangeLogQueryHandler : IRequestHandler<GetCustome
_currentUser = currentUser; _currentUser = currentUser;
} }
public async Task<List<GetCustomerWalletChangeLogResponseDto>> Handle( public async Task<List<GetCustomerWalletHistoryResponseDto>> Handle(
GetCustomerWalletChangeLogQuery request, GetCustomerWalletHistoryQuery request,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
// Get current user's ID from JWT // Get current user's ID from JWT
@@ -35,7 +35,7 @@ public class GetCustomerWalletChangeLogQueryHandler : IRequestHandler<GetCustome
} }
// Build query for wallet change logs // Build query for wallet change logs
var query = _context.UserWalletChangeLogs var query = _context.UserWalletHistories
.AsNoTracking() .AsNoTracking()
.Where(x => x.WalletId == userWallet.Id); .Where(x => x.WalletId == userWallet.Id);
@@ -53,7 +53,7 @@ public class GetCustomerWalletChangeLogQueryHandler : IRequestHandler<GetCustome
// Order by newest first // Order by newest first
var result = await query var result = await query
.OrderByDescending(x => x.Created) .OrderByDescending(x => x.Created)
.ProjectToType<GetCustomerWalletChangeLogResponseDto>() .ProjectToType<GetCustomerWalletHistoryResponseDto>()
.ToListAsync(cancellationToken); .ToListAsync(cancellationToken);
return result; return result;
@@ -1,6 +1,6 @@
namespace CMSMicroservice.Application.UserWalletCQ.Queries.GetCustomerWalletChangeLog; namespace CMSMicroservice.Application.UserWalletCQ.Queries.GetCustomerWalletHistory;
public class GetCustomerWalletChangeLogResponseDto public class GetCustomerWalletHistoryResponseDto
{ {
/// <summary> /// <summary>
/// موجودی جاری /// موجودی جاری
@@ -1,21 +0,0 @@
using CMSMicroservice.Domain.Events;
namespace CMSMicroservice.Application.UserWalletChangeLogCQ.Commands.CreateNewUserWalletChangeLog;
public class CreateNewUserWalletChangeLogCommandHandler : IRequestHandler<CreateNewUserWalletChangeLogCommand, CreateNewUserWalletChangeLogResponseDto>
{
private readonly IApplicationDbContext _context;
public CreateNewUserWalletChangeLogCommandHandler(IApplicationDbContext context)
{
_context = context;
}
public async Task<CreateNewUserWalletChangeLogResponseDto> Handle(CreateNewUserWalletChangeLogCommand request,
CancellationToken cancellationToken)
{
var entity = request.Adapt<UserWalletChangeLog>();
await _context.UserWalletChangeLogs.AddAsync(entity, cancellationToken);
entity.AddDomainEvent(new CreateNewUserWalletChangeLogEvent(entity));
await _context.SaveChangesAsync(cancellationToken);
return entity.Adapt<CreateNewUserWalletChangeLogResponseDto>();
}
}
@@ -1,7 +0,0 @@
namespace CMSMicroservice.Application.UserWalletChangeLogCQ.Commands.CreateNewUserWalletChangeLog;
public class CreateNewUserWalletChangeLogResponseDto
{
//شناسه
public long Id { get; set; }
}
@@ -1,7 +0,0 @@
namespace CMSMicroservice.Application.UserWalletChangeLogCQ.Commands.DeleteUserWalletChangeLog;
public record DeleteUserWalletChangeLogCommand : IRequest<Unit>
{
//شناسه
public long Id { get; init; }
}
@@ -1,22 +0,0 @@
using CMSMicroservice.Domain.Events;
namespace CMSMicroservice.Application.UserWalletChangeLogCQ.Commands.DeleteUserWalletChangeLog;
public class DeleteUserWalletChangeLogCommandHandler : IRequestHandler<DeleteUserWalletChangeLogCommand, Unit>
{
private readonly IApplicationDbContext _context;
public DeleteUserWalletChangeLogCommandHandler(IApplicationDbContext context)
{
_context = context;
}
public async Task<Unit> Handle(DeleteUserWalletChangeLogCommand request, CancellationToken cancellationToken)
{
var entity = await _context.UserWalletChangeLogs
.FirstOrDefaultAsync(x => x.Id == request.Id, cancellationToken) ?? throw new NotFoundException(nameof(UserWalletChangeLog), request.Id);
entity.IsDeleted = true;
_context.UserWalletChangeLogs.Update(entity);
entity.AddDomainEvent(new DeleteUserWalletChangeLogEvent(entity));
await _context.SaveChangesAsync(cancellationToken);
return Unit.Value;
}
}
@@ -1,16 +0,0 @@
namespace CMSMicroservice.Application.UserWalletChangeLogCQ.Commands.DeleteUserWalletChangeLog;
public class DeleteUserWalletChangeLogCommandValidator : AbstractValidator<DeleteUserWalletChangeLogCommand>
{
public DeleteUserWalletChangeLogCommandValidator()
{
RuleFor(model => model.Id)
.NotNull();
}
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{
var result = await ValidateAsync(ValidationContext<DeleteUserWalletChangeLogCommand>.CreateWithOptions((DeleteUserWalletChangeLogCommand)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
};
}
@@ -1,22 +0,0 @@
using CMSMicroservice.Domain.Events;
namespace CMSMicroservice.Application.UserWalletChangeLogCQ.Commands.UpdateUserWalletChangeLog;
public class UpdateUserWalletChangeLogCommandHandler : IRequestHandler<UpdateUserWalletChangeLogCommand, Unit>
{
private readonly IApplicationDbContext _context;
public UpdateUserWalletChangeLogCommandHandler(IApplicationDbContext context)
{
_context = context;
}
public async Task<Unit> Handle(UpdateUserWalletChangeLogCommand request, CancellationToken cancellationToken)
{
var entity = await _context.UserWalletChangeLogs
.FirstOrDefaultAsync(x => x.Id == request.Id, cancellationToken) ?? throw new NotFoundException(nameof(UserWalletChangeLog), request.Id);
request.Adapt(entity);
_context.UserWalletChangeLogs.Update(entity);
entity.AddDomainEvent(new UpdateUserWalletChangeLogEvent(entity));
await _context.SaveChangesAsync(cancellationToken);
return Unit.Value;
}
}
@@ -1,22 +0,0 @@
using CMSMicroservice.Domain.Events;
using Microsoft.Extensions.Logging;
namespace CMSMicroservice.Application.UserWalletChangeLogCQ.EventHandlers;
public class CreateNewUserWalletChangeLogEventHandler : INotificationHandler<CreateNewUserWalletChangeLogEvent>
{
private readonly ILogger<
CreateNewUserWalletChangeLogEventHandler> _logger;
public CreateNewUserWalletChangeLogEventHandler(ILogger<CreateNewUserWalletChangeLogEventHandler> logger)
{
_logger = logger;
}
public Task Handle(CreateNewUserWalletChangeLogEvent notification, CancellationToken cancellationToken)
{
_logger.LogInformation("Domain Event: {DomainEvent}", notification.GetType().Name);
return Task.CompletedTask;
}
}
@@ -1,22 +0,0 @@
using CMSMicroservice.Domain.Events;
using Microsoft.Extensions.Logging;
namespace CMSMicroservice.Application.UserWalletChangeLogCQ.EventHandlers;
public class DeleteUserWalletChangeLogEventHandler : INotificationHandler<DeleteUserWalletChangeLogEvent>
{
private readonly ILogger<
DeleteUserWalletChangeLogEventHandler> _logger;
public DeleteUserWalletChangeLogEventHandler(ILogger<DeleteUserWalletChangeLogEventHandler> logger)
{
_logger = logger;
}
public Task Handle(DeleteUserWalletChangeLogEvent notification, CancellationToken cancellationToken)
{
_logger.LogInformation("Domain Event: {DomainEvent}", notification.GetType().Name);
return Task.CompletedTask;
}
}
@@ -1,22 +0,0 @@
using CMSMicroservice.Domain.Events;
using Microsoft.Extensions.Logging;
namespace CMSMicroservice.Application.UserWalletChangeLogCQ.EventHandlers;
public class UpdateUserWalletChangeLogEventHandler : INotificationHandler<UpdateUserWalletChangeLogEvent>
{
private readonly ILogger<
UpdateUserWalletChangeLogEventHandler> _logger;
public UpdateUserWalletChangeLogEventHandler(ILogger<UpdateUserWalletChangeLogEventHandler> logger)
{
_logger = logger;
}
public Task Handle(UpdateUserWalletChangeLogEvent notification, CancellationToken cancellationToken)
{
_logger.LogInformation("Domain Event: {DomainEvent}", notification.GetType().Name);
return Task.CompletedTask;
}
}
@@ -1,14 +0,0 @@
namespace CMSMicroservice.Application.UserWalletChangeLogCQ.Queries.GetAllUserWalletChangeLogByFilter;
public class GetAllUserWalletChangeLogByFilterQueryValidator : AbstractValidator<GetAllUserWalletChangeLogByFilterQuery>
{
public GetAllUserWalletChangeLogByFilterQueryValidator()
{
}
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{
var result = await ValidateAsync(ValidationContext<GetAllUserWalletChangeLogByFilterQuery>.CreateWithOptions((GetAllUserWalletChangeLogByFilterQuery)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
};
}
@@ -1,7 +0,0 @@
namespace CMSMicroservice.Application.UserWalletChangeLogCQ.Queries.GetUserWalletChangeLog;
public record GetUserWalletChangeLogQuery : IRequest<GetUserWalletChangeLogResponseDto>
{
//شناسه
public long Id { get; init; }
}
@@ -1,22 +0,0 @@
namespace CMSMicroservice.Application.UserWalletChangeLogCQ.Queries.GetUserWalletChangeLog;
public class GetUserWalletChangeLogQueryHandler : IRequestHandler<GetUserWalletChangeLogQuery, GetUserWalletChangeLogResponseDto>
{
private readonly IApplicationDbContext _context;
public GetUserWalletChangeLogQueryHandler(IApplicationDbContext context)
{
_context = context;
}
public async Task<GetUserWalletChangeLogResponseDto> Handle(GetUserWalletChangeLogQuery request,
CancellationToken cancellationToken)
{
var response = await _context.UserWalletChangeLogs
.AsNoTracking()
.Where(x => x.Id == request.Id)
.ProjectToType<GetUserWalletChangeLogResponseDto>()
.FirstOrDefaultAsync(cancellationToken);
return response ?? throw new NotFoundException(nameof(UserWalletChangeLog), request.Id);
}
}
@@ -1,5 +1,5 @@
namespace CMSMicroservice.Application.UserWalletChangeLogCQ.Commands.CreateNewUserWalletChangeLog; namespace CMSMicroservice.Application.UserWalletHistoryCQ.Commands.CreateNewUserWalletHistory;
public record CreateNewUserWalletChangeLogCommand : IRequest<CreateNewUserWalletChangeLogResponseDto> public record CreateNewUserWalletHistoryCommand : IRequest<CreateNewUserWalletHistoryResponseDto>
{ {
//شناسه کیف پول //شناسه کیف پول
public long WalletId { get; init; } public long WalletId { get; init; }
@@ -0,0 +1,21 @@
using CMSMicroservice.Domain.Events;
namespace CMSMicroservice.Application.UserWalletHistoryCQ.Commands.CreateNewUserWalletHistory;
public class CreateNewUserWalletHistoryCommandHandler : IRequestHandler<CreateNewUserWalletHistoryCommand, CreateNewUserWalletHistoryResponseDto>
{
private readonly IApplicationDbContext _context;
public CreateNewUserWalletHistoryCommandHandler(IApplicationDbContext context)
{
_context = context;
}
public async Task<CreateNewUserWalletHistoryResponseDto> Handle(CreateNewUserWalletHistoryCommand request,
CancellationToken cancellationToken)
{
var entity = request.Adapt<UserWalletHistory>();
await _context.UserWalletHistories.AddAsync(entity, cancellationToken);
entity.AddDomainEvent(new CreateNewUserWalletHistoryEvent(entity));
await _context.SaveChangesAsync(cancellationToken);
return entity.Adapt<CreateNewUserWalletHistoryResponseDto>();
}
}
@@ -1,7 +1,7 @@
namespace CMSMicroservice.Application.UserWalletChangeLogCQ.Commands.CreateNewUserWalletChangeLog; namespace CMSMicroservice.Application.UserWalletHistoryCQ.Commands.CreateNewUserWalletHistory;
public class CreateNewUserWalletChangeLogCommandValidator : AbstractValidator<CreateNewUserWalletChangeLogCommand> public class CreateNewUserWalletHistoryCommandValidator : AbstractValidator<CreateNewUserWalletHistoryCommand>
{ {
public CreateNewUserWalletChangeLogCommandValidator() public CreateNewUserWalletHistoryCommandValidator()
{ {
RuleFor(model => model.WalletId) RuleFor(model => model.WalletId)
.NotNull(); .NotNull();
@@ -18,7 +18,7 @@ public class CreateNewUserWalletChangeLogCommandValidator : AbstractValidator<Cr
} }
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) => public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{ {
var result = await ValidateAsync(ValidationContext<CreateNewUserWalletChangeLogCommand>.CreateWithOptions((CreateNewUserWalletChangeLogCommand)model, x => x.IncludeProperties(propertyName))); var result = await ValidateAsync(ValidationContext<CreateNewUserWalletHistoryCommand>.CreateWithOptions((CreateNewUserWalletHistoryCommand)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid) if (result.IsValid)
return Array.Empty<string>(); return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage); return result.Errors.Select(e => e.ErrorMessage);
@@ -0,0 +1,7 @@
namespace CMSMicroservice.Application.UserWalletHistoryCQ.Commands.CreateNewUserWalletHistory;
public class CreateNewUserWalletHistoryResponseDto
{
//شناسه
public long Id { get; set; }
}
@@ -0,0 +1,7 @@
namespace CMSMicroservice.Application.UserWalletHistoryCQ.Commands.DeleteUserWalletHistory;
public record DeleteUserWalletHistoryCommand : IRequest<Unit>
{
//شناسه
public long Id { get; init; }
}
@@ -0,0 +1,22 @@
using CMSMicroservice.Domain.Events;
namespace CMSMicroservice.Application.UserWalletHistoryCQ.Commands.DeleteUserWalletHistory;
public class DeleteUserWalletHistoryCommandHandler : IRequestHandler<DeleteUserWalletHistoryCommand, Unit>
{
private readonly IApplicationDbContext _context;
public DeleteUserWalletHistoryCommandHandler(IApplicationDbContext context)
{
_context = context;
}
public async Task<Unit> Handle(DeleteUserWalletHistoryCommand request, CancellationToken cancellationToken)
{
var entity = await _context.UserWalletHistories
.FirstOrDefaultAsync(x => x.Id == request.Id, cancellationToken) ?? throw new NotFoundException(nameof(UserWalletHistory), request.Id);
entity.IsDeleted = true;
_context.UserWalletHistories.Update(entity);
entity.AddDomainEvent(new DeleteUserWalletHistoryEvent(entity));
await _context.SaveChangesAsync(cancellationToken);
return Unit.Value;
}
}
@@ -0,0 +1,16 @@
namespace CMSMicroservice.Application.UserWalletHistoryCQ.Commands.DeleteUserWalletHistory;
public class DeleteUserWalletHistoryCommandValidator : AbstractValidator<DeleteUserWalletHistoryCommand>
{
public DeleteUserWalletHistoryCommandValidator()
{
RuleFor(model => model.Id)
.NotNull();
}
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{
var result = await ValidateAsync(ValidationContext<DeleteUserWalletHistoryCommand>.CreateWithOptions((DeleteUserWalletHistoryCommand)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
};
}
@@ -1,5 +1,5 @@
namespace CMSMicroservice.Application.UserWalletChangeLogCQ.Commands.UpdateUserWalletChangeLog; namespace CMSMicroservice.Application.UserWalletHistoryCQ.Commands.UpdateUserWalletHistory;
public record UpdateUserWalletChangeLogCommand : IRequest<Unit> public record UpdateUserWalletHistoryCommand : IRequest<Unit>
{ {
//شناسه //شناسه
public long Id { get; init; } public long Id { get; init; }
@@ -0,0 +1,22 @@
using CMSMicroservice.Domain.Events;
namespace CMSMicroservice.Application.UserWalletHistoryCQ.Commands.UpdateUserWalletHistory;
public class UpdateUserWalletHistoryCommandHandler : IRequestHandler<UpdateUserWalletHistoryCommand, Unit>
{
private readonly IApplicationDbContext _context;
public UpdateUserWalletHistoryCommandHandler(IApplicationDbContext context)
{
_context = context;
}
public async Task<Unit> Handle(UpdateUserWalletHistoryCommand request, CancellationToken cancellationToken)
{
var entity = await _context.UserWalletHistories
.FirstOrDefaultAsync(x => x.Id == request.Id, cancellationToken) ?? throw new NotFoundException(nameof(UserWalletHistory), request.Id);
request.Adapt(entity);
_context.UserWalletHistories.Update(entity);
entity.AddDomainEvent(new UpdateUserWalletHistoryEvent(entity));
await _context.SaveChangesAsync(cancellationToken);
return Unit.Value;
}
}
@@ -1,7 +1,7 @@
namespace CMSMicroservice.Application.UserWalletChangeLogCQ.Commands.UpdateUserWalletChangeLog; namespace CMSMicroservice.Application.UserWalletHistoryCQ.Commands.UpdateUserWalletHistory;
public class UpdateUserWalletChangeLogCommandValidator : AbstractValidator<UpdateUserWalletChangeLogCommand> public class UpdateUserWalletHistoryCommandValidator : AbstractValidator<UpdateUserWalletHistoryCommand>
{ {
public UpdateUserWalletChangeLogCommandValidator() public UpdateUserWalletHistoryCommandValidator()
{ {
RuleFor(model => model.Id) RuleFor(model => model.Id)
.NotNull(); .NotNull();
@@ -20,7 +20,7 @@ public class UpdateUserWalletChangeLogCommandValidator : AbstractValidator<Updat
} }
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) => public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{ {
var result = await ValidateAsync(ValidationContext<UpdateUserWalletChangeLogCommand>.CreateWithOptions((UpdateUserWalletChangeLogCommand)model, x => x.IncludeProperties(propertyName))); var result = await ValidateAsync(ValidationContext<UpdateUserWalletHistoryCommand>.CreateWithOptions((UpdateUserWalletHistoryCommand)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid) if (result.IsValid)
return Array.Empty<string>(); return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage); return result.Errors.Select(e => e.ErrorMessage);
@@ -0,0 +1,22 @@
using CMSMicroservice.Domain.Events;
using Microsoft.Extensions.Logging;
namespace CMSMicroservice.Application.UserWalletHistoryCQ.EventHandlers;
public class CreateNewUserWalletHistoryEventHandler : INotificationHandler<CreateNewUserWalletHistoryEvent>
{
private readonly ILogger<
CreateNewUserWalletHistoryEventHandler> _logger;
public CreateNewUserWalletHistoryEventHandler(ILogger<CreateNewUserWalletHistoryEventHandler> logger)
{
_logger = logger;
}
public Task Handle(CreateNewUserWalletHistoryEvent notification, CancellationToken cancellationToken)
{
_logger.LogInformation("Domain Event: {DomainEvent}", notification.GetType().Name);
return Task.CompletedTask;
}
}
@@ -0,0 +1,22 @@
using CMSMicroservice.Domain.Events;
using Microsoft.Extensions.Logging;
namespace CMSMicroservice.Application.UserWalletHistoryCQ.EventHandlers;
public class DeleteUserWalletHistoryEventHandler : INotificationHandler<DeleteUserWalletHistoryEvent>
{
private readonly ILogger<
DeleteUserWalletHistoryEventHandler> _logger;
public DeleteUserWalletHistoryEventHandler(ILogger<DeleteUserWalletHistoryEventHandler> logger)
{
_logger = logger;
}
public Task Handle(DeleteUserWalletHistoryEvent notification, CancellationToken cancellationToken)
{
_logger.LogInformation("Domain Event: {DomainEvent}", notification.GetType().Name);
return Task.CompletedTask;
}
}
@@ -0,0 +1,22 @@
using CMSMicroservice.Domain.Events;
using Microsoft.Extensions.Logging;
namespace CMSMicroservice.Application.UserWalletHistoryCQ.EventHandlers;
public class UpdateUserWalletHistoryEventHandler : INotificationHandler<UpdateUserWalletHistoryEvent>
{
private readonly ILogger<
UpdateUserWalletHistoryEventHandler> _logger;
public UpdateUserWalletHistoryEventHandler(ILogger<UpdateUserWalletHistoryEventHandler> logger)
{
_logger = logger;
}
public Task Handle(UpdateUserWalletHistoryEvent notification, CancellationToken cancellationToken)
{
_logger.LogInformation("Domain Event: {DomainEvent}", notification.GetType().Name);
return Task.CompletedTask;
}
}
@@ -1,14 +1,14 @@
namespace CMSMicroservice.Application.UserWalletChangeLogCQ.Queries.GetAllUserWalletChangeLogByFilter; namespace CMSMicroservice.Application.UserWalletHistoryCQ.Queries.GetAllUserWalletHistoryByFilter;
public record GetAllUserWalletChangeLogByFilterQuery : IRequest<GetAllUserWalletChangeLogByFilterResponseDto> public record GetAllUserWalletHistoryByFilterQuery : IRequest<GetAllUserWalletHistoryByFilterResponseDto>
{ {
//موقعیت صفحه بندی //موقعیت صفحه بندی
public PaginationState? PaginationState { get; init; } public PaginationState? PaginationState { get; init; }
//مرتب سازی بر اساس //مرتب سازی بر اساس
public string? SortBy { get; init; } public string? SortBy { get; init; }
//فیلتر //فیلتر
public GetAllUserWalletChangeLogByFilterFilter? Filter { get; init; } public GetAllUserWalletHistoryByFilterFilter? Filter { get; init; }
}public class GetAllUserWalletChangeLogByFilterFilter }public class GetAllUserWalletHistoryByFilterFilter
{ {
//شناسه //شناسه
public long? Id { get; set; } public long? Id { get; set; }
@@ -1,16 +1,16 @@
namespace CMSMicroservice.Application.UserWalletChangeLogCQ.Queries.GetAllUserWalletChangeLogByFilter; namespace CMSMicroservice.Application.UserWalletHistoryCQ.Queries.GetAllUserWalletHistoryByFilter;
public class GetAllUserWalletChangeLogByFilterQueryHandler : IRequestHandler<GetAllUserWalletChangeLogByFilterQuery, GetAllUserWalletChangeLogByFilterResponseDto> public class GetAllUserWalletHistoryByFilterQueryHandler : IRequestHandler<GetAllUserWalletHistoryByFilterQuery, GetAllUserWalletHistoryByFilterResponseDto>
{ {
private readonly IApplicationDbContext _context; private readonly IApplicationDbContext _context;
public GetAllUserWalletChangeLogByFilterQueryHandler(IApplicationDbContext context) public GetAllUserWalletHistoryByFilterQueryHandler(IApplicationDbContext context)
{ {
_context = context; _context = context;
} }
public async Task<GetAllUserWalletChangeLogByFilterResponseDto> Handle(GetAllUserWalletChangeLogByFilterQuery request, CancellationToken cancellationToken) public async Task<GetAllUserWalletHistoryByFilterResponseDto> Handle(GetAllUserWalletHistoryByFilterQuery request, CancellationToken cancellationToken)
{ {
var query = _context.UserWalletChangeLogs var query = _context.UserWalletHistories
.Include(i=>i.Wallet) .Include(i=>i.Wallet)
.ApplyOrder(sortBy: request.SortBy) .ApplyOrder(sortBy: request.SortBy)
.AsNoTracking() .AsNoTracking()
@@ -27,11 +27,11 @@ public class GetAllUserWalletChangeLogByFilterQueryHandler : IRequestHandler<Get
.Where(x => request.Filter.UserId == null || x.Wallet.UserId == request.Filter.UserId) .Where(x => request.Filter.UserId == null || x.Wallet.UserId == request.Filter.UserId)
; ;
} }
return new GetAllUserWalletChangeLogByFilterResponseDto return new GetAllUserWalletHistoryByFilterResponseDto
{ {
MetaData = await query.GetMetaData(request.PaginationState, cancellationToken), MetaData = await query.GetMetaData(request.PaginationState, cancellationToken),
Models = await query.PaginatedListAsync(paginationState: request.PaginationState) Models = await query.PaginatedListAsync(paginationState: request.PaginationState)
.ProjectToType<GetAllUserWalletChangeLogByFilterResponseModel>().ToListAsync(cancellationToken) .ProjectToType<GetAllUserWalletHistoryByFilterResponseModel>().ToListAsync(cancellationToken)
}; };
} }
} }
@@ -0,0 +1,14 @@
namespace CMSMicroservice.Application.UserWalletHistoryCQ.Queries.GetAllUserWalletHistoryByFilter;
public class GetAllUserWalletHistoryByFilterQueryValidator : AbstractValidator<GetAllUserWalletHistoryByFilterQuery>
{
public GetAllUserWalletHistoryByFilterQueryValidator()
{
}
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{
var result = await ValidateAsync(ValidationContext<GetAllUserWalletHistoryByFilterQuery>.CreateWithOptions((GetAllUserWalletHistoryByFilterQuery)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
};
}
@@ -1,12 +1,12 @@
namespace CMSMicroservice.Application.UserWalletChangeLogCQ.Queries.GetAllUserWalletChangeLogByFilter; namespace CMSMicroservice.Application.UserWalletHistoryCQ.Queries.GetAllUserWalletHistoryByFilter;
public class GetAllUserWalletChangeLogByFilterResponseDto public class GetAllUserWalletHistoryByFilterResponseDto
{ {
//متادیتا //متادیتا
public MetaData MetaData { get; set; } public MetaData MetaData { get; set; }
//مدل خروجی //مدل خروجی
public List<GetAllUserWalletChangeLogByFilterResponseModel>? Models { get; set; } public List<GetAllUserWalletHistoryByFilterResponseModel>? Models { get; set; }
}public class GetAllUserWalletChangeLogByFilterResponseModel }public class GetAllUserWalletHistoryByFilterResponseModel
{ {
//شناسه //شناسه
public long Id { get; set; } public long Id { get; set; }
@@ -0,0 +1,7 @@
namespace CMSMicroservice.Application.UserWalletHistoryCQ.Queries.GetUserWalletHistory;
public record GetUserWalletHistoryQuery : IRequest<GetUserWalletHistoryResponseDto>
{
//شناسه
public long Id { get; init; }
}
@@ -0,0 +1,22 @@
namespace CMSMicroservice.Application.UserWalletHistoryCQ.Queries.GetUserWalletHistory;
public class GetUserWalletHistoryQueryHandler : IRequestHandler<GetUserWalletHistoryQuery, GetUserWalletHistoryResponseDto>
{
private readonly IApplicationDbContext _context;
public GetUserWalletHistoryQueryHandler(IApplicationDbContext context)
{
_context = context;
}
public async Task<GetUserWalletHistoryResponseDto> Handle(GetUserWalletHistoryQuery request,
CancellationToken cancellationToken)
{
var response = await _context.UserWalletHistories
.AsNoTracking()
.Where(x => x.Id == request.Id)
.ProjectToType<GetUserWalletHistoryResponseDto>()
.FirstOrDefaultAsync(cancellationToken);
return response ?? throw new NotFoundException(nameof(UserWalletHistory), request.Id);
}
}
@@ -1,14 +1,14 @@
namespace CMSMicroservice.Application.UserWalletChangeLogCQ.Queries.GetUserWalletChangeLog; namespace CMSMicroservice.Application.UserWalletHistoryCQ.Queries.GetUserWalletHistory;
public class GetUserWalletChangeLogQueryValidator : AbstractValidator<GetUserWalletChangeLogQuery> public class GetUserWalletHistoryQueryValidator : AbstractValidator<GetUserWalletHistoryQuery>
{ {
public GetUserWalletChangeLogQueryValidator() public GetUserWalletHistoryQueryValidator()
{ {
RuleFor(model => model.Id) RuleFor(model => model.Id)
.NotNull(); .NotNull();
} }
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) => public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{ {
var result = await ValidateAsync(ValidationContext<GetUserWalletChangeLogQuery>.CreateWithOptions((GetUserWalletChangeLogQuery)model, x => x.IncludeProperties(propertyName))); var result = await ValidateAsync(ValidationContext<GetUserWalletHistoryQuery>.CreateWithOptions((GetUserWalletHistoryQuery)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid) if (result.IsValid)
return Array.Empty<string>(); return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage); return result.Errors.Select(e => e.ErrorMessage);
@@ -1,5 +1,5 @@
namespace CMSMicroservice.Application.UserWalletChangeLogCQ.Queries.GetUserWalletChangeLog; namespace CMSMicroservice.Application.UserWalletHistoryCQ.Queries.GetUserWalletHistory;
public class GetUserWalletChangeLogResponseDto public class GetUserWalletHistoryResponseDto
{ {
//شناسه //شناسه
public long Id { get; set; } public long Id { get; set; }
@@ -115,7 +115,7 @@ public class VerifyDiscountWalletChargeCommandHandler
await _context.SaveChangesAsync(cancellationToken); await _context.SaveChangesAsync(cancellationToken);
// ثبت لاگ تغییرات کیف پول (بعد از ایجاد Transaction برای داشتن TransactionId) // ثبت لاگ تغییرات کیف پول (بعد از ایجاد Transaction برای داشتن TransactionId)
_context.UserWalletChangeLogs.Add(new Domain.Entities.UserWalletChangeLog _context.UserWalletHistories.Add(new Domain.Entities.UserWalletHistory
{ {
WalletId = wallet.Id, WalletId = wallet.Id,
CurrentBalance = wallet.Balance, CurrentBalance = wallet.Balance,
@@ -167,8 +167,8 @@ public class VerifyMagicWalletChargeCommandHandler
wallet.MagicTotalDeposited += depositAmount; wallet.MagicTotalDeposited += depositAmount;
wallet.MagicTotalCredited += creditAmount; wallet.MagicTotalCredited += creditAmount;
// 9. ثبت WalletChangeLog (اجباری) // 9. ثبت WalletHistory (اجباری)
var walletLog = new UserWalletChangeLog var walletLog = new UserWalletHistory
{ {
WalletId = wallet.Id, WalletId = wallet.Id,
CurrentBalance = wallet.Balance, CurrentBalance = wallet.Balance,
@@ -181,7 +181,7 @@ public class VerifyMagicWalletChargeCommandHandler
RefrenceId = depositTransaction.Id RefrenceId = depositTransaction.Id
}; };
_context.UserWalletChangeLogs.Add(walletLog); _context.UserWalletHistories.Add(walletLog);
// 10. لینک PaymentTransaction به Transaction داخلی // 10. لینک PaymentTransaction به Transaction داخلی
paymentTx.TransactionId = depositTransaction.Id; paymentTx.TransactionId = depositTransaction.Id;
@@ -0,0 +1,19 @@
namespace CMSMicroservice.Domain.Common;
/// <summary>
/// اینترفیس مارکر برای entityهایی که تاریخچه تغییرات خودکار دارند (Q27).
/// هر entity که این اینترفیس رو implement کنه، در SaveChanges interceptor
/// به‌صورت خودکار یک snapshot از تغییرات ثبت می‌شه.
/// </summary>
/// <typeparam name="THistory">نوع entity تاریخچه (مثلاً PackageHistory)</typeparam>
public interface IHasHistory<THistory> where THistory : BaseAuditableEntity, new()
{
/// <summary>
/// ساخت snapshot تاریخچه از وضعیت فعلی entity.
/// اطلاعات Original (قبل از تغییر) و Current (بعد از تغییر) باید مقایسه شوند.
/// </summary>
/// <param name="action">نوع عملیات (Created, Updated, etc.) — as string to be generic</param>
/// <param name="performedBy">چه کسی انجام داده</param>
/// <returns>یک رکورد تاریخچه آماده ذخیره</returns>
THistory CreateHistorySnapshot(string action, string? performedBy);
}
+23 -1
View File
@@ -1,9 +1,12 @@
using CMSMicroservice.Domain.Common;
using CMSMicroservice.Domain.Enums;
namespace CMSMicroservice.Domain.Entities; namespace CMSMicroservice.Domain.Entities;
/// <summary> /// <summary>
/// پکیج — هر پکیج قیمت، ویژگی‌ها و تنظیمات مستقل دارد /// پکیج — هر پکیج قیمت، ویژگی‌ها و تنظیمات مستقل دارد
/// </summary> /// </summary>
public class Package : BaseAuditableEntity public class Package : BaseAuditableEntity, IHasHistory<History.PackageHistory>
{ {
// === فیلدهای فعلی (حفظ) === // === فیلدهای فعلی (حفظ) ===
@@ -76,4 +79,23 @@ public class Package : BaseAuditableEntity
/// <summary>تاریخچه تغییرات پکیج (Q27)</summary> /// <summary>تاریخچه تغییرات پکیج (Q27)</summary>
public virtual ICollection<History.PackageHistory>? PackageHistories { get; set; } public virtual ICollection<History.PackageHistory>? PackageHistories { get; set; }
/// <summary>
/// ساخت snapshot تاریخچه — Q27 auto-tracking
/// </summary>
public History.PackageHistory CreateHistorySnapshot(string action, string? performedBy)
{
return new History.PackageHistory
{
PackageId = Id,
NewPrice = Price,
NewActivationFee = ActivationFee,
NewMagicMultiplier = MagicWalletMultiplier,
NewMagicMaxDeposit = MagicWalletMaxDeposit,
NewMaxBalancesPerLeg = MaxBalancesPerLeg,
NewIsActive = IsActive,
Action = Enum.TryParse<PackageAction>(action, out var a) ? a : PackageAction.Updated,
PerformedBy = performedBy
};
}
} }
@@ -48,6 +48,6 @@ public class UserWallet : BaseAuditableEntity
#endregion #endregion
//UserWalletChangeLog Collection Navigation Reference //UserWalletHistory Collection Navigation Reference
public virtual ICollection<UserWalletChangeLog> UserWalletChangeLogs { get; set; } public virtual ICollection<UserWalletHistory> UserWalletHistories { get; set; }
} }
@@ -1,6 +1,6 @@
namespace CMSMicroservice.Domain.Entities; namespace CMSMicroservice.Domain.Entities;
//آدرس کاربر //آدرس کاربر
public class UserWalletChangeLog : BaseAuditableEntity public class UserWalletHistory : BaseAuditableEntity
{ {
//شناسه کیف پول //شناسه کیف پول
public long WalletId { get; set; } public long WalletId { get; set; }
@@ -1,8 +0,0 @@
namespace CMSMicroservice.Domain.Events;
public class CreateNewUserWalletChangeLogEvent : BaseEvent
{
public CreateNewUserWalletChangeLogEvent(UserWalletChangeLog item)
{
}
public UserWalletChangeLog Item { get; }
}
@@ -1,8 +0,0 @@
namespace CMSMicroservice.Domain.Events;
public class DeleteUserWalletChangeLogEvent : BaseEvent
{
public DeleteUserWalletChangeLogEvent(UserWalletChangeLog item)
{
}
public UserWalletChangeLog Item { get; }
}
@@ -1,8 +0,0 @@
namespace CMSMicroservice.Domain.Events;
public class UpdateUserWalletChangeLogEvent : BaseEvent
{
public UpdateUserWalletChangeLogEvent(UserWalletChangeLog item)
{
}
public UserWalletChangeLog Item { get; }
}
@@ -0,0 +1,8 @@
namespace CMSMicroservice.Domain.Events;
public class CreateNewUserWalletHistoryEvent : BaseEvent
{
public CreateNewUserWalletHistoryEvent(UserWalletHistory item)
{
}
public UserWalletHistory Item { get; }
}
@@ -0,0 +1,8 @@
namespace CMSMicroservice.Domain.Events;
public class DeleteUserWalletHistoryEvent : BaseEvent
{
public DeleteUserWalletHistoryEvent(UserWalletHistory item)
{
}
public UserWalletHistory Item { get; }
}
@@ -0,0 +1,8 @@
namespace CMSMicroservice.Domain.Events;
public class UpdateUserWalletHistoryEvent : BaseEvent
{
public UpdateUserWalletHistoryEvent(UserWalletHistory item)
{
}
public UserWalletHistory Item { get; }
}
@@ -31,6 +31,7 @@ public static class ConfigureServices
services.Configure<SmsSettings>(configuration.GetSection(SmsSettings.SectionName)); services.Configure<SmsSettings>(configuration.GetSection(SmsSettings.SectionName));
services.AddScoped<AuditableEntitySaveChangesInterceptor>(); services.AddScoped<AuditableEntitySaveChangesInterceptor>();
services.AddScoped<HistoryTrackingSaveChangesInterceptor>();
services.AddScoped<ApplicationDbContextInitialiser>(); services.AddScoped<ApplicationDbContextInitialiser>();
services.AddScoped<IGenerateJwtToken, GenerateJwtTokenService>(); services.AddScoped<IGenerateJwtToken, GenerateJwtTokenService>();
services.AddScoped<IHashService, HashService>(); services.AddScoped<IHashService, HashService>();
@@ -18,6 +18,7 @@ public class ApplicationDbContext : DbContext, IApplicationDbContext
{ {
private readonly IMediator? _mediator; private readonly IMediator? _mediator;
private readonly AuditableEntitySaveChangesInterceptor? _auditableEntitySaveChangesInterceptor; private readonly AuditableEntitySaveChangesInterceptor? _auditableEntitySaveChangesInterceptor;
private readonly HistoryTrackingSaveChangesInterceptor? _historyTrackingInterceptor;
/// <summary> /// <summary>
/// Constructor برای design-time (migrations) /// Constructor برای design-time (migrations)
@@ -33,11 +34,13 @@ public class ApplicationDbContext : DbContext, IApplicationDbContext
public ApplicationDbContext( public ApplicationDbContext(
DbContextOptions<ApplicationDbContext> options, DbContextOptions<ApplicationDbContext> options,
IMediator mediator, IMediator mediator,
AuditableEntitySaveChangesInterceptor auditableEntitySaveChangesInterceptor) AuditableEntitySaveChangesInterceptor auditableEntitySaveChangesInterceptor,
HistoryTrackingSaveChangesInterceptor historyTrackingInterceptor)
: base(options) : base(options)
{ {
_mediator = mediator; _mediator = mediator;
_auditableEntitySaveChangesInterceptor = auditableEntitySaveChangesInterceptor; _auditableEntitySaveChangesInterceptor = auditableEntitySaveChangesInterceptor;
_historyTrackingInterceptor = historyTrackingInterceptor;
} }
protected override void OnModelCreating(ModelBuilder builder) protected override void OnModelCreating(ModelBuilder builder)
{ {
@@ -57,6 +60,11 @@ public class ApplicationDbContext : DbContext, IApplicationDbContext
optionsBuilder.AddInterceptors(_auditableEntitySaveChangesInterceptor); optionsBuilder.AddInterceptors(_auditableEntitySaveChangesInterceptor);
} }
if (_historyTrackingInterceptor != null)
{
optionsBuilder.AddInterceptors(_historyTrackingInterceptor);
}
// Suppress PendingModelChangesWarning in EF Core 9 // Suppress PendingModelChangesWarning in EF Core 9
optionsBuilder.ConfigureWarnings(w => w.Ignore(RelationalEventId.PendingModelChangesWarning)); optionsBuilder.ConfigureWarnings(w => w.Ignore(RelationalEventId.PendingModelChangesWarning));
} }
@@ -89,7 +97,7 @@ public class ApplicationDbContext : DbContext, IApplicationDbContext
public DbSet<OrderVAT> OrderVATs => Set<OrderVAT>(); public DbSet<OrderVAT> OrderVATs => Set<OrderVAT>();
public DbSet<UserPackagePurchase> UserPackagePurchases => Set<UserPackagePurchase>(); public DbSet<UserPackagePurchase> UserPackagePurchases => Set<UserPackagePurchase>();
public DbSet<UserWallet> UserWallets => Set<UserWallet>(); public DbSet<UserWallet> UserWallets => Set<UserWallet>();
public DbSet<UserWalletChangeLog> UserWalletChangeLogs => Set<UserWalletChangeLog>(); public DbSet<UserWalletHistory> UserWalletHistories => Set<UserWalletHistory>();
public DbSet<DayaLoanContract> DayaLoanContracts => Set<DayaLoanContract>(); public DbSet<DayaLoanContract> DayaLoanContracts => Set<DayaLoanContract>();
// Payment // Payment
@@ -3,9 +3,9 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace CMSMicroservice.Infrastructure.Persistence.Configurations; namespace CMSMicroservice.Infrastructure.Persistence.Configurations;
//آدرس کاربر //آدرس کاربر
public class UserWalletChangeLogConfiguration : IEntityTypeConfiguration<UserWalletChangeLog> public class UserWalletHistoryConfiguration : IEntityTypeConfiguration<UserWalletHistory>
{ {
public void Configure(EntityTypeBuilder<UserWalletChangeLog> builder) public void Configure(EntityTypeBuilder<UserWalletHistory> builder)
{ {
builder.HasQueryFilter(p => !p.IsDeleted); builder.HasQueryFilter(p => !p.IsDeleted);
builder.Ignore(entity => entity.DomainEvents); builder.Ignore(entity => entity.DomainEvents);
@@ -13,7 +13,7 @@ public class UserWalletChangeLogConfiguration : IEntityTypeConfiguration<UserWal
builder.Property(entity => entity.Id).UseIdentityColumn(); builder.Property(entity => entity.Id).UseIdentityColumn();
builder builder
.HasOne(entity => entity.Wallet) .HasOne(entity => entity.Wallet)
.WithMany(entity => entity.UserWalletChangeLogs) .WithMany(entity => entity.UserWalletHistories)
.HasForeignKey(entity => entity.WalletId) .HasForeignKey(entity => entity.WalletId)
.IsRequired(true); .IsRequired(true);
builder.Property(entity => entity.CurrentBalance).IsRequired(true); builder.Property(entity => entity.CurrentBalance).IsRequired(true);
@@ -0,0 +1,150 @@
using System.Collections.Generic;
using System.Linq;
using CMSMicroservice.Application.Common.Interfaces;
using CMSMicroservice.Domain.Common;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.Extensions.Logging;
namespace CMSMicroservice.Infrastructure.Persistence.Interceptors;
/// <summary>
/// Interceptor ثبت خودکار تاریخچه تغییرات (Q27).
/// هر entity که IHasHistory&lt;T&gt; رو implement کرده باشه،
/// هنگام Modified یا Added شدن یک رکورد history ثبت می‌شه.
/// </summary>
public class HistoryTrackingSaveChangesInterceptor : SaveChangesInterceptor
{
private readonly ICurrentUserService _currentUserService;
private readonly ILogger<HistoryTrackingSaveChangesInterceptor> _logger;
public HistoryTrackingSaveChangesInterceptor(
ICurrentUserService currentUserService,
ILogger<HistoryTrackingSaveChangesInterceptor> logger)
{
_currentUserService = currentUserService;
_logger = logger;
}
public override InterceptionResult<int> SavingChanges(
DbContextEventData eventData,
InterceptionResult<int> result)
{
TrackHistoryChanges(eventData.Context);
return base.SavingChanges(eventData, result);
}
public override ValueTask<InterceptionResult<int>> SavingChangesAsync(
DbContextEventData eventData,
InterceptionResult<int> result,
CancellationToken cancellationToken = default)
{
TrackHistoryChanges(eventData.Context);
return base.SavingChangesAsync(eventData, result, cancellationToken);
}
private void TrackHistoryChanges(DbContext? context)
{
if (context == null) return;
var performedBy = _currentUserService.GetPerformedBy();
var historyEntries = new List<object>();
foreach (var entry in context.ChangeTracker.Entries())
{
// فقط Modified و Added — Deleted رو ignore می‌کنیم (soft delete)
if (entry.State != EntityState.Modified && entry.State != EntityState.Added)
continue;
var entityType = entry.Entity.GetType();
// بررسی اینکه entity آیا IHasHistory<T> رو implement کرده
var historyInterface = entityType.GetInterfaces()
.FirstOrDefault(i => i.IsGenericType
&& i.GetGenericTypeDefinition() == typeof(IHasHistory<>));
if (historyInterface == null)
continue;
// تعیین نوع عملیات
var action = entry.State == EntityState.Added ? "Created" : "Updated";
try
{
// فراخوانی CreateHistorySnapshot از طریق reflection
var method = historyInterface.GetMethod("CreateHistorySnapshot");
if (method == null) continue;
var historyEntity = method.Invoke(entry.Entity, new object?[] { action, performedBy });
if (historyEntity == null) continue;
// برای Modified: مقادیر Original رو ست کنیم
if (entry.State == EntityState.Modified)
{
SetOriginalValues(entry, historyEntity);
}
historyEntries.Add(historyEntity);
}
catch (Exception ex)
{
_logger.LogWarning(ex,
"Failed to create history snapshot for {EntityType} (Id={Id})",
entityType.Name,
entry.Property("Id").CurrentValue);
}
}
// اضافه کردن history entities به context
foreach (var historyEntry in historyEntries)
{
context.Add(historyEntry);
}
if (historyEntries.Count > 0)
{
_logger.LogDebug("HistoryTrackingInterceptor: {Count} history records queued", historyEntries.Count);
}
}
/// <summary>
/// ست کردن مقادیر Original (قبل از تغییر) روی history entity.
/// از روی نام property: "OldX" ← OriginalValue("X"), "NewX" ← CurrentValue("X")
/// </summary>
private static void SetOriginalValues(
Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry entry,
object historyEntity)
{
var historyType = historyEntity.GetType();
var historyProps = historyType.GetProperties();
foreach (var historyProp in historyProps)
{
// الگو: OldPrice ← entry.OriginalValues["Price"]
if (!historyProp.Name.StartsWith("Old") || !historyProp.CanWrite)
continue;
var sourcePropertyName = historyProp.Name[3..]; // "OldPrice" → "Price"
try
{
var entryProperty = entry.Properties
.FirstOrDefault(p => p.Metadata.Name == sourcePropertyName);
if (entryProperty != null)
{
var originalValue = entryProperty.OriginalValue;
// تبدیل نوع اگه nullable باشه
if (originalValue != null || Nullable.GetUnderlyingType(historyProp.PropertyType) != null)
{
historyProp.SetValue(historyEntity, originalValue);
}
}
}
catch
{
// اگه property match نداشت، skip — ممکنه OldIsActive با bool? باشه
}
}
}
}
@@ -0,0 +1,190 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace CMSMicroservice.Infrastructure.Persistence.Migrations
{
/// <inheritdoc />
public partial class Q27_HistoryTables_And_RenameWalletHistory : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.RenameTable(
name: "UserWalletChangeLogs",
schema: "CMS",
newName: "UserWalletHistories",
newSchema: "CMS");
migrationBuilder.RenameIndex(
name: "IX_UserWalletChangeLogs_PackageId",
schema: "CMS",
table: "UserWalletHistories",
newName: "IX_UserWalletHistories_PackageId");
migrationBuilder.RenameIndex(
name: "IX_UserWalletChangeLogs_WalletId",
schema: "CMS",
table: "UserWalletHistories",
newName: "IX_UserWalletHistories_WalletId");
migrationBuilder.Sql(
"EXEC sp_rename N'CMS.PK_UserWalletChangeLogs', N'PK_UserWalletHistories', N'OBJECT'");
migrationBuilder.Sql(
"EXEC sp_rename N'CMS.FK_UserWalletChangeLogs_Packages_PackageId', N'FK_UserWalletHistories_Packages_PackageId', N'OBJECT'");
migrationBuilder.Sql(
"EXEC sp_rename N'CMS.FK_UserWalletChangeLogs_UserWallets_WalletId', N'FK_UserWalletHistories_UserWallets_WalletId', N'OBJECT'");
migrationBuilder.CreateTable(
name: "ClubMembershipCycleHistories",
schema: "CMS",
columns: table => new
{
Id = table.Column<long>(type: "bigint", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
ClubMembershipCycleId = table.Column<long>(type: "bigint", nullable: false),
UserId = table.Column<long>(type: "bigint", nullable: false),
CycleNumber = table.Column<int>(type: "int", nullable: false),
OldIsCurrentCycle = table.Column<bool>(type: "bit", nullable: false),
NewIsCurrentCycle = table.Column<bool>(type: "bit", nullable: false),
OldMagicStartedAt = table.Column<DateTime>(type: "datetime2", nullable: true),
NewMagicStartedAt = table.Column<DateTime>(type: "datetime2", nullable: true),
OldMagicCompletedAt = table.Column<DateTime>(type: "datetime2", nullable: true),
NewMagicCompletedAt = table.Column<DateTime>(type: "datetime2", nullable: true),
Action = table.Column<int>(type: "int", nullable: false),
PerformedBy = table.Column<string>(type: "nvarchar(100)", maxLength: 100, nullable: true),
Reason = table.Column<string>(type: "nvarchar(500)", maxLength: 500, nullable: true),
Created = table.Column<DateTime>(type: "datetime2", nullable: false),
CreatedBy = table.Column<string>(type: "nvarchar(max)", nullable: true),
LastModified = table.Column<DateTime>(type: "datetime2", nullable: true),
LastModifiedBy = table.Column<string>(type: "nvarchar(max)", nullable: true),
IsDeleted = table.Column<bool>(type: "bit", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ClubMembershipCycleHistories", x => x.Id);
table.ForeignKey(
name: "FK_ClubMembershipCycleHistories_ClubMembershipCycles_ClubMembershipCycleId",
column: x => x.ClubMembershipCycleId,
principalSchema: "CMS",
principalTable: "ClubMembershipCycles",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "PackageHistories",
schema: "CMS",
columns: table => new
{
Id = table.Column<long>(type: "bigint", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
PackageId = table.Column<long>(type: "bigint", nullable: false),
OldPrice = table.Column<long>(type: "bigint", nullable: true),
NewPrice = table.Column<long>(type: "bigint", nullable: true),
OldActivationFee = table.Column<long>(type: "bigint", nullable: true),
NewActivationFee = table.Column<long>(type: "bigint", nullable: true),
OldMagicMultiplier = table.Column<decimal>(type: "decimal(18,4)", precision: 18, scale: 4, nullable: true),
NewMagicMultiplier = table.Column<decimal>(type: "decimal(18,4)", precision: 18, scale: 4, nullable: true),
OldMagicMaxDeposit = table.Column<long>(type: "bigint", nullable: true),
NewMagicMaxDeposit = table.Column<long>(type: "bigint", nullable: true),
OldMaxBalancesPerLeg = table.Column<int>(type: "int", nullable: true),
NewMaxBalancesPerLeg = table.Column<int>(type: "int", nullable: true),
OldIsActive = table.Column<bool>(type: "bit", nullable: true),
NewIsActive = table.Column<bool>(type: "bit", nullable: true),
Action = table.Column<int>(type: "int", nullable: false),
PerformedBy = table.Column<string>(type: "nvarchar(100)", maxLength: 100, nullable: true),
Reason = table.Column<string>(type: "nvarchar(500)", maxLength: 500, nullable: true),
Created = table.Column<DateTime>(type: "datetime2", nullable: false),
CreatedBy = table.Column<string>(type: "nvarchar(max)", nullable: true),
LastModified = table.Column<DateTime>(type: "datetime2", nullable: true),
LastModifiedBy = table.Column<string>(type: "nvarchar(max)", nullable: true),
IsDeleted = table.Column<bool>(type: "bit", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_PackageHistories", x => x.Id);
table.ForeignKey(
name: "FK_PackageHistories_Packages_PackageId",
column: x => x.PackageId,
principalSchema: "CMS",
principalTable: "Packages",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateIndex(
name: "IX_ClubMembershipCycleHistory_Action",
schema: "CMS",
table: "ClubMembershipCycleHistories",
column: "Action");
migrationBuilder.CreateIndex(
name: "IX_ClubMembershipCycleHistory_CycleId",
schema: "CMS",
table: "ClubMembershipCycleHistories",
column: "ClubMembershipCycleId");
migrationBuilder.CreateIndex(
name: "IX_ClubMembershipCycleHistory_UserId_Created",
schema: "CMS",
table: "ClubMembershipCycleHistories",
columns: new[] { "UserId", "Created" });
migrationBuilder.CreateIndex(
name: "IX_PackageHistory_Action",
schema: "CMS",
table: "PackageHistories",
column: "Action");
migrationBuilder.CreateIndex(
name: "IX_PackageHistory_PackageId_Created",
schema: "CMS",
table: "PackageHistories",
columns: new[] { "PackageId", "Created" });
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "ClubMembershipCycleHistories",
schema: "CMS");
migrationBuilder.DropTable(
name: "PackageHistories",
schema: "CMS");
migrationBuilder.RenameTable(
name: "UserWalletHistories",
schema: "CMS",
newName: "UserWalletChangeLogs",
newSchema: "CMS");
migrationBuilder.RenameIndex(
name: "IX_UserWalletHistories_PackageId",
schema: "CMS",
table: "UserWalletChangeLogs",
newName: "IX_UserWalletChangeLogs_PackageId");
migrationBuilder.RenameIndex(
name: "IX_UserWalletHistories_WalletId",
schema: "CMS",
table: "UserWalletChangeLogs",
newName: "IX_UserWalletChangeLogs_WalletId");
migrationBuilder.Sql(
"EXEC sp_rename N'CMS.PK_UserWalletHistories', N'PK_UserWalletChangeLogs', N'OBJECT'");
migrationBuilder.Sql(
"EXEC sp_rename N'CMS.FK_UserWalletHistories_Packages_PackageId', N'FK_UserWalletChangeLogs_Packages_PackageId', N'OBJECT'");
migrationBuilder.Sql(
"EXEC sp_rename N'CMS.FK_UserWalletHistories_UserWallets_WalletId', N'FK_UserWalletChangeLogs_UserWallets_WalletId', N'OBJECT'");
}
}
}
@@ -1935,6 +1935,81 @@ namespace CMSMicroservice.Infrastructure.Persistence.Migrations
b.ToTable("States", "GMS"); b.ToTable("States", "GMS");
}); });
modelBuilder.Entity("CMSMicroservice.Domain.Entities.History.ClubMembershipCycleHistory", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"));
b.Property<int>("Action")
.HasColumnType("int");
b.Property<long>("ClubMembershipCycleId")
.HasColumnType("bigint");
b.Property<DateTime>("Created")
.HasColumnType("datetime2");
b.Property<string>("CreatedBy")
.HasColumnType("nvarchar(max)");
b.Property<int>("CycleNumber")
.HasColumnType("int");
b.Property<bool>("IsDeleted")
.HasColumnType("bit");
b.Property<DateTime?>("LastModified")
.HasColumnType("datetime2");
b.Property<string>("LastModifiedBy")
.HasColumnType("nvarchar(max)");
b.Property<bool>("NewIsCurrentCycle")
.HasColumnType("bit");
b.Property<DateTime?>("NewMagicCompletedAt")
.HasColumnType("datetime2");
b.Property<DateTime?>("NewMagicStartedAt")
.HasColumnType("datetime2");
b.Property<bool>("OldIsCurrentCycle")
.HasColumnType("bit");
b.Property<DateTime?>("OldMagicCompletedAt")
.HasColumnType("datetime2");
b.Property<DateTime?>("OldMagicStartedAt")
.HasColumnType("datetime2");
b.Property<string>("PerformedBy")
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
b.Property<string>("Reason")
.HasMaxLength(500)
.HasColumnType("nvarchar(500)");
b.Property<long>("UserId")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("Action")
.HasDatabaseName("IX_ClubMembershipCycleHistory_Action");
b.HasIndex("ClubMembershipCycleId")
.HasDatabaseName("IX_ClubMembershipCycleHistory_CycleId");
b.HasIndex("UserId", "Created")
.HasDatabaseName("IX_ClubMembershipCycleHistory_UserId_Created");
b.ToTable("ClubMembershipCycleHistories", "CMS");
});
modelBuilder.Entity("CMSMicroservice.Domain.Entities.History.ClubMembershipHistory", b => modelBuilder.Entity("CMSMicroservice.Domain.Entities.History.ClubMembershipHistory", b =>
{ {
b.Property<long>("Id") b.Property<long>("Id")
@@ -2133,6 +2208,92 @@ namespace CMSMicroservice.Infrastructure.Persistence.Migrations
b.ToTable("NetworkMembershipHistories", "CMS"); b.ToTable("NetworkMembershipHistories", "CMS");
}); });
modelBuilder.Entity("CMSMicroservice.Domain.Entities.History.PackageHistory", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"));
b.Property<int>("Action")
.HasColumnType("int");
b.Property<DateTime>("Created")
.HasColumnType("datetime2");
b.Property<string>("CreatedBy")
.HasColumnType("nvarchar(max)");
b.Property<bool>("IsDeleted")
.HasColumnType("bit");
b.Property<DateTime?>("LastModified")
.HasColumnType("datetime2");
b.Property<string>("LastModifiedBy")
.HasColumnType("nvarchar(max)");
b.Property<long?>("NewActivationFee")
.HasColumnType("bigint");
b.Property<bool?>("NewIsActive")
.HasColumnType("bit");
b.Property<long?>("NewMagicMaxDeposit")
.HasColumnType("bigint");
b.Property<decimal?>("NewMagicMultiplier")
.HasPrecision(18, 4)
.HasColumnType("decimal(18,4)");
b.Property<int?>("NewMaxBalancesPerLeg")
.HasColumnType("int");
b.Property<long?>("NewPrice")
.HasColumnType("bigint");
b.Property<long?>("OldActivationFee")
.HasColumnType("bigint");
b.Property<bool?>("OldIsActive")
.HasColumnType("bit");
b.Property<long?>("OldMagicMaxDeposit")
.HasColumnType("bigint");
b.Property<decimal?>("OldMagicMultiplier")
.HasPrecision(18, 4)
.HasColumnType("decimal(18,4)");
b.Property<int?>("OldMaxBalancesPerLeg")
.HasColumnType("int");
b.Property<long?>("OldPrice")
.HasColumnType("bigint");
b.Property<long>("PackageId")
.HasColumnType("bigint");
b.Property<string>("PerformedBy")
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
b.Property<string>("Reason")
.HasMaxLength(500)
.HasColumnType("nvarchar(500)");
b.HasKey("Id");
b.HasIndex("Action")
.HasDatabaseName("IX_PackageHistory_Action");
b.HasIndex("PackageId", "Created")
.HasDatabaseName("IX_PackageHistory_PackageId_Created");
b.ToTable("PackageHistories", "CMS");
});
modelBuilder.Entity("CMSMicroservice.Domain.Entities.InventoryItem", b => modelBuilder.Entity("CMSMicroservice.Domain.Entities.InventoryItem", b =>
{ {
b.Property<long>("Id") b.Property<long>("Id")
@@ -3826,7 +3987,7 @@ namespace CMSMicroservice.Infrastructure.Persistence.Migrations
b.ToTable("UserWallets", "CMS"); b.ToTable("UserWallets", "CMS");
}); });
modelBuilder.Entity("CMSMicroservice.Domain.Entities.UserWalletChangeLog", b => modelBuilder.Entity("CMSMicroservice.Domain.Entities.UserWalletHistory", b =>
{ {
b.Property<long>("Id") b.Property<long>("Id")
.ValueGeneratedOnAdd() .ValueGeneratedOnAdd()
@@ -3885,7 +4046,7 @@ namespace CMSMicroservice.Infrastructure.Persistence.Migrations
b.HasIndex("WalletId"); b.HasIndex("WalletId");
b.ToTable("UserWalletChangeLogs", "CMS"); b.ToTable("UserWalletHistories", "CMS");
}); });
modelBuilder.Entity("CMSMicroservice.Domain.Entities.Warehouse", b => modelBuilder.Entity("CMSMicroservice.Domain.Entities.Warehouse", b =>
@@ -4430,6 +4591,17 @@ namespace CMSMicroservice.Infrastructure.Persistence.Migrations
b.Navigation("Country"); b.Navigation("Country");
}); });
modelBuilder.Entity("CMSMicroservice.Domain.Entities.History.ClubMembershipCycleHistory", b =>
{
b.HasOne("CMSMicroservice.Domain.Entities.Club.ClubMembershipCycle", "ClubMembershipCycle")
.WithMany("CycleHistories")
.HasForeignKey("ClubMembershipCycleId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.Navigation("ClubMembershipCycle");
});
modelBuilder.Entity("CMSMicroservice.Domain.Entities.History.ClubMembershipHistory", b => modelBuilder.Entity("CMSMicroservice.Domain.Entities.History.ClubMembershipHistory", b =>
{ {
b.HasOne("CMSMicroservice.Domain.Entities.Club.ClubMembership", "ClubMembership") b.HasOne("CMSMicroservice.Domain.Entities.Club.ClubMembership", "ClubMembership")
@@ -4460,6 +4632,17 @@ namespace CMSMicroservice.Infrastructure.Persistence.Migrations
b.Navigation("WeekDefinition"); b.Navigation("WeekDefinition");
}); });
modelBuilder.Entity("CMSMicroservice.Domain.Entities.History.PackageHistory", b =>
{
b.HasOne("CMSMicroservice.Domain.Entities.Package", "Package")
.WithMany("PackageHistories")
.HasForeignKey("PackageId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.Navigation("Package");
});
modelBuilder.Entity("CMSMicroservice.Domain.Entities.InventoryItem", b => modelBuilder.Entity("CMSMicroservice.Domain.Entities.InventoryItem", b =>
{ {
b.HasOne("CMSMicroservice.Domain.Entities.DiscountShop.DiscountProduct", "DiscountProduct") b.HasOne("CMSMicroservice.Domain.Entities.DiscountShop.DiscountProduct", "DiscountProduct")
@@ -4781,7 +4964,7 @@ namespace CMSMicroservice.Infrastructure.Persistence.Migrations
b.Navigation("User"); b.Navigation("User");
}); });
modelBuilder.Entity("CMSMicroservice.Domain.Entities.UserWalletChangeLog", b => modelBuilder.Entity("CMSMicroservice.Domain.Entities.UserWalletHistory", b =>
{ {
b.HasOne("CMSMicroservice.Domain.Entities.Package", "Package") b.HasOne("CMSMicroservice.Domain.Entities.Package", "Package")
.WithMany() .WithMany()
@@ -4789,7 +4972,7 @@ namespace CMSMicroservice.Infrastructure.Persistence.Migrations
.OnDelete(DeleteBehavior.Restrict); .OnDelete(DeleteBehavior.Restrict);
b.HasOne("CMSMicroservice.Domain.Entities.UserWallet", "Wallet") b.HasOne("CMSMicroservice.Domain.Entities.UserWallet", "Wallet")
.WithMany("UserWalletChangeLogs") .WithMany("UserWalletHistories")
.HasForeignKey("WalletId") .HasForeignKey("WalletId")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
.IsRequired(); .IsRequired();
@@ -4834,6 +5017,11 @@ namespace CMSMicroservice.Infrastructure.Persistence.Migrations
b.Navigation("UserClubFeatures"); b.Navigation("UserClubFeatures");
}); });
modelBuilder.Entity("CMSMicroservice.Domain.Entities.Club.ClubMembershipCycle", b =>
{
b.Navigation("CycleHistories");
});
modelBuilder.Entity("CMSMicroservice.Domain.Entities.Commission.UserCommissionPayout", b => modelBuilder.Entity("CMSMicroservice.Domain.Entities.Commission.UserCommissionPayout", b =>
{ {
b.Navigation("CommissionPayoutHistories"); b.Navigation("CommissionPayoutHistories");
@@ -4901,6 +5089,8 @@ namespace CMSMicroservice.Infrastructure.Persistence.Migrations
{ {
b.Navigation("PackageFeatures"); b.Navigation("PackageFeatures");
b.Navigation("PackageHistories");
b.Navigation("Purchases"); b.Navigation("Purchases");
b.Navigation("UserOrders"); b.Navigation("UserOrders");
@@ -4984,7 +5174,7 @@ namespace CMSMicroservice.Infrastructure.Persistence.Migrations
modelBuilder.Entity("CMSMicroservice.Domain.Entities.UserWallet", b => modelBuilder.Entity("CMSMicroservice.Domain.Entities.UserWallet", b =>
{ {
b.Navigation("UserWalletChangeLogs"); b.Navigation("UserWalletHistories");
}); });
modelBuilder.Entity("CMSMicroservice.Domain.Entities.Warehouse", b => modelBuilder.Entity("CMSMicroservice.Domain.Entities.Warehouse", b =>
@@ -471,7 +471,7 @@ public class OrmCommissionCalculationStrategy : ICommissionCalculationStrategy
.ToDictionaryAsync(w => w.UserId, cancellationToken); .ToDictionaryAsync(w => w.UserId, cancellationToken);
var newWallets = new List<UserWallet>(); var newWallets = new List<UserWallet>();
var walletLogs = new List<UserWalletChangeLog>(); var walletLogs = new List<UserWalletHistory>();
foreach (var payout in payouts) foreach (var payout in payouts)
{ {
@@ -510,7 +510,7 @@ public class OrmCommissionCalculationStrategy : ICommissionCalculationStrategy
var wallet = existingWallets[payout.UserId]; var wallet = existingWallets[payout.UserId];
wallet.NetworkBalance += payout.TotalAmount; wallet.NetworkBalance += payout.TotalAmount;
var walletLog = new UserWalletChangeLog var walletLog = new UserWalletHistory
{ {
WalletId = wallet.Id, WalletId = wallet.Id,
CurrentBalance = wallet.Balance, CurrentBalance = wallet.Balance,
@@ -526,7 +526,7 @@ public class OrmCommissionCalculationStrategy : ICommissionCalculationStrategy
walletLogs.Add(walletLog); walletLogs.Add(walletLog);
} }
await _context.UserWalletChangeLogs.AddRangeAsync(walletLogs, cancellationToken); await _context.UserWalletHistories.AddRangeAsync(walletLogs, cancellationToken);
await _context.SaveChangesAsync(cancellationToken); await _context.SaveChangesAsync(cancellationToken);
} }
@@ -534,7 +534,7 @@ public class OrmCommissionCalculationStrategy : ICommissionCalculationStrategy
List<long> oldPayoutIds, List<long> oldPayoutIds,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
var oldWalletLogs = await _context.UserWalletChangeLogs var oldWalletLogs = await _context.UserWalletHistories
.Where(l => l.RefrenceId.HasValue && oldPayoutIds.Contains(l.RefrenceId.Value)) .Where(l => l.RefrenceId.HasValue && oldPayoutIds.Contains(l.RefrenceId.Value))
.ToListAsync(cancellationToken); .ToListAsync(cancellationToken);
@@ -557,7 +557,7 @@ public class OrmCommissionCalculationStrategy : ICommissionCalculationStrategy
} }
} }
_context.UserWalletChangeLogs.RemoveRange(oldWalletLogs); _context.UserWalletHistories.RemoveRange(oldWalletLogs);
await _context.SaveChangesAsync(cancellationToken); await _context.SaveChangesAsync(cancellationToken);
} }
@@ -29,7 +29,7 @@
<Protobuf Include="Protos\user.proto" ProtoRoot="Protos\" GrpcServices="Both" /> <Protobuf Include="Protos\user.proto" ProtoRoot="Protos\" GrpcServices="Both" />
<Protobuf Include="Protos\useraddress.proto" ProtoRoot="Protos\" GrpcServices="Both" /> <Protobuf Include="Protos\useraddress.proto" ProtoRoot="Protos\" GrpcServices="Both" />
<Protobuf Include="Protos\userwallet.proto" ProtoRoot="Protos\" GrpcServices="Both" /> <Protobuf Include="Protos\userwallet.proto" ProtoRoot="Protos\" GrpcServices="Both" />
<Protobuf Include="Protos\userwalletchangelog.proto" ProtoRoot="Protos\" GrpcServices="Both" /> <Protobuf Include="Protos\userwallethistory.proto" ProtoRoot="Protos\" GrpcServices="Both" />
<Protobuf Include="Protos\usercarts.proto" ProtoRoot="Protos\" GrpcServices="Both" /> <Protobuf Include="Protos\usercarts.proto" ProtoRoot="Protos\" GrpcServices="Both" />
<Protobuf Include="Protos\productgalleries.proto" ProtoRoot="Protos\" GrpcServices="Both" /> <Protobuf Include="Protos\productgalleries.proto" ProtoRoot="Protos\" GrpcServices="Both" />
<Protobuf Include="Protos\factordetails.proto" ProtoRoot="Protos\" GrpcServices="Both" /> <Protobuf Include="Protos\factordetails.proto" ProtoRoot="Protos\" GrpcServices="Both" />
@@ -51,9 +51,9 @@ service UserWalletContract
get: "/Customer/GetWallet" get: "/Customer/GetWallet"
}; };
}; };
rpc GetCustomerWalletChangeLog(GetCustomerWalletChangeLogRequest) returns (GetCustomerWalletChangeLogResponse){ rpc GetCustomerWalletHistory(GetCustomerWalletHistoryRequest) returns (GetCustomerWalletHistoryResponse){
option (google.api.http) = { option (google.api.http) = {
post: "/Customer/GetWalletChangeLog" post: "/Customer/GetWalletHistory"
body: "*" body: "*"
}; };
}; };
@@ -167,19 +167,19 @@ message GetCustomerWalletResponse
int32 wallet_mode = 4; // 0=Normal, 1=Magic int32 wallet_mode = 4; // 0=Normal, 1=Magic
} }
message GetCustomerWalletChangeLogRequest message GetCustomerWalletHistoryRequest
{ {
google.protobuf.Int64Value reference_id = 1; google.protobuf.Int64Value reference_id = 1;
google.protobuf.BoolValue is_increase = 2; google.protobuf.BoolValue is_increase = 2;
} }
message GetCustomerWalletChangeLogResponse message GetCustomerWalletHistoryResponse
{ {
messages.MetaData meta_data = 1; messages.MetaData meta_data = 1;
repeated CustomerWalletChangeLogModel models = 2; repeated CustomerWalletHistoryModel models = 2;
} }
message CustomerWalletChangeLogModel message CustomerWalletHistoryModel
{ {
int64 current_balance = 1; int64 current_balance = 1;
int64 change_value = 2; int64 change_value = 2;
@@ -1,6 +1,6 @@
syntax = "proto3"; syntax = "proto3";
package userwalletchangelog; package userwallethistory;
import "public_messages.proto"; import "public_messages.proto";
import "google/protobuf/empty.proto"; import "google/protobuf/empty.proto";
@@ -9,42 +9,42 @@ import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto"; import "google/protobuf/timestamp.proto";
import "google/api/annotations.proto"; import "google/api/annotations.proto";
option csharp_namespace = "CMSMicroservice.Protobuf.Protos.UserWalletChangeLog"; option csharp_namespace = "CMSMicroservice.Protobuf.Protos.UserWalletHistory";
service UserWalletChangeLogContract service UserWalletHistoryContract
{ {
rpc CreateNewUserWalletChangeLog(CreateNewUserWalletChangeLogRequest) returns (CreateNewUserWalletChangeLogResponse){ rpc CreateNewUserWalletHistory(CreateNewUserWalletHistoryRequest) returns (CreateNewUserWalletHistoryResponse){
option (google.api.http) = { option (google.api.http) = {
post: "/CreateNewUserWalletChangeLog" post: "/CreateNewUserWalletHistory"
body: "*" body: "*"
}; };
}; };
rpc UpdateUserWalletChangeLog(UpdateUserWalletChangeLogRequest) returns (google.protobuf.Empty){ rpc UpdateUserWalletHistory(UpdateUserWalletHistoryRequest) returns (google.protobuf.Empty){
option (google.api.http) = { option (google.api.http) = {
put: "/UpdateUserWalletChangeLog" put: "/UpdateUserWalletHistory"
body: "*" body: "*"
}; };
}; };
rpc DeleteUserWalletChangeLog(DeleteUserWalletChangeLogRequest) returns (google.protobuf.Empty){ rpc DeleteUserWalletHistory(DeleteUserWalletHistoryRequest) returns (google.protobuf.Empty){
option (google.api.http) = { option (google.api.http) = {
delete: "/DeleteUserWalletChangeLog" delete: "/DeleteUserWalletHistory"
body: "*" body: "*"
}; };
}; };
rpc GetUserWalletChangeLog(GetUserWalletChangeLogRequest) returns (GetUserWalletChangeLogResponse){ rpc GetUserWalletHistory(GetUserWalletHistoryRequest) returns (GetUserWalletHistoryResponse){
option (google.api.http) = { option (google.api.http) = {
get: "/GetUserWalletChangeLog" get: "/GetUserWalletHistory"
}; };
}; };
rpc GetAllUserWalletChangeLogByFilter(GetAllUserWalletChangeLogByFilterRequest) returns (GetAllUserWalletChangeLogByFilterResponse){ rpc GetAllUserWalletHistoryByFilter(GetAllUserWalletHistoryByFilterRequest) returns (GetAllUserWalletHistoryByFilterResponse){
option (google.api.http) = { option (google.api.http) = {
get: "/GetAllUserWalletChangeLogByFilter" get: "/GetAllUserWalletHistoryByFilter"
}; };
}; };
} }
message CreateNewUserWalletChangeLogRequest message CreateNewUserWalletHistoryRequest
{ {
int64 wallet_id = 1; int64 wallet_id = 1;
int64 current_balance = 2; int64 current_balance = 2;
@@ -54,11 +54,11 @@ message CreateNewUserWalletChangeLogRequest
bool is_increase = 6; bool is_increase = 6;
google.protobuf.Int64Value refrence_id = 7; google.protobuf.Int64Value refrence_id = 7;
} }
message CreateNewUserWalletChangeLogResponse message CreateNewUserWalletHistoryResponse
{ {
int64 id = 1; int64 id = 1;
} }
message UpdateUserWalletChangeLogRequest message UpdateUserWalletHistoryRequest
{ {
int64 id = 1; int64 id = 1;
int64 wallet_id = 2; int64 wallet_id = 2;
@@ -69,15 +69,15 @@ message UpdateUserWalletChangeLogRequest
bool is_increase = 7; bool is_increase = 7;
google.protobuf.Int64Value refrence_id = 8; google.protobuf.Int64Value refrence_id = 8;
} }
message DeleteUserWalletChangeLogRequest message DeleteUserWalletHistoryRequest
{ {
int64 id = 1; int64 id = 1;
} }
message GetUserWalletChangeLogRequest message GetUserWalletHistoryRequest
{ {
int64 id = 1; int64 id = 1;
} }
message GetUserWalletChangeLogResponse message GetUserWalletHistoryResponse
{ {
int64 id = 1; int64 id = 1;
int64 wallet_id = 2; int64 wallet_id = 2;
@@ -89,13 +89,13 @@ message GetUserWalletChangeLogResponse
google.protobuf.Int64Value refrence_id = 8; google.protobuf.Int64Value refrence_id = 8;
google.protobuf.Timestamp created_at = 9; google.protobuf.Timestamp created_at = 9;
} }
message GetAllUserWalletChangeLogByFilterRequest message GetAllUserWalletHistoryByFilterRequest
{ {
messages.PaginationState pagination_state = 1; messages.PaginationState pagination_state = 1;
google.protobuf.StringValue sort_by = 2; google.protobuf.StringValue sort_by = 2;
GetAllUserWalletChangeLogByFilterFilter filter = 3; GetAllUserWalletHistoryByFilterFilter filter = 3;
} }
message GetAllUserWalletChangeLogByFilterFilter message GetAllUserWalletHistoryByFilterFilter
{ {
google.protobuf.Int64Value id = 1; google.protobuf.Int64Value id = 1;
google.protobuf.Int64Value wallet_id = 2; google.protobuf.Int64Value wallet_id = 2;
@@ -105,12 +105,12 @@ message GetAllUserWalletChangeLogByFilterFilter
google.protobuf.Int64Value refrence_id = 6; google.protobuf.Int64Value refrence_id = 6;
google.protobuf.Int64Value user_id = 7; google.protobuf.Int64Value user_id = 7;
} }
message GetAllUserWalletChangeLogByFilterResponse message GetAllUserWalletHistoryByFilterResponse
{ {
messages.MetaData meta_data = 1; messages.MetaData meta_data = 1;
repeated GetAllUserWalletChangeLogByFilterResponseModel models = 2; repeated GetAllUserWalletHistoryByFilterResponseModel models = 2;
} }
message GetAllUserWalletChangeLogByFilterResponseModel message GetAllUserWalletHistoryByFilterResponseModel
{ {
int64 id = 1; int64 id = 1;
int64 wallet_id = 2; int64 wallet_id = 2;
@@ -1,19 +0,0 @@
using FluentValidation;
using CMSMicroservice.Protobuf.Protos.UserWalletChangeLog;
namespace CMSMicroservice.Protobuf.Validator.UserWalletChangeLog;
public class DeleteUserWalletChangeLogRequestValidator : AbstractValidator<DeleteUserWalletChangeLogRequest>
{
public DeleteUserWalletChangeLogRequestValidator()
{
RuleFor(model => model.Id)
.NotNull();
}
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{
var result = await ValidateAsync(ValidationContext<DeleteUserWalletChangeLogRequest>.CreateWithOptions((DeleteUserWalletChangeLogRequest)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
};
}
@@ -1,17 +0,0 @@
using FluentValidation;
using CMSMicroservice.Protobuf.Protos.UserWalletChangeLog;
namespace CMSMicroservice.Protobuf.Validator.UserWalletChangeLog;
public class GetAllUserWalletChangeLogByFilterRequestValidator : AbstractValidator<GetAllUserWalletChangeLogByFilterRequest>
{
public GetAllUserWalletChangeLogByFilterRequestValidator()
{
}
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{
var result = await ValidateAsync(ValidationContext<GetAllUserWalletChangeLogByFilterRequest>.CreateWithOptions((GetAllUserWalletChangeLogByFilterRequest)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
};
}
@@ -1,10 +1,10 @@
using FluentValidation; using FluentValidation;
using CMSMicroservice.Protobuf.Protos.UserWalletChangeLog; using CMSMicroservice.Protobuf.Protos.UserWalletHistory;
namespace CMSMicroservice.Protobuf.Validator.UserWalletChangeLog; namespace CMSMicroservice.Protobuf.Validator.UserWalletHistory;
public class CreateNewUserWalletChangeLogRequestValidator : AbstractValidator<CreateNewUserWalletChangeLogRequest> public class CreateNewUserWalletHistoryRequestValidator : AbstractValidator<CreateNewUserWalletHistoryRequest>
{ {
public CreateNewUserWalletChangeLogRequestValidator() public CreateNewUserWalletHistoryRequestValidator()
{ {
RuleFor(model => model.WalletId) RuleFor(model => model.WalletId)
.NotNull(); .NotNull();
@@ -21,7 +21,7 @@ public class CreateNewUserWalletChangeLogRequestValidator : AbstractValidator<Cr
} }
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) => public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{ {
var result = await ValidateAsync(ValidationContext<CreateNewUserWalletChangeLogRequest>.CreateWithOptions((CreateNewUserWalletChangeLogRequest)model, x => x.IncludeProperties(propertyName))); var result = await ValidateAsync(ValidationContext<CreateNewUserWalletHistoryRequest>.CreateWithOptions((CreateNewUserWalletHistoryRequest)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid) if (result.IsValid)
return Array.Empty<string>(); return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage); return result.Errors.Select(e => e.ErrorMessage);
@@ -0,0 +1,19 @@
using FluentValidation;
using CMSMicroservice.Protobuf.Protos.UserWalletHistory;
namespace CMSMicroservice.Protobuf.Validator.UserWalletHistory;
public class DeleteUserWalletHistoryRequestValidator : AbstractValidator<DeleteUserWalletHistoryRequest>
{
public DeleteUserWalletHistoryRequestValidator()
{
RuleFor(model => model.Id)
.NotNull();
}
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{
var result = await ValidateAsync(ValidationContext<DeleteUserWalletHistoryRequest>.CreateWithOptions((DeleteUserWalletHistoryRequest)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
};
}
@@ -0,0 +1,17 @@
using FluentValidation;
using CMSMicroservice.Protobuf.Protos.UserWalletHistory;
namespace CMSMicroservice.Protobuf.Validator.UserWalletHistory;
public class GetAllUserWalletHistoryByFilterRequestValidator : AbstractValidator<GetAllUserWalletHistoryByFilterRequest>
{
public GetAllUserWalletHistoryByFilterRequestValidator()
{
}
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{
var result = await ValidateAsync(ValidationContext<GetAllUserWalletHistoryByFilterRequest>.CreateWithOptions((GetAllUserWalletHistoryByFilterRequest)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
};
}
@@ -1,17 +1,17 @@
using FluentValidation; using FluentValidation;
using CMSMicroservice.Protobuf.Protos.UserWalletChangeLog; using CMSMicroservice.Protobuf.Protos.UserWalletHistory;
namespace CMSMicroservice.Protobuf.Validator.UserWalletChangeLog; namespace CMSMicroservice.Protobuf.Validator.UserWalletHistory;
public class GetUserWalletChangeLogRequestValidator : AbstractValidator<GetUserWalletChangeLogRequest> public class GetUserWalletHistoryRequestValidator : AbstractValidator<GetUserWalletHistoryRequest>
{ {
public GetUserWalletChangeLogRequestValidator() public GetUserWalletHistoryRequestValidator()
{ {
RuleFor(model => model.Id) RuleFor(model => model.Id)
.NotNull(); .NotNull();
} }
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) => public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{ {
var result = await ValidateAsync(ValidationContext<GetUserWalletChangeLogRequest>.CreateWithOptions((GetUserWalletChangeLogRequest)model, x => x.IncludeProperties(propertyName))); var result = await ValidateAsync(ValidationContext<GetUserWalletHistoryRequest>.CreateWithOptions((GetUserWalletHistoryRequest)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid) if (result.IsValid)
return Array.Empty<string>(); return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage); return result.Errors.Select(e => e.ErrorMessage);
@@ -1,10 +1,10 @@
using FluentValidation; using FluentValidation;
using CMSMicroservice.Protobuf.Protos.UserWalletChangeLog; using CMSMicroservice.Protobuf.Protos.UserWalletHistory;
namespace CMSMicroservice.Protobuf.Validator.UserWalletChangeLog; namespace CMSMicroservice.Protobuf.Validator.UserWalletHistory;
public class UpdateUserWalletChangeLogRequestValidator : AbstractValidator<UpdateUserWalletChangeLogRequest> public class UpdateUserWalletHistoryRequestValidator : AbstractValidator<UpdateUserWalletHistoryRequest>
{ {
public UpdateUserWalletChangeLogRequestValidator() public UpdateUserWalletHistoryRequestValidator()
{ {
RuleFor(model => model.Id) RuleFor(model => model.Id)
.NotNull(); .NotNull();
@@ -23,7 +23,7 @@ public class UpdateUserWalletChangeLogRequestValidator : AbstractValidator<Updat
} }
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) => public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{ {
var result = await ValidateAsync(ValidationContext<UpdateUserWalletChangeLogRequest>.CreateWithOptions((UpdateUserWalletChangeLogRequest)model, x => x.IncludeProperties(propertyName))); var result = await ValidateAsync(ValidationContext<UpdateUserWalletHistoryRequest>.CreateWithOptions((UpdateUserWalletHistoryRequest)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid) if (result.IsValid)
return Array.Empty<string>(); return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage); return result.Errors.Select(e => e.ErrorMessage);
@@ -1,6 +1,6 @@
namespace CMSMicroservice.WebApi.Common.Mappings; namespace CMSMicroservice.WebApi.Common.Mappings;
public class UserWalletChangeLogProfile : IRegister public class UserWalletHistoryProfile : IRegister
{ {
void IRegister.Register(TypeAdapterConfig config) void IRegister.Register(TypeAdapterConfig config)
{ {
+1 -1
View File
@@ -281,7 +281,7 @@ static bool IsCustomerService(string serviceName)
"User", "UserAddress", "Commission", "NetworkMembership", "User", "UserAddress", "Commission", "NetworkMembership",
"ClubMembership", "UserOrder", "UserWallet", "UserCarts", "ClubMembership", "UserOrder", "UserWallet", "UserCarts",
"DiscountShoppingCart", "City", "Package", "Transactions", "DiscountShoppingCart", "City", "Package", "Transactions",
"UserContract", "UserWalletChangeLog" "UserContract", "UserWalletHistory"
}; };
return customerServices.Any(customer => serviceName.Contains(customer, StringComparison.OrdinalIgnoreCase)) && return customerServices.Any(customer => serviceName.Contains(customer, StringComparison.OrdinalIgnoreCase)) &&
@@ -321,7 +321,7 @@ public class PackageService : PackageContract.PackageContractBase
wallet.DiscountBalance += discountAmount; wallet.DiscountBalance += discountAmount;
// ثبت لاگ کیف پول // ثبت لاگ کیف پول
var walletLog = new CMSMicroservice.Domain.Entities.UserWalletChangeLog var walletLog = new CMSMicroservice.Domain.Entities.UserWalletHistory
{ {
WalletId = wallet.Id, WalletId = wallet.Id,
CurrentBalance = wallet.Balance, CurrentBalance = wallet.Balance,
@@ -333,7 +333,7 @@ public class PackageService : PackageContract.PackageContractBase
IsIncrease = true, IsIncrease = true,
RefrenceId = transaction.Id RefrenceId = transaction.Id
}; };
_context.UserWalletChangeLogs.Add(walletLog); _context.UserWalletHistories.Add(walletLog);
// به‌روزرسانی کاربر // به‌روزرسانی کاربر
var user = await _context.Users var user = await _context.Users
@@ -322,7 +322,7 @@ public class UserOrderService : UserOrderContract.UserOrderContractBase
wallet.Balance -= totalAmount; wallet.Balance -= totalAmount;
// Create wallet change log // Create wallet change log
var walletLog = new UserWalletChangeLog var walletLog = new UserWalletHistory
{ {
WalletId = wallet.Id, WalletId = wallet.Id,
CurrentBalance = wallet.Balance, CurrentBalance = wallet.Balance,
@@ -335,7 +335,7 @@ public class UserOrderService : UserOrderContract.UserOrderContractBase
RefrenceId = transaction.Id RefrenceId = transaction.Id
}; };
_context.UserWalletChangeLogs.Add(walletLog); _context.UserWalletHistories.Add(walletLog);
// ═══ Magic Wallet: Entry / Exit Trigger ═══ // ═══ Magic Wallet: Entry / Exit Trigger ═══
// Q24: آستانه <= 1,000,000 ریال به جای == 0 (چون قیمت محصولات متفاوت است) // Q24: آستانه <= 1,000,000 ریال به جای == 0 (چون قیمت محصولات متفاوت است)
@@ -833,7 +833,7 @@ public class UserOrderService : UserOrderContract.UserOrderContractBase
if (wallet != null) if (wallet != null)
{ {
wallet.Balance += refundAmount; wallet.Balance += refundAmount;
_context.UserWalletChangeLogs.Add(new UserWalletChangeLog _context.UserWalletHistories.Add(new UserWalletHistory
{ {
WalletId = wallet.Id, WalletId = wallet.Id,
CurrentBalance = wallet.Balance, CurrentBalance = wallet.Balance,
@@ -1,37 +0,0 @@
using CMSMicroservice.Protobuf.Protos.UserWalletChangeLog;
using CMSMicroservice.WebApi.Common.Services;
using CMSMicroservice.Application.UserWalletChangeLogCQ.Commands.CreateNewUserWalletChangeLog;
using CMSMicroservice.Application.UserWalletChangeLogCQ.Commands.UpdateUserWalletChangeLog;
using CMSMicroservice.Application.UserWalletChangeLogCQ.Commands.DeleteUserWalletChangeLog;
using CMSMicroservice.Application.UserWalletChangeLogCQ.Queries.GetUserWalletChangeLog;
using CMSMicroservice.Application.UserWalletChangeLogCQ.Queries.GetAllUserWalletChangeLogByFilter;
namespace CMSMicroservice.WebApi.Services;
public class UserWalletChangeLogService : UserWalletChangeLogContract.UserWalletChangeLogContractBase
{
private readonly IDispatchRequestToCQRS _dispatchRequestToCQRS;
public UserWalletChangeLogService(IDispatchRequestToCQRS dispatchRequestToCQRS)
{
_dispatchRequestToCQRS = dispatchRequestToCQRS;
}
public override async Task<CreateNewUserWalletChangeLogResponse> CreateNewUserWalletChangeLog(CreateNewUserWalletChangeLogRequest request, ServerCallContext context)
{
return await _dispatchRequestToCQRS.Handle<CreateNewUserWalletChangeLogRequest, CreateNewUserWalletChangeLogCommand, CreateNewUserWalletChangeLogResponse>(request, context);
}
public override async Task<Empty> UpdateUserWalletChangeLog(UpdateUserWalletChangeLogRequest request, ServerCallContext context)
{
return await _dispatchRequestToCQRS.Handle<UpdateUserWalletChangeLogRequest, UpdateUserWalletChangeLogCommand>(request, context);
}
public override async Task<Empty> DeleteUserWalletChangeLog(DeleteUserWalletChangeLogRequest request, ServerCallContext context)
{
return await _dispatchRequestToCQRS.Handle<DeleteUserWalletChangeLogRequest, DeleteUserWalletChangeLogCommand>(request, context);
}
public override async Task<GetUserWalletChangeLogResponse> GetUserWalletChangeLog(GetUserWalletChangeLogRequest request, ServerCallContext context)
{
return await _dispatchRequestToCQRS.Handle<GetUserWalletChangeLogRequest, GetUserWalletChangeLogQuery, GetUserWalletChangeLogResponse>(request, context);
}
public override async Task<GetAllUserWalletChangeLogByFilterResponse> GetAllUserWalletChangeLogByFilter(GetAllUserWalletChangeLogByFilterRequest request, ServerCallContext context)
{
return await _dispatchRequestToCQRS.Handle<GetAllUserWalletChangeLogByFilterRequest, GetAllUserWalletChangeLogByFilterQuery, GetAllUserWalletChangeLogByFilterResponse>(request, context);
}
}
@@ -0,0 +1,37 @@
using CMSMicroservice.Protobuf.Protos.UserWalletHistory;
using CMSMicroservice.WebApi.Common.Services;
using CMSMicroservice.Application.UserWalletHistoryCQ.Commands.CreateNewUserWalletHistory;
using CMSMicroservice.Application.UserWalletHistoryCQ.Commands.UpdateUserWalletHistory;
using CMSMicroservice.Application.UserWalletHistoryCQ.Commands.DeleteUserWalletHistory;
using CMSMicroservice.Application.UserWalletHistoryCQ.Queries.GetUserWalletHistory;
using CMSMicroservice.Application.UserWalletHistoryCQ.Queries.GetAllUserWalletHistoryByFilter;
namespace CMSMicroservice.WebApi.Services;
public class UserWalletHistoryService : UserWalletHistoryContract.UserWalletHistoryContractBase
{
private readonly IDispatchRequestToCQRS _dispatchRequestToCQRS;
public UserWalletHistoryService(IDispatchRequestToCQRS dispatchRequestToCQRS)
{
_dispatchRequestToCQRS = dispatchRequestToCQRS;
}
public override async Task<CreateNewUserWalletHistoryResponse> CreateNewUserWalletHistory(CreateNewUserWalletHistoryRequest request, ServerCallContext context)
{
return await _dispatchRequestToCQRS.Handle<CreateNewUserWalletHistoryRequest, CreateNewUserWalletHistoryCommand, CreateNewUserWalletHistoryResponse>(request, context);
}
public override async Task<Empty> UpdateUserWalletHistory(UpdateUserWalletHistoryRequest request, ServerCallContext context)
{
return await _dispatchRequestToCQRS.Handle<UpdateUserWalletHistoryRequest, UpdateUserWalletHistoryCommand>(request, context);
}
public override async Task<Empty> DeleteUserWalletHistory(DeleteUserWalletHistoryRequest request, ServerCallContext context)
{
return await _dispatchRequestToCQRS.Handle<DeleteUserWalletHistoryRequest, DeleteUserWalletHistoryCommand>(request, context);
}
public override async Task<GetUserWalletHistoryResponse> GetUserWalletHistory(GetUserWalletHistoryRequest request, ServerCallContext context)
{
return await _dispatchRequestToCQRS.Handle<GetUserWalletHistoryRequest, GetUserWalletHistoryQuery, GetUserWalletHistoryResponse>(request, context);
}
public override async Task<GetAllUserWalletHistoryByFilterResponse> GetAllUserWalletHistoryByFilter(GetAllUserWalletHistoryByFilterRequest request, ServerCallContext context)
{
return await _dispatchRequestToCQRS.Handle<GetAllUserWalletHistoryByFilterRequest, GetAllUserWalletHistoryByFilterQuery, GetAllUserWalletHistoryByFilterResponse>(request, context);
}
}
@@ -7,7 +7,7 @@ using CMSMicroservice.Application.WalletCQ.Commands.ChargeMagicWallet;
using CMSMicroservice.Application.WalletCQ.Commands.ChargeDiscountWallet; using CMSMicroservice.Application.WalletCQ.Commands.ChargeDiscountWallet;
using CMSMicroservice.Application.UserWalletCQ.Queries.GetUserWallet; using CMSMicroservice.Application.UserWalletCQ.Queries.GetUserWallet;
using CMSMicroservice.Application.UserWalletCQ.Queries.GetAllUserWalletByFilter; using CMSMicroservice.Application.UserWalletCQ.Queries.GetAllUserWalletByFilter;
using CMSMicroservice.Application.UserWalletCQ.Queries.GetCustomerWalletChangeLog; using CMSMicroservice.Application.UserWalletCQ.Queries.GetCustomerWalletHistory;
using CMSMicroservice.Application.UserWalletCQ.Queries.GetCustomerWithdrawals; using CMSMicroservice.Application.UserWalletCQ.Queries.GetCustomerWithdrawals;
using CMSMicroservice.Application.UserWalletCQ.Queries.GetCustomerWithdrawalSettings; using CMSMicroservice.Application.UserWalletCQ.Queries.GetCustomerWithdrawalSettings;
using CMSMicroservice.Application.Common.Interfaces; using CMSMicroservice.Application.Common.Interfaces;
@@ -102,9 +102,9 @@ public class UserWalletService : UserWalletContract.UserWalletContractBase
}; };
} }
public override async Task<GetCustomerWalletChangeLogResponse> GetCustomerWalletChangeLog(GetCustomerWalletChangeLogRequest request, ServerCallContext context) public override async Task<GetCustomerWalletHistoryResponse> GetCustomerWalletHistory(GetCustomerWalletHistoryRequest request, ServerCallContext context)
{ {
var query = new GetCustomerWalletChangeLogQuery var query = new GetCustomerWalletHistoryQuery
{ {
ReferenceId = request.ReferenceId, ReferenceId = request.ReferenceId,
IsIncrease = request.IsIncrease IsIncrease = request.IsIncrease
@@ -112,7 +112,7 @@ public class UserWalletService : UserWalletContract.UserWalletContractBase
var changeLogs = await _sender.Send(query, context.CancellationToken); var changeLogs = await _sender.Send(query, context.CancellationToken);
var response = new GetCustomerWalletChangeLogResponse var response = new GetCustomerWalletHistoryResponse
{ {
MetaData = new CMSMicroservice.Protobuf.Protos.MetaData MetaData = new CMSMicroservice.Protobuf.Protos.MetaData
{ {
@@ -127,7 +127,7 @@ public class UserWalletService : UserWalletContract.UserWalletContractBase
foreach (var log in changeLogs) foreach (var log in changeLogs)
{ {
response.Models.Add(new CustomerWalletChangeLogModel response.Models.Add(new CustomerWalletHistoryModel
{ {
CurrentBalance = log.CurrentBalance, CurrentBalance = log.CurrentBalance,
ChangeValue = log.ChangeValue, ChangeValue = log.ChangeValue,