Пример #1
0
        public async Task UpdateMeaningOfSignaturesAsync(int reviewId, IEnumerable <MeaningOfSignatureParameter> meaningOfSignatureParameters, int userId)
        {
            var reviewInfo = await GetReviewInfoAsync(reviewId, userId);

            if (!await _permissionsRepository.HasEditPermissions(reviewId, userId))
            {
                throw ReviewsExceptionHelper.UserCannotModifyReviewException(reviewId);
            }

            var reviewData = await _reviewsRepository.GetReviewAsync(reviewId, userId);

            if (reviewData.ReviewStatus == ReviewPackageStatus.Closed)
            {
                throw ReviewsExceptionHelper.ReviewClosedException();
            }

            if (!reviewData.ReviewPackageRawData.IsMoSEnabled)
            {
                throw new ConflictException("Could not update review because meaning of signature is not enabled.", ErrorCodes.MeaningOfSignatureNotEnabled);
            }

            await LockReviewAsync(reviewId, userId, reviewInfo);

            await UpdateMeaningOfSignaturesInternalAsync(reviewId, userId, reviewData.ReviewPackageRawData, meaningOfSignatureParameters, new MeaningOfSignatureUpdateSpecificStrategy());

            await _reviewsRepository.UpdateReviewPackageRawDataAsync(reviewId, reviewData.ReviewPackageRawData, userId);
        }
Пример #2
0
        public async Task <ReviewSettings> UpdateReviewSettingsAsync(int reviewId, ReviewSettings updatedReviewSettings, bool autoSave, int userId)
        {
            var reviewInfo = await GetReviewInfoAsync(reviewId, userId);

            if (!await _permissionsRepository.HasEditPermissions(reviewId, userId))
            {
                throw ReviewsExceptionHelper.UserCannotModifyReviewException(reviewId);
            }

            var reviewData = await _reviewsRepository.GetReviewAsync(reviewId, userId);

            if (reviewData.ReviewStatus == ReviewPackageStatus.Closed)
            {
                throw new ConflictException(I18NHelper.FormatInvariant(ErrorMessages.ReviewIsClosed, reviewId), ErrorCodes.ReviewClosed);
            }

            await LockReviewAsync(reviewId, userId, reviewInfo);

            UpdateEndDate(updatedReviewSettings, autoSave, reviewData.ReviewPackageRawData);
            UpdateShowOnlyDescription(updatedReviewSettings, reviewData.ReviewPackageRawData);
            UpdateCanMarkAsComplete(reviewId, updatedReviewSettings, reviewData.ReviewPackageRawData);

            UpdateRequireESignature(reviewData.ReviewType, updatedReviewSettings, reviewData.ReviewPackageRawData);
            await UpdateRequireMeaningOfSignatureAsync(reviewInfo.ItemId, userId, reviewInfo.ProjectId, reviewData.ReviewType, updatedReviewSettings, reviewData.ReviewPackageRawData);

            await _reviewsRepository.UpdateReviewPackageRawDataAsync(reviewId, reviewData.ReviewPackageRawData, userId);

            return(await GetReviewSettingsFromReviewData(reviewData, reviewInfo));
        }
        public IEnumerable <MeaningOfSignatureUpdate> GetMeaningOfSignatureUpdates(int participantId,
                                                                                   Dictionary <int, List <ParticipantMeaningOfSignatureResult> > possibleMeaningOfSignatures,
                                                                                   IEnumerable <MeaningOfSignatureParameter> meaningOfSignatureParameters)
        {
            var updates = new List <MeaningOfSignatureUpdate>();

            foreach (var meaningOfSignatureParameter in meaningOfSignatureParameters.Where(mosp => mosp.ParticipantId == participantId))
            {
                if (!possibleMeaningOfSignatures.ContainsKey(participantId))
                {
                    throw ReviewsExceptionHelper.MeaningOfSignatureNotPossibleException();
                }

                var meaningOfSignature = possibleMeaningOfSignatures[participantId].FirstOrDefault(mos => mos.RoleId == meaningOfSignatureParameter.RoleId);

                if (meaningOfSignature == null)
                {
                    throw new ConflictException("Could not update meaning of signature because meaning of signature is not possible for a participant.", ErrorCodes.MeaningOfSignatureNotPossible);
                }

                updates.Add(new MeaningOfSignatureUpdate()
                {
                    Adding             = meaningOfSignatureParameter.Adding,
                    MeaningOfSignature = meaningOfSignature
                });
            }

            return(updates);
        }
