コード例 #1
0
        public async Task <IActionResult> Checkout(CheckoutTransferModel model)
        {
            var userId = long.Parse(User.Claims.First().Subject.Name);
            var result = await _orderService.Checkout(userId, model);

            return(ApiResponder.RespondSuccess(result));
        }
コード例 #2
0
        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;
                }
            }
        }