using CMSMicroservice.Domain.Enums; using CMSMicroservice.Domain.Events; namespace CMSMicroservice.Application.UserOrderCQ.Commands.SubmitShopBuyOrder; public class SubmitShopBuyOrderCommandHandler : IRequestHandler { private readonly IApplicationDbContext _context; public SubmitShopBuyOrderCommandHandler(IApplicationDbContext context) { _context = context; } public async Task Handle(SubmitShopBuyOrderCommand request, CancellationToken cancellationToken) { var user = await _context.Users .Include(i => i.UserAddresss) .Include(i => i.UserWallets) .ThenInclude(i => i.UserWalletChangeLogs) .Include(i => i.UserCartss) .ThenInclude(i => i.Product) .FirstOrDefaultAsync(w => w.Id == request.UserId, cancellationToken: cancellationToken); if (user.UserCartss.Count == 0) throw new NotFoundException("UserCart", request.UserId); if (user.UserCartss.Sum(s => s.Count * s.Product.Price) != request.TotalAmount) throw new Exception("مبلغ سفارش با مجموع سبد خرید مطابقت ندارد."); var userWallet = user.UserWallets.FirstOrDefault(); if (userWallet == null) throw new Exception("کیف پول کاربر یافت نشد."); var newTransaction = new Transactions() { Amount = request.TotalAmount, Description = "خرید از فروشگاه", PaymentStatus = PaymentStatus.Success, PaymentDate = DateTime.Now, Type = TransactionType.Buy, RefId = "localwallet-" + Guid.NewGuid().ToString() }; await _context.Transactionss.AddAsync(newTransaction, cancellationToken); await _context.SaveChangesAsync(cancellationToken); var newWalletLog = new UserWalletChangeLog() { CurrentBalance = userWallet.Balance, ChangeValue = -1*request.TotalAmount, IsIncrease = false, RefrenceId = newTransaction.Id }; userWallet.Balance -= request.TotalAmount; await _context.UserWalletChangeLogs.AddAsync(newWalletLog, cancellationToken); await _context.SaveChangesAsync(cancellationToken); var newOrder = new UserOrder() { Amount = request.TotalAmount, PaymentStatus = PaymentStatus.Success, PaymentMethod = PaymentMethod.Wallet, PaymentDate = DateTime.Now, UserId = request.UserId, UserAddressId = user.UserAddresss.First(f => f.IsDefault).Id, TransactionId = newTransaction.Id }; await _context.UserOrders.AddAsync(newOrder, cancellationToken); await _context.SaveChangesAsync(cancellationToken); await _context.FactorDetailss.AddRangeAsync(user.UserCartss.Select(s => new FactorDetails() { ProductId = s.ProductId, Count = s.Count, UnitPrice = s.Product.Price, OrderId = newOrder.Id }), cancellationToken); user.UserCartss.Clear(); await _context.SaveChangesAsync(cancellationToken); return new SubmitShopBuyOrderResponseDto() { Id = newOrder.Id, PaymentMethod = newOrder.PaymentMethod, PaymentStatus = newOrder.PaymentStatus, TotalAmount = newOrder.Amount, UserAddressText = user.UserAddresss.First(f => f.IsDefault).Address, Created = newOrder.PaymentDate }; } }