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:
+169
@@ -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
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user