예제 #1
0
        /// <summary>
        /// Met à jour les libellés des causes d'écarts sur les actions.
        /// </summary>
        private void UpdateDifferenceReasons()
        {
            if (this.SelectedOriginalScenario != null && this.SelectedTargetScenario != null)
            {
                foreach (var action in this.SelectedOriginalScenario.Actions.Concat(
                             this.SelectedTargetScenario.Actions))
                {
                    action.DifferenceReasonManaged = action.DifferenceReason;
                }

                foreach (var action in this.SelectedOriginalScenario.Actions)
                {
                    var derived = ScenarioActionHierarchyHelper.GetDerivedAction(action, this.SelectedTargetScenario);
                    if (derived != null && action.DifferenceReason != null)
                    {
                        derived.DifferenceReasonManaged = action.DifferenceReason;
                    }
                }

                foreach (var action in this.SelectedTargetScenario.Actions)
                {
                    var ancestor = ScenarioActionHierarchyHelper.GetAncestorAction(action, this.SelectedOriginalScenario);
                    if (ancestor != null && action.DifferenceReason != null)
                    {
                        ancestor.DifferenceReasonManaged = action.DifferenceReason;
                    }
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Obtient les données pour l'écran Simuler.
        /// </summary>
        /// <param name="context">le contexte EF.</param>
        /// <param name="projectId">L'identifiant du projet.</param>
        /// <param name="natureFilter">Le filtre des codes de nature.</param>
        /// <returns>
        /// Les données
        /// </returns>
        public static async Task <SimulateData> GetSimulateData(KsmedEntities context, int projectId, GetDataScenarioNatures natureFilter)
        {
            IDictionary <ProcessReferentialIdentifier, bool> referentialsUsed = await GetReferentialsUse(context, projectId);

            await Queries.LoadAllReferentialsOfProject(context, projectId, referentialsUsed);

            await context.Projects
            .Include(nameof(Project.Process))
            .Include($"{nameof(Project.Process)}.{nameof(Procedure.Videos)}")
            .Where(p => p.ProjectId == projectId)
            .SelectMany(p => p.Process.Videos)
            .ToArrayAsync();

            Scenario[] scenarios = await LoadScenarios(context, projectId, referentialsUsed, natureFilter);

            Project project = await context.Projects.SingleAsync(p => p.ProjectId == projectId);

            ScenarioActionHierarchyHelper.MapScenariosActionsOriginals(scenarios);

            SimulateData data = new SimulateData()
            {
                Scenarios          = scenarios,
                ActionTypes        = await context.ActionTypes.ToArrayAsync(),
                CustomFieldsLabels = GetCustomFieldsLabels(project),
            };

            return(data);
        }
예제 #3
0
        /// <summary>
        /// Obtient les données pour l'écran Construire.
        /// </summary>
        /// <param name="context">Le contexte EF.</param>
        /// <param name="projectId">L'identifiant du projet.</param>
        /// <param name="natureFilter">Le filtre sur les codes de nature de scénario.</param>
        /// <returns>Les données</returns>
        public static async Task <BuildData> GetBuildData(KsmedEntities context, int projectId, GetDataScenarioNatures natureFilter)
        {
            IDictionary <ProcessReferentialIdentifier, bool> referentialsUsed = await GetReferentialsUse(context, projectId);

            Referentials referentials = await Queries.LoadAllReferentialsOfProject(context, projectId, referentialsUsed);

            BuildData data = new BuildData
            {
                Categories = referentials.Categories,
                Skills     = referentials.Skills,
                Resources  = referentials.Resources,
                Videos     = await context.Projects
                             .Include(nameof(Project.Process))
                             .Include($"{nameof(Project.Process)}.{nameof(Procedure.Videos)}")
                             .Where(p => p.ProjectId == projectId)
                             .SelectMany(p => p.Process.Videos)
                             .ToArrayAsync(),
                ActionTypes = (await context.ActionTypes.ToArrayAsync()).OrderBy(a => a.ActionTypeCode, new KnownActionCategoryTypes.ActionCategoryTypeDefaultOrderComparer()).ToArray()
            };

            Project project = await context.Projects.SingleAsync(p => p.ProjectId == projectId);

            data.CustomFieldsLabels = GetCustomFieldsLabels(project);

            Scenario[] scenarios = await LoadScenarios(context, projectId, referentialsUsed, natureFilter);

            ScenarioActionHierarchyHelper.MapScenariosActionsOriginals(scenarios);

            data.Scenarios = scenarios;

            return(data);
        }
예제 #4
0
        /// <summary>
        /// Obtient la source de la cause des écarts.
        /// </summary>
        /// <param name="action">L'action où la cause des écarts a changé.</param>
        /// <param name="isFromValidationScenario"><c>true</c> si l'action provient du scénario de validation. <c>false</c> si elle provient du scénario cible.</param>
        /// <param name="targetAction">L'action du scénario cible.</param>
        /// <param name="validationAction">L'action du scénario de validation.</param>
        /// <returns></returns>
        private DifferenceReasonSource GetDifferenceReasonSource(KAction action, out bool isFromValidationScenario,
                                                                 out KAction targetAction, out KAction validationAction)
        {
            isFromValidationScenario = this.SelectedTargetScenario != null && this.SelectedTargetScenario.Actions.Contains(action);

            if (isFromValidationScenario)
            {
                validationAction = action;
                targetAction     = ScenarioActionHierarchyHelper.GetAncestorAction(action, this.SelectedOriginalScenario);
                if (targetAction == null)
                {
                    return(DifferenceReasonSource.FromSourceScenarioNew);
                }
                else
                {
                    return(DifferenceReasonSource.FromBoth);
                }
            }
            else
            {
                targetAction     = action;
                validationAction = ScenarioActionHierarchyHelper.GetDerivedAction(action, this.SelectedTargetScenario);
                if (validationAction == null)
                {
                    return(DifferenceReasonSource.FromTargetScenarioDeleted);
                }
                else
                {
                    return(DifferenceReasonSource.FromBoth);
                }
            }
        }
예제 #5
0
        /// <summary>
        /// Obtient les données pour l'écran Restituer.
        /// </summary>
        /// <param name="context">le contexte EF.</param>
        /// <param name="projectId">L'identifiant du projet.</param>
        /// <returns>
        /// Les données
        /// </returns>
        public static async Task <RestitutionData> GetRestitutionData(KsmedEntities context, int projectId)
        {
            IDictionary <ProcessReferentialIdentifier, bool> referentialsUsed = await GetReferentialsUse(context, projectId);

            Referentials referentials = await Queries.LoadAllReferentialsOfProject(context, projectId, referentialsUsed);

            ActionCategory[] categories = referentials.Categories;
            await context.Projects
            .Include(nameof(Project.Process))
            .Include($"{nameof(Project.Process)}.{nameof(Procedure.Videos)}")
            .Where(p => p.ProjectId == projectId)
            .SelectMany(p => p.Process.Videos)
            .ToArrayAsync();

            Scenario[] scenarios = await context.Scenarios
                                   .Where(s => s.ProjectId == projectId)
                                   .ToArrayAsync();

            await Queries.LoadScenariosDetails(context, scenarios, referentialsUsed);

            ILookup <int, KAction> actionsToLoad = scenarios
                                                   .SelectMany(a => a.Actions)
                                                   .Where(a => a.IsReduced && a.OriginalActionId.HasValue)
                                                   .ToLookup(a => a.OriginalActionId.Value, a => a);

            if (actionsToLoad.Any())
            {
                foreach (ActionDuration duration in await GetActionsBuildDurations(context, actionsToLoad.Select(g => g.Key)))
                {
                    foreach (KAction action in actionsToLoad[duration.ActionId])
                    {
                        action.Reduced.Saving = duration.BuildDuration - action.BuildDuration;
                    }
                }
            }

            ScenarioActionHierarchyHelper.MapScenariosActionsOriginals(scenarios);
            foreach (Scenario scenario in scenarios)
            {
                UpdateIsGroup(scenario);
            }

            RestitutionData data = new RestitutionData()
            {
                Scenarios        = scenarios,
                ActionCategories = categories,
            };

            return(data);
        }
예제 #6
0
        /// <summary>
        /// Exporte les solutions.
        /// </summary>
        /// <param name="scenario">Le scénario.</param>
        /// <param name="cellReference">La référence de la cellule.</param>
        /// <param name="file">Le fichier.</param>
        /// <param name="sheet">La feuille.</param>
        private void ExportSolutions(Scenario scenario, CellReference cellReference, WorksheetPart sheet)
        {
            ITimeTicksFormatService timeFormatService = IoC.Resolve <IServiceBus>().Get <ITimeTicksFormatService>();
            long timeScale = _data.Project.TimeScale;

            List <SolutionWrapper> solutions = new List <SolutionWrapper>();

            foreach (var solution in scenario.Solutions.OrderBy(s => s.SolutionDescription))
            {
                var w = CreateSolutionWrapper(scenario.Actions, solution);
                solutions.Add(w);
            }

            var originalScenario = scenario.Original;

            while (originalScenario != null)
            {
                // Déterminer les actions qui sont concernées
                var originalActions = originalScenario.Actions.Where(originalAction =>
                                                                     scenario.Actions.Any(currentScenarioAction =>
                                                                                          ScenarioActionHierarchyHelper.IsAncestor(originalAction, currentScenarioAction)));

                foreach (var solution in originalScenario.Solutions.OrderBy(s => s.SolutionDescription))
                {
                    var wrapper = CreateSolutionWrapper(originalActions, solution);
                    // Ignorer les solutions qui n'apportent pas de gain. C'est un surplus d'infos inutile
                    if (wrapper.Saving != 0)
                    {
                        solutions.Add(wrapper);
                    }
                }

                originalScenario = originalScenario.Original;
            }

            // Définir l'index
            int i = 1;

            foreach (var wrapper in solutions)
            {
                wrapper.Index = i++;
            }

            var solutionsFormats = new ColumnFormat[]
            {
                #region Format pour les solutions

                // Index
                new ColumnFormat()
                {
                    Header = ""
                },

                // Scénario
                new ColumnFormat()
                {
                    Header = LocalizationManager.GetString("View_RestitutionSolutions_Columns_Scenario")
                },

                // Solution
                new ColumnFormat()
                {
                    Header = LocalizationManager.GetString("View_RestitutionSolutions_Columns_Solution")
                },

                // Tâches liées
                new ColumnFormat()
                {
                    Header = LocalizationManager.GetString("View_RestitutionSolutions_Columns_RelatedActions")
                },

                // Gain
                new ColumnFormat()
                {
                    Header = LocalizationManager.GetString("View_RestitutionSolutions_Columns_Saving")
                },

                // Investissement
                new ColumnFormat()
                {
                    Header = LocalizationManager.GetString("View_RestitutionSolutions_Columns_Investment")
                },

                // I/G
                new ColumnFormat()
                {
                    Header = LocalizationManager.GetString("View_RestitutionSolutions_Columns_IG")
                },

                // Difficulté
                new ColumnFormat()
                {
                    Header = LocalizationManager.GetString("View_RestitutionSolutions_Columns_Diffculty")
                },

                // Coûts
                new ColumnFormat()
                {
                    Header = LocalizationManager.GetString("View_RestitutionSolutions_Columns_Cost")
                },

                // DC/G
                new ColumnFormat()
                {
                    Header = LocalizationManager.GetString("View_RestitutionSolutions_Columns_DCG")
                },

                // OK
                new ColumnFormat()
                {
                    Header = LocalizationManager.GetString("View_RestitutionSolutions_Columns_OK")
                },

                // Comments
                new ColumnFormat()
                {
                    Header = LocalizationManager.GetString("View_RestitutionSolutions_Columns_Comments")
                },

                #endregion
            };

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

            i = 0;
            foreach (var solution in solutions)
            {
                CellContent[] row = new CellContent[solutionsFormats.Length];

                int j = 0;

                #region Data

                // Index
                row[j++] = solution.Index;

                // Scénario
                row[j++] = solution.Solution.Scenario.Label;

                // Solution
                row[j++] = solution.Solution.SolutionDescription;

                // Tâches liées
                row[j++] = solution.RelatedActions;

                // Gain
                row[j++] = CellContent.TimeSpan(timeFormatService.RoundTime(solution.Saving, timeScale));

                // Investissement
                if (solution.Solution.Investment.HasValue)
                {
                    row[j++] = solution.Solution.Investment;
                }
                else
                {
                    row[j++] = null;
                }

                // I/G
                if (solution.IG.HasValue)
                {
                    row[j++] = solution.IG;
                }
                else
                {
                    row[j++] = null;
                }

                // Difficulté
                if (solution.Solution.Difficulty.HasValue)
                {
                    row[j++] = solution.Solution.Difficulty;
                }
                else
                {
                    row[j++] = null;
                }

                // Coûts
                if (solution.Solution.Cost.HasValue)
                {
                    row[j++] = solution.Solution.Cost;
                }
                else
                {
                    row[j++] = null;
                }

                // DC/G
                if (solution.DCG.HasValue)
                {
                    row[j++] = solution.DCG;
                }
                else
                {
                    row[j++] = null;
                }

                // OK
                row[j++] = solution.Solution.Approved.ToString();

                // Comments
                row[j++] = solution.Solution.Comments;

                #endregion

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

            _file.AddTable(sheet, solutionsFormats, data, cellReference);
        }
예제 #7
0
        /// <summary>
        /// Obtient les données pour l'écran Acquérir.
        /// </summary>
        /// <param name="context">Le contexte EF.</param>
        /// <param name="projectId">L'identifiant du projet.</param>
        /// <param name="natureFilter">Le filtre sur les codes de nature de scénario.</param>
        /// <returns>
        /// Les données
        /// </returns>
        public static async Task <AcquireData> GetAcquireData(KsmedEntities context, int projectId, GetDataScenarioNatures natureFilter)
        {
            IDictionary <ProcessReferentialIdentifier, bool> referentialsUsed = await GetReferentialsUse(context, projectId);

            int processId = (await context.Projects.SingleAsync(p => p.ProjectId == projectId)).ProcessId;

            AcquireData data = new AcquireData
            {
                Categories = await Queries.FilterReferentials(context.ActionCategories, processId, ProcessReferentialIdentifier.Category).ToArrayAsync(),
                Skills     = await Queries.FilterReferentials(context.Skills, processId, ProcessReferentialIdentifier.Skill).ToArrayAsync(),
                Resources  = await Queries.FilterResources(context, processId).ToArrayAsync(),
                Videos     = await context.Projects
                             .Include(nameof(Project.Process))
                             .Include($"{nameof(Project.Process)}.{nameof(Procedure.Videos)}")
                             .Where(p => p.ProjectId == projectId)
                             .SelectMany(p => p.Process.Videos)
                             .OrderBy(v => v.CameraName).OrderBy(v => v.DefaultResourceId).OrderBy(v => v.ResourceView).OrderBy(v => v.ShootingDate)
                             .ToArrayAsync()
            };

            if (referentialsUsed[ProcessReferentialIdentifier.Ref1])
            {
                data.Ref1s = await Queries.FilterReferentials(context.Refs1, processId, ProcessReferentialIdentifier.Ref1).ToArrayAsync();
            }

            if (referentialsUsed[ProcessReferentialIdentifier.Ref2])
            {
                data.Ref2s = await Queries.FilterReferentials(context.Refs2, processId, ProcessReferentialIdentifier.Ref2).ToArrayAsync();
            }

            if (referentialsUsed[ProcessReferentialIdentifier.Ref3])
            {
                data.Ref3s = await Queries.FilterReferentials(context.Refs3, processId, ProcessReferentialIdentifier.Ref3).ToArrayAsync();
            }

            if (referentialsUsed[ProcessReferentialIdentifier.Ref4])
            {
                data.Ref4s = await Queries.FilterReferentials(context.Refs4, processId, ProcessReferentialIdentifier.Ref4).ToArrayAsync();
            }

            if (referentialsUsed[ProcessReferentialIdentifier.Ref5])
            {
                data.Ref5s = await Queries.FilterReferentials(context.Refs5, processId, ProcessReferentialIdentifier.Ref5).ToArrayAsync();
            }

            if (referentialsUsed[ProcessReferentialIdentifier.Ref6])
            {
                data.Ref6s = await Queries.FilterReferentials(context.Refs6, processId, ProcessReferentialIdentifier.Ref6).ToArrayAsync();
            }

            if (referentialsUsed[ProcessReferentialIdentifier.Ref7])
            {
                data.Ref7s = await Queries.FilterReferentials(context.Refs7, processId, ProcessReferentialIdentifier.Ref7).ToArrayAsync();
            }

            Project project = await context.Projects.Include(nameof(Project.Process)).SingleAsync(p => p.ProjectId == projectId);

            data.CustomFieldsLabels = GetCustomFieldsLabels(project);

            Scenario[] scenarios = null;
            Scenario[] scenariosUsedForMapping = null;

            if (natureFilter == GetDataScenarioNatures.InitialAndTarget)
            {
                // Il y a tout ce qu'il faut pour faire le mapping dans les scenarii chargés
                scenariosUsedForMapping = await LoadScenarios(context, projectId, referentialsUsed, GetDataScenarioNatures.InitialAndTarget);

                scenarios = scenariosUsedForMapping;
            }
            else if (natureFilter == GetDataScenarioNatures.Realized)
            {
                // Il faut charger au moins les scenarii cibles également
                scenariosUsedForMapping = await LoadScenarios(context, projectId, referentialsUsed, GetDataScenarioNatures.All);

                scenarios = scenariosUsedForMapping.Where(scenario => scenario.NatureCode == KnownScenarioNatures.Realized).ToArray();
            }
            else
            {
                // Le cas all à priori, on considère de toute façon qu'il s'agit du cas par défaut
                scenariosUsedForMapping = await LoadScenarios(context, projectId, referentialsUsed, natureFilter);

                scenarios = scenariosUsedForMapping;
            }

            ScenarioActionHierarchyHelper.MapScenariosActionsOriginals(scenariosUsedForMapping);

            data.Scenarios = scenarios;

            return(data);
        }
예제 #8
0
        /// <summary>
        /// Charge le scénario spécifié.
        /// </summary>
        private void LoadScenario(Scenario oldScenario, Scenario newScenario)
        {
            if (oldScenario == newScenario)
            {
                return;
            }

            _scenario = newScenario;

            if (oldScenario != null)
            {
                foreach (var solution in oldScenario.Solutions)
                {
                    base.UnregisterToStateChanged(solution);
                    solution.StopTracking();
                }
            }

            if (newScenario != null)
            {
                var solutions = new List <SolutionWrapper>();

                // On ne doit pas afficher les solutions du scénario de validation et du scénario initial
                if (newScenario.NatureCode != KnownScenarioNatures.Realized && newScenario.NatureCode != KnownScenarioNatures.Initial)
                {
                    foreach (var solution in newScenario.Solutions.OrderBy(s => s.SolutionDescription))
                    {
                        var w = CreateSolutionWrapper(newScenario.Actions, solution);
                        w.IsNotReadOnly = true;
                        solutions.Add(w);
                    }
                }

                var originalScenario = newScenario.Original;
                while (originalScenario != null)
                {
                    // On ne doit pas afficher le scénario initial
                    if (originalScenario.NatureCode == KnownScenarioNatures.Initial)
                    {
                        break;
                    }

                    // Déterminer les actions qui sont concernées
                    var originalActions = originalScenario.Actions.Where(originalAction =>
                                                                         newScenario.Actions.Any(currentScenarioAction =>
                                                                                                 ScenarioActionHierarchyHelper.IsAncestor(originalAction, currentScenarioAction)));

                    foreach (var solution in originalScenario.Solutions.OrderBy(s => s.SolutionDescription))
                    {
                        var wrapper = CreateSolutionWrapper(originalActions, solution);
                        // Ignorer les solutions qui n'apportent pas de gain. C'est un surplus d'infos inutile
                        if (wrapper.Saving != 0)
                        {
                            solutions.Add(wrapper);
                        }
                    }

                    originalScenario = originalScenario.Original;
                }

                // Définir l'index
                int i = 1;
                foreach (var wrapper in solutions)
                {
                    wrapper.Index = i++;
                }

                this.Solutions = solutions.ToArray();
            }
            else
            {
                this.Solutions = null;
            }
        }
예제 #9
0
        /// <summary>
        /// Obtient toutes les données du projet spécifié.
        /// </summary>
        /// <param name="projectId">L'identifiant du projet.</param>
        public virtual async Task <RestitutionData> GetFullProjectDetails(int projectId) =>
        await Task.Run(async() =>
        {
            using (var context = ContextFactory.GetNewContext(_securityContext.CurrentUser, _localizationManager))
            {
                IDictionary <ProcessReferentialIdentifier, bool> referentialsUsed = await _sharedScenarioActionsOperations.GetReferentialsUse(context, projectId);
                Referentials referentials = await Queries.LoadAllReferentialsOfProject(context, projectId, referentialsUsed);

                //await context.Videos.Where(v => v.ProjectId == projectId).ToArrayAsync();
                await context.ScenarioNatures.ToArrayAsync();
                await context.ScenarioStates.ToArrayAsync();
                await context.ActionTypes.ToArrayAsync();
                await context.ActionValues.ToArrayAsync();

                Project project = await context.Projects
                                  .Include(nameof(Project.Process))
                                  .Include($"{nameof(Project.Process)}.{nameof(Procedure.Videos)}")
                                  .Include($"{nameof(Project.Process)}.{nameof(Procedure.UserRoleProcesses)}")
                                  .Include($"{nameof(Project.Process)}.{nameof(Procedure.UserRoleProcesses)}.{nameof(UserRoleProcess.User)}")
                                  .Include($"{nameof(Project.Process)}.{nameof(Procedure.UserRoleProcesses)}.{nameof(UserRoleProcess.User)}.{nameof(User.DefaultLanguage)}")
                                  .Include(nameof(Project.Scenarios))
                                  .Include($"{nameof(Project.Scenarios)}.{nameof(Scenario.Actions)}")
                                  .Include(nameof(Project.Objective))
                                  .FirstAsync(s => s.ProjectId == projectId);

                project.ScenariosCriticalPath = PrepareService.GetSummary(project, true);

                // Scénarios
                foreach (Scenario scenario in project.Scenarios.Where(s => s.OriginalScenarioId.HasValue))
                {
                    // Remapper l'original
                    scenario.Original = project.Scenarios.Single(s => s.ScenarioId == scenario.OriginalScenarioId);

                    ScenarioCriticalPath matchingCriticalItem = project.ScenariosCriticalPath.FirstOrDefault(i => i.Id == scenario.ScenarioId);
                    if (matchingCriticalItem != null)
                    {
                        matchingCriticalItem.OriginalLabel = scenario.Original.Label;
                    }
                }

                ProjectReferential[] projectReferentials = await context.ProjectReferentials.Where(pr => pr.ProjectId == projectId).ToArrayAsync();

                User user = await context.Users.FirstAsync(u => u.UserId == project.CreatedByUserId);

                ModificationsUsers modificationsUsers = new ModificationsUsers
                {
                    CreatedByFullName      = (await context.Users.FirstAsync(u => u.UserId == project.ModifiedByUserId)).FullName,
                    LastModifiedByFullName = (await context.Users.FirstAsync(u => u.UserId == project.ModifiedByUserId)).FullName
                };

                Scenario[] scenarios = await context.Scenarios
                                       .Where(s => s.ProjectId == projectId)
                                       .ToArrayAsync();

                await Queries.LoadScenariosDetails(context, scenarios, referentialsUsed);

                ILookup <int, KAction> actionsToLoad = scenarios
                                                       .SelectMany(a => a.Actions)
                                                       .Where(a => a.IsReduced && a.OriginalActionId.HasValue)
                                                       .ToLookup(a => a.OriginalActionId.Value, a => a);

                if (actionsToLoad.Any())
                {
                    foreach (var duration in await _sharedScenarioActionsOperations.GetActionsBuildDurations(context, actionsToLoad.Select(g => g.Key)))
                    {
                        foreach (KAction action in actionsToLoad[duration.ActionId])
                        {
                            action.Reduced.Saving = duration.BuildDuration - action.BuildDuration;
                        }
                    }
                }

                ScenarioActionHierarchyHelper.MapScenariosActionsOriginals(scenarios);

                return(new RestitutionData()
                {
                    Project = project,
                    ProjectCreatedByUser = user,
                    Scenarios = scenarios,
                    ActionCategories = referentials.Categories,
                    ModificationsUsers = modificationsUsers,
                    ReferentialsUse = projectReferentials,
                });
            }
        });
예제 #10
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());
        }
예제 #11
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);
            }
        }