Beispiel #1
0
        public static string GetIES(this KAction action)
        {
            string label = null;

            // Amélioration
            if (action.Reduced != null)
            {
                // Amélioration I/E/S

                if (ActionsTimingsMoveManagement.IsActionInternal(action))
                {
                    label = LocalizationManager.GetString("ViewModel_AnalyzeRestitution_Export_Action_Reduced_Internal");
                }
                else if (ActionsTimingsMoveManagement.IsActionExternal(action))
                {
                    label = LocalizationManager.GetString("ViewModel_AnalyzeRestitution_Export_Action_Reduced_External");
                }
                else if (ActionsTimingsMoveManagement.IsActionDeleted(action))
                {
                    label = LocalizationManager.GetString("ViewModel_AnalyzeRestitution_Export_Action_Reduced_Deleted");
                }
                else
                {
                    throw new ArgumentOutOfRangeException();
                }
            }

            return(label);
        }
Beispiel #2
0
        /// <summary>
        /// Calcule les temps critiques.
        /// </summary>
        /// <param name="actions">Les actions.</param>
        /// <returns>Les temps critiques.</returns>
        protected override CriticalAction[] CalculateCriticalTimes(IEnumerable <KAction> actions)
        {
            var actionTimings = ActionsTimingsMoveManagement.CreateActionTimings(actions, this.UseManagedPredecessorsSuccessors,
                                                                                 GetBuildStart, GetBuildFinish);

            return(ActionsTimingsMoveManagement.CalculateCriticalTimes(actionTimings));
        }
Beispiel #3
0
        /// <summary>
        /// Crée un nouvel élément représentant une action.
        /// </summary>
        /// <param name="action">L'action.</param>
        /// <returns>L'élément créé.</returns>
        protected override ActionGanttItem CreateNewActionItemImpl(KAction action)
        {
            ActionGanttItem item;

            if (this.IsViewByReferential())
            {
                item = new ActionGanttItem(action, WBSHelper.IndentationFromWBS(action.WBS) + 1);
            }
            else
            {
                item = new ActionGanttItem(action, WBSHelper.IndentationFromWBS(action.WBS));
            }

            item.CanResize = base.AllowTimingsDurationChange;

            Brush fillBrush, strokeBrush;

            GetActionBrushes(action, out fillBrush, out strokeBrush);

            item.FillBrush              = fillBrush;
            item.StrokeBrush            = strokeBrush;
            item.OrangeHeaderVisibility = ActionsTimingsMoveManagement.IsActionExternal(action) ? Visibility.Visible : Visibility.Collapsed;
            item.OrangeHeaderToolTip    = LocalizationManager.GetString("VM_ActionManager_ExternalToolTip");
            item.GreenHeaderToolTip     = LocalizationManager.GetString("VM_ActionManager_NewToolTip");

            return(item);
        }
Beispiel #4
0
        /// <summary>
        /// Appelé lorsque un type de réduction (IES) a été appliqué sur une action.
        /// </summary>
        /// <param name="action">L'action.</param>
        protected override void OnReducedTypeApplied(KAction action)
        {
            var item = this.ItemsOfTypeAction.FirstOrDefault(i => i.Action == action);

            if (item != null)
            {
                item.OrangeHeaderVisibility = ActionsTimingsMoveManagement.IsActionExternal(action) ? Visibility.Visible : Visibility.Collapsed;
            }
        }
Beispiel #5
0
        private void FixupImportedActions()
        {
            var sortedActions = _targetScenario.Actions.OrderBy(a => WBSHelper.GetParts(a.WBS), new WBSHelper.WBSComparer()).ToArray();

            ActionsTimingsMoveManagement.FixPredecessorsSuccessorsTimings(sortedActions, false);
            ActionsTimingsMoveManagement.UpdateVideoGroupsTiming(sortedActions);
            ActionsTimingsMoveManagement.UpdateBuildGroupsTiming(sortedActions);
            _targetScenario.CriticalPathIDuration = ActionsTimingsMoveManagement.GetInternalCriticalPathDuration(_targetScenario);

            ActionsTimingsMoveManagement.DebugCheckAllWBS(_targetScenario);
        }
Beispiel #6
0
 /// <summary>
 /// Appelé lorsque l'état de l'entité courante (spécifiée via RegisterToStateChanged) a changé.
 /// </summary>
 /// <param name="newState">le nouvel état.</param>
 protected override void OnEntityStateChanged(ObjectState newState)
 {
     CanChange &= newState == ObjectState.Unchanged;
     if (CurrentActionItem is ActionGanttItem actionGanttItem)
     {
         BrushesHelper.GetBrush(actionGanttItem.Action.Category?.Color, true, out Brush fillBrush, out Brush strokeBrush);
         actionGanttItem.FillBrush              = fillBrush;
         actionGanttItem.StrokeBrush            = strokeBrush;
         actionGanttItem.OrangeHeaderVisibility = ActionsTimingsMoveManagement.IsActionExternal(actionGanttItem.Action) ? Visibility.Visible : Visibility.Collapsed;
         ActionsManager.UpdateReductionDescription(actionGanttItem.Action, true);
     }
 }
Beispiel #7
0
        public void TestCanAddPredecessor()
        {
            var t1 = new KAction()
            {
                Label = "T1", WBS = "1"
            };
            var g1 = new KAction()
            {
                Label = "G1", WBS = "2"
            };
            var t2 = new KAction()
            {
                Label = "T2", WBS = "2.1"
            };
            var t3 = new KAction()
            {
                Label = "T3", WBS = "2.2"
            };
            var t4 = new KAction()
            {
                Label = "T4", WBS = "3"
            };
            var t5 = new KAction()
            {
                Label = "T5", WBS = "4"
            };

            var actions = new List <KAction>()
            {
                t1, g1, t2, t3, t4, t5
            };

            t3.Predecessors.Add(t1);
            t3.Predecessors.Add(t2);
            t4.Predecessors.Add(t3);
            t5.Predecessors.Add(t3);

            var collection = new BulkObservableCollection <DataTreeGridItem>();

            var manager = new GridActionsManager(collection, null, null);

            manager.ChangeView(GanttGridView.WBS, null);

            manager.RegisterInitialActions(actions);

            Assert.IsFalse(ActionsTimingsMoveManagement.CheckCanAddPredecessor(manager.GetActionsSortedByWBS(), t1, t1));
            Assert.IsFalse(ActionsTimingsMoveManagement.CheckCanAddPredecessor(manager.GetActionsSortedByWBS(), t1, t3));
            Assert.IsFalse(ActionsTimingsMoveManagement.CheckCanAddPredecessor(manager.GetActionsSortedByWBS(), g1, t3));

            Assert.IsTrue(ActionsTimingsMoveManagement.CheckCanAddPredecessor(manager.GetActionsSortedByWBS(), t4, t1));
            Assert.IsTrue(ActionsTimingsMoveManagement.CheckCanAddPredecessor(manager.GetActionsSortedByWBS(), t5, t1));
            Assert.IsTrue(ActionsTimingsMoveManagement.CheckCanAddPredecessor(manager.GetActionsSortedByWBS(), t2, t1));
        }
Beispiel #8
0
        public void Delete_Random_Consistency()
        {
            var random  = new Random();
            var testEnd = DateTime.Now.AddSeconds(30);

            while (DateTime.Now < testEnd)
            {
                var tasks          = new List <KAction>();
                var rootTasksCount = random.Next(10);

                var currentWbsParts = new Stack <int>();
                currentWbsParts.Push(0);

                PopulateRandom(random, tasks, currentWbsParts, 5, false);

                WriteTasksWBS(tasks);
                ActionsTimingsMoveManagement.DebugCheckAllWBS(tasks);
                if (CheckWBS(tasks) != null)
                {
                    throw new InvalidOperationException("Wrong generation");
                }

                while (tasks.Count > 0)
                {
                    var index         = random.Next(tasks.Count);
                    var countToDelete = Math.Min(random.Next(1, 10), tasks.Count);
                    var toDelete      = tasks[index];

                    var currentStatus = Clone(tasks).ToArray();

                    ActionsTimingsMoveManagement.DeleteUpdateWBS(tasks.ToArray(), toDelete);
                    tasks.Remove(toDelete);

                    TestContext.WriteLine("Deleted: {0} {1}.", toDelete.WBS, toDelete.Label);

                    var wrongWbs = CheckWBS(tasks);
                    if (wrongWbs != null)
                    {
                        // Rappeler l'état d'origine et l'élément supprimé
                        TestContext.WriteLine("Fail!");
                        TestContext.WriteLine("--- Before deletion, indented format:");
                        WriteTasksWBS(currentStatus);
                        TestContext.WriteLine("--- Before deletion, appended format: {0}", string.Join(" ", currentStatus.Select(t => t.WBS)));
                        TestContext.WriteLine("--- Deleted element {0} {1}", toDelete.WBS, toDelete.Label);
                        TestContext.WriteLine("--- After deletion, indented format:");
                        WriteTasksWBS(tasks);

                        Assert.Fail("The WBS {0} is invalid", wrongWbs);
                    }
                    ActionsTimingsMoveManagement.DebugCheckAllWBS(tasks);
                }
            }
        }
Beispiel #9
0
        /// <summary>
        /// Met à jour le début, la durée et la fin sur les éléments de groupe
        /// </summary>
        protected override void UpdateBuildGroupsTiming()
        {
            if (!EnableGroupsTimingCoercion || (!AllowTimingsChange && !_useGanttItemsTimingsOnly) || _isUpdatingGroupsTimings)
            {
                return;
            }

            _isUpdatingGroupsTimings = true;
            ActionsTimingsMoveManagement.UpdateBuildGroupsTiming(GetActionsSortedByWBS(),
                                                                 GetBuildStart, GetBuildFinish, SetBuildStart, SetBuildFinish);
            _isUpdatingGroupsTimings = false;
        }
Beispiel #10
0
        /// <summary>
        /// Détermine si un lien peut être ajouté.
        /// </summary>
        /// <param name="item">L'élément.</param>
        /// <param name="predecessor">Le prédécesseur.</param>
        /// <returns><c>true</c> si le lien peut être ajouté.</returns>
        public bool DependencyCreationValidatorProvider(GanttChartItem item, GanttChartItem predecessor)
        {
            if (!DefaultDependencyCreationValidatorProvider(item, predecessor))
            {
                return(false);
            }

            var actionItem      = item as ActionGanttItem;
            var predecessorItem = predecessor as ActionGanttItem;

            if (actionItem == null || predecessorItem == null)
            {
                return(false);
            }

            return(ActionsTimingsMoveManagement.CheckCanAddPredecessor(base.GetActionsSortedByWBS(), actionItem.Action, predecessorItem.Action));
        }
Beispiel #11
0
        /// <summary>
        /// Corrige les temps en fonction des prédécesseurs et successeurs de chaque action.
        /// </summary>
        public override void FixPredecessorsSuccessorsTimings()
        {
            if (!EnablePredecessorTimingFix || (!AllowTimingsChange && !_useGanttItemsTimingsOnly) || IsFixingPredecessorsSuccessorsTiming)
            {
                return;
            }

            IsFixingPredecessorsSuccessorsTiming = true;
            ActionsTimingsMoveManagement.FixPredecessorsSuccessorsTimings(
                GetActionsSortedByWBS(),
                this.UseManagedPredecessorsSuccessors,
                this.GetBuildStart,
                this.GetBuildFinish,
                this.SetBuildStart,
                this.SetBuildFinish);
            IsFixingPredecessorsSuccessorsTiming = false;

            this.UpdateBuildGroupsTiming();
            this.UpdateCriticalPath();
        }
