diff --git a/fenixedu-ist-integration/src/main/dml/fenixedu-ist-integration.dml b/fenixedu-ist-integration/src/main/dml/fenixedu-ist-integration.dml index 8536fcba36c..6286922531b 100644 --- a/fenixedu-ist-integration/src/main/dml/fenixedu-ist-integration.dml +++ b/fenixedu-ist-integration/src/main/dml/fenixedu-ist-integration.dml @@ -338,3 +338,12 @@ relation RemoteSystemDomainRoot { .pt.ist.fenixframework.DomainRoot playsRole domainRoot; } +relation SpecialSeasonStatuteException { + .org.fenixedu.bennu.core.domain.Bennu playsRole bennu { + multiplicity 0..1; + } + .org.fenixedu.academic.domain.student.StatuteType playsRole specialSeasonStatuteException { + multiplicity *; + } +} + diff --git a/fenixedu-ist-integration/src/main/java/pt/ist/fenixedu/integration/task/updateData/payments/GenerateSpecialSeasonEnrolmentPaymentCodesAndEvents.java b/fenixedu-ist-integration/src/main/java/pt/ist/fenixedu/integration/task/updateData/payments/GenerateSpecialSeasonEnrolmentPaymentCodesAndEvents.java index d3dd1b1629a..5e95d5fcc6a 100644 --- a/fenixedu-ist-integration/src/main/java/pt/ist/fenixedu/integration/task/updateData/payments/GenerateSpecialSeasonEnrolmentPaymentCodesAndEvents.java +++ b/fenixedu-ist-integration/src/main/java/pt/ist/fenixedu/integration/task/updateData/payments/GenerateSpecialSeasonEnrolmentPaymentCodesAndEvents.java @@ -1,7 +1,12 @@ package pt.ist.fenixedu.integration.task.updateData.payments; +import java.util.Collection; +import java.util.Collections; +import java.util.Set; + import org.fenixedu.academic.domain.Degree; import org.fenixedu.academic.domain.EnrolmentEvaluation; +import org.fenixedu.academic.domain.ExecutionSemester; import org.fenixedu.academic.domain.ExecutionYear; import org.fenixedu.academic.domain.Person; import org.fenixedu.academic.domain.accounting.PaymentCodeType; @@ -9,26 +14,45 @@ import org.fenixedu.academic.domain.accounting.paymentCodes.AccountingEventPaymentCode; import org.fenixedu.academic.domain.administrativeOffice.AdministrativeOffice; import org.fenixedu.academic.domain.student.Registration; +import org.fenixedu.academic.domain.student.StatuteType; +import org.fenixedu.academic.domain.student.Student; import org.fenixedu.academic.util.EnrolmentEvaluationState; import org.fenixedu.academic.util.Money; +import org.fenixedu.bennu.core.domain.Bennu; import org.fenixedu.bennu.core.domain.User; import org.fenixedu.bennu.core.groups.Group; import org.fenixedu.bennu.scheduler.CronTask; import org.fenixedu.bennu.scheduler.annotation.Task; import org.fenixedu.messaging.core.domain.Message; +import org.fenixedu.messaging.core.template.DeclareMessageTemplate; +import org.fenixedu.messaging.core.template.TemplateParameter; import org.joda.time.YearMonthDay; -import java.util.Collections; +@DeclareMessageTemplate(id = "special.season.enrolment.payment.info.message.template", + description = "special.season.enrolment.payment.info.message.description", + subject = "special.season.enrolment.payment.info.message.subject", + text = "special.season.enrolment.payment.info.message.body", + parameters = { + @TemplateParameter(id = "eventDescriptionPT", + description = "special.season.enrolment.payment.info.message.parameter.event.description.pt"), + @TemplateParameter(id = "eventDescriptionEN", + description = "special.season.enrolment.payment.info.message.parameter.event.description.en"), + @TemplateParameter(id = "paymentEntityCode", description = "special.season.enrolment.payment.info.message.parameter.entity.code"), + @TemplateParameter(id = "paymentCode", description = "special.season.enrolment.payment.info.message.parameter.code"), + @TemplateParameter(id = "amount", description = "special.season.enrolment.payment.info.message.parameter.amount"), + }, + bundle = "resources.FenixeduIstIntegrationResources") @Task(englishTitle = "Create Events and Payment Codes for Special Season Enrolments", readOnly = false) public class GenerateSpecialSeasonEnrolmentPaymentCodesAndEvents extends CronTask { private static final Money AMOUNT_TO_PAY = new Money("20"); - private static final String EVENT_DESCRIPTION = "Inscrição em época especial à disciplina "; + private static final String EVENT_DESCRIPTION_PT = "Inscrição em época especial à disciplina "; + private static final String EVENT_DESCRIPTION_EN = "Special Season Enrolment Course "; + private static final Set EXCEPTION_STATUTE_TYPES = Bennu.getInstance().getSpecialSeasonStatuteExceptionSet(); @Override public void runTask() { - ExecutionYear.readCurrentExecutionYear().getExecutionPeriodsSet().stream() .flatMap(es -> es.getEnrolmentsSet().stream()) .flatMap(e -> e.getEvaluationsSet().stream()) @@ -47,6 +71,16 @@ private void createEvent(final EnrolmentEvaluation ee) { final Degree degree = registration.getDegree(); final AdministrativeOffice office = degree.getAdministrativeOffice(); final Person person = registration.getPerson(); + final Student student = person.getStudent(); + final Collection statuteTypes = + student.getStatutesTypesValidOnAnyExecutionSemesterFor(ee.getEnrolment().getExecutionYear()); + final User user = registration.getPerson().getUser(); + + if (statuteTypes.stream().anyMatch(st -> EXCEPTION_STATUTE_TYPES.contains(st))) { + taskLog("Skipped payment for student due to exception statute: %s%n", user.getUsername()); + return; + } + final SpecialSeasonEnrolmentEvent event = new SpecialSeasonEnrolmentEvent(office, person, Collections.singleton(ee)); final YearMonthDay today = new YearMonthDay(); @@ -54,47 +88,35 @@ private void createEvent(final EnrolmentEvaluation ee) { AccountingEventPaymentCode.create(PaymentCodeType.SPECIAL_SEASON_ENROLMENT, today, today.plusDays(10), event, AMOUNT_TO_PAY, AMOUNT_TO_PAY, event.getPerson()); - final User user = registration.getPerson().getUser(); - final String eventDescription = eventDescription(ee); - - taskLog("Generated payment codes for: %s -> %s%n", user.getUsername(), eventDescription); - - final String subject = "Pagamento Inscrição Época Especial - " + eventDescription; - final String body = - "A inscrição em exames de época especial ou extraordinário está sujeita ao " + - "pagamento de um emolumento de 20 Euros por unidade curricular. " + - "\n\n" + - "A sua inscrição só é finalizada após o pagamento do referido emolumento " + - "usando a referência multibanco junta. " + - "\n\n" + - "Há uma referência multibanco associada a cada unidade curricular a que " + - "pretende inscrever-se. " + - "\n\n" + - "Este pagamento deverá ser efectuado no prazo de 48h, sob pena " + - "de a inscrição deixar de ser válida. " + - "\n\n" + - "Pode efetuar o pagamento via multibanco com os seguintes dados a partir " + - "das 20:00 do dia de hoje (ou das 20:00 do dia seguinte se esta mensagem " + - "tiver sido enviada depois das 18h00): " + - "\n\n" + - "Entidade: " + paymentCode.getEntityCode() + "\n" + - "\n" + - "Referência: " + paymentCode.getCode() + "\n\n" + - "\n" + - "Valor: " + AMOUNT_TO_PAY.toString() + " €" + - "\n\n" - ; + final String eventDescriptionPT = eventDescriptionPT(ee); + final String eventDescriptionEN = eventDescriptionEN(ee); + + taskLog("Generated payment codes for: %s -> %s%n", user.getUsername(), eventDescriptionEN); + Message.fromSystem() - .replyToSender() - .to(Group.users(user)) - .subject(subject) - .textBody(body) - .send(); + .replyToSender() + .to(Group.users(user)) + .template("special.season.enrolment.payment.info.message.template") + .parameter("eventDescriptionPT", eventDescriptionPT) + .parameter("eventDescriptionEN", eventDescriptionEN) + .parameter("paymentEntityCode", paymentCode.getEntityCode()) + .parameter("paymentCode", paymentCode.getCode()) + .parameter("amount", AMOUNT_TO_PAY.toString()) + .and() + .send(); + } - private String eventDescription(final EnrolmentEvaluation ee) { - return EVENT_DESCRIPTION + ee.getEnrolment().getCurricularCourse().getName(ee.getExecutionPeriod()) + " - " + private String eventDescriptionPT(final EnrolmentEvaluation ee) { + return EVENT_DESCRIPTION_PT + ee.getEnrolment().getCurricularCourse().getName(ee.getExecutionPeriod()) + " - " + ee.getExecutionPeriod().getQualifiedName(); } -} \ No newline at end of file + private String eventDescriptionEN(final EnrolmentEvaluation ee) { + ExecutionSemester executionSemester = ee.getExecutionPeriod(); + String semester = executionSemester.getSemester() == 1 ? "1st" : "2nd" + " Semester "; + String year = executionSemester.getExecutionYear().getYear().toString(); + return EVENT_DESCRIPTION_EN + ee.getEnrolment().getCurricularCourse().getNameEn(ee.getExecutionPeriod()) + " - " + + semester + year; + } +} diff --git a/fenixedu-ist-integration/src/main/resources/resources/FenixeduIstIntegrationResources_en.properties b/fenixedu-ist-integration/src/main/resources/resources/FenixeduIstIntegrationResources_en.properties index a066756cd09..4023017efb4 100644 --- a/fenixedu-ist-integration/src/main/resources/resources/FenixeduIstIntegrationResources_en.properties +++ b/fenixedu-ist-integration/src/main/resources/resources/FenixeduIstIntegrationResources_en.properties @@ -72,5 +72,13 @@ message.academicAdministration.abandonState.observations=Automatically changed t message.academicAdministration.abandonState.warning=Attention: The student registration with no enrolments in the semesters {0} and {1} will be put on Abandon state. message.error.page.submitted.body=Thank you for contact, your message will be processed as soon as possible. For further questions, email us at: message.error.page.submitted=Your request has been logged +special.season.enrolment.payment.info.message.body = The enrollment in exams in special season is subject to the payment of a fee of 20 Euros per curricular unit.\n\nYour registration is only finalized after the payment of the referred fee using the ATM reference.\n\nThere is a ATM reference associated with each course you wish to enroll.\n\nThis payment must be made within 48 hours, otherwise the registration will no longer be valid.\n\nYou can pay via ATM with the following information from 8:00 PM today (or 8:00 PM the next day if this message was sent after 6:00 PM):\n\nEntity: {{paymentEntityCode}}\n\nReference: {{paymentCode}}\n\n\nValue: {{amount}} \u20AC +special.season.enrolment.payment.info.message.description = Message model to notify special season enrolment payment informations +special.season.enrolment.payment.info.message.parameter.event.description.pt = String that partially describes the message subject in portuguese +special.season.enrolment.payment.info.message.parameter.event.description.en = String that partially describes the message subject in english +special.season.enrolment.payment.info.message.parameter.entity.code = String that represents the payment entity transaction code +special.season.enrolment.payment.info.message.parameter.code = String that represents the transaction code +special.season.enrolment.payment.info.message.parameter.amount = String that represent the amount to pay (in euros) +special.season.enrolment.payment.info.message.subject = Special Season Enrolment Payment - {{ eventDescriptionEN }} title.student.merit.report = Student Merit Report -link.dges.importation.process.cancel.stand.by.candidacies.from.previous.years = Cancel Not Concluded Applications From Previous Years \ No newline at end of file +link.dges.importation.process.cancel.stand.by.candidacies.from.previous.years = Cancel Not Concluded Applications From Previous Years diff --git a/fenixedu-ist-integration/src/main/resources/resources/FenixeduIstIntegrationResources_pt.properties b/fenixedu-ist-integration/src/main/resources/resources/FenixeduIstIntegrationResources_pt.properties index 67fb35acb3c..ff1be339ee2 100644 --- a/fenixedu-ist-integration/src/main/resources/resources/FenixeduIstIntegrationResources_pt.properties +++ b/fenixedu-ist-integration/src/main/resources/resources/FenixeduIstIntegrationResources_pt.properties @@ -72,5 +72,13 @@ message.academicAdministration.abandonState.observations=Estado colocado automat message.academicAdministration.abandonState.warning=Atenção: As matrículas dos alunos sem inscrições nos semestres {0} e {1} vão passar ao estado de Abandono. message.error.page.submitted.body=Agradecemos o seu contacto, a sua mensagem será processada o mais brevemente possível. Para mais questões, envie-nos um email para: message.error.page.submitted=O seu pedido foi registado +special.season.enrolment.payment.info.message.body = A inscrição em exames de época especial ou extraordinário está sujeita ao pagamento de um emolumento de 20 Euros por unidade curricular.\n\nA sua inscrição só é finalizada após o pagamento do referido emolumento usando a referência multibanco junta.\n\nHá uma referência multibanco associada a cada unidade curricular a que pretende inscrever-se.\n\nEste pagamento deverá ser efectuado no prazo de 48h, sob pena de a inscrição deixar de ser válida.\n\nPode efetuar o pagamento via multibanco com os seguintes dados a partir das 20:00 do dia de hoje (ou das 20:00 do dia seguinte se esta mensagem tiver sido enviada depois das 18h00): \n\nEntidade: {{ paymentEntityCode }} \n\nReferência: {{ paymentCode }}\n\n\nValor: {{ amount }} \u20AC\n\n +special.season.enrolment.payment.info.message.description = Modelo de mensagem para notificar informações sobre o pagamento de inscrições em época especial +special.season.enrolment.payment.info.message.parameter.event.description.pt = String que descreve parcialmente o assunto da mensagem em portugu\u1EBDs +special.season.enrolment.payment.info.message.parameter.event.description.en = String que descreve parcialmente o assunto da mensagem em inglês +special.season.enrolment.payment.info.message.parameter.entity.code = String que representa o código da transação da entitade de pagamento +special.season.enrolment.payment.info.message.parameter.code = String que representa o codigo de transação +special.season.enrolment.payment.info.message.parameter.amount = String que representa a quantitade monetária (em euros) a pagar +special.season.enrolment.payment.info.message.subject = Pagamento Inscrição Época Especial - {{ eventDescriptionPT }} title.student.merit.report = Listagem de Médias dos Alunos -link.dges.importation.process.cancel.stand.by.candidacies.from.previous.years = Cancelar Candidaturas Não Concluídas de Anos Anteriores \ No newline at end of file +link.dges.importation.process.cancel.stand.by.candidacies.from.previous.years = Cancelar Candidaturas Não Concluídas de Anos Anteriores