public async Task <ClaimResult> EditPickupBid(PickupBid bid, PublisherGame?conditionalDropPublisherGame, uint bidAmount) { if (bid.Successful != null) { return(new ClaimResult(new List <ClaimError>() { new ClaimError("Bid has already been processed", false) }, null)); } if (bidAmount < bid.LeagueYear.Options.MinimumBidAmount) { return(new ClaimResult(new List <ClaimError>() { new ClaimError("That bid does not meet the league's minimum bid.", false) }, null)); } if (bidAmount > bid.Publisher.Budget) { return(new ClaimResult(new List <ClaimError>() { new ClaimError("You do not have enough budget to make that bid.", false) }, null)); } int?validDropSlot = null; if (conditionalDropPublisherGame is not null) { if (bid.CounterPick) { return(new ClaimResult("Cannot make a counter pick bid with a conditional drop.", null)); } var dropResult = await MakeDropRequest(bid.LeagueYear, bid.Publisher, conditionalDropPublisherGame, true); if (dropResult.Result.IsFailure) { return(new ClaimResult(dropResult.Result.Error, null)); } validDropSlot = conditionalDropPublisherGame.SlotNumber; } await _fantasyCriticRepo.EditPickupBid(bid, conditionalDropPublisherGame, bidAmount); var currentDate = _clock.GetToday(); MasterGameWithEligibilityFactors eligibilityFactors = bid.LeagueYear.GetEligibilityFactorsForMasterGame(bid.MasterGame, currentDate); var slotResult = SlotEligibilityService.GetPublisherSlotAcquisitionResult(bid.Publisher, bid.LeagueYear.Options, eligibilityFactors, bid.CounterPick, validDropSlot, false); if (!slotResult.SlotNumber.HasValue) { return(new ClaimResult(slotResult.ClaimErrors, null)); } return(new ClaimResult(slotResult.SlotNumber.Value)); }
public IReadOnlyList <ClaimError> GetClaimErrorsForSlot(LeagueYear leagueYear) { var eligibilityFactors = leagueYear.GetEligibilityFactorsForSlot(this); if (eligibilityFactors is null) { return(new List <ClaimError>()); } return(SlotEligibilityService.GetClaimErrorsForSlot(this, eligibilityFactors)); }
public async Task <IActionResult> SetGameEligibilityOverride([FromBody] EligibilityOverrideRequest request) { var leagueYearRecord = await GetExistingLeagueYear(request.LeagueID, request.Year, ActionProcessingModeBehavior.Ban, RequiredRelationship.LeagueManager, RequiredYearStatus.AnyYearNotFinished); if (leagueYearRecord.FailedResult is not null) { return(leagueYearRecord.FailedResult); } var validResult = leagueYearRecord.ValidResult !; var leagueYear = validResult.LeagueYear; MasterGame?masterGame = await _interLeagueService.GetMasterGame(request.MasterGameID); if (masterGame is null) { return(BadRequest()); } if (masterGame.ReleaseDate.HasValue && masterGame.ReleaseDate.Value.Year < leagueYear.Year) { return(BadRequest("You can't change the override setting of a game that came out in a previous year.")); } var currentDate = _clock.GetToday(); var eligibilityFactors = leagueYear.GetEligibilityFactorsForMasterGame(masterGame, currentDate); bool alreadyEligible = SlotEligibilityService.GameIsEligibleInLeagueYear(eligibilityFactors); bool isAllowing = request.Eligible.HasValue && request.Eligible.Value; bool isBanning = request.Eligible.HasValue && !request.Eligible.Value; if (isAllowing && alreadyEligible) { return(BadRequest("That game is already eligible in your league.")); } if (isBanning && !alreadyEligible) { return(BadRequest("That game is already ineligible in your league.")); } await _fantasyCriticService.SetEligibilityOverride(leagueYear, masterGame, request.Eligible); var refreshedLeagueYear = await _fantasyCriticService.GetLeagueYear(leagueYear.League.LeagueID, request.Year); if (refreshedLeagueYear is null) { return(BadRequest()); } await _fantasyCriticService.UpdatePublisherGameCalculatedStats(refreshedLeagueYear); return(Ok()); }
public static PossibleMasterGameYear GetPossibleMasterGameYear(MasterGameYear masterGame, IReadOnlyList <PublisherSlot> openNonCounterPickSlots, HashSet <MasterGame> publisherStandardMasterGames, HashSet <MasterGame> myPublisherMasterGames, MasterGameWithEligibilityFactors eligibilityFactors, LocalDate currentDate) { bool isEligible = SlotEligibilityService.GameIsEligibleInLeagueYear(eligibilityFactors); bool taken = publisherStandardMasterGames.Contains(masterGame.MasterGame); bool alreadyOwned = myPublisherMasterGames.Contains(masterGame.MasterGame); bool isReleased = masterGame.MasterGame.IsReleased(currentDate); bool willRelease = masterGame.WillRelease(); bool hasScore = masterGame.MasterGame.CriticScore.HasValue; bool isEligibleInOpenSlot = SlotEligibilityService.GameIsEligibleInOpenSlot(openNonCounterPickSlots, eligibilityFactors); PossibleMasterGameYear possibleMasterGame = new PossibleMasterGameYear(masterGame, taken, alreadyOwned, isEligible, isEligibleInOpenSlot, isReleased, willRelease, hasScore); return(possibleMasterGame); }
public PossibleMasterGameYear GetPossibleMasterGameYear(MasterGameYear masterGame, IReadOnlyList <PublisherSlot> openNonCounterPickSlots, HashSet <MasterGame> publisherStandardMasterGames, HashSet <MasterGame> myPublisherMasterGames, MasterGameWithEligibilityFactors eligibilityFactors, IEnumerable <LeagueTagStatus> tagsForSlot, LocalDate currentDate) { var tagsToUse = eligibilityFactors.TagOverrides.Any() ? eligibilityFactors.TagOverrides : masterGame.MasterGame.Tags; var claimErrors = LeagueTagExtensions.GameHasValidTags(tagsForSlot, new List <LeagueTagStatus>(), masterGame.MasterGame, tagsToUse, currentDate); bool isEligible = !claimErrors.Any(); bool taken = publisherStandardMasterGames.Contains(masterGame.MasterGame); bool alreadyOwned = myPublisherMasterGames.Contains(masterGame.MasterGame); bool isReleased = masterGame.MasterGame.IsReleased(currentDate); bool willRelease = masterGame.WillRelease(); bool hasScore = masterGame.MasterGame.CriticScore.HasValue; bool isEligibleInOpenSlot = SlotEligibilityService.GameIsEligibleInOpenSlot(openNonCounterPickSlots, eligibilityFactors); PossibleMasterGameYear possibleMasterGame = new PossibleMasterGameYear(masterGame, taken, alreadyOwned, isEligible, isEligibleInOpenSlot, isReleased, willRelease, hasScore); return(possibleMasterGame); }
private async Task <(int StandardGamesAdded, int CounterPicksAdded)> AutoDraftForLeague(LeagueYear leagueYear, int standardGamesAdded, int counterPicksAdded) { var today = _clock.GetToday(); var updatedLeagueYear = await _fantasyCriticRepo.GetLeagueYear(leagueYear.League, leagueYear.Year); var nextPublisher = GetNextDraftPublisher(updatedLeagueYear); if (nextPublisher is null) { return(standardGamesAdded, counterPicksAdded); } if (!nextPublisher.AutoDraft) { return(standardGamesAdded, counterPicksAdded); } var draftPhase = GetDraftPhase(updatedLeagueYear); var draftStatus = GetDraftStatus(draftPhase, updatedLeagueYear); if (draftPhase.Equals(DraftPhase.Complete)) { return(standardGamesAdded, counterPicksAdded); } if (draftPhase.Equals(DraftPhase.StandardGames)) { var publisherWatchList = await _publisherService.GetQueuedGames(nextPublisher); var availableGames = await _gameSearchingService.GetTopAvailableGames(updatedLeagueYear, nextPublisher); var availableGamesEligibleInRemainingSlots = new List <PossibleMasterGameYear>(); var openSlots = nextPublisher.GetPublisherSlots(updatedLeagueYear.Options).Where(x => !x.CounterPick && x.PublisherGame is null).ToList(); foreach (var availableGame in availableGames) { foreach (var slot in openSlots) { var eligibilityFactors = updatedLeagueYear.GetEligibilityFactorsForMasterGame(availableGame.MasterGame.MasterGame, today); var claimErrors = SlotEligibilityService.GetClaimErrorsForSlot(slot, eligibilityFactors); if (!claimErrors.Any()) { availableGamesEligibleInRemainingSlots.Add(availableGame); break; } } } var gamesToTake = publisherWatchList.OrderBy(x => x.Rank).Select(x => x.MasterGame) .Concat(availableGamesEligibleInRemainingSlots.Select(x => x.MasterGame.MasterGame)); foreach (var possibleGame in gamesToTake) { var request = new ClaimGameDomainRequest(updatedLeagueYear, nextPublisher, possibleGame.GameName, false, false, false, true, possibleGame, draftStatus.DraftPosition, draftStatus.OverallDraftPosition); var autoDraftResult = await _gameAcquisitionService.ClaimGame(request, false, true, true); if (autoDraftResult.Success) { standardGamesAdded++; break; } } } else if (draftPhase.Equals(DraftPhase.CounterPicks)) { var otherPublisherGames = updatedLeagueYear.GetAllPublishersExcept(nextPublisher) .SelectMany(x => x.PublisherGames) .Where(x => !x.CounterPick) .Where(x => x.MasterGame is not null); var possibleGames = otherPublisherGames .Select(x => x.MasterGame !) .Where(x => x.AdjustedPercentCounterPick.HasValue) .OrderByDescending(x => x.AdjustedPercentCounterPick); foreach (var possibleGame in possibleGames) { var request = new ClaimGameDomainRequest(updatedLeagueYear, nextPublisher, possibleGame.MasterGame.GameName, true, false, false, true, possibleGame.MasterGame, draftStatus.DraftPosition, draftStatus.OverallDraftPosition); var autoDraftResult = await _gameAcquisitionService.ClaimGame(request, false, true, true); if (autoDraftResult.Success) { counterPicksAdded++; break; } } } else { return(standardGamesAdded, counterPicksAdded); } return(await AutoDraftForLeague(updatedLeagueYear, standardGamesAdded, counterPicksAdded)); }
public bool GameIsEligibleInAnySlot(MasterGame masterGame, LocalDate dateOfPotentialAcquisition) { var eligibilityFactors = GetEligibilityFactorsForMasterGame(masterGame, dateOfPotentialAcquisition); return(SlotEligibilityService.GameIsEligibleInLeagueYear(eligibilityFactors)); }
public ClaimResult CanClaimGame(ClaimGameDomainRequest request, Instant?nextBidTime, int?validDropSlot, bool acquiringNow, bool drafting) { var currentDate = _clock.GetToday(); var dateOfPotentialAcquisition = currentDate; if (nextBidTime.HasValue) { dateOfPotentialAcquisition = nextBidTime.Value.ToEasternDate(); } var leagueYear = request.LeagueYear; List <ClaimError> claimErrors = new List <ClaimError>(); var basicErrors = GetBasicErrors(leagueYear.League, request.Publisher); claimErrors.AddRange(basicErrors); if (request.MasterGame is not null) { var masterGameErrors = GetGenericSlotMasterGameErrors(leagueYear, request.MasterGame, leagueYear.Year, false, currentDate, dateOfPotentialAcquisition, request.CounterPick, request.CounterPickedGameIsManualWillNotRelease, drafting); claimErrors.AddRange(masterGameErrors); } LeaguePublisherGameSet gameSet = new LeaguePublisherGameSet(request.Publisher.PublisherID, leagueYear.Publishers); bool thisPlayerAlreadyHas = gameSet.ThisPlayerStandardGames.ContainsGame(request); bool gameAlreadyClaimed = gameSet.OtherPlayerStandardGames.ContainsGame(request); if (!request.CounterPick) { if (gameAlreadyClaimed) { claimErrors.Add(new ClaimError("Cannot claim a game that someone already has.", false)); } if (thisPlayerAlreadyHas) { claimErrors.Add(new ClaimError("Cannot claim a game that you already have.", false)); } } if (request.CounterPick) { bool otherPlayerHasCounterPick = gameSet.OtherPlayerCounterPicks.ContainsGame(request); if (otherPlayerHasCounterPick) { claimErrors.Add(new ClaimError("Cannot counter-pick a game that someone else has already counter picked.", false)); } bool thisPlayerHasCounterPick = gameSet.ThisPlayerCounterPicks.ContainsGame(request); if (thisPlayerHasCounterPick) { claimErrors.Add(new ClaimError("You already have that counter pick.", false)); } bool otherPlayerHasDraftGame = gameSet.OtherPlayerStandardGames.ContainsGame(request); if (!otherPlayerHasDraftGame) { claimErrors.Add(new ClaimError("Cannot counter pick a game that no other player is publishing.", false)); } } MasterGameWithEligibilityFactors?eligibilityFactors = null; if (request.MasterGame is not null) { eligibilityFactors = leagueYear.GetEligibilityFactorsForMasterGame(request.MasterGame, dateOfPotentialAcquisition); } var slotResult = SlotEligibilityService.GetPublisherSlotAcquisitionResult(request.Publisher, leagueYear.Options, eligibilityFactors, request.CounterPick, validDropSlot, acquiringNow); if (!slotResult.SlotNumber.HasValue) { claimErrors.AddRange(slotResult.ClaimErrors); return(new ClaimResult(claimErrors, null)); } var result = new ClaimResult(claimErrors, slotResult.SlotNumber.Value); if (result.Overridable && request.ManagerOverride) { return(new ClaimResult(slotResult.SlotNumber.Value)); } return(result); }
public Result <IReadOnlyList <PublisherGame> > GetNewPublisherGamesFromTrade(Instant completionTime) { var dateOfAcquisition = completionTime.ToEasternDate(); var proposerGameDictionary = Proposer.PublisherGames.Where(x => x.MasterGame is not null).ToDictionary(x => x.GetMasterGameYearWithCounterPick() !); var counterPartyGameDictionary = CounterParty.PublisherGames.Where(x => x.MasterGame is not null).ToDictionary(x => x.GetMasterGameYearWithCounterPick() !); List <PotentialPublisherSlot> newlyOpenProposerSlotNumbers = new List <PotentialPublisherSlot>(); foreach (var game in ProposerMasterGames) { var existingPublisherGame = proposerGameDictionary[game]; newlyOpenProposerSlotNumbers.Add(new PotentialPublisherSlot(existingPublisherGame.SlotNumber, game.CounterPick)); } List <PotentialPublisherSlot> newlyOpenCounterPartySlotNumbers = new List <PotentialPublisherSlot>(); foreach (var game in CounterPartyMasterGames) { var existingPublisherGame = counterPartyGameDictionary[game]; newlyOpenCounterPartySlotNumbers.Add(new PotentialPublisherSlot(existingPublisherGame.SlotNumber, game.CounterPick)); } var alreadyOpenProposerSlotNumbers = Proposer.GetPublisherSlots(LeagueYear.Options).Where(x => x.PublisherGame is null).Select(x => new PotentialPublisherSlot(x.SlotNumber, x.CounterPick)); var alreadyOpenCounterPartySlotNumbers = CounterParty.GetPublisherSlots(LeagueYear.Options).Where(x => x.PublisherGame is null).Select(x => new PotentialPublisherSlot(x.SlotNumber, x.CounterPick)); var allOpenProposerSlotNumbers = alreadyOpenProposerSlotNumbers.Concat(newlyOpenProposerSlotNumbers).Distinct().OrderBy(x => x.CounterPick).ThenBy(x => x.SlotNumber).ToList(); var allOpenCounterPartySlotNumbers = alreadyOpenCounterPartySlotNumbers.Concat(newlyOpenCounterPartySlotNumbers).Distinct().OrderBy(x => x.CounterPick).ThenBy(x => x.SlotNumber).ToList(); List <PublisherGame> newPublisherGames = new List <PublisherGame>(); foreach (var game in ProposerMasterGames) { var existingPublisherGame = proposerGameDictionary[game]; var eligibilityFactors = LeagueYear.GetEligibilityFactorsForMasterGame(game.MasterGameYear.MasterGame, dateOfAcquisition); var openSlotNumbers = allOpenCounterPartySlotNumbers.Where(x => x.CounterPick == game.CounterPick).Select(x => x.SlotNumber); var slotResult = SlotEligibilityService.GetTradeSlotResult(CounterParty, LeagueYear.Options, game, eligibilityFactors, openSlotNumbers); if (!slotResult.HasValue) { return(Result.Failure <IReadOnlyList <PublisherGame> >($"Cannot find an appropriate slot for: {game.MasterGameYear.MasterGame.GameName}")); } allOpenCounterPartySlotNumbers = allOpenCounterPartySlotNumbers.Where(x => !(x.SlotNumber == slotResult.Value && x.CounterPick == game.CounterPick)).ToList(); PublisherGame newPublisherGame = new PublisherGame(CounterParty.PublisherID, Guid.NewGuid(), game.MasterGameYear.MasterGame.GameName, completionTime, game.CounterPick, existingPublisherGame.ManualCriticScore, existingPublisherGame.ManualWillNotRelease, existingPublisherGame.FantasyPoints, game.MasterGameYear, slotResult.Value, null, null, null, TradeID); newPublisherGames.Add(newPublisherGame); } foreach (var game in CounterPartyMasterGames) { var existingPublisherGame = counterPartyGameDictionary[game]; var eligibilityFactors = LeagueYear.GetEligibilityFactorsForMasterGame(game.MasterGameYear.MasterGame, dateOfAcquisition); var openSlotNumbers = allOpenProposerSlotNumbers.Where(x => x.CounterPick == game.CounterPick).Select(x => x.SlotNumber); var slotResult = SlotEligibilityService.GetTradeSlotResult(Proposer, LeagueYear.Options, game, eligibilityFactors, openSlotNumbers); if (!slotResult.HasValue) { return(Result.Failure <IReadOnlyList <PublisherGame> >($"Cannot find an appropriate slot for: {game.MasterGameYear.MasterGame.GameName}")); } allOpenProposerSlotNumbers = allOpenProposerSlotNumbers.Where(x => !(x.SlotNumber == slotResult.Value && x.CounterPick == game.CounterPick)).ToList(); PublisherGame newPublisherGame = new PublisherGame(Proposer.PublisherID, Guid.NewGuid(), game.MasterGameYear.MasterGame.GameName, completionTime, game.CounterPick, existingPublisherGame.ManualCriticScore, existingPublisherGame.ManualWillNotRelease, existingPublisherGame.FantasyPoints, game.MasterGameYear, slotResult.Value, null, null, null, TradeID); newPublisherGames.Add(newPublisherGame); } return(newPublisherGames); }