public void MoveWorkStep(WorkStep stepToMove, WorkStep toStep)
        {
            if(stepToMove.WorkItemClass!=toStep.WorkItemClass)
            {
                throw new InvalidOperationException("Cannot move work step. Work item classes are not compatible");
            }

            var siblings = _workflowRepository.GetChildWorkSteps(toStep.Path);
            if(siblings.Where(ws=>ws.Ordinal==stepToMove.Ordinal).Count()>0)
            {
                throw new InvalidOperationException("Cannot move work step. Conflicting ordinals");
            }

            if(_workflowRepository.IsWithinTransientStep(stepToMove))
            {
                throw new InvalidOperationException("Cannot move transient work step or step within transient work step");
            }

            var commonRoot = WorkflowPath.FindCommonRoot(stepToMove.Path, toStep.Path);

            foreach (var path in WorkflowPath.GetPathsBetween(commonRoot,stepToMove.Path))
            {
                if(path==commonRoot || path==stepToMove.Path)
                {
                    continue;
                }

                if(_workflowRepository.GetWorkStep(path).Type==WorkStepType.Expand)
                {
                    throw new InvalidOperationException("Cannot move work step within expand step outside expand step");
                }

                if (_workflowRepository.GetWorkStep(path).Type == WorkStepType.Parallel)
                {
                    throw new InvalidOperationException("Cannot move work step within expand step outside parallel step");
                }

            }

            var wipLimitChecker = new WipLimitChecker(_workflowRepository);

            if(!wipLimitChecker.CanAcceptWorkStep(toStep,stepToMove))
            {
                throw new InvalidOperationException("Cannot move work step when WIP limit of new ancestors are violated");
            }

            MoveWorkStepRecursively(stepToMove, toStep);
        }
 public WorkItemMover(IWorkflowRepository workflowRepository, ITimeSource timeSource)
     : base(workflowRepository)
 {
     _timeSource = timeSource;
     WipLimitChecker = new WipLimitChecker(workflowRepository);
 }
 public void Init()
 {
     _workStepRepository = new MemoryWorkStepRepository();
     _workItemRepository = new MemoryWorkItemRepository();
     _wipLimit           = new WipLimitChecker(_workStepRepository, _workItemRepository);
 }
 public void Init()
 {
     _workStepRepository = new MemoryWorkStepRepository();
     _workItemRepository = new MemoryWorkItemRepository();
     _wipLimit = new WipLimitChecker(_workStepRepository,_workItemRepository);
 }
 private void ThrowIfUpdatingWipLimitAndWipLimitIsViolated(WorkStep currentWorkStep, WorkStep workStepUpdate)
 {
     if(workStepUpdate.WipLimit!=null && (!currentWorkStep.WipLimit.HasValue || workStepUpdate.WipLimit!=currentWorkStep.WipLimit))
     {
         var checker = new WipLimitChecker(WorkflowRepository);
         if(checker.CountWip(currentWorkStep)>workStepUpdate.WipLimit)
         {
             throw new InvalidOperationException("Cannot update wip limit below current work in process");
         }
     }
 }