001package org.cpsolver.studentsct.report; 002 003import java.util.HashSet; 004import java.util.Map; 005import java.util.Set; 006 007import org.cpsolver.ifs.assignment.Assignment; 008import org.cpsolver.ifs.util.CSVFile; 009import org.cpsolver.ifs.util.DataProperties; 010import org.cpsolver.studentsct.StudentSectioningModel; 011import org.cpsolver.studentsct.model.Choice; 012import org.cpsolver.studentsct.model.Config; 013import org.cpsolver.studentsct.model.Course; 014import org.cpsolver.studentsct.model.CourseRequest; 015import org.cpsolver.studentsct.model.Enrollment; 016import org.cpsolver.studentsct.model.Request; 017import org.cpsolver.studentsct.model.Section; 018import org.cpsolver.studentsct.model.Student; 019import org.cpsolver.studentsct.model.Subpart; 020import org.cpsolver.studentsct.reservation.Reservation; 021 022/** 023 * This reports lists information needed for additional reporting.<br> 024 * <br> 025 * 026 * @version StudentSct 1.3 (Student Sectioning)<br> 027 * Copyright (C) 2015 Tomáš Müller<br> 028 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br> 029 * <a href="http://muller.unitime.org">http://muller.unitime.org</a><br> 030 * <br> 031 * This library is free software; you can redistribute it and/or modify 032 * it under the terms of the GNU Lesser General Public License as 033 * published by the Free Software Foundation; either version 3 of the 034 * License, or (at your option) any later version. <br> 035 * <br> 036 * This library is distributed in the hope that it will be useful, but 037 * WITHOUT ANY WARRANTY; without even the implied warranty of 038 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 039 * Lesser General Public License for more details. <br> 040 * <br> 041 * You should have received a copy of the GNU Lesser General Public 042 * License along with this library; if not see 043 * <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>. 044 */ 045public class TableauReport extends AbstractStudentSectioningReport { 046 047 /** 048 * Constructor 049 * 050 * @param model 051 * student sectioning model 052 */ 053 public TableauReport(StudentSectioningModel model) { 054 super(model); 055 } 056 057 @Override 058 public CSVFile createTable(Assignment<Request, Enrollment> assignment, DataProperties properties) { 059 CSVFile csv = new CSVFile(); 060 boolean simple = properties.getPropertyBoolean("simple", false); 061 if (simple) { 062 csv.setHeader(new CSVFile.CSVField[] { 063 new CSVFile.CSVField("__Student"), 064 new CSVFile.CSVField("Student"), 065 new CSVFile.CSVField("Course"), 066 new CSVFile.CSVField("Course Limit"), 067 new CSVFile.CSVField("Primary"), 068 new CSVFile.CSVField("Priority"), 069 new CSVFile.CSVField("Alternativity"), 070 new CSVFile.CSVField("Enrolled"), 071 new CSVFile.CSVField("Request Type") 072 }); 073 } else { 074 csv.setHeader(new CSVFile.CSVField[] { 075 new CSVFile.CSVField("__Student"), 076 new CSVFile.CSVField("Student"), 077 new CSVFile.CSVField("Course"), 078 new CSVFile.CSVField("Course Limit"), 079 new CSVFile.CSVField("Controlling Course"), 080 new CSVFile.CSVField("Primary"), 081 new CSVFile.CSVField("Priority"), 082 new CSVFile.CSVField("Alternativity"), 083 new CSVFile.CSVField("Enrolled"), 084 new CSVFile.CSVField("Credits"), 085 new CSVFile.CSVField("Sections"), 086 new CSVFile.CSVField("Preferred Sections"), 087 new CSVFile.CSVField("Required Sections"), 088 new CSVFile.CSVField("Instructional Method"), 089 new CSVFile.CSVField("Preferred Instructional Methods"), 090 new CSVFile.CSVField("Required Instructional Methods"), 091 new CSVFile.CSVField("Request Type") 092 }); 093 } 094 for (Student student: getModel().getStudents()) { 095 if (student.isDummy()) continue; 096 int regPriority = 1, altPriority = 1; 097 for (Request r: student.getRequests()) { 098 if (r instanceof CourseRequest) { 099 CourseRequest cr = (CourseRequest)r; 100 Enrollment e = cr.getAssignment(assignment); 101 if (!matches(r, e)) continue; 102 int primary = (cr.isAlternative() ? 0 : 1); 103 int priority = 0; 104 if (cr.isAlternative()) 105 priority = altPriority++; 106 else 107 priority = regPriority++; 108 int alternativity = 0; 109 for (Course course: cr.getCourses()) { 110 int enrolled = (e != null && e.getCourse().equals(course) ? 1 : 0); 111 String sect = null; 112 if (e != null && e.getCourse().equals(course)) { 113 sect = ""; 114 Set<String> added = new HashSet<String>(); 115 for (Section s: e.getSections()) { 116 String x = s.getName(e.getCourse().getId()); 117 if (x.indexOf('-') > 0) x = x.substring(0, x.indexOf('-')); 118 if (added.add(x)) sect += (sect.isEmpty() ? "" : ",") + x; 119 } 120 } 121 String imR = "", sctR = ""; 122 Set<String> addedR = new HashSet<String>(); 123 for (Choice ch: cr.getRequiredChoices()) { 124 if (course.getOffering().equals(ch.getOffering())) { 125 if (ch.getConfigId() != null) { 126 for (Config cfg: ch.getOffering().getConfigs()) { 127 if (ch.getConfigId().equals(cfg.getId())) { 128 String im = cfg.getInstructionalMethodReference(); 129 if (im != null && addedR.add(im)) 130 imR += (imR.isEmpty() ? "" : ",") + im; 131 } 132 } 133 } 134 if (ch.getSectionId() != null) { 135 String x = ch.getOffering().getSection(ch.getSectionId()).getName(course.getId()); 136 if (x.indexOf('-') > 0) x = x.substring(0, x.indexOf('-')); 137 if (addedR.add(x)) 138 sctR += (sctR.isEmpty() ? "" : ",") + x; 139 } 140 } 141 } 142 for (Reservation rs: cr.getReservations(course)) { 143 if (rs.mustBeUsed()) { 144 for (Map.Entry<Subpart, Set<Section>> ent: rs.getSections().entrySet()) { 145 for (Section s: ent.getValue()) { 146 String x = s.getName(course.getId()); 147 if (x.indexOf('-') > 0) x = x.substring(0, x.indexOf('-')); 148 if (addedR.add(x)) 149 sctR += (sctR.isEmpty() ? "" : ",") + x; 150 } 151 } 152 if (rs.getSections().isEmpty()) { 153 for (Config cfg: rs.getConfigs()) { 154 String im = cfg.getInstructionalMethodReference(); 155 if (im != null && addedR.add(im)) 156 imR += (imR.isEmpty() ? "" : ",") + im; 157 } 158 } 159 } 160 } 161 String imP = "", sctP = ""; 162 for (Choice ch: cr.getSelectedChoices()) { 163 Set<String> added = new HashSet<String>(); 164 if (course.getOffering().equals(ch.getOffering())) { 165 if (ch.getConfigId() != null) { 166 for (Config cfg: ch.getOffering().getConfigs()) { 167 if (ch.getConfigId().equals(cfg.getId())) { 168 String im = cfg.getInstructionalMethodReference(); 169 if (im != null && added.add(im)) 170 imP += (imP.isEmpty() ? "" : ",") + im; 171 } 172 } 173 } 174 if (ch.getSectionId() != null) { 175 String x = ch.getOffering().getSection(ch.getSectionId()).getName(course.getId()); 176 if (x.indexOf('-') > 0) x = x.substring(0, x.indexOf('-')); 177 if (added.add(x)) 178 sctP += (sctP.isEmpty() ? "" : ",") + x; 179 } 180 } 181 } 182 if (simple) 183 csv.addLine(new CSVFile.CSVField[] { 184 new CSVFile.CSVField(student.getId()), 185 new CSVFile.CSVField(student.getExternalId()), 186 new CSVFile.CSVField(course.getName()), 187 new CSVFile.CSVField(course.getLimit() < 0 ? null : course.getLimit()), 188 new CSVFile.CSVField(primary == 1 ? "Yes" : "No"), 189 new CSVFile.CSVField(priority), 190 new CSVFile.CSVField(alternativity), 191 new CSVFile.CSVField(enrolled == 1 ? "Yes" : "No"), 192 new CSVFile.CSVField(cr.getRequestPriority() == null ? "" : cr.getRequestPriority().name()) 193 }); 194 else 195 csv.addLine(new CSVFile.CSVField[] { 196 new CSVFile.CSVField(student.getId()), 197 new CSVFile.CSVField(student.getExternalId()), 198 new CSVFile.CSVField(course.getName()), 199 new CSVFile.CSVField(course.getLimit() < 0 ? null : course.getLimit()), 200 new CSVFile.CSVField(course.getOffering().getCourses().size() <= 1 ? null : course.getOffering().getName()), 201 new CSVFile.CSVField(primary == 1 ? "Yes" : "No"), 202 new CSVFile.CSVField(priority), 203 new CSVFile.CSVField(alternativity), 204 new CSVFile.CSVField(enrolled == 1 ? "Yes" : "No"), 205 new CSVFile.CSVField(enrolled == 1 ? e.getCredit() : course.getCreditValue() == null ? 0f : course.getCreditValue()), 206 new CSVFile.CSVField(sect), 207 new CSVFile.CSVField(sctP), 208 new CSVFile.CSVField(sctR), 209 new CSVFile.CSVField(e != null ? e.getConfig().getInstructionalMethodReference() : null), 210 new CSVFile.CSVField(imP), 211 new CSVFile.CSVField(imR), 212 new CSVFile.CSVField(cr.getRequestPriority() == null ? "" : cr.getRequestPriority().name()) 213 }); 214 alternativity++; 215 } 216 } 217 } 218 } 219 return csv; 220 } 221}