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,169 @@
using CMSMicroservice.Application.Common.Interfaces;
using CMSMicroservice.Domain.Entities.DiscountShop;
using CMSMicroservice.Domain.Entities.Payment;
using CMSMicroservice.Domain.Enums;
using MediatR;
using Microsoft.EntityFrameworkCore;
namespace CMSMicroservice.Application.DiscountShopCQ.Commands.PlaceOrder;
public class PlaceOrderCommandHandler : IRequestHandler<PlaceOrderCommand, PlaceOrderResponseDto>
{
private readonly IApplicationDbContext _context;
public PlaceOrderCommandHandler(IApplicationDbContext context)
{
_context = context;
}
public async Task<PlaceOrderResponseDto> Handle(PlaceOrderCommand request, CancellationToken cancellationToken)
{
// Get user wallet
var userWallet = await _context.UserWallets
.FirstOrDefaultAsync(w => w.UserId == request.UserId, cancellationToken);
if (userWallet == null)
{
return new PlaceOrderResponseDto
{
Success = false,
Message = "کیف پول کاربر یافت نشد"
};
}
// Get cart items with products
var cartItems = await _context.DiscountShoppingCarts
.Where(c => c.UserId == request.UserId)
.Include(c => c.Product)
.ToListAsync(cancellationToken);
if (!cartItems.Any())
{
return new PlaceOrderResponseDto
{
Success = false,
Message = "سبد خرید خالی است"
};
}
// Validate stock and calculate totals
long totalAmount = 0;
long totalDiscountAmount = 0;
var orderDetails = new List<DiscountOrderDetail>();
foreach (var cartItem in cartItems)
{
var product = cartItem.Product;
// Check stock
if (product.RemainingCount < cartItem.Count)
{
return new PlaceOrderResponseDto
{
Success = false,
Message = $"موجودی محصول '{product.Title}' کافی نیست"
};
}
// Check if product is active
if (!product.IsActive)
{
return new PlaceOrderResponseDto
{
Success = false,
Message = $"محصول '{product.Title}' غیرفعال است"
};
}
// Calculate discount for this product
var itemTotal = product.Price * cartItem.Count;
var maxDiscountForItem = (itemTotal * product.MaxDiscountPercent) / 100;
totalAmount += itemTotal;
totalDiscountAmount += maxDiscountForItem;
orderDetails.Add(new DiscountOrderDetail
{
ProductId = product.Id,
Count = cartItem.Count,
UnitPrice = product.Price,
DiscountPercentUsed = product.MaxDiscountPercent,
DiscountAmount = maxDiscountForItem,
FinalPrice = itemTotal - maxDiscountForItem
});
}
// Validate discount balance usage
var maxDiscountBalanceUsable = totalDiscountAmount;
var actualDiscountBalanceUsed = Math.Min(request.DiscountBalanceToUse, maxDiscountBalanceUsable);
actualDiscountBalanceUsed = Math.Min(actualDiscountBalanceUsed, userWallet.DiscountBalance);
if (actualDiscountBalanceUsed < request.DiscountBalanceToUse)
{
return new PlaceOrderResponseDto
{
Success = false,
Message = $"موجودی تخفیف کافی نیست. حداکثر قابل استفاده: {maxDiscountBalanceUsable:N0} تومان، موجودی شما: {userWallet.DiscountBalance:N0} تومان"
};
}
var gatewayAmountRequired = totalAmount - actualDiscountBalanceUsed;
// Calculate VAT (9%)
var vatAmount = (gatewayAmountRequired * 9) / 100;
var finalGatewayAmount = gatewayAmountRequired + vatAmount;
// Create transaction for gateway payment
var transaction = new Transaction
{
Amount = finalGatewayAmount,
Description = $"خرید از فروشگاه تخفیف - مبلغ کل: {totalAmount:N0}، اعتبار تخفیف: {actualDiscountBalanceUsed:N0}",
PaymentStatus = PaymentStatus.Pending,
Type = TransactionType.DiscountShopPurchase
};
_context.Transactions.Add(transaction);
await _context.SaveChangesAsync(cancellationToken);
// Create order
var order = new DiscountOrder
{
UserId = request.UserId,
TotalAmount = totalAmount,
DiscountBalanceUsed = actualDiscountBalanceUsed,
GatewayAmountPaid = finalGatewayAmount,
VatAmount = vatAmount,
PaymentStatus = PaymentStatus.Pending,
TransactionId = transaction.Id,
UserAddressId = request.UserAddressId,
DeliveryStatus = DeliveryStatus.Pending
};
_context.DiscountOrders.Add(order);
await _context.SaveChangesAsync(cancellationToken);
// Add order details
foreach (var detail in orderDetails)
{
detail.DiscountOrderId = order.Id;
}
_context.DiscountOrderDetails.AddRange(orderDetails);
// Clear cart
_context.DiscountShoppingCarts.RemoveRange(cartItems);
await _context.SaveChangesAsync(cancellationToken);
return new PlaceOrderResponseDto
{
Success = true,
Message = "سفارش ایجاد شد. لطفا پرداخت را تکمیل کنید",
OrderId = order.Id,
TransactionId = transaction.Id,
TotalAmount = totalAmount,
DiscountBalanceUsed = actualDiscountBalanceUsed,
GatewayAmountRequired = finalGatewayAmount
};
}
}