private async Task PerformCommonCreateCampaignValidationsAsync(IGuildUser subject, GuildRoleBrief targetRankRole, IEnumerable <GuildRoleBrief> rankRoles) { if (await PromotionCampaignRepository.AnyAsync(new PromotionCampaignSearchCriteria() { GuildId = AuthorizationService.CurrentGuildId.Value, SubjectId = subject.Id, TargetRoleId = targetRankRole.Id, IsClosed = false })) { throw new InvalidOperationException($"An active campaign already exists for {subject.GetFullUsername()} to be promoted to {targetRankRole.Name}"); } // JoinedAt is null, when it cannot be obtained if (subject.JoinedAt.HasValue) { if (subject.JoinedAt.Value.DateTime > (DateTimeOffset.Now - TimeSpan.FromDays(20))) { throw new InvalidOperationException($"{subject.GetFullUsername()} has joined less than 20 days prior"); } } if (!await CheckIfUserIsRankOrHigherAsync(rankRoles, AuthorizationService.CurrentUserId.Value, targetRankRole.Id)) { throw new InvalidOperationException($"Creating a promotion campaign requires a rank at least as high as the proposed target rank"); } }
private async Task PerformCommonCreateCampaignValidationsAsync(IGuildUser subject, GuildRoleBrief targetRankRole, IEnumerable <GuildRoleBrief> rankRoles) { if (await PromotionCampaignRepository.AnyAsync(new PromotionCampaignSearchCriteria() { GuildId = AuthorizationService.CurrentGuildId.Value, SubjectId = subject.Id, TargetRoleId = targetRankRole.Id, IsClosed = false })) { throw new InvalidOperationException($"An active campaign already exists for {subject.GetDisplayNameWithDiscriminator()} to be promoted to {targetRankRole.Name}"); } if (!await CheckIfUserIsRankOrHigherAsync(rankRoles, AuthorizationService.CurrentUserId.Value, targetRankRole.Id)) { throw new InvalidOperationException($"Creating a promotion campaign requires a rank at least as high as the proposed target rank"); } }
/// <inheritdoc /> public async Task CreateCampaignAsync(ulong subjectId, ulong targetRoleId, string comment) { AuthorizationService.RequireAuthenticatedGuild(); AuthorizationService.RequireAuthenticatedUser(); AuthorizationService.RequireClaims(AuthorizationClaim.PromotionsCreateCampaign); using (var campaignTransaction = await PromotionCampaignRepository.BeginCreateTransactionAsync()) using (var commentTransaction = await PromotionCommentRepository.BeginCreateTransactionAsync()) { var rankRoles = await GetRankRolesAsync(AuthorizationService.CurrentGuildId.Value); var targetRankRoleIndex = rankRoles .Select((x, i) => (role: x, index: (int?)i)) .FirstOrDefault(x => x.role.Id == targetRoleId) .index; if (targetRankRoleIndex is null) throw new InvalidOperationException($"Role {targetRoleId} is not a defined promotion rank"); var targetRankRole = rankRoles[targetRankRoleIndex.Value]; if (await PromotionCampaignRepository.AnyAsync(new PromotionCampaignSearchCriteria() { GuildId = AuthorizationService.CurrentGuildId.Value, SubjectId = subjectId, TargetRoleId = targetRankRole.Id, IsClosed = false })) throw new InvalidOperationException($"An active campaign already exists for user {subjectId} to be promoted to {targetRoleId}"); var subject = await UserService.GetGuildUserAsync(AuthorizationService.CurrentGuildId.Value, subjectId); if (subject.RoleIds.Contains(targetRoleId)) throw new InvalidOperationException($"User {subjectId} is already a member of role {targetRoleId}"); if(targetRankRoleIndex > 0) { var previousRankRole = rankRoles[targetRankRoleIndex.Value - 1]; if (!subject.RoleIds.Contains(previousRankRole.Id)) throw new InvalidOperationException($"The proposed promotion would skip over rank {previousRankRole.Name}"); } else if (subject.RoleIds.Intersect(rankRoles.Select(x => x.Id)).Any()) throw new InvalidOperationException($"User {subjectId} is already ranked"); if(!(await CheckIfUserIsRankOrHigher(rankRoles, AuthorizationService.CurrentUserId.Value, targetRankRole.Id))) throw new InvalidOperationException($"Creating a promotion campaign requires a rank at least as high as the proposed target rank"); var campaignId = await PromotionCampaignRepository.CreateAsync(new PromotionCampaignCreationData() { GuildId = AuthorizationService.CurrentGuildId.Value, SubjectId = subjectId, TargetRoleId = targetRankRole.Id, CreatedById = AuthorizationService.CurrentUserId.Value }); await PromotionCommentRepository.CreateAsync(new PromotionCommentCreationData() { GuildId = AuthorizationService.CurrentGuildId.Value, CampaignId = campaignId, Sentiment = PromotionSentiment.Approve, Content = comment, CreatedById = AuthorizationService.CurrentUserId.Value }); campaignTransaction.Commit(); commentTransaction.Commit(); } }