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);
var newWallets = new List<UserWallet>();
var walletLogs = new List<UserWalletChangeLog>();
var walletLogs = new List<UserWalletHistory>();
foreach (var payout in payouts)
{
@@ -241,7 +241,7 @@ public class CalculateWeeklyCommissionPoolCommandHandler : IRequestHandler<Calcu
wallet.NetworkBalance += payout.TotalAmount;
// ایجاد لاگ تغییر کیف پول
var walletLog = new UserWalletChangeLog
var walletLog = new UserWalletHistory
{
WalletId = wallet.Id,
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);
}
@@ -271,7 +271,7 @@ public class CalculateWeeklyCommissionPoolCommandHandler : IRequestHandler<Calcu
CancellationToken cancellationToken)
{
// پیدا کردن لاگ‌های کیف پول مرتبط با پرداخت‌های قبلی
var oldWalletLogs = await _context.UserWalletChangeLogs
var oldWalletLogs = await _context.UserWalletHistories
.Where(l => l.RefrenceId.HasValue && oldPayoutIds.Contains(l.RefrenceId.Value))
.ToListAsync(cancellationToken);
@@ -300,7 +300,7 @@ public class CalculateWeeklyCommissionPoolCommandHandler : IRequestHandler<Calcu
}
// حذف لاگ‌های قبلی
_context.UserWalletChangeLogs.RemoveRange(oldWalletLogs);
_context.UserWalletHistories.RemoveRange(oldWalletLogs);
await _context.SaveChangesAsync(cancellationToken);
}
@@ -32,7 +32,7 @@ public interface IApplicationDbContext
DbSet<OrderVAT> OrderVATs { get; }
DbSet<UserPackagePurchase> UserPackagePurchases { get; }
DbSet<UserWallet> UserWallets { get; }
DbSet<UserWalletChangeLog> UserWalletChangeLogs { get; }
DbSet<UserWalletHistory> UserWalletHistories { get; }
DbSet<ManualPayment> ManualPayments { get; }
DbSet<PaymentTransaction> PaymentTransactions { 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. شارژ کیف پول عادی
wallet.Balance += package.Price;
var mainLog = new UserWalletChangeLog
var mainLog = new UserWalletHistory
{
WalletId = wallet.Id,
CurrentBalance = 0,
@@ -233,13 +233,13 @@ public class CheckAndProcessDayaLoansCommandHandler : IRequestHandler<CheckAndPr
IsIncrease = true,
RefrenceId = transaction.Id
};
await _context.UserWalletChangeLogs.AddAsync(mainLog, cancellationToken);
await _context.UserWalletHistories.AddAsync(mainLog, cancellationToken);
// 4. شارژ کیف پول تخفیف
var discountAmount = (long)(package.Price * package.DiscountMultiplier);
wallet.DiscountBalance += discountAmount;
var discountLog = new UserWalletChangeLog
var discountLog = new UserWalletHistory
{
WalletId = wallet.Id,
CurrentBalance = wallet.Balance,
@@ -251,7 +251,7 @@ public class CheckAndProcessDayaLoansCommandHandler : IRequestHandler<CheckAndPr
IsIncrease = true,
RefrenceId = transaction.Id
};
await _context.UserWalletChangeLogs.AddAsync(discountLog, cancellationToken);
await _context.UserWalletHistories.AddAsync(discountLog, cancellationToken);
// 5. به‌روزرسانی کاربر
user.HasReceivedDayaCredit = true;
@@ -67,7 +67,7 @@ public class CompleteOrderPaymentCommandHandler : IRequestHandler<CompleteOrderP
userWallet.DiscountBalance -= order.DiscountBalanceUsed;
// ثبت لاگ تغییرات کیف پول
_context.UserWalletChangeLogs.Add(new Domain.Entities.UserWalletChangeLog
_context.UserWalletHistories.Add(new Domain.Entities.UserWalletHistory
{
WalletId = userWallet.Id,
CurrentBalance = userWallet.Balance,
@@ -279,7 +279,7 @@ public class PlaceOrderCommandHandler : IRequestHandler<PlaceOrderCommand, Place
walletForDeduct.DiscountBalance -= actualDiscountBalanceUsed;
// ثبت لاگ تغییرات کیف پول
_context.UserWalletChangeLogs.Add(new Domain.Entities.UserWalletChangeLog
_context.UserWalletHistories.Add(new Domain.Entities.UserWalletHistory
{
WalletId = walletForDeduct.Id,
CurrentBalance = walletForDeduct.Balance,
@@ -108,7 +108,7 @@ public class ApproveManualPaymentCommandHandler : IRequestHandler<ApproveManualP
wallet.DiscountBalance += manualPayment.Amount;
// لاگ Balance
await _context.UserWalletChangeLogs.AddAsync(new UserWalletChangeLog
await _context.UserWalletHistories.AddAsync(new UserWalletHistory
{
WalletId = wallet.Id,
CurrentBalance = wallet.Balance,
@@ -122,7 +122,7 @@ public class ApproveManualPaymentCommandHandler : IRequestHandler<ApproveManualP
}, cancellationToken);
// لاگ DiscountBalance
await _context.UserWalletChangeLogs.AddAsync(new UserWalletChangeLog
await _context.UserWalletHistories.AddAsync(new UserWalletHistory
{
WalletId = wallet.Id,
CurrentBalance = wallet.Balance,
@@ -139,7 +139,7 @@ public class ApproveManualPaymentCommandHandler : IRequestHandler<ApproveManualP
case ManualPaymentType.DiscountWalletCharge:
wallet.DiscountBalance += manualPayment.Amount;
await _context.UserWalletChangeLogs.AddAsync(new UserWalletChangeLog
await _context.UserWalletHistories.AddAsync(new UserWalletHistory
{
WalletId = wallet.Id,
CurrentBalance = wallet.Balance,
@@ -156,7 +156,7 @@ public class ApproveManualPaymentCommandHandler : IRequestHandler<ApproveManualP
case ManualPaymentType.NetworkWalletCharge:
wallet.NetworkBalance += manualPayment.Amount;
await _context.UserWalletChangeLogs.AddAsync(new UserWalletChangeLog
await _context.UserWalletHistories.AddAsync(new UserWalletHistory
{
WalletId = wallet.Id,
CurrentBalance = wallet.Balance,
@@ -183,7 +183,7 @@ public class ApproveManualPaymentCommandHandler : IRequestHandler<ApproveManualP
wallet.DiscountBalance -= manualPayment.Amount;
}
await _context.UserWalletChangeLogs.AddAsync(new UserWalletChangeLog
await _context.UserWalletHistories.AddAsync(new UserWalletHistory
{
WalletId = wallet.Id,
CurrentBalance = wallet.Balance,
@@ -201,7 +201,7 @@ public class ApproveManualPaymentCommandHandler : IRequestHandler<ApproveManualP
// Other یا سایر موارد - فقط Balance
wallet.Balance += manualPayment.Amount;
await _context.UserWalletChangeLogs.AddAsync(new UserWalletChangeLog
await _context.UserWalletHistories.AddAsync(new UserWalletHistory
{
WalletId = wallet.Id,
CurrentBalance = wallet.Balance,
@@ -120,7 +120,7 @@ public class CreateManualPaymentCommandHandler : IRequestHandler<CreateManualPay
wallet.DiscountBalance += discountBalanceAmount;
// 8. ثبت لاگ کیف پول
var walletLog = new UserWalletChangeLog
var walletLog = new UserWalletHistory
{
WalletId = wallet.Id,
CurrentBalance = 0,
@@ -133,7 +133,7 @@ public class CreateManualPaymentCommandHandler : IRequestHandler<CreateManualPay
RefrenceId = transaction.Id
};
await _context.UserWalletChangeLogs.AddAsync(walletLog, cancellationToken);
await _context.UserWalletHistories.AddAsync(walletLog, cancellationToken);
// 9. تنظیم روش خرید پکیج
user.PackagePurchaseMethod = PackagePurchaseMethod.DirectPurchase;
@@ -104,7 +104,7 @@ public class ProcessManualMembershipPaymentCommandHandler : IRequestHandler<Proc
wallet.DiscountBalance += request.Amount;
// 8. ثبت لاگ Balance
var balanceLog = new UserWalletChangeLog
var balanceLog = new UserWalletHistory
{
WalletId = wallet.Id,
CurrentBalance = wallet.Balance,
@@ -116,7 +116,7 @@ public class ProcessManualMembershipPaymentCommandHandler : IRequestHandler<Proc
IsIncrease = true,
RefrenceId = transaction.Id
};
await _context.UserWalletChangeLogs.AddAsync(balanceLog, cancellationToken);
await _context.UserWalletHistories.AddAsync(balanceLog, cancellationToken);
user.PackagePurchaseMethod = PackagePurchaseMethod.DirectPurchase;
// 10. به‌روزرسانی ManualPayment با TransactionId
@@ -60,7 +60,7 @@ public class CancelOrderByAdminCommandHandler : IRequestHandler<CancelOrderByAdm
var wallet = order.User.UserWallets.FirstOrDefault();
if (wallet != null)
{
var walletLog = new UserWalletChangeLog
var walletLog = new UserWalletHistory
{
WalletId = wallet.Id,
CurrentBalance = wallet.Balance,
@@ -74,7 +74,7 @@ public class CancelOrderByAdminCommandHandler : IRequestHandler<CancelOrderByAdm
wallet.Balance += order.Amount;
await _context.UserWalletChangeLogs.AddAsync(walletLog, cancellationToken);
await _context.UserWalletHistories.AddAsync(walletLog, cancellationToken);
_logger.LogInformation(
"Refund processed. OrderId: {OrderId}, Amount: {Amount}, UserId: {UserId}",
@@ -129,7 +129,7 @@ public class VerifyPackagePurchaseCommandHandler
await _context.SaveChangesAsync(cancellationToken);
// 6. ثبت لاگ تغییر Balance
var balanceLog = new UserWalletChangeLog
var balanceLog = new UserWalletHistory
{
WalletId = wallet.Id,
CurrentBalance = wallet.Balance,
@@ -141,10 +141,10 @@ public class VerifyPackagePurchaseCommandHandler
IsIncrease = true,
RefrenceId = transaction.Id
};
await _context.UserWalletChangeLogs.AddAsync(balanceLog, cancellationToken);
await _context.UserWalletHistories.AddAsync(balanceLog, cancellationToken);
// 7. ثبت لاگ تغییر DiscountBalance
var discountLog = new UserWalletChangeLog
var discountLog = new UserWalletHistory
{
WalletId = wallet.Id,
CurrentBalance = wallet.Balance,
@@ -156,7 +156,7 @@ public class VerifyPackagePurchaseCommandHandler
IsIncrease = true,
RefrenceId = transaction.Id
};
await _context.UserWalletChangeLogs.AddAsync(discountLog, cancellationToken);
await _context.UserWalletHistories.AddAsync(discountLog, cancellationToken);
// 8. ثبت UserPackagePurchase
if (order.PackageId.HasValue)
@@ -60,7 +60,7 @@ public class GetCustomerReferralsQueryHandler : IRequestHandler<GetCustomerRefer
// Calculate this month's commission from wallet changelog
var startOfMonth = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
var thisMonthCommission = await _context.UserWalletChangeLogs
var thisMonthCommission = await _context.UserWalletHistories
.AsNoTracking()
.Include(x => x.Wallet)
.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>
/// فیلتر بر اساس شناسه ارجاع (اختیاری)
@@ -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 ICurrentUserService _currentUser;
public GetCustomerWalletChangeLogQueryHandler(
public GetCustomerWalletHistoryQueryHandler(
IApplicationDbContext context,
ICurrentUserService currentUser)
{
@@ -13,8 +13,8 @@ public class GetCustomerWalletChangeLogQueryHandler : IRequestHandler<GetCustome
_currentUser = currentUser;
}
public async Task<List<GetCustomerWalletChangeLogResponseDto>> Handle(
GetCustomerWalletChangeLogQuery request,
public async Task<List<GetCustomerWalletHistoryResponseDto>> Handle(
GetCustomerWalletHistoryQuery request,
CancellationToken cancellationToken)
{
// Get current user's ID from JWT
@@ -35,7 +35,7 @@ public class GetCustomerWalletChangeLogQueryHandler : IRequestHandler<GetCustome
}
// Build query for wallet change logs
var query = _context.UserWalletChangeLogs
var query = _context.UserWalletHistories
.AsNoTracking()
.Where(x => x.WalletId == userWallet.Id);
@@ -53,7 +53,7 @@ public class GetCustomerWalletChangeLogQueryHandler : IRequestHandler<GetCustome
// Order by newest first
var result = await query
.OrderByDescending(x => x.Created)
.ProjectToType<GetCustomerWalletChangeLogResponseDto>()
.ProjectToType<GetCustomerWalletHistoryResponseDto>()
.ToListAsync(cancellationToken);
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>
/// موجودی جاری
@@ -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;
public record CreateNewUserWalletChangeLogCommand : IRequest<CreateNewUserWalletChangeLogResponseDto>
namespace CMSMicroservice.Application.UserWalletHistoryCQ.Commands.CreateNewUserWalletHistory;
public record CreateNewUserWalletHistoryCommand : IRequest<CreateNewUserWalletHistoryResponseDto>
{
//شناسه کیف پول
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;
public class CreateNewUserWalletChangeLogCommandValidator : AbstractValidator<CreateNewUserWalletChangeLogCommand>
namespace CMSMicroservice.Application.UserWalletHistoryCQ.Commands.CreateNewUserWalletHistory;
public class CreateNewUserWalletHistoryCommandValidator : AbstractValidator<CreateNewUserWalletHistoryCommand>
{
public CreateNewUserWalletChangeLogCommandValidator()
public CreateNewUserWalletHistoryCommandValidator()
{
RuleFor(model => model.WalletId)
.NotNull();
@@ -18,7 +18,7 @@ public class CreateNewUserWalletChangeLogCommandValidator : AbstractValidator<Cr
}
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)
return Array.Empty<string>();
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;
public record UpdateUserWalletChangeLogCommand : IRequest<Unit>
namespace CMSMicroservice.Application.UserWalletHistoryCQ.Commands.UpdateUserWalletHistory;
public record UpdateUserWalletHistoryCommand : IRequest<Unit>
{
//شناسه
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;
public class UpdateUserWalletChangeLogCommandValidator : AbstractValidator<UpdateUserWalletChangeLogCommand>
namespace CMSMicroservice.Application.UserWalletHistoryCQ.Commands.UpdateUserWalletHistory;
public class UpdateUserWalletHistoryCommandValidator : AbstractValidator<UpdateUserWalletHistoryCommand>
{
public UpdateUserWalletChangeLogCommandValidator()
public UpdateUserWalletHistoryCommandValidator()
{
RuleFor(model => model.Id)
.NotNull();
@@ -20,7 +20,7 @@ public class UpdateUserWalletChangeLogCommandValidator : AbstractValidator<Updat
}
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)
return Array.Empty<string>();
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;
public record GetAllUserWalletChangeLogByFilterQuery : IRequest<GetAllUserWalletChangeLogByFilterResponseDto>
namespace CMSMicroservice.Application.UserWalletHistoryCQ.Queries.GetAllUserWalletHistoryByFilter;
public record GetAllUserWalletHistoryByFilterQuery : IRequest<GetAllUserWalletHistoryByFilterResponseDto>
{
//موقعیت صفحه بندی
public PaginationState? PaginationState { 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; }
@@ -1,16 +1,16 @@
namespace CMSMicroservice.Application.UserWalletChangeLogCQ.Queries.GetAllUserWalletChangeLogByFilter;
public class GetAllUserWalletChangeLogByFilterQueryHandler : IRequestHandler<GetAllUserWalletChangeLogByFilterQuery, GetAllUserWalletChangeLogByFilterResponseDto>
namespace CMSMicroservice.Application.UserWalletHistoryCQ.Queries.GetAllUserWalletHistoryByFilter;
public class GetAllUserWalletHistoryByFilterQueryHandler : IRequestHandler<GetAllUserWalletHistoryByFilterQuery, GetAllUserWalletHistoryByFilterResponseDto>
{
private readonly IApplicationDbContext _context;
public GetAllUserWalletChangeLogByFilterQueryHandler(IApplicationDbContext context)
public GetAllUserWalletHistoryByFilterQueryHandler(IApplicationDbContext 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)
.ApplyOrder(sortBy: request.SortBy)
.AsNoTracking()
@@ -27,11 +27,11 @@ public class GetAllUserWalletChangeLogByFilterQueryHandler : IRequestHandler<Get
.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),
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;
public class GetAllUserWalletChangeLogByFilterResponseDto
namespace CMSMicroservice.Application.UserWalletHistoryCQ.Queries.GetAllUserWalletHistoryByFilter;
public class GetAllUserWalletHistoryByFilterResponseDto
{
//متادیتا
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; }
@@ -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;
public class GetUserWalletChangeLogQueryValidator : AbstractValidator<GetUserWalletChangeLogQuery>
namespace CMSMicroservice.Application.UserWalletHistoryCQ.Queries.GetUserWalletHistory;
public class GetUserWalletHistoryQueryValidator : AbstractValidator<GetUserWalletHistoryQuery>
{
public GetUserWalletChangeLogQueryValidator()
public GetUserWalletHistoryQueryValidator()
{
RuleFor(model => model.Id)
.NotNull();
}
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)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
@@ -1,5 +1,5 @@
namespace CMSMicroservice.Application.UserWalletChangeLogCQ.Queries.GetUserWalletChangeLog;
public class GetUserWalletChangeLogResponseDto
namespace CMSMicroservice.Application.UserWalletHistoryCQ.Queries.GetUserWalletHistory;
public class GetUserWalletHistoryResponseDto
{
//شناسه
public long Id { get; set; }
@@ -115,7 +115,7 @@ public class VerifyDiscountWalletChargeCommandHandler
await _context.SaveChangesAsync(cancellationToken);
// ثبت لاگ تغییرات کیف پول (بعد از ایجاد Transaction برای داشتن TransactionId)
_context.UserWalletChangeLogs.Add(new Domain.Entities.UserWalletChangeLog
_context.UserWalletHistories.Add(new Domain.Entities.UserWalletHistory
{
WalletId = wallet.Id,
CurrentBalance = wallet.Balance,
@@ -167,8 +167,8 @@ public class VerifyMagicWalletChargeCommandHandler
wallet.MagicTotalDeposited += depositAmount;
wallet.MagicTotalCredited += creditAmount;
// 9. ثبت WalletChangeLog (اجباری)
var walletLog = new UserWalletChangeLog
// 9. ثبت WalletHistory (اجباری)
var walletLog = new UserWalletHistory
{
WalletId = wallet.Id,
CurrentBalance = wallet.Balance,
@@ -181,7 +181,7 @@ public class VerifyMagicWalletChargeCommandHandler
RefrenceId = depositTransaction.Id
};
_context.UserWalletChangeLogs.Add(walletLog);
_context.UserWalletHistories.Add(walletLog);
// 10. لینک PaymentTransaction به Transaction داخلی
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;
/// <summary>
/// پکیج — هر پکیج قیمت، ویژگی‌ها و تنظیمات مستقل دارد
/// </summary>
public class Package : BaseAuditableEntity
public class Package : BaseAuditableEntity, IHasHistory<History.PackageHistory>
{
// === فیلدهای فعلی (حفظ) ===
@@ -76,4 +79,23 @@ public class Package : BaseAuditableEntity
/// <summary>تاریخچه تغییرات پکیج (Q27)</summary>
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
//UserWalletChangeLog Collection Navigation Reference
public virtual ICollection<UserWalletChangeLog> UserWalletChangeLogs { get; set; }
//UserWalletHistory Collection Navigation Reference
public virtual ICollection<UserWalletHistory> UserWalletHistories { get; set; }
}
@@ -1,6 +1,6 @@
namespace CMSMicroservice.Domain.Entities;
//آدرس کاربر
public class UserWalletChangeLog : BaseAuditableEntity
public class UserWalletHistory : BaseAuditableEntity
{
//شناسه کیف پول
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.AddScoped<AuditableEntitySaveChangesInterceptor>();
services.AddScoped<HistoryTrackingSaveChangesInterceptor>();
services.AddScoped<ApplicationDbContextInitialiser>();
services.AddScoped<IGenerateJwtToken, GenerateJwtTokenService>();
services.AddScoped<IHashService, HashService>();
@@ -18,6 +18,7 @@ public class ApplicationDbContext : DbContext, IApplicationDbContext
{
private readonly IMediator? _mediator;
private readonly AuditableEntitySaveChangesInterceptor? _auditableEntitySaveChangesInterceptor;
private readonly HistoryTrackingSaveChangesInterceptor? _historyTrackingInterceptor;
/// <summary>
/// Constructor برای design-time (migrations)
@@ -33,11 +34,13 @@ public class ApplicationDbContext : DbContext, IApplicationDbContext
public ApplicationDbContext(
DbContextOptions<ApplicationDbContext> options,
IMediator mediator,
AuditableEntitySaveChangesInterceptor auditableEntitySaveChangesInterceptor)
AuditableEntitySaveChangesInterceptor auditableEntitySaveChangesInterceptor,
HistoryTrackingSaveChangesInterceptor historyTrackingInterceptor)
: base(options)
{
_mediator = mediator;
_auditableEntitySaveChangesInterceptor = auditableEntitySaveChangesInterceptor;
_historyTrackingInterceptor = historyTrackingInterceptor;
}
protected override void OnModelCreating(ModelBuilder builder)
{
@@ -57,6 +60,11 @@ public class ApplicationDbContext : DbContext, IApplicationDbContext
optionsBuilder.AddInterceptors(_auditableEntitySaveChangesInterceptor);
}
if (_historyTrackingInterceptor != null)
{
optionsBuilder.AddInterceptors(_historyTrackingInterceptor);
}
// Suppress PendingModelChangesWarning in EF Core 9
optionsBuilder.ConfigureWarnings(w => w.Ignore(RelationalEventId.PendingModelChangesWarning));
}
@@ -89,7 +97,7 @@ public class ApplicationDbContext : DbContext, IApplicationDbContext
public DbSet<OrderVAT> OrderVATs => Set<OrderVAT>();
public DbSet<UserPackagePurchase> UserPackagePurchases => Set<UserPackagePurchase>();
public DbSet<UserWallet> UserWallets => Set<UserWallet>();
public DbSet<UserWalletChangeLog> UserWalletChangeLogs => Set<UserWalletChangeLog>();
public DbSet<UserWalletHistory> UserWalletHistories => Set<UserWalletHistory>();
public DbSet<DayaLoanContract> DayaLoanContracts => Set<DayaLoanContract>();
// Payment
@@ -3,9 +3,9 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
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.Ignore(entity => entity.DomainEvents);
@@ -13,7 +13,7 @@ public class UserWalletChangeLogConfiguration : IEntityTypeConfiguration<UserWal
builder.Property(entity => entity.Id).UseIdentityColumn();
builder
.HasOne(entity => entity.Wallet)
.WithMany(entity => entity.UserWalletChangeLogs)
.WithMany(entity => entity.UserWalletHistories)
.HasForeignKey(entity => entity.WalletId)
.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");
});
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 =>
{
b.Property<long>("Id")
@@ -2133,6 +2208,92 @@ namespace CMSMicroservice.Infrastructure.Persistence.Migrations
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 =>
{
b.Property<long>("Id")
@@ -3826,7 +3987,7 @@ namespace CMSMicroservice.Infrastructure.Persistence.Migrations
b.ToTable("UserWallets", "CMS");
});
modelBuilder.Entity("CMSMicroservice.Domain.Entities.UserWalletChangeLog", b =>
modelBuilder.Entity("CMSMicroservice.Domain.Entities.UserWalletHistory", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
@@ -3885,7 +4046,7 @@ namespace CMSMicroservice.Infrastructure.Persistence.Migrations
b.HasIndex("WalletId");
b.ToTable("UserWalletChangeLogs", "CMS");
b.ToTable("UserWalletHistories", "CMS");
});
modelBuilder.Entity("CMSMicroservice.Domain.Entities.Warehouse", b =>
@@ -4430,6 +4591,17 @@ namespace CMSMicroservice.Infrastructure.Persistence.Migrations
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 =>
{
b.HasOne("CMSMicroservice.Domain.Entities.Club.ClubMembership", "ClubMembership")
@@ -4460,6 +4632,17 @@ namespace CMSMicroservice.Infrastructure.Persistence.Migrations
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 =>
{
b.HasOne("CMSMicroservice.Domain.Entities.DiscountShop.DiscountProduct", "DiscountProduct")
@@ -4781,7 +4964,7 @@ namespace CMSMicroservice.Infrastructure.Persistence.Migrations
b.Navigation("User");
});
modelBuilder.Entity("CMSMicroservice.Domain.Entities.UserWalletChangeLog", b =>
modelBuilder.Entity("CMSMicroservice.Domain.Entities.UserWalletHistory", b =>
{
b.HasOne("CMSMicroservice.Domain.Entities.Package", "Package")
.WithMany()
@@ -4789,7 +4972,7 @@ namespace CMSMicroservice.Infrastructure.Persistence.Migrations
.OnDelete(DeleteBehavior.Restrict);
b.HasOne("CMSMicroservice.Domain.Entities.UserWallet", "Wallet")
.WithMany("UserWalletChangeLogs")
.WithMany("UserWalletHistories")
.HasForeignKey("WalletId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
@@ -4834,6 +5017,11 @@ namespace CMSMicroservice.Infrastructure.Persistence.Migrations
b.Navigation("UserClubFeatures");
});
modelBuilder.Entity("CMSMicroservice.Domain.Entities.Club.ClubMembershipCycle", b =>
{
b.Navigation("CycleHistories");
});
modelBuilder.Entity("CMSMicroservice.Domain.Entities.Commission.UserCommissionPayout", b =>
{
b.Navigation("CommissionPayoutHistories");
@@ -4901,6 +5089,8 @@ namespace CMSMicroservice.Infrastructure.Persistence.Migrations
{
b.Navigation("PackageFeatures");
b.Navigation("PackageHistories");
b.Navigation("Purchases");
b.Navigation("UserOrders");
@@ -4984,7 +5174,7 @@ namespace CMSMicroservice.Infrastructure.Persistence.Migrations
modelBuilder.Entity("CMSMicroservice.Domain.Entities.UserWallet", b =>
{
b.Navigation("UserWalletChangeLogs");
b.Navigation("UserWalletHistories");
});
modelBuilder.Entity("CMSMicroservice.Domain.Entities.Warehouse", b =>
@@ -471,7 +471,7 @@ public class OrmCommissionCalculationStrategy : ICommissionCalculationStrategy
.ToDictionaryAsync(w => w.UserId, cancellationToken);
var newWallets = new List<UserWallet>();
var walletLogs = new List<UserWalletChangeLog>();
var walletLogs = new List<UserWalletHistory>();
foreach (var payout in payouts)
{
@@ -510,7 +510,7 @@ public class OrmCommissionCalculationStrategy : ICommissionCalculationStrategy
var wallet = existingWallets[payout.UserId];
wallet.NetworkBalance += payout.TotalAmount;
var walletLog = new UserWalletChangeLog
var walletLog = new UserWalletHistory
{
WalletId = wallet.Id,
CurrentBalance = wallet.Balance,
@@ -526,7 +526,7 @@ public class OrmCommissionCalculationStrategy : ICommissionCalculationStrategy
walletLogs.Add(walletLog);
}
await _context.UserWalletChangeLogs.AddRangeAsync(walletLogs, cancellationToken);
await _context.UserWalletHistories.AddRangeAsync(walletLogs, cancellationToken);
await _context.SaveChangesAsync(cancellationToken);
}
@@ -534,7 +534,7 @@ public class OrmCommissionCalculationStrategy : ICommissionCalculationStrategy
List<long> oldPayoutIds,
CancellationToken cancellationToken)
{
var oldWalletLogs = await _context.UserWalletChangeLogs
var oldWalletLogs = await _context.UserWalletHistories
.Where(l => l.RefrenceId.HasValue && oldPayoutIds.Contains(l.RefrenceId.Value))
.ToListAsync(cancellationToken);
@@ -557,7 +557,7 @@ public class OrmCommissionCalculationStrategy : ICommissionCalculationStrategy
}
}
_context.UserWalletChangeLogs.RemoveRange(oldWalletLogs);
_context.UserWalletHistories.RemoveRange(oldWalletLogs);
await _context.SaveChangesAsync(cancellationToken);
}
@@ -29,7 +29,7 @@
<Protobuf Include="Protos\user.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\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\productgalleries.proto" ProtoRoot="Protos\" GrpcServices="Both" />
<Protobuf Include="Protos\factordetails.proto" ProtoRoot="Protos\" GrpcServices="Both" />
@@ -51,9 +51,9 @@ service UserWalletContract
get: "/Customer/GetWallet"
};
};
rpc GetCustomerWalletChangeLog(GetCustomerWalletChangeLogRequest) returns (GetCustomerWalletChangeLogResponse){
rpc GetCustomerWalletHistory(GetCustomerWalletHistoryRequest) returns (GetCustomerWalletHistoryResponse){
option (google.api.http) = {
post: "/Customer/GetWalletChangeLog"
post: "/Customer/GetWalletHistory"
body: "*"
};
};
@@ -167,19 +167,19 @@ message GetCustomerWalletResponse
int32 wallet_mode = 4; // 0=Normal, 1=Magic
}
message GetCustomerWalletChangeLogRequest
message GetCustomerWalletHistoryRequest
{
google.protobuf.Int64Value reference_id = 1;
google.protobuf.BoolValue is_increase = 2;
}
message GetCustomerWalletChangeLogResponse
message GetCustomerWalletHistoryResponse
{
messages.MetaData meta_data = 1;
repeated CustomerWalletChangeLogModel models = 2;
repeated CustomerWalletHistoryModel models = 2;
}
message CustomerWalletChangeLogModel
message CustomerWalletHistoryModel
{
int64 current_balance = 1;
int64 change_value = 2;
@@ -1,6 +1,6 @@
syntax = "proto3";
package userwalletchangelog;
package userwallethistory;
import "public_messages.proto";
import "google/protobuf/empty.proto";
@@ -9,42 +9,42 @@ import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.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) = {
post: "/CreateNewUserWalletChangeLog"
post: "/CreateNewUserWalletHistory"
body: "*"
};
};
rpc UpdateUserWalletChangeLog(UpdateUserWalletChangeLogRequest) returns (google.protobuf.Empty){
rpc UpdateUserWalletHistory(UpdateUserWalletHistoryRequest) returns (google.protobuf.Empty){
option (google.api.http) = {
put: "/UpdateUserWalletChangeLog"
put: "/UpdateUserWalletHistory"
body: "*"
};
};
rpc DeleteUserWalletChangeLog(DeleteUserWalletChangeLogRequest) returns (google.protobuf.Empty){
rpc DeleteUserWalletHistory(DeleteUserWalletHistoryRequest) returns (google.protobuf.Empty){
option (google.api.http) = {
delete: "/DeleteUserWalletChangeLog"
delete: "/DeleteUserWalletHistory"
body: "*"
};
};
rpc GetUserWalletChangeLog(GetUserWalletChangeLogRequest) returns (GetUserWalletChangeLogResponse){
rpc GetUserWalletHistory(GetUserWalletHistoryRequest) returns (GetUserWalletHistoryResponse){
option (google.api.http) = {
get: "/GetUserWalletChangeLog"
get: "/GetUserWalletHistory"
};
};
rpc GetAllUserWalletChangeLogByFilter(GetAllUserWalletChangeLogByFilterRequest) returns (GetAllUserWalletChangeLogByFilterResponse){
rpc GetAllUserWalletHistoryByFilter(GetAllUserWalletHistoryByFilterRequest) returns (GetAllUserWalletHistoryByFilterResponse){
option (google.api.http) = {
get: "/GetAllUserWalletChangeLogByFilter"
get: "/GetAllUserWalletHistoryByFilter"
};
};
}
message CreateNewUserWalletChangeLogRequest
message CreateNewUserWalletHistoryRequest
{
int64 wallet_id = 1;
int64 current_balance = 2;
@@ -54,11 +54,11 @@ message CreateNewUserWalletChangeLogRequest
bool is_increase = 6;
google.protobuf.Int64Value refrence_id = 7;
}
message CreateNewUserWalletChangeLogResponse
message CreateNewUserWalletHistoryResponse
{
int64 id = 1;
}
message UpdateUserWalletChangeLogRequest
message UpdateUserWalletHistoryRequest
{
int64 id = 1;
int64 wallet_id = 2;
@@ -69,15 +69,15 @@ message UpdateUserWalletChangeLogRequest
bool is_increase = 7;
google.protobuf.Int64Value refrence_id = 8;
}
message DeleteUserWalletChangeLogRequest
message DeleteUserWalletHistoryRequest
{
int64 id = 1;
}
message GetUserWalletChangeLogRequest
message GetUserWalletHistoryRequest
{
int64 id = 1;
}
message GetUserWalletChangeLogResponse
message GetUserWalletHistoryResponse
{
int64 id = 1;
int64 wallet_id = 2;
@@ -89,13 +89,13 @@ message GetUserWalletChangeLogResponse
google.protobuf.Int64Value refrence_id = 8;
google.protobuf.Timestamp created_at = 9;
}
message GetAllUserWalletChangeLogByFilterRequest
message GetAllUserWalletHistoryByFilterRequest
{
messages.PaginationState pagination_state = 1;
google.protobuf.StringValue sort_by = 2;
GetAllUserWalletChangeLogByFilterFilter filter = 3;
GetAllUserWalletHistoryByFilterFilter filter = 3;
}
message GetAllUserWalletChangeLogByFilterFilter
message GetAllUserWalletHistoryByFilterFilter
{
google.protobuf.Int64Value id = 1;
google.protobuf.Int64Value wallet_id = 2;
@@ -105,12 +105,12 @@ message GetAllUserWalletChangeLogByFilterFilter
google.protobuf.Int64Value refrence_id = 6;
google.protobuf.Int64Value user_id = 7;
}
message GetAllUserWalletChangeLogByFilterResponse
message GetAllUserWalletHistoryByFilterResponse
{
messages.MetaData meta_data = 1;
repeated GetAllUserWalletChangeLogByFilterResponseModel models = 2;
repeated GetAllUserWalletHistoryByFilterResponseModel models = 2;
}
message GetAllUserWalletChangeLogByFilterResponseModel
message GetAllUserWalletHistoryByFilterResponseModel
{
int64 id = 1;
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 CMSMicroservice.Protobuf.Protos.UserWalletChangeLog;
namespace CMSMicroservice.Protobuf.Validator.UserWalletChangeLog;
using CMSMicroservice.Protobuf.Protos.UserWalletHistory;
namespace CMSMicroservice.Protobuf.Validator.UserWalletHistory;
public class CreateNewUserWalletChangeLogRequestValidator : AbstractValidator<CreateNewUserWalletChangeLogRequest>
public class CreateNewUserWalletHistoryRequestValidator : AbstractValidator<CreateNewUserWalletHistoryRequest>
{
public CreateNewUserWalletChangeLogRequestValidator()
public CreateNewUserWalletHistoryRequestValidator()
{
RuleFor(model => model.WalletId)
.NotNull();
@@ -21,7 +21,7 @@ public class CreateNewUserWalletChangeLogRequestValidator : AbstractValidator<Cr
}
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)
return Array.Empty<string>();
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 CMSMicroservice.Protobuf.Protos.UserWalletChangeLog;
namespace CMSMicroservice.Protobuf.Validator.UserWalletChangeLog;
using CMSMicroservice.Protobuf.Protos.UserWalletHistory;
namespace CMSMicroservice.Protobuf.Validator.UserWalletHistory;
public class GetUserWalletChangeLogRequestValidator : AbstractValidator<GetUserWalletChangeLogRequest>
public class GetUserWalletHistoryRequestValidator : AbstractValidator<GetUserWalletHistoryRequest>
{
public GetUserWalletChangeLogRequestValidator()
public GetUserWalletHistoryRequestValidator()
{
RuleFor(model => model.Id)
.NotNull();
}
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)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
@@ -1,10 +1,10 @@
using FluentValidation;
using CMSMicroservice.Protobuf.Protos.UserWalletChangeLog;
namespace CMSMicroservice.Protobuf.Validator.UserWalletChangeLog;
using CMSMicroservice.Protobuf.Protos.UserWalletHistory;
namespace CMSMicroservice.Protobuf.Validator.UserWalletHistory;
public class UpdateUserWalletChangeLogRequestValidator : AbstractValidator<UpdateUserWalletChangeLogRequest>
public class UpdateUserWalletHistoryRequestValidator : AbstractValidator<UpdateUserWalletHistoryRequest>
{
public UpdateUserWalletChangeLogRequestValidator()
public UpdateUserWalletHistoryRequestValidator()
{
RuleFor(model => model.Id)
.NotNull();
@@ -23,7 +23,7 @@ public class UpdateUserWalletChangeLogRequestValidator : AbstractValidator<Updat
}
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)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
@@ -1,6 +1,6 @@
namespace CMSMicroservice.WebApi.Common.Mappings;
public class UserWalletChangeLogProfile : IRegister
public class UserWalletHistoryProfile : IRegister
{
void IRegister.Register(TypeAdapterConfig config)
{
+1 -1
View File
@@ -281,7 +281,7 @@ static bool IsCustomerService(string serviceName)
"User", "UserAddress", "Commission", "NetworkMembership",
"ClubMembership", "UserOrder", "UserWallet", "UserCarts",
"DiscountShoppingCart", "City", "Package", "Transactions",
"UserContract", "UserWalletChangeLog"
"UserContract", "UserWalletHistory"
};
return customerServices.Any(customer => serviceName.Contains(customer, StringComparison.OrdinalIgnoreCase)) &&
@@ -321,7 +321,7 @@ public class PackageService : PackageContract.PackageContractBase
wallet.DiscountBalance += discountAmount;
// ثبت لاگ کیف پول
var walletLog = new CMSMicroservice.Domain.Entities.UserWalletChangeLog
var walletLog = new CMSMicroservice.Domain.Entities.UserWalletHistory
{
WalletId = wallet.Id,
CurrentBalance = wallet.Balance,
@@ -333,7 +333,7 @@ public class PackageService : PackageContract.PackageContractBase
IsIncrease = true,
RefrenceId = transaction.Id
};
_context.UserWalletChangeLogs.Add(walletLog);
_context.UserWalletHistories.Add(walletLog);
// به‌روزرسانی کاربر
var user = await _context.Users
@@ -322,7 +322,7 @@ public class UserOrderService : UserOrderContract.UserOrderContractBase
wallet.Balance -= totalAmount;
// Create wallet change log
var walletLog = new UserWalletChangeLog
var walletLog = new UserWalletHistory
{
WalletId = wallet.Id,
CurrentBalance = wallet.Balance,
@@ -335,7 +335,7 @@ public class UserOrderService : UserOrderContract.UserOrderContractBase
RefrenceId = transaction.Id
};
_context.UserWalletChangeLogs.Add(walletLog);
_context.UserWalletHistories.Add(walletLog);
// ═══ Magic Wallet: Entry / Exit Trigger ═══
// Q24: آستانه <= 1,000,000 ریال به جای == 0 (چون قیمت محصولات متفاوت است)
@@ -833,7 +833,7 @@ public class UserOrderService : UserOrderContract.UserOrderContractBase
if (wallet != null)
{
wallet.Balance += refundAmount;
_context.UserWalletChangeLogs.Add(new UserWalletChangeLog
_context.UserWalletHistories.Add(new UserWalletHistory
{
WalletId = wallet.Id,
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.UserWalletCQ.Queries.GetUserWallet;
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.GetCustomerWithdrawalSettings;
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,
IsIncrease = request.IsIncrease
@@ -112,7 +112,7 @@ public class UserWalletService : UserWalletContract.UserWalletContractBase
var changeLogs = await _sender.Send(query, context.CancellationToken);
var response = new GetCustomerWalletChangeLogResponse
var response = new GetCustomerWalletHistoryResponse
{
MetaData = new CMSMicroservice.Protobuf.Protos.MetaData
{
@@ -127,7 +127,7 @@ public class UserWalletService : UserWalletContract.UserWalletContractBase
foreach (var log in changeLogs)
{
response.Models.Add(new CustomerWalletChangeLogModel
response.Models.Add(new CustomerWalletHistoryModel
{
CurrentBalance = log.CurrentBalance,
ChangeValue = log.ChangeValue,