예제 #1
0
        public async Task <PlaceBidResult> PlaceBidAsync(PlaceBidRequest bidRequest)
        {
            var result = new PlaceBidResult();

            if (!bidRequest.Event.IsBiddingOpen(DateTime.Now))
            {
                result.ResultType = PlaceBidResultType.BiddingClosed;
                return(result);
            }

            if (bidRequest.Amount < bidRequest.Product.NextMinBidAmount)
            {
                result.ResultType = PlaceBidResultType.InvalidAmount;
                return(result);
            }

            try
            {
                var previousBid = await GetLatestBidAsync(bidRequest.Product.Id);

                var bid = new Bid
                {
                    Product   = bidRequest.Product,
                    User      = bidRequest.User,
                    Timestamp = DateTime.Now,
                    Amount    = bidRequest.Amount
                };

                _dbContext.Bids.Add(bid);
                await _dbContext.SaveChangesAsync();

                bidRequest.Product.CurrentBidAmount     = bid.Amount;
                bidRequest.Product.CurrentHighBidUserId = bidRequest.User.Id;
                bidRequest.Product.BidCount++;

                _dbContext.Products.Update(bidRequest.Product);
                await _dbContext.SaveChangesAsync();

                result.ResultType = PlaceBidResultType.Success;
                result.BidId      = bid.Id;

                await _hubContext.Clients.All.SendAsync("BidPlaced", bidRequest.Product.Name, bidRequest.Amount);

                if (previousBid != null && previousBid.UserId != bidRequest.User.Id)
                {
                    await SendOutbidNoticeAsync(bidRequest.Event, bidRequest.Product, previousBid, bid);
                }

                return(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error placing bid for product ID {id} (User: {userId})", bidRequest.Product.Id, bidRequest.User.Id);

                throw ex;
            }
        }
예제 #2
0
        public async Task <IActionResult> Create(string evtSlug, EventUserListViewModel model)
        {
            var evt = await _dbContext.Events.SingleOrDefaultAsync(x => x.Slug == evtSlug);

            if (evt == null)
            {
                _logger.LogInformation("Event with slug '{slug}' not found", evtSlug);
                return(NotFound());
            }

            try
            {
                var user = await _userManager.FindByEmailAsync(model.NewUserEmail);

                if (user == null)
                {
                    ModelState.AddModelError("NewUserEmail", "User with this email does not exist.");
                    return(await Index(evtSlug));
                }

                var existingUser = await _dbContext.EventUsers.SingleOrDefaultAsync(x => x.EventId == evt.Id && x.UserId == user.Id);

                if (existingUser != null)
                {
                    ModelState.AddModelError("NewUserEmail", "User is alredy a member of this event.");
                    return(await Index(evtSlug));
                }

                var evtUser = new EventUser
                {
                    Event     = evt,
                    User      = user,
                    IsAdmin   = model.NewUserIsAdmin,
                    CreatedOn = DateTime.Now
                };

                _dbContext.EventUsers.Add(evtUser);
                await _dbContext.SaveChangesAsync();

                return(RedirectToAction(nameof(Index), new { slug = evtSlug }));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error adding user '{user}' to event {id}", model.NewUserEmail, evt.Id);

                ModelState.AddModelError("", "Error adding user to event");
                return(await Index(evtSlug));
            }
        }
예제 #3
0
        public async Task <IActionResult> BuyNow([FromBody] BuyNowModel model)
        {
            var product = await _dbContext.Products.FindAsync(model.ProductId);

            if (product == null)
            {
                _logger.LogInformation("Product {productId} not found", model.ProductId);
                return(NotFound());
            }

            if (!product.BuyItNowPrice.HasValue)
            {
                return(BadRequest("Buy it now not enabled for specified product."));
            }

            var evt = await _dbContext.Events.FindAsync(product.EventId);

            if (evt == null)
            {
                _logger.LogInformation("Event {eventId} not found", product.EventId);
                return(NotFound());
            }

            var user = await _userManager.GetUserAsync(User);

            if (product.IsPurchased)
            {
                return(BadRequest("Product has already been purchased."));
            }

            try
            {
                var placeBidRequest = new PlaceBidRequest
                {
                    Event   = evt,
                    Product = product,
                    User    = user,
                    Amount  = product.BuyItNowPrice.Value
                };
                var bidResult = await _bidService.PlaceBidAsync(placeBidRequest);

                // TODO: probably would be wise to move this into the BidService
                product.PurchasedDate   = DateTime.UtcNow;
                product.PurchasedUserId = user.Id;

                _dbContext.Products.Update(product);
                await _dbContext.SaveChangesAsync();

                return(Created("", null));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error procesing buy it now for product ID {id}", model.ProductId);
                return(StatusCode(500));
            }
        }
예제 #4
0
        public async Task <IActionResult> Create(EditEventViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return(View(model));
            }

            if (!(await _authorizationService.AuthorizeAsync(User, Policies.Admin)).Succeeded)
            {
                return(Forbid());
            }

            try
            {
                var user = await _userManager.GetUserAsync(User);

                var evt = new Event
                {
                    Name                    = model.Name,
                    Description             = model.Description,
                    StartOn                 = model.StartOn,
                    EndOn                   = model.EndOn,
                    DisplayOn               = model.DisplayOn,
                    HideBidderNames         = model.HideBidderNames,
                    DefaultMinimumBidAmount = model.DefaultMinimumBidAmount,
                    Owner                   = user,
                    CreatedOn               = DateTime.UtcNow
                };

                evt.Slug = await GenerateSlug(evt.Name);

                _dbContext.Events.Add(evt);
                await _dbContext.SaveChangesAsync();

                return(RedirectToAction(nameof(Index)));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error creating event '{name}'", model.Name);
                return(View(model));
            }
        }
