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}