private static void StartBuidingReport(WebClient client, DateTime reportStartDate, DateTime reportEndDate, StreamWriter sw, String reportType) { //temp file to buid summary section StreamWriter summaryFile = new StreamWriter(sHTMLSummaryFile, false, Encoding.UTF8); StreamReader sr = new StreamReader(ReportPath + "Summary_Header.html"); String content = sr.ReadToEnd(); summaryFile.Write(content); summaryFile.Close(); bool projectAdded2Report = false; //get collection of projects ProjectsCollection projectsCollection = JsonConvert.DeserializeObject <ProjectsCollection>(client.DownloadString(PathToTp + "projects?" + ProjectSelectionFields + "&where=(IsActive eq 'true')" + ProjectExclutionCondition + " &take=1000&format=json" + token)); //excelude Dmitry Mironov's personal tasks //project acid property //String acid = ""; ShowInConsole("Total projects: " + projectsCollection.Items.Count()); //check that projec collection has at least one project if (projectsCollection.Items.Count > 0) { bool AddProjectToSummaryLeft = true; //for each project check if there are any userstories or bugs foreach (Project project in projectsCollection.Items) { //get project acid ShowInConsole("Getting project ACID."); ProjectContext projectContext = JsonConvert.DeserializeObject <ProjectContext>(client.DownloadString(PathToTp + "Context/?ids=" + project.Id + "&format=json" + token)); //TeamIterationsCollection tic = JsonConvert.DeserializeObject<TeamIterationsCollection>(client.DownloadString(PathToTp + "teamiterations?where=(IsCurrent eq 'true')&format=json" + token)); TeamIteration teamIteration = JsonConvert.DeserializeObject <TeamIterationsCollection>(client.DownloadString(PathToTp + "teamiterations?where=(IsCurrent eq 'true')&format=json" + token)).Items[0]; ShowInConsole("Start processing project : " + project.Id + " : " + project.Name); //preparing all collections we need for the report ShowInConsole("Start processing UserStories and Bugs for the project."); string queryCondition = ""; #region Collections : Completed //Completed UserStoriesCollection userStoriesCollection_Done = JsonConvert.DeserializeObject <UserStoriesCollection>(client.DownloadString(PathToTp + "UserStories?" + UserStorySelectionFields + "&where=(Project.Id eq " + project.Id + ") and (ModifyDate gte '" + reportStartDate.ToString("yyyy-MM-dd") + "') and (ModifyDate lte '" + reportEndDate.ToString("yyyy-MM-dd") + "') and (EntityState.Name eq 'Done')&take=1000&format=json" + token)); BugsCollection bugsCollection_Done = JsonConvert.DeserializeObject <BugsCollection>(client.DownloadString(PathToTp + "Bugs?" + BugSelectionFields + "&where=(Project.Id eq " + project.Id + ") and (ModifyDate gte '" + reportStartDate.ToString("yyyy-MM-dd") + "') and (ModifyDate lte '" + reportEndDate.ToString("yyyy-MM-dd") + "') and (EntityState.Name eq 'Done')&take=1000&format=json" + token)); UserStoriesCollection userStoriesCollection_R2R = JsonConvert.DeserializeObject <UserStoriesCollection>(client.DownloadString(PathToTp + "UserStories?" + UserStorySelectionFields + "&where=(Project.Id eq " + project.Id + ") and (EntityState.Name eq 'Ready to release') and (ModifyDate gte '" + reportStartDate.ToString("yyyy-MM-dd") + "') and (ModifyDate lte '" + reportEndDate.ToString("yyyy-MM-dd") + "')&take=1000&format=json" + token)); BugsCollection bugsCollection_R2R = JsonConvert.DeserializeObject <BugsCollection>(client.DownloadString(PathToTp + "Bugs?" + BugSelectionFields + "&where=(Project.Id eq " + project.Id + ") and (EntityState.Name eq 'Ready to release') and (ModifyDate gte '" + reportStartDate.ToString("yyyy-MM-dd") + "') and (ModifyDate lte '" + reportEndDate.ToString("yyyy-MM-dd") + "')&take=1000&format=json" + token)); #endregion #region Collections : Work In Progress (Weekly) / Modified (Daily) switch (reportType) { case "Daily": //queryCondition = "(Project.Id eq " + project.Id + ") and (EntityState.name ne 'Open') and (EntityState.name ne 'Planned') and (EntityState.name ne 'User Acceptance Testing') and (EntityState.name ne 'Ready to release') and (EntityState.name ne 'Done') and (ModifyDate gte '" + reportStartDate.ToString("yyyy-MM-dd") + "') and (ModifyDate lte '" + reportEndDate.ToString("yyyy-MM-dd") + "') and (CreateDate ne '" + reportStartDate.ToString("yyyy-MM-dd") + "')"; queryCondition = "(Project.Id eq " + project.Id + ") and (EntityState.name ne 'Open') and (EntityState.name ne 'Planned') and (EntityState.name ne 'User Acceptance Testing') and (EntityState.name ne 'Ready to release') and (EntityState.name ne 'Done') and (CreateDate ne '" + reportStartDate.ToString("yyyy-MM-dd") + "')"; break; case "Weekly": if (project.Process.Name.Equals("Scrum")) { queryCondition = "(Project.Id eq " + project.Id + ") and (EntityState.name ne 'Open') and (EntityState.name ne 'Planned') and (EntityState.name ne 'User Acceptance Testing') and (EntityState.name ne 'Ready to release') and (EntityState.name ne 'Done') and (TeamIteration.ID eq " + teamIteration.Id + ")"; } else { queryCondition = "(Project.Id eq " + project.Id + ") and (EntityState.name ne 'Open') and (EntityState.name ne 'Planned') and (EntityState.name ne 'User Acceptance Testing') and (EntityState.name ne 'Ready to release') and (EntityState.name ne 'Done')"; } break; //case "Custom": // queryCondition = "(Project.Id eq " + project.Id + ") and (EntityState.name ne 'Open') and (EntityState.name ne 'Planned') and (EntityState.name ne 'User Acceptance Testing') and (EntityState.name ne 'Ready to release') and (EntityState.name ne 'Done') and (ModifyDate gte '" + reportStartDate.ToString("yyyy-MM-dd") + "') and (ModifyDate lte '" + reportEndDate.ToString("yyyy-MM-dd") + "')"; // break; } BugsCollection bugsCollection_InProgress = JsonConvert.DeserializeObject <BugsCollection>(client.DownloadString(PathToTp + "Bugs?" + BugSelectionFields + "&where=" + queryCondition + "&take=1000&format=json" + token)); UserStoriesCollection userStoriesCollection_InProgress = JsonConvert.DeserializeObject <UserStoriesCollection>(client.DownloadString(PathToTp + "UserStories?" + UserStorySelectionFields + "&where=" + queryCondition + "&take=1000&format=json" + token)); List <UserStory> us_WIP = new List <UserStory>(); if (userStoriesCollection_InProgress.Items.Count > 0) { //отбираем только измененные за отчетный период стори либо стори, у ктороых были изменены таски. foreach (UserStory story in userStoriesCollection_InProgress.Items.ToList <UserStory>()) { if (story.ModifyDate.Date >= reportStartDate.Date && story.ModifyDate.Date <= reportEndDate.Date) { us_WIP.Add(story); } else { //сама стори не менялась, проверяем ее таски на изменения //string s = "tasks?where=(UserStory.id eq " + story.Id + ") and (ModifyDate gte '" + reportStartDate.ToString("yyyy-MM-dd") + "') and (ModifyDate lte '" + reportEndDate.ToString("yyyy-MM-dd") + "')&take=1000&format=json" + token; TasksCollection tc = JsonConvert.DeserializeObject <TasksCollection>(client.DownloadString(PathToTp + "tasks?where=(UserStory.id eq " + story.Id + ") and (ModifyDate gte '" + reportStartDate.ToString("yyyy-MM-dd") + "') and (ModifyDate lte '" + reportEndDate.ToString("yyyy-MM-dd") + "')&take=1000&format=json" + token)); if (tc.Items.Count > 0) { //есть таски измененные в отчетный период, добавляем стори в коллекцию us_WIP.Add(story); } } } } #endregion "Work In Progress" #region Collections : Planned //Planned switch (reportType) { case "Daily": queryCondition = "(Project.Id eq " + project.Id + ") and (EntityState.name eq 'Planned')"; break; case "Weekly": if (project.Process.Name.Equals("Scrum")) { queryCondition = "(Project.Id eq " + project.Id + ") and (EntityState.name eq 'Open') and (TeamIteration.ID eq " + teamIteration.Id + ")"; } else { //queryCondition = "(Project.Id eq " + project.Id + ") and (EntityState.name eq 'Open')"; //Женя попросил сделать queryCondition = "(Project.Id eq " + project.Id + ") and (EntityState.name eq 'Planned')"; } break; } UserStoriesCollection userStoriesCollection_Planned = JsonConvert.DeserializeObject <UserStoriesCollection>(client.DownloadString(PathToTp + "UserStories?" + UserStorySelectionFields + "&where=" + queryCondition + "&take=1000&format=json" + token)); BugsCollection bugsCollection_Planned = JsonConvert.DeserializeObject <BugsCollection>(client.DownloadString(PathToTp + "Bugs?" + BugSelectionFields + "&where=" + queryCondition + "&take=1000&format=json" + token)); //TO-DO: add selection for Scrum projects as well. #endregion #region Collections : UAT //User Accesptance testing UserStoriesCollection userStoriesCollection_UAT = JsonConvert.DeserializeObject <UserStoriesCollection>(client.DownloadString(PathToTp + "UserStories?" + UserStorySelectionFields + "&where=(Project.Id eq " + project.Id + ") and (EntityState.name eq 'User Acceptance testing')&take=1000&format=json" + token)); BugsCollection bugsCollection_UAT = JsonConvert.DeserializeObject <BugsCollection>(client.DownloadString(PathToTp + "Bugs?" + BugSelectionFields + "&where=(Project.Id eq " + project.Id + ") and (EntityState.name eq 'User Acceptance testing')&take=1000&format=json" + token)); #endregion #region Collections : Added UserStoriesCollection userStoriesCollection_Added = JsonConvert.DeserializeObject <UserStoriesCollection>(client.DownloadString(PathToTp + "UserStories?" + UserStorySelectionFields + "&where=(Project.Id eq " + project.Id + ") and (EntityState.name ne 'Done') and (EntityState.name ne 'Ready to release') and (CreateDate gte '" + reportStartDate.ToString("yyyy-MM-dd") + "') and (CreateDate lte '" + reportEndDate.ToString("yyyy-MM-dd") + "')&take=1000&format=json" + token)); BugsCollection bugsCollection_Added = JsonConvert.DeserializeObject <BugsCollection>(client.DownloadString(PathToTp + "Bugs?" + BugSelectionFields + "&where=(Project.Id eq " + project.Id + ") and (EntityState.name ne 'Done') and (EntityState.name ne 'Ready to release') and (CreateDate gte '" + reportStartDate.ToString("yyyy-MM-dd") + "') and (CreateDate lte '" + reportEndDate.ToString("yyyy-MM-dd") + "')&take=1000&format=json" + token)); #endregion //********************************************* // Start generating report HTML //********************************************* int bugsCompleted = 0; int bugsInProgress = 0; int bugsPlanned = 0; int bugsUAT = 0; int userStoryCompleted = 0; int userStoryInProgress = 0; int userStoryPlanned = 0; int userStoryUAT = 0; ShowInConsole("Checking that we have at lease one entity to show in the report:"); //check that we got at least one user story or bug that need to be added to the report Boolean addProjectToReport = false; if (reportType == "Daily") { if (userStoriesCollection_Done.Items.Count > 0 || bugsCollection_Done.Items.Count > 0 || userStoriesCollection_R2R.Items.Count > 0 || bugsCollection_R2R.Items.Count > 0 || us_WIP.Count > 0 || bugsCollection_InProgress.Items.Count > 0) { addProjectToReport = true; } } else { if (userStoriesCollection_Done.Items.Count > 0 || bugsCollection_Done.Items.Count > 0 || userStoriesCollection_R2R.Items.Count > 0 || bugsCollection_R2R.Items.Count > 0 || us_WIP.Count > 0 || bugsCollection_InProgress.Items.Count > 0 || userStoriesCollection_Planned.Items.Count > 0 || bugsCollection_Planned.Items.Count > 0) { addProjectToReport = true; } } if (addProjectToReport) { ShowInConsole("At least one entity should be added to the report."); AddProjectHeaderToReport(project, sw); projectAdded2Report = true; //Section = Выполнено if (userStoriesCollection_Done.Items.Count > 0 || bugsCollection_Done.Items.Count > 0 || userStoriesCollection_R2R.Items.Count > 0 || bugsCollection_R2R.Items.Count > 0) { AddSectionHeaderToReport("Выполнено", sw); //adding completed entities if (userStoriesCollection_Done.Items.Count > 0) { AddRecordsToReport(userStoriesCollection_Done.Items.ToList <UserStory>(), sw, projectContext.Acid); userStoryCompleted += userStoriesCollection_Done.Items.Count; } if (bugsCollection_Done.Items.Count > 0) { AddRecordsToReport(bugsCollection_Done.Items.ToList <Bug>(), sw, projectContext.Acid); bugsCompleted += bugsCollection_Done.Items.Count; } if (userStoriesCollection_R2R.Items.Count > 0) { AddRecordsToReport(userStoriesCollection_R2R.Items.ToList <UserStory>(), sw, projectContext.Acid); userStoryCompleted += userStoriesCollection_Done.Items.Count; } if (bugsCollection_R2R.Items.Count > 0) { AddRecordsToReport(bugsCollection_R2R.Items.ToList <Bug>(), sw, projectContext.Acid); bugsCompleted += bugsCollection_Done.Items.Count; } AddSectionFooterToReport(sw); } //Section = В работе (для еженедельного отчета) //Section = Измененные (для ежедневного отчета) if (us_WIP.Count > 0 || bugsCollection_InProgress.Items.Count > 0) { AddSectionHeaderToReport(reportType == "Daily"?"Изменено":"В работе", sw); if (us_WIP.Count > 0) { AddRecordsToReport(us_WIP, sw, projectContext.Acid); userStoryInProgress += us_WIP.Count; } if (bugsCollection_InProgress.Items.Count > 0) { AddRecordsToReport(bugsCollection_InProgress.Items.ToList <Bug>(), sw, projectContext.Acid); bugsInProgress += bugsCollection_InProgress.Items.Count; } } AddSectionFooterToReport(sw); //Section = Запланировано (только для еженедельного отчета) if (reportType == "Weekly") { if (userStoriesCollection_Planned.Items.Count > 0 || bugsCollection_Planned.Items.Count > 0) { AddSectionHeaderToReport("Запланировано", sw); if (userStoriesCollection_Planned.Items.Count > 0) { AddRecordsToReport(userStoriesCollection_Planned.Items.ToList <UserStory>(), sw, projectContext.Acid); userStoryPlanned += userStoriesCollection_Planned.Items.Count; } if (bugsCollection_Planned.Items.Count > 0) { AddRecordsToReport(bugsCollection_Planned.Items.ToList <Bug>(), sw, projectContext.Acid); bugsPlanned += bugsCollection_Planned.Items.Count; } AddSectionFooterToReport(sw); } } //Section = Добавлено (только для ежедневного отчета) if (reportType == "Daily") { if (userStoriesCollection_Added.Items.Count > 0 || bugsCollection_Added.Items.Count > 0) { AddSectionHeaderToReport("Добавлено", sw); if (userStoriesCollection_Added.Items.Count > 0) { AddRecordsToReport(userStoriesCollection_Added.Items.ToList <UserStory>(), sw, projectContext.Acid); } if (bugsCollection_Added.Items.Count > 0) { AddRecordsToReport(bugsCollection_Added.Items.ToList <Bug>(), sw, projectContext.Acid); } AddSectionFooterToReport(sw); } } //Section = UAT (только для ежедневного отчета) if (reportType == "Weekly") { if (userStoriesCollection_UAT.Items.Count > 0 || bugsCollection_UAT.Items.Count > 0) { AddSectionHeaderToReport("На тестировании у заказчика", sw); if (userStoriesCollection_UAT.Items.Count > 0) { AddRecordsToReport(userStoriesCollection_UAT.Items.ToList <UserStory>(), sw, projectContext.Acid); userStoryUAT += userStoriesCollection_UAT.Items.Count; } if (bugsCollection_UAT.Items.Count > 0) { AddRecordsToReport(bugsCollection_UAT.Items.ToList <Bug>(), sw, projectContext.Acid); bugsUAT += bugsCollection_UAT.Items.Count; } AddSectionFooterToReport(sw); } } //Add project footer if (projectAdded2Report) { AddProjectFooterToReport(sw); projectAdded2Report = false; } //Add project to Summary section AddProjectToSummary(project, userStoryCompleted, userStoryInProgress, userStoryPlanned, userStoryUAT, bugsCompleted, bugsInProgress, bugsPlanned, bugsUAT, AddProjectToSummaryLeft); if (AddProjectToSummaryLeft) { AddProjectToSummaryLeft = false; } else { AddProjectToSummaryLeft = true; } } } } else { //TO-DO: add infor to the report that no projects had been modified for this day. } //add summary Footer StreamReader srSummary = new StreamReader(ReportPath + "Summary_Footer.html"); content = srSummary.ReadToEnd(); StreamWriter swSummary = new StreamWriter(sHTMLSummaryFile, true, Encoding.UTF8); swSummary.Write(content); srSummary.Close(); swSummary.Close(); }