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}