public async Task <IList <IssueDTO> > GetAll(ObjectId issueId, bool recursive)
        {
            var issue = await _issueRepository.GetAsync(issueId);

            if (issue == null)
            {
                throw new HttpStatusException(StatusCodes.Status400BadRequest, $"Issue {issueId} does not exist");
            }

            //TODO Field can be null because DB was not cleared yet
            if (issue.ChildrenIssueIds == null)
            {
                return(new List <IssueDTO>());
            }

            IList <Issue> children;

            if (recursive)
            {
                children = await _issueHelper.GetChildrenRecursive(issue);
            }
            else
            {
                children = await Task.WhenAll(issue.ChildrenIssueIds.Select(it => _issueRepository.GetAsync(it)));
            }
            if (await _authorizationService.HasAtLeastOneRequirement(_httpContextAccessor.HttpContext.User,
                                                                     await _projectRepository.GetAsync(issue.ProjectId), ProjectRolesRequirement.CustomerRequirement))
            {
                children = children.Where(it => it.IssueDetail.Visibility).ToList();
            }

            return(await Task.WhenAll(children.Select(it => _issueService.Get(it.Id))));
        }
Пример #2
0
        public void RegisterFsmEvents()
        {
            Func <Issue, StateDTO, StateDTO, Task <StateDTO> > moveToProcessingPhase = async(Issue issue, StateDTO oldState, StateDTO newState) =>
            {
                if (oldState.Phase == State.NegotiationPhase && newState.Phase == State.ProcessingPhase)
                {
                    if (!issue.IssueDetail.RequirementsAccepted)
                    {
                        throw new HttpStatusException(400,
                                                      "An issue can only be moved from negotiation phase to processing phase if the requirements are accepted");
                    }
                }
                //Das Issue wird in Waiting gesetzt wenn das Startdatum noch nicht erreicht ist
                if (issue.IssueDetail.StartDate > DateTime.Now)
                {
                    var waitingState = await GetStateByName(issue, State.WaitingState);

                    return(await SetState(issue, waitingState));
                }

                Task <Issue> parent = null;
                if (issue.ParentIssueId is { } parentId)
                {
                    parent = _issueRepository.GetAsync(parentId);
                }
                var predecessors = Task.WhenAll(issue.PredecessorIssueIds.Select(_issueRepository.GetAsync));


                Task <StateDTO> parentState = null;
                if (parent is { } parentNotNull)
                {
                    parentState = _stateService.GetState((await parentNotNull).ProjectId, (await parentNotNull).StateId);
                }
                var predecessorStates = await Task.WhenAll((await predecessors).Select(it => _stateService.GetState(it.ProjectId, it.StateId)));

                /*
                 * Issue wird blockiert wenn:
                 * 1) Das Oberticket nicht in der Bearbeitungsphase ist
                 * 2) Nicht alle Vorgänger abgeschlossen sind
                 *
                 */
                if (parentState != null && ((await parentState).Phase == State.NegotiationPhase ||
                                            (await parentState).Phase == State.BlockedState ||
                                            (await parentState).Phase == State.WaitingState) ||
                    predecessorStates.HasWhere(it => it.Phase != State.ConclusionPhase))
                {
                    var blockedState = await GetStateByName(issue, State.BlockedState);

                    return(await SetState(issue, blockedState));
                }

                var res = await SetState(issue, newState);
                await OnIssueReachedProcessingPhase(issue);

                return(res);
            };

            _updateStateHandler.AddEvent(
                new FsmEvent <Func <Issue, StateDTO, StateDTO, Task <StateDTO> > > //CheckingState -> NegotiationState
            {
                OldState = State.CheckingState,
                NewState = State.NegotiationState,
                Func     = async(issue, oldState, newState) => await SetState(issue, newState)
            });
            _updateStateHandler.AddEvent(
                new FsmEvent <Func <Issue, StateDTO, StateDTO, Task <StateDTO> > > //NegotiationState -> ProcessingState
            {
                OldState = State.NegotiationState,
                NewState = State.ProcessingState,
                Func     = moveToProcessingPhase
            });
            _updateStateHandler.AddEvent(new FsmEvent <Func <Issue, StateDTO, StateDTO, Task <StateDTO> > > //BlockedState -> ProcessingState
            {
                OldState = State.BlockedState,
                NewState = State.ProcessingState,
                Func     = moveToProcessingPhase
            });
            _updateStateHandler.AddEvent(new FsmEvent <Func <Issue, StateDTO, StateDTO, Task <StateDTO> > > //WaitingState -> ProcessingState
            {
                OldState = State.WaitingState,
                NewState = State.ProcessingState,
                Func     = moveToProcessingPhase
            });
            _updateStateHandler.AddEvent(new FsmEvent <Func <Issue, StateDTO, StateDTO, Task <StateDTO> > > //Cancel Issue
            {
                OldState = "",
                NewState = State.CancelledState,
                Func     = async(issue, oldState, newState) =>
                {
                    //Cancels all children
                    await SetState(issue, newState);
                    var children = await _issueHelper.GetChildrenRecursive(issue);
                    await Task.WhenAll(children.Select(it => UpdateState(it, newState)));
                    await OnIssueReachedCompletionPhase(issue);
                    return(newState);
                }
            });
            _updateStateHandler.AddEvent(
                new FsmEvent <Func <Issue, StateDTO, StateDTO, Task <StateDTO> > > //ProcessingState -> ReviewState
            {
                OldState = State.ProcessingState,
                NewState = State.ReviewState,
                Func     = async(issue, oldState, newState) =>
                {
                    var children       = await Task.WhenAll(issue.ChildrenIssueIds.Select(_issueRepository.GetAsync));
                    var childrenStates = await Task.WhenAll(children.Select(it => _stateService.GetState(it.ProjectId, it.StateId)));
                    if (childrenStates.HasWhere(it => it.Phase != State.ConclusionPhase))
                    {
                        throw new HttpStatusException(400, "At least one sub issue is not in conclusion phase");
                    }
                    return(await SetState(issue, newState));
                }
            });
            _updateStateHandler.AddEvent(
                new FsmEvent <Func <Issue, StateDTO, StateDTO, Task <StateDTO> > > //ReviewState -> CompletedState
            {
                OldState = State.ReviewState,
                NewState = State.CompletedState,
                Func     = async(issue, oldState, newState) =>
                {
                    //TODO Projektleiter überprüft ticket
                    await SetState(issue, newState);
                    await OnIssueReachedCompletionPhase(issue);
                    return(newState);
                }
            });
            _updateStateHandler.AddEvent(
                new FsmEvent <Func <Issue, StateDTO, StateDTO, Task <StateDTO> > > //CompletedState -> ArchivedState
            {
                OldState = State.CompletedState,
                NewState = State.ArchivedState,
                Func     = async(issue, oldState, newState) =>
                {
                    //TODO Abschlusskommentar
                    await SetState(issue, newState);
                    await OnIssueReachedCompletionPhase(issue);
                    return(newState);
                }
            });
            _updateStateHandler.AddEvent(new FsmEvent <Func <Issue, StateDTO, StateDTO, Task <StateDTO> > >
            {
                OldState = State.ReviewState,
                NewState = State.ProcessingState,
                Func     = async(issue, oldState, newState) => await SetState(issue, newState)
            });
        }