예제 #5
0
        public async Task <IActionResult> Create(string evtSlug, EditProductViewModel model)
        {
            var evt = await _dbContext.Events.SingleOrDefaultAsync(x => x.Slug == evtSlug);

            var user = await _userManager.GetUserAsync(User);

            if (!ModelState.IsValid)
            {
                return(View(model));
            }

            if (evt == null)
            {
                _logger.LogInformation("Could not find event with slug '{slug}'", evtSlug);
                return(RedirectToAction("Index", "Events"));
            }

            if (!(await _authorizationService.AuthorizeAsync(User, evt, Policies.EventAdmin)).Succeeded)
            {
                return(Forbid());
            }

            // Reset event props in case something fails...
            model.EventId   = evt.Id;
            model.EventSlug = evt.Slug;
            model.EventName = evt.Name;

            try
            {
                var product = new Product
                {
                    Event            = evt,
                    Name             = model.Name,
                    Description      = model.Description,
                    StartingPrice    = model.StartingPrice,
                    MinimumBidAmount = model.MinimumBidAmount,
                    CurrentBidAmount = model.StartingPrice,
                    BuyItNowPrice    = model.BuyItNowPrice
                };

                product.Slug = await GenerateSlugAsync(evt.Id, product.Name);

                _dbContext.Products.Add(product);
                await _dbContext.SaveChangesAsync();

                // Save images after the product is created because we need the ID
                if (model.ImageFile != null)
                {
                    product.ImageFilename = GenerateImageFilename(product, model.ImageFile.FileName);

                    var imagePath = string.Format(Constants.ImagePathFormat, evt.Slug, product.ImageFilename);

                    using (var stream = model.ImageFile.OpenReadStream())
                    {
                        await _fileService.SaveFileAsync(imagePath, model.ImageFile.ContentType, stream);
                    }

                    _dbContext.Products.Update(product);
                    await _dbContext.SaveChangesAsync();
                }

                if (model.ThumbnailFile != null)
                {
                    product.ThumbnailFilename = GenerateImageFilename(product, model.ThumbnailFile.FileName, true);

                    var imagePath = string.Format(Constants.ImagePathFormat, evt.Slug, product.ThumbnailFilename);

                    using (var stream = model.ThumbnailFile.OpenReadStream())
                    {
                        await _fileService.SaveFileAsync(imagePath, model.ThumbnailFile.ContentType, stream);
                    }

                    _dbContext.Products.Update(product);
                    await _dbContext.SaveChangesAsync();
                }

                return(RedirectToAction("Details", "Events", new { slug = evtSlug }));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error adding product '{name}' to event ID {evtId}", model.Name, evt.Id);

                return(View(model));
            }
        }