fr.paris.lutece.plugins.genericalert.service.TaskNotifyReminder.java Source code

Java tutorial

Introduction

Here is the source code for fr.paris.lutece.plugins.genericalert.service.TaskNotifyReminder.java

Source

/*
 * Copyright (c) 2002-2014, Mairie de Paris
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice
 *     and the following disclaimer.
 *
 *  2. Redistributions in binary form must reproduce the above copyright notice
 *     and the following disclaimer in the documentation and/or other materials
 *     provided with the distribution.
 *
 *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
 *     contributors may be used to endorse or promote products derived from
 *     this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * License 1.0
 */
package fr.paris.lutece.plugins.genericalert.service;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;

import javax.inject.Inject;
import javax.inject.Named;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;

import fr.paris.lutece.plugins.appointment.business.Appointment;
import fr.paris.lutece.plugins.appointment.business.AppointmentForm;
import fr.paris.lutece.plugins.appointment.business.AppointmentFormHome;
import fr.paris.lutece.plugins.appointment.business.AppointmentHome;
import fr.paris.lutece.plugins.appointment.business.calendar.AppointmentSlot;
import fr.paris.lutece.plugins.appointment.business.calendar.AppointmentSlotHome;
import fr.paris.lutece.plugins.appointment.service.AppointmentPlugin;
import fr.paris.lutece.plugins.appointment.service.entrytype.EntryTypePhone;
import fr.paris.lutece.plugins.appointment.web.AppointmentApp;
import fr.paris.lutece.plugins.genericalert.business.ReminderAppointment;
import fr.paris.lutece.plugins.genericalert.business.TaskNotifyReminderConfig;
import fr.paris.lutece.plugins.genericalert.business.TaskNotifyReminderConfigHome;
import fr.paris.lutece.plugins.genericattributes.business.Entry;
import fr.paris.lutece.plugins.genericattributes.business.EntryFilter;
import fr.paris.lutece.plugins.genericattributes.business.EntryHome;
import fr.paris.lutece.plugins.genericattributes.business.Response;
import fr.paris.lutece.plugins.genericattributes.business.ResponseHome;
import fr.paris.lutece.plugins.genericattributes.service.entrytype.EntryTypeServiceManager;
import fr.paris.lutece.plugins.genericattributes.service.entrytype.IEntryTypeService;
import fr.paris.lutece.plugins.workflow.utils.WorkflowUtils;
import fr.paris.lutece.plugins.workflowcore.business.action.Action;
import fr.paris.lutece.plugins.workflowcore.business.resource.ResourceHistory;
import fr.paris.lutece.plugins.workflowcore.business.resource.ResourceWorkflow;
import fr.paris.lutece.plugins.workflowcore.business.state.State;
import fr.paris.lutece.plugins.workflowcore.service.action.IActionService;
import fr.paris.lutece.plugins.workflowcore.service.config.ITaskConfigService;
import fr.paris.lutece.plugins.workflowcore.service.resource.IResourceHistoryService;
import fr.paris.lutece.plugins.workflowcore.service.resource.IResourceWorkflowService;
import fr.paris.lutece.plugins.workflowcore.service.state.StateService;
import fr.paris.lutece.plugins.workflowcore.service.task.ITask;
import fr.paris.lutece.plugins.workflowcore.service.task.ITaskService;
import fr.paris.lutece.plugins.workflowcore.service.task.SimpleTask;
import fr.paris.lutece.portal.service.daemon.AppDaemonService;
import fr.paris.lutece.portal.service.daemon.Daemon;
import fr.paris.lutece.portal.service.i18n.I18nService;
import fr.paris.lutece.portal.service.mail.MailService;
import fr.paris.lutece.portal.service.plugin.Plugin;
import fr.paris.lutece.portal.service.plugin.PluginService;
import fr.paris.lutece.portal.service.spring.SpringContextService;
import fr.paris.lutece.portal.service.util.AppException;
import fr.paris.lutece.portal.service.util.AppLogService;
import fr.paris.lutece.portal.service.util.AppPropertiesService;
import fr.paris.lutece.portal.web.l10n.LocaleService;
import fr.paris.lutece.util.sql.TransactionManager;

