/// <summary> /// Creates a DataTable fore each fiscal year for given stratify grouping /// </summary> /// <param name="startTime">Report start date</param> /// <param name="endTime">Report end date</param> /// <param name="stratifyBy">StratifyOption to retireve group names</param> /// <param name="dataType">Data to be displayed</param> /// <param name="dictionary">QandRwithTimestamp grouped into stratify group then in to their month</param> /// <returns>DataTable for each month for given stratify grouping</returns> private DataTable createDtForEachMonth(DateTime startTime, DateTime endTime, Constants.StratifyOption stratifyBy, Constants.DataType dataType, Dictionary <int, Dictionary <MonthYearPair, List<QandRwithTimestamp>>> dictionary) { var dt = new DataTable(); dt.Clear(); //Finds the string representation of stratifyBy option and create a column string stratifyGroups = Enum.GetName(typeof (Constants.StratifyOption), stratifyBy); var stratifyGrpColum = new DataColumn(stratifyGroups, typeof (string)); dt.Columns.Add(stratifyGrpColum); //create column for each month int totalNumOfMonths = endTime.Month + (endTime.Year - startTime.Year)*12 - startTime.Month; var startMonthYearPair = new MonthYearPair(startTime.Month, startTime.Year); for (int i = 0; i < totalNumOfMonths; i++) { var monthColumn = new DataColumn(startMonthYearPair.ToString(), typeof (Int64)) { DefaultValue = 0 }; dt.Columns.Add(monthColumn); startMonthYearPair.addmonth(1); } //gets the names of the stratify groups. ie, callerType,region or tumourGroup Codes Dictionary<int, string> idToName = getTypeNames(stratifyBy); //Even if the dictionary does not contain the no group data, table should still show them. if (!dictionary.ContainsKey(-1)) { DataRow noGroupRow = dt.NewRow(); noGroupRow[stratifyGroups] = "No " + stratifyGroups; dt.Rows.Add(noGroupRow); } foreach ( var keyValuePair in dictionary.OrderByDescending(x => x.Key).Reverse()) { //adds a row for each stratify groups in the table DataRow newRow = dt.NewRow(); //if the key is null then it should create a row for 'No group assigned' requests if (keyValuePair.Key != -1) { newRow[stratifyGroups] = idToName[keyValuePair.Key]; idToName.Remove(keyValuePair.Key); } else { newRow[stratifyGroups] = "No " + stratifyGroups; } //now visit each year which the requests are sub-grouped by year //and adds the proper value for the cell in the dataTable foreach (var valuePair in keyValuePair.Value) { switch (dataType) { case Constants.DataType.AvgTimePerRequest: newRow[valuePair.Key.ToString()] = averageTime(valuePair.Value); break; case Constants.DataType.AvgTimeToComplete: newRow[valuePair.Key.ToString()] = avgTimeFromStartToComplete(valuePair.Value); break; case Constants.DataType.TotalNumOfRequests: newRow[valuePair.Key.ToString()] = valuePair.Value.Count; break; case Constants.DataType.TotalTimeSpent: newRow[valuePair.Key.ToString()] = totalTimeSpent(valuePair.Value); break; } } dt.Rows.Add(newRow); } DataRow groupRow; foreach (var group in idToName) { groupRow = dt.NewRow(); groupRow[stratifyGroups] = group.Value; dt.Rows.Add(groupRow); } return dt; }
/// <summary> /// Creates list of dataTables for monthly report, to be exported based on the month and criteria specified /// </summary> /// <param name="startDate">Start date, selected by the user</param> /// <param name="endDate">End date, selected by the user</param> /// <param name="dataToDisplay">Date Types to represent, selected by the user</param> /// <param name="stratifyBy">Stratify option, selected by the user</param> /// <returns>The list of data tables, one table for each data type chosen</returns> public Dictionary<string, DataTable> generateMonthlyReport( DateTime startDate, DateTime endDate, IEnumerable<Constants.DataType> dataToDisplay, Constants.StratifyOption stratifyBy) { var dataTablesForReport = new Dictionary<string, DataTable>(); //executes different methods depending on the stratify options selected switch (stratifyBy) { case Constants.StratifyOption.Region: //Retrieves the requests from the database which opened within the given timeFrame //then group them by the region Dictionary<int, List<Request>> regionDictionary = (from reqs in _db .Repository < Request >() where reqs .TimeOpened > startDate && reqs .TimeOpened <= endDate group reqs by reqs .RegionID into regionGroups select regionGroups) .ToDictionary(r => nullableToInt(r.Key), r => r.ToList()); //Sub-groups the regionGroups by the year the request is opened. Dictionary<int, Dictionary<MonthYearPair, List<Request>>> regionAndYear = regionDictionary.ToDictionary( keyValuePair => keyValuePair.Key, keyValuePair => keyValuePair.Value.GroupBy( r => new MonthYearPair(r.TimeOpened)) .Select(grp => grp) .ToDictionary(grp => grp.Key, grp => grp.ToList())); //creates dataTable for each data and adds it to the dictionary of dataTables foreach (Constants.DataType dataType in dataToDisplay) { int titleIndex = ((int) stratifyBy - 1)*4 + (int) dataType; dataTablesForReport.Add( Constants.DATATABLE_TITLES[titleIndex], createDtForEachMonth(startDate, endDate, stratifyBy, dataType, regionAndYear)); } break; case Constants.StratifyOption.RequestorType: //Retrieves the requests from the database which opened within the given timeFrame //then group them by the callerType Dictionary<int, List<Request>> callerDictionary = (from reqs in _db .Repository < Request >() where reqs .TimeOpened > startDate && reqs .TimeOpened <= endDate group reqs by reqs .RequestorTypeID into callerGroups select callerGroups) .ToDictionary(r => nullableToInt(r.Key), r => r.ToList()); //Sub-groups the regionGroups by the year the request is opened. Dictionary<int, Dictionary<MonthYearPair, List<Request>>> callerAndYear = callerDictionary.ToDictionary( keyValuePair => keyValuePair.Key, keyValuePair => keyValuePair.Value.GroupBy( r => new MonthYearPair(r.TimeOpened)) .Select(grp => grp) .ToDictionary(grp => grp.Key, grp => grp.ToList())); //creates dataTable for each data and adds it to the dictionary of dataTables foreach (Constants.DataType dataType in dataToDisplay) { int titleIndex = ((int) stratifyBy - 1)*4 + (int) dataType; dataTablesForReport.Add( Constants.DATATABLE_TITLES[titleIndex], createDtForEachMonth(startDate, endDate, stratifyBy, dataType, callerAndYear)); } break; case Constants.StratifyOption.TumorGroup: //Retrieves the QuestionResponse from the database which opened within the given timeFrame, //adds the open, close timestamps, then group them by the tumourGroup Dictionary<int, List<QandRwithTimestamp>> qrTumourGrpDic = (from reqs in _db.Repository<Request>() where reqs.TimeOpened > startDate && reqs.TimeOpened <= endDate join qr in _db.Repository<QuestionResponse>() on reqs.RequestID equals qr.RequestID select new QandRwithTimestamp(qr, reqs.TimeOpened, reqs.TimeClosed)).ToList() .GroupBy( q => q.qr .TumourGroupID) .Select( grp => grp) .ToDictionary (grp => nullableToInt(grp.Key), grp => grp.ToList()); //Sub-groups the regionGroups by the year the question(request) is opened. Dictionary <int, Dictionary<MonthYearPair, List<QandRwithTimestamp>>> tgAndYear = qrTumourGrpDic.ToDictionary( keyValuePair => keyValuePair.Key, keyValuePair => keyValuePair.Value.GroupBy( r => new MonthYearPair(r.timeOpened)) .Select(grp => grp) .ToDictionary(grp => grp.Key, grp => grp.ToList())); //creates dataTable for each data and adds it to the dictionary of dataTables foreach (Constants.DataType dataType in dataToDisplay) { int titleIndex = ((int) stratifyBy - 1)*4 + (int) dataType; dataTablesForReport.Add( Constants.DATATABLE_TITLES[titleIndex], createDtForEachMonth(startDate, endDate, stratifyBy, dataType, tgAndYear)); } break; default: //Retrieves the requests from the database which opened within the given timeFrame //then group them by the year Dictionary<MonthYearPair, List<Request>> dictionaryByMonth = (from reqs in _db .Repository < Request > () where reqs .TimeOpened > startDate && reqs .TimeOpened <= endDate group reqs by new { reqs .TimeOpened .Month, reqs .TimeOpened .Year } into listByYear select listByYear) .ToDictionary( r => new MonthYearPair(r.Key.Month, r.Key.Year), r => r.ToList()); var dt = new DataTable(); dt.Clear(); //Finds the string representation of stratifyBy option and create a column var dataTypeColumn = new DataColumn(Constants.DataTypeStrings.DATA_TYPE, typeof (string)); dt.Columns.Add(dataTypeColumn); //create column for each month int totalNumOfMonths = endDate.Month + (endDate.Year - startDate.Year)*12 - startDate.Month; var startMonthYearPair = new MonthYearPair(startDate.Month, startDate.Year); for (int i = 0; i < totalNumOfMonths; i++) { var monthColumn = new DataColumn(startMonthYearPair.ToString(), typeof (Int64)) { DefaultValue = 0 }; dt.Columns.Add(monthColumn); startMonthYearPair.addmonth(1); } foreach ( Constants.DataType dataType in dataToDisplay.OrderByDescending(x => x).Reverse()) { //adds a row for each dataType in the table DataRow newRow = dt.NewRow(); //depending what data we need, the following enters the correct value for the the data cell. switch (dataType) { case Constants.DataType.AvgTimePerRequest: newRow[Constants.DataTypeStrings.DATA_TYPE] = Constants.DataTypeStrings.AVG_TIME; foreach (var keyValue in dictionaryByMonth) { newRow[keyValue.Key.ToString()] = averageTime(keyValue.Value); } break; case Constants.DataType.AvgTimeToComplete: newRow[Constants.DataTypeStrings.DATA_TYPE] = Constants.DataTypeStrings .AVG_TIME_TO_COMPLETE; foreach (var keyValue in dictionaryByMonth) { newRow[keyValue.Key.ToString()] = avgTimeFromStartToComplete( keyValue.Value); } break; case Constants.DataType.TotalNumOfRequests: newRow[Constants.DataTypeStrings.DATA_TYPE] = Constants.DataTypeStrings.TOTAL_NUM; foreach (var keyValue in dictionaryByMonth) { newRow[keyValue.Key.ToString()] = keyValue.Value.Count; } break; case Constants.DataType.TotalTimeSpent: newRow[Constants.DataTypeStrings.DATA_TYPE] = Constants.DataTypeStrings.TOTAL_TIME_SPENT; foreach (var keyValue in dictionaryByMonth) { newRow[keyValue.Key.ToString()] = totalTimeSpent(keyValue.Value); } break; } dt.Rows.Add(newRow); } dataTablesForReport.Add(Constants.DATATABLE_TITLES[0], dt); break; } return dataTablesForReport; }