/** * Copyright © 2002 Instituto Superior Técnico * * This file is part of FenixEdu Academic. * * FenixEdu Academic is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * FenixEdu Academic is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with FenixEdu Academic. If not, see <http://www.gnu.org/licenses/>. */ package org.fenixedu.academic.domain.reports; import java.io.ByteArrayOutputStream; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.apache.commons.lang.StringUtils; import org.fenixedu.academic.domain.CompetenceCourse; import org.fenixedu.academic.domain.CurricularCourse; import org.fenixedu.academic.domain.Degree; import org.fenixedu.academic.domain.DegreeCurricularPlan; import org.fenixedu.academic.domain.ExecutionCourse; import org.fenixedu.academic.domain.ExecutionDegree; import org.fenixedu.academic.domain.ExecutionSemester; import org.fenixedu.academic.domain.ExecutionYear; import org.fenixedu.academic.domain.Professorship; import org.fenixedu.academic.domain.QueueJobResult; import org.fenixedu.academic.domain.Shift; import org.fenixedu.academic.domain.WrittenEvaluation; import org.fenixedu.academic.domain.degree.DegreeType; import org.fenixedu.academic.domain.student.Registration; import org.fenixedu.academic.domain.student.curriculum.ConclusionProcess; import org.fenixedu.academic.domain.student.registrationStates.RegistrationStateType; import org.fenixedu.academic.util.HtmlToTextConverterUtil; import org.fenixedu.commons.spreadsheet.Spreadsheet; import org.fenixedu.commons.spreadsheet.Spreadsheet.Row; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.hash.Hashing; public abstract class GepReportFile extends GepReportFile_Base { private static final Logger logger = LoggerFactory.getLogger(GepReportFile.class); public static final String CODE_SEPARATOR = "_#_"; public GepReportFile() { super(); } public static String getExecutionSemesterCode(ExecutionSemester executionSemester) { return executionSemester.getSemester() + CODE_SEPARATOR + executionSemester.getYear(); } public static String getExecutionCourseCode(ExecutionCourse executionCourse) { return executionCourse.getSigla() + CODE_SEPARATOR + getExecutionSemesterCode(executionCourse.getExecutionPeriod()); } public static String getExecutionDegreeCode(ExecutionDegree executionDegree) { return getDegreeCurricularPlanCode(executionDegree.getDegreeCurricularPlan()) + CODE_SEPARATOR + executionDegree.getExecutionYear().getName(); } private static String getDegreeCurricularPlanCode(DegreeCurricularPlan dcp) { return dcp.getName() + CODE_SEPARATOR + dcp.getDegree().getSigla(); } public static String getCompetenceCourseCode(CompetenceCourse competenceCourse) { return competenceCourse.getAcronym(); } public static String getProfessorshipCode(Professorship professorship) { return professorship.getPerson().getUsername() + CODE_SEPARATOR + getExecutionCourseCode(professorship.getExecutionCourse()); } public static String getShiftCode(Shift shift) { return shift.getNome() + CODE_SEPARATOR + getExecutionCourseCode(shift.getExecutionCourse()); } public static String getWrittenEvaluationCode(WrittenEvaluation writtenEvaluation) { StringBuilder code = new StringBuilder().append(writtenEvaluation.getInterval().toString()).append(writtenEvaluation.getFullName()) .append(writtenEvaluation.getEvaluationType().toString()); writtenEvaluation.getAssociatedExecutionCoursesSet().stream().forEach(ec -> code.append(getExecutionCourseCode(ec))); return Hashing.murmur3_128().hashBytes(code.toString().getBytes(StandardCharsets.UTF_8)).toString(); } public static ExecutionYear getExecutionYearFourYearsBack(final ExecutionYear executionYear) { ExecutionYear executionYearFourYearsBack = executionYear; if (executionYear != null) { for (int i = 5; i > 1; i--) { final ExecutionYear previousExecutionYear = executionYearFourYearsBack.getPreviousExecutionYear(); if (previousExecutionYear != null) { executionYearFourYearsBack = previousExecutionYear; } } } return executionYearFourYearsBack; } @Override public String getDescription() { return " no formato " + getType().toUpperCase(); } public abstract String getJobName(); protected abstract String getPrefix(); @Override public String getFilename() { return getReportName().replace(' ', '_') + "." + getType(); } private String getReportName() { final StringBuilder result = new StringBuilder(); result.append(getRequestDate().toString("yyyy_MM_dd_HH_mm")).append("_"); result.append(getPrefix()).append("_"); result.append(getDegreeType() == null ? "Todos_Cursos" : getDegreeType().getName().getContent()).append("_"); result.append(getExecutionYear() == null ? "Todos_Anos" : getExecutionYear().getName().replace('/', '_')); return result.toString(); } protected void setDegreeHeaders(final Spreadsheet spreadsheet) { spreadsheet.setHeader("tipo curso"); spreadsheet.setHeader("nome curso"); spreadsheet.setHeader("sigla curso"); } protected void setDegreeHeaders(final Spreadsheet spreadsheet, final String suffix) { spreadsheet.setHeader("tipo curso " + suffix); spreadsheet.setHeader("nome curso " + suffix); spreadsheet.setHeader("sigla curso " + suffix); } protected void setDegreeCells(final Row row, final Degree degree) { row.setCell(degree.getDegreeType().getName().getContent()); row.setCell(degree.getNameI18N().getContent()); row.setCell(degree.getSigla()); } protected boolean checkDegreeType(final DegreeType degreeType, final ConclusionProcess conclusionProcess) { return degreeType == null || conclusionProcess.getDegree().getDegreeType() == degreeType; } protected static boolean checkDegreeType(final DegreeType degreeType, final Degree degree) { return degreeType == null || degree.getDegreeType() == degreeType; } protected static boolean checkExecutionYear(final ExecutionYear executionYear, final DegreeCurricularPlan degreeCurricularPlan) { return executionYear == null || degreeCurricularPlan.hasExecutionDegreeFor(executionYear); } protected static boolean checkExecutionYear(ExecutionYear executionYear, final CurricularCourse curricularCourse) { return executionYear == null || curricularCourse.isActive(executionYear); } protected static boolean checkExecutionYear(ExecutionYear executionYear, ExecutionCourse executionCourse) { return executionYear == null || executionCourse.getExecutionYear().equals(executionYear); } protected boolean isActive(final Degree degree) { for (final DegreeCurricularPlan degreeCurricularPlan : degree.getDegreeCurricularPlansSet()) { if (checkExecutionYear(getExecutionYear(), degreeCurricularPlan)) { return true; } } return false; } protected String normalize(final String text) { if (!StringUtils.isEmpty(text)) { String result = ""; try { result = HtmlToTextConverterUtil.convertToText(text); } catch (Exception ex) { result = HtmlToTextConverterUtil.convertToTextWithRegEx(text); } return result.replace('\t', ' ').replace('\n', ' ').replace('\r', ' '); } return ""; } public abstract void renderReport(Spreadsheet spreadsheet) throws Exception; @Override public QueueJobResult execute() throws Exception { final Spreadsheet spreadsheet = new Spreadsheet(getReportName()); this.renderReport(spreadsheet); ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream(); if ("csv".compareTo(getType()) == 0) { spreadsheet.exportToCSV(byteArrayOS, "\t"); } else { spreadsheet.exportToXLSSheet(byteArrayOS); } final QueueJobResult queueJobResult = new QueueJobResult(); queueJobResult.setContentType("application/txt"); queueJobResult.setContent(byteArrayOS.toByteArray()); logger.info("Job " + getFilename() + " completed"); return queueJobResult; } public String getUpperCaseType() { return this.getType().toUpperCase(); } protected static List<Registration> getFullRegistrationPath(final Registration current) { if (current.getDegreeType().isBolonhaDegree() || current.getDegreeType().isIntegratedMasterDegree()) { List<Registration> path = new ArrayList<Registration>(); path.add(current); Registration source; if (current.getSourceRegistration() != null && (!(source = current.getSourceRegistration()).isBolonha() || isValidSourceLink(source))) { path.addAll(getFullRegistrationPath(source)); } else if ((source = findSourceRegistrationByEquivalencePlan(current)) != null) { path.addAll(getFullRegistrationPath(source)); } Collections.sort(path, Registration.COMPARATOR_BY_START_DATE); return path; } else { return Collections.singletonList(current); } } protected static boolean isValidSourceLink(Registration source) { return source.getActiveStateType().equals(RegistrationStateType.TRANSITED) || source.getActiveStateType().equals(RegistrationStateType.FLUNKED) || source.getActiveStateType().equals(RegistrationStateType.INTERNAL_ABANDON) || source.getActiveStateType().equals(RegistrationStateType.EXTERNAL_ABANDON) || source.getActiveStateType().equals(RegistrationStateType.INTERRUPTED); } private static Registration findSourceRegistrationByEquivalencePlan(Registration targetRegistration) { final DegreeCurricularPlan targetDegreeCurricularPlan = targetRegistration.getLastDegreeCurricularPlan(); if (targetDegreeCurricularPlan.getEquivalencePlan() != null) { for (Registration sourceRegistration : targetRegistration.getStudent().getRegistrationsSet()) { final DegreeCurricularPlan sourceDegreeCurricularPlan = sourceRegistration.getLastDegreeCurricularPlan(); if (sourceRegistration != targetRegistration && sourceRegistration.getActiveStateType() == RegistrationStateType.TRANSITED && targetDegreeCurricularPlan.getEquivalencePlan().getSourceDegreeCurricularPlan() .equals(sourceDegreeCurricularPlan)) { return sourceRegistration; } } } return null; } }