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 implements StudentSectioningReport { 046 private StudentSectioningModel iModel = null; 047 048 /** 049 * Constructor 050 * 051 * @param model 052 * student sectioning model 053 */ 054 public TableauReport(StudentSectioningModel model) { 055 iModel = model; 056 } 057 058 /** Return student sectioning model 059 * @return problem model 060 **/ 061 public StudentSectioningModel getModel() { 062 return iModel; 063 } 064 065 @Override 066 public CSVFile create(Assignment<Request, Enrollment> assignment, DataProperties properties) { 067 CSVFile csv = new CSVFile(); 068 boolean simple = properties.getPropertyBoolean("simple", false); 069 if (simple) { 070 csv.setHeader(new CSVFile.CSVField[] { 071 new CSVFile.CSVField("__Student"), 072 new CSVFile.CSVField("Student"), 073 new CSVFile.CSVField("Course"), 074 new CSVFile.CSVField("Course Limit"), 075 new CSVFile.CSVField("Primary"), 076 new CSVFile.CSVField("Priority"), 077 new CSVFile.CSVField("Alternativity"), 078 new CSVFile.CSVField("Enrolled"), 079 new CSVFile.CSVField("Request Type") 080 }); 081 } else { 082 csv.setHeader(new CSVFile.CSVField[] { 083 new CSVFile.CSVField("__Student"), 084 new CSVFile.CSVField("Student"), 085 new CSVFile.CSVField("Course"), 086 new CSVFile.CSVField("Course Limit"), 087 new CSVFile.CSVField("Controlling Course"), 088 new CSVFile.CSVField("Primary"), 089 new CSVFile.CSVField("Priority"), 090 new CSVFile.CSVField("Alternativity"), 091 new CSVFile.CSVField("Enrolled"), 092 new CSVFile.CSVField("Credits"), 093 new CSVFile.CSVField("Sections"), 094 new CSVFile.CSVField("Preferred Sections"), 095 new CSVFile.CSVField("Required Sections"), 096 new CSVFile.CSVField("Instructional Method"), 097 new CSVFile.CSVField("Preferred Instructional Methods"), 098 new CSVFile.CSVField("Required Instructional Methods"), 099 new CSVFile.CSVField("Request Type") 100 }); 101 } 102 for (Student student: getModel().getStudents()) { 103 if (student.isDummy()) continue; 104 int regPriority = 1, altPriority = 1; 105 for (Request r: student.getRequests()) { 106 if (r instanceof CourseRequest) { 107 CourseRequest cr = (CourseRequest)r; 108 Enrollment e = cr.getAssignment(assignment); 109 int primary = (cr.isAlternative() ? 0 : 1); 110 int priority = 0; 111 if (cr.isAlternative()) 112 priority = altPriority++; 113 else 114 priority = regPriority++; 115 int alternativity = 0; 116 for (Course course: cr.getCourses()) { 117 int enrolled = (e != null && e.getCourse().equals(course) ? 1 : 0); 118 String sect = null; 119 if (e != null && e.getCourse().equals(course)) { 120 sect = ""; 121 Set<String> added = new HashSet<String>(); 122 for (Section s: e.getSections()) { 123 String x = s.getName(e.getCourse().getId()); 124 if (x.indexOf('-') > 0) x = x.substring(0, x.indexOf('-')); 125 if (added.add(x)) sect += (sect.isEmpty() ? "" : ",") + x; 126 } 127 } 128 String imR = "", sctR = ""; 129 Set<String> addedR = new HashSet<String>(); 130 for (Choice ch: cr.getRequiredChoices()) { 131 if (course.getOffering().equals(ch.getOffering())) { 132 if (ch.getConfigId() != null) { 133 for (Config cfg: ch.getOffering().getConfigs()) { 134 if (ch.getConfigId().equals(cfg.getId())) { 135 String im = cfg.getInstructionalMethodReference(); 136 if (im != null && addedR.add(im)) 137 imR += (imR.isEmpty() ? "" : ",") + im; 138 } 139 } 140 } 141 if (ch.getSectionId() != null) { 142 String x = ch.getOffering().getSection(ch.getSectionId()).getName(course.getId()); 143 if (x.indexOf('-') > 0) x = x.substring(0, x.indexOf('-')); 144 if (addedR.add(x)) 145 sctR += (sctR.isEmpty() ? "" : ",") + x; 146 } 147 } 148 } 149 for (Reservation rs: cr.getReservations(course)) { 150 if (rs.mustBeUsed()) { 151 for (Map.Entry<Subpart, Set<Section>> ent: rs.getSections().entrySet()) { 152 for (Section s: ent.getValue()) { 153 String x = s.getName(course.getId()); 154 if (x.indexOf('-') > 0) x = x.substring(0, x.indexOf('-')); 155 if (addedR.add(x)) 156 sctR += (sctR.isEmpty() ? "" : ",") + x; 157 } 158 } 159 if (rs.getSections().isEmpty()) { 160 for (Config cfg: rs.getConfigs()) { 161 String im = cfg.getInstructionalMethodReference(); 162 if (im != null && addedR.add(im)) 163 imR += (imR.isEmpty() ? "" : ",") + im; 164 } 165 } 166 } 167 } 168 String imP = "", sctP = ""; 169 for (Choice ch: cr.getSelectedChoices()) { 170 Set<String> added = new HashSet<String>(); 171 if (course.getOffering().equals(ch.getOffering())) { 172 if (ch.getConfigId() != null) { 173 for (Config cfg: ch.getOffering().getConfigs()) { 174 if (ch.getConfigId().equals(cfg.getId())) { 175 String im = cfg.getInstructionalMethodReference(); 176 if (im != null && added.add(im)) 177 imP += (imP.isEmpty() ? "" : ",") + im; 178 } 179 } 180 } 181 if (ch.getSectionId() != null) { 182 String x = ch.getOffering().getSection(ch.getSectionId()).getName(course.getId()); 183 if (x.indexOf('-') > 0) x = x.substring(0, x.indexOf('-')); 184 if (added.add(x)) 185 sctP += (sctP.isEmpty() ? "" : ",") + x; 186 } 187 } 188 } 189 if (simple) 190 csv.addLine(new CSVFile.CSVField[] { 191 new CSVFile.CSVField(student.getId()), 192 new CSVFile.CSVField(student.getExternalId()), 193 new CSVFile.CSVField(course.getName()), 194 new CSVFile.CSVField(course.getLimit() < 0 ? null : course.getLimit()), 195 new CSVFile.CSVField(primary == 1 ? "Yes" : "No"), 196 new CSVFile.CSVField(priority), 197 new CSVFile.CSVField(alternativity), 198 new CSVFile.CSVField(enrolled == 1 ? "Yes" : "No"), 199 new CSVFile.CSVField(cr.getRequestPriority() == null ? "" : cr.getRequestPriority().name()) 200 }); 201 else 202 csv.addLine(new CSVFile.CSVField[] { 203 new CSVFile.CSVField(student.getId()), 204 new CSVFile.CSVField(student.getExternalId()), 205 new CSVFile.CSVField(course.getName()), 206 new CSVFile.CSVField(course.getLimit() < 0 ? null : course.getLimit()), 207 new CSVFile.CSVField(course.getOffering().getCourses().size() <= 1 ? null : course.getOffering().getName()), 208 new CSVFile.CSVField(primary == 1 ? "Yes" : "No"), 209 new CSVFile.CSVField(priority), 210 new CSVFile.CSVField(alternativity), 211 new CSVFile.CSVField(enrolled == 1 ? "Yes" : "No"), 212 new CSVFile.CSVField(enrolled == 1 ? e.getCredit() : course.getCreditValue() == null ? 0f : course.getCreditValue()), 213 new CSVFile.CSVField(sect), 214 new CSVFile.CSVField(sctP), 215 new CSVFile.CSVField(sctR), 216 new CSVFile.CSVField(e != null ? e.getConfig().getInstructionalMethodReference() : null), 217 new CSVFile.CSVField(imP), 218 new CSVFile.CSVField(imR), 219 new CSVFile.CSVField(cr.getRequestPriority() == null ? "" : cr.getRequestPriority().name()) 220 }); 221 alternativity++; 222 } 223 } 224 } 225 } 226 return csv; 227 } 228}