public DeleteRequirementTypeCommandValidator(
            IRequirementTypeValidator requirementTypeValidator,
            IRowVersionValidator rowVersionValidator)
        {
            CascadeMode = CascadeMode.Stop;

            RuleFor(command => command)
            .MustAsync((command, token) => BeAnExistingRequirementTypeAsync(command.RequirementTypeId, token))
            .WithMessage(command => $"Requirement type doesn't exist! Requirement type={command.RequirementTypeId}")
            .MustAsync((command, token) => NotHaveAnyRequirementDefinitions(command.RequirementTypeId, token))
            .WithMessage(command => $"Requirement type has requirement definitions! Requirement type={command.RequirementTypeId}")
            .MustAsync((command, token) => BeAVoidedRequirementTypeAsync(command.RequirementTypeId, token))
            .WithMessage(command => $"Requirement type is not voided! Requirement type={command.RequirementTypeId}")
            .Must(command => HaveAValidRowVersion(command.RowVersion))
            .WithMessage(command => $"Not a valid row version! Row version={command.RowVersion}");

            async Task <bool> BeAnExistingRequirementTypeAsync(int requirementTypeId, CancellationToken token)
            => await requirementTypeValidator.ExistsAsync(requirementTypeId, token);
            async Task <bool> NotHaveAnyRequirementDefinitions(int requirementTypeId, CancellationToken token)
            => !await requirementTypeValidator.AnyRequirementDefinitionExistsAsync(requirementTypeId, token);
            async Task <bool> BeAVoidedRequirementTypeAsync(int requirementTypeId, CancellationToken token)
            => await requirementTypeValidator.IsVoidedAsync(requirementTypeId, token);

            bool HaveAValidRowVersion(string rowVersion)
            => rowVersionValidator.IsValid(rowVersion);
        }
        public UpdateActionCommandValidator(
            IProjectValidator projectValidator,
            ITagValidator tagValidator,
            IActionValidator actionValidator,
            IRowVersionValidator rowVersionValidator)
        {
            CascadeMode = CascadeMode.Stop;

            RuleFor(command => command)
            .MustAsync((command, token) => NotBeAClosedProjectForTagAsync(command.TagId, token))
            .WithMessage(command => $"Project for tag is closed! Tag={command.TagId}")
            .MustAsync((command, token) => NotBeAVoidedTagAsync(command.TagId, token))
            .WithMessage(command => $"Tag is voided! Tag={command.TagId}")
            .MustAsync(BeAnExistingActionAsync)
            .WithMessage(command => "Tag and/or action doesn't exist!")
            .MustAsync((command, token) => NotBeAClosedActionAsync(command.ActionId, token))
            .WithMessage(command => $"Action is closed! Action={command.ActionId}")
            .Must(command => HaveAValidRowVersion(command.RowVersion))
            .WithMessage(command => $"Not a valid row version! Row version={command.RowVersion}");

            async Task <bool> NotBeAClosedProjectForTagAsync(int tagId, CancellationToken token)
            => !await projectValidator.IsClosedForTagAsync(tagId, token);
            async Task <bool> NotBeAVoidedTagAsync(int tagId, CancellationToken token)
            => !await tagValidator.IsVoidedAsync(tagId, token);
            async Task <bool> BeAnExistingActionAsync(UpdateActionCommand command, CancellationToken token)
            => await tagValidator.ExistsActionAsync(command.TagId, command.ActionId, token);
            async Task <bool> NotBeAClosedActionAsync(int actionId, CancellationToken token)
            => !await actionValidator.IsClosedAsync(actionId, token);

            bool HaveAValidRowVersion(string rowVersion)
            => rowVersionValidator.IsValid(rowVersion);
        }
示例#3
0
        public DeleteModeCommandValidator(
            IModeValidator modeValidator,
            IRowVersionValidator rowVersionValidator)
        {
            CascadeMode = CascadeMode.Stop;

            RuleFor(command => command)
            .MustAsync((command, token) => BeAnExistingMode(command.ModeId, token))
            .WithMessage(command => $"Mode doesn't exist! Mode={command.ModeId}")
            .MustAsync((command, token) => BeAVoidedMode(command.ModeId, token))
            .WithMessage(command => $"Mode is not voided! Mode={command.ModeId}")
            .MustAsync((command, token) => NotBeUsedInAnyStep(command.ModeId, token))
            .WithMessage(command => $"Mode is used in step(s)! Mode={command.ModeId}")
            .Must(command => HaveAValidRowVersion(command.RowVersion))
            .WithMessage(command => $"Not a valid row version! Row version={command.RowVersion}");

            async Task <bool> BeAnExistingMode(int modeId, CancellationToken token)
            => await modeValidator.ExistsAsync(modeId, token);

            async Task <bool> BeAVoidedMode(int modeId, CancellationToken token)
            => await modeValidator.IsVoidedAsync(modeId, token);

            async Task <bool> NotBeUsedInAnyStep(int modeId, CancellationToken token)
            => !await modeValidator.IsUsedInStepAsync(modeId, token);

            bool HaveAValidRowVersion(string rowVersion)
            => rowVersionValidator.IsValid(rowVersion);
        }
示例#4
0
        public DeleteTagCommandValidator(
            ITagValidator tagValidator,
            IRowVersionValidator rowVersionValidator)
        {
            CascadeMode = CascadeMode.Stop;

            RuleFor(command => command)
            .MustAsync((command, token) => BeAnExistingTagAsync(command.TagId, token))
            .WithMessage(command => $"Tag doesn't exist! Tag={command.TagId}")
            .MustAsync((command, token) => BeAVoidedTagAsync(command.TagId, token))
            .WithMessage(command => $"Tag is not voided! Tag={command.TagId}")
            .MustAsync((command, token) => NotBeInUse(command.TagId, token))
            .WithMessage(command => $"Tag is in use! Tag={command.TagId}")
            .Must(command => HaveAValidRowVersion(command.RowVersion))
            .WithMessage(command => $"Not a valid row version! Row version={command.RowVersion}");

            async Task <bool> BeAnExistingTagAsync(int tagId, CancellationToken token)
            => await tagValidator.ExistsAsync(tagId, token);
            async Task <bool> BeAVoidedTagAsync(int tagId, CancellationToken token)
            => await tagValidator.IsVoidedAsync(tagId, token);
            async Task <bool> NotBeInUse(int tagId, CancellationToken token)
            => !await tagValidator.IsInUseAsync(tagId, token);

            bool HaveAValidRowVersion(string rowVersion)
            => rowVersionValidator.IsValid(rowVersion);
        }
示例#5
0
        public DeleteJourneyCommandValidator(
            IJourneyValidator journeyValidator,
            IRowVersionValidator rowVersionValidator)
        {
            CascadeMode = CascadeMode.Stop;

            RuleFor(command => command)
            .MustAsync((command, token) => BeAnExistingJourneyAsync(command.JourneyId, token))
            .WithMessage(command => $"Journey doesn't exist! Journey={command.JourneyId}")
            .MustAsync((command, token) => BeAVoidedJourneyAsync(command.JourneyId, token))
            .WithMessage(command => $"Journey is not voided! Journey={command.JourneyId}")
            .MustAsync((command, token) => NotBeUsedAsync(command.JourneyId, token))
            .WithMessage(command => $"Journey is used! Journey={command.JourneyId}")
            .Must(command => HaveAValidRowVersion(command.RowVersion))
            .WithMessage(command => $"Not a valid row version! Row version={command.RowVersion}");

            async Task <bool> BeAnExistingJourneyAsync(int journeyId, CancellationToken token)
            => await journeyValidator.ExistsAsync(journeyId, token);

            async Task <bool> BeAVoidedJourneyAsync(int journeyId, CancellationToken token)
            => await journeyValidator.IsVoidedAsync(journeyId, token);

            async Task <bool> NotBeUsedAsync(int journeyId, CancellationToken token)
            => !await journeyValidator.IsInUseAsync(journeyId, token);

            bool HaveAValidRowVersion(string rowVersion)
            => rowVersionValidator.IsValid(rowVersion);
        }