Beispiel #12
0
        public void FixPredecessorsSuccessorsTimings_Outside_Of_CriticalPath()
        {
            // Création de 3 tâches successives

            // Voilà une représentation des tâches
            // -- T1
            //   -- T2
            //     -- T3
            //   - T4

            // Et les précédesseurs :
            // T3 -> T2 -> T1,
            // T3 -> T4 -> T1

            // Le test va consister à supprimer T2
            // Quand on le supprime, T3 devrait se décaller de 1 vers la droite que correspondre au précédesseur T4

            var t1 = CreateAction("1", 2);
            var t2 = CreateAction("2", 2, t1);
            var t4 = CreateAction("4", 1, t1);
            var t3 = CreateAction("3", 2, t2, t4);

            var actions = new KAction[] { t1, t2, t3, t4 };

            ActionsTimingsMoveManagement.FixPredecessorsSuccessorsTimings(actions, false);

            // On vérifie que le temps process a bien été modifié
            Assert.AreEqual(4, t3.BuildStart);
            Assert.AreEqual(6, t3.BuildFinish);

            // On supprime t2
            t3.Predecessors.Remove(t2);
            actions = new KAction[] { t1, t3, t4 };

            ActionsTimingsMoveManagement.FixPredecessorsSuccessorsTimings(actions, false);

            // On vérifie que le temps process a bien été modifié
            Assert.AreEqual(3, t3.BuildStart);
            Assert.AreEqual(5, t3.BuildFinish);
        }
Beispiel #13
0
        private void ImportActions()
        {
            // Trier les actions par WBS
            _actions = _import.ExportedVideoDecomposition.Actions.OrderBy(a => WBSHelper.GetParts(a.WBS), new WBSHelper.WBSComparer()).ToArray();

            // Actions
            var parents = new Dictionary <KAction, KAction>();

            // Faire une liste des parents
            foreach (var action in _actions)
            {
                var parent = WBSHelper.GetParent(action, _actions);
                if (parent != null)
                {
                    parents[action] = parent;
                }
            }

            foreach (var action in _actions)
            {
                action.ActionId = default(int);

                action.OriginalActionId = null;
                SharedScenarioActionsOperations.ApplyNewReduced(action, KnownActionCategoryTypes.I);

                // Réinitialiser les timings
                // Ils seront ensuite automatiquement recalculés en fonction des pred/succ
                action.BuildStart    = 0;
                action.BuildDuration = action.Duration;

                var parent = parents.ContainsKey(action) ? parents[action] : null;

                ActionsTimingsMoveManagement.InsertUpdateWBS(_targetScenario.Actions.ToArray(), action, parent, -1);
                _targetScenario.Actions.Add(action);
            }
        }
Beispiel #14
0
        /// <summary>
        /// Sauvegarde le scénario spécifié.
        /// </summary>
        /// <param name="context">Le contexte EF.</param>
        /// <param name="allScenarios">Tous les scénarios liés.</param>
        /// <param name="recursive"><c>true</c> pour appliquer les changements récursivement sur les scénarios dérivés.</param>
        public static Task SaveBuildScenario(KsmedEntities context, Scenario[] allScenarios, Scenario updatedScenario, bool recursive)
        {
            // Consolider les solutions
            string[] distinctSolutionsLabels = updatedScenario.Actions
                                               .Where(a => a.IsReduced && !string.IsNullOrWhiteSpace(a.Reduced.Solution))
                                               .Select(a => a.Reduced.Solution)
                                               .Distinct()
                                               .ToArray();

            // Ajouter les nouvelles solutions
            foreach (string solutionLabel in distinctSolutionsLabels)
            {
                if (!updatedScenario.Solutions.Any(s => s.SolutionDescription == solutionLabel))
                {
                    // Créer une nouvelle solution
                    Solution solution = new Solution()
                    {
                        SolutionDescription = solutionLabel,
                    };
                    updatedScenario.Solutions.Add(solution);
                }
            }

            EnsureEmptySolutionExists(updatedScenario);

            // Supprimer les anciennes solutions
            Solution[] allSolutions = updatedScenario.Solutions.Where(s => !s.IsEmpty).ToArray();
            foreach (Solution sol in allSolutions)
            {
                if (!distinctSolutionsLabels.Contains(sol.SolutionDescription))
                {
                    sol.MarkAsDeleted();
                    updatedScenario.Solutions.Remove(sol);
                }
            }

            // Copier le temps original
            foreach (KActionReduced reduced in updatedScenario.Actions
                     .Where(a => a.IsReduced)
                     .Select(a => a.Reduced)
                     .Where(r => r.OriginalBuildDuration == default(long)))
            {
                reduced.OriginalBuildDuration = reduced.Action.BuildDuration;
            }

            // Appliquer l'état Approved
            UdpateSolutionsApprovedState(updatedScenario);

            ActionsRecursiveUpdate.UpdateActions(context, updatedScenario, allScenarios, out KAction[] actionsToDelete, out IList <KAction> actionsWithOriginal);

            KAction[] allActions = allScenarios
                                   .SelectMany(s => s.Actions)
                                   .Where(a => a.IsNotMarkedAsUnchanged || (a.IsReduced && a.Reduced.IsNotMarkedAsUnchanged))
                                   .ToArray();

            foreach (KAction action in allActions)
            {
                context.KActions.ApplyChanges(action);
                if (action.IsReduced)
                {
                    context.KActionsReduced.ApplyChanges(action.Reduced);
                }
            }

            foreach (KAction action in actionsWithOriginal)
            {
                SetActionsOriginalReference(context, action);
            }


            foreach (Scenario scenario in allScenarios.Where(s => s.IsNotMarkedAsUnchanged))
            {
                context.Scenarios.ApplyChanges(scenario);
            }

            foreach (Solution solution in updatedScenario.Solutions)
            {
                context.Solutions.ApplyChanges(solution);
            }

            // Vérifier que tout est correct
            ActionsTimingsMoveManagement.DebugCheckAllWBS(allScenarios.Where(s => s.IsNotMarkedAsUnchanged));

            return(context.SaveChangesAsync());
        }
Beispiel #15
0
        /// <summary>
        /// Sauvegarde les actions spécifiées.
        /// </summary>
        /// <param name="context">Le contexte.</param>
        /// <param name="allScenarios">Tous les scénarios liés.</param>
        /// <param name="updatedScenario">Le scénario qui a été mis à jour.</param>
        /// <param name="recursive"><c>true</c> pour appliquer les changements récursivement sur les scénarios dérivés.</param>
        public static Task SaveAcquireData(KsmedEntities context, Scenario[] allScenarios, Scenario updatedScenario, bool recursive)
        {
            KAction[]       actionsToDelete;
            IList <KAction> actionsWithOriginal;

            if (recursive)
            {
                ActionsRecursiveUpdate.UpdateActions(context, updatedScenario, allScenarios, out actionsToDelete, out actionsWithOriginal);
            }
            else
            {
                actionsWithOriginal = null;
                actionsToDelete     = updatedScenario.Actions.Where(a => a.IsMarkedAsDeleted).ToArray();
                updatedScenario.CriticalPathIDuration = ActionsTimingsMoveManagement.GetInternalCriticalPathDuration(updatedScenario);
            }

            // Consolider les solutions vides
            EnsureEmptySolutionExists(updatedScenario);
            UdpateSolutionsApprovedState(updatedScenario);

            KAction[] allActions = allScenarios
                                   .SelectMany(s => s.Actions)
                                   .Where(a => a.IsNotMarkedAsUnchanged)
                                   .ToArray();

            foreach (KAction action in allActions)
            {
                if (!action.IsReduced)
                {
                    ApplyNewReduced(action, KnownActionCategoryTypes.I);
                }
                context.KActions.ApplyChanges(action);
                context.KActionsReduced.ApplyChanges(action.Reduced);
            }

            if (actionsWithOriginal != null)
            {
                foreach (KAction action in actionsWithOriginal)
                {
                    SetActionsOriginalReference(context, action);
                }
            }

            foreach (Scenario scenario in allScenarios.Where(s => s.IsNotMarkedAsUnchanged))
            {
                context.Scenarios.ApplyChanges(scenario);
            }

            context.Scenarios.ApplyChanges(updatedScenario);

            foreach (KAction action in actionsToDelete)
            {
                action.Predecessors.Clear();
                action.Successors.Clear();
                action.MarkAsDeleted();

                // Ne pas appeler ApplyChanges car les self tracking le gèrent mal (plantage lors de la sauvegarde)
                // Ajouter l'action au contexte si elle n'y est pas attachée
                if (!context.ObjectStateManager.TryGetObjectStateEntry(action, out ObjectStateEntry entry))
                {
                    context.AddObject(KsmedEntities.KActionsEntitySetName, action);
                    context.ObjectStateManager.ChangeObjectState(action, EntityState.Deleted);
                }
                else
                {
                    context.KActions.DeleteObject(action);
                }
            }

            // Vérifier que tout est correct
            if (recursive)
            {
                ActionsTimingsMoveManagement.DebugCheckAllWBS(allScenarios.Where(s => s.IsNotMarkedAsUnchanged));
            }

            return(context.SaveChangesAsync());
        }