/**
 * Task notify appointment
 * @author Mairie de Paris
 *
 */
public class TaskNotifyReminder extends SimpleTask {

    //mark    
    private static final String MARK_FIRST_NAME = "${firstName}";
    private static final String MARK_LAST_NAME = "${lastName}";
    private static final String MARK_DATE_APP = "${date_appointment}";
    private static final String MARK_TIME_APP = "${time_appointment}";
    private static final String MARK_LOCALIZATION = "${localisation}";
    private static final String MARK_CANCEL_APP = "${url_cancel}";
    private static final String MARK_PREFIX_SENDER = "@contact-everyone.fr";
    private static final String MARK_SENDER_SMS = "magali.lemaire@paris.fr";
    private static final String MARK_REGEX_SMS = "^(06|07)[0-9]{8}$";
    private static final String USER_AUTO = "auto";
    private static final String MARK_DURATION_LIMIT = "daemon.reminder.interval";

    //properties
    private static final String PROPERTY_MAIL_SENDER_NAME = "genericalert.task_notify_reminder.mailSenderName";
    private static final String MESSAGE_MARK_DESCRIPTION = "genericalert.task_notify_reminder.description";

    //service 
    private final StateService _stateService = SpringContextService.getBean(StateService.BEAN_SERVICE);
    @Inject
    @Named(TaskNotifyReminderConfigService.BEAN_SERVICE)
    private ITaskConfigService _taskNotifyReminderConfigService;

    @Inject
    private IActionService _actionService;

    @Inject
    private ITaskService _taskService;

    @Inject
    private IResourceHistoryService _resourceHistoryService;

    @Inject
    private IResourceWorkflowService _resourceWorkflowService;

    @Override
    public void processTask(int nIdResourceHistory, HttpServletRequest request, Locale locale) {

        ResourceHistory resourceHistory = _resourceHistoryService.findByPrimaryKey(nIdResourceHistory);
        Action action = _actionService.findByPrimaryKey(resourceHistory.getAction().getId());

        State stateBefore = action.getStateBefore();

        Date date = new Date();
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        Timestamp timestampDay = new Timestamp(calendar.getTimeInMillis());

        List<AppointmentForm> listForms = AppointmentFormHome.getActiveAppointmentFormsList();

        for (AppointmentForm form : listForms) {
            int nIdForm = form.getIdForm();

            TaskNotifyReminderConfig config = TaskNotifyReminderConfigHome.findByIdForm(this.getId(), nIdForm);

            if (config != null) {
                List<ReminderAppointment> listReminders = null;
                List<Appointment> listAppointments = getListAppointment(form);

                for (Appointment appointment : listAppointments) {
                    Calendar cal2 = new GregorianCalendar();
                    Date startAppointment = appointment.getStartAppointment();
                    cal2.setTime(startAppointment);
                    Timestamp timeStartDate = new Timestamp(cal2.getTimeInMillis());

                    State stateAppointment = _stateService.findByResource(appointment.getIdAppointment(),
                            Appointment.APPOINTMENT_RESOURCE_TYPE, form.getIdWorkflow());

                    if (timeStartDate.getTime() > timestampDay.getTime() && stateAppointment != null
                            && stateAppointment.getId() == stateBefore.getId()) {
                        long lDiffTimeStamp = Math.abs(timestampDay.getTime() - timeStartDate.getTime());
                        int nDays = (int) lDiffTimeStamp / (1000 * 60 * 60 * 24);
                        int nDiffHours = ((int) lDiffTimeStamp / (60 * 60 * 1000) % 24) + (nDays * 24);
                        int nDiffMin = (nDiffHours * 60) + (int) (lDiffTimeStamp / (60 * 1000) % 60);

                        ResourceHistory appointHistory = _resourceHistoryService.getLastHistoryResource(
                                appointment.getIdAppointment(), Appointment.APPOINTMENT_RESOURCE_TYPE,
                                form.getIdWorkflow());
                        Calendar cal = new GregorianCalendar();
                        if (appointHistory != null) {
                            cal.setTime(appointHistory.getCreationDate());
                        }
                        Timestamp timestampCreationDate = new Timestamp(cal.getTimeInMillis());

                        long nDiff = Math.abs(timestampDay.getTime() - timestampCreationDate.getTime());
                        int nDaysCreationDate = (int) nDiff / (1000 * 60 * 60 * 24);
                        int nDiffHoursCreationDate = ((int) nDiff / (60 * 60 * 1000) % 24)
                                + (nDaysCreationDate * 24);
                        int nDiffCreationDate = (nDiffHoursCreationDate * 60) + (int) (nDiff / (60 * 1000) % 60);

                        if (config.getNbAlerts() > 0) {
                            listReminders = config.getListReminderAppointment();
                        }

                        for (ReminderAppointment reminder : listReminders) {
                            if (nDiffCreationDate > 2 && timestampDay.getTime() > timestampCreationDate.getTime())
                                sendReminder(appointment, reminder, startAppointment, nDiffMin, form, config);
                        }
                    }
                }
            }
        }
    }