示例#6
0
        public UpdateJourneyCommandValidator(
            IJourneyValidator journeyValidator,
            IRowVersionValidator rowVersionValidator)
        {
            CascadeMode = CascadeMode.Stop;

            RuleFor(command => command)
            .MustAsync((command, token) => BeAnExistingJourneyAsync(command.JourneyId, token))
            .WithMessage(command => $"Journey doesn't exist! Journey={command.JourneyId}")
            .MustAsync((command, token) => HaveUniqueJourneyTitleAsync(command.JourneyId, command.Title, token))
            .WithMessage(command => $"Another journey with this title already exists! Journey={command.Title}")
            .MustAsync((command, token) => NotBeAVoidedJourneyAsync(command.JourneyId, token))
            .WithMessage(command => $"Journey is voided! Journey={command.JourneyId}")
            .Must(command => HaveAValidRowVersion(command.RowVersion))
            .WithMessage(command => $"Not a valid row version! Row version={command.RowVersion}");

            async Task <bool> BeAnExistingJourneyAsync(int journeyId, CancellationToken token)
            => await journeyValidator.ExistsAsync(journeyId, token);
            async Task <bool> HaveUniqueJourneyTitleAsync(int journeyId, string journeyTitle, CancellationToken token) =>
            !await journeyValidator.ExistsWithSameTitleInAnotherJourneyAsync(journeyId, journeyTitle, token);
            async Task <bool> NotBeAVoidedJourneyAsync(int journeyId, CancellationToken token)
            => !await journeyValidator.IsVoidedAsync(journeyId, token);

            bool HaveAValidRowVersion(string rowVersion)
            => rowVersionValidator.IsValid(rowVersion);
        }
示例#7
0
        public UpdateRequirementTypeCommandValidator(
            IRequirementTypeValidator requirementTypeValidator,
            IRowVersionValidator rowVersionValidator)
        {
            CascadeMode = CascadeMode.Stop;

            RuleFor(command => command)
            .MustAsync((command, token) => BeAnExistingRequirementTypeAsync(command.RequirementTypeId, token))
            .WithMessage(command => $"Requirement type doesn't exist! Requirement type={command.RequirementTypeId}")
            .MustAsync((command, token) => NotBeAVoidedRequirementTypeAsync(command.RequirementTypeId, token))
            .WithMessage(command => $"Requirement type is voided! Requirement type={command.RequirementTypeId}")
            .MustAsync((command, token) => BeAUniqueCodeAsync(command.RequirementTypeId, command.Code, token))
            .WithMessage(command => $"Another requirement type with this code already exists! Code={command.Code}")
            .MustAsync((command, token) => BeAUniqueTitleAsync(command.RequirementTypeId, command.Title, token))
            .WithMessage(command => $"Another requirement type with this title already exists! Title={command.Title}")
            .Must(command => HaveAValidRowVersion(command.RowVersion))
            .WithMessage(command => $"Not a valid row version! Row version={command.RowVersion}");

            async Task <bool> BeAnExistingRequirementTypeAsync(int requirementTypeId, CancellationToken token)
            => await requirementTypeValidator.ExistsAsync(requirementTypeId, token);
            async Task <bool> NotBeAVoidedRequirementTypeAsync(int requirementTypeId, CancellationToken token)
            => !await requirementTypeValidator.IsVoidedAsync(requirementTypeId, token);
            async Task <bool> BeAUniqueCodeAsync(int requirementTypeId, string code, CancellationToken token)
            => !await requirementTypeValidator.ExistsWithSameCodeInAnotherTypeAsync(requirementTypeId, code, token);
            async Task <bool> BeAUniqueTitleAsync(int requirementTypeId, string title, CancellationToken token)
            => !await requirementTypeValidator.ExistsWithSameTitleInAnotherTypeAsync(requirementTypeId, title, token);

            bool HaveAValidRowVersion(string rowVersion)
            => rowVersionValidator.IsValid(rowVersion);
        }
        public SwapStepsCommandValidator(
            IJourneyValidator journeyValidator,
            IStepValidator stepValidator,
            IRowVersionValidator rowVersionValidator)
        {
            CascadeMode = CascadeMode.Stop;

            RuleFor(command => command)
            .MustAsync((command, token) => BeAnExistingStepAsync(command.JourneyId, command.StepAId, token))
            .WithMessage(_ => "Journey and/or step doesn't exist!")
            .MustAsync((command, token) => BeAnExistingStepAsync(command.JourneyId, command.StepBId, token))
            .WithMessage(_ => "Journey and/or step doesn't exist!")
            .MustAsync((command, token) => BeAdjacentStepsInAJourneyAsync(command.JourneyId, command.StepAId, command.StepBId, token))
            .WithMessage(command => $"Steps are not adjacent! Steps={command.StepAId} and {command.StepBId}")
            .Must(command => HaveAValidRowVersion(command.StepARowVersion))
            .WithMessage(command => $"Not a valid row version! Row version{command.StepARowVersion}")
            .Must(command => HaveAValidRowVersion(command.StepBRowVersion))
            .WithMessage(command => $"Not a valid row version! Row version={command.StepBRowVersion}");

            async Task <bool> BeAnExistingStepAsync(int journeyId, int stepId, CancellationToken token)
            => await journeyValidator.ExistsStepAsync(journeyId, stepId, token);

            async Task <bool> BeAdjacentStepsInAJourneyAsync(int journeyId, int stepAId, int stepBId, CancellationToken token)
            => await journeyValidator.AreAdjacentStepsInAJourneyAsync(journeyId, stepAId, stepBId, token);

            bool HaveAValidRowVersion(string rowVersion)
            => rowVersionValidator.IsValid(rowVersion);
        }
        public DeleteRequirementDefinitionCommandValidator(
            IRequirementTypeValidator requirementTypeValidator,
            IRequirementDefinitionValidator requirementDefinitionValidator,
            IRowVersionValidator rowVersionValidator)
        {
            CascadeMode = CascadeMode.Stop;

            RuleFor(command => command)
            .MustAsync(BeAnExistingRequirementDefinitionAsync)
            .WithMessage(command => "Requirement type and/or requirement definition doesn't exist!")
            .MustAsync((command, token) => BeAVoidedRequirementDefinitionAsync(command.RequirementDefinitionId, token))
            .WithMessage(command => $"Requirement definition is not voided! Requirement definition={command.RequirementDefinitionId}")
            .MustAsync((command, token) => NotHaveAnyFieldsAsync(command.RequirementDefinitionId, token))
            .WithMessage(command => $"Requirement definition has fields! Requirement definition={command.RequirementDefinitionId}")
            .MustAsync((command, token) => NotHaveAnyTagRequirementsAsync(command.RequirementDefinitionId, token))
            .WithMessage(command => $"Tag requirement with this requirement definition exists! Requirement definition={command.RequirementDefinitionId}")
            .MustAsync((command, token) => NotHaveAnyTagFunctionRequirementsAsync(command.RequirementDefinitionId, token))
            .WithMessage(command => $"Tag function requirement with this requirement definition exists! Requirement definition={command.RequirementDefinitionId}")
            .Must(command => HaveAValidRowVersion(command.RowVersion))
            .WithMessage(command => $"Not a valid row version! Row version={command.RowVersion}");

            async Task <bool> BeAnExistingRequirementDefinitionAsync(DeleteRequirementDefinitionCommand command, CancellationToken token)
            => await requirementTypeValidator.RequirementDefinitionExistsAsync(command.RequirementTypeId, command.RequirementDefinitionId, token);
            async Task <bool> BeAVoidedRequirementDefinitionAsync(int requirementDefinitionId, CancellationToken token)
            => await requirementDefinitionValidator.IsVoidedAsync(requirementDefinitionId, token);
            async Task <bool> NotHaveAnyFieldsAsync(int requirementDefinitionId, CancellationToken token)
            => !await requirementDefinitionValidator.HasAnyFieldsAsync(requirementDefinitionId, token);
            async Task <bool> NotHaveAnyTagRequirementsAsync(int requirementDefinitionId, CancellationToken token)
            => !await requirementDefinitionValidator.TagRequirementsExistAsync(requirementDefinitionId, token);
            async Task <bool> NotHaveAnyTagFunctionRequirementsAsync(int requirementDefinitionId, CancellationToken token)
            => !await requirementDefinitionValidator.TagFunctionRequirementsExistAsync(requirementDefinitionId, token);

            bool HaveAValidRowVersion(string rowVersion)
            => rowVersionValidator.IsValid(rowVersion);
        }
