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