    /**
     * Get list appointment
     * @param form the appointmentForm
     * @return list appointment
     */
    private List<Appointment> getListAppointment(AppointmentForm form) {
        List<Appointment> listAllAppointments = AppointmentHome.getAppointmentsListByIdForm(form.getIdForm());
        List<Integer> list = new ArrayList<Integer>();
        for (Appointment appointment : listAllAppointments) {
            list.add(appointment.getIdAppointment());

        }
        List<Appointment> listAppointments = AppointmentHome.getAppointmentListById(list);
        return listAppointments;
    }

    /**
     * 
     * @param appointment the appointment
     * @param reminder the reminder
     * @param startAppointment startAppointment date of start appointment
     * @param nDiffMin diffrence time in minutes
     * @param form the appointment form
     * @param config the task config
     */
    private void sendReminder(Appointment appointment, ReminderAppointment reminder, Date startAppointment,
            int nDiffMin, AppointmentForm form, TaskNotifyReminderConfig config) {
        int nInterval = Integer.parseInt(AppPropertiesService.getProperty(MARK_DURATION_LIMIT));

        int nMinTime = (reminder.getTimeToAlert() * 60 * 24) - nInterval;
        int nMaxTime = (reminder.getTimeToAlert() * 60 * 24) + nInterval;

        AppLogService.info("Alert time :" + reminder.getTimeToAlert());
        AppLogService.info("nDiffMin  : " + nDiffMin);

        if (nDiffMin <= nMaxTime && nDiffMin >= nMinTime
                && ((appointment.getHasNotify() == 0) || (appointment.getHasNotify() != (reminder.getRank())))) {
            boolean bNotified = false;
            Locale locale = LocaleService.getDefault();
            String strSenderMail = MailService.getNoReplyEmail();
            String strSenderName = I18nService.getLocalizedString(PROPERTY_MAIL_SENDER_NAME, locale);
            String strEmailCc = reminder.getEmailCc();

            AppLogService.info("IN :");
            AppLogService.info("strSenderMail : " + strSenderMail);
            AppLogService.info("strSenderName : " + strSenderName);
            AppLogService.info("Dest : " + appointment.getEmail());
            AppLogService.info("Objet : " + reminder.getAlertSubject());
            AppLogService.info("email texte : " + reminder.getEmailAlertMessage());

            String strEmailText = reminder.getEmailAlertMessage();
            String strSmsText = reminder.getSmsAlertMessage();

            if (strEmailText != null && !strEmailText.isEmpty()) {
                strEmailText = getMessageAppointment(strEmailText, appointment);
            }
            if (strSmsText != null && !strSmsText.isEmpty()) {
                strSmsText = getMessageAppointment(strSmsText, appointment);
            }
            if (reminder.isEmailNotify() && !appointment.getEmail().isEmpty()) {
                try {
                    AppLogService.info("try to send MAIL : \n ");
                    MailService.sendMailHtml(appointment.getEmail(), strEmailCc, StringUtils.EMPTY, strSenderName,
                            strSenderMail, reminder.getAlertSubject(), strEmailText);
                    bNotified = true;
                    AppLogService.info("AppointmentReminderDaemon - Info sending reminder alert mail to : "
                            + appointment.getEmail());
                } catch (Exception e) {
                    AppLogService.info("CATCH sending MAIL");
                    AppLogService.error(
                            "AppointmentReminderDaemon - Error sending reminder alert MAIL to : " + e.getMessage(),
                            e);
                }
            }
            AppLogService.info("SMS :  " + reminder.isSmsNotify());
            if (reminder.isSmsNotify() && reminder.getNumberPhone() != null) {
                String strRecipient = getSmsFromAppointment(appointment, reminder);
                AppLogService.info("PHONE : " + strRecipient);

                if (!strRecipient.isEmpty() && strRecipient.matches(MARK_REGEX_SMS)) {
                    try {
                        strRecipient += MARK_PREFIX_SENDER;
                        AppLogService.info("try to send SMS : \n ");
                        AppLogService.info("strRecipient" + strRecipient);
                        AppLogService.info("strSenderName" + strSenderName);
                        AppLogService.info("MARK_SENDER_SMS" + MARK_SENDER_SMS);
                        AppLogService.info("strText" + strSmsText);

                        MailService.sendMailHtml(strRecipient, strSenderName, MARK_SENDER_SMS,
                                reminder.getAlertSubject(), strSmsText);
                        bNotified = true;
                        AppLogService.info(
                                "AppointmentReminderDaemon - Info sending reminder alert SMS to : " + strRecipient);
                    } catch (Exception e) {
                        AppLogService.info("CATCH sending reminder alert SMS: ");
                        AppLogService.error("AppointmentReminderDaemon - Error sending reminder alert SMS to : "
                                + strRecipient + e.getMessage(), e);
                    }
                }
            }
            if (bNotified) {
                appointment.setHasNotify(reminder.getRank());
                try {
                    AppointmentHome.update(appointment);
                    AppLogService.info("BEGIN CHANGE STATE : ");
                    doChangeState(config, reminder, form, appointment);
                    AppLogService.info("END CHANGE STATE : ");
                    State stateApp = _stateService.findByResource(appointment.getIdAppointment(),
                            Appointment.APPOINTMENT_RESOURCE_TYPE, form.getIdWorkflow());
                    AppLogService.info("State appointment after changing  :  " + stateApp.getId());
                } catch (Exception e) {
                    AppLogService.info("CATCH CHANGING STATE : ");
                    throw new AppException(e.getMessage(), e);

                }
            }
        }
    }