Пример #4
0
        public async Task <ReviewSettings> GetReviewSettingsAsync(int reviewId, int userId, int?versionId = null)
        {
            var revisionId = await _itemInfoRepository.GetRevisionId(reviewId, userId, versionId);

            var reviewInfo = await GetReviewInfoAsync(reviewId, userId, revisionId);

            if (!await _permissionsRepository.HasReadPermissions(reviewId, userId, revisionId: revisionId))
            {
                throw ReviewsExceptionHelper.UserCannotAccessReviewException(reviewId);
            }

            var reviewData = await _reviewsRepository.GetReviewAsync(reviewId, userId, revisionId);

            return(await GetReviewSettingsFromReviewData(reviewData, reviewInfo));
        }
Пример #5
0
        private static void UpdateRequireESignature(ReviewType reviewType, ReviewSettings updatedReviewSettings, ReviewPackageRawData reviewRawData)
        {
            var settingChanged = (!reviewRawData.IsESignatureEnabled.HasValue && updatedReviewSettings.RequireESignature) ||
                                 (reviewRawData.IsESignatureEnabled.HasValue && reviewRawData.IsESignatureEnabled.Value != updatedReviewSettings.RequireESignature);

            if (!settingChanged)
            {
                return;
            }

            if (reviewType == ReviewType.Formal && reviewRawData.Status == ReviewPackageStatus.Active)
            {
                throw ReviewsExceptionHelper.ReviewActiveFormalException();
            }

            reviewRawData.IsESignatureEnabled = updatedReviewSettings.RequireESignature;
        }
Пример #6
0
        private async Task <ArtifactBasicDetails> GetReviewInfoAsync(int reviewId, int userId, int revisionId = int.MaxValue)
        {
            var artifactInfo = await _artifactRepository.GetArtifactBasicDetails(reviewId, userId);

            if (artifactInfo == null)
            {
                throw ReviewsExceptionHelper.ReviewNotFoundException(reviewId, revisionId);
            }

            if (revisionId == int.MaxValue && (artifactInfo.DraftDeleted || artifactInfo.LatestDeleted))
            {
                throw ReviewsExceptionHelper.ReviewNotFoundException(reviewId, revisionId);
            }

            if (artifactInfo.PrimitiveItemTypePredefined != (int)ItemTypePredefined.ArtifactReviewPackage)
            {
                throw new BadRequestException(I18NHelper.FormatInvariant(ErrorMessages.ArtifactIsNotReview, reviewId), ErrorCodes.BadRequest);
            }

            return(artifactInfo);
        }
Пример #7
0
        private async Task UpdateRequireMeaningOfSignatureAsync(int reviewId, int userId, int projectId, ReviewType reviewType, ReviewSettings updatedReviewSettings, ReviewPackageRawData reviewRawData)
        {
            var settingChanged = reviewRawData.IsMoSEnabled != updatedReviewSettings.RequireMeaningOfSignature;

            if (!settingChanged)
            {
                return;
            }

            if (reviewType == ReviewType.Formal && reviewRawData.Status == ReviewPackageStatus.Active)
            {
                throw ReviewsExceptionHelper.ReviewActiveFormalException();
            }

            if (updatedReviewSettings.RequireMeaningOfSignature && (!reviewRawData.IsESignatureEnabled.HasValue || !reviewRawData.IsESignatureEnabled.Value))
            {
                throw ReviewsExceptionHelper.RequireESignatureDisabledException(reviewId);
            }

            var projectPermissions = await _permissionsRepository.GetProjectPermissions(projectId);

            if (!projectPermissions.HasFlag(ProjectPermissions.IsMeaningOfSignatureEnabled))
            {
                throw ReviewsExceptionHelper.MeaningOfSignatureIsDisabledInProjectException();
            }

            reviewRawData.IsMoSEnabled = updatedReviewSettings.RequireMeaningOfSignature;

            if (reviewRawData.IsMoSEnabled && reviewRawData.Reviewers != null)
            {
                var meaningOfSignatureParameters = reviewRawData.Reviewers
                                                   .Where(r => r.Permission == ReviewParticipantRole.Approver)
                                                   .Select(r => new MeaningOfSignatureParameter {
                    ParticipantId = r.UserId
                });

                await UpdateMeaningOfSignaturesInternalAsync(reviewId, userId, reviewRawData, meaningOfSignatureParameters, new MeaningOfSignatureUpdateSetDefaultsStrategy());
            }
        }
