예제 #1
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>
 public virtual Task <Scenario[]> PredictImpactedScenarios(
     Scenario sourceModifiedScenario, Scenario[] allScenarios, KAction[] actionsToDelete, KAction[] actionsWithUpdatedWBS) =>
 Task.Run(() =>
 {
     return(ActionsRecursiveUpdate.PredictImpactedScenarios(sourceModifiedScenario, allScenarios, actionsToDelete, actionsWithUpdatedWBS));
 });
예제 #2
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 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());
        }
예제 #3
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>
        private 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);
        }
예제 #4
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;
            }
        }