    /**
     *  Get sms number
     * @param appointment the appointment
     * @param reminder the reminder task
     * @return the sms number
     */
    private String getSmsFromAppointment(Appointment appointment, ReminderAppointment reminder) {
        AppLogService.info(" getSmsFromAppointment GET NUMBER : ");
        String strPhoneNumber = StringUtils.EMPTY;
        AppointmentSlot slot = AppointmentSlotHome.findByPrimaryKey(appointment.getIdSlot());
        EntryFilter entryFilter = new EntryFilter();
        entryFilter.setIdResource(slot.getIdForm());

        List<Integer> listIdResponse = AppointmentHome.findListIdResponse(appointment.getIdAppointment());
        AppLogService.info("listIdResponse.SIZE  : " + listIdResponse.size());
        List<Response> listResponses = new ArrayList<Response>(listIdResponse.size());
        AppLogService.info("listResponses.SIZE  : " + listResponses.size());
        for (int nIdResponse : listIdResponse) {
            Response response = ResponseHome.findByPrimaryKey(nIdResponse);
            if (response != null) {
                listResponses.add(response);
            }
        }

        List<Entry> listEntries = EntryHome.getEntryList(entryFilter);
        AppLogService.info("listEntries.SIZE  : " + listEntries.size());
        for (Entry entry : listEntries) {
            IEntryTypeService entryTypeService = EntryTypeServiceManager.getEntryTypeService(entry);

            if (entryTypeService instanceof EntryTypePhone) {
                for (Response response : listResponses) {
                    if ((response.getEntry().getIdEntry() == entry.getIdEntry())
                            && StringUtils.isNotBlank(response.getResponseValue())
                            && entry.getTitle().equals(reminder.getNumberPhone())) {
                        strPhoneNumber = response.getResponseValue();

                        break;
                    }
                }

                if (StringUtils.isNotEmpty(strPhoneNumber)) {
                    break;
                }
            }
        }
        return strPhoneNumber;
    }

