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); }
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); }
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); }
public UploadAttachmentCommandValidator(IInvitationValidator invitationValidator, IOptionsMonitor <BlobStorageOptions> options) { CascadeMode = CascadeMode.Stop; RuleFor(x => x) .NotNull(); RuleFor(x => x.FileName) .NotEmpty() .WithMessage("Filename not given!") .MaximumLength(Attachment.FileNameLengthMax) .WithMessage($"Filename too long! Max {Attachment.FileNameLengthMax} characters") .Must(BeAValidFile) .WithMessage(x => $"File {x.FileName} is not a valid file for upload!"); RuleFor(x => x.Content.Length) .Must(BeSmallerThanMaxSize) .When(x => x.Content != null) .WithMessage($"Maximum file size is {options.CurrentValue.MaxSizeMb}MB!"); 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) => NotHaveAttachmentWithFileNameAsync(command.InvitationId, command.FileName, cancellationToken)) .WithMessage(command => $"Invitation already has an attachment with filename {command.FileName}! Please rename file or choose to overwrite.") .When(c => !c.OverWriteIfExists, ApplyConditionTo.CurrentValidator); bool BeAValidFile(string fileName) { var suffix = Path.GetExtension(fileName?.ToLower()); return(suffix != null && !options.CurrentValue.BlockedFileSuffixes.Contains(suffix) && fileName?.IndexOfAny(Path.GetInvalidFileNameChars()) == -1); } bool BeSmallerThanMaxSize(long fileSizeInBytes) { var maxSizeInBytes = options.CurrentValue.MaxSizeMb * 1024 * 1024; return(fileSizeInBytes < maxSizeInBytes); } async Task <bool> BeAnExistingInvitationAsync(int invitationId, CancellationToken cancellationToken) => await invitationValidator.IpoExistsAsync(invitationId, cancellationToken); async Task <bool> NotHaveAttachmentWithFileNameAsync(int invitationId, string fileName, CancellationToken cancellationToken) => !await invitationValidator.AttachmentWithFileNameExistsAsync(invitationId, fileName, cancellationToken); }
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); }
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 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); }
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 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 AddCommentCommandValidator(IInvitationValidator invitationValidator) { CascadeMode = CascadeMode.Stop; RuleFor(command => command) //input validators .Must((command) => command.Comment.Length <= Comment.CommentMaxLength) .WithMessage(command => $"Comment cannot be more than {Comment.CommentMaxLength} characters! Comment={command.Comment}") //business validators .MustAsync((command, cancellationToken) => BeAnExistingInvitation(command.InvitationId, cancellationToken)) .WithMessage(command => $"Invitation with this ID does not exist! Id={command.InvitationId}") .MustAsync((command, cancellationToken) => BeANonCanceledInvitation(command.InvitationId, cancellationToken)) .WithMessage(command => "Invitation is canceled, and thus cannot be commented on!"); 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); }
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 CreateInvitationCommandValidator(IInvitationValidator invitationValidator) { CascadeMode = CascadeMode.Stop; RuleFor(command => command) //input validators .Must(command => command.Participants != null) .WithMessage("Participants cannot be null!") .Must(command => command.ProjectName != null && command.ProjectName.Length >= Invitation.ProjectNameMinLength && command.ProjectName.Length < Invitation.ProjectNameMaxLength) .WithMessage(command => $"Project name must be between {Invitation.ProjectNameMinLength} and {Invitation.ProjectNameMaxLength} characters! ProjectName={command.ProjectName}") .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 .Must(command => MustHaveValidScope(command.Type, command.McPkgScope, command.CommPkgScope)) .WithMessage("Not a valid scope! Choose either DP with mc scope or MDP with comm pkg scope") .Must(command => TwoFirstParticipantsMustBeSetWithCorrectOrganization(command.Participants)) .WithMessage("Contractor and Construction Company must be invited!") .Must(command => RequiredParticipantsHaveLowestSortKeys(command.Participants)) .WithMessage("Contractor must be first and Construction Company must be second!") .Must(command => ParticipantListMustBeValid(command.Participants)) .WithMessage("Each participant must contain an email or oid!"); RuleForEach(command => command.Participants) .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}"); bool MustHaveValidScope(DisciplineType type, IList <string> mcPkgScope, IList <string> commPkgScope) => invitationValidator.IsValidScope(type, mcPkgScope, commPkgScope); bool TwoFirstParticipantsMustBeSetWithCorrectOrganization(IList <ParticipantsForCommand> participants) => invitationValidator.RequiredParticipantsMustBeInvited(participants); bool RequiredParticipantsHaveLowestSortKeys(IList <ParticipantsForCommand> participants) => invitationValidator.OnlyRequiredParticipantsHaveLowestSortKeys(participants); bool ParticipantListMustBeValid(IList <ParticipantsForCommand> participants) => invitationValidator.IsValidParticipantList(participants); 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); } }