/**
* Copyright © ${project.inceptionYear} Instituto Superior Técnico
*
* This file is part of Fenix IST.
*
* Fenix IST 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.
*
* Fenix IST 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 Fenix IST. If not, see <http://www.gnu.org/licenses/>.
*/
package pt.ist.fenix.ui.struts.action.koha;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.fenixedu.academic.domain.Degree;
import org.fenixedu.academic.domain.DegreeCurricularPlan;
import org.fenixedu.academic.domain.Department;
import org.fenixedu.academic.domain.DomainObjectUtil;
import org.fenixedu.academic.domain.ExecutionYear;
import org.fenixedu.academic.domain.Person;
import org.fenixedu.academic.domain.StudentCurricularPlan;
import org.fenixedu.academic.domain.Teacher;
import org.fenixedu.academic.domain.accounting.events.insurance.InsuranceEvent;
import org.fenixedu.academic.domain.contacts.EmailAddress;
import org.fenixedu.academic.domain.contacts.MobilePhone;
import org.fenixedu.academic.domain.contacts.PartyContact;
import org.fenixedu.academic.domain.contacts.Phone;
import org.fenixedu.academic.domain.degree.DegreeType;
import org.fenixedu.academic.domain.organizationalStructure.DepartmentUnit;
import org.fenixedu.academic.domain.organizationalStructure.Unit;
import org.fenixedu.academic.domain.phd.PhdIndividualProgramProcess;
import org.fenixedu.academic.domain.phd.PhdIndividualProgramProcessState;
import org.fenixedu.academic.domain.student.Registration;
import org.fenixedu.academic.domain.student.Student;
import org.fenixedu.academic.domain.student.registrationStates.RegistrationState;
import org.fenixedu.bennu.core.domain.Bennu;
import org.fenixedu.bennu.core.domain.User;
import org.fenixedu.bennu.struts.annotations.Mapping;
import org.fenixedu.spaces.domain.Space;
import org.joda.time.DateTime;
import org.joda.time.YearMonthDay;
import pt.ist.fenix.FenixIstConfiguration;
import pt.ist.fenix.ui.struts.action.externalServices.ExternalInterfaceDispatchAction;
import pt.ist.fenixedu.contracts.domain.Employee;
import pt.ist.fenixedu.contracts.domain.research.Researcher;
import pt.utl.ist.fenix.tools.util.excel.Spreadsheet;
import pt.utl.ist.fenix.tools.util.excel.Spreadsheet.Row;
@Mapping(module = "external", path = "/exportUserInfoForKoha", scope = "request", parameter = "method")
public class ExportUserInfoForKoha extends ExternalInterfaceDispatchAction {
private boolean chackCredentials(final HttpServletRequest request) {
final String username = (String) getFromRequest(request, "username");
final String password = (String) getFromRequest(request, "password");
final String usernameProp = FenixIstConfiguration.getConfiguration().getExternalServicesKohaUsername();
final String passwordProp = FenixIstConfiguration.getConfiguration().getExternalServicesKohaPassword();
return !StringUtils.isEmpty(username) && !StringUtils.isEmpty(password) && !StringUtils.isEmpty(usernameProp)
&& !StringUtils.isEmpty(passwordProp) && username.equals(usernameProp) && password.equals(passwordProp);
}
@Override
public ActionForward execute(final ActionMapping mapping, final ActionForm actionForm, final HttpServletRequest request,
final HttpServletResponse response) throws Exception {
if (chackCredentials(request)) {
super.execute(mapping, actionForm, request, response);
} else {
response.sendError(404, "Not authorized");
}
return null;
}
private ActionForward sendXls(final HttpServletResponse response, final Spreadsheet spreadsheet) throws IOException {
final OutputStream stream = response.getOutputStream();
response.setContentType("application/vnd.ms-access");
response.setHeader("Content-disposition", "attachment; filename=list.xls");
spreadsheet.exportToXLSSheet(stream);
stream.close();
return null;
}
public ActionForward getDegreeTypes(final ActionMapping mapping, final ActionForm actionForm,
final HttpServletRequest request, final HttpServletResponse response) throws Exception {
final Spreadsheet spreadsheet = new Spreadsheet("DegreeTypes");
spreadsheet.setHeader("*ID").setHeader("descrição");
for (final DegreeType degreeType : DegreeType.values()) {
final Row row = spreadsheet.addRow();
row.setCell(degreeType.getName()).setCell(degreeType.getLocalizedName());
}
return sendXls(response, spreadsheet);
}
public ActionForward getDegrees(final ActionMapping mapping, final ActionForm actionForm, final HttpServletRequest request,
final HttpServletResponse response) throws Exception {
final Spreadsheet spreadsheet = new Spreadsheet("Degrees");
spreadsheet.setHeader("*ID").setHeader("descrição").setHeader("abreviatura").setHeader("*grau");
for (final Degree degree : rootDomainObject.getDegreesSet()) {
final Row row = spreadsheet.addRow();
row.setCell(degree.getExternalId()).setCell(degree.getPresentationName()).setCell(degree.getSigla())
.setCell(degree.getDegreeType().name());
}
return sendXls(response, spreadsheet);
}
public ActionForward getDepartments(final ActionMapping mapping, final ActionForm actionForm,
final HttpServletRequest request, final HttpServletResponse response) throws Exception {
final Spreadsheet spreadsheet = new Spreadsheet("Departments");
spreadsheet.setHeader("*ID").setHeader("descrição");
for (final Department department : rootDomainObject.getDepartmentsSet()) {
final Row row = spreadsheet.addRow();
row.setCell(department.getExternalId()).setCell(department.getName());
}
return sendXls(response, spreadsheet);
}
public ActionForward getTeachersAndResearchers(final ActionMapping mapping, final ActionForm actionForm,
final HttpServletRequest request, final HttpServletResponse response) throws Exception {
final Spreadsheet spreadsheet = new Spreadsheet("TeachersAndResearchers");
spreadsheet.setHeader("IST-ID").setHeader("*departamento").setHeader("nome").setHeader("email").setHeader("telefone")
.setHeader("cgdCode");
Set<Person> teachersAndResearchers = new HashSet<>();
for (Teacher teacher : Bennu.getInstance().getTeachersSet()) {
if (teacher.isActiveContractedTeacher()) {
teachersAndResearchers.add(teacher.getPerson());
}
}
for (Researcher researcher : Bennu.getInstance().getResearchersSet()) {
if (researcher.isActiveContractedResearcher()) {
teachersAndResearchers.add(researcher.getPerson());
}
}
teachersAndResearchers.forEach(p -> addEmployeeInformation(spreadsheet, p));
return sendXls(response, spreadsheet);
}
private void addEmployeeInformation(final Spreadsheet spreadsheet, final Person person) {
final Row row = spreadsheet.addRow();
row.setCell(person.getUsername()).setCell(getWorkingDepartment(person)).setCell(person.getName())
.setCell(getEmail(person)).setCell(getTelefone(person)).setCell(getCGDCode(person));
}
public ActionForward getStudents(final ActionMapping mapping, final ActionForm actionForm, final HttpServletRequest request,
final HttpServletResponse response) throws Exception {
final Spreadsheet spreadsheet = new Spreadsheet("Students");
spreadsheet.setHeader("IST-ID").setHeader("polo").setHeader("curso").setHeader("nome").setHeader("email")
.setHeader("telefone").setHeader("cgdCode");
final ExecutionYear executionYear = ExecutionYear.readCurrentExecutionYear();
final DateTime begin = executionYear.getBeginDateYearMonthDay().toDateTimeAtMidnight();
final DateTime end = executionYear.getEndDateYearMonthDay().toDateTimeAtMidnight();;
for (User user : Bennu.getInstance().getUserSet()) {
Person person = user.getPerson();
if (person != null && person.getStudent() != null) {
final Student student = person.getStudent();
final StudentCurricularPlan scp = findStudentCurricularPlan(student, begin, end);
if (scp != null) {
final Row row = spreadsheet.addRow();
row.setCell(person.getUsername()).setCell(getCampus(scp.getCampus(executionYear)));
row.setCell(scp.getDegree().getExternalId()).setCell(person.getName());
row.setCell(getEmail(person)).setCell(getTelefone(person)).setCell(getCGDCode(person));
} else {
final PhdIndividualProgramProcess phd = findPhd(person);
if (phd != null) {
final Row row = spreadsheet.addRow();
row.setCell(person.getUsername()).setCell(getCampus(phd));
row.setCell(getDegree(phd).getExternalId()).setCell(person.getName());
row.setCell(getEmail(person)).setCell(getTelefone(person)).setCell(getCGDCode(person));
}
}
}
}
return sendXls(response, spreadsheet);
}
private Degree getDegree(final PhdIndividualProgramProcess phd) {
return phd.getPhdProgram().getDegree();
}
private String getCampus(final PhdIndividualProgramProcess phd) {
final DegreeCurricularPlan degreeCurricularPlan = phd.getPhdProgram().getDegree().getLastActiveDegreeCurricularPlan();
return getCampus(degreeCurricularPlan.getCurrentCampus());
}
private String getCampus(final Space campus) {
return campus == null ? " " : campus.getName();
}
private StudentCurricularPlan findStudentCurricularPlan(final Student student, final DateTime begin, final DateTime end) {
final Set<StudentCurricularPlan> studentCurricularPlans = getStudentCurricularPlans(begin, end, student);
if (studentCurricularPlans.size() == 1) {
return studentCurricularPlans.iterator().next();
} else if (studentCurricularPlans.size() > 1) {
return findMaxStudentCurricularPlan(studentCurricularPlans);
}
return null;
}
public static Set<StudentCurricularPlan> getStudentCurricularPlans(final DateTime begin, final DateTime end,
final Student student) {
final Set<StudentCurricularPlan> studentCurricularPlans = new HashSet<StudentCurricularPlan>();
for (final Registration registration : student.getRegistrationsSet()) {
if (!registration.isActive()) {
continue;
}
final DegreeType degreeType = registration.getDegreeType();
if (!degreeType.isBolonhaType()) {
continue;
}
for (final StudentCurricularPlan studentCurricularPlan : registration.getStudentCurricularPlansSet()) {
if (studentCurricularPlan.isActive()) {
if (degreeType == DegreeType.BOLONHA_DEGREE || degreeType == DegreeType.BOLONHA_MASTER_DEGREE
|| degreeType == DegreeType.BOLONHA_INTEGRATED_MASTER_DEGREE
|| degreeType == DegreeType.BOLONHA_ADVANCED_SPECIALIZATION_DIPLOMA) {
studentCurricularPlans.add(studentCurricularPlan);
} else {
final RegistrationState registrationState = registration.getActiveState();
if (registrationState != null) {
final DateTime dateTime = registrationState.getStateDate();
if (!dateTime.isBefore(begin) && !dateTime.isAfter(end)) {
studentCurricularPlans.add(studentCurricularPlan);
}
}
}
}
}
}
return studentCurricularPlans;
}
private static StudentCurricularPlan findMaxStudentCurricularPlan(final Set<StudentCurricularPlan> studentCurricularPlans) {
return Collections.max(studentCurricularPlans, new Comparator<StudentCurricularPlan>() {
@Override
public int compare(final StudentCurricularPlan o1, final StudentCurricularPlan o2) {
final DegreeType degreeType1 = o1.getDegreeType();
final DegreeType degreeType2 = o2.getDegreeType();
if (degreeType1 == degreeType2) {
final YearMonthDay yearMonthDay1 = o1.getStartDateYearMonthDay();
final YearMonthDay yearMonthDay2 = o2.getStartDateYearMonthDay();
final int c = yearMonthDay1.compareTo(yearMonthDay2);
return c == 0 ? DomainObjectUtil.COMPARATOR_BY_ID.compare(o1, o2) : c;
} else {
return degreeType1.compareTo(degreeType2);
}
}
});
}
private PhdIndividualProgramProcess findPhd(final Person person) {
final InsuranceEvent event = person.getInsuranceEventFor(ExecutionYear.readCurrentExecutionYear());
return event != null && event.isClosed() ? findPhd(person.getPhdIndividualProgramProcessesSet()) : null;
}
private PhdIndividualProgramProcess findPhd(final Collection<PhdIndividualProgramProcess> phdIndividualProgramProcesses) {
PhdIndividualProgramProcess result = null;
for (final PhdIndividualProgramProcess process : phdIndividualProgramProcesses) {
if (process.getActiveState() == PhdIndividualProgramProcessState.WORK_DEVELOPMENT) {
if (result != null) {
return null;
}
result = process;
}
}
return result;
}
private String getWorkingDepartment(final Person person) {
if (person.getEmployee() != null) {
final Employee employee = person.getEmployee();
final Unit unit = employee.getCurrentWorkingPlace();
if (unit != null) {
final DepartmentUnit departmentUnit = unit.getDepartmentUnit();
if (departmentUnit != null) {
return departmentUnit.getDepartment().getExternalId();
}
}
}
return " ";
}
public String getEmail(final Person person) {
final EmailAddress email = person.getEmailAddressForSendingEmails();
return email != null ? email.getValue() : " ";
}
private String getTelefone(final Person person) {
final StringBuilder builder = new StringBuilder();
for (final PartyContact partyContact : person.getPartyContactsSet()) {
if (partyContact.isActiveAndValid()) {
if (partyContact.isPhone()) {
final Phone phone = (Phone) partyContact;
if (builder.length() > 0) {
builder.append(", ");
}
builder.append(phone.getNumber());
} else if (partyContact.isMobile()) {
final MobilePhone mobilePhone = (MobilePhone) partyContact;
if (builder.length() > 0) {
builder.append(", ");
}
builder.append(mobilePhone.getNumber());
}
}
}
return builder.toString();
}
private String getCGDCode(final Person person) {
return "";
// CardGenerationEntry result = null;
// for (final CardGenerationEntry entry : person.getCardGenerationEntriesSet()) {
// final CardGenerationBatch batch = entry.getCardGenerationBatch();
// if (batch.getSent() != null && batch.getCardGenerationProblemsSet().size() == 0) {
// if (result == null || result.getCardGenerationBatch().getSent().isBefore(batch.getSent())) {
// result = entry;
// }
// }
// }
// return result == null ? " " : result.getCgdIdentifier();
}
}