Beispiel #16
0
        /// <summary>
        /// Sauvegarde les actions spécifiées.
        /// </summary>
        /// <param name="context">Le contexte.</param>
        /// <param name="allScenarios">Tous les scénarios liés.</param>
        /// <param name="updatedScenario">Le scénario qui a été mis à jour.</param>
        /// <param name="recursive"><c>true</c> pour appliquer les changements récursivement sur les scénarios dérivés.</param>
        public async Task <Scenario> SaveAcquireData(KsmedEntities context, Scenario[] allScenarios, Scenario updatedScenario, bool recursive)
        {
            try
            {
                // Don't insert a thumbnail that already exists
                var actionsWithNewThumbnail = updatedScenario.Actions.Where(_ =>
                                                                            (_.IsMarkedAsAdded && _.Thumbnail != null) ||
                                                                            (_.IsMarkedAsModified && _.ChangeTracker.ModifiedValues.ContainsKey(nameof(KAction.Thumbnail)) && _.Thumbnail != null));
                foreach (var action in actionsWithNewThumbnail)
                {
                    CloudFile thumbnail = updatedScenario.Actions.Where(_ => _.Thumbnail != null && _.ActionId != action.ActionId).Select(_ => _.Thumbnail).FirstOrDefault(_ => _.Hash == action.ThumbnailHash);
                    if (thumbnail == null)
                    {
                        thumbnail = await context.CloudFiles.SingleOrDefaultAsync(_ => _.Hash == action.Thumbnail.Hash);
                    }
                    if (thumbnail != null)
                    {
                        action.Thumbnail = thumbnail;
                    }
                }

                KAction[]       actionsToDelete;
                IList <KAction> actionsWithOriginal;

                if (recursive)
                {
                    ActionsRecursiveUpdate.UpdateActions(context, updatedScenario, allScenarios, out actionsToDelete, out actionsWithOriginal);
                }
                else
                {
                    actionsWithOriginal = null;
                    actionsToDelete     = updatedScenario.Actions.Where(a => a.IsMarkedAsDeleted).ToArray();
                    updatedScenario.CriticalPathIDuration = ActionsTimingsMoveManagement.GetInternalCriticalPathDuration(updatedScenario);
                }

                // Consolider les solutions vides
                EnsureEmptySolutionExists(updatedScenario);
                UdpateSolutionsApprovedState(updatedScenario);

                // Update InheritedAction if original will be deleted
                var actionIdsToDelete = actionsToDelete.Select(_ => _.ActionId).ToList();
                var inheritedActions  = await context.KActions
                                        .Where(_ => _.OriginalActionId != null && actionIdsToDelete.Contains(_.OriginalActionId.Value))
                                        .ToListAsync();

                foreach (var inheritedAction in inheritedActions)
                {
                    inheritedAction.OriginalActionId = null;
                    context.KActions.ApplyChanges(inheritedAction);
                }

                KAction[] allActions = allScenarios
                                       .SelectMany(s => s.Actions)
                                       .Where(a => a.IsNotMarkedAsUnchanged)
                                       .ToArray();

                foreach (KAction action in allActions)
                {
                    if (!action.IsReduced)
                    {
                        ApplyNewReduced(action, KnownActionCategoryTypes.I);
                    }
                    context.KActions.ApplyChanges(action);
                    context.KActionsReduced.ApplyChanges(action.Reduced);
                }

                if (actionsWithOriginal != null)
                {
                    foreach (KAction action in actionsWithOriginal)
                    {
                        SetActionsOriginalReference(context, action);
                    }
                }

                foreach (Scenario scenario in allScenarios.Where(s => s.IsNotMarkedAsUnchanged))
                {
                    context.Scenarios.ApplyChanges(scenario);
                }

                context.Scenarios.ApplyChanges(updatedScenario);

                foreach (KAction action in actionsToDelete)
                {
                    action.Predecessors.Clear();
                    action.Successors.Clear();
                    action.MarkAsDeleted();

                    // Ne pas appeler ApplyChanges car les self tracking le gèrent mal (plantage lors de la sauvegarde)
                    // Ajouter l'action au contexte si elle n'y est pas attachée
                    if (!context.ObjectStateManager.TryGetObjectStateEntry(action, out ObjectStateEntry entry))
                    {
                        context.AddObject(KsmedEntities.KActionsEntitySetName, action);
                        context.ObjectStateManager.ChangeObjectState(action, EntityState.Deleted);
                    }
                    else
                    {
                        context.KActions.DeleteObject(action);
                    }
                }

                // Vérifier que tout est correct
                if (recursive)
                {
                    ActionsTimingsMoveManagement.DebugCheckAllWBS(allScenarios.Where(s => s.IsNotMarkedAsUnchanged));
                }

                await context.SaveChangesAsync();

                return(updatedScenario);
            }
            catch (Exception ex)
            {
                TraceManager.TraceError(ex, $"Error while saving scenario {updatedScenario.ScenarioId}");
                throw;
            }
        }
Beispiel #17
0
        /// <summary>
        /// Crée un scénario cible à partir d'un autre scénario, initial ou cible.
        /// </summary>
        /// <param name="context">Le contexte.</param>
        /// <param name="sourceScenario">Le scenario source.</param>
        /// <param name="natureCode">Le code de la nature.</param>
        /// <param name="save"><c>true</c> pour sauvegarder le scénario créé.</param>
        /// <param name="targetNumber">Le numéro cible.</param>
        /// <returns>
        /// Le scénario créé
        /// </returns>
        public static async Task <Scenario> CreateDerivatedScenario(KsmedEntities context, Scenario sourceScenario, string natureCode, bool save, int targetNumber)
        {
            // Charger les données du scénario source
            var newScenario = new Scenario();

            ActionCloneBehavior cloneBehavior;

            if (sourceScenario.NatureCode == KnownScenarioNatures.Initial && natureCode == KnownScenarioNatures.Target)
            {
                cloneBehavior = ActionCloneBehavior.InitialToTarget;
            }
            else if (sourceScenario.NatureCode == KnownScenarioNatures.Target && natureCode == KnownScenarioNatures.Target)
            {
                cloneBehavior = ActionCloneBehavior.TargetToTarget;
            }
            else if (sourceScenario.NatureCode == KnownScenarioNatures.Target && natureCode == KnownScenarioNatures.Realized)
            {
                cloneBehavior = ActionCloneBehavior.TargetToRealized;
            }
            else if (sourceScenario.NatureCode == KnownScenarioNatures.Realized && natureCode == KnownScenarioNatures.Initial)
            {
                cloneBehavior = ActionCloneBehavior.RealizedToNewInitial;
            }
            else if (sourceScenario.NatureCode == KnownScenarioNatures.Target && natureCode == KnownScenarioNatures.Initial)
            {
                cloneBehavior = ActionCloneBehavior.TargetToNewInitial;
            }
            else if (sourceScenario.NatureCode == KnownScenarioNatures.Initial && natureCode == KnownScenarioNatures.Initial)
            {
                cloneBehavior = ActionCloneBehavior.InitialToNewInitial;
            }
            else
            {
                throw new InvalidOperationException("Conversion impossible pour ces scénarios");
            }
            switch (natureCode)
            {
            case KnownScenarioNatures.Target:
                newScenario.Label = LocalizationManager.GetString("Business_AnalyzeService_TargetScenarioLabel") + " " + targetNumber;
                break;

            case KnownScenarioNatures.Realized:
                newScenario.Label = LocalizationManager.GetString("Business_AnalyzeService_ValidationScenarioLabel");
                break;

            case KnownScenarioNatures.Initial:
                newScenario.Label = LocalizationManager.GetString("Business_AnalyzeService_InitialScenarioLabel");
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(natureCode));
            }

            newScenario.StateCode  = KnownScenarioStates.Draft;
            newScenario.NatureCode = natureCode;
            if (cloneBehavior != ActionCloneBehavior.RealizedToNewInitial &&
                cloneBehavior != ActionCloneBehavior.TargetToNewInitial &&
                cloneBehavior != ActionCloneBehavior.InitialToNewInitial)
            {
                newScenario.ProjectId          = sourceScenario.ProjectId;
                newScenario.Original           = sourceScenario;
                newScenario.OriginalScenarioId = sourceScenario.ScenarioId;
            }
            newScenario.IsShownInSummary      = true;
            newScenario.CriticalPathIDuration = sourceScenario.CriticalPathIDuration;

            string[] scenarioLAbels = await EnsureCanShowScenarioInSummary(newScenario, true);

            // Copier toutes les actions
            foreach (var action in sourceScenario.Actions.ToArray())
            {
                var newAction = CloneAction(action, cloneBehavior);

                newAction.OriginalActionId = action.ActionId;
                newAction.Original         = action;
                if (newAction.Reduced != null)
                {
                    newAction.Reduced.OriginalBuildDuration = action.BuildDuration;
                }

                // S'il s'agit d'un scénario validé, utiliser les temps process en tant que temps vidéo
                if (cloneBehavior == ActionCloneBehavior.TargetToRealized)
                {
                    newAction.Start  = newAction.BuildStart;
                    newAction.Finish = newAction.BuildFinish;
                }

                newScenario.Actions.Add(newAction);
            }

            SharedScenarioActionsOperations.EnsureEmptySolutionExists(newScenario);
            SharedScenarioActionsOperations.UdpateSolutionsApprovedState(newScenario);

            // Copier les liens prédécesseurs successeurs
            foreach (var action in sourceScenario.Actions.ToArray())
            {
                var newAction = newScenario.Actions.FirstOrDefault(a => a.OriginalActionId == action.ActionId);
                if (newAction != null)
                {
                    foreach (var predecessor in action.Predecessors)
                    {
                        var newPredecessor = newScenario.Actions.FirstOrDefault(a => a.OriginalActionId == predecessor.ActionId);
                        if (newPredecessor != null)
                        {
                            newAction.Predecessors.Add(newPredecessor);
                        }
                    }
                }
            }

            //Suppression des actions avec durée = 0
            if (cloneBehavior == ActionCloneBehavior.TargetToRealized || cloneBehavior == ActionCloneBehavior.TargetToTarget)
            {
                ActionsRecursiveUpdate.RemoveEmptyDurationActionsAndGroupsFromNewScenario(newScenario);
            }

            if (cloneBehavior != ActionCloneBehavior.TargetToRealized &&        // ToDelete ne s'applique pas aux scenarios validés
                cloneBehavior != ActionCloneBehavior.InitialToNewInitial &&     // ToDelete ne s'applique pas aux scenarios initiaux
                cloneBehavior != ActionCloneBehavior.TargetToNewInitial &&      // ToDelete ne s'applique pas aux scenarios initiaux
                cloneBehavior != ActionCloneBehavior.RealizedToNewInitial)      // ToDelete ne s'applique pas aux scenarios initiaux
            {
                foreach (var newAction in newScenario.Actions)
                {
                    // Si la category associée est dite "à supprimer", modifier la tache optimisée à "à supprimer"
                    if (newAction.Category != null && newAction.Category.ActionTypeCode == KnownActionCategoryTypes.S)
                    {
                        SharedScenarioActionsOperations.ApplyNewReduced(newAction, KnownActionCategoryTypes.S);
                    }
                }
            }

            if (save)
            {
                context.Scenarios.ApplyChanges(newScenario);
                await context.SaveChangesAsync();
            }

            ActionsTimingsMoveManagement.FixPredecessorsSuccessorsTimings(newScenario.Actions.ToArray(), false);
            ActionsTimingsMoveManagement.UpdateVideoGroupsTiming(newScenario.Actions.ToArray());
            ActionsTimingsMoveManagement.UpdateBuildGroupsTiming(newScenario.Actions.ToArray());
            newScenario.CriticalPathIDuration = ActionsTimingsMoveManagement.GetInternalCriticalPathDuration(newScenario);

            // Supprimer les liens vers les originaux car dans un autre projet
            if (cloneBehavior == ActionCloneBehavior.RealizedToNewInitial ||
                cloneBehavior == ActionCloneBehavior.TargetToNewInitial ||
                cloneBehavior == ActionCloneBehavior.InitialToNewInitial)
            {
                foreach (var action in newScenario.Actions)
                {
                    action.Original         = null;
                    action.OriginalActionId = null;
                }

                newScenario.Original           = null;
                newScenario.OriginalScenarioId = null;
            }

            return(newScenario);
        }
