static void Main(string[] args) { Options options = new Options(); Parser.Default.ParseArguments(args, options); //derived parameters int minTermYear = int.Parse(options.minTerm.Substring(0, 4)); int minTermTerm = int.Parse("" + options.minTerm[4]); int maxTermYear = int.Parse(options.maxTerm.Substring(0, 4)); int maxTermTerm = int.Parse("" + options.maxTerm[4]); OrionTerm startTerm = new OrionTerm(options.minTerm); OrionTerm stopTerm = new OrionTerm(options.maxTerm); //datastores Dictionary <String, AcademicProgram> programDictionary = new Dictionary <string, AcademicProgram>(); Dictionary <String, Course> globalCourseDictionary = new Dictionary <string, Course>(); Dictionary <String, List <String> > onlineCourses = new Dictionary <string, List <string> >(); Dictionary <String, List <String> > AAElectivesByTerm = new Dictionary <string, List <string> >(); Dictionary <Tuple <String, String>, float> TotalProgramHoursForProgram = new Dictionary <Tuple <string, string>, float>(); Dictionary <Tuple <String, String>, float> TotalGeneralEducationHoursForProgram = new Dictionary <Tuple <string, string>, float>(); Dictionary <Tuple <String, String>, float> TotalCoreAndProfessionalForProgram = new Dictionary <Tuple <string, string>, float>(); List <AcademicProgram> programs = new List <AcademicProgram>(); SqlConnection conn = new SqlConnection("Server=vulcan;database=MIS;Trusted_Connection=yes"); try { conn.Open(); } catch (Exception) { throw; } SqlCommand comm = new SqlCommand("SELECT DISTINCT " + " prog.PGM_CD " + " ,CASE " + " WHEN prog.PGM_OFFCL_TTL <> '' THEN prog.PGM_OFFCL_TTL " + " ELSE prog.PGM_TRK_TTL " + " END AS [Title] " + " ,prog.AWD_TY " + " ,prog.EFF_TRM_D " + " ,prog.END_TRM " + " ,proggroup.PGM_AREA " + " ,progarea.PGM_AREA_TYPE " + " ,proggroup.PGM_AREA_GROUP " + " ,proggroup.PGM_AREA_OPTN_CD " + " ,proggroup.PGM_AREA_OPTN_OPER " + " ,groupcourse.PGM_AREA_GROUP_CRS " + " ,CASE WHEN prog.AWD_TY = 'VC' THEN prog.PGM_TTL_MIN_CNTCT_HRS_REQD ELSE prog.PGM_TTL_CRD_HRS END AS HRS " + " ,prog.PGM_TTL_GE_HRS_REQD " + " ,prog.FIN_AID_APPRVD " + " FROM " + " MIS.dbo.ST_PROGRAMS_A_136 prog " + " INNER JOIN MIS.dbo.ST_PROGRAMS_A_136 progarea ON progarea.PGM_CD = prog.PGM_CD " + " AND progarea.EFF_TRM_A = prog.EFF_TRM_D " + " INNER JOIN MIS.dbo.ST_PROGRAMS_A_136 proggroup ON proggroup.PGM_CD = prog.PGM_CD " + " AND proggroup.EFF_TRM_G = prog.EFF_TRM_D " + " INNER JOIN MIS.dbo.ST_PROGRAMS_A_PGM_AREA_GROUP_CRS_136 groupcourse ON groupcourse.ISN_ST_PROGRAMS_A = proggroup.ISN_ST_PROGRAMS_A" + " WHERE " + " prog.EFF_TRM_D <> '' " + " AND prog.EFF_TRM_D <= '" + options.maxTerm + "' " + " AND prog.END_TRM = '' " + " AND prog.AWD_TY NOT IN ('NC','ND','HS') " + " AND SUBSTRING(prog.PGM_CD, 1, 2) <> '00' " + " ORDER BY " + " prog.PGM_CD " + " ,prog.EFF_TRM_D " + " ,proggroup.PGM_AREA " + " ,proggroup.PGM_AREA_GROUP", conn); SqlDataReader reader = comm.ExecuteReader(); while (reader.Read()) { String curProgramCode = reader["PGM_CD"].ToString(); String effectiveTerm = reader["EFF_TRM_D"].ToString(); String endTerm = reader["END_TRM"].ToString(); String courseID = reader["PGM_AREA_GROUP_CRS"].ToString().Trim(); int areaNum = int.Parse(reader["PGM_AREA"].ToString()); int groupNum = int.Parse(reader["PGM_AREA_GROUP"].ToString()); bool financialAidApproved = reader["FIN_AID_APPRVD"].ToString() == "Y"; AcademicProgram prog; if (!programDictionary.ContainsKey(curProgramCode)) { prog = new AcademicProgram(); prog.progCode = curProgramCode; prog.awardType = reader["AWD_TY"].ToString(); prog.progName = reader["Title"].ToString(); prog.financialAidApproved = financialAidApproved; prog.catalogChanges = new List <AcademicProgram.CatalogChange>(); prog.catalogDictionary = new Dictionary <string, AcademicProgram.CatalogChange>(); programs.Add(prog); programDictionary.Add(curProgramCode, prog); } else { prog = programDictionary[curProgramCode]; } AcademicProgram.CatalogChange catalog; if (!prog.catalogDictionary.ContainsKey(effectiveTerm)) { catalog = new AcademicProgram.CatalogChange(); catalog.effectiveTerm = effectiveTerm; catalog.endTerm = endTerm; catalog.totalProgramHours = (int)float.Parse(reader["HRS"].ToString()); catalog.totalGeneralEducationHours = (int)float.Parse(reader["PGM_TTL_GE_HRS_REQD"].ToString()); catalog.totalCoreAndProfessionalHours = catalog.totalProgramHours - catalog.totalGeneralEducationHours; catalog.effectiveTermYear = int.Parse(catalog.effectiveTerm.Substring(0, 4)); catalog.effectiveTermTerm = int.Parse("" + catalog.effectiveTerm[4]); catalog.endTermYear = catalog.endTerm != "" ? int.Parse(catalog.endTerm.Substring(0, 4)) : 9999; catalog.endTermTerm = catalog.endTerm != "" ? int.Parse("" + catalog.endTerm[4]) : 9; catalog.areaDictionary = new Dictionary <int, AcademicProgram.CatalogChange.Area>(); catalog.flatCourseArray = new List <string>(); prog.catalogChanges.Add(catalog); prog.catalogDictionary.Add(effectiveTerm, catalog); catalog.areas = new List <AcademicProgram.CatalogChange.Area>(); } else { catalog = prog.catalogDictionary[effectiveTerm]; } AcademicProgram.CatalogChange.Area area; if (!catalog.areaDictionary.ContainsKey(areaNum)) { area = new AcademicProgram.CatalogChange.Area(); area.areaNum = areaNum; area.areaType = reader["PGM_AREA_TYPE"].ToString(); area.groupDictionary = new Dictionary <int, AcademicProgram.CatalogChange.Area.Group>(); area.groups = new List <AcademicProgram.CatalogChange.Area.Group>(); catalog.areas.Add(area); catalog.areaDictionary.Add(area.areaNum, area); } else { area = catalog.areaDictionary[areaNum]; } AcademicProgram.CatalogChange.Area.Group group; if (!area.groupDictionary.ContainsKey(groupNum)) { group = new AcademicProgram.CatalogChange.Area.Group(); group.groupNum = groupNum; group.optCode = reader["PGM_AREA_OPTN_CD"].ToString(); group.operatorCode = reader["PGM_AREA_OPTN_OPER"].ToString(); group.courseDictionary = new Dictionary <string, Course>(); group.courses = new List <Course>(); area.groups.Add(group); area.groupDictionary.Add(groupNum, group); } else { group = area.groupDictionary[groupNum]; } Course course; if (!globalCourseDictionary.ContainsKey(courseID)) { course = new Course(); course.courseID = courseID; globalCourseDictionary.Add(courseID, course); } else { course = globalCourseDictionary[courseID]; } if (group.courseDictionary.ContainsKey(courseID)) { continue; } group.courseDictionary.Add(courseID, course); group.courses.Add(course); catalog.flatCourseArray.Add(courseID); } reader.Close(); comm = new SqlCommand("SELECT " + " class.crsID " + " ,class.efftrm " + " ,CASE " + " WHEN course.CRED_TY IN ('01','02','03','14','15') THEN class.EVAL_CRED_HRS " + " ELSE class.CNTCT_HRS " + " END AS HRS " + " ,course.USED_FOR_AA_ELECTIVE " + " ,CASE " + " WHEN SUM(CASE " + " WHEN class.NON_FF_PERC > 50 THEN 1 " + " ELSE 0 " + " END) > 1 THEN 'Online' " + " ELSE 'Not Online' " + " END AS 'Online_Status' " + " FROM " + " MIS.dbo.ST_CLASS_A_151 class " + " INNER JOIN MIS.dbo.ST_COURSE_A_150 course ON course.CRS_ID = class.crsID " + " INNER JOIN MIS.[dbo].[ST_PROGRAMS_A_PGM_AREA_GROUP_CRS_136] groupcourse ON groupcourse.[PGM_AREA_GROUP_CRS] = course.CRS_ID" + " INNER JOIN MIS.dbo.ST_PROGRAMS_A_136 proggroup ON proggroup.ISN_ST_PROGRAMS_A = groupcourse.ISN_ST_PROGRAMS_A " + " INNER JOIN MIS.dbo.ST_PROGRAMS_A_136 prog ON prog.PGM_CD = proggroup.PGM_CD " + " AND prog.EFF_TRM_D = proggroup.EFF_TRM_G " + " WHERE " + " class.efftrm >= '" + options.minTerm + "' " + " AND class.efftrm <= '" + options.maxTerm + "' " + " AND prog.AWD_TY NOT IN ('NC','ND','HS') " + " AND SUBSTRING(prog.PGM_CD, 1, 2) <> '00' " + " AND class.CLS_STAT <> 'C' " + " AND class.CRNT_ENRLD > 0 " + " GROUP BY " + " class.crsId " + " ,class.effTrm " + " ,course.CRED_TY " + " ,class.EVAL_CRED_HRS " + " ,course.USED_FOR_AA_ELECTIVE " + " ,class.CNTCT_HRS", conn); comm.CommandTimeout = 1200; reader = comm.ExecuteReader(); while (reader.Read()) { String course = reader["crsID"].ToString().Trim(); String term = reader["efftrm"].ToString(); float hours = float.Parse(reader["HRS"].ToString()); bool online = reader["Online_Status"].ToString() == "Online"; bool AAElective = reader["USED_FOR_AA_ELECTIVE"].ToString() == "Y"; if (!globalCourseDictionary.ContainsKey(course)) { continue; } globalCourseDictionary[course].hours = hours; if (AAElective) { if (!AAElectivesByTerm.ContainsKey(term)) { AAElectivesByTerm.Add(term, new List <string>()); } if (!AAElectivesByTerm[term].Contains(course)) { AAElectivesByTerm[term].Add(course); } } if (!onlineCourses.ContainsKey(term)) { onlineCourses.Add(term, new List <String>()); } if (online && !onlineCourses[term].Contains(course)) { onlineCourses[term].Add(course); } } reader.Close(); conn.Close(); foreach (AcademicProgram curProgram in programs) { int maxCatalogYear = 0; int maxCatalogTerm = 0; AcademicProgram.CatalogChange maxCatalog = null; foreach (AcademicProgram.CatalogChange catalog in curProgram.catalogChanges) { if (catalog.effectiveTermYear > maxCatalogYear && catalog.effectiveTermTerm > maxCatalogTerm) { maxCatalog = catalog; maxCatalogYear = catalog.effectiveTermYear; maxCatalogTerm = catalog.effectiveTermTerm; } } AcademicProgram.CatalogChange[] copyOfCatalogChanges = new AcademicProgram.CatalogChange[curProgram.catalogChanges.Count]; curProgram.catalogChanges.CopyTo(copyOfCatalogChanges); foreach (AcademicProgram.CatalogChange catalog in copyOfCatalogChanges) { if (catalog.effectiveTerm != maxCatalog.effectiveTerm) { curProgram.catalogChanges.Remove(catalog); } } } foreach (AcademicProgram curProgram in programs) { foreach (AcademicProgram.CatalogChange catalog in curProgram.catalogChanges) { float totalProgramHours = 0; float totalGenEdHours = 0; float totalCoreAndProfessionalHours = 0; int curYear = catalog.effectiveTermYear; int curTerm = catalog.effectiveTermTerm; List <String> satisfiedCourses = new List <string>(); List <String> AACoursesForProgram = new List <string>(); Tuple <String, String> key = new Tuple <string, string>(curProgram.progCode, catalog.effectiveTerm); TotalProgramHoursForProgram.Add(key, 0); TotalGeneralEducationHoursForProgram.Add(key, 0); TotalCoreAndProfessionalForProgram.Add(key, 0); for (OrionTerm i = startTerm; i < stopTerm; i++) { String term = curYear.ToString() + curTerm.ToString(); if (!onlineCourses.ContainsKey(term)) { continue; } foreach (String course in catalog.flatCourseArray) { if (onlineCourses[i.ToString()].Contains(course)) { satisfiedCourses.Add(course); } } if (curProgram.progCode == "1108") { if (AAElectivesByTerm.ContainsKey(i.ToString())) { foreach (String course in AAElectivesByTerm[term]) { if (!AACoursesForProgram.Contains(course)) { AACoursesForProgram.Add(course); totalProgramHours += globalCourseDictionary[course].hours; totalCoreAndProfessionalHours += globalCourseDictionary[course].hours; } } } } } foreach (AcademicProgram.CatalogChange.Area area in catalog.areas) { bool genEdArea = false; switch (area.areaType.Substring(0, 2)) { case "01": case "02": case "03": case "04": case "05": if (curProgram.awardType != "VC" && curProgram.awardType != "TC") { genEdArea = true; } break; default: if (curProgram.awardType == "AA") { genEdArea = true; } break; } List <float> groupHours = new List <float>(); List <char> operands = new List <char>(); List <float> andGroups = new List <float>(); foreach (AcademicProgram.CatalogChange.Area.Group group in area.groups) { float groupHoursTotal = 0; List <Course> coursesInGroup = new List <Course>(); foreach (String course in group.courseDictionary.Keys) { if (satisfiedCourses.Contains(course)) { coursesInGroup.Add(group.courseDictionary[course]); } } switch (group.optCode) { case "14": case "00": foreach (Course course in coursesInGroup) { groupHoursTotal += course.hours; } break; case "11": float hoursForGroup = Course.findAndSumFirstNCourses(coursesInGroup, 2); groupHoursTotal += hoursForGroup; break; case "21": case "31": case "41": case "61": case "71": case "81": case "82": case "83": case "84": hoursForGroup = Course.findAndSumFirstNCourses(coursesInGroup, 1); groupHoursTotal += hoursForGroup; break; case "22": case "32": case "42": case "62": case "72": hoursForGroup = Course.findAndSumFirstNCourses(coursesInGroup, 2); groupHoursTotal += hoursForGroup; break; case "23": case "33": case "43": case "63": hoursForGroup = Course.findAndSumFirstNCourses(coursesInGroup, 3); groupHoursTotal += hoursForGroup; break; case "24": case "34": hoursForGroup = Course.findAndSumFirstNCourses(coursesInGroup, 4); groupHoursTotal += hoursForGroup; break; case "25": hoursForGroup = Course.findAndSumFirstNCourses(coursesInGroup, 5); groupHoursTotal += hoursForGroup; break; case "26": case "87": hoursForGroup = Course.findAndSumFirstNCourses(coursesInGroup, 6); groupHoursTotal += hoursForGroup; break; case "27": hoursForGroup = Course.findAndSumFirstNCourses(coursesInGroup, 7); groupHoursTotal += hoursForGroup; break; case "28": hoursForGroup = Course.findAndSumFirstNCourses(coursesInGroup, 8); groupHoursTotal += hoursForGroup; break; case "29": hoursForGroup = Course.findAndSumFirstNCourses(coursesInGroup, 9); groupHoursTotal += hoursForGroup; break; default: break; } groupHours.Add(groupHoursTotal); operands.Add(group.operatorCode.Length == 0 ? ' ' : group.operatorCode[0]); } for (int i = 0; i < operands.Count; i++) { float andGroupTotal = groupHours[0]; int j = i + 1; do { if (j >= operands.Count) { break; } andGroupTotal += groupHours[j]; j++; if (j >= operands.Count) { break; } } while (operands[j] == 'A'); andGroups.Add(andGroupTotal); } float areaHours = 0; if (andGroups.Count == 0) { areaHours += groupHours.Max(); } else { areaHours += andGroups.Max(); } totalProgramHours += areaHours; if (genEdArea) { totalGenEdHours += areaHours; } else { totalCoreAndProfessionalHours += areaHours; } } TotalProgramHoursForProgram[key] += totalProgramHours; TotalGeneralEducationHoursForProgram[key] += totalGenEdHours; TotalCoreAndProfessionalForProgram[key] += totalCoreAndProfessionalHours; } } DirectoryInfo dataDirectory = new DirectoryInfo("..\\..\\..\\data\\" + options.month + " " + options.year); if (!dataDirectory.Exists) { Directory.CreateDirectory("..\\..\\..\\data\\" + options.month + " " + options.year); } using (System.IO.StreamWriter file = new System.IO.StreamWriter("..\\..\\..\\data\\" + options.month + " " + options.year + "\\SACS Course Delivery Method Report " + options.month + " " + options.year + ".csv")) { file.WriteLine("Begin Term, End Term, Award Type, POS Code, POS Title, PGM Hrs (reqd for degree), # PGM hrs via DE, % PGM Hrs via DE, # Gen Ed Hrs via DE, % Gen Ed Hrs via DE, # Prof Hrs via DE, % Prof Hrs via DE, FA Apprvd"); foreach (AcademicProgram prog in programs) { foreach (AcademicProgram.CatalogChange catalog in prog.catalogChanges) { Tuple <String, String> key = new Tuple <string, string>(prog.progCode, catalog.effectiveTerm); float totalProgramHours = TotalProgramHoursForProgram[key] > catalog.totalProgramHours ? catalog.totalProgramHours : TotalProgramHoursForProgram[key]; float totalGenEdHours = TotalGeneralEducationHoursForProgram[key] > catalog.totalGeneralEducationHours ? catalog.totalGeneralEducationHours : TotalGeneralEducationHoursForProgram[key]; float totalCoreAndProfessional = TotalCoreAndProfessionalForProgram[key] > catalog.totalCoreAndProfessionalHours ? catalog.totalCoreAndProfessionalHours : TotalCoreAndProfessionalForProgram[key]; float percentProgramHours = totalProgramHours / catalog.totalProgramHours; float percentGenEdHours = (float)(catalog.totalGeneralEducationHours == 0 ? 0.00 : (totalGenEdHours / catalog.totalGeneralEducationHours)); float percentCoreAndProfessionalHours = (float)(catalog.totalCoreAndProfessionalHours == 0 ? 0.00 : (totalCoreAndProfessional / catalog.totalCoreAndProfessionalHours)); percentProgramHours = percentProgramHours * 100; percentGenEdHours = percentGenEdHours * 100; percentCoreAndProfessionalHours = percentCoreAndProfessionalHours * 100; file.WriteLine(String.Format(options.minTerm + "," + options.maxTerm + "," + prog.awardType + "," + prog.progCode + @",""" + prog.progName + @"""," + catalog.totalProgramHours + "," + totalProgramHours + ",{0:0.00}," + totalGenEdHours + ",{1:0.00}," + totalCoreAndProfessional + ",{2:0.00}," + prog.financialAidApproved, percentProgramHours, percentGenEdHours, percentCoreAndProfessionalHours)); } } file.Close(); } }
static int Main(string[] args) { Options options = new Options(); if (!CommandLine.Parser.Default.ParseArgumentsStrict(args, options) || options.minTerm == null || options.maxTerm == null || options.month == null || options.year == null) { return(-1); } //derived parameters int minTermYear = int.Parse(options.minTerm.Substring(0, 4)); int minTermTerm = int.Parse("" + options.minTerm[4]); int maxTermYear = int.Parse(options.maxTerm.Substring(0, 4)); int maxTermTerm = int.Parse("" + options.maxTerm[4]); OrionTerm startTerm = new OrionTerm(options.minTerm); OrionTerm stopTerm = new OrionTerm(options.maxTerm); //datastores Dictionary <String, AcademicProgram> programDictionary = new Dictionary <string, AcademicProgram>(); Dictionary <String, Course> globalCourseDictionary = new Dictionary <string, Course>(); Dictionary <Tuple <String, String>, List <String> > classesByCampusCenterAndTerm = new Dictionary <Tuple <string, string>, List <string> >(); List <String> campusCenters = new List <String>(); Dictionary <Tuple <String, String>, List <String> > AAElectivesByCampusAndTerm = new Dictionary <Tuple <string, string>, List <string> >(); List <AcademicProgram> programs = new List <AcademicProgram>(); Dictionary <Tuple <String, String, String>, float> TotalProgramHoursForProgramByCampusCenter = new Dictionary <Tuple <string, string, string>, float>(); Dictionary <Tuple <String, String, String>, float> TotalGeneralEducationHoursForProgramByCampusCenter = new Dictionary <Tuple <string, string, string>, float>(); Dictionary <Tuple <String, String, String>, float> TotalCoreAndProfessionalForProgramByCampusCenter = new Dictionary <Tuple <string, string, string>, float>(); Dictionary <Tuple <String, String, String>, List <String> > SatisfiedCoursesForProgramByCatalogYearAndCampusCenter = new Dictionary <Tuple <string, string, string>, List <string> >(); Dictionary <Tuple <String, String, String>, List <String> > AACoursesByAACatalogAndCampus = new Dictionary <Tuple <string, string, string>, List <string> >(); Dictionary <String, String> locationNameDict = new Dictionary <string, string>(); String[] highschoolCodes = new String[] { "D1427", "C1411", "A1618", "D1401", "C1634", "C1414", "A1103", "B1403", "A1104", "A1105", "D1103", "B1408", "A1110", "A1111", "A1112", "Z7000", "A1303", "A1116", "A1301", "A1117", "Z7004", "A1118", "B1613", "A1119", "A1114", "Z7015", "Z7002", "B1410", "F1410", "A1106", "A1122", "B1414", "A1115", "A1121", "A1421", "D4407", "Z7003", "D4407" }; String[] onlineCodes = new String[] { "A0720" }; SqlConnection conn = new SqlConnection("Server=vulcan;database=MIS;Trusted_Connection=yes"); try { conn.Open(); } catch (Exception) { throw; } SqlCommand comm = new SqlCommand("SELECT DISTINCT " + " prog.PGM_CD " + " ,prog.AWD_TY " + " ,prog.EFF_TRM_D " + " ,prog.END_TRM " + " ,proggroup.PGM_AREA " + " ,progarea.PGM_AREA_TYPE " + " ,proggroup.PGM_AREA_GROUP " + " ,proggroup.PGM_AREA_OPTN_CD " + " ,proggroup.PGM_AREA_OPTN_OPER " + " ,groupcourse.PGM_AREA_GROUP_CRS " + " ,CASE WHEN prog.AWD_TY = 'VC' THEN prog.PGM_TTL_MIN_CNTCT_HRS_REQD ELSE prog.PGM_TTL_CRD_HRS END AS HRS " + " ,prog.PGM_TTL_GE_HRS_REQD " + "FROM " + " MIS.dbo.ST_PROGRAMS_A_136 prog " + " INNER JOIN MIS.dbo.ST_PROGRAMS_A_136 progarea ON progarea.PGM_CD = prog.PGM_CD " + " AND progarea.EFF_TRM_A = prog.EFF_TRM_D " + " INNER JOIN MIS.dbo.ST_PROGRAMS_A_136 proggroup ON proggroup.PGM_CD = prog.PGM_CD " + " AND proggroup.EFF_TRM_G = prog.EFF_TRM_D " + " AND proggroup.PGM_AREA = progarea.PGM_AREA " + " INNER JOIN MIS.dbo.ST_PROGRAMS_A_PGM_AREA_GROUP_CRS_136 groupcourse ON groupcourse.ISN_ST_PROGRAMS_A = proggroup.ISN_ST_PROGRAMS_A " + "WHERE " + " prog.EFF_TRM_D <> '' " + " AND prog.EFF_TRM_D <= '" + options.maxTerm + "' " + " AND (prog.END_TRM = '' OR prog.END_TRM >= '" + options.minTerm + "') " + " AND prog.AWD_TY NOT IN ('ND','NC','HS') " + (options.programCode == "" ? " " : (" AND prog.PGM_CD = '" + options.programCode + "' ")) + "ORDER BY " + " prog.PGM_CD " + " ,prog.EFF_TRM_D " + " ,proggroup.PGM_AREA " + " ,proggroup.PGM_AREA_GROUP", conn); SqlDataReader reader = comm.ExecuteReader(); while (reader.Read()) { String curProgramCode = reader["PGM_CD"].ToString(); String effectiveTerm = reader["EFF_TRM_D"].ToString(); String endTerm = reader["END_TRM"].ToString(); String courseID = reader["PGM_AREA_GROUP_CRS"].ToString().Trim(); int areaNum = int.Parse(reader["PGM_AREA"].ToString()); int groupNum = int.Parse(reader["PGM_AREA_GROUP"].ToString()); AcademicProgram prog; if (!programDictionary.ContainsKey(curProgramCode)) { prog = new AcademicProgram(); prog.progCode = curProgramCode; prog.awardType = reader["AWD_TY"].ToString(); prog.catalogChanges = new List <AcademicProgram.CatalogChange>(); prog.catalogDictionary = new Dictionary <string, AcademicProgram.CatalogChange>(); programs.Add(prog); programDictionary.Add(curProgramCode, prog); } else { prog = programDictionary[curProgramCode]; } AcademicProgram.CatalogChange catalog; if (!prog.catalogDictionary.ContainsKey(effectiveTerm)) { catalog = new AcademicProgram.CatalogChange(); catalog.effectiveTerm = effectiveTerm; catalog.endTerm = endTerm; catalog.totalProgramHours = (int)float.Parse(reader["HRS"].ToString()); catalog.totalGeneralEducationHours = (int)float.Parse(reader["PGM_TTL_GE_HRS_REQD"].ToString()); catalog.totalCoreAndProfessionalHours = catalog.totalProgramHours - catalog.totalGeneralEducationHours; catalog.effectiveTermYear = int.Parse(catalog.effectiveTerm.Substring(0, 4)); catalog.effectiveTermTerm = int.Parse("" + catalog.effectiveTerm[4]); catalog.endTermYear = catalog.endTerm != "" ? int.Parse(catalog.endTerm.Substring(0, 4)) : 9999; catalog.endTermTerm = catalog.endTerm != "" ? int.Parse("" + catalog.endTerm[4]) : 9; catalog.areaDictionary = new Dictionary <int, AcademicProgram.CatalogChange.Area>(); catalog.flatCourseArray = new List <string>(); prog.catalogChanges.Add(catalog); prog.catalogDictionary.Add(effectiveTerm, catalog); catalog.areas = new List <AcademicProgram.CatalogChange.Area>(); } else { catalog = prog.catalogDictionary[effectiveTerm]; } AcademicProgram.CatalogChange.Area area; if (!catalog.areaDictionary.ContainsKey(areaNum)) { area = new AcademicProgram.CatalogChange.Area(); area.areaNum = areaNum; area.areaType = reader["PGM_AREA_TYPE"].ToString(); area.groupDictionary = new Dictionary <int, AcademicProgram.CatalogChange.Area.Group>(); area.groups = new List <AcademicProgram.CatalogChange.Area.Group>(); catalog.areas.Add(area); catalog.areaDictionary.Add(area.areaNum, area); } else { area = catalog.areaDictionary[areaNum]; } AcademicProgram.CatalogChange.Area.Group group; if (!area.groupDictionary.ContainsKey(groupNum)) { group = new AcademicProgram.CatalogChange.Area.Group(); group.groupNum = groupNum; group.optCode = reader["PGM_AREA_OPTN_CD"].ToString(); group.operatorCode = reader["PGM_AREA_OPTN_OPER"].ToString(); group.courseDictionary = new Dictionary <string, Course>(); group.courses = new List <Course>(); area.groups.Add(group); area.groupDictionary.Add(groupNum, group); } else { group = area.groupDictionary[groupNum]; } Course course; if (!globalCourseDictionary.ContainsKey(courseID)) { course = new Course(); course.courseID = courseID; globalCourseDictionary.Add(courseID, course); } else { course = globalCourseDictionary[courseID]; } group.courseDictionary.Add(courseID, course); group.courses.Add(course); catalog.flatCourseArray.Add(courseID); } reader.Close(); comm = new SqlCommand("SELECT DISTINCT " + " class.campCntr " + " ,loc.LOCATION_NAME " + " FROM " + " MIS.dbo.ST_CLASS_A_151 class " + " INNER JOIN MIS.dbo.FAC199_LOCATION_A_199 loc ON loc.SITE_LOCAL_NUM + loc.LOCATION_NUM = class.campCntr", conn); reader = comm.ExecuteReader(); while (reader.Read()) { String campCntr = reader["campCntr"].ToString(); String locName = reader["LOCATION_NAME"].ToString(); if (options.runForHighSchool) { if (!highschoolCodes.Contains(campCntr)) { continue; } } else { if (highschoolCodes.Contains(campCntr)) { continue; } } if (campCntr.Substring(1, 4) == "7300" || onlineCodes.Contains(campCntr)) { continue; } campusCenters.Add(campCntr); locationNameDict.Add(campCntr, locName); } reader.Close(); comm = new SqlCommand("SELECT DISTINCT " + " class.crsID " + " ,class.campCntr " + " ,class.efftrm " + " ,CASE " + " WHEN course.CRED_TY IN ('01','02','03','14','15') THEN class.EVAL_CRED_HRS " + " ELSE class.CNTCT_HRS " + " END AS HRS " + " ,course.USED_FOR_AA_ELECTIVE " + " FROM " + " MIS.dbo.ST_CLASS_A_151 class " + " INNER JOIN MIS.dbo.ST_COURSE_A_150 course ON course.CRS_ID = class.crsID " + " INNER JOIN MIS.[dbo].[ST_PROGRAMS_A_PGM_AREA_GROUP_CRS_136] groupcourse ON groupcourse.[PGM_AREA_GROUP_CRS] = course.CRS_ID " + " INNER JOIN MIS.dbo.ST_PROGRAMS_A_136 proggroup ON proggroup.ISN_ST_PROGRAMS_A = groupcourse.ISN_ST_PROGRAMS_A " + " WHERE " + " class.efftrm <= '" + options.maxTerm + "' " + (options.campusCenter == "" ? "" : (" AND class.campCntr = '" + options.campusCenter + "'")) + " AND class.efftrm >= '" + options.minTerm + "' " + " AND class.CLS_STAT <> 'C' " + " AND class.CRNT_ENRLD > 0", conn); comm.CommandTimeout = 240; reader = comm.ExecuteReader(); while (reader.Read()) { String curCampusCenter = reader["campCntr"].ToString(); String term = reader["efftrm"].ToString(); String courseID = reader["crsID"].ToString().Trim(); Tuple <String, String> key = new Tuple <string, string>(curCampusCenter, term); float hours = float.Parse(reader["HRS"].ToString()); bool AAElective = reader["USED_FOR_AA_ELECTIVE"].ToString() == "Y"; if (!globalCourseDictionary.ContainsKey(courseID)) { continue; } List <String> courses; if (classesByCampusCenterAndTerm.ContainsKey(key)) { courses = classesByCampusCenterAndTerm[key]; } else { courses = new List <string>(); classesByCampusCenterAndTerm.Add(key, courses); } if (AAElective) { if (!AAElectivesByCampusAndTerm.ContainsKey(key)) { AAElectivesByCampusAndTerm.Add(key, new List <string>()); } if (!AAElectivesByCampusAndTerm[key].Contains(courseID)) { AAElectivesByCampusAndTerm[key].Add(courseID); } } courses.Add(courseID); Course course = globalCourseDictionary[courseID]; course.hours = hours; } reader.Close(); conn.Close(); foreach (AcademicProgram curProgram in programs) { foreach (AcademicProgram.CatalogChange catalog in curProgram.catalogChanges) { foreach (String camp in campusCenters) { float totalProgramHours = 0; float totalGenEdHours = 0; float totalCoreAndProfessionalHours = 0; int curYear = catalog.effectiveTermYear; int curTerm = catalog.effectiveTermTerm; List <String> satisfiedCourses = new List <string>(); List <String> AACoursesForProgram = new List <string>(); Tuple <String, String, String> key = new Tuple <string, string, string>(curProgram.progCode, catalog.effectiveTerm, camp); SatisfiedCoursesForProgramByCatalogYearAndCampusCenter.Add(key, new List <String>()); for (OrionTerm i = startTerm; i <= stopTerm; i++) { Tuple <String, String> yearkey = new Tuple <string, string>(camp, curYear.ToString() + curTerm.ToString()); List <String> coursesAtCampusCenterForTerm; if (classesByCampusCenterAndTerm.ContainsKey(yearkey)) { coursesAtCampusCenterForTerm = classesByCampusCenterAndTerm[yearkey]; } else { continue; } foreach (String course in catalog.flatCourseArray) { if (coursesAtCampusCenterForTerm.Contains(course) && !satisfiedCourses.Contains(course)) { satisfiedCourses.Add(course); SatisfiedCoursesForProgramByCatalogYearAndCampusCenter[key].Add(course); if (curProgram.progCode == "1108") { AACoursesForProgram.Add(course); } } } if (curProgram.progCode == "1108" && AAElectivesByCampusAndTerm.ContainsKey(yearkey)) { foreach (String course in AAElectivesByCampusAndTerm[yearkey]) { if (!AACoursesForProgram.Contains(course)) { AACoursesForProgram.Add(course); totalProgramHours += globalCourseDictionary[course].hours; totalCoreAndProfessionalHours += globalCourseDictionary[course].hours; } } } } if (curProgram.progCode == "1108") { AACoursesByAACatalogAndCampus.Add(key, AACoursesForProgram); } if (satisfiedCourses.Count == 0) { TotalProgramHoursForProgramByCampusCenter.Add(key, totalProgramHours); TotalGeneralEducationHoursForProgramByCampusCenter.Add(key, totalGenEdHours); TotalCoreAndProfessionalForProgramByCampusCenter.Add(key, totalCoreAndProfessionalHours); continue; } foreach (AcademicProgram.CatalogChange.Area area in catalog.areas) { bool genEdArea = false; switch (area.areaType.Substring(0, 2)) { case "01": case "02": case "03": case "04": case "05": if (curProgram.awardType != "VC" && curProgram.awardType != "TC") { genEdArea = true; } break; default: if (curProgram.awardType == "AA") { genEdArea = true; } break; } List <float> groupHours = new List <float>(); List <char> operands = new List <char>(); List <float> andGroups = new List <float>(); foreach (AcademicProgram.CatalogChange.Area.Group group in area.groups) { float groupHoursTotal = 0; List <Course> coursesInGroup = new List <Course>(); foreach (String course in group.courseDictionary.Keys) { if (satisfiedCourses.Contains(course)) { coursesInGroup.Add(group.courseDictionary[course]); } } switch (group.optCode) { case "14": case "00": foreach (Course course in coursesInGroup) { groupHoursTotal += course.hours; } break; case "11": float hoursForGroup = Course.findAndSumFirstNCourses(coursesInGroup, 2); groupHoursTotal += hoursForGroup; break; case "21": case "31": case "41": case "61": case "71": case "81": case "82": case "83": case "84": hoursForGroup = Course.findAndSumFirstNCourses(coursesInGroup, 1); groupHoursTotal += hoursForGroup; break; case "22": case "32": case "42": case "62": case "72": hoursForGroup = Course.findAndSumFirstNCourses(coursesInGroup, 2); groupHoursTotal += hoursForGroup; break; case "23": case "33": case "43": case "63": hoursForGroup = Course.findAndSumFirstNCourses(coursesInGroup, 3); groupHoursTotal += hoursForGroup; break; case "24": case "34": hoursForGroup = Course.findAndSumFirstNCourses(coursesInGroup, 4); groupHoursTotal += hoursForGroup; break; case "25": hoursForGroup = Course.findAndSumFirstNCourses(coursesInGroup, 5); groupHoursTotal += hoursForGroup; break; case "26": case "87": hoursForGroup = Course.findAndSumFirstNCourses(coursesInGroup, 6); groupHoursTotal += hoursForGroup; break; case "27": hoursForGroup = Course.findAndSumFirstNCourses(coursesInGroup, 7); groupHoursTotal += hoursForGroup; break; case "28": hoursForGroup = Course.findAndSumFirstNCourses(coursesInGroup, 8); groupHoursTotal += hoursForGroup; break; case "29": hoursForGroup = Course.findAndSumFirstNCourses(coursesInGroup, 9); groupHoursTotal += hoursForGroup; break; default: break; } groupHours.Add(groupHoursTotal); operands.Add(group.operatorCode.Length == 0 ? ' ' : group.operatorCode[0]); } for (int i = 0; i < operands.Count; i++) { float andGroupTotal = groupHours[0]; int j = i + 1; do { if (j >= operands.Count) { break; } andGroupTotal += groupHours[j]; j++; if (j >= operands.Count) { break; } } while (operands[j] == 'A'); andGroups.Add(andGroupTotal); } float areaHours = 0; if (andGroups.Count == 0) { areaHours = groupHours.Max(); } else { areaHours = andGroups.Max(); } totalProgramHours += areaHours; if (genEdArea) { totalGenEdHours += areaHours; } else { totalCoreAndProfessionalHours += areaHours; } } TotalProgramHoursForProgramByCampusCenter.Add(key, totalProgramHours); TotalGeneralEducationHoursForProgramByCampusCenter.Add(key, totalGenEdHours); TotalCoreAndProfessionalForProgramByCampusCenter.Add(key, totalCoreAndProfessionalHours); } } } DirectoryInfo dataDirectory = new DirectoryInfo("..\\..\\..\\data\\" + options.month + " " + options.year); if (!dataDirectory.Exists) { Directory.CreateDirectory("..\\..\\..\\data\\" + options.month + " " + options.year); } using (System.IO.StreamWriter file = new System.IO.StreamWriter("..\\..\\..\\data\\" + options.month + " " + options.year + "\\SACS " + (options.runForHighSchool ? "High School " : "") + "Program Location Report " + (options.summary ? "Summary " : "") + options.month + " " + options.year + ".csv")) { if (options.summary) { file.WriteLine("PGM CD,AWD TYPE,CATALOG YEAR,CAMP CNTR,LOCATION NAME,TRM FROM,TRM TO,TOT REQD PGM HRS,TOT PGM HRS,% PGM HRS,TOT GEN-ED HRS,TOT PROF HRS"); foreach (AcademicProgram curProgram in programs) { foreach (AcademicProgram.CatalogChange catalog in curProgram.catalogChanges) { foreach (String camp in campusCenters) { Tuple <String, String, String> key = new Tuple <string, string, string>(curProgram.progCode, catalog.effectiveTerm, camp); float totalProgramHours = TotalProgramHoursForProgramByCampusCenter[key] > catalog.totalProgramHours ? catalog.totalProgramHours : TotalProgramHoursForProgramByCampusCenter[key]; float genEdHours = TotalGeneralEducationHoursForProgramByCampusCenter[key] > catalog.totalGeneralEducationHours ? catalog.totalGeneralEducationHours : TotalGeneralEducationHoursForProgramByCampusCenter[key]; float coreAndProfHours = TotalCoreAndProfessionalForProgramByCampusCenter[key] > catalog.totalCoreAndProfessionalHours ? catalog.totalCoreAndProfessionalHours: TotalCoreAndProfessionalForProgramByCampusCenter[key]; float percentageCompletable = (totalProgramHours / catalog.totalProgramHours) * 100; if (totalProgramHours != 0) { file.WriteLine(String.Format(curProgram.progCode + "," + curProgram.awardType + "," + catalog.effectiveTerm + "," + camp + @",""" + locationNameDict[camp] + @"""," + options.minTerm + "," + options.maxTerm + "," + catalog.totalProgramHours + "," + totalProgramHours + @",{0:0.00}," + genEdHours + "," + coreAndProfHours, percentageCompletable)); } } } } } else { file.WriteLine("PGM CD,AWD TYPE,CATALOG YEAR,CAMP CNTR,TRM FROM,TRM TO,AREA,GROUP,CRS ID USED,CRS HRS,TOT PGM HRS,TOT GEN-ED HRS,TOT PROF HRS"); foreach (AcademicProgram curProgram in programs) { foreach (AcademicProgram.CatalogChange catalog in curProgram.catalogChanges) { foreach (String camp in campusCenters) { Tuple <String, String, String> key = new Tuple <string, string, string>(curProgram.progCode, catalog.effectiveTerm, camp); if (SatisfiedCoursesForProgramByCatalogYearAndCampusCenter[key].Count > 0) { foreach (String course in SatisfiedCoursesForProgramByCatalogYearAndCampusCenter[key]) { int areaNum = 0; int groupNum = 0; foreach (AcademicProgram.CatalogChange.Area area in catalog.areas) { foreach (AcademicProgram.CatalogChange.Area.Group group in area.groups) { if (group.courseDictionary.Keys.Contains(course)) { areaNum = area.areaNum; groupNum = group.groupNum; } } } file.WriteLine(curProgram.progCode + "," + curProgram.awardType + "," + catalog.effectiveTerm + "," + camp + "," + options.minTerm + "," + options.maxTerm + "," + areaNum.ToString() + "," + groupNum.ToString() + "," + course + "," + globalCourseDictionary[course].hours.ToString() + "," + (TotalProgramHoursForProgramByCampusCenter[key] > catalog.totalProgramHours ? catalog.totalProgramHours.ToString() : TotalProgramHoursForProgramByCampusCenter[key].ToString()) + "," + (TotalGeneralEducationHoursForProgramByCampusCenter[key] > catalog.totalGeneralEducationHours ? catalog.totalGeneralEducationHours.ToString() : TotalGeneralEducationHoursForProgramByCampusCenter[key].ToString()) + "," + (TotalCoreAndProfessionalForProgramByCampusCenter[key] > catalog.totalCoreAndProfessionalHours ? catalog.totalCoreAndProfessionalHours.ToString() : TotalCoreAndProfessionalForProgramByCampusCenter[key].ToString())); } if (curProgram.progCode == "1108") { foreach (String course in AACoursesByAACatalogAndCampus[key]) { int curYear = minTermYear; int curTerm = minTermTerm; if (!SatisfiedCoursesForProgramByCatalogYearAndCampusCenter[key].Contains(course)) { file.WriteLine(curProgram.progCode + "," + curProgram.awardType + "," + catalog.effectiveTerm + "," + camp + "," + options.minTerm + "," + options.maxTerm + ",ELEC,," + course + "," + globalCourseDictionary[course].hours.ToString() + "," + (TotalProgramHoursForProgramByCampusCenter[key] > catalog.totalProgramHours ? catalog.totalProgramHours.ToString() : TotalProgramHoursForProgramByCampusCenter[key].ToString()) + "," + (TotalGeneralEducationHoursForProgramByCampusCenter[key] > catalog.totalGeneralEducationHours ? catalog.totalGeneralEducationHours.ToString(): TotalGeneralEducationHoursForProgramByCampusCenter[key].ToString()) + "," + (TotalCoreAndProfessionalForProgramByCampusCenter[key] > catalog.totalCoreAndProfessionalHours ? catalog.totalCoreAndProfessionalHours.ToString() : TotalCoreAndProfessionalForProgramByCampusCenter[key].ToString())); } } } } } } } } file.Close(); return(0); } }