Пример #8
0
        public async Task <ReviewChangeItemsStatusResult> AssignApprovalRequiredToArtifactsAsync(int reviewId, AssignArtifactsApprovalParameter content, int userId)
        {
            if ((content.ItemIds == null || !content.ItemIds.Any()) && content.SelectionType == SelectionType.Selected)
            {
                throw new BadRequestException("Incorrect input parameters", ErrorCodes.OutOfRangeParameter);
            }

            if (!await _permissionsRepository.HasEditPermissions(reviewId, userId))
            {
                throw ReviewsExceptionHelper.UserCannotModifyReviewException(reviewId);
            }

            var reviewInfo = await GetReviewInfoAsync(reviewId, userId);

            if (reviewInfo.LockedByUserId.GetValueOrDefault() != userId)
            {
                throw ExceptionHelper.ArtifactNotLockedException(reviewId, userId);
            }

            var review = await _reviewsRepository.GetReviewAsync(reviewId, userId);

            if (review.ReviewStatus == ReviewPackageStatus.Closed)
            {
                throw ReviewsExceptionHelper.ReviewClosedException();
            }

            if (review.Contents.Artifacts == null ||
                !review.Contents.Artifacts.Any())
            {
                throw ExceptionHelper.ArtifactDoesNotSupportOperation(reviewId);
            }

            // If review is active and formal we throw conflict exception. No changes allowed
            if (review.ReviewStatus == ReviewPackageStatus.Active &&
                review.ReviewType == ReviewType.Formal)
            {
                throw ReviewsExceptionHelper.ReviewActiveFormalException();
            }
            foreach (var artifact in review.Contents.Artifacts)
            {
                if (artifact.ApprovalNotRequested == null)
                {
                    artifact.ApprovalNotRequested = (review.BaselineId == null);
                }
            }
            var resultErrors = new List <ReviewChangeItemsError>();

            var updatingArtifacts = GetReviewArtifacts(content, resultErrors, review.Contents);

            if (updatingArtifacts.Any())
            {
                // For Informal review
                await ExcludeDeletedAndNotInProjectArtifacts(content, review, reviewInfo.ProjectId, resultErrors, updatingArtifacts);
                await ExcludeArtifactsWithoutReadPermissions(content, userId, resultErrors, updatingArtifacts);

                var reviewRawData = review.ReviewPackageRawData;
                if (review.ReviewStatus == ReviewPackageStatus.Active &&
                    updatingArtifacts.Any() &&
                    content.ApprovalRequired)
                {
                    var hasArtifactsRequireApproval = review.Contents.Artifacts.FirstOrDefault(a => a.ApprovalNotRequested == false) != null;
                    // if Review has already artifacts require approval before current action it means that it is already converted to formal
                    if (!hasArtifactsRequireApproval)
                    {
                        var approver =
                            reviewRawData.Reviewers?.FirstOrDefault(r => r.Permission == ReviewParticipantRole.Approver);
                        if (approver != null)
                        {
                            throw new ConflictException(
                                      "Could not update review artifacts because review needs to be converted to Formal.",
                                      ErrorCodes.ReviewNeedsToMoveBackToDraftState);
                        }
                    }
                }

                foreach (var updatingArtifact in updatingArtifacts)
                {
                    updatingArtifact.ApprovalNotRequested = !content.ApprovalRequired;
                }

                var resultArtifactsXml = ReviewRawDataHelper.GetStoreData(review.Contents);

                await _reviewsRepository.UpdateReviewArtifactsAsync(reviewId, userId, resultArtifactsXml, null, false);

                if (content.ApprovalRequired)
                {
                    await EnableRequireESignatureWhenProjectESignatureEnabledByDefaultAsync(reviewId, userId, reviewInfo.ProjectId, reviewRawData);
                }
            }

            var result = new ReviewChangeItemsStatusResult();

            result.ReviewType = await _reviewsRepository.GetReviewTypeAsync(reviewId, userId);

            if (resultErrors.Any())
            {
                result.ReviewChangeItemErrors = resultErrors;
            }

            return(result);
        }
