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}