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.Request.RequestPriority;
018import org.cpsolver.studentsct.model.Section;
019import org.cpsolver.studentsct.model.Student;
020import org.cpsolver.studentsct.model.Subpart;
021import org.cpsolver.studentsct.reservation.Reservation;
022
023/**
024 * This reports lists information needed for additional reporting.<br>
025 * <br>
026 * 
027 * @version StudentSct 1.3 (Student Sectioning)<br>
028 *          Copyright (C) 2015 Tomas Muller<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 implements StudentSectioningReport {
047    private StudentSectioningModel iModel = null;
048
049    /**
050     * Constructor
051     * 
052     * @param model
053     *            student sectioning model
054     */
055    public TableauReport(StudentSectioningModel model) {
056        iModel = model;
057    }
058
059    /** Return student sectioning model 
060     * @return problem model
061     **/
062    public StudentSectioningModel getModel() {
063        return iModel;
064    }
065    
066    @Override
067    public CSVFile create(Assignment<Request, Enrollment> assignment, DataProperties properties) {
068        CSVFile csv = new CSVFile();
069        boolean simple = properties.getPropertyBoolean("simple", false);
070        RequestPriority rp = RequestPriority.valueOf(properties.getProperty("priority", RequestPriority.Critical.name()));
071        if (simple) {
072            csv.setHeader(new CSVFile.CSVField[] {
073                    new CSVFile.CSVField("__Student"),
074                    new CSVFile.CSVField("Student"),
075                    new CSVFile.CSVField("Course"),
076                    new CSVFile.CSVField("Course Limit"),
077                    new CSVFile.CSVField("Primary"),
078                    new CSVFile.CSVField("Priority"),
079                    new CSVFile.CSVField("Alternativity"),
080                    new CSVFile.CSVField("Enrolled")});
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("Critical")
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) {
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                            });
200                        else
201                            csv.addLine(new CSVFile.CSVField[] {
202                                    new CSVFile.CSVField(student.getId()),
203                                    new CSVFile.CSVField(student.getExternalId()),
204                                    new CSVFile.CSVField(course.getName()),
205                                    new CSVFile.CSVField(course.getLimit() < 0 ? null : course.getLimit()),
206                                    new CSVFile.CSVField(course.getOffering().getCourses().size() <= 1 ? null : course.getOffering().getName()),
207                                    new CSVFile.CSVField(primary == 1 ? "Yes" : "No"),
208                                    new CSVFile.CSVField(priority),
209                                    new CSVFile.CSVField(alternativity),
210                                    new CSVFile.CSVField(enrolled == 1 ? "Yes" : "No"),
211                                    new CSVFile.CSVField(enrolled == 1 ? e.getCredit() : course.getCreditValue() == null ? 0f : course.getCreditValue()),
212                                    new CSVFile.CSVField(sect),
213                                    new CSVFile.CSVField(sctP),
214                                    new CSVFile.CSVField(sctR),
215                                    new CSVFile.CSVField(e != null ? e.getConfig().getInstructionalMethodReference() : null),
216                                    new CSVFile.CSVField(imP),
217                                    new CSVFile.CSVField(imR),
218                                    new CSVFile.CSVField(rp.isCritical(cr) ? "Yes" : "No")
219                            });
220                        alternativity++;
221                    }
222                }
223            }
224        }
225        return csv;
226    }
227}