    /**
     * Get message text
     * @param msg the text message
     * @param appointment the appointment
     * @return the text message
     */
    private String getMessageAppointment(String msg, Appointment appointment) {
        DateFormat formater = DateFormat.getDateInstance(DateFormat.FULL, Locale.FRENCH);
        SimpleDateFormat formatTime = new SimpleDateFormat("HH:mm");
        String strLocation = appointment.getLocation() == null ? StringUtils.EMPTY : appointment.getLocation();
        String strText = StringUtils.EMPTY;
        strText = msg.replace(MARK_FIRST_NAME, appointment.getFirstName());
        strText = strText.replace(MARK_LAST_NAME, appointment.getLastName());
        strText = strText.replace(MARK_DATE_APP, formater.format(appointment.getDateAppointment()));
        strText = strText.replace(MARK_TIME_APP, formatTime.format(appointment.getStartAppointment()));
        strText = strText.replace(MARK_LOCALIZATION, strLocation);
        strText = strText.replace(MARK_CANCEL_APP, AppointmentApp.getCancelAppointmentUrl(appointment));

        return strText;
    }

    /**
     * 
     * @param config the config task
     * @param reminder the reminder task
     * @param form the appointment form
     * @param appointment the appointment
     */
    private void doChangeState(TaskNotifyReminderConfig config, ReminderAppointment reminder, AppointmentForm form,
            Appointment appointment) {
        //The locale is not important. It is just used to fetch the task action id
        Locale locale = I18nService.getDefaultLocale();
        ITask task = _taskService.findByPrimaryKey(config.getIdTask(), locale);

        AppLogService.info("task : " + task.getId());

        State stateAppointment = _stateService.findByResource(appointment.getIdAppointment(),
                Appointment.APPOINTMENT_RESOURCE_TYPE, form.getIdWorkflow());

        AppLogService.info("State appointment before changing  :  " + stateAppointment.getId());

        if (task != null) {

            State state = _stateService.findByPrimaryKey(reminder.getIdStateAfter());
            if (state != null) {
                AppLogService.info("State state : " + state.getId());
            }
            Action action = _actionService.findByPrimaryKey(task.getAction().getId());

            AppLogService.info("Action action" + action.getId());

            if ((state != null) && (action != null)) {

                // Create Resource History
                ResourceHistory resourceHistory = new ResourceHistory();
                resourceHistory.setIdResource(appointment.getIdAppointment());
                resourceHistory.setResourceType(Appointment.APPOINTMENT_RESOURCE_TYPE);
                resourceHistory.setAction(action);
                resourceHistory.setWorkFlow(action.getWorkflow());
                resourceHistory.setCreationDate(WorkflowUtils.getCurrentTimestamp());
                resourceHistory.setUserAccessCode(USER_AUTO);
                _resourceHistoryService.create(resourceHistory);

                // Update Resource
                ResourceWorkflow resourceWorkflow = _resourceWorkflowService.findByPrimaryKey(
                        appointment.getIdAppointment(), Appointment.APPOINTMENT_RESOURCE_TYPE,
                        form.getIdWorkflow());

                AppLogService.info("ResourceWorkflow resourceWorkflow :" + resourceWorkflow.getIdResource());
                resourceWorkflow.setState(state);
                _resourceWorkflowService.update(resourceWorkflow);

                AppLogService.info("_resourceWorkflowService updated :");
            }
        }
        State stateApp = _stateService.findByResource(appointment.getIdAppointment(),
                Appointment.APPOINTMENT_RESOURCE_TYPE, form.getIdWorkflow());
        AppLogService.info("State appointment after changing  :  " + stateApp.getId());
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void doRemoveConfig() {
        _taskNotifyReminderConfigService.remove(this.getId());
    }

    @Override
    public String getTitle(Locale locale) {
        return I18nService.getLocalizedString(MESSAGE_MARK_DESCRIPTION, locale);
    }

}