package net.sourceforge.fenixedu.presentationTier.docs.academicAdministrativeOffice; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.ResourceBundle; import java.util.Map.Entry; import net.sourceforge.fenixedu._development.PropertiesManager; import net.sourceforge.fenixedu.domain.DomainReference; import net.sourceforge.fenixedu.domain.Employee; import net.sourceforge.fenixedu.domain.ExecutionYear; import net.sourceforge.fenixedu.domain.OptionalEnrolment; import net.sourceforge.fenixedu.domain.Person; import net.sourceforge.fenixedu.domain.RootDomainObject; import net.sourceforge.fenixedu.domain.accounting.PostingRule; import net.sourceforge.fenixedu.domain.accounting.postingRules.serviceRequests.CertificateRequestPR; import net.sourceforge.fenixedu.domain.accounting.serviceAgreementTemplates.AdministrativeOfficeServiceAgreementTemplate; import net.sourceforge.fenixedu.domain.degree.DegreeType; import net.sourceforge.fenixedu.domain.degreeStructure.CycleType; import net.sourceforge.fenixedu.domain.organizationalStructure.Unit; import net.sourceforge.fenixedu.domain.organizationalStructure.UniversityUnit; import net.sourceforge.fenixedu.domain.serviceRequests.AcademicServiceRequestSituationType; import net.sourceforge.fenixedu.domain.serviceRequests.documentRequests.CertificateRequest; import net.sourceforge.fenixedu.domain.serviceRequests.documentRequests.CourseLoadRequest; import net.sourceforge.fenixedu.domain.serviceRequests.documentRequests.DocumentRequest; import net.sourceforge.fenixedu.domain.serviceRequests.documentRequests.ExternalCourseLoadRequest; import net.sourceforge.fenixedu.domain.serviceRequests.documentRequests.ExternalProgramCertificateRequest; import net.sourceforge.fenixedu.domain.serviceRequests.documentRequests.ExtraCurricularCertificateRequest; import net.sourceforge.fenixedu.domain.serviceRequests.documentRequests.ProgramCertificateRequest; import net.sourceforge.fenixedu.domain.serviceRequests.documentRequests.StandaloneEnrolmentCertificateRequest; import net.sourceforge.fenixedu.domain.student.MobilityProgram; import net.sourceforge.fenixedu.domain.student.Registration; import net.sourceforge.fenixedu.domain.student.curriculum.ICurriculum; import net.sourceforge.fenixedu.domain.student.curriculum.ICurriculumEntry; import net.sourceforge.fenixedu.domain.studentCurriculum.ExternalEnrolment; import net.sourceforge.fenixedu.injectionCode.AccessControl; import net.sourceforge.fenixedu.presentationTier.docs.FenixReport; import net.sourceforge.fenixedu.util.HtmlToTextConverterUtil; import net.sourceforge.fenixedu.util.Money; import net.sourceforge.fenixedu.util.StringFormatter; import net.sourceforge.fenixedu.util.StringUtils; import org.joda.time.DateTime; import org.joda.time.LocalDate; import pt.utl.ist.fenix.tools.util.i18n.MultiLanguageString; import com.linkare.commons.metainfo.Linkare; import com.linkare.commons.utils.EqualityUtils; public class AdministrativeOfficeDocument extends FenixReport { private static final boolean IS_DIPLOMA_SUPPLEMENT_ENABLED = PropertiesManager .getBooleanProperty("diploma.supplement.enabled"); static final protected int LINE_LENGTH = 64; static final protected int SUFFIX_LENGTH = 12; static final protected String[] identifiers = { "*", "#", "+", "**", "***" }; static final protected String LINE_BREAK = "\n"; static final protected char END_CHAR = '-'; protected DomainReference documentRequestDomainReference; public static class AdministrativeOfficeDocumentCreator { public static List create(final DocumentRequest documentRequest) { switch (documentRequest.getDocumentRequestType()) { case ENROLMENT_CERTIFICATE: return Collections.singletonList(new EnrolmentCertificate(documentRequest)); case APPROVEMENT_CERTIFICATE: return Collections.singletonList(new ApprovementCertificate(documentRequest)); case DEGREE_FINALIZATION_CERTIFICATE: return Collections.singletonList(new DegreeFinalizationCertificate(documentRequest)); case SCHOOL_REGISTRATION_DECLARATION: return Collections.singletonList(new RegistrationDeclaration(documentRequest)); case ENROLMENT_DECLARATION: return Collections.singletonList(new EnrolmentDeclaration(documentRequest)); case IRS_DECLARATION: return Collections.singletonList(new IRSDeclaration(documentRequest)); case DIPLOMA_REQUEST: final Diploma diploma = new Diploma(documentRequest); if (IS_DIPLOMA_SUPPLEMENT_ENABLED) { final List result = new ArrayList(); result.add(diploma); for (final Locale locale : DiplomaSupplement.suportedLocales) { result.add(new DiplomaSupplement(documentRequest, locale)); } return result; } else { return Collections.singletonList(diploma); } case EXAM_DATE_CERTIFICATE: return Collections.singletonList(new ExamDateCertificate(documentRequest)); case COURSE_LOAD: return Collections.singletonList(new CourseLoadRequestDocument((CourseLoadRequest) documentRequest)); case EXTERNAL_COURSE_LOAD: return Collections.singletonList(new ExternalCourseLoadRequestDocument( (ExternalCourseLoadRequest) documentRequest)); case PROGRAM_CERTIFICATE: return Collections.singletonList(new ProgramCertificateRequestDocument( (ProgramCertificateRequest) documentRequest)); case EXTERNAL_PROGRAM_CERTIFICATE: return Collections.singletonList(new ExternalProgramCertificateRequestDocument( (ExternalProgramCertificateRequest) documentRequest)); case EXTRA_CURRICULAR_CERTIFICATE: return Collections.singletonList(new ExtraCurricularCertificateRequestDocument( (ExtraCurricularCertificateRequest) documentRequest)); case STANDALONE_ENROLMENT_CERTIFICATE: return Collections.singletonList(new StandaloneEnrolmentCertificateRequestDocument( (StandaloneEnrolmentCertificateRequest) documentRequest)); default: return Collections.singletonList(new AdministrativeOfficeDocument(documentRequest)); } } } protected AdministrativeOfficeDocument(final DocumentRequest documentRequest) { this(documentRequest, new Locale(documentRequest.getLanguage().name())); } public AdministrativeOfficeDocument(final DocumentRequest documentRequest, final Locale locale) { super(locale); setResourceBundle(ResourceBundle.getBundle("resources.AcademicAdminOffice", locale)); this.documentRequestDomainReference = new DomainReference(documentRequest); fillReport(); } protected DocumentRequest getDocumentRequest() { return documentRequestDomainReference.getObject(); } @Override public String getReportTemplateKey() { return getDocumentRequest().getDocumentTemplateKey(); } @Override public String getReportFileName() { final StringBuilder result = new StringBuilder(); result.append(getRegistration().getPerson().getIstUsername()); result.append("-"); result.append(new DateTime().toString(YYYYMMMDD, getLocale())); result.append("-"); result.append(getDocumentRequest().getDescription().replace(":", EMPTY_STR).replace(SINGLE_SPACE, EMPTY_STR)); result.append("-"); result.append(getLanguage().toString()); return result.toString(); } protected Registration getRegistration() { return getDocumentRequest().getRegistration(); } @Override protected void fillReport() { addParameter("bundle", getResourceBundle()); addParameter("documentRequest", getDocumentRequest()); addParameter("registration", getRegistration()); if (showPriceFields()) { addPriceFields(); } addIntroParameters(AccessControl.getPerson().getEmployee()); setPersonFields(); if (getDocumentRequest().hasExecutionYear()) { String situation = getExecutionYear().containsDate(new DateTime()) ? "label.is" : "label.was"; addParameter("situation", getResourceBundle().getString(situation)); } addParameter("degreeDescription", getDegreeDescription()); addParameter("employeeLocation", AccessControl.getPerson().getEmployee().getCurrentCampus().getLocation()); addParameter("day", new LocalDate().toString(DD_MM_YYYY, getLocale())); } protected boolean showPriceFields() { return getDocumentRequest().isCertificate(); } protected void addPriceFields() { final CertificateRequest certificateRequest = (CertificateRequest) getDocumentRequest(); final CertificateRequestPR certificateRequestPR = (CertificateRequestPR) getPostingRule(); final Money amountPerPage = certificateRequestPR.getAmountPerPage(); final Money baseAmountPlusAmountForUnits = certificateRequestPR.getBaseAmount().add( certificateRequestPR.getAmountPerUnit().multiply(BigDecimal.valueOf(certificateRequest.getNumberOfUnits()))); final Money urgencyAmount = certificateRequest.getUrgentRequest() ? certificateRequestPR.getBaseAmount() : Money.ZERO; addParameter("amountPerPage", amountPerPage); addParameter("baseAmountPlusAmountForUnits", baseAmountPlusAmountForUnits); addParameter("urgencyAmount", urgencyAmount); addParameter("printPriceFields", printPriceParameters(certificateRequest)); } final protected PostingRule getPostingRule() { final AdministrativeOfficeServiceAgreementTemplate serviceAgreementTemplate = getDocumentRequest() .getAdministrativeOffice().getServiceAgreementTemplate(); return serviceAgreementTemplate.findPostingRuleByEventType(getDocumentRequest().getEventType()); } final protected boolean printPriceParameters(final CertificateRequest certificateRequest) { return (certificateRequest.getAcademicServiceRequestSituationType() == AcademicServiceRequestSituationType.PROCESSING && !certificateRequest .isFree()) || certificateRequest.hasEvent(); } final protected void addIntroParameters(final Employee employee) { addParameter("administrativeOfficeCoordinator", employee.getCurrentWorkingPlace().getActiveUnitCoordinator()); addParameter("administrativeOfficeName", getMLSTextContent(employee.getCurrentWorkingPlace().getPartyName())); addParameter("institutionName", getMLSTextContent(RootDomainObject.getInstance().getInstitutionUnit().getPartyName())); addParameter("universityName", getMLSTextContent(UniversityUnit.getInstitutionsUniversityUnit().getPartyName())); } protected void setPersonFields() { final Person person = getRegistration().getPerson(); addParameter("name", StringUtils.multipleLineRightPad(person.getName().toUpperCase(), LINE_LENGTH, END_CHAR)); StringBuilder builder = new StringBuilder(); builder.append(getResourceBundle().getString("label.with")); builder.append(SINGLE_SPACE).append(person.getIdDocumentType().getLocalizedName(getLocale())); builder.append(SINGLE_SPACE).append(getResourceBundle().getString("label.number.short")); builder.append(SINGLE_SPACE).append(person.getDocumentIdNumber()); addParameter("documentIdNumber", StringUtils.multipleLineRightPad(builder.toString(), LINE_LENGTH, END_CHAR)); builder = new StringBuilder(); builder.append(getResourceBundle().getString("documents.birthLocale")); builder.append(SINGLE_SPACE).append(getBirthLocale(person, false)); addParameter("birthLocale", StringUtils.multipleLineRightPad(builder.toString(), LINE_LENGTH, END_CHAR)); builder = new StringBuilder(); builder.append(getResourceBundle().getString("documents.nationality.one")); final String nationality = person.getCountry().getFilteredNationality(getLocale()); builder.append(SINGLE_SPACE).append(nationality.toUpperCase()).append(SINGLE_SPACE); addParameter("nationality", StringUtils.multipleLineRightPad(builder.toString(), LINE_LENGTH, END_CHAR)); } @Linkare(author = "Paulo Zenida", comments = "Changed the simple not equals logic in the end of the method to use the NullPointerException safe equality check.") protected String getBirthLocale(final Person person, final boolean prettyPrint) { final StringBuilder result = new StringBuilder(); final String parishOfBirth = prettyPrint ? StringFormatter.prettyPrint(person.getParishOfBirth()) : person .getParishOfBirth(); final String districtSubdivision = prettyPrint ? StringFormatter.prettyPrint(person.getDistrictSubdivisionOfBirth()) : person.getDistrictSubdivisionOfBirth(); result.append(parishOfBirth); if (!EqualityUtils.equals(parishOfBirth, districtSubdivision)) { result.append(",").append(SINGLE_SPACE).append(districtSubdivision); } return result.toString(); } @Linkare(author = "Paulo Zenida", comments = "Changed method to check if the degree has any cycle type and call the degreeDescription method with a degreeType instead if it doesn't have cycles.") protected String getDegreeDescription() { final Registration registration = getRegistration(); final DegreeType degreeType = registration.getDegreeType(); if (degreeType.hasAnyCycleTypes()) { final CycleType cycleType = degreeType.hasExactlyOneCycleType() ? degreeType.getCycleType() : registration .getCycleType(getExecutionYear()); return registration.getDegreeDescription(cycleType, getLocale()); } else { return registration.getDegreeDescription(degreeType, getLocale()); } } protected ExecutionYear getExecutionYear() { if (getDocumentRequest().hasExecutionYear()) { return getDocumentRequest().getExecutionYear(); } return ExecutionYear.readByDateTime(getDocumentRequest().getRequestDate()); } final protected String getCreditsDescription() { return getDocumentRequest().getDegreeType().getCreditsDescription(); } final protected String generateEndLine() { return StringUtils.rightPad(EMPTY_STR, LINE_LENGTH, END_CHAR); } final protected String getCurriculumEntryName(final Map academicUnitIdentifiers, final ICurriculumEntry entry) { final StringBuilder result = new StringBuilder(); if (entry instanceof ExternalEnrolment) { result.append(getAcademicUnitIdentifier(academicUnitIdentifiers, ((ExternalEnrolment) entry).getAcademicUnit())); } result.append(getPresentationNameFor(entry).toUpperCase()); return result.toString(); } protected String getPresentationNameFor(final ICurriculumEntry entry) { final MultiLanguageString result; if (entry instanceof OptionalEnrolment) { final OptionalEnrolment optionalEnrolment = (OptionalEnrolment) entry; result = optionalEnrolment.getCurricularCourse().getNameI18N(); } else { result = entry.getName(); } return getMLSTextContent(result); } protected String getMLSTextContent(final MultiLanguageString mls) { if (mls == null) { return EMPTY_STR; } final String content = mls.hasContent(getLanguage()) && !StringUtils.isEmpty(mls.getContent(getLanguage())) ? mls .getContent(getLanguage()) : mls.getContent(); return convert(content); } protected String convert(final String content) { return HtmlToTextConverterUtil.convertToText(content).replace("\n\n", "\t").replace(LINE_BREAK, EMPTY_STR).replace("\t", "\n\n").trim(); } @SuppressWarnings("static-access") final protected String getAcademicUnitIdentifier(final Map academicUnitIdentifiers, final Unit academicUnit) { if (!academicUnitIdentifiers.containsKey(academicUnit)) { academicUnitIdentifiers.put(academicUnit, this.identifiers[academicUnitIdentifiers.size()]); } return academicUnitIdentifiers.get(academicUnit); } final protected void getCreditsInfo(final StringBuilder result, final ICurriculumEntry entry) { result.append(entry.getEctsCreditsForCurriculum()).append(getCreditsDescription()).append(", "); } final protected String getRemainingCreditsInfo(final ICurriculum curriculum) { final BigDecimal remainingCredits = curriculum.getRemainingCredits(); final StringBuilder result = new StringBuilder(); if (remainingCredits != BigDecimal.ZERO) { result.append(LINE_BREAK); final String remainingCreditsInfo = getResourceBundle().getString("documents.remainingCreditsInfo"); result.append(StringUtils.multipleLineRightPadWithSuffix(remainingCreditsInfo + ":", LINE_LENGTH, END_CHAR, remainingCredits + getCreditsDescription())); result.append(LINE_BREAK); } return result.toString(); } final protected String getAcademicUnitInfo(final Map unitIDs, final MobilityProgram mobilityProgram) { final StringBuilder result = new StringBuilder(); for (final Entry academicUnitId : unitIDs.entrySet()) { final StringBuilder unit = new StringBuilder(); unit.append(academicUnitId.getValue()); unit.append(SINGLE_SPACE).append(getResourceBundle().getString("documents.external.curricular.courses.one")); unit.append(SINGLE_SPACE).append(getMLSTextContent(academicUnitId.getKey().getPartyName()).toUpperCase()); if (mobilityProgram != null) { unit.append(SINGLE_SPACE).append(getResourceBundle().getString("documents.external.curricular.courses.two")); unit.append(SINGLE_SPACE).append(mobilityProgram.getDescription(getLocale()).toUpperCase()); } result.append(StringUtils.multipleLineRightPad(unit.toString(), LINE_LENGTH, END_CHAR)); result.append(LINE_BREAK); } return result.toString(); } }