示例#10
0
        public DeleteStepCommandValidator(
            IJourneyValidator journeyValidator,
            IStepValidator stepValidator,
            IRowVersionValidator rowVersionValidator)
        {
            CascadeMode = CascadeMode.Stop;

            RuleFor(command => command)
            .MustAsync((command, token) => BeAnExistingStepAsync(command.JourneyId, command.StepId, token))
            .WithMessage(command => "Journey and/or step doesn't exist!")
            .MustAsync((command, token) => BeAVoidedStepAsync(command.StepId, token))
            .WithMessage(command => $"Step is not voided! Step={command.StepId}")
            .MustAsync((command, token) => JourneyForStepNotBeUsedAsync(command.JourneyId, token))
            .WithMessage(command => $"No steps can be deleted from journey when preservation tags exists in journey! Journey={command.JourneyId}")
            .Must(command => HaveAValidRowVersion(command.RowVersion))
            .WithMessage(command => $"Not a valid row version! Row version={command.RowVersion}");

            async Task <bool> BeAnExistingStepAsync(int journeyId, int stepId, CancellationToken token)
            => await journeyValidator.ExistsStepAsync(journeyId, stepId, token);

            async Task <bool> BeAVoidedStepAsync(int stepId, CancellationToken token)
            => await stepValidator.IsVoidedAsync(stepId, token);

            async Task <bool> JourneyForStepNotBeUsedAsync(int journeyId, CancellationToken token)
            => !await journeyValidator.IsAnyStepInJourneyInUseAsync(journeyId, token);

            bool HaveAValidRowVersion(string rowVersion)
            => rowVersionValidator.IsValid(rowVersion);
        }
        public DeletePunchOutCommandValidator(
            IInvitationValidator invitationValidator,
            IRowVersionValidator rowVersionValidator)
        {
            CascadeMode = CascadeMode.Stop;

            RuleFor(command => command)
            .MustAsync((command, cancellationToken) => BeAnExistingInvitation(command.InvitationId, cancellationToken))
            .WithMessage(command =>
                         $"Invitation with this ID does not exist! Id={command.InvitationId}")
            .MustAsync((command, cancellationToken) => InvitationIsCanceled(command.InvitationId, cancellationToken))
            .WithMessage(command =>
                         $"IPO is not canceled! Id={command.InvitationId}")
            .MustAsync((command, cancellationToken) => CurrentUserIsCreatorOrOfInvitationOrAdmin(command.InvitationId, cancellationToken))
            .WithMessage(command =>
                         $"Current user is not the creator of the invitation and not ipo admin! Id={command.InvitationId}")
            .Must(command => HaveAValidRowVersion(command.RowVersion))
            .WithMessage(command =>
                         $"Invitation does not have valid rowVersion! RowVersion={command.RowVersion}");

            async Task <bool> BeAnExistingInvitation(int invitationId, CancellationToken cancellationToken)
            => await invitationValidator.IpoExistsAsync(invitationId, cancellationToken);

            async Task <bool> CurrentUserIsCreatorOrOfInvitationOrAdmin(int invitationId, CancellationToken cancellationToken)
            => await invitationValidator.CurrentUserIsAllowedToDeleteIpoAsync(invitationId, cancellationToken);

            async Task <bool> InvitationIsCanceled(int invitationId, CancellationToken cancellationToken)
            => await invitationValidator.IpoIsInStageAsync(invitationId, IpoStatus.Canceled, cancellationToken);

            bool HaveAValidRowVersion(string rowVersion)
            => rowVersionValidator.IsValid(rowVersion);
        }
示例#12
0
        public RescheduleCommandValidator(
            IProjectValidator projectValidator,
            ITagValidator tagValidator,
            IRowVersionValidator rowVersionValidator)
        {
            CascadeMode = CascadeMode.Stop;

            RuleFor(command => command.Tags)
            .Must(ids => ids != null && ids.Any())
            .WithMessage("At least 1 tag must be given!")
            .Must(BeUniqueTags)
            .WithMessage("Tags must be unique!")
            .MustAsync(BeInSameProjectAsync)
            .WithMessage("Tags must be in same project!")
            .MustAsync(NotBeAClosedProjectForTagAsync)
            .WithMessage("Project is closed!");

            RuleFor(command => command.Weeks)
            .InclusiveBetween(1, MaxRescheduleWeeks)
            .WithMessage($"Rescheduling must be in range of 1 to {MaxRescheduleWeeks} week(s)!");

            When(command => command.Tags.Any() && BeUniqueTags(command.Tags), () =>
            {
                RuleForEach(command => command.Tags)
                .MustAsync((_, tag, __, token) => BeAnExistingTagAsync(tag.Id, token))
                .WithMessage((_, tag) => $"Tag doesn't exist! Tag={tag.Id}")
                .MustAsync((_, tag, __, token) => NotBeAVoidedTagAsync(tag.Id, token))
                .WithMessage((_, tag) => $"Tag is voided! Tag={tag.Id}")
                .MustAsync((_, tag, __, token) => IsReadyToBeRescheduledAsync(tag.Id, token))
                .WithMessage((_, tag) => $"Tag can not be rescheduled! Tag={tag.Id}")
                .Must(tag => HaveAValidRowVersion(tag.RowVersion))
                .WithMessage((_, tag) => $"Not a valid row version! Row version={tag.RowVersion}");
            });

            bool BeUniqueTags(IEnumerable <IdAndRowVersion> tags)
            {
                var ids = tags.Select(x => x.Id).ToList();

                return(ids.Distinct().Count() == ids.Count);
            }

            async Task <bool> BeInSameProjectAsync(IEnumerable <IdAndRowVersion> tags, CancellationToken token)
            => await projectValidator.AllTagsInSameProjectAsync(tags.Select(t => t.Id), token);

            async Task <bool> NotBeAClosedProjectForTagAsync(IEnumerable <IdAndRowVersion> tags, CancellationToken token)
            => !await projectValidator.IsClosedForTagAsync(tags.First().Id, token);

            async Task <bool> BeAnExistingTagAsync(int tagId, CancellationToken token)
            => await tagValidator.ExistsAsync(tagId, token);

            async Task <bool> NotBeAVoidedTagAsync(int tagId, CancellationToken token)
            => !await tagValidator.IsVoidedAsync(tagId, token);

            async Task <bool> IsReadyToBeRescheduledAsync(int tagId, CancellationToken token)
            => await tagValidator.IsReadyToBeRescheduledAsync(tagId, token);

            bool HaveAValidRowVersion(string rowVersion)
            => rowVersionValidator.IsValid(rowVersion);
        }
        public UpdateStepCommandValidator(
            IJourneyValidator journeyValidator,
            IStepValidator stepValidator,
            IModeValidator modeValidator,
            IResponsibleValidator responsibleValidator,
            IRowVersionValidator rowVersionValidator)
        {
            CascadeMode = CascadeMode.Stop;

            RuleFor(command => command)
            .MustAsync((command, token) => BeAnExistingStepAsync(command.JourneyId, command.StepId, token))
            .WithMessage(_ => "Journey and/or step doesn't exist!")
            .MustAsync((command, token) => HaveUniqueStepTitleInJourneyAsync(command.JourneyId, command.StepId, command.Title, token))
            .WithMessage(command => $"Another step with title already exists in a journey! Step={command.Title}")
            .MustAsync((command, token) => NotBeAVoidedStepAsync(command.StepId, token))
            .WithMessage(command => $"Step is voided! Step={command.StepId}")
            .MustAsync((command, token) => BeAnExistingModeAsync(command.ModeId, token))
            .WithMessage(command => $"Mode doesn't exist! Mode={command.ModeId}")
            .MustAsync((command, token) => NotChangedToAVoidedModeAsync(command.ModeId, command.StepId, token))
            .WithMessage(command => $"Mode is voided! Mode={command.ModeId}")
            .MustAsync((command, token) => NotBeAnExistingAndVoidedResponsibleAsync(command.ResponsibleCode, token))
            .WithMessage(command => $"Responsible is voided! ResponsibleCode={command.ResponsibleCode}")
            .MustAsync((command, token) => NotHaveOtherStepsWithSameAutoTransferMethodInJourneyAsync(command.JourneyId, command.StepId, command.AutoTransferMethod, token))
            .WithMessage(command => $"Same auto transfer method can not be set on multiple steps in a journey! Method={command.AutoTransferMethod}")
            .Must(command => HaveAValidRowVersion(command.RowVersion))
            .WithMessage(command => $"Not a valid row version! Row version={command.RowVersion}");

            async Task <bool> BeAnExistingStepAsync(int journeyId, int stepId, CancellationToken token)
            => await journeyValidator.ExistsStepAsync(journeyId, stepId, token);

            async Task <bool> HaveUniqueStepTitleInJourneyAsync(int journeyId, int stepId, string stepTitle, CancellationToken token) =>
            !await journeyValidator.OtherStepExistsWithSameTitleAsync(journeyId, stepId, stepTitle, token);

            async Task <bool> NotBeAVoidedStepAsync(int stepId, CancellationToken token)
            => !await stepValidator.IsVoidedAsync(stepId, token);

            async Task <bool> BeAnExistingModeAsync(int modeId, CancellationToken token)
            => await modeValidator.ExistsAsync(modeId, token);

            async Task <bool> NotChangedToAVoidedModeAsync(int modeId, int stepId, CancellationToken token)
            => await stepValidator.HasModeAsync(modeId, stepId, token) ||
            !await modeValidator.IsVoidedAsync(modeId, token);

            async Task <bool> NotBeAnExistingAndVoidedResponsibleAsync(string responsibleCode, CancellationToken token)
            => !await responsibleValidator.ExistsAndIsVoidedAsync(responsibleCode, token);

            bool HaveAValidRowVersion(string rowVersion)
            => rowVersionValidator.IsValid(rowVersion);

            async Task <bool> NotHaveOtherStepsWithSameAutoTransferMethodInJourneyAsync(int journeyId, int stepId, AutoTransferMethod autoTransferMethod, CancellationToken token)
            => autoTransferMethod == AutoTransferMethod.None || !await journeyValidator.HasOtherStepWithAutoTransferMethodAsync(journeyId, stepId, autoTransferMethod, token);
        }
        public AcceptPunchOutCommandValidator(IInvitationValidator invitationValidator, IRowVersionValidator rowVersionValidator)
        {
            CascadeMode = CascadeMode.Stop;

            RuleFor(command => command)
            .MustAsync((command, cancellationToken) => BeAnExistingInvitation(command.InvitationId, cancellationToken))
            .WithMessage(command =>
                         $"Invitation with this ID does not exist! Id={command.InvitationId}")
            .MustAsync((command, cancellationToken) => BeAnInvitationInCompletedStage(command.InvitationId, cancellationToken))
            .WithMessage(command =>
                         "Invitation is not in completed stage, and thus cannot be accepted!")
            .Must(command => HaveAValidRowVersion(command.InvitationRowVersion))
            .WithMessage(command =>
                         $"Invitation row version is not valid! InvitationRowVersion={command.InvitationRowVersion}")
            .Must(command => HaveAValidRowVersion(command.ParticipantRowVersion))
            .WithMessage(command =>
                         $"Participant row version is not valid! ParticipantRowVersion={command.ParticipantRowVersion}")
            .MustAsync((command, cancellationToken) => BeAnAccepterOnIpo(command.InvitationId, cancellationToken))
            .WithMessage(command =>
                         "The IPO does not have a construction company assigned to accept the IPO!")
            .MustAsync((command, cancellationToken) => BeTheAssignedPersonIfPersonParticipant(command.InvitationId, cancellationToken))
            .WithMessage(command =>
                         "Person signing is not the construction company assigned to accept this IPO, or there is not a valid construction company on the IPO!");

            RuleForEach(command => command.Participants)
            .MustAsync((command, participant, _, cancellationToken) => BeAnExistingParticipant(participant.Id, command.InvitationId, cancellationToken))
            .WithMessage((command, participant) =>
                         $"Participant with ID does not exist on invitation! Participant={participant.Id}")
            .Must((command, participant) => HaveAValidRowVersion(participant.RowVersion))
            .WithMessage((command, participant) =>
                         $"Participant doesn't have valid rowVersion! Participant={participant.Id}");

            async Task <bool> BeAnExistingInvitation(int invitationId, CancellationToken cancellationToken)
            => await invitationValidator.IpoExistsAsync(invitationId, cancellationToken);

            async Task <bool> BeAnInvitationInCompletedStage(int invitationId, CancellationToken cancellationToken)
            => await invitationValidator.IpoIsInStageAsync(invitationId, IpoStatus.Completed, cancellationToken);

            async Task <bool> BeAnAccepterOnIpo(int invitationId, CancellationToken cancellationToken)
            => await invitationValidator.IpoHasAccepterAsync(invitationId, cancellationToken);

            async Task <bool> BeTheAssignedPersonIfPersonParticipant(int invitationId, CancellationToken cancellationToken)
            => await invitationValidator.CurrentUserIsValidAccepterParticipantAsync(invitationId, cancellationToken);

            async Task <bool> BeAnExistingParticipant(int participantId, int invitationId, CancellationToken cancellationToken)
            => await invitationValidator.ParticipantExistsAsync(participantId, invitationId, cancellationToken);

            bool HaveAValidRowVersion(string rowVersion)
            => rowVersionValidator.IsValid(rowVersion);
        }
