public async Task <ActionResult <MultiTimestampDto> > RejectAll(long characterId, long teamId, [FromBody] ApproveOrRejectAllListsDto dto) { var character = await _context.Characters.FindAsync(characterId); if (character is null) { return(NotFound()); } var team = await _context.RaidTeams.FindAsync(teamId); if (team is null) { return(NotFound()); } if (!await AuthorizeTeamAsync(team, AppPolicies.RaidLeaderOrAdmin)) { return(Unauthorized()); } if (character.TeamId.HasValue) { return(Problem("This action is only available for characters not on a raid team.")); } if (character.Deactivated) { return(Problem("Character has been deactivated.")); } var currentPhases = await GetCurrentPhasesAsync(); var lootLists = await _context.CharacterLootLists.AsTracking() .Where(ll => ll.CharacterId == characterId && currentPhases.Contains(ll.Phase)) .ToListAsync(); if (!ValidateAllTimestamps(lootLists, dto.Timestamps, out byte invalidPhase)) { return(Problem($"The loot list for phase {invalidPhase} has been changed. Refresh before trying again.")); } var submissions = await _context.LootListTeamSubmissions .AsTracking() .Where(s => s.LootListCharacterId == characterId) .ToListAsync(); if (submissions.Find(s => s.TeamId == teamId) is null) { return(Unauthorized()); } _context.LootListTeamSubmissions.RemoveRange(submissions.Where(s => s.TeamId == teamId)); foreach (var list in lootLists) { if (!submissions.Any(s => s.TeamId != teamId && s.LootListPhase == list.Phase)) { if (list.Status != LootListStatus.Locked) { list.Status = LootListStatus.Editing; } list.ApprovedBy = null; } } await _context.SaveChangesAsync(); TrackListStatusChange(lootLists); await NotifyOwnerAsync(character, team, approved : false, dto.Message); return(new MultiTimestampDto { Timestamps = lootLists.ToDictionary(ll => ll.Phase, ll => ll.Timestamp) }); }
public async Task <ActionResult <ApproveAllListsResponseDto> > ApproveAll(long characterId, long teamId, [FromBody] ApproveOrRejectAllListsDto dto) { var character = await _context.Characters.FindAsync(characterId); if (character is null) { return(NotFound()); } var team = await _context.RaidTeams.FindAsync(teamId); if (team is null) { return(NotFound()); } if (!await AuthorizeTeamAsync(team, AppPolicies.RaidLeaderOrAdmin)) { return(Unauthorized()); } if (character.TeamId.HasValue) { return(Problem("This action is only available for characters not on a raid team.")); } if (character.Deactivated) { return(Problem("Character has been deactivated.")); } var submittedPhases = dto.Timestamps.Keys.ToHashSet(); var currentPhases = await GetCurrentPhasesAsync(); var lootLists = await _context.CharacterLootLists.AsTracking() .Where(ll => ll.CharacterId == characterId && currentPhases.Contains(ll.Phase)) .ToListAsync(); if (lootLists.Count != currentPhases.Count) { return(Problem("Character does not have a loot list for all current phases.")); } if (!submittedPhases.SetEquals(currentPhases)) { return(Problem("Request is missing one or more loot list timestamps.")); } if (!ValidateAllTimestamps(lootLists, dto.Timestamps, out byte invalidPhase)) { return(Problem($"The loot list for phase {invalidPhase} has been changed. Refresh before trying again.")); } if (character.OwnerId > 0) { var existingCharacterName = await _context.Characters .AsNoTracking() .Where(c => c.OwnerId == character.OwnerId && c.TeamId == team.Id) .Select(c => c.Name) .FirstOrDefaultAsync(); if (existingCharacterName?.Length > 0) { return(Problem($"The owner of this character is already on this team as {existingCharacterName}.")); } } var submissions = await _context.LootListTeamSubmissions .AsTracking() .Where(s => s.LootListCharacterId == characterId) .ToListAsync(); if (submissions.Find(s => s.TeamId == teamId) is null) { return(Unauthorized()); } _context.LootListTeamSubmissions.RemoveRange(submissions); character.TeamId = teamId; character.MemberStatus = RaidMemberStatus.FullTrial; character.JoinedTeamAt = _serverTimeZoneInfo.TimeZoneNow(); foreach (var list in lootLists) { list.ApprovedBy = User.GetDiscordId(); if (list.Status != LootListStatus.Locked) { list.Status = LootListStatus.Approved; } } await _context.SaveChangesAsync(); TrackListStatusChange(lootLists); await NotifyOwnerAsync(character, team, approved : true, dto.Message); return(new ApproveAllListsResponseDto { Timestamps = lootLists.ToDictionary(ll => ll.Phase, ll => ll.Timestamp), Member = await TryGetMemberDtoAsync(character, team) }); }