Beispiel #18
0
        /// <summary>
        /// Clone une action pour qu'elle soit utilisée dans un nouveau scénario.
        /// </summary>
        /// <param name="action">The action.</param>
        /// <param name="cloneBehavior">The clone behavior.</param>
        /// <returns></returns>
        public static KAction CloneAction(KAction action, ActionCloneBehavior cloneBehavior)
        {
            var newAction = new KAction();

            var originalValues = action.GetCurrentValues();

            // Ignorer certaines propriétés
            var excludedPropertyNames = new List <string> {
                "ActionId", "ScenarioId", "OriginalActionId", "Predecessors", "Successors", "Reduced"
            };

            // Quand on passe vers un scénario de validation, il ne faut pas copier la vignette car on supprime les leins avec les vidéos
            if (cloneBehavior == ActionCloneBehavior.TargetToRealized)
            {
                excludedPropertyNames.Add("Thumbnail");
                excludedPropertyNames.Add("IsThumbnailSpecific");
                excludedPropertyNames.Add("ThumbnailPosition");
            }

            // Vérifier que ces noms de propriétés soient corrects
            if (excludedPropertyNames.Except(originalValues.Keys).Any())
            {
                throw new InvalidOperationException("Les noms de propriétés présents dans excludedPropertyNames ne sont pas valides.");
            }

            foreach (var kvp in originalValues)
            {
                if (!excludedPropertyNames.Contains(kvp.Key))
                {
                    newAction.SetPropertyValue(kvp.Key, kvp.Value);
                }
            }

            // Copier les liens actions / référentiel
            CloneReferentialActionsLinks(action, newAction);

            // Copier la partie Reduced
            switch (cloneBehavior)
            {
            case ActionCloneBehavior.InitialToTarget:
            {
                // S'il existe un prétypage par la catégorie, il est prioritaire. Sinon, utiliser celui sur l'action s'il y en a.
                string actionTypeCode;

                if (action.Category != null && action.Category.ActionTypeCode != null)
                {
                    actionTypeCode = action.Category.ActionTypeCode;
                }
                else
                {
                    actionTypeCode = action.IsReduced ? action.Reduced.ActionTypeCode : KnownActionCategoryTypes.I;
                }

                SharedScenarioActionsOperations.ApplyNewReduced(newAction, actionTypeCode);
            }
            break;

            case ActionCloneBehavior.TargetToTarget:

                if (action.Reduced.ActionTypeCode == null)
                {
                    throw new InvalidOperationException("Une action cible doit toujours être réduite avec un type");
                }

                if (!ActionsTimingsMoveManagement.GetIsSolutionApproved(action).GetValueOrDefault(true))
                {
                    // Tache I provenant du grand parent, on n'applique pas le prétype mais on applique la réduc
                    SharedScenarioActionsOperations.ApplyNewReduced(newAction, KnownActionCategoryTypes.I);
                }
                else
                {
                    switch (action.Reduced.ActionTypeCode)
                    {
                    case KnownActionCategoryTypes.I:
                        // Déterminer si la tâche provient d'un scénario ancêtre
                        if (action.OriginalActionId != null)
                        {
                            // Tache I provenant du grand parent, on n'applique pas le prétype mais on applique la réduc
                            SharedScenarioActionsOperations.ApplyNewReduced(newAction, KnownActionCategoryTypes.I);
                        }
                        else
                        {
                            // Tache I provenant du parent, on applique le prétypage et la réduc s'il y en a

                            string actionTypeCode;

                            if (action.Category != null && action.Category.ActionTypeCode != null)
                            {
                                actionTypeCode = action.Category.ActionTypeCode;
                            }
                            else
                            {
                                actionTypeCode = KnownActionCategoryTypes.I;
                            }

                            SharedScenarioActionsOperations.ApplyNewReduced(newAction, actionTypeCode);
                        }

                        break;

                    case KnownActionCategoryTypes.E:
                        // Tâche E, on conserve E et on applique la réduc
                        SharedScenarioActionsOperations.ApplyNewReduced(newAction, KnownActionCategoryTypes.E);
                        break;

                    case KnownActionCategoryTypes.S:
                        SharedScenarioActionsOperations.ApplyReduced(action, newAction);
                        break;

                    default:
                        throw new ArgumentOutOfRangeException(nameof(action), new ArgumentOutOfRangeException(nameof(KAction.Reduced), new ArgumentOutOfRangeException(nameof(KActionReduced.ActionTypeCode))));
                    }
                }

                break;

            case ActionCloneBehavior.TargetToRealized:

                // Pour les tâches externes, il faut les faire réapparaitre comme externes
                // Pour les tâches internes, il faut qu'elle aient une partie réduite pour pouvoir les repasser à exerne.
                switch (action.Reduced.ActionTypeCode)
                {
                case KnownActionCategoryTypes.I:
                    SharedScenarioActionsOperations.ApplyNewReduced(newAction, KnownActionCategoryTypes.I);
                    break;

                case KnownActionCategoryTypes.E:
                    SharedScenarioActionsOperations.ApplyNewReduced(newAction, KnownActionCategoryTypes.E);
                    break;
                }

                break;


            case ActionCloneBehavior.Cascade:
                SharedScenarioActionsOperations.ApplyReduced(action, newAction);
                break;

            case ActionCloneBehavior.RealizedToNewInitial:
            case ActionCloneBehavior.TargetToNewInitial:
            case ActionCloneBehavior.InitialToNewInitial:

                // Pour les tâches externes, il faut les faire réapparaitre comme externes
                // Pour les tâches internes, il faut qu'elle aient une partie réduite pour pouvoir les repasser à exerne.
                if (action.Reduced != null)
                {
                    switch (action.Reduced.ActionTypeCode)
                    {
                    case KnownActionCategoryTypes.I:
                        SharedScenarioActionsOperations.ApplyNewReduced(newAction, KnownActionCategoryTypes.I);
                        break;

                    case KnownActionCategoryTypes.E:
                        SharedScenarioActionsOperations.ApplyNewReduced(newAction, KnownActionCategoryTypes.E);
                        break;
                    }
                }

                break;


            default:
                throw new ArgumentOutOfRangeException(nameof(cloneBehavior));
            }

            return(newAction);
        }
Beispiel #19
0
        /// <summary>
        /// Calcule les données pour un côté.
        /// </summary>
        /// <param name="actionFilter">Le filtre sur les actions.</param>
        /// <param name="distinctReferentials">The distinct referentials.</param>
        /// <returns>
        /// Les données créées.
        /// </returns>
        private IEnumerable <TData> GenerateItems(Func <KAction, bool> actionFilter, TReferential[] distinctReferentials, out TData[] total)
        {
            var scenarios = ParentViewModel.ScenariosToShow;

            var dataCol = new List <TData>();

            foreach (var sc in scenarios)
            {
                var data = new TData()
                {
                    Scenario = sc.Label
                };

                var dataItems = new List <TDataItem>();

                foreach (var referential in distinctReferentials)
                {
                    var actions = sc.Actions.
                                  Where(actionFilter)
                                  .Where(a => MatchesReferential(a, referential) && !a.IsGroup);

                    var actionsNotDeletedCount = actions.Where(a => !ActionsTimingsMoveManagement.IsActionDeleted(a)).Count();

                    var item = new TDataItem()
                    {
                        ReferentialName        = referential != null ? referential.Label : LocalizationManager.GetString("ViewModel_Restitution_EmptyReferential"),
                        ReferentialDuration    = actions.Any() ? actions.Sum(a => a.BuildDuration) : 0,
                        ReferentialOccurrences = actionsNotDeletedCount,
                        ValueMode  = SelectedValueMode,
                        IsStandard = referential is IActionReferentialProcess actionRef && actionRef.ProcessId == null
                    };

                    this.InitializeItem(item, referential);

                    dataItems.Add(item);
                }

                data.Items = dataItems.ToArray();
                dataCol.Add(data);
            }

            // Une fois les items définis, les trier par ordre décroissant de valeurs
            Scenario referenceScenario = scenarios.FirstOrDefault();

            if (referenceScenario != null)
            {
                var data = dataCol.First(d => d.Scenario == referenceScenario.Label);
                data.Items = data.Items.OrderByDescending(d => d.ReferentialDuration).ToArray();

                var comparer = new ReferenceArrayComparer <string>(data.Items.Select(d => d.ReferentialName).ToArray());

                foreach (var d in dataCol.Except(data))
                {
                    d.Items = d.Items.OrderBy(i => i.ReferentialName, comparer).ToArray();
                }
            }

            switch (this.SelectedValueMode)
            {
            case RestitutionValueMode.Absolute:
            {
                // Calculer la durée totale du scénario initial
                long totalDuration = 0;
                foreach (var data in dataCol)
                {
                    totalDuration = data.Items.Sum(i => i.ReferentialDuration);
                    if (totalDuration != 0)
                    {
                        break;
                    }
                }

                if (totalDuration != 0)
                {
                    foreach (var data in dataCol)
                    {
                        foreach (var item in data.Items)
                        {
                            item.ReferentialPercentage = Convert.ToDouble(item.ReferentialDuration) / Convert.ToDouble(totalDuration) * 100.0;
                        }
                    }
                }
            }
            break;

            case RestitutionValueMode.Relative:
            {
                foreach (var data in dataCol)
                {
                    var totalDuration = data.Items.Sum(i => i.ReferentialDuration);

                    if (totalDuration != 0)
                    {
                        foreach (var item in data.Items)
                        {
                            item.ReferentialPercentage = Convert.ToDouble(item.ReferentialDuration) / Convert.ToDouble(totalDuration) * 100.0;
                        }
                    }
                }
            }
            break;

            case RestitutionValueMode.Occurences:
                break;

            default:
                throw new ArgumentOutOfRangeException("ValueMode");
            }

            // Calculer les totaux
            total = new TData[scenarios.Length];
            int ii = 0;

            foreach (var sc in scenarios)
            {
                var data = new TData()
                {
                    Scenario = sc.Label
                };

                var item = new TDataItem()
                {
                    ReferentialName        = LocalizationManager.GetString("ViewModel_Restitution_Total"),
                    ReferentialDuration    = dataCol[ii].Items.Sum(i => i.ReferentialDuration),
                    ReferentialPercentage  = dataCol[ii].Items.Sum(i => i.ReferentialPercentage),
                    ReferentialOccurrences = dataCol[ii].Items.Sum(i => i.ReferentialOccurrences),
                    ValueMode = this.SelectedValueMode,
                };

                data.Items = new TDataItem[] { item };
                total[ii]  = data;
                ii++;
            }

            return(dataCol);
        }