示例#15
0
        public SignPunchOutCommandValidator(IInvitationValidator invitationValidator, IRowVersionValidator rowVersionValidator)
        {
            CascadeMode = CascadeMode.Stop;

            RuleFor(command => command)
            .MustAsync((command, cancellationToken) => BeAnExistingInvitation(command.InvitationId, cancellationToken))
            .WithMessage(command =>
                         $"Invitation with this ID does not exist! Id={command.InvitationId}")
            .MustAsync((command, cancellationToken) => BeAnExistingParticipant(command.ParticipantId, command.InvitationId, cancellationToken))
            .WithMessage(command =>
                         $"Participant with ID does not exist on invitation! Id={command.ParticipantId}")
            .MustAsync((command, cancellationToken) => BeANonCanceledInvitation(command.InvitationId, cancellationToken))
            .WithMessage(command =>
                         "Invitation is canceled, and thus cannot be signed!")
            .Must(command => HaveAValidRowVersion(command.ParticipantRowVersion))
            .WithMessage(command =>
                         $"Participant row version is not valid! ParticipantRowVersion={command.ParticipantRowVersion}")
            .MustAsync((command, cancellationToken) => BeASigningParticipantOnIpo(command.InvitationId, command.ParticipantId, cancellationToken))
            .WithMessage(command =>
                         $"Participant is not assigned to sign this IPO! ParticipantId={command.ParticipantId}")
            .MustAsync((command, cancellationToken) => BeTheAssignedPersonIfPersonParticipant(command.InvitationId, command.ParticipantId, cancellationToken))
            .WithMessage(command =>
                         "Person signing is not assigned to sign IPO, or there is not a valid functional role on the IPO!")
            .MustAsync((command, cancellationToken) => BeUnsignedParticipant(command.ParticipantId, command.InvitationId, cancellationToken))
            .WithMessage(command =>
                         "Participant is already signed!");

            async Task <bool> BeAnExistingInvitation(int invitationId, CancellationToken cancellationToken)
            => await invitationValidator.IpoExistsAsync(invitationId, cancellationToken);

            async Task <bool> BeANonCanceledInvitation(int invitationId, CancellationToken cancellationToken)
            => !await invitationValidator.IpoIsInStageAsync(invitationId, IpoStatus.Canceled, cancellationToken);

            async Task <bool> BeASigningParticipantOnIpo(int invitationId, int participantId, CancellationToken cancellationToken)
            => await invitationValidator.SignerExistsAsync(invitationId, participantId, cancellationToken);

            async Task <bool> BeTheAssignedPersonIfPersonParticipant(int invitationId, int participantId, CancellationToken cancellationToken)
            => await invitationValidator.CurrentUserIsValidSigningParticipantAsync(invitationId, participantId, cancellationToken);

            async Task <bool> BeAnExistingParticipant(int participantId, int invitationId, CancellationToken cancellationToken)
            => await invitationValidator.ParticipantExistsAsync(participantId, invitationId, cancellationToken);

            async Task <bool> BeUnsignedParticipant(int participantId, int invitationId, CancellationToken cancellationToken)
            => !await invitationValidator.ParticipantIsSignedAsync(participantId, invitationId, cancellationToken);

            bool HaveAValidRowVersion(string rowVersion)
            => rowVersionValidator.IsValid(rowVersion);
        }
示例#16
0
        public UpdateAttendedStatusOnParticipantCommandValidator(IInvitationValidator invitationValidator, IRowVersionValidator rowVersionValidator)
        {
            CascadeMode = CascadeMode.Stop;

            RuleFor(command => command)
            .MustAsync((command, cancellationToken) =>
                       BeAnExistingInvitation(command.InvitationId, cancellationToken))
            .WithMessage(command =>
                         $"Invitation with this ID does not exist! Id={command.InvitationId}")
            .MustAsync((command, cancellationToken) =>
                       NotBeCancelledInvitation(command.InvitationId, cancellationToken))
            .WithMessage(command =>
                         $"Cannot perform updates on cancelled invitation! Id={command.InvitationId}")
            .MustAsync((command, cancellationToken) =>
                       BeAnExistingParticipant(command.ParticipantId, command.InvitationId, cancellationToken))
            .WithMessage(command =>
                         $"Participant with ID does not exist on invitation! ParticipantId={command.ParticipantId}")
            .Must(command => HaveAValidRowVersion(command.RowVersion))
            .WithMessage(command =>
                         $"Participant doesn't have valid rowVersion! ParticipantRowVersion={command.RowVersion}")
            .MustAsync((command, cancellationToken) =>
                       HavePermissionToEdit(command.ParticipantId, command.InvitationId, cancellationToken))
            .WithMessage("The current user does not have sufficient privileges to edit this participant.")
            .MustAsync((command, cancellationToken) =>
                       HaveOppositeAttendedStatusIfTouched(command.ParticipantId, command.InvitationId, command.Attended, cancellationToken))
            .WithMessage("Cannot update participant to its current attendedStatus.");

            async Task <bool> BeAnExistingInvitation(int invitationId, CancellationToken cancellationToken)
            => await invitationValidator.IpoExistsAsync(invitationId, cancellationToken);

            async Task <bool> NotBeCancelledInvitation(int invitationId, CancellationToken cancellationToken)
            => !await invitationValidator.IpoIsInStageAsync(invitationId, IpoStatus.Canceled, cancellationToken);

            async Task <bool> BeAnExistingParticipant(int participantId, int invitationId, CancellationToken cancellationToken)
            => await invitationValidator.ParticipantExistsAsync(participantId, invitationId, cancellationToken);

            async Task <bool> HavePermissionToEdit(int participantId, int invitationId, CancellationToken cancellationToken)
            => await invitationValidator.HasPermissionToEditParticipantAsync(participantId, invitationId, cancellationToken);

            async Task <bool> HaveOppositeAttendedStatusIfTouched(int participantId, int invitationId, bool attended, CancellationToken cancellationToken)
            => await invitationValidator.HasOppositeAttendedStatusIfTouchedAsync(participantId, invitationId, attended, cancellationToken);

            bool HaveAValidRowVersion(string rowVersion)
            => rowVersionValidator.IsValid(rowVersion);
        }
