Пример #1
0
        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");
            }
        }
Пример #2
0
        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");
            }
        }
Пример #3
0
        /// <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();
            }
        }