Skip to content

Instantly share code, notes, and snippets.

@ricardorcr
Created July 29, 2016 14:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ricardorcr/2ebf96dc2bbe8d6ee32a80e1d8cbfc43 to your computer and use it in GitHub Desktop.
Save ricardorcr/2ebf96dc2bbe8d6ee32a80e1d8cbfc43 to your computer and use it in GitHub Desktop.
Validate Bolonha Enrolments
package pt.ist.fenixedu.integration.task.exportData.academic;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
import org.fenixedu.academic.domain.Enrolment;
import org.fenixedu.academic.domain.ExecutionSemester;
import org.fenixedu.academic.domain.Person;
import org.fenixedu.academic.domain.StudentCurricularPlan;
import org.fenixedu.academic.domain.accessControl.AcademicAuthorizationGroup;
import org.fenixedu.academic.domain.accessControl.academicAdministration.AcademicOperationType;
import org.fenixedu.academic.domain.curricularRules.executors.RuleResult;
import org.fenixedu.academic.domain.curricularRules.executors.RuleResultMessage;
import org.fenixedu.academic.domain.curricularRules.executors.ruleExecutors.CurricularRuleLevel;
import org.fenixedu.academic.domain.curriculum.EnrollmentCondition;
import org.fenixedu.academic.domain.exceptions.EnrollmentDomainException;
import org.fenixedu.academic.domain.log.CurriculumLineLog;
import org.fenixedu.academic.domain.person.RoleType;
import org.fenixedu.academic.domain.student.Registration;
import org.fenixedu.academic.domain.student.Student;
import org.fenixedu.bennu.core.domain.User;
import org.fenixedu.bennu.core.domain.exceptions.DomainException;
import org.fenixedu.bennu.core.security.Authenticate;
import org.fenixedu.bennu.scheduler.custom.CustomTask;
import org.fenixedu.commons.spreadsheet.Spreadsheet;
import org.fenixedu.commons.spreadsheet.Spreadsheet.Row;
import org.joda.time.DateTime;
import pt.ist.fenixframework.Atomic.TxMode;
import pt.ist.fenixframework.FenixFramework;
public class ValidateBolonhaEnrolments extends CustomTask {
private static final ResourceBundle APPLICATION_RESOURCES = ResourceBundle.getBundle("resources/ApplicationResources",
new Locale("pt", "PT"));
@Override
public TxMode getTxMode() {
return TxMode.READ;
}
@Override
public void runTask() throws Exception {
final Spreadsheet spreadsheet = createSpreadsheet();
final ExecutionSemester executionPeriod = ExecutionSemester.readActualExecutionSemester();
Authenticate.mock(User.findByUsername("ist23000"));
taskLog("Validating for " + executionPeriod.getName() + " " + executionPeriod.getExecutionYear().getYear());
// validateOneStudent(person, executionPeriod, 51011, spreadsheet);
validateAllStudentCurricularPlans(executionPeriod, spreadsheet);
ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream();
spreadsheet.exportToXLSSheet(byteArrayOS);
output("validacao_inscricoes_" + new DateTime().toString("ddMMyyyyHHmm") + ".xls", byteArrayOS.toByteArray());
}
private Spreadsheet createSpreadsheet() {
final Spreadsheet spreadsheet = new Spreadsheet("Validation");
spreadsheet.setHeaders("Curso,Numero,Nome,Inscrição Secretaria,Disciplinas Impossíveis,Mensagens".split(","));
return spreadsheet;
}
protected void validateOneStudent(ExecutionSemester executionPeriod, int studentNumber, Spreadsheet spreadsheet)
throws Exception {
final Student student = Student.readStudentByNumber(studentNumber);
for (final Registration registration : student.getActiveRegistrations()) {
for (final StudentCurricularPlan studentCurricularPlan : registration.getStudentCurricularPlansSet()) {
enrollStudent(studentCurricularPlan, executionPeriod, spreadsheet);
}
}
}
protected void validateAllStudentCurricularPlans(final ExecutionSemester executionSemester, Spreadsheet spreadsheet)
throws Exception {
taskLog("Building scps list ...");
final Set<StudentCurricularPlan> scps = new HashSet<StudentCurricularPlan>();
for (final Enrolment enrolment : executionSemester.getEnrolmentsSet()) {
scps.add(enrolment.getStudentCurricularPlan());
}
taskLog("Found " + scps.size() + " students");
for (final StudentCurricularPlan scp : scps) {
final Student student = scp.getRegistration().getStudent();
if (!student.getRegistrationsToEnrolByStudent().contains(scp.getRegistration())) {
//taskLog("\t no registration to be enroled");
continue;
}
enrollStudent(scp, executionSemester, spreadsheet);
}
}
private void enrollStudent(StudentCurricularPlan studentCurricularPlan, ExecutionSemester executionSemester,
Spreadsheet spreadsheet) throws Exception {
FenixFramework.atomic(() -> {
RuleResult result = null;
Integer number = null;
try {
number = studentCurricularPlan.getRegistration().getStudent().getNumber();
result = studentCurricularPlan.enrol(executionSemester, CurricularRuleLevel.ENROLMENT_VERIFICATION_WITH_RULES);
String printErrors = printErrors(result);
if (printErrors.length() > 0) {
taskLog("Processed SCP " + studentCurricularPlan.getExternalId() + " for student " + number);
taskLog(printErrors(result));
}
} catch (EnrollmentDomainException e) {
taskLog("Processed SCP " + studentCurricularPlan.getExternalId() + " for student " + number);
taskLog(printErrors(e.getFalseResult()));
} catch (DomainException e) {
taskLog("Processed SCP " + studentCurricularPlan.getExternalId() + " for student " + number);
taskLog("Error processing: " + number + e.getMessage());
}
final List<Enrolment> enrolments = studentCurricularPlan.getEnrolmentsByExecutionPeriod(executionSemester);
setValidStateOnAllEnrolmentsIfAnyPerformedByAcademicAdminOffice(enrolments);
final Map<EnrollmentCondition, List<Enrolment>> enrolmentConditions = groupByEnrolmentCondition(enrolments);
printLogEnrolmentsInformation(enrolmentConditions);
reportInformation(studentCurricularPlan, enrolmentConditions, executionSemester, result, spreadsheet);
});
}
private void setValidStateOnAllEnrolmentsIfAnyPerformedByAcademicAdminOffice(final List<Enrolment> enrolments) {
if (hasAnyImpossibleEnrolment(enrolments)) {
taskLog("Found impossible enrolments create by admin office, changing all to validated");
for (final Enrolment enrolment : enrolments) {
if (enrolment.isImpossible()) {
enrolment.setEnrolmentCondition(EnrollmentCondition.VALIDATED);
}
}
}
}
private boolean hasAnyImpossibleEnrolment(final List<Enrolment> enrolments) {
for (final Enrolment enrolment : enrolments) {
if (enrolment.isImpossible()) {
final Person person = Person.readPersonByUsername(enrolment.getCreatedBy());
if (RoleType.ACADEMIC_ADMINISTRATIVE_OFFICE.isMember(person.getUser())
|| RoleType.INTERNATIONAL_RELATION_OFFICE.isMember(person.getUser())
|| AcademicAuthorizationGroup.get(AcademicOperationType.ENROLMENT_WITHOUT_RULES).isMember(
person.getUser())) {
return true;
}
}
}
return false;
}
private Map<EnrollmentCondition, List<Enrolment>> groupByEnrolmentCondition(final List<Enrolment> enrolments) {
final Map<EnrollmentCondition, List<Enrolment>> enrolmentConditions = new HashMap<EnrollmentCondition, List<Enrolment>>();
for (final Enrolment enrolment : enrolments) {
addToMap(enrolmentConditions, enrolment);
}
return enrolmentConditions;
}
private void addToMap(final Map<EnrollmentCondition, List<Enrolment>> enrolmentConditions, final Enrolment enrolment) {
List<Enrolment> enrolments = enrolmentConditions.get(enrolment.getEnrolmentCondition());
if (enrolments == null) {
enrolmentConditions.put(enrolment.getEnrolmentCondition(), enrolments = new ArrayList<Enrolment>());
}
enrolments.add(enrolment);
}
private void printLogEnrolmentsInformation(final Map<EnrollmentCondition, List<Enrolment>> enrolmentConditions) {
for (final Entry<EnrollmentCondition, List<Enrolment>> entry : enrolmentConditions.entrySet()) {
if (entry.getKey() == EnrollmentCondition.IMPOSSIBLE) {
taskLog("\t [ " + entry.getKey() + " ]");
for (final Enrolment enrolment : entry.getValue()) {
taskLog("\t\t -> " + enrolment.getName().getContent());
}
}
}
}
private String printErrors(final RuleResult... falseRuleResults) {
final StringBuilder builder = new StringBuilder();
for (final RuleResult ruleResult : falseRuleResults) {
for (final RuleResultMessage message : ruleResult.getMessages()) {
if (message.isToTranslate()) {
builder.append(getTranslatedMessage(message));
} else {
builder.append(message.getMessage());
}
builder.append(",");
}
}
if (builder.length() > 0) {
builder.deleteCharAt(builder.length() - 1);
}
return builder.toString();
}
private void reportInformation(StudentCurricularPlan scp, Map<EnrollmentCondition, List<Enrolment>> enrolmentConditions,
ExecutionSemester executionSemester, RuleResult result, Spreadsheet spreadsheet) {
if (enrolmentConditions.isEmpty()) {
return;
}
final Row row = spreadsheet.addRow();
row.setCell(scp.getDegreeCurricularPlan().getName());
row.setCell(scp.getRegistration().getStudent().getNumber());
row.setCell(scp.getName());
String enrolmentsMadeByOffice = StringUtils.EMPTY;
if (result != null) {
enrolmentsMadeByOffice = getOfficeUsers(scp.getRegistration(), executionSemester);
}
row.setCell(enrolmentsMadeByOffice);
row.setCell(buildCurricularCoursesNames(enrolmentConditions));
if (result != null) {
row.setCell(printErrors(result));
}
}
private String getOfficeUsers(Registration registration, ExecutionSemester executionSemester) {
StringBuilder sb = new StringBuilder();
for (CurriculumLineLog curriculumLineLog : registration.getCurriculumLineLogs(executionSemester)) {
if (curriculumLineLog.getWho() != null && !curriculumLineLog.getWho().equals(registration.getPerson().getUsername())) {
sb.append(curriculumLineLog.getWho()).append(",");
}
}
return sb.toString();
}
private String buildCurricularCoursesNames(Map<EnrollmentCondition, List<Enrolment>> enrolmentConditions) {
if (!enrolmentConditions.containsKey(EnrollmentCondition.IMPOSSIBLE)) {
return "";
}
final StringBuilder builder = new StringBuilder();
for (final Enrolment enrolment : enrolmentConditions.get(EnrollmentCondition.IMPOSSIBLE)) {
builder.append(enrolment.getName()).append(",");
}
if (builder.length() > 0) {
builder.deleteCharAt(builder.length() - 1);
}
return builder.toString();
}
private String getTranslatedMessage(final RuleResultMessage message) {
String result = APPLICATION_RESOURCES.getString(message.getMessage());
if (message.getArgs() != null) {
int i = 0;
while (i < message.getArgs().length) {
final Pattern pattern = Pattern.compile("(\\{" + i + "\\})");
final Matcher m = pattern.matcher(result);
result = m.replaceAll(message.getArgs()[i]);
i++;
}
}
return result;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment