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 }
private async Task CreateTestStats(Guid shopId) { var purchasedItemsList = new List <RustPurchasedItem>(); var rustPurchaseStatsList = new List <RustPurchaseStats>(); var user = await _userManager.FindByEmailAsync(DefaultIdentity.AdminUserName); var shop = _shopService.GetShopById(shopId); var steamUser = await CreateDefaultRustUser(); DateTime dateWeekAgo = DateTime.Now.Subtract(TimeSpan.FromDays(7)); DateTime dateMonthAgo = DateTime.Now.Subtract(TimeSpan.FromDays(31)); DateTime dateYearAgo = DateTime.Now.Subtract(TimeSpan.FromDays(365)); Random rnd = new Random(); for (int i = 0; i < 1000; i++) { var rndAmount = rnd.Next(1, 3); var rustPurchasedItem = new RustPurchasedItem { Id = Guid.NewGuid(), SteamUser = steamUser, RustItem = _easyShopContext.RustItems.First(), AmountLeft = rndAmount, AmountOnPurchase = rndAmount, ItemsPerStack = rnd.Next(1, 3), TotalPaid = rnd.Next(1, 5) }; if (i >= 0 && i < 50) //Last week { rustPurchasedItem.PurchaseDateTime = dateWeekAgo.AddDays(rnd.Next(0, 7)); } else if (i >= 50 && i < 200) //Last month { rustPurchasedItem.PurchaseDateTime = dateMonthAgo.AddDays(rnd.Next(0, 24)); } else if (i >= 200 && i < 1000) //Last three months { rustPurchasedItem.PurchaseDateTime = dateYearAgo.AddDays(rnd.Next(0, 330)); } purchasedItemsList.Add(rustPurchasedItem); var rustPurchaseStats = new RustPurchaseStats { Id = Guid.NewGuid(), AppUser = user, RustPurchasedItem = rustPurchasedItem, Shop = shop }; rustPurchaseStatsList.Add(rustPurchaseStats); } await _easyShopContext.RustPurchasedItems.AddRangeAsync(purchasedItemsList); await _easyShopContext.RustPurchaseStats.AddRangeAsync(rustPurchaseStatsList); await _easyShopContext.SaveChangesAsync(); }