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