/// <summary> /// This takes an UpdatePackage, which represents an email, and records it to the database /// </summary> /// <param name="package">An UpdatePackage is a normalized email</param> /// <returns>Guid of updated project as a string. /// Useful if this project is new or caller wants to retreive other data on that project</returns> public string RecordUpdatePackage(UpdatePackage package) { //__get the information from input string projectName = package.ProjectName; string subject = package.Subject; string body = package.Body; if (string.IsNullOrEmpty(projectName)) return null; Dictionary<string, string> updatePairs = package.Updates; Project project = context.Projects.FirstOrDefault(p => p.ProjectName == projectName); //__if no existing project, create new one bool madeNewProject = false; if (project == null) { project = new Project(); project.ProjectID = Guid.NewGuid(); madeNewProject = true; } //__get the Project ID to use locally Guid projectID = project.ProjectID; //__Look for VerticalID int verticalID = -1;//__default is not assigned. try { KeyValuePair<string, string> verticalPair = updatePairs.FirstOrDefault(u => u.Key.ToLower() == "verticalid"); if (verticalPair.Value != null) verticalID = Convert.ToInt16(verticalPair.Value); if (verticalID < -1 || verticalID > 8) verticalID = -1; } catch (Exception) { //__just use default value verticalID = -1; } //__these might be new or changed project.VerticalID = verticalID; project.ProjectName = projectName; //__Look for a PhaseID int phaseID = -1; try { KeyValuePair<string, string> phasePair = updatePairs.FirstOrDefault(u => u.Key.ToLower() == "phaseid"); if (phasePair.Value != null) phaseID = Convert.ToInt16(phasePair.Value); if (phaseID < -1 || phaseID > 7) phaseID = -1; } catch (Exception) { //_simply use default phaseID = -1; } //__do fuzzy word matches if no phase found yet if (phaseID < 0) { string searchString = subject + body; phaseID = Convert.ToInt16(PhaseKeywords.GuessPhase(searchString)); } //__if this is new Project write it to DB if (madeNewProject) { context.Projects.Add(project); context.SaveChanges(); } //__create and record new ProjectUpdate ProjectUpdate projectUpdate = new ProjectUpdate(); projectUpdate.ProjectUpdateID = Guid.NewGuid(); projectUpdate.ProjectID = projectID; projectUpdate.Subject = subject; projectUpdate.Body = body; context.ProjectUpdates.Add(projectUpdate); context.SaveChanges(); //__build and record StatusUpdates from list of Key:Value pairs //__also make sure to update ProjectPhase table for efficient queries later StatusUpdate statusUpdateTemplate = new StatusUpdate(); statusUpdateTemplate.ProjectID = projectID; statusUpdateTemplate.ProjectUpdateID = projectUpdate.ProjectUpdateID; statusUpdateTemplate.PhaseID = phaseID; statusUpdateTemplate.VerticalID = verticalID; //__safety, incase of duplicate keys, combine the values so there is only one entry //___trying to record duplicate keys in the same PackageUpdate will cause primary key error in DB Dictionary<string, string> cleanedPairs = combineEqualKeys(updatePairs); foreach (var pair in cleanedPairs) { string key = pair.Key; string value = pair.Value; StatusUpdate statusUpdate = statusUpdateTemplate.Clone(); statusUpdate.UpdateKey = key; statusUpdate.UpdateValue = value; statusUpdate.RecordDate = DateTime.Now; context.StatusUpdates.Add(statusUpdate); context.SaveChanges(); updateProjectPhase(projectID, phaseID, key); } return projectID.ToString(); }
/// <summary> /// Originally this would update each related StatusUpdate, and the entries in ProjectPhase, but this was commented /// out since the ProjectPhase table is not currently in use. Instead, each StatusUpdate which came from the associated /// ProjectUpdate is modified with the new PhaseID /// </summary> /// <param name="update">An representative StatusUpdate, it is only used to get ProjectUpdateID</param> /// <param name="newPhase">An integer representing the new PhaseID</param> /// <returns>True or False to indicate success or failure</returns> public bool ChangeProjectUpdatePhase(StatusUpdate update, int newPhase) { if (update == null || newPhase < 0 || newPhase > Enum.GetNames(typeof(Phases)).Length) return false; //int oldPhase = update.PhaseID.Value; //Guid projectID = update.ProjectID; //string updateKey = update.UpdateKey; Guid projectUpdateID = update.ProjectUpdateID; var updates = context.StatusUpdates.Where(u => u.ProjectUpdateID == projectUpdateID); foreach (StatusUpdate statusUpdate in updates) { statusUpdate.PhaseID = newPhase; ////__also update any related entries in ProjectPhase table //ProjectPhase pp = context.ProjectPhases.FirstOrDefault(p => p.ProjectID == projectID // && p.UpdateKey == updateKey); //if (pp != null) pp.PhaseID = newPhase; } context.SaveChanges(); return true; }
public static List<ProjectUpdate> GenerateUpdates(int numberOfProjects) { List<ProjectUpdate> projectUpdates = new List<ProjectUpdate>(); List<String> usedNames = new List<string>() { "Start" }; Random rnd = new Random(); DateTime now = DateTime.Now; for (int n = 0; n < 7; n++)//__loop through the number of Verticals { for (int i = 0; i < numberOfProjects; i++)//__create this many projects { Guid projectID = Guid.NewGuid(); string projectName = "Start"; while (usedNames.Contains(projectName)) { int nameIndex = rnd.Next(8); int typeIndex = rnd.Next(10); projectName = projectNames[nameIndex] + " " + projectTypes[typeIndex] + "-V" + n; } int verticalID = n;// rnd.Next(7); int iNumPhases = rnd.Next(7); for (int p = 0; p < iNumPhases; p++)//__loop through this number of phases { int iNumberEmails = rnd.Next(12) + 1; for (int m = 0; m < iNumberEmails; m++)//__generate m emails for this Project, Phase { //__we want only 1 Environment and 1 Task per email bool TaskNotRecorded = true; bool EnvironmentNotRecorded = true; List<string> usedIdentifiers = new List<string>(); ProjectUpdate newProjectUpdate = new ProjectUpdate(); int numberOfDataPoints = rnd.Next(11) + 1; for (int k = 0; k < numberOfDataPoints; k++)//__generate k data points for this email { StatusUpdate update = new StatusUpdate(); update.ProjectID = projectID; update.ProjectName = projectName; update.PhaseID = p-1; update.VerticalID = n-1; update.RecordDate = now; if (rnd.Next(10) > 2) //___adjust by some random number of days { update.RecordDate = now.Subtract(TimeSpan.FromDays(rnd.Next(60) + 1)); } int doTagSwitch = rnd.Next(6); if (doTagSwitch < 3 && EnvironmentNotRecorded) { update.UpdateKey = "Environment"; update.UpdateValue = "System #" + rnd.Next(12); EnvironmentNotRecorded = false; } else if (doTagSwitch < 3 && TaskNotRecorded) { update.UpdateKey = "Task"; update.UpdateValue = "Task #" + rnd.Next(7); TaskNotRecorded = false; } else { string identifier = rnd.Next(8) + "." + rnd.Next(8); //__ensure there are no duplicate keys in a given email while(usedIdentifiers.Contains(identifier)) identifier = rnd.Next(8) + "." + rnd.Next(8); update.UpdateKey = "Key." + identifier; update.UpdateValue = "Value." + identifier; } newProjectUpdate.StatusUpdates.Add(update); }//__end loop through data points projectUpdates.Add(newProjectUpdate);//__Add this email to the list to return }//__end loop through emails }//__end loop through Phases }//__end loop through Projects }//__end loop through Verticals return projectUpdates; }