示例#17
0
        public DeleteSavedFilterCommandValidator(
            ISavedFilterValidator savedFilterValidator,
            IRowVersionValidator rowVersionValidator)
        {
            CascadeMode = CascadeMode.Stop;

            RuleFor(command => command)
            .MustAsync((command, token) => BeAnExistingSavedFilterAsync(command.SavedFilterId, token))
            .WithMessage(command => $"Saved filter doesn't exist! Saved filter={command.SavedFilterId}")
            .Must(command => HaveAValidRowVersion(command.RowVersion))
            .WithMessage(command => $"Not a valid row version! Row version={command.RowVersion}");

            async Task <bool> BeAnExistingSavedFilterAsync(int savedFilterId, CancellationToken token)
            => await savedFilterValidator.ExistsAsync(savedFilterId, token);

            bool HaveAValidRowVersion(string rowVersion)
            => rowVersionValidator.IsValid(rowVersion);
        }
        public UpdateAttendedStatusAndNotesOnParticipantsCommandValidator(IInvitationValidator invitationValidator, IRowVersionValidator rowVersionValidator)
        {
            CascadeMode = CascadeMode.Stop;

            RuleFor(command => command)
            .MustAsync((command, cancellationToken) => BeAnExistingInvitation(command.InvitationId, cancellationToken))
            .WithMessage(command =>
                         $"Invitation with this ID does not exist! Id={command.InvitationId}")
            .MustAsync((command, cancellationToken) => BeAnInvitationInCompletedStage(command.InvitationId, cancellationToken))
            .WithMessage(command =>
                         "Invitation is not in completed stage, and thus cannot change attended statuses or notes!")
            .MustAsync((command, cancellationToken) => BeAContractorOnIpo(command.InvitationId, cancellationToken))
            .WithMessage(command =>
                         "The IPO does not have a contractor assigned to the IPO!")
            .MustAsync((command, cancellationToken) => BeTheAssignedContractorIfPersonParticipant(command.InvitationId, cancellationToken))
            .WithMessage(command =>
                         "User is not the contractor assigned to complete this IPO, or there is not a valid contractor on the IPO!");

            RuleForEach(command => command.Participants)
            .MustAsync((command, participant, _, cancellationToken) => BeAnExistingParticipant(participant.Id, command.InvitationId, cancellationToken))
            .WithMessage((command, participant) =>
                         $"Participant with ID does not exist on invitation! ParticipantId={participant.Id}")
            .Must((command, participant) => HaveAValidRowVersion(participant.RowVersion))
            .WithMessage((command, participant) =>
                         $"Participant doesn't have valid rowVersion! ParticipantRowVersion={participant.RowVersion}");

            async Task <bool> BeAnExistingInvitation(int invitationId, CancellationToken cancellationToken)
            => await invitationValidator.IpoExistsAsync(invitationId, cancellationToken);

            async Task <bool> BeAnInvitationInCompletedStage(int invitationId, CancellationToken cancellationToken)
            => await invitationValidator.IpoIsInStageAsync(invitationId, IpoStatus.Completed, cancellationToken);

            async Task <bool> BeAnExistingParticipant(int participantId, int invitationId, CancellationToken cancellationToken)
            => await invitationValidator.ParticipantExistsAsync(participantId, invitationId, cancellationToken);

            async Task <bool> BeTheAssignedContractorIfPersonParticipant(int invitationId, CancellationToken cancellationToken)
            => await invitationValidator.CurrentUserIsValidCompleterParticipantAsync(invitationId, cancellationToken);

            async Task <bool> BeAContractorOnIpo(int invitationId, CancellationToken cancellationToken)
            => await invitationValidator.IpoHasCompleterAsync(invitationId, cancellationToken);

            bool HaveAValidRowVersion(string rowVersion)
            => rowVersionValidator.IsValid(rowVersion);
        }
        public UpdateSavedFilterCommandValidator(
            ISavedFilterValidator savedFilterValidator,
            IRowVersionValidator rowVersionValidator)
        {
            CascadeMode = CascadeMode.Stop;

            RuleFor(command => command)
            .MustAsync((command, token) => BeAnExistingSavedFilterAsync(command.SavedFilterId, token))
            .WithMessage(command => $"Saved filter doesn't exist! Saved filter={command.SavedFilterId}")
            .MustAsync((command, token) => HaveAUniqueTitleForPerson(command.Title, command.SavedFilterId, token))
            .WithMessage(command => $"A saved filter with this title already exists! Title={command.Title}")
            .Must(command => HaveAValidRowVersion(command.RowVersion))
            .WithMessage(command => $"Not a valid row version! Row version={command.RowVersion}");

            async Task <bool> BeAnExistingSavedFilterAsync(int savedFilterId, CancellationToken token)
            => await savedFilterValidator.ExistsAsync(savedFilterId, token);
            async Task <bool> HaveAUniqueTitleForPerson(string title, int savedFilterId, CancellationToken token)
            => !await savedFilterValidator.ExistsAnotherWithSameTitleForPersonInProjectAsync(savedFilterId, title, token);

            bool HaveAValidRowVersion(string rowVersion)
            => rowVersionValidator.IsValid(rowVersion);
        }
        public DeleteAttachmentCommandValidator(
            IInvitationValidator invitationValidator,
            IRowVersionValidator rowVersionValidator)
        {
            CascadeMode = CascadeMode.Stop;

            RuleFor(command => command)
            .MustAsync((command, cancellationToken) => BeAnExistingInvitationAsync(command.InvitationId, cancellationToken))
            .WithMessage(command => $"Invitation with this ID does not exist! Id={command.InvitationId}")
            .MustAsync((command, cancellationToken) => BeAnExistingAttachmentAsync(command.InvitationId, command.AttachmentId, cancellationToken))
            .WithMessage(command => $"Attachment doesn't exist! Attachment={command.AttachmentId}.")
            .Must(command => HaveAValidRowVersion(command.RowVersion))
            .WithMessage(command => $"Not a valid row version! Row version={command.RowVersion}.");

            async Task <bool> BeAnExistingInvitationAsync(int invitationId, CancellationToken cancellationToken)
            => await invitationValidator.IpoExistsAsync(invitationId, cancellationToken);
            async Task <bool> BeAnExistingAttachmentAsync(int invitationId, int attachmentId, CancellationToken cancellationToken)
            => await invitationValidator.AttachmentExistsAsync(invitationId, attachmentId, cancellationToken);

            bool HaveAValidRowVersion(string rowVersion)
            => rowVersionValidator.IsValid(rowVersion);
        }
        public VoidTagFunctionCommandValidator(
            ITagFunctionValidator tagFunctionValidator,
            IRowVersionValidator rowVersionValidator)
        {
            CascadeMode = CascadeMode.Stop;

            RuleFor(command => command)
            .MustAsync((command, token) => BeAnExistingTagFunctionAsync(command.TagFunctionCode, token))
            .WithMessage(command => $"Tag function doesn't exist! Tag function={command.TagFunctionCode}")
            .MustAsync((command, token) => NotBeAVoidedTagFunctionAsync(command.TagFunctionCode, token))
            .WithMessage(command => $"Tag function is already voided! Tag function={command.TagFunctionCode}")
            .Must(command => HaveAValidRowVersion(command.RowVersion))
            .WithMessage(command => $"Not a valid row version! Row version={command.RowVersion}");

            async Task <bool> BeAnExistingTagFunctionAsync(string tagFunctionCode, CancellationToken token)
            => await tagFunctionValidator.ExistsAsync(tagFunctionCode, token);
            async Task <bool> NotBeAVoidedTagFunctionAsync(string tagFunctionCode, CancellationToken token)
            => !await tagFunctionValidator.IsVoidedAsync(tagFunctionCode, token);

            bool HaveAValidRowVersion(string rowVersion)
            => rowVersionValidator.IsValid(rowVersion);
        }
        public UnCompletePunchOutCommandValidator(IInvitationValidator invitationValidator, IRowVersionValidator rowVersionValidator)
        {
            CascadeMode = CascadeMode.Stop;

            RuleFor(command => command)
            .MustAsync((command, cancellationToken) => BeAnExistingInvitation(command.InvitationId, cancellationToken))
            .WithMessage(command =>
                         $"Invitation with this ID does not exist! Id={command.InvitationId}")
            .MustAsync((command, cancellationToken) => BeAnInvitationInCompletedStage(command.InvitationId, cancellationToken))
            .WithMessage(command =>
                         "Invitation is not in completed stage, and thus cannot be uncompleted!")
            .Must(command => HaveAValidRowVersion(command.InvitationRowVersion))
            .WithMessage(command =>
                         $"Invitation row version is not valid! InvitationRowVersion={command.InvitationRowVersion}")
            .Must(command => HaveAValidRowVersion(command.ParticipantRowVersion))
            .WithMessage(command =>
                         $"Participant row version is not valid! ParticipantRowVersion={command.ParticipantRowVersion}")
            .MustAsync((command, cancellationToken) => BeACompleterOnIpo(command.InvitationId, cancellationToken))
            .WithMessage(command =>
                         "The IPO does not have a contractor assigned to uncomplete the IPO!")
            .MustAsync((command, cancellationToken) => BeAdminOrThePersonWhoCompleted(command.InvitationId, cancellationToken))
            .WithMessage(command =>
                         "Person trying to uncomplete is not an admin and not the person who completed the IPO!");

            async Task <bool> BeAnExistingInvitation(int invitationId, CancellationToken cancellationToken)
            => await invitationValidator.IpoExistsAsync(invitationId, cancellationToken);

            async Task <bool> BeAnInvitationInCompletedStage(int invitationId, CancellationToken cancellationToken)
            => await invitationValidator.IpoIsInStageAsync(invitationId, IpoStatus.Completed, cancellationToken);

            async Task <bool> BeACompleterOnIpo(int invitationId, CancellationToken cancellationToken)
            => await invitationValidator.IpoHasCompleterAsync(invitationId, cancellationToken);

            async Task <bool> BeAdminOrThePersonWhoCompleted(int invitationId, CancellationToken cancellationToken)
            => await invitationValidator.CurrentUserIsAdminOrValidCompletorParticipantAsync(invitationId, cancellationToken);

            bool HaveAValidRowVersion(string rowVersion)
            => rowVersionValidator.IsValid(rowVersion);
        }