Beispiel #20
0
        /// <summary>
        /// Met à jour les actions récursivement sur les scénarios dérivés de celui spécifié.
        /// </summary>
        /// <param name="context">Le contexte EF.</param>
        /// <param name="sourceScenario">Le scénario source.</param>
        /// <param name="allScenarios">Tous les scénarios qui peuvent être impactés.</param>
        /// <param name="actionsToRemove">Les actions à supprimer manuellement.</param>
        internal static void UpdateActions(KsmedEntities context, Scenario sourceScenario, Scenario[] allScenarios,
                                           out KAction[] actionsToRemove, out IList <KAction> actionsWithOriginal)
        {
            var derivedScenarios = ScenarioActionHierarchyHelper.GetDerivedScenarios(sourceScenario, allScenarios);

            var actions = GetActionsSortedWBS(sourceScenario);

            actionsWithOriginal = new List <KAction>();

            foreach (var scenario in derivedScenarios)
            {
                // Mettre à jour IsGroup
                foreach (var action in scenario.Actions)
                {
                    action.IsGroup = WBSHelper.HasChildren(action, scenario.Actions);
                }
            }

            foreach (var originalAction in actions)
            {
                // J'enlève le IsMArkedAsModified car les 2 références sont la sauvegarde des actions depuis la construction et depuis l'optimisation
                // Or depuis la construction, en modification, le bout de code cidessous est déjà appelé
                // Et depuis l'optimisation, il n'y a pas de changement de temps video
                if (originalAction.IsMarkedAsAdded /*|| originalAction.IsMarkedAsModified*/)
                {
                    var originalValues = originalAction.ChangeTracker.OriginalValues;
                    var modifiedValues = originalAction.ChangeTracker.ModifiedValues;

                    if (originalAction.IsMarkedAsAdded || modifiedValues.ContainsKey(ActionsTimingsMoveManagement.KActionStartPropertyName) || modifiedValues.ContainsKey(ActionsTimingsMoveManagement.KActionFinishPropertyName))
                    {
                        // Vérifier si le temps vidéo a changé
                        ActionsTimingsMoveManagement.GetOrignalModifiedVideoDurations(originalAction, out long originalDuration, out long modifiedDuration);

                        bool hasVideoDurationChanged = originalDuration != modifiedDuration;

                        // Si c'est une tâche créée et non dupliquée, le buildDuration est à 0, donc on doit le mettre à jour
                        //Sinon, si c'est une tâche dupliquée, on le laisse tel quel.
                        if (originalAction.BuildDuration == 0)
                        {
                            var paceRating = originalAction.Resource != null ? originalAction.Resource.PaceRating : 1d;
                            originalAction.BuildDuration = Convert.ToInt64(modifiedDuration * paceRating);
                        }
                    }
                }

                if (originalAction.IsMarkedAsAdded)
                {
                    // Si l'action est une action nouvelle dans un scénario cible, définir automatiquement la partie réduite
                    if (sourceScenario.NatureCode == KnownScenarioNatures.Target && originalAction.Reduced == null)
                    {
                        SharedScenarioActionsOperations.ApplyNewReduced(originalAction);
                    }

                    var originalActionKey    = context.CreateEntityKey(KsmedEntities.KActionsEntitySetName, originalAction);
                    var parentOriginalAction = WBSHelper.GetParent(originalAction, actions);

                    foreach (var derivedScenario in derivedScenarios)
                    {
                        var derivedActions = GetActionsSortedWBS(derivedScenario);

                        // Rechercher le parent dans le scénario dérivé
                        var parentDerivedAction = ScenarioActionHierarchyHelper.GetDerivedAction(parentOriginalAction, derivedScenario);

                        // Cloner l'action originale
                        var newAction = ScenarioCloneManager.CloneAction(originalAction, ActionCloneBehavior.Cascade);

                        // Assigner l'original
                        var originalActionForCurrentDerivedScenario = derivedScenario.Original == sourceScenario ? originalAction :
                                                                      ScenarioActionHierarchyHelper.GetDerivedAction(originalAction, derivedScenario.Original);
                        newAction.Original = originalActionForCurrentDerivedScenario;
                        actionsWithOriginal.Add(newAction);

                        // Insérer l'action clonée dans le scénario dérivé
                        ActionsTimingsMoveManagement.InsertUpdateWBS(
                            derivedActions, newAction, parentDerivedAction, WBSHelper.GetParts(originalAction.WBS).Last(),
                            (a, wbs) => EnsureTracking(a));

                        // Rafraichir les actions
                        derivedScenario.Actions.Add(newAction);
                        derivedActions = GetActionsSortedWBS(derivedScenario);

                        // Ajouter les mêmes prédécesseurs et successeurs
                        foreach (var originalPredecessor in originalAction.Predecessors)
                        {
                            var derivedPredecessor = ScenarioActionHierarchyHelper.GetDerivedAction(originalPredecessor, derivedScenario);
                            if (derivedPredecessor != null)
                            {
                                EnsureTracking(derivedPredecessor);
                                ActionsTimingsMoveManagement.AddPredecessor(derivedActions, newAction, derivedPredecessor);
                            }
                        }

                        foreach (var originalSuccessor in originalAction.Successors)
                        {
                            var derivedSuccessor = ScenarioActionHierarchyHelper.GetDerivedAction(originalSuccessor, derivedScenario);
                            if (derivedSuccessor != null)
                            {
                                EnsureTracking(derivedSuccessor);
                                ActionsTimingsMoveManagement.AddPredecessor(derivedActions, derivedSuccessor, newAction);
                            }
                        }

                        EnsureTracking(derivedScenario);
                        SharedScenarioActionsOperations.EnsureEmptySolutionExists(derivedScenario);
                        SharedScenarioActionsOperations.UdpateSolutionsApprovedState(derivedScenario);

                        ActionsTimingsMoveManagement.DebugCheckAllWBS(derivedActions);
                    }
                }
                else if (originalAction.IsMarkedAsModified)
                {
                    var originalValues         = originalAction.ChangeTracker.OriginalValues;
                    var modifiedValues         = originalAction.ChangeTracker.ModifiedValues;
                    var propertiesToCopyValues = new Dictionary <string, object>();

                    foreach (var propertyName in _kActionPropertyNamesToCopy)
                    {
                        if (modifiedValues.ContainsKey(propertyName))
                        {
                            propertiesToCopyValues[propertyName] = modifiedValues[propertyName];
                        }
                    }

                    // Vérifier si les reduced doit être impactés également
                    ActionsTimingsMoveManagement.GetOrignalModifiedBuildDurations(originalAction, out long originalDuration, out long modifiedDuration);

                    bool hasBuildDurationChanged = originalDuration != modifiedDuration;


                    foreach (var derivedScenario in derivedScenarios)
                    {
                        var derivedAction = ScenarioActionHierarchyHelper.GetDerivedAction(originalAction, derivedScenario);
                        if (derivedAction != null)
                        {
                            EnsureTracking(derivedAction);
                            foreach (var kvp in propertiesToCopyValues)
                            {
                                derivedAction.SetPropertyValue(kvp.Key, kvp.Value);
                            }

                            if (hasBuildDurationChanged)
                            {
                                if (derivedAction.IsReduced)
                                {
                                    // Modifier l'original duration et recalculer le temps final en fonction du gain
                                    EnsureTracking(derivedAction.Reduced);
                                    derivedAction.Reduced.OriginalBuildDuration = modifiedDuration;

                                    ActionsTimingsMoveManagement.UpdateTimingsFromReducedReduction(derivedAction);
                                }
                                else
                                {
                                    // Simplement recopier la durée
                                    derivedAction.BuildDuration = modifiedDuration;
                                }
                            }
                        }
                    }
                }
            }

            var toRemove = new List <KAction>();

            // Gérer les actions supprimées
            // EF gérant mal l'ordre des suppressions, ça créer une ConstraintException sur la FK OriginalActionId
            // Malheureusement un CascadeDelete est impossible puisque la FK est sur un même table
            if (sourceScenario.ChangeTracker.ObjectsRemovedFromCollectionProperties.ContainsKey("Actions"))
            {
                var removedActions = sourceScenario.ChangeTracker.ObjectsRemovedFromCollectionProperties["Actions"].ToArray();
                foreach (KAction originalAction in removedActions)
                {
                    EnsureTracking(originalAction);
                    toRemove.Add(originalAction);
                    originalAction.MarkAsUnchanged();

                    foreach (var derivedScenario in derivedScenarios)
                    {
                        var derivedAction = ScenarioActionHierarchyHelper.GetDerivedAction(originalAction, derivedScenario);
                        if (derivedAction != null)
                        {
                            var derivedActions = GetActionsSortedWBS(derivedScenario);

                            // Mettre à jour les WBS des autres actions
                            ActionsTimingsMoveManagement.DeleteUpdateWBS(derivedActions, derivedAction,
                                                                         (a, wbs) => EnsureTracking(a));
                            EnsureTracking(derivedAction);
                            toRemove.Add(derivedAction);
                        }
                    }
                }

                // Il faut maintenant trier les actions à supprimer pour que la suppression se fasse dans le bon ordre
                toRemove.Reverse();
                actionsToRemove = toRemove.ToArray();
            }
            else
            {
                actionsToRemove = new KAction[] { }
            };

            sourceScenario.CriticalPathIDuration = ActionsTimingsMoveManagement.GetInternalCriticalPathDuration(sourceScenario);
            foreach (var scenario in derivedScenarios)
            {
                EnsureTracking(scenario);
                ActionsTimingsMoveManagement.FixPredecessorsSuccessorsTimings(scenario.Actions.ToArray(), false);
                ActionsTimingsMoveManagement.UpdateVideoGroupsTiming(scenario.Actions.ToArray());
                ActionsTimingsMoveManagement.UpdateBuildGroupsTiming(scenario.Actions.ToArray());
                scenario.CriticalPathIDuration = ActionsTimingsMoveManagement.GetInternalCriticalPathDuration(scenario);
            }
        }
Beispiel #21
0
        public void Delete_From_Input_TestCases()
        {
            var jsonObject = JObject.Parse(File.ReadAllText("ActionsTimingsMoveManagement_DeleteTestCases.json"));


            JArray cases = (JArray)jsonObject["delete"];

            var testCases = JsonConvert.DeserializeObject <DeleteTestCase[]>(cases.ToString());

            foreach (var tc in testCases)
            {
                TestContext.WriteLine("---------------------------------");
                TestContext.WriteLine("Analyzing Test Case {0}", tc.Label);

                var inputTasks = new List <KAction>();

                var wbses = tc.Input.Split(' ');

                foreach (var wbs in wbses)
                {
                    var task = new KAction
                    {
                        Label = "T" + wbs,
                        WBS   = wbs,
                    };
                    inputTasks.Add(task);
                }

                TestContext.WriteLine("Input :", tc.Label);
                WriteTasksWBS(inputTasks);

                TestContext.WriteLine("Delete : {0}", tc.Delete);

                var tasksToDelete = inputTasks.Where(t => tc.Delete.Any(wbs => wbs == t.WBS)).ToArray();

                var outputTasks = inputTasks.ToList();
                foreach (var task in tasksToDelete)
                {
                    TestContext.WriteLine("Deleting : {0}", tc.Delete);
                    ActionsTimingsMoveManagement.DeleteUpdateWBS(outputTasks.ToArray(), task);

                    outputTasks.Remove(task);
                    WriteTasksWBS(outputTasks);

                    ActionsTimingsMoveManagement.DebugCheckAllWBS(outputTasks);
                }

                TestContext.WriteLine("Output :", tc.Label);
                WriteTasksWBS(outputTasks);

                TestContext.WriteLine("Expected :", tc.Label);
                WriteTasksWBS(tc.Expected);

                int i = 0;
                foreach (var expectedWbs in tc.Expected.Keys)
                {
                    var expectedLabel = tc.Expected[expectedWbs];

                    if (outputTasks.Count - 1 < i)
                    {
                        Assert.Fail("The actual has less tasks than expected");
                    }

                    var task        = outputTasks[i];
                    var actualWbs   = task.WBS;
                    var actuallabel = task.Label;


                    Assert.AreEqual(expectedWbs, task.WBS, string.Format("Expected {0}: {1}, Found {2}: {3}", expectedWbs, expectedLabel, actualWbs, actuallabel));
                    Assert.AreEqual(expectedLabel, actuallabel, string.Format("Expected {0}: {1}, Found {2}: {3}", expectedWbs, expectedLabel, actualWbs, actuallabel));


                    i++;
                }

                if (i != outputTasks.Count)
                {
                    Assert.Fail("The actual has more tasks than expected");
                }
            }
        }
