/* * @(#)EmailDigesterUtil.java * * Copyright 2010 Instituto Superior Tecnico * Founding Authors: Luis Cruz, Nuno Ochoa, Paulo Abrantes * * https://fenix-ashes.ist.utl.pt/ * * This file is part of the Expenditure Tracking Module. * * The Expenditure Tracking Module 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. * * The Expenditure Tracking Module 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 the Expenditure Tracking Module. If not, see <http://www.gnu.org/licenses/>. * */ package module.mission.domain; import java.util.Collection; import java.util.Date; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; 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.core.security.Authenticate; import org.fenixedu.bennu.core.util.CoreConfiguration; import org.fenixedu.commons.i18n.I18N; import org.fenixedu.messaging.core.domain.Message; import org.fenixedu.messaging.core.template.DeclareMessageTemplate; import org.fenixedu.messaging.core.template.TemplateParameter; import org.jfree.data.time.Month; import org.joda.time.LocalDate; import module.organization.domain.Party; import pt.ist.expenditureTrackingSystem._development.Bundle; import pt.ist.expenditureTrackingSystem.domain.ExpenditureTrackingSystem; import pt.ist.expenditureTrackingSystem.domain.RoleType; import pt.ist.expenditureTrackingSystem.domain.authorizations.Authorization; import pt.ist.expenditureTrackingSystem.domain.organization.AccountingUnit; import pt.ist.expenditureTrackingSystem.domain.organization.Person; /** * * @author Luis Cruz * */ @DeclareMessageTemplate(id = "expenditures.mission.pending", bundle = Bundle.MISSION, description = "template.mission.pending", subject = "template.mission.pending.subject", text = "template.mission.pending.text", parameters = { @TemplateParameter(id = "applicationTitle", description = "template.parameter.application.subtitle"), @TemplateParameter(id = "applicationUrl", description = "template.parameter.application.url"), @TemplateParameter(id = "processesByType", description = "template.parameter.mission.processes.by.type"), @TemplateParameter(id = "processesTotal", description = "template.parameter.mission.processes.total") }) public class EmailDigesterUtil { public static final String TAKEN = "taken", PENDING_APPROVAL = "approval", PENDING_VEHICLE = "vehicle", PENDING_AUTHORIZATION = "authorization", PENDING_FUND = "fund", PENDING_PROCESSING = "processing"; public static class MissionProcessBean implements Comparable<MissionProcessBean> { private String id; private String destination; private Date departure, arrival; public String getId() { return id; } public String getDestination() { return destination; } public Date getDeparture() { return departure; } public Date getArrival() { return arrival; } public MissionProcessBean(MissionProcess process) { this.id = process.getProcessNumber(); Mission mission = process.getMission(); this.destination = mission.getDestinationDescription(); this.departure = mission.getDaparture().toDate(); this.arrival = mission.getArrival().toDate(); } @Override public int compareTo(MissionProcessBean b) { return id.compareTo(b.getId()); } } private static List<MissionProcessBean> getMissionProcessBeans(Set<MissionProcess> processes) { return processes.stream().map(p -> new MissionProcessBean(p)).sorted().collect(Collectors.toList()); } public static void executeTask() { I18N.setLocale(new Locale(CoreConfiguration.getConfiguration().defaultLocale())); for (Person person : getPeopleToProcess()) { final User user = person.getUser(); if (user.getPerson() != null && user.getExpenditurePerson() != null) { Authenticate.mock(user); try { final MissionYear missionYear = MissionYear.getCurrentYear(); final LocalDate today = new LocalDate(); final MissionYear previousYear = today.getMonthOfYear() == Month.JANUARY ? MissionYear.findOrCreateMissionYear(today.getYear() - 1) : null; Map<String, List<MissionProcessBean>> processesTypeMap = new LinkedHashMap<>(); processesTypeMap.put(TAKEN, getMissionProcessBeans(getTaken(missionYear, previousYear).collect(Collectors.toSet()))); if (previousYear == null) { processesTypeMap.put(PENDING_APPROVAL, getMissionProcessBeans(missionYear.getPendingAproval())); processesTypeMap.put(PENDING_VEHICLE, getMissionProcessBeans(missionYear.getPendingVehicleAuthorization())); processesTypeMap .put(PENDING_AUTHORIZATION, getMissionProcessBeans(missionYear.getPendingAuthorization())); processesTypeMap.put(PENDING_FUND, getMissionProcessBeans(missionYear.getPendingFundAllocation())); processesTypeMap.put(PENDING_PROCESSING, getMissionProcessBeans(missionYear.getPendingProcessingPersonelInformation())); } else { processesTypeMap.put(PENDING_APPROVAL, getMissionProcessBeans(previousYear.getPendingAproval(missionYear.getPendingAproval()))); processesTypeMap.put(PENDING_VEHICLE, getMissionProcessBeans(previousYear .getPendingVehicleAuthorization(missionYear.getPendingVehicleAuthorization()))); processesTypeMap.put(PENDING_AUTHORIZATION, getMissionProcessBeans(previousYear .getPendingAuthorization(missionYear.getPendingAuthorization()))); processesTypeMap.put(PENDING_FUND, getMissionProcessBeans(previousYear .getPendingFundAllocation(missionYear.getPendingFundAllocation()))); processesTypeMap.put(PENDING_PROCESSING, getMissionProcessBeans(previousYear .getPendingProcessingPersonelInformation(missionYear.getPendingProcessingPersonelInformation()))); } final int totalPending = processesTypeMap.values().stream().map(Collection::size).reduce(0, Integer::sum); if (totalPending > 0) { Message.fromSystem().to(Group.users(person.getUser())).template("expenditures.mission.pending") .parameter("applicationTitle", Bennu.getInstance().getConfiguration().getApplicationSubTitle()) .parameter("applicationUrl", CoreConfiguration.getConfiguration().applicationUrl()) .parameter("processesByType", processesTypeMap).parameter("processesTotal", totalPending).and() .send(); } } finally { Authenticate.unmock(); } } } } private static Stream<MissionProcess> getTaken(final MissionYear missionYear, final MissionYear previousYear) { return previousYear == null ? missionYear.getTakenStream() : Stream.concat(missionYear.getTakenStream(), previousYear.getTakenStream()); } private static Collection<Person> getPeopleToProcess() { final Set<Person> people = new HashSet<Person>(); final LocalDate today = new LocalDate(); final ExpenditureTrackingSystem expendituresSystem = ExpenditureTrackingSystem.getInstance(); for (User user : MissionSystem.getInstance().getVehicleAuthorizersSet()) { people.add(user.getExpenditurePerson()); } for (final Authorization authorization : expendituresSystem.getAuthorizationsSet()) { if (authorization.isValidFor(today)) { final Person person = authorization.getPerson(); if (person.getOptions().getReceiveNotificationsByEmail()) { people.add(person); } } } for (final RoleType roleType : RoleType.values()) { addPeopleWithRole(people, roleType); } for (final AccountingUnit accountingUnit : expendituresSystem.getAccountingUnitsSet()) { addPeople(people, accountingUnit.getPeopleSet()); addPeople(people, accountingUnit.getProjectAccountantsSet()); addPeople(people, accountingUnit.getResponsiblePeopleSet()); addPeople(people, accountingUnit.getResponsibleProjectAccountantsSet()); addPeople(people, accountingUnit.getTreasuryMembersSet()); } final MissionYear missionYear = MissionYear.getCurrentYear(); addRequestorsAndResponsibles(people, missionYear); if (today.getMonthOfYear() == Month.JANUARY) { final MissionYear previousYear = MissionYear.findOrCreateMissionYear(today.getYear() - 1); addRequestorsAndResponsibles(people, previousYear); } return people; } private static void addRequestorsAndResponsibles(final Set<Person> people, final MissionYear missionYear) { for (final MissionProcess missionProcess : missionYear.getMissionProcessSet()) { final Mission mission = missionProcess.getMission(); final module.organization.domain.Person requestingPerson = mission.getRequestingPerson(); if (requestingPerson != null && requestingPerson.getUser().getExpenditurePerson() != null) { people.add(requestingPerson.getUser().getExpenditurePerson()); } final Party missionResponsible = mission.getMissionResponsible(); if (missionResponsible != null && missionResponsible.isPerson()) { final module.organization.domain.Person missionPerson = (module.organization.domain.Person) missionResponsible; if (missionPerson.getUser() != null) { final User user = missionPerson.getUser(); if (user != null && user.getExpenditurePerson() != null) { final Person person = user.getExpenditurePerson(); if (person.getOptions().getReceiveNotificationsByEmail()) { people.add(person); } } } } } } private static void addPeopleWithRole(final Set<Person> people, final RoleType roleType) { addUsers(people, roleType.group().getMembers()); } private static void addPeople(final Set<Person> people, Collection<Person> unverified) { unverified.forEach(p -> addPerson(people, p)); } private static void addPerson(final Set<Person> people, final Person person) { if (person.getOptions().getReceiveNotificationsByEmail()) { people.add(person); } } private static void addUsers(final Set<Person> people, Stream<User> unverified) { unverified.forEach(u -> addPerson(people, u.getExpenditurePerson())); } }