private static string GetDefaultResponsible(IClaimSource group, bool includeSelf) { var result = ResponsibleMasterExtensions.GetResponsibleMasters(@group, includeSelf) .Select(u => u.GetDisplayName()) .JoinStrings(", "); return(string.IsNullOrWhiteSpace(result) ? "Никто" : result); }
private static T FillFromCharacterGroup <T>(T viewModel, IClaimSource field) where T : CharacterGroupViewModelBase { viewModel.Masters = GetMasters(field, includeSelf: true); viewModel.ProjectName = field.Project.ProjectName; viewModel.ProjectId = field.Project.ProjectId; return(viewModel); }
private static IEnumerable <MasterListItemViewModel> GetMasters(IClaimSource group, bool includeSelf) { return(group.Project.GetMasterListViewModel() .Union(new MasterListItemViewModel() { Id = "-1", Name = "По умолчанию", // TODO Temporary disabled as shown in hot profiles + GetDefaultResponsible(group, includeSelf) }).OrderByDescending(m => m.Id == "-1").ThenBy(m => m.Name)); }
public static bool IsAvailableForTarget([NotNull] this ProjectField field, [CanBeNull] IClaimSource target) { if (field == null) { throw new ArgumentNullException(nameof(field)); } return(field.IsActive && (field.FieldBoundTo == FieldBoundTo.Claim || field.ValidForNpc || !target.IsNpc()) && (!field.GroupsAvailableFor.Any() || target.IsPartOfAnyOfGroups(field.GroupsAvailableFor))); }
public bool HasEditAccess(AccessArguments accessArguments, IClaimSource target) { return(accessArguments.MasterAccess || (accessArguments.PlayerAccessToCharacter && Field.CanPlayerEdit && Field.FieldBoundTo == FieldBoundTo.Character) || (accessArguments.PlayerAccesToClaim && Field.CanPlayerEdit && (Field.ShowOnUnApprovedClaims || accessArguments.PlayerAccessToCharacter))); }
public static bool IsNpc([CanBeNull] this IClaimSource target) { var character = target as Character; if (character == null) { return(false); } return(!character.IsAcceptingClaims && character.ApprovedClaim == null); }
private static IEnumerable <ClaimProblem> CheckField(IClaimSource target, FieldWithValue fieldWithValue) { if (!fieldWithValue.Field.CanHaveValue()) { yield break; } var isAvailableForTarget = fieldWithValue.Field.IsAvailableForTarget(target); var hasValue = fieldWithValue.HasValue; if (hasValue) { if (isAvailableForTarget) { yield break; } if (!fieldWithValue.Field.IsActive) { yield return(FieldProblem(ClaimProblemType.DeletedFieldHasValue, ProblemSeverity.Hint, fieldWithValue)); } else { yield return(FieldProblem(ClaimProblemType.FieldShouldNotHaveValue, ProblemSeverity.Hint, fieldWithValue)); } } else { if (!isAvailableForTarget) { yield break; } switch (fieldWithValue.Field.MandatoryStatus) { case MandatoryStatus.Optional: break; case MandatoryStatus.Recommended: yield return(FieldProblem(ClaimProblemType.FieldIsEmpty, ProblemSeverity.Hint, fieldWithValue)); break; case MandatoryStatus.Required: yield return(FieldProblem(ClaimProblemType.FieldIsEmpty, ProblemSeverity.Warning, fieldWithValue)); break; default: throw new ArgumentOutOfRangeException(); } } }
public AddClaimViewModel Fill(IClaimSource obj, User user) { ProjectId = obj.ProjectId; ProjectName = obj.Project.ProjectName; HasAnyClaim = user.Claims.Any(c => c.ProjectId == obj.ProjectId && c.IsPending); HasApprovedClaim = !(obj.Project.Details?.EnableManyCharacters ?? false) && obj.Project.Claims.OfUserApproved(user.UserId).Any(); HasMyClaim = obj.HasClaimForUser(user.UserId); TargetName = obj.Name; Description = obj.Description.ToHtmlString(); IsAvailable = obj.IsAvailable; ClaimApplyRules = obj.Project.Details?.ClaimApplyRules.ToHtmlString(); Fields = new CustomFieldsViewModel(user.UserId, obj); IsRoot = obj.IsRoot; return(this); }
public CustomFieldsViewModel(int?currentUserId, IClaimSource target) { CurrentUserId = currentUserId; HasMasterAccess = target.HasMasterAccess(currentUserId); EditAllowed = target.Project.Active; Target = target; HasPlayerClaimAccess = true; var renderer = new JoinrpgMarkdownLinkRenderer(Target.Project); Fields = target.Project.GetFields() .Select(ch => new FieldValueViewModel(this, ch, renderer)) .ToList(); }
/// <summary> /// Called from AddClaimViewModel /// </summary> public CustomFieldsViewModel(int?currentUserId, IClaimSource target) { CurrentUserId = currentUserId; AccessArguments = new AccessArguments( target.HasMasterAccess(currentUserId), playerAccessToCharacter: false, playerAccesToClaim: true); EditAllowed = target.Project.Active; Target = target; var renderer = new JoinrpgMarkdownLinkRenderer(Target.Project); Fields = target.Project.GetFieldsNotFilled() .Select(ch => new FieldValueViewModel(this, ch, renderer)) .ToList(); }
public AddClaimViewModel Fill(IClaimSource claimSource, int playerUserId) { var disallowReasons = claimSource.ValidateIfCanAddClaim(playerUserId) .Select(x => x.ToViewModel()).ToList(); CanSendClaim = !disallowReasons.Any(); IsProjectRelatedReason = disallowReasons.Intersect(new[] { AddClaimForbideReasonViewModel.ProjectClaimsClosed, AddClaimForbideReasonViewModel.ProjectNotActive, }) .Any(); if (!disallowReasons.Any()) { var myClaims = claimSource.Project.Claims.OfUserActive(playerUserId); if (myClaims.Any()) { disallowReasons.Add(AddClaimForbideReasonViewModel .AlredySentNotApprovedClaimToAnotherPlace); } } ValidationStatus = disallowReasons; ProjectAllowsMultipleCharacters = claimSource.Project.Details.EnableManyCharacters; ProjectId = claimSource.Project.ProjectId; ProjectName = claimSource.Project.ProjectName; TargetName = claimSource.Name; Description = claimSource.Description.ToHtmlString(); IsAvailable = claimSource.IsAvailable; ClaimApplyRules = claimSource.Project.Details.ClaimApplyRules.ToHtmlString(); Fields = new CustomFieldsViewModel(playerUserId, claimSource); IsRoot = claimSource.IsRoot; return(this); }
public static IEnumerable <User> GetResponsibleMasters([NotNull] this IClaimSource group, bool includeSelf = true) { if (group == null) { throw new ArgumentNullException(nameof(group)); } if (group.ResponsibleMasterUser != null && includeSelf) { return(new[] { group.ResponsibleMasterUser }); } var candidates = new HashSet <CharacterGroup>(); var removedGroups = new HashSet <CharacterGroup>(); var lookupGroups = new HashSet <CharacterGroup>(group.ParentGroups); while (lookupGroups.Any()) { var currentGroup = lookupGroups.First(); _ = lookupGroups.Remove(currentGroup); //Get next group if (removedGroups.Contains(currentGroup) || candidates.Contains(currentGroup)) { continue; } if (currentGroup.ResponsibleMasterUserId != null) { _ = candidates.Add(currentGroup); removedGroups.UnionWith(currentGroup.FlatTree(c => c.ParentGroups, includeSelf: false)); //Some group with set responsible master will shadow out all parents. } else { lookupGroups.UnionWith(currentGroup.ParentGroups); } } return(candidates.Except(removedGroups).Select(c => c.ResponsibleMasterUser)); }
/// <summary> /// Called from AddClaimViewModel /// </summary> public CustomFieldsViewModel(int?currentUserId, IClaimSource target) : this() { AccessArguments = new AccessArguments( target.HasMasterAccess(currentUserId), playerAccessToCharacter: false, playerAccesToClaim: true); EditAllowed = target.Project.Active; Target = target; var renderer = new JoinrpgMarkdownLinkRenderer(Target.Project); var fieldsList = target.Project.GetFieldsNotFilled(); if (target is Character character) { fieldsList.FillIfEnabled(claim: null, character: character); } Fields = fieldsList .Select(ch => CreateFieldValueView(ch, renderer)) .ToList(); }
public static IEnumerable <CharacterGroup> GetParentGroupsToTop([CanBeNull] this IClaimSource target) { return(target?.ParentGroups.SelectMany(g => g.FlatTree(gr => gr.ParentGroups)).OrderBy(g => g.CharacterGroupId) .Distinct() ?? Enumerable.Empty <CharacterGroup>()); }
public static bool HasClaimForUser(this IClaimSource claimSource, int currentUserId) { return(claimSource.Claims.OfUserActive(currentUserId).Any()); }
public bool HasEditAccess(bool masterAccess, bool characterAccess, bool claimAccess, IClaimSource target) { return((masterAccess || (characterAccess && Field.CanPlayerEdit && Field.FieldBoundTo == FieldBoundTo.Character) || (claimAccess && Field.CanPlayerEdit && (Field.ShowOnUnApprovedClaims || characterAccess))) && (HasValue || Field.IsAvailableForTarget(target))); }
public static bool IsAvailableForTarget(this ProjectField field, IClaimSource target) { return(field.IsActive && (field.FieldBoundTo == FieldBoundTo.Claim || field.ValidForNpc || !target.IsNpc()) && (!field.GroupsAvailableFor.Any() || target.IsPartOfAnyOfGroups(field.GroupsAvailableFor))); }
public static void EnsureCanMoveClaim(this IClaimSource claimSource, Claim claim) { ThrowIfValidationFailed(claimSource.ValidateIfCanMoveClaim(claim), claim); }
public static bool IsNpc([CanBeNull] this IClaimSource target) { return(target is Character character && !character.IsAcceptingClaims && character.ApprovedClaim == null); }
/// <summary> /// Perform real validation /// </summary> /// <param name="claimSource">Where we are trying to add/move claim</param> /// <param name="playerUserId">User</param> /// <param name="existingClaim">If we already have claim (move), that's it</param> /// <returns></returns> private static IEnumerable <AddClaimForbideReason> ValidateImpl(this IClaimSource claimSource, int?playerUserId, [CanBeNull] Claim existingClaim) { var project = claimSource.Project; if (!project.Active) { yield return(AddClaimForbideReason.ProjectNotActive); } if (!project.IsAcceptingClaims) { yield return(AddClaimForbideReason.ProjectClaimsClosed); } switch (claimSource) { case CharacterGroup characterGroup: if (!characterGroup.HaveDirectSlots) { yield return(AddClaimForbideReason.NotForDirectClaims); } else if (!characterGroup.DirectSlotsUnlimited && characterGroup.AvaiableDirectSlots == 0) { yield return(AddClaimForbideReason.SlotsExhausted); } if (existingClaim?.IsApproved == true) { yield return(AddClaimForbideReason.ApprovedClaimMovedToGroup); } break; case Character character: if (character.ApprovedClaimId != null) { yield return(AddClaimForbideReason.Busy); } if (!character.IsAcceptingClaims) { yield return(AddClaimForbideReason.Npc); } break; } if (existingClaim?.ClaimStatus == Claim.Status.CheckedIn) { yield return(AddClaimForbideReason.CheckedInClaimCantBeMoved); } if (playerUserId is int playerId) { if (claimSource.Claims.OfUserActive(playerId).Any()) { if (!(claimSource is CharacterGroup) || !project.Details.EnableManyCharacters) { yield return(AddClaimForbideReason.AlreadySent); } } if (!project.Details.EnableManyCharacters && project.Claims.OfUserApproved(playerId).Except(new [] { existingClaim }).Any()) { yield return(AddClaimForbideReason.OnlyOneCharacter); } } }
private void ShouldDisAllowMove(Claim claim, IClaimSource characterGroup, AddClaimForbideReason reason) { characterGroup.ValidateIfCanMoveClaim(claim).ShouldBe(new [] { reason }); }
private void ShouldAllowMove(Claim claim, IClaimSource characterGroup) { characterGroup.ValidateIfCanMoveClaim(claim).ShouldBeEmpty(); }
public static bool HasActiveClaims(this IClaimSource target) { return(target.Claims.Any(claim => claim.ClaimStatus.IsActive())); }
private void ShouldBeAllowed(IClaimSource mockCharacter) => mockCharacter.ValidateIfCanAddClaim(Mock.Player.UserId).ShouldBeEmpty();
public static IReadOnlyCollection <AddClaimForbideReason> ValidateIfCanMoveClaim(this IClaimSource claimSource, Claim claim) { return(ValidateImpl(claimSource, claim.PlayerUserId, claim).ToList()); }
public static bool IsPartOfGroup(this IClaimSource claimSource, int characterGroupId) { //TODO we can do faster than this return(claimSource.GetGroupsPartOf().Any(g => g.CharacterGroupId == characterGroupId)); }
protected static IEnumerable <ClaimProblem> CheckFields(IEnumerable <FieldWithValue> fieldsToCheck, IClaimSource target) { return(fieldsToCheck.SelectMany(fieldWithValue => CheckField(target, fieldWithValue))); }
public static bool IsNpc(this IClaimSource target) { return((target as Character)?.IsAcceptingClaims == false); }
private void ShouldBeNotAllowed(IClaimSource claimSource, AddClaimForbideReason reason) => claimSource.ValidateIfCanAddClaim(Mock.Player.UserId).ShouldContain(reason);
public static bool IsPartOfAnyOfGroups(this IClaimSource claimSource, IEnumerable <CharacterGroup> groups) { //TODO we can do faster than this return(claimSource.GetGroupsPartOf().Intersect(groups).Any()); }