Пример #9
0
        public async Task <ReviewChangeParticipantsStatusResult> AssignRoleToParticipantsAsync(int reviewId, AssignParticipantRoleParameter content, int userId)
        {
            if ((content.ItemIds == null || !content.ItemIds.Any()) && content.SelectionType == SelectionType.Selected)
            {
                throw new BadRequestException("Incorrect input parameters", ErrorCodes.OutOfRangeParameter);
            }

            if (!await _permissionsRepository.HasEditPermissions(reviewId, userId))
            {
                throw ReviewsExceptionHelper.UserCannotModifyReviewException(reviewId);
            }

            var reviewInfo = await GetReviewInfoAsync(reviewId, userId);

            if (reviewInfo.LockedByUserId.GetValueOrDefault() != userId)
            {
                throw ExceptionHelper.ArtifactNotLockedException(reviewId, userId);
            }

            var reviewData = await _reviewsRepository.GetReviewAsync(reviewId, userId);

            if (reviewData.ReviewStatus == ReviewPackageStatus.Closed)
            {
                const string errorMessage = "The approval status could not be updated because another user has changed the Review status.";
                throw new ConflictException(errorMessage, ErrorCodes.ApprovalRequiredIsReadonlyForReview);
            }

            if (reviewData.ReviewPackageRawData.Reviewers == null ||
                !reviewData.ReviewPackageRawData.Reviewers.Any())
            {
                throw ExceptionHelper.ArtifactDoesNotSupportOperation(reviewId);
            }

            if (reviewData.ReviewStatus == ReviewPackageStatus.Active)
            {
                if (content.Role == ReviewParticipantRole.Approver)
                {
                    var hasApproversAlready = reviewData.ReviewPackageRawData.Reviewers.FirstOrDefault(
                        r => r.Permission == ReviewParticipantRole.Approver) != null;
                    // If we have approvers before current action, it means that review already was converted to formal
                    if (!hasApproversAlready)
                    {
                        var artifactRequredApproval =
                            reviewData.Contents.Artifacts?.FirstOrDefault(a => !a.ApprovalNotRequested ?? true);
                        if (artifactRequredApproval != null)
                        {
                            throw new ConflictException(
                                      "Could not update review participants because review needs to be converted to Formal.",
                                      ErrorCodes.ReviewNeedsToMoveBackToDraftState);
                        }
                    }
                }
                else // If new role is reviewer
                {
                    ReviewsExceptionHelper.VerifyNotLastApproverInFormalReview(content, reviewData);
                }
            }

            var resultErrors = new List <ReviewChangeItemsError>();

            UpdateParticipantRole(reviewData.ReviewPackageRawData, content, resultErrors);

            await UpdateMeaningOfSignatureWhenAssignApprovalRoles(reviewId, userId, content, reviewData.ReviewPackageRawData);

            await _reviewsRepository.UpdateReviewPackageRawDataAsync(reviewId, reviewData.ReviewPackageRawData, userId);

            var changeResult = new ReviewChangeParticipantsStatusResult
            {
                ReviewType = await _reviewsRepository.GetReviewTypeAsync(reviewId, userId)
            };

            if (content.Role == ReviewParticipantRole.Approver)
            {
                await EnableRequireESignatureWhenProjectESignatureEnabledByDefaultAsync(reviewId, userId, reviewInfo.ProjectId, reviewData.ReviewPackageRawData);

                if (reviewData.ReviewPackageRawData.IsMoSEnabled && content.SelectionType == SelectionType.Selected && content.ItemIds.Count() == 1)
                {
                    changeResult.DropdownItems = reviewData.ReviewPackageRawData.Reviewers
                                                 .First(r => r.UserId == content.ItemIds.FirstOrDefault())
                                                 .SelectedRoleMoSAssignments.Select(mos => new DropdownItem(mos.GetMeaningOfSignatureDisplayValue(), mos.RoleId));
                }
            }

            if (resultErrors.Any())
            {
                changeResult.ReviewChangeItemErrors = resultErrors;
            }

            return(changeResult);
        }