/// <summary> /// Find those status types in the database that are not being used by any step. /// </summary> /// <returns>The total number of orphaned items found</returns> private int UpdateOrphanedStatusTypes() { Dictionary <int, int> usedStatusTypes = new Dictionary <int, int>(); IJTXDatabase3 wmxDb = this.WmxDatabase; string[] coreStatusNames = { C_STATUS_CLOSED, C_STATUS_CREATED, C_STATUS_DONE_WORKING, C_STATUS_READY_TO_WORK, C_STATUS_WORKING }; IJTXConfiguration3 configMgr = wmxDb.ConfigurationManager as IJTXConfiguration3; // Iterate through each job currently in the system, adding the status types used // by these jobs IJTXJobSet jobs = wmxDb.JobManager.GetAllJobs(); for (int i = 0; i < jobs.Count; i++) { IJTXJob3 job = jobs.get_Item(i) as IJTXJob3; if (job.Status != null) { usedStatusTypes[job.Status.ID] = job.Status.ID; } } // Iterate through each workflow, building up the list of used status types // based on the statuses that are assigned by each step IJTXWorkflowSet workflows = configMgr.Workflows; for (int i = 0; i < workflows.Count; i++) { // Skip over those workflows that aren't in use IJTXWorkflow workflow = workflows.get_Item(i); if (m_unusedWorkflows.Keys.Contains(workflow.ID)) { continue; } // Examine the remaining workflows IJTXWorkflowConfiguration workflowCfg = workflows.get_Item(i) as IJTXWorkflowConfiguration; int[] stepIds = workflowCfg.GetAllSteps(); foreach (int stepId in stepIds) { IJTXStep3 step = workflowCfg.GetStep(stepId) as IJTXStep3; usedStatusTypes[step.StatusID] = step.StatusID; } } // Add the status types used by Workflow Manager itself foreach (string s in coreStatusNames) { IJTXStatus2 status = configMgr.GetStatus(s) as IJTXStatus2; // Avoid problems if someone deleted one of these mandatory types from the database if (status != null) { int id = status.ID; usedStatusTypes[id] = id; } } // Get the complete list of status types in the database IJTXStatusSet allStatusTypes = configMgr.Statuses; // Loop over all of the status types. For anything whose ID is not contained // in the "used" list, add it to the "unused" list. If all of the items are // used, don't bother trying to add to the unused list. if (usedStatusTypes.Count != allStatusTypes.Count) { for (int i = 0; i < allStatusTypes.Count; i++) { IJTXStatus2 statusType = allStatusTypes.get_Item(i) as IJTXStatus2; if (!usedStatusTypes.ContainsKey(statusType.ID)) { m_unusedStatusTypes[statusType.ID] = statusType.Name; } } } return(m_unusedStatusTypes.Count); }
/// <summary> /// Helper function that runs all of those checks that operate on each step in /// every workflow; intended to make the checks slightly more efficient by running /// through them all at once rather than looping through all of the elements /// multiple times /// </summary> /// <param name="msgs">Add any GP messages to this object</param> /// <param name="errorCount">Counter used to track the number of problems found</param> /// <param name="logFileWriter">Object used to write error descriptions to a text file</param> private void ExecuteWorkflowStepChecks(IGPMessages msgs, ref int errorCount, StreamWriter logFileWriter) { // Only continue executing this function if needed if (!m_flagInvalidStepAssign && !m_flagUnassignedSteps && !m_flagZeroPctSteps && !m_flagDifferingStepNames) { return; } IJTXConfiguration3 configMgr = this.WmxDatabase.ConfigurationManager as IJTXConfiguration3; IJTXConfigurationEdit2 configEdit = configMgr as IJTXConfigurationEdit2; // Put the items into a sorted list in order to make the output easier to // read/follow IJTXWorkflowSet allWorkflows = configMgr.Workflows; SortedList <string, IJTXWorkflow> allWorkflowsSorted = new SortedList <string, IJTXWorkflow>(); for (int i = 0; i < allWorkflows.Count; i++) { allWorkflowsSorted[allWorkflows.get_Item(i).Name] = allWorkflows.get_Item(i); } // Iterate through each item foreach (IJTXWorkflow workflow in allWorkflowsSorted.Values) { IJTXWorkflowConfiguration workflowCfg = workflow as IJTXWorkflowConfiguration; int[] allStepIds = workflowCfg.GetAllSteps(); foreach (int j in allStepIds) { IJTXStep3 step = workflowCfg.GetStep(j) as IJTXStep3; string assignedTo = step.AssignedTo; // Check for any default step types with an invalid step assignment if (m_flagInvalidStepAssign) { if (step.AssignedType == jtxAssignmentType.jtxAssignmentTypeUser && configMgr.GetUser(assignedTo) == null) { string message = "Workflow '" + workflow.Name + "', step '" + step.StepName + "' assigned to unknown user '" + assignedTo + "'"; RecordMessage(message, msgs, logFileWriter); errorCount++; } else if (step.AssignedType == jtxAssignmentType.jtxAssignmentTypeGroup && configMgr.GetUserGroup(assignedTo) == null) { string message = "Workflow '" + workflow.Name + "', step '" + step.StepName + "' assigned to unknown group '" + assignedTo + "'"; RecordMessage(message, msgs, logFileWriter); errorCount++; } } // Check for any steps that have not been assigned to a group or user if (m_flagUnassignedSteps) { if (step.AssignedType == jtxAssignmentType.jtxAssignmentTypeUnassigned) { string message = "Workflow '" + workflow.Name + "', step '" + step.StepName + "' is unassigned"; RecordMessage(message, msgs, logFileWriter); errorCount++; } } // Check for any steps whose "post-complete" percentage is 0 if (m_flagZeroPctSteps) { if (step.DefaultPercComplete < double.Epsilon) { string message = "Workflow '" + workflow.Name + "', step '" + step.StepName + "' sets percent complete to 0"; RecordMessage(message, msgs, logFileWriter); errorCount++; } } // Check for any steps whose descriptions in a workflow does not match // the underlying step type name if (m_flagDifferingStepNames) { IJTXStepType2 stepType = configMgr.GetStepTypeByID(step.StepTypeID) as IJTXStepType2; if (!step.StepName.Equals(stepType.Name)) { string message = "Workflow '" + workflow.Name + "', step name '" + step.StepName + "' does not match step type name '" + stepType.Name + "'"; RecordMessage(message, msgs, logFileWriter); errorCount++; } } } // end for each step } // end for each workflow }