Phase 7a: Cosmetic cleanup + delete orphaned PurchasePackage handler
- Delete orphaned PurchasePackageCommand handler (no RPC dispatch, no callers) - Fix doc-comments: طلایی → پکیج in enums, entities, handlers - Remove stale 56M inline comments - Clean SystemConstants deprecated field docs
This commit is contained in:
+1
-1
@@ -12,7 +12,7 @@ namespace CMSMicroservice.Application.DayaLoanCQ.Commands.CheckAndProcessDayaLoa
|
||||
/// 1. استعلام از API دایا
|
||||
/// 2. ذخیره/بهروزرسانی DayaLoanContract
|
||||
/// 3. شارژ کیف پول برای وامهای تأیید شده
|
||||
/// 4. ثبت Order پکیج طلایی
|
||||
/// 4. ثبت Order پکیج
|
||||
/// 5. ارسال SMS
|
||||
/// </summary>
|
||||
public class CheckAndProcessDayaLoansCommandHandler : IRequestHandler<CheckAndProcessDayaLoansCommand, CheckAndProcessDayaLoansResponseDto>
|
||||
|
||||
+2
-2
@@ -116,8 +116,8 @@ public class CreateManualPaymentCommandHandler : IRequestHandler<CreateManualPay
|
||||
var oldBalance = wallet.Balance;
|
||||
var oldDiscountBalance = wallet.DiscountBalance;
|
||||
|
||||
wallet.Balance += balanceAmount; // +56M
|
||||
wallet.DiscountBalance += discountBalanceAmount; // +112M
|
||||
wallet.Balance += balanceAmount;
|
||||
wallet.DiscountBalance += discountBalanceAmount;
|
||||
|
||||
// 8. ثبت لاگ کیف پول
|
||||
var walletLog = new UserWalletChangeLog
|
||||
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
using CMSMicroservice.Application.Common.Interfaces;
|
||||
using CMSMicroservice.Application.Common.Models;
|
||||
using CMSMicroservice.Domain.Enums;
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace CMSMicroservice.Application.PackageCQ.Commands.PurchasePackage;
|
||||
|
||||
/// <summary>
|
||||
/// دستور خرید پکیج از طریق درگاه بانکی
|
||||
/// </summary>
|
||||
public class PurchasePackageCommand : IRequest<PaymentInitiateResult>
|
||||
{
|
||||
/// <summary>
|
||||
/// شناسه کاربر
|
||||
/// </summary>
|
||||
public long UserId { get; set; }
|
||||
}
|
||||
-164
@@ -1,164 +0,0 @@
|
||||
using CMSMicroservice.Application.Common.Exceptions;
|
||||
using CMSMicroservice.Application.Common.Interfaces;
|
||||
using CMSMicroservice.Application.Common.Models;
|
||||
using CMSMicroservice.Domain.Entities;
|
||||
using CMSMicroservice.Domain.Enums;
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using ValidationException = FluentValidation.ValidationException;
|
||||
|
||||
namespace CMSMicroservice.Application.PackageCQ.Commands.PurchasePackage;
|
||||
|
||||
public class PurchasePackageCommandHandler
|
||||
: IRequestHandler<PurchasePackageCommand, PaymentInitiateResult>
|
||||
{
|
||||
private readonly IApplicationDbContext _context;
|
||||
private readonly IPaymentGatewayService _paymentGateway;
|
||||
private readonly IConfiguration _configuration;
|
||||
private readonly ILogger<PurchasePackageCommandHandler> _logger;
|
||||
|
||||
public PurchasePackageCommandHandler(
|
||||
IApplicationDbContext context,
|
||||
IPaymentGatewayService paymentGateway,
|
||||
IConfiguration configuration,
|
||||
ILogger<PurchasePackageCommandHandler> logger)
|
||||
{
|
||||
_context = context;
|
||||
_paymentGateway = paymentGateway;
|
||||
_configuration = configuration;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task<PaymentInitiateResult> Handle(
|
||||
PurchasePackageCommand request,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.LogInformation(
|
||||
"Starting package purchase for UserId: {UserId}",
|
||||
request.UserId
|
||||
);
|
||||
|
||||
// 1. بررسی وجود کاربر
|
||||
var user = await _context.Users
|
||||
.FirstOrDefaultAsync(u => u.Id == request.UserId, cancellationToken);
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
_logger.LogWarning("User not found: {UserId}", request.UserId);
|
||||
throw new NotFoundException(nameof(User), request.UserId);
|
||||
}
|
||||
|
||||
// 2. بررسی اینکه قبلاً پکیج نخریده باشد
|
||||
if (user.PackagePurchaseMethod != PackagePurchaseMethod.None)
|
||||
{
|
||||
_logger.LogWarning(
|
||||
"User {UserId} has already purchased package via {Method}",
|
||||
request.UserId,
|
||||
user.PackagePurchaseMethod
|
||||
);
|
||||
throw new ValidationException(
|
||||
"شما قبلاً پکیج را خریداری کردهاید"
|
||||
);
|
||||
}
|
||||
|
||||
// 3. پیدا کردن پکیج (فعلاً پکیج طلایی)
|
||||
var goldenPackage = await _context.Packages
|
||||
.FirstOrDefaultAsync(
|
||||
p => p.Title.Contains("طلایی") || p.Title.Contains("Golden"),
|
||||
cancellationToken
|
||||
);
|
||||
|
||||
if (goldenPackage == null)
|
||||
{
|
||||
_logger.LogError("Package not found in database");
|
||||
throw new NotFoundException("پکیج یافت نشد");
|
||||
}
|
||||
|
||||
// 4. پیدا کردن آدرس پیشفرض کاربر (برای فیلد اجباری)
|
||||
var defaultAddress = await _context.UserAddresses
|
||||
.Where(a => a.UserId == request.UserId)
|
||||
.OrderByDescending(a => a.Created)
|
||||
.FirstOrDefaultAsync(cancellationToken);
|
||||
|
||||
if (defaultAddress == null)
|
||||
{
|
||||
_logger.LogWarning("No address found for user {UserId}", request.UserId);
|
||||
throw new ValidationException(
|
||||
"لطفاً ابتدا یک آدرس برای خود ثبت کنید"
|
||||
);
|
||||
}
|
||||
|
||||
// 5. ایجاد سفارش
|
||||
var order = new UserOrder
|
||||
{
|
||||
UserId = user.Id,
|
||||
PackageId = goldenPackage.Id,
|
||||
Amount = goldenPackage.Price, // 56,000,000 تومان
|
||||
PaymentStatus = PaymentStatus.Pending,
|
||||
DeliveryStatus = DeliveryStatus.None,
|
||||
UserAddressId = defaultAddress.Id,
|
||||
PaymentMethod = PaymentMethod.IPG
|
||||
};
|
||||
|
||||
_context.UserOrders.Add(order);
|
||||
await _context.SaveChangesAsync(cancellationToken);
|
||||
|
||||
_logger.LogInformation(
|
||||
"Created UserOrder {OrderId} for UserId {UserId}, Amount: {Amount}",
|
||||
order.Id,
|
||||
request.UserId,
|
||||
order.Amount
|
||||
);
|
||||
|
||||
// 6. ایجاد درخواست پرداخت از درگاه
|
||||
var paymentRequest = new PaymentRequest
|
||||
{
|
||||
Amount = order.Amount,
|
||||
UserId = user.Id,
|
||||
Mobile = user.Mobile ?? "",
|
||||
CallbackUrl = $"{_configuration["CmsBaseUrl"] ?? "https://localhost:32846"}/api/package/verify-package",
|
||||
Description = $"خرید پکیج - سفارش #{order.Id}"
|
||||
};
|
||||
|
||||
var paymentResult = await _paymentGateway.InitiatePaymentAsync(paymentRequest);
|
||||
|
||||
if (!paymentResult.IsSuccess)
|
||||
{
|
||||
_logger.LogError(
|
||||
"Payment gateway failed for OrderId {OrderId}: {ErrorMessage}",
|
||||
order.Id,
|
||||
paymentResult.ErrorMessage
|
||||
);
|
||||
|
||||
// بهروزرسانی وضعیت سفارش
|
||||
order.PaymentStatus = PaymentStatus.Reject;
|
||||
await _context.SaveChangesAsync(cancellationToken);
|
||||
|
||||
throw new Exception(
|
||||
$"خطا در ارتباط با درگاه پرداخت: {paymentResult.ErrorMessage}"
|
||||
);
|
||||
}
|
||||
|
||||
_logger.LogInformation(
|
||||
"Payment initiated successfully. OrderId: {OrderId}, RefId: {RefId}",
|
||||
order.Id,
|
||||
paymentResult.RefId
|
||||
);
|
||||
|
||||
return paymentResult;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(
|
||||
ex,
|
||||
"Error in PurchasePackageCommand for UserId: {UserId}",
|
||||
request.UserId
|
||||
);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
using FluentValidation;
|
||||
|
||||
namespace CMSMicroservice.Application.PackageCQ.Commands.PurchasePackage;
|
||||
|
||||
public class PurchasePackageCommandValidator : AbstractValidator<PurchasePackageCommand>
|
||||
{
|
||||
public PurchasePackageCommandValidator()
|
||||
{
|
||||
RuleFor(x => x.UserId)
|
||||
.GreaterThan(0)
|
||||
.WithMessage("شناسه کاربر باید بزرگتر از صفر باشد");
|
||||
}
|
||||
}
|
||||
@@ -41,14 +41,14 @@ public static class SystemConstants
|
||||
#region Package Settings
|
||||
|
||||
/// <summary>
|
||||
/// مبلغ پکیج طلایی / پایه (ریال) - 56 میلیون تومان
|
||||
/// مبلغ پکیج پایه (ریال)
|
||||
/// [DEPRECATED] از Package.Price استفاده کنید
|
||||
/// </summary>
|
||||
[Obsolete("Moved to Package.Price. Read from Package entity instead.")]
|
||||
public const long BasePackageAmount = 56_000_000;
|
||||
|
||||
/// <summary>
|
||||
/// مبلغ وام دایا (ریال) - همان مبلغ پکیج طلایی
|
||||
/// مبلغ وام دایا (ریال)
|
||||
/// [DEPRECATED] از Package.Price استفاده کنید
|
||||
/// </summary>
|
||||
[Obsolete("Moved to Package.Price. Read from Package entity with SupportsDayaPurchase=true.")]
|
||||
|
||||
@@ -63,7 +63,7 @@ public class User : BaseAuditableEntity
|
||||
public DateTime? DayaCreditReceivedAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// نحوه خرید پکیج طلایی (برای جلوگیری از خرید مجدد)
|
||||
/// نحوه خرید پکیج (برای جلوگیری از خرید مجدد)
|
||||
/// </summary>
|
||||
public PackagePurchaseMethod PackagePurchaseMethod { get; set; } = PackagePurchaseMethod.None;
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ public class UserWallet : BaseAuditableEntity
|
||||
public long Balance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// موجودی شبکه/کارمزد (کیف پول طلایی) - قابل برداشت نقدی یا خرید الماس
|
||||
/// موجودی شبکه/کارمزد — قابل برداشت نقدی یا خرید الماس
|
||||
/// </summary>
|
||||
public long NetworkBalance { get; set; }
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ public enum CommissionPayoutStatus
|
||||
Pending = 0,
|
||||
|
||||
/// <summary>
|
||||
/// واریز شده به کیف پول طلایی
|
||||
/// واریز شده به کیف پول
|
||||
/// </summary>
|
||||
Paid = 1,
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace CMSMicroservice.Domain.Enums;
|
||||
|
||||
/// <summary>
|
||||
/// نحوه خرید پکیج طلایی توسط کاربر
|
||||
/// نحوه خرید پکیج توسط کاربر
|
||||
/// </summary>
|
||||
public enum PackagePurchaseMethod
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user