public async Task <IActionResult> RustStandardItem([FromForm] RustStoreStandardItemOrder model) { if (User.Identity.IsAuthenticated) { var purchaseResult = await _rustStoreStandardProductPurchaseService.TryPurchaseAsync(model); if (purchaseResult.Status == RustStorePurchaseProductResultEnum.ContactSupport) { return(RedirectToAction("PurchaseFailed", "Purchase", new { message = purchaseResult.ErrorMessage, contactSupport = true })); } if (purchaseResult.Status == RustStorePurchaseProductResultEnum.Failed) { return(RedirectToAction("PurchaseFailed", "Purchase", new { message = purchaseResult.ErrorMessage })); } return(RedirectToAction("PurchaseSuccess", "Purchase", new { imgUrl = purchaseResult.RustProduct.RustItem.ImgUrl })); } return(RedirectToAction("UserHaveToBeLoggedIn", "Authentication")); }
public async Task <RustStorePurchaseStandardProductResultDto> TryPurchaseAsync(RustStoreStandardItemOrder model) { #region Data preparation var steamUser = _steamUserService.GetCurrentRequestSteamUser(); var steamUserShop = _steamUserService.GetCurrentRequestSteamUserShop(); var currentShop = _rustShopService.GetCurrentRequestShopInRustStore(); var currentUserShop = _easyShopContext.UserShops.FirstOrDefault(x => x.ShopId == currentShop.Id); var appUser = await _userManager.FindByIdAsync(currentUserShop?.AppUserId); var rustUserItem = _easyShopContext.RustUserItems .Include(x => x.RustItem) .FirstOrDefault(x => x.Id == Guid.Parse(model.ItemId)); #endregion Data preparation #region Check data, continue or return var errorId = Guid.NewGuid(); if (rustUserItem is null || appUser is null || currentUserShop is null || currentShop is null || steamUserShop is null || steamUser is null) { var error = new { ErrorId = errorId, rustUserItem = rustUserItem?.Id, currentShopOwner = appUser?.Id, currentShop = currentShop?.Id, ErrosteamUserrId = steamUser?.Id, currentUserShop_AppUserId = currentUserShop?.AppUserId, currentUserShop_ShopId = currentUserShop?.ShopId, steamUserShop_SteamUserId = steamUserShop?.SteamUser.Id, steamUserShop_ShopId = steamUserShop?.Shop.Id, }; _logger.LogError($"Purchase data preparation ErrorID: {errorId}\nVariables:\n{JsonConvert.SerializeObject(error, Formatting.Indented)}"); return(new RustStorePurchaseStandardProductResultDto() { Status = RustStorePurchaseProductResultEnum.ContactSupport, ErrorMessage = $"Please contact support and give them this id '{errorId}'" }); } #endregion Check data, continue or return #region Price calculation decimal actualPrice; if (rustUserItem.Discount > 0) { actualPrice = rustUserItem.Price - (rustUserItem.Price / 100) * rustUserItem.Discount; } else { actualPrice = rustUserItem.Price; } actualPrice *= model.Amount; #endregion Price calculation #region Check balance have enough money, if not return if (steamUserShop.Balance < actualPrice) { var balanceTooLow = new { SteamUserId = steamUser.Id, ShopId = currentShop.Id, UserBalanceInShop = steamUserShop.Balance, OrderPrice = actualPrice, AmountOfItemsInOrder = model.Amount, SingleItemPrice = rustUserItem.Price - (rustUserItem.Price / 100) * rustUserItem.Discount }; _logger.LogInformation($"Balance too low:\n{JsonConvert.SerializeObject(balanceTooLow, Formatting.Indented)}"); return(new RustStorePurchaseStandardProductResultDto() { Status = RustStorePurchaseProductResultEnum.Failed, ErrorMessage = "Sorry, your balance is too low for this item please Top-Up balance and try again." }); } #endregion Check balance have enough money, if not return #region SteamUserShop updating entry values steamUserShop.Balance -= actualPrice; steamUserShop.TotalSpent += actualPrice; _easyShopContext.SteamUsersShops.Update(steamUserShop); #endregion SteamUserShop updating entry values #region SteamUser updating entry values steamUser.TotalSpent += actualPrice; _easyShopContext.SteamUsers.Update(steamUser); #endregion SteamUser updating entry values #region Creating entry RustPurchasedItems Guid rustPurchasedItemId; do { rustPurchasedItemId = Guid.NewGuid(); } while (_easyShopContext.RustPurchasedItems.FirstOrDefault(x => x.Id == rustPurchasedItemId) != null); var newRustPurchasedItem = new RustPurchasedItem { Id = rustPurchasedItemId, SteamUser = steamUser, RustItem = rustUserItem.RustItem, AmountLeft = model.Amount, AmountOnPurchase = model.Amount, ItemsPerStack = rustUserItem.ItemsPerStack, PurchaseDateTime = DateTime.Now, TotalPaid = actualPrice }; _easyShopContext.RustPurchasedItems.Add(newRustPurchasedItem); #endregion Creating entry RustPurchasedItems #region Creating entry RustPurchaseStats Guid rustPurchasedStatsId; do { rustPurchasedStatsId = Guid.NewGuid(); } while (_easyShopContext.RustPurchaseStats.FirstOrDefault(x => x.Id == rustPurchasedStatsId) != null); var newRustPurchaseStats = new RustPurchaseStats { Id = rustPurchasedStatsId, AppUser = appUser, RustPurchasedItem = newRustPurchasedItem, Shop = currentShop }; _easyShopContext.RustPurchaseStats.Add(newRustPurchaseStats); #endregion Creating entry RustPurchaseStats #region Try to save data into DB. Return on error try { await _easyShopContext.SaveChangesAsync(); var purchaseSuccessDetails = new { SteamUserId = steamUser.Id, RustPurchasedItemId = rustPurchasedItemId, RustPurchasedStatsId = rustPurchasedStatsId }; var balanceBeforeFundsAddition = appUser.Balance; decimal fundsAddToAppUser = actualPrice - (actualPrice / 100) * _servicePercentPerTransaction; appUser.Balance += fundsAddToAppUser; _easyShopContext.Users.Update(appUser); await _easyShopContext.SaveChangesAsync(); _logger.LogInformation($"\nAppUser ID: {appUser.Id}\nAppUser Email: {appUser.Email}\nBalance before funds addition: {balanceBeforeFundsAddition}\nFunds added: {fundsAddToAppUser}\nBalance after funds addition: {appUser.Balance}"); _logger.LogInformation($"Purchase success:\n{JsonConvert.SerializeObject(purchaseSuccessDetails, Formatting.Indented)}"); return(new RustStorePurchaseStandardProductResultDto { Status = RustStorePurchaseProductResultEnum.Success, RustProduct = rustUserItem }); } catch (Exception e) { _logger.LogError(e, $"Error on purchase:\n"); return(new RustStorePurchaseStandardProductResultDto() { Status = RustStorePurchaseProductResultEnum.Failed, ErrorMessage = "Please contact support!" }); } #endregion Try to save data into DB. Return on error }