public async Task <UserTokenTransactionModel> CreateTokenTransaction(long userId, TokenTransactionInsertModel model, TokenTransactionType transactionType) { using (var transaction = await _context.Database.BeginTransactionAsync()) { try { var currentDateTime = DateTime.UtcNow; var tokenTransaction = _tokenHelper.AddTokenTransaction(userId, currentDateTime, currentDateTime, model, transactionType); transaction.Commit(); return(_mapper.Map <UserTokenTransaction, UserTokenTransactionModel>(tokenTransaction)); } catch (Exception) { transaction.Rollback(); throw; } } }
public async Task <OrderReturnModel> Checkout(long userId, CheckoutTransferModel model) { using (var transaction = await _context.Database.BeginTransactionAsync()) { try { var order = await _context.Orders .Include(o => o.Customer) .Include(o => o.OrderItems) .ThenInclude(oi => oi.Product) .FirstOrDefaultAsync(o => o.CustomerId == userId && o.AddedDate > o.CheckedOutDate && o.AddedDate > o.ConfirmedDate && o.AddedDate > o.CancelledDate); if (order == null) { order = new Order { AddedDate = DateTime.UtcNow, CustomerId = userId }; _context.Orders.Add(order); _context.SaveChanges(); order = await _context.Orders .Include(o => o.Customer) .Include(o => o.OrderItems) .ThenInclude(oi => oi.Product) .FirstOrDefaultAsync(o => o.CustomerId == userId && o.AddedDate > o.CheckedOutDate && o.AddedDate > o.ConfirmedDate && o.AddedDate > o.CancelledDate); } foreach (var item in model.Items) { var product = await _context.Products.FirstOrDefaultAsync(p => p.Id == item.ProductId); if (product == null) { throw new ProductNotFoundException(); } if (product.Deprecated) { throw new ProductIsDeprecatedException(); } if (product.OutOfStock) { throw new ProductIsOutOfStockException(); } var orderItem = _mapper.Map <OrderItemTransferModel, OrderItem>(item); orderItem.OrderId = order.Id; orderItem.SinglePrice = product.Price; _context.OrderItems.Add(orderItem); } var totalPrice = order.OrderItems.Sum(oi => oi.SinglePrice * oi.Quantity); if (totalPrice > order.Customer.Balance) { throw new InsufficientBalanceException(); } order.CustomerName = model.Name; order.Address = model.Address; order.Notes = model.Notes; order.CheckedOutDate = DateTime.UtcNow; // Updating balance var currentDateTime = DateTime.UtcNow; var tokenTransactionInsertModel = new TokenTransactionInsertModel { Amount = totalPrice, Notes = $"Payment for order with ID : {order.Id}" }; _tokenHelper.AddTokenTransaction(userId, currentDateTime, currentDateTime, tokenTransactionInsertModel, TokenTransactionType.Subtract); _context.Orders.Update(order); _context.Users.Update(order.Customer); await _context.SaveChangesAsync(); transaction.Commit(); var populatedCart = await _context.Orders .Include(o => o.OrderItems) .ThenInclude(oi => oi.Product) .Include(o => o.Customer) .FirstOrDefaultAsync(o => o.Id == order.Id); return(_mapper.Map <Order, OrderReturnModel>(populatedCart)); } catch (Exception) { transaction.Rollback(); throw; } } }