Add validators and services for Product Galleries and Product Tags

- Implemented Create, Delete, Get, and Update validators for Product Galleries.
- Added Create, Delete, Get, and Update validators for Product Tags.
- Created service classes for handling Discount Categories, Discount Orders, Discount Products, Discount Shopping Cart, Product Categories, Product Galleries, and Product Tags.
- Each service class integrates with CQRS for command and query handling.
- Established mapping profiles for Product Galleries.
This commit is contained in:
masoodafar-web
2025-12-04 02:40:49 +03:30
parent 40d54d08fc
commit f0f48118e7
436 changed files with 33159 additions and 2005 deletions
@@ -0,0 +1,160 @@
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.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 ILogger<PurchasePackageCommandHandler> _logger;
public PurchasePackageCommandHandler(
IApplicationDbContext context,
IPaymentGatewayService paymentGateway,
ILogger<PurchasePackageCommandHandler> logger)
{
_context = context;
_paymentGateway = paymentGateway;
_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 = $"https://yourdomain.com/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;
}
}
}