Beispiel #22
0
        /// <summary>
        /// Enregistre des actions déjà existantes et construit les éléments.
        /// </summary>
        /// <param name="allActions">Toutes les actions.</param>
        /// <param name="filter">Les filtre I/E/S.</param>
        public void RegisterInitialActions(IEnumerable <KAction> allActions, IESFilterValue filter)
        {
            Func <ActionsDisplayResults> displayedActions;

            bool isCriticalPathEnabled;
            bool useManagedPredSucc;
            bool useGanttItemsTimingsOnly;
            bool fixPredSuccTimings;
            bool refreshTimings;

            foreach (var action in allActions)
            {
                action.IsGroup         = WBSHelper.HasChildren(action, allActions);
                action.IsLinkToProcess = action.LinkedProcessId != null;
            }

            switch (filter)
            {
            case IESFilterValue.IES:
                useManagedPredSucc    = false;
                isCriticalPathEnabled = true;
                displayedActions      = () => new ActionsDisplayResults {
                    Actions = allActions
                };
                useGanttItemsTimingsOnly = false;
                fixPredSuccTimings       = true;
                refreshTimings           = true;
                break;

            case IESFilterValue.I:
                useManagedPredSucc    = true;
                isCriticalPathEnabled = true;
                displayedActions      = () => FilterActionsUpdatePredSuccManaged(allActions,
                                                                                 a => ActionsTimingsMoveManagement.IsActionExternal(a) || ActionsTimingsMoveManagement.IsActionDeleted(a),
                                                                                 a => ActionsTimingsMoveManagement.IsActionInternal(a));
                useGanttItemsTimingsOnly = true;
                fixPredSuccTimings       = true;
                refreshTimings           = false;
                break;

            case IESFilterValue.IE:
                useManagedPredSucc    = true;
                isCriticalPathEnabled = false;
                displayedActions      = () => FilterActionsUpdatePredSuccManaged(allActions,
                                                                                 a => ActionsTimingsMoveManagement.IsActionDeleted(a),
                                                                                 a => ActionsTimingsMoveManagement.IsActionExternal(a) || ActionsTimingsMoveManagement.IsActionInternal(a));
                useGanttItemsTimingsOnly = true;
                fixPredSuccTimings       = true;
                refreshTimings           = false;
                break;

            default:
                throw new ArgumentOutOfRangeException("filter");
            }

            _useGanttItemsTimingsOnly = useGanttItemsTimingsOnly;

            this.IsCriticalPathEnabled = isCriticalPathEnabled;

            var results = displayedActions();

            this.UseManagedPredecessorsSuccessors = useManagedPredSucc;
            if (filter == IESFilterValue.IES && useManagedPredSucc)
            {
                ActionsTimingsMoveManagement.DebugCheckAllWBS(results.Actions);
            }

            this.RegisterInitialActionsImpl(results.Actions);

            if (results.NewTimings != null)
            {
                foreach (var timing in results.NewTimings)
                {
                    SetBuildStart(timing.Action, timing.Start);
                    SetBuildFinish(timing.Action, timing.Finish);
                }
            }

            if (refreshTimings)
            {
                foreach (var item in this.ItemsOfTypeAction)
                {
                    _updatingitem = item;
                    item.Start    = GanttDates.ToDateTime(item.Action.BuildStart);
                    item.Finish   = GanttDates.ToDateTime(item.Action.BuildFinish);
                    _updatingitem = null;
                }
            }

            if (fixPredSuccTimings)
            {
                this.FixPredecessorsSuccessorsTimings();
                this.UpdateResourcesLoad();
            }
        }
Beispiel #23
0
        public void TestsIsActionInternalExternalDeletedMutuallyExclusive()
        {
            SampleData.ClearDatabaseThenImportDefaultProject();
            // Vérifie dans toutes les actions de la BDD si les actions sont soi I, E ou S et jamais aucun des trois ou plus d'un des 3 à la fois.
            var prepareService = new PrepareService();
            var analyzeService = new AnalyzeService();
            var mre            = new System.Threading.ManualResetEvent(false);

            ProjectsData pData     = null;
            Exception    exception = null;

            prepareService.GetProjects(d =>
            {
                pData = d;
                mre.Set();
            }, ex =>
            {
                exception = ex;
                mre.Set();
            });

            mre.WaitOne();
            AssertExt.IsExceptionNull(exception);

            foreach (var project in pData.Projects)
            {
                mre.Reset();
                RestitutionData rData = null;
                analyzeService.GetFullProjectDetails(project.ProjectId, d =>
                {
                    rData = d;
                    mre.Set();
                }, ex =>
                {
                    exception = ex;
                    mre.Set();
                });

                mre.WaitOne();
                AssertExt.IsExceptionNull(exception);

                foreach (var scenario in rData.Scenarios)
                {
                    foreach (var action in scenario.Actions)
                    {
                        bool i = ActionsTimingsMoveManagement.IsActionInternal(action);
                        bool e = ActionsTimingsMoveManagement.IsActionExternal(action);
                        bool s = ActionsTimingsMoveManagement.IsActionDeleted(action);

                        Assert.IsTrue(i || e || s);

                        if (i)
                        {
                            Assert.IsFalse(e || s);
                        }
                        else if (e)
                        {
                            Assert.IsFalse(i || s);
                        }
                        else
                        {
                            Assert.IsFalse(i || e);
                        }
                    }
                }
            }
        }
Beispiel #24
0
        public void BulkScenarioCloneTests()
        {
            SampleData.ClearDatabaseThenImportDefaultProject();
            var service = new PrepareService();

            int[] projectIds;
            using (var context = KProcess.Ksmed.Data.ContextFactory.GetNewContext())
            {
                projectIds = context.Projects.Select(p => p.ProjectId).ToArray();
            }

            foreach (var pid in projectIds)
            {
                var mre = new System.Threading.ManualResetEvent(false);

                Exception     e    = null;
                ScenariosData data = null;

                service.GetScenarios(pid, d =>
                {
                    data = d;
                    mre.Set();
                }, ex =>
                {
                    e = ex;
                    mre.Set();
                });

                mre.WaitOne();
                AssertExt.IsExceptionNull(e);
                Assert.IsNotNull(data);

                foreach (var scenario in data.Scenarios.Where(s => s.NatureCode != KnownScenarioNatures.Realized))
                {
                    if (scenario.NatureCode == KnownScenarioNatures.Target && scenario.Actions.Any(a => !a.IsReduced))
                    {
                        // Il s'agit d'un vieux projet. Tous les actions d'un scénario cible doivent aujourd'hui avoir une partie réduite
                        continue;
                    }

                    mre.Reset();

                    Scenario newScenario = null;

                    service.CreateScenario(pid, scenario, true, s =>
                    {
                        newScenario = s;
                        mre.Set();
                    }, ex =>
                    {
                        e = ex;
                        mre.Set();
                    });

                    mre.WaitOne();
                    AssertExt.IsExceptionNull(e);
                    Assert.IsNotNull(newScenario);

                    // Vérification de l'intégrité du scénario
                    ActionsTimingsMoveManagement.DebugCheckAllWBS(EnumerableExt.Concat(newScenario));

                    // Vérifier qu'il n'y ai pas de tâche avec un temps process nul
                    if (scenario.NatureCode != KnownScenarioNatures.Initial && newScenario.Actions.Any(a => a.BuildDuration <= 0))
                    {
                        Assert.Fail("Une action a un temps invalide");
                    }
                }
            }
        }
Beispiel #25
0
        /// <summary>
        /// Supprime les actions dont la durée est 0 du scénario.
        /// Supprime également les groupes vides qui pourraient résulter des suppressions précédentes.
        /// </summary>
        /// <param name="scenario">Le scénario.</param>
        internal static void RemoveEmptyDurationActionsAndGroupsFromNewScenario(Scenario scenario)
        {
            var emptyDurationActionsToDelete = new List <KAction>();
            var newTimings = new List <ActionTiming>();

            var derivedActions = GetActionsSortedWBS(scenario);

            // Mettre à jour IsGroup
            foreach (var action in derivedActions)
            {
                action.IsGroup = WBSHelper.HasChildren(action, derivedActions);
            }

            foreach (var action in derivedActions)
            {
                //On ne supprime pas si: la catégorie de type à supprimer &&  pas de parent dans le scenario n && originalBuildDuration!=0

                if (action.BuildDuration == 0 && !action.IsGroup &&
                    !(action.Category != null && action.Category.ActionTypeCode != null &&
                      action.Category.ActionTypeCode == KnownActionCategoryTypes.S &&
                      action.Original.Original == null &&
                      action.Reduced != null &&
                      action.Reduced.OriginalBuildDuration != 0))
                {
                    // Déplacer tous les pred vers ses succ
                    ActionsTimingsMoveManagement.MapAllPredToSucc(action, a => a.BuildDuration != 0 && !action.IsGroup, newTimings, false);

                    emptyDurationActionsToDelete.Add(action);
                    scenario.Actions.Remove(action);
                    action.Predecessors.Clear();
                    action.Successors.Clear();
                    action.MarkAsDeleted();
                }
            }

            //foreach (var action in actionsToDelete)
            //{
            //    // Mettre à jour les WBS des autres actions
            //    ActionsTimingsMoveManagement.DeleteUpdateWBS(derivedActions, action);
            //}

            if (scenario.NatureCode == KnownScenarioNatures.Realized)
            {
                foreach (var timing in newTimings)
                {
                    timing.Action.Start  = timing.Start;
                    timing.Action.Finish = timing.Finish;
                }
            }

            //actionsToDelete.Clear();
            var emptyGroupActionsToDelete = new List <KAction>();

            var actionsFiltered = GetActionsSortedWBS(scenario);

            foreach (var action in actionsFiltered)
            {
                if (action.IsGroup && !WBSHelper.HasChildren(action, actionsFiltered))
                {
                    emptyGroupActionsToDelete.Add(action);
                    scenario.Actions.Remove(action);
                    action.MarkAsDeleted();
                }
            }

            //foreach (var action in emptyGroupActionsToDelete)
            //{
            //    // Mettre à jour les WBS des autres actions
            //    ActionsTimingsMoveManagement.DeleteUpdateWBS(derivedActions, action);
            //}

            // Mettre à jour les WBS des autres actions
            var tree = derivedActions.VirtualizeTree();

            emptyDurationActionsToDelete
            .Union(emptyGroupActionsToDelete)
            .ForEach(_ => tree.Remove(_));
            tree.ApplyWBS();


            ActionsTimingsMoveManagement.DebugCheckAllWBS(EnumerableExt.Concat(scenario));
            ActionsTimingsMoveManagement.DebugCheckPredSucc(scenario.Actions, false);
        }