示例#23
0
        public CancelPunchOutCommandValidator(
            IInvitationValidator invitationValidator,
            IRowVersionValidator rowVersionValidator)
        {
            CascadeMode = CascadeMode.Stop;

            RuleFor(command => command)
            .MustAsync((command, cancellationToken) => BeAnExistingInvitation(command.InvitationId, cancellationToken))
            .WithMessage(command =>
                         $"Invitation with this ID does not exist! Id={command.InvitationId}")
            .MustAsync((command, cancellationToken) => InvitationIsNotCanceled(command.InvitationId, cancellationToken))
            .WithMessage(command =>
                         $"IPO is already canceled! Id={command.InvitationId}")
            .MustAsync((command, cancellationToken) => InvitationIsNotAccepted(command.InvitationId, cancellationToken))
            .WithMessage(command =>
                         $"IPO is in accepted stage! Id={command.InvitationId}")
            .MustAsync((command, cancellationToken) => CurrentUserIsCreatorOrIsInContractorFunctionalRoleOfInvitation(command.InvitationId, cancellationToken))
            .WithMessage(command =>
                         $"Current user is not the creator of the invitation and not in Contractor Functional Role! Id={command.InvitationId}")
            .Must(command => HaveAValidRowVersion(command.RowVersion))
            .WithMessage(command =>
                         $"Invitation does not have valid rowVersion! RowVersion={command.RowVersion}");

            async Task <bool> BeAnExistingInvitation(int invitationId, CancellationToken cancellationToken)
            => await invitationValidator.IpoExistsAsync(invitationId, cancellationToken);

            async Task <bool> CurrentUserIsCreatorOrIsInContractorFunctionalRoleOfInvitation(int invitationId, CancellationToken cancellationToken)
            => await invitationValidator.CurrentUserIsAllowedToCancelIpoAsync(invitationId, cancellationToken);

            async Task <bool> InvitationIsNotCanceled(int invitationId, CancellationToken cancellationToken)
            => !await invitationValidator.IpoIsInStageAsync(invitationId, IpoStatus.Canceled, cancellationToken);

            async Task <bool> InvitationIsNotAccepted(int invitationId, CancellationToken cancellationToken)
            => !await invitationValidator.IpoIsInStageAsync(invitationId, IpoStatus.Accepted, cancellationToken);

            bool HaveAValidRowVersion(string rowVersion)
            => rowVersionValidator.IsValid(rowVersion);
        }
        public UnvoidStepCommandValidator(
            IJourneyValidator journeyValidator,
            IStepValidator stepValidator,
            IRowVersionValidator rowVersionValidator)
        {
            CascadeMode = CascadeMode.Stop;

            RuleFor(command => command)
            .MustAsync((command, token) => BeAnExistingStepAsync(command.JourneyId, command.StepId, token))
            .WithMessage(command => "Journey and/or step doesn't exist!")
            .MustAsync((command, token) => BeAVoidedStepAsync(command.StepId, token))
            .WithMessage(command => $"Step is not voided! Step={command.StepId}")
            .Must(command => HaveAValidRowVersion(command.RowVersion))
            .WithMessage(command => $"Not a valid row version! Row version={command.RowVersion}");

            async Task <bool> BeAnExistingStepAsync(int journeyId, int stepId, CancellationToken token)
            => await journeyValidator.ExistsStepAsync(journeyId, stepId, token);
            async Task <bool> BeAVoidedStepAsync(int stepId, CancellationToken token)
            => await stepValidator.IsVoidedAsync(stepId, token);

            bool HaveAValidRowVersion(string rowVersion)
            => rowVersionValidator.IsValid(rowVersion);
        }
        public VoidRequirementDefinitionCommandValidator(
            IRequirementTypeValidator requirementTypeValidator,
            IRequirementDefinitionValidator requirementDefinitionValidator,
            IRowVersionValidator rowVersionValidator
            )
        {
            CascadeMode = CascadeMode.Stop;

            RuleFor(command => command)
            .MustAsync(BeAnExistingRequirementDefinitionAsync)
            .WithMessage(command => "Requirement type and/or requirement definition doesn't exist!")
            .MustAsync((command, token) => NotBeAVoidedRequirementDefinitionAsync(command.RequirementDefinitionId, token))
            .WithMessage(command => $"Requirement definition is already voided! Requirement definition={command.RequirementDefinitionId}")
            .Must(command => HaveAValidRowVersion(command.RowVersion))
            .WithMessage(command => $"Not a valid row version! Row version={command.RowVersion}");

            async Task <bool> BeAnExistingRequirementDefinitionAsync(VoidRequirementDefinitionCommand command, CancellationToken token)
            => await requirementTypeValidator.RequirementDefinitionExistsAsync(command.RequirementTypeId, command.RequirementDefinitionId, token);
            async Task <bool> NotBeAVoidedRequirementDefinitionAsync(int requirementDefinitionId, CancellationToken token)
            => !await requirementDefinitionValidator.IsVoidedAsync(requirementDefinitionId, token);

            bool HaveAValidRowVersion(string rowVersion)
            => rowVersionValidator.IsValid(rowVersion);
        }
        public EditInvitationCommandValidator(IInvitationValidator invitationValidator, IRowVersionValidator rowVersionValidator)
        {
            CascadeMode = CascadeMode.Stop;

            RuleFor(command => command)
            //input validators
            .Must(command => command.UpdatedParticipants != null)
            .WithMessage("Participants cannot be null!")
            .Must(command => command.Description == null || command.Description.Length < Invitation.DescriptionMaxLength)
            .WithMessage(command =>
                         $"Description cannot be more than {Invitation.DescriptionMaxLength} characters! Description={command.Description}")
            .Must(command => command.Location == null || command.Location.Length < Invitation.LocationMaxLength)
            .WithMessage(command =>
                         $"Location cannot be more than {Invitation.LocationMaxLength} characters! Location={command.Location}")
            .Must(command => command.StartTime < command.EndTime)
            .WithMessage(command =>
                         $"Start time must be before end time! Start={command.StartTime} End={command.EndTime}")
            .Must(command =>
                  command.Title != null &&
                  command.Title.Length >= Invitation.TitleMinLength &&
                  command.Title.Length < Invitation.TitleMaxLength)
            .WithMessage(command =>
                         $"Title must be between {Invitation.TitleMinLength} and {Invitation.TitleMaxLength} characters! Title={command.Title}")
            //business validators
            .MustAsync((command, cancellationToken) => BeAnExistingIpo(command.InvitationId, cancellationToken))
            .WithMessage(command => $"Invitation with this ID does not exist! Id={command.InvitationId}")
            .MustAsync((command, cancellationToken) => BeAnIpoInPlannedStage(command.InvitationId, cancellationToken))
            .WithMessage(command => $"IPO must be in planned stage to be edited! Id={command.InvitationId}")
            .Must(command => HaveAValidRowVersion(command.RowVersion))
            .WithMessage(command => $"Invitation does not have valid rowVersion! RowVersion={command.RowVersion}")
            .Must(command => MustHaveValidScope(command.Type, command.UpdatedMcPkgScope, command.UpdatedCommPkgScope))
            .WithMessage("Not a valid scope! Choose either DP with mc scope or MDP with comm pkg scope")
            .Must(command => TwoFirstParticipantsMustBeSetWithCorrectOrganization(command.UpdatedParticipants))
            .WithMessage("Contractor and Construction Company must be invited!")
            .Must(command => RequiredParticipantsHaveLowestSortKeys(command.UpdatedParticipants))
            .WithMessage("Contractor must be first and Construction Company must be second!")
            .Must(command => ParticipantListMustBeValid(command.UpdatedParticipants))
            .WithMessage("Each participant must contain an email or oid!");

            RuleForEach(command => command.UpdatedParticipants)
            .MustAsync((command, participant, _, cancellationToken) => ParticipantToBeUpdatedMustExist(participant, command.InvitationId, cancellationToken))
            .WithMessage(_ => $"Participant with ID does not exist on invitation!")
            .Must(participant => participant.SortKey >= 0)
            .WithMessage((_, participant) =>
                         $"Sort key for participant must be a non negative number! SortKey={participant.SortKey}")
            .Must(FunctionalRoleParticipantsMustBeValid)
            .WithMessage((_, participant) =>
                         $"Functional role code must be between 3 and {Participant.FunctionalRoleCodeMaxLength} characters! Code={participant.InvitedFunctionalRole.Code}")
            .Must((command, participant) => ParticipantsHaveValidRowVersions(participant))
            .WithMessage(_ => "Participant doesn't have valid rowVersion!");

            async Task <bool> BeAnExistingIpo(int invitationId, CancellationToken cancellationToken)
            => await invitationValidator.IpoExistsAsync(invitationId, cancellationToken);

            async Task <bool> BeAnIpoInPlannedStage(int invitationId, CancellationToken cancellationToken)
            => await invitationValidator.IpoIsInStageAsync(invitationId, IpoStatus.Planned, cancellationToken);

            bool MustHaveValidScope(
                DisciplineType type,
                IList <string> updatedMcPkgScope,
                IList <string> updatedCommPkgScope)
            => invitationValidator.IsValidScope(type, updatedMcPkgScope, updatedCommPkgScope);

            async Task <bool> ParticipantToBeUpdatedMustExist(ParticipantsForCommand participant, int invitationId, CancellationToken cancellationToken)
            => await invitationValidator.ParticipantWithIdExistsAsync(participant, invitationId, cancellationToken);

            bool TwoFirstParticipantsMustBeSetWithCorrectOrganization(IList <ParticipantsForEditCommand> participants)
            => invitationValidator.RequiredParticipantsMustBeInvited(participants.Cast <ParticipantsForCommand>().ToList());

            bool RequiredParticipantsHaveLowestSortKeys(IList <ParticipantsForEditCommand> participants)
            => invitationValidator.OnlyRequiredParticipantsHaveLowestSortKeys(participants.Cast <ParticipantsForCommand>().ToList());

            bool ParticipantListMustBeValid(IList <ParticipantsForEditCommand> participants)
            => invitationValidator.IsValidParticipantList(participants.Cast <ParticipantsForCommand>().ToList());

            bool HaveAValidRowVersion(string rowVersion)
            => rowVersionValidator.IsValid(rowVersion);

            bool ParticipantsHaveValidRowVersions(ParticipantsForEditCommand participant)
            {
                if (participant.InvitedExternalEmailToEdit?.Id != null)
                {
                    return(rowVersionValidator.IsValid(participant.InvitedExternalEmailToEdit.RowVersion));
                }
                if (participant.InvitedPersonToEdit?.Id != null)
                {
                    return(rowVersionValidator.IsValid(participant.InvitedPersonToEdit.RowVersion));
                }

                if (participant.InvitedFunctionalRoleToEdit != null)
                {
                    if (participant.InvitedFunctionalRoleToEdit.Id != null && !rowVersionValidator.IsValid(participant.InvitedFunctionalRoleToEdit.RowVersion))
                    {
                        return(false);
                    }

                    return(participant.InvitedFunctionalRoleToEdit.EditPersons.All(person => person.Id == null || rowVersionValidator.IsValid(person.RowVersion)));
                }

                return(true);
            }

            bool FunctionalRoleParticipantsMustBeValid(ParticipantsForCommand participant)
            {
                if (participant.InvitedFunctionalRole == null)
                {
                    return(true);
                }

                return(participant.InvitedFunctionalRole.Code != null &&
                       participant.InvitedFunctionalRole.Code.Length > 2 &&
                       participant.InvitedFunctionalRole.Code.Length < Participant.FunctionalRoleCodeMaxLength);
            }
        }
        public UpdateTagStepAndRequirementsCommandValidator(
            IProjectValidator projectValidator,
            ITagValidator tagValidator,
            IStepValidator stepValidator,
            IRequirementDefinitionValidator requirementDefinitionValidator,
            IRowVersionValidator rowVersionValidator)
        {
            CascadeMode = CascadeMode.Stop;

            WhenAsync((command, token) => IsASupplierStepAsync(command.StepId, token), () =>
            {
                WhenAsync((command, token) => NotBeAPoAreaTagAsync(command.TagId, token), () =>
                {
                    RuleFor(command => command)
                    .MustAsync((_, command, token) =>
                               RequirementUsageIsForAllJourneysAsync(
                                   command.TagId,
                                   command.UpdatedRequirements.Where(u => !u.IsVoided).Select(u => u.TagRequirementId).ToList(),
                                   command.UpdatedRequirements.Where(u => u.IsVoided).Select(u => u.TagRequirementId).ToList(),
                                   command.NewRequirements.Select(r => r.RequirementDefinitionId).ToList(),
                                   token))
                    .WithMessage(_ => "Requirements must include requirements to be used both for supplier and other than suppliers!");
                }).Otherwise(() =>
                {
                    RuleFor(command => command)
                    .MustAsync((_, command, token) =>
                               RequirementUsageIsForSupplierAsync(
                                   command.TagId,
                                   command.UpdatedRequirements.Where(u => !u.IsVoided).Select(u => u.TagRequirementId).ToList(),
                                   command.UpdatedRequirements.Where(u => u.IsVoided).Select(u => u.TagRequirementId).ToList(),
                                   command.NewRequirements.Select(r => r.RequirementDefinitionId).ToList(),
                                   token))
                    .WithMessage(_ => "Requirements must include requirements to be used for supplier!")
                    .MustAsync((command, token) => RequirementUsageIsNotForOtherThanSupplierAsync(
                                   command.TagId,
                                   command.UpdatedRequirements.Where(u => !u.IsVoided).Select(u => u.TagRequirementId).ToList(),
                                   command.UpdatedRequirements.Where(u => u.IsVoided).Select(u => u.TagRequirementId).ToList(),
                                   command.NewRequirements.Select(r => r.RequirementDefinitionId).ToList(),
                                   token))
                    .WithMessage(_ => "Requirements can not include requirements for other than suppliers!");
                });
            }).Otherwise(() =>
            {
                RuleFor(command => command)
                .MustAsync((command, token) => NotBeAPoAreaTagAsync(command.TagId, token))
                .WithMessage(_ => $"Step for a {TagType.PoArea.GetTagNoPrefix()} tag needs to be for supplier!")
                .MustAsync((_, command, token) =>
                           RequirementUsageIsForJourneysWithoutSupplierAsync(
                               command.TagId,
                               command.UpdatedRequirements.Where(u => !u.IsVoided).Select(u => u.TagRequirementId).ToList(),
                               command.UpdatedRequirements.Where(u => u.IsVoided).Select(u => u.TagRequirementId).ToList(),
                               command.NewRequirements.Select(r => r.RequirementDefinitionId).ToList(),
                               token))
                .WithMessage(_ => "Requirements must include requirements to be used for other than suppliers!");
            });

            WhenAsync((command, token) => IsAnAreaTagAsync(command.TagId, token), () =>
            {
                RuleFor(command => command)
                .Must(command => !string.IsNullOrEmpty(command.Description))
                .WithMessage(_ => "Description can not be blank!");
            }).Otherwise(() =>
            {
                RuleFor(command => command)
                .MustAsync((command, token)
                           => NotChangeDescriptionAsync(command.TagId, command.Description, token))
                .WithMessage(_ => "Tag must be an area tag to update description!");
            });

            RuleFor(command => command)
            .MustAsync((_, command, token) =>
                       RequirementsMustBeUniqueAfterUpdateAsync(
                           command.TagId,
                           command.NewRequirements.Select(r => r.RequirementDefinitionId).ToList(),
                           token))
            .WithMessage(_ => "Requirements must be unique!")
            .MustAsync((command, token) => NotBeAClosedProjectForTagAsync(command.TagId, token))
            .WithMessage(command => $"Project for tag is closed! Tag={command.TagId}")
            .MustAsync((command, token) => BeAnExistingTagAsync(command.TagId, token))
            .WithMessage(command => $"Tag doesn't exist! Tag={command.TagId}")
            .MustAsync((command, token) => NotBeAVoidedTagAsync(command.TagId, token))
            .WithMessage(command => $"Tag is voided! Tag={command.TagId}")
            .MustAsync((command, token) => NotChangedToAVoidedStepAsync(command.TagId, command.StepId, token))
            .WithMessage(command => $"Step is voided! Step={command.StepId}")
            .Must(command => HaveAValidRowVersion(command.RowVersion))
            .WithMessage(command => $"Not a valid row version! Row version={command.RowVersion}");

            RuleForEach(command => command.UpdatedRequirements)
            .MustAsync((command, req, _, token) => BeAnExistingTagRequirementAsync(command.TagId, req.TagRequirementId, token))
            .WithMessage((_, req) => $"Requirement doesn't exist! Requirement={req.TagRequirementId}");

            RuleForEach(command => command.DeletedRequirements)
            .MustAsync((command, req, _, token) => BeAnExistingTagRequirementAsync(command.TagId, req.TagRequirementId, token))
            .WithMessage((_, req) => $"Requirement doesn't exist! Requirement={req.TagRequirementId}")
            .MustAsync((command, req, _, token) => BeAVoidedTagRequirementAsync(
                           command.TagId,
                           req.TagRequirementId,
                           command.UpdatedRequirements.Where(u => u.IsVoided).Select(u => u.TagRequirementId).ToList(),
                           token))
            .WithMessage((_, req) => $"Requirement is not voided! Requirement={req.TagRequirementId}");

            RuleForEach(command => command.NewRequirements)
            .MustAsync((_, req, _, token) => BeAnExistingRequirementDefinitionAsync(req.RequirementDefinitionId, token))
            .WithMessage((_, req) =>
                         $"Requirement definition doesn't exist! Requirement definition={req.RequirementDefinitionId}")
            .MustAsync((_, req, _, token) => NotBeAVoidedRequirementDefinitionAsync(req.RequirementDefinitionId, token))
            .WithMessage((_, req) =>
                         $"Requirement definition is voided! Requirement definition={req.RequirementDefinitionId}");

            async Task <bool> RequirementsMustBeUniqueAfterUpdateAsync(
                int tagId,
                List <int> requirementDefinitionIdsToBeAdded,
                CancellationToken token)
            => requirementDefinitionIdsToBeAdded.Count == 0 ||
            await tagValidator.AllRequirementsWillBeUniqueAsync(tagId, requirementDefinitionIdsToBeAdded, token);

            async Task <bool> RequirementUsageIsNotForOtherThanSupplierAsync(
                int tagId,
                List <int> tagRequirementIdsToBeUnvoided,
                List <int> tagRequirementIdsToBeVoided,
                List <int> requirementDefinitionIdsToBeAdded,
                CancellationToken token)
            => !await tagValidator.RequirementHasAnyForOtherThanSuppliersUsageAsync(
                tagId,
                tagRequirementIdsToBeUnvoided,
                tagRequirementIdsToBeVoided,
                requirementDefinitionIdsToBeAdded,
                token);

            async Task <bool> RequirementUsageIsForSupplierAsync(
                int tagId,
                List <int> tagRequirementIdsToBeUnvoided,
                List <int> tagRequirementIdsToBeVoided,
                List <int> requirementDefinitionIdsToBeAdded,
                CancellationToken token)
            => await tagValidator.RequirementUsageWillCoverForSuppliersAsync(
                tagId,
                tagRequirementIdsToBeUnvoided,
                tagRequirementIdsToBeVoided,
                requirementDefinitionIdsToBeAdded,
                token);

            async Task <bool> RequirementUsageIsForAllJourneysAsync(
                int tagId,
                List <int> tagRequirementIdsToBeUnvoided,
                List <int> tagRequirementIdsToBeVoided,
                List <int> requirementDefinitionIdsToBeAdded,
                CancellationToken token)
            => await tagValidator.RequirementUsageWillCoverBothForSupplierAndOtherAsync(
                tagId,
                tagRequirementIdsToBeUnvoided,
                tagRequirementIdsToBeVoided,
                requirementDefinitionIdsToBeAdded,
                token);

            async Task <bool> RequirementUsageIsForJourneysWithoutSupplierAsync(
                int tagId,
                List <int> tagRequirementIdsToBeUnvoided,
                List <int> tagRequirementIdsToBeVoided,
                List <int> requirementDefinitionIdsToBeAdded,
                CancellationToken token)
            => await tagValidator.RequirementUsageWillCoverForOtherThanSuppliersAsync(
                tagId,
                tagRequirementIdsToBeUnvoided,
                tagRequirementIdsToBeVoided,
                requirementDefinitionIdsToBeAdded,
                token);

            async Task <bool> IsASupplierStepAsync(int stepId, CancellationToken token)
            => await stepValidator.IsForSupplierAsync(stepId, token);

            async Task <bool> NotBeAClosedProjectForTagAsync(int tagId, CancellationToken token)
            => !await projectValidator.IsClosedForTagAsync(tagId, token);

            async Task <bool> IsAnAreaTagAsync(int tagId, CancellationToken token)
            => await tagValidator.VerifyTagIsAreaTagAsync(tagId, token);

            async Task <bool> BeAnExistingTagAsync(int tagId, CancellationToken token)
            => await tagValidator.ExistsAsync(tagId, token);

            async Task <bool> NotBeAVoidedTagAsync(int tagId, CancellationToken token)
            => !await tagValidator.IsVoidedAsync(tagId, token);

            async Task <bool> NotBeAPoAreaTagAsync(int tagId, CancellationToken token)
            => !await tagValidator.VerifyTagTypeAsync(tagId, TagType.PoArea, token);

            async Task <bool> NotChangedToAVoidedStepAsync(int tagId, int stepId, CancellationToken token)
            => await tagValidator.HasStepAsync(tagId, stepId, token) ||
            !await stepValidator.IsVoidedAsync(stepId, token);

            async Task <bool> BeAnExistingRequirementDefinitionAsync(int requirementDefinitionId, CancellationToken token)
            => await requirementDefinitionValidator.ExistsAsync(requirementDefinitionId, token);

            async Task <bool> NotBeAVoidedRequirementDefinitionAsync(int requirementDefinitionId, CancellationToken token)
            => !await requirementDefinitionValidator.IsVoidedAsync(requirementDefinitionId, token);

            async Task <bool> BeAnExistingTagRequirementAsync(int tagId, int tagRequirementId, CancellationToken token)
            => await tagValidator.HasRequirementAsync(tagId, tagRequirementId, token);

            async Task <bool> BeAVoidedTagRequirementAsync(
                int tagId,
                int tagRequirementId,
                List <int> tagRequirementIdsToBeVoided,
                CancellationToken token)
            {
                if (tagRequirementIdsToBeVoided.Contains(tagRequirementId))
                {
                    return(true);
                }

                return(await tagValidator.IsRequirementVoidedAsync(tagId, tagRequirementId, token));
            }

            bool HaveAValidRowVersion(string rowVersion)
            => rowVersionValidator.IsValid(rowVersion);

            async Task <bool> NotChangeDescriptionAsync(int tagId, string description, CancellationToken token)
            => description == null || await tagValidator.VerifyTagDescriptionAsync(tagId, description, token);
        }