Beispiel #26
0
        /// <summary>
        /// Prédit les scénarios qui seront impactés par les modifications en attente de sauvegarde.
        /// </summary>
        /// <param name="sourceModifiedScenario">Le scenério source modifié.</param>
        /// <param name="allScenarios">Tous les scénarios.</param>
        /// <param name="actionsToDelete">Les actions à supprimer.</param>
        /// <returns>
        /// Les scénarios impactés.
        /// </returns>
        internal static Scenario[] PredictImpactedScenarios(Scenario sourceModifiedScenario, Scenario[] allScenarios, KAction[] actionsToDelete, KAction[] actionsWithUpdatedWBS)
        {
            var derivedScenarios   = ScenarioActionHierarchyHelper.GetDerivedScenarios(sourceModifiedScenario, allScenarios);
            var scenariosToInspect = new List <Scenario>(derivedScenarios);
            var actions            = GetActionsSortedWBS(sourceModifiedScenario);

            if (actions.Any(a => a.IsMarkedAsAdded))
            {
                scenariosToInspect.Clear();
            }
            else
            {
                foreach (var originalAction in actions)
                {
                    bool hasUpdatedWBS = actionsWithUpdatedWBS != null && actionsWithUpdatedWBS.Contains(originalAction);
                    if (originalAction.IsMarkedAsModified || hasUpdatedWBS)
                    {
                        var modifiedValues = originalAction.ChangeTracker.ModifiedValues;

                        // S'il y a une correspondance entre le nom d'une propriété modifiée et les propriétés qui sont impactantes
                        if (hasUpdatedWBS || modifiedValues.Keys.Intersect(_kActionPropertyNamesToCopy).Any())
                        {
                            // rechercher tous les scénarios qui possèdent ces actions dérivées
                            foreach (var derivedScenario in scenariosToInspect.ToArray())
                            {
                                var derivedAction = ScenarioActionHierarchyHelper.GetDerivedAction(originalAction, derivedScenario);
                                if (derivedAction != null)
                                {
                                    scenariosToInspect.Remove(derivedScenario);
                                }

                                if (!scenariosToInspect.Any())
                                {
                                    break;
                                }
                            }
                        }

                        if (modifiedValues.ContainsKey(ActionsTimingsMoveManagement.KActionBuildStartPropertyName) || modifiedValues.ContainsKey(ActionsTimingsMoveManagement.KActionBuildFinishPropertyName))
                        {
                            ActionsTimingsMoveManagement.GetOrignalModifiedBuildDurations(originalAction, out long originalDuration, out long modifiedDuration);

                            if (modifiedDuration != originalDuration)
                            {
                                // rechercher tous les scénarios qui possèdent ces actions dérivées
                                foreach (var derivedScenario in scenariosToInspect.ToArray())
                                {
                                    var derivedAction = ScenarioActionHierarchyHelper.GetDerivedAction(originalAction, derivedScenario);
                                    if (derivedAction != null && derivedAction.IsReduced)
                                    {
                                        scenariosToInspect.Remove(derivedScenario);
                                    }

                                    if (!scenariosToInspect.Any())
                                    {
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            if (actionsToDelete != null)
            {
                foreach (var originalAction in actionsToDelete)
                {
                    // rechercher tous les scénarios qui possèdent ces actions dérivées
                    foreach (var derivedScenario in scenariosToInspect.ToArray())
                    {
                        var derivedAction = ScenarioActionHierarchyHelper.GetDerivedAction(originalAction, derivedScenario);
                        if (derivedAction != null)
                        {
                            scenariosToInspect.Remove(derivedScenario);
                        }
                    }
                    if (!scenariosToInspect.Any())
                    {
                        break;
                    }
                }
            }

            return(derivedScenarios.Except(scenariosToInspect).ToArray());
        }
Beispiel #27
0
        /// <summary>
        /// Exporte les actions spécifiées.
        /// </summary>
        /// <param name="actions">Les actions.</param>
        /// <param name="cellReference">La référence de la cellule.</param>
        /// <param name="sheet">La feuille.</param>
        private void ExportActions(ICollection <KAction> actions, WorksheetPart sheet, ref CellReference cellReference)
        {
            var timeFormatService = IoC.Resolve <IServiceBus>().Get <ITimeTicksFormatService>();

            var timeScale = _data.Project.TimeScale;

            #region Format pour les actions

            // Actions
            var actionsFormats = new List <ColumnFormat>()
            {
                // Thumbnail
                new ColumnFormat()
                {
                    Header = string.Empty
                },

                // Label
                new ColumnFormat()
                {
                    Header = LocalizationManager.GetString("ViewModel_AnalyzeRestitution_Export_Action_Task")
                },

                // Start
                new ColumnFormat()
                {
                    Header = LocalizationManager.GetString("ViewModel_AnalyzeRestitution_Export_Action_Start")
                },

                // Duration
                new ColumnFormat()
                {
                    Header = LocalizationManager.GetString("ViewModel_AnalyzeRestitution_Export_Action_Duration")
                },

                // Finish
                new ColumnFormat()
                {
                    Header = LocalizationManager.GetString("ViewModel_AnalyzeRestitution_Export_Action_Finish")
                },

                // BuildStart
                new ColumnFormat()
                {
                    Header = LocalizationManager.GetString("ViewModel_AnalyzeRestitution_Export_Action_BuildStart")
                },

                // BuildDuration
                new ColumnFormat()
                {
                    Header = LocalizationManager.GetString("ViewModel_AnalyzeRestitution_Export_Action_BuildDuration")
                },

                // BuildFinish
                new ColumnFormat()
                {
                    Header = LocalizationManager.GetString("ViewModel_AnalyzeRestitution_Export_Action_BuildFinish")
                },

                // WBS
                new ColumnFormat()
                {
                    Header = LocalizationManager.GetString("ViewModel_AnalyzeRestitution_Export_Action_WBS")
                },

                // Category
                new ColumnFormat()
                {
                    Header = LocalizationManager.GetString("ViewModel_AnalyzeRestitution_Export_Action_Category")
                },

                // Resource
                new ColumnFormat()
                {
                    Header = LocalizationManager.GetString("ViewModel_AnalyzeRestitution_Export_Action_Resource")
                },

                // Video
                new ColumnFormat()
                {
                    Header = LocalizationManager.GetString("ViewModel_AnalyzeRestitution_Export_Action_Video")
                },

                // Predecessors
                new ColumnFormat()
                {
                    Header = LocalizationManager.GetString("ViewModel_AnalyzeRestitution_Export_Action_Predecessors")
                },

                // Original
                new ColumnFormat()
                {
                    Header = LocalizationManager.GetString("ViewModel_AnalyzeRestitution_Export_Action_Original")
                },
            };

            // Ref1
            if (_referentialsUse[ProcessReferentialIdentifier.Ref1].IsEnabled)
            {
                actionsFormats.Add(new ColumnFormat()
                {
                    Header = IoC.Resolve <IReferentialsUseService>().GetLabel(ProcessReferentialIdentifier.Ref1)
                });
            }

            // Ref2
            if (_referentialsUse[ProcessReferentialIdentifier.Ref2].IsEnabled)
            {
                actionsFormats.Add(new ColumnFormat()
                {
                    Header = IoC.Resolve <IReferentialsUseService>().GetLabel(ProcessReferentialIdentifier.Ref2)
                });
            }

            // Ref3
            if (_referentialsUse[ProcessReferentialIdentifier.Ref3].IsEnabled)
            {
                actionsFormats.Add(new ColumnFormat()
                {
                    Header = IoC.Resolve <IReferentialsUseService>().GetLabel(ProcessReferentialIdentifier.Ref3)
                });
            }

            // Ref4
            if (_referentialsUse[ProcessReferentialIdentifier.Ref4].IsEnabled)
            {
                actionsFormats.Add(new ColumnFormat()
                {
                    Header = IoC.Resolve <IReferentialsUseService>().GetLabel(ProcessReferentialIdentifier.Ref4)
                });
            }

            // Ref5
            if (_referentialsUse[ProcessReferentialIdentifier.Ref5].IsEnabled)
            {
                actionsFormats.Add(new ColumnFormat()
                {
                    Header = IoC.Resolve <IReferentialsUseService>().GetLabel(ProcessReferentialIdentifier.Ref5)
                });
            }

            // Ref6
            if (_referentialsUse[ProcessReferentialIdentifier.Ref6].IsEnabled)
            {
                actionsFormats.Add(new ColumnFormat()
                {
                    Header = IoC.Resolve <IReferentialsUseService>().GetLabel(ProcessReferentialIdentifier.Ref6)
                });
            }

            // Ref7
            if (_referentialsUse[ProcessReferentialIdentifier.Ref7].IsEnabled)
            {
                actionsFormats.Add(new ColumnFormat()
                {
                    Header = IoC.Resolve <IReferentialsUseService>().GetLabel(ProcessReferentialIdentifier.Ref7)
                });
            }

            // IsRandom
            actionsFormats.Add(new ColumnFormat()
            {
                Header = LocalizationManager.GetString("ViewModel_AnalyzeRestitution_Export_Action_IsRandom")
            });

            // Custom Text
            actionsFormats.Add(new ColumnFormat()
            {
                Header = LocalizationManager.GetString("ViewModel_AnalyzeRestitution_Export_Action_CustomValue_Text1")
            });
            actionsFormats.Add(new ColumnFormat()
            {
                Header = LocalizationManager.GetString("ViewModel_AnalyzeRestitution_Export_Action_CustomValue_Text2")
            });
            actionsFormats.Add(new ColumnFormat()
            {
                Header = LocalizationManager.GetString("ViewModel_AnalyzeRestitution_Export_Action_CustomValue_Text3")
            });
            actionsFormats.Add(new ColumnFormat()
            {
                Header = LocalizationManager.GetString("ViewModel_AnalyzeRestitution_Export_Action_CustomValue_Text4")
            });

            // Custom Numeric
            actionsFormats.Add(new ColumnFormat()
            {
                Header = LocalizationManager.GetString("ViewModel_AnalyzeRestitution_Export_Action_CustomValue_Numeric1")
            });
            actionsFormats.Add(new ColumnFormat()
            {
                Header = LocalizationManager.GetString("ViewModel_AnalyzeRestitution_Export_Action_CustomValue_Numeric2")
            });
            actionsFormats.Add(new ColumnFormat()
            {
                Header = LocalizationManager.GetString("ViewModel_AnalyzeRestitution_Export_Action_CustomValue_Numeric3")
            });
            actionsFormats.Add(new ColumnFormat()
            {
                Header = LocalizationManager.GetString("ViewModel_AnalyzeRestitution_Export_Action_CustomValue_Numeric4")
            });

            // DifferenceReason
            actionsFormats.Add(new ColumnFormat()
            {
                Header = LocalizationManager.GetString("ViewModel_AnalyzeRestitution_Export_Action_DifferenceReason")
            });

            // Amélioration I/E/S
            actionsFormats.Add(new ColumnFormat()
            {
                Header = LocalizationManager.GetString("ViewModel_AnalyzeRestitution_Export_Action_Reduced_IES")
            });

            // Solution
            actionsFormats.Add(new ColumnFormat()
            {
                Header = LocalizationManager.GetString("ViewModel_AnalyzeRestitution_Export_Action_Reduced_Solution")
            });

            // Reduction ratio
            actionsFormats.Add(new ColumnFormat()
            {
                Header = LocalizationManager.GetString("ViewModel_AnalyzeRestitution_Export_Action_Reduced_ReductionRatio")
            });

            #endregion

            CellContent[][] data = new CellContent[actions.Count][];

            uint tableRowIndex = cellReference.RowIndex;

            int i = 0;
            foreach (var action in actions)
            {
                CellContent[] row = new CellContent[actionsFormats.Count];

                // Mettre à jour IsGroup
                action.IsGroup = WBSHelper.HasChildren(action, actions);

                int j = 0;

                #region Data pour les actions

                // Thumbnail
                j++;

                // Label
                row[j++] = action.Label;

                if (!action.IsGroup)
                {
                    // Start
                    row[j++] = CellContent.TimeSpan(timeFormatService.RoundTime(action.Start, timeScale));

                    // Duration
                    row[j++] = CellContent.TimeSpan(timeFormatService.RoundTime(action.Duration, timeScale));

                    // Finish
                    row[j++] = CellContent.TimeSpan(timeFormatService.RoundTime(action.Finish, timeScale));
                }
                else
                {
                    j += 3; // Nombre de colonnes précédentes
                }
                // BuildStart
                row[j++] = CellContent.TimeSpan(timeFormatService.RoundTime(action.BuildStart, timeScale));

                // BuildDuration
                row[j++] = CellContent.TimeSpan(timeFormatService.RoundTime(action.BuildDuration, timeScale));

                // BuildFinish
                row[j++] = CellContent.TimeSpan(timeFormatService.RoundTime(action.BuildFinish, timeScale));

                // WBS
                row[j++] = action.WBS;


                if (!action.IsGroup)
                {
                    // Category
                    if (action.Category != null)
                    {
                        row[j++] = action.Category.Label;
                    }
                    else
                    {
                        row[j++] = null;
                    }

                    // Resource
                    if (action.Resource != null)
                    {
                        row[j++] = action.Resource.Label;
                    }
                    else
                    {
                        row[j++] = null;
                    }

                    // Video
                    if (action.Video != null)
                    {
                        row[j++] = action.Video.Filename;
                    }
                    else
                    {
                        row[j++] = null;
                    }

                    // Predecessors
                    row[j++] = FormatPredecessorsString(action);

                    // Original
                    if (action.Original != null)
                    {
                        row[j++] = action.Original.Label;
                    }
                    else
                    {
                        row[j++] = null;
                    }

                    // Ref1
                    if (_referentialsUse[ProcessReferentialIdentifier.Ref1].IsEnabled)
                    {
                        row[j++] = GetMultiReferentialLabels(action.Ref1, ProcessReferentialIdentifier.Ref1);
                    }

                    // Ref2
                    if (_referentialsUse[ProcessReferentialIdentifier.Ref2].IsEnabled)
                    {
                        row[j++] = GetMultiReferentialLabels(action.Ref2, ProcessReferentialIdentifier.Ref2);
                    }

                    // Ref3
                    if (_referentialsUse[ProcessReferentialIdentifier.Ref3].IsEnabled)
                    {
                        row[j++] = GetMultiReferentialLabels(action.Ref3, ProcessReferentialIdentifier.Ref3);
                    }

                    // Ref4
                    if (_referentialsUse[ProcessReferentialIdentifier.Ref4].IsEnabled)
                    {
                        row[j++] = GetMultiReferentialLabels(action.Ref4, ProcessReferentialIdentifier.Ref4);
                    }

                    // Ref5
                    if (_referentialsUse[ProcessReferentialIdentifier.Ref5].IsEnabled)
                    {
                        row[j++] = GetMultiReferentialLabels(action.Ref5, ProcessReferentialIdentifier.Ref5);
                    }

                    // Ref6
                    if (_referentialsUse[ProcessReferentialIdentifier.Ref6].IsEnabled)
                    {
                        row[j++] = GetMultiReferentialLabels(action.Ref6, ProcessReferentialIdentifier.Ref6);
                    }

                    // Ref7
                    if (_referentialsUse[ProcessReferentialIdentifier.Ref7].IsEnabled)
                    {
                        row[j++] = GetMultiReferentialLabels(action.Ref7, ProcessReferentialIdentifier.Ref7);
                    }

                    // IsRandom
                    row[j++] = action.IsRandom.ToString();

                    // Custom Text
                    row[j++] = action.CustomTextValue;
                    row[j++] = action.CustomTextValue2;
                    row[j++] = action.CustomTextValue3;
                    row[j++] = action.CustomTextValue4;

                    // Custom Numeric
                    row[j++] = action.CustomNumericValue;
                    row[j++] = action.CustomNumericValue2;
                    row[j++] = action.CustomNumericValue3;
                    row[j++] = action.CustomNumericValue4;

                    // DifferenceReason
                    row[j++] = action.DifferenceReason;

                    // Amélioration
                    if (action.Reduced != null)
                    {
                        // Amélioration I/E/S
                        string label;

                        if (ActionsTimingsMoveManagement.IsActionInternal(action))
                        {
                            label = LocalizationManager.GetString("ViewModel_AnalyzeRestitution_Export_Action_Reduced_Internal");
                        }
                        else if (ActionsTimingsMoveManagement.IsActionExternal(action))
                        {
                            label = LocalizationManager.GetString("ViewModel_AnalyzeRestitution_Export_Action_Reduced_External");
                        }
                        else if (ActionsTimingsMoveManagement.IsActionDeleted(action))
                        {
                            label = LocalizationManager.GetString("ViewModel_AnalyzeRestitution_Export_Action_Reduced_Deleted");
                        }
                        else
                        {
                            throw new ArgumentOutOfRangeException();
                        }

                        row[j++] = label;

                        row[j++] = action.Reduced.Solution;
                        row[j++] = CellContent.Percentage(action.Reduced.ReductionRatio);
                    }
                    else
                    {
                        row[j++] = null;
                        row[j++] = null;
                        row[j++] = null;
                    }
                }

                #endregion

                data[i] = row;
                i++;
            }

            _file.AddTable(sheet, actionsFormats.ToArray(), data, cellReference);


            // Ajouter une image

            cellReference.NewLine();

            i = 0;
            foreach (var action in actions)
            {
                if (action.Thumbnail != null)
                {
                    // Ajout du libellé du lien
                    var tableCellRef = new CellReference(1, tableRowIndex + (uint)i + 1);
                    _file.SetCellValue(sheet, tableCellRef, new CellContent(action.ActionId.ToString(), CellDataType.Hyperlink));

                    // Ajout du lien
                    string definedName = string.Format("Action.{0}", action.ActionId);
                    _file.CreateDefinedName(sheet, cellReference, definedName);

                    _file.AddHyperlinkToDefinedName(sheet, tableCellRef, definedName, "");

                    // Ajout du libellé
                    _file.SetCellValue(sheet, cellReference, string.Format("{0} {1}", action.WBS, action.Label ?? string.Empty));
                    cellReference.MoveRight();

                    // Ajout de l'image
                    using (var ms = new System.IO.MemoryStream(action.Thumbnail.Data))
                    {
                        var decoder   = System.Windows.Media.Imaging.BitmapDecoder.Create(ms, System.Windows.Media.Imaging.BitmapCreateOptions.PreservePixelFormat, System.Windows.Media.Imaging.BitmapCacheOption.OnLoad);
                        var size      = new System.Windows.Size(decoder.Frames[0].PixelWidth, decoder.Frames[0].PixelHeight);
                        var mimeTypes = decoder.CodecInfo.MimeTypes;

                        ImagePartType imageType;
                        if (mimeTypes.Contains("image/jpeg"))
                        {
                            imageType = ImagePartType.Jpeg;
                        }
                        else if (mimeTypes.Contains("image/bmp"))
                        {
                            imageType = ImagePartType.Bmp;
                        }
                        else if (mimeTypes.Contains("image/png"))
                        {
                            imageType = ImagePartType.Png;
                        }
                        else
                        {
                            continue;
                        }

                        string pictureName = string.Format("Thumbnail.{0}", action.ActionId);

                        uint rowsLength = _file.AddImage(sheet, action.Thumbnail.Data, imageType, action.ActionId.ToString(), pictureName, size, cellReference);

                        // On déplace la cellule active à après l'image
                        cellReference = new CellReference(1, cellReference.RowIndex + rowsLength);
                    }
                }
                i++;
            }
        }
Beispiel #28
0
        /// <summary>
        /// Filtre les actions et met à jour leurs prédécesseurs et succésseurs managés.
        /// </summary>
        /// <param name="allActions">Toutes les actions.</param>
        /// <param name="excludedActionsFilter">Le filtre excluant les actions.</param>
        /// <param name="includedActionsPredSuccFilter">Le filtre incluant les actions prédécesseurs et succ.</param>
        /// <returns>Les actions filtrées.</returns>
        private ActionsDisplayResults FilterActionsUpdatePredSuccManaged(IEnumerable <KAction> allActions,
                                                                         Func <KAction, bool> excludedActionsFilter,
                                                                         Func <KAction, bool> includedActionsPredSuccFilter)
        {
            var results    = new ActionsDisplayResults();
            var newTimings = new List <ActionTiming>();

            var actionsSorted = allActions
                                .OrderBy(a => a.WBSParts, new WBSHelper.WBSComparer())
                                .ToArray();

#if DEBUG
            foreach (var action in allActions)
            {
                // S'assurer qu'une action soit un seul de : I/E/S/Group
                var isI = ActionsTimingsMoveManagement.IsActionInternal(action);
                var isE = ActionsTimingsMoveManagement.IsActionExternal(action);
                var isS = ActionsTimingsMoveManagement.IsActionDeleted(action);
                var isG = action.IsGroup;

                if (!(isI | isE | isS | isG))
                {
                    throw new InvalidOperationException("Impossible qu'une action soit à la fois I ou E ou S ou G");
                }
            }
#endif

            var actionsFinal = new List <KAction>();

            foreach (var action in actionsSorted)
            {
                action.PredecessorsManaged.Clear();
                action.SuccessorsManaged.Clear();
            }

            foreach (var action in actionsSorted)
            {
                if (excludedActionsFilter(action))
                {
                    // Déplacer tous les pred vers ses succ
                    ActionsTimingsMoveManagement.MapAllPredToSucc(action, includedActionsPredSuccFilter, newTimings, true);
                }
                else if (!action.IsGroup)
                {
                    foreach (var pred in action.Predecessors)
                    {
                        if (includedActionsPredSuccFilter(pred))
                        {
                            pred.SuccessorsManaged.Add(action);
                            action.PredecessorsManaged.Add(pred);
                        }
                    }
                    actionsFinal.Add(action);
                }
                else
                {
                    System.Diagnostics.Debug.Assert(action.IsGroup);
                    actionsFinal.Add(action);
                }
            }

            // Supprimer les liens pour les actions non présentes dans la collection
            foreach (var action in actionsFinal)
            {
                foreach (var pred in action.PredecessorsManaged.ToArray())
                {
                    if (!actionsFinal.Contains(pred))
                    {
                        action.PredecessorsManaged.Remove(pred);
                        pred.SuccessorsManaged.Remove(action);
                    }
                }

                foreach (var succ in action.SuccessorsManaged.ToArray())
                {
                    if (!actionsFinal.Contains(succ))
                    {
                        action.SuccessorsManaged.Remove(succ);
                        succ.PredecessorsManaged.Remove(action);
                    }
                }
            }

            // Il faut automatiquement supprimer les groupes qui ne contiennent plus d'enfants
            // Les groupes n'ayant ni précédesseurs ni successeurs, on peut les supprimer sans réel impact
            var copy = actionsFinal.ToArray();
            foreach (var action in copy)
            {
                if (action.IsGroup && !WBSHelper.HasChildren(action, copy))
                {
                    actionsFinal.Remove(action);
                }
            }

            results.Actions    = actionsFinal;
            results.NewTimings = newTimings;

            return(results);
        }