Merge pull request #45 from dgray16/master
Rewrite notification system.
This commit is contained in:
commit
327360bd08
35 changed files with 1777 additions and 372 deletions
|
|
@ -25,13 +25,20 @@ package org.libreplan.business.common.entities;
|
||||||
* {@link JobSchedulerConfiguration}
|
* {@link JobSchedulerConfiguration}
|
||||||
*
|
*
|
||||||
* @author Miciele Ghiorghis <m.ghiorghis@antoniusziekenhuis.nl>
|
* @author Miciele Ghiorghis <m.ghiorghis@antoniusziekenhuis.nl>
|
||||||
|
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
|
||||||
*/
|
*/
|
||||||
public enum JobClassNameEnum {
|
public enum JobClassNameEnum {
|
||||||
|
|
||||||
IMPORT_ROSTER_FROM_TIM_JOB("org.libreplan.importers", "ImportRosterFromTimJob"),
|
IMPORT_ROSTER_FROM_TIM_JOB("org.libreplan.importers", "ImportRosterFromTimJob"),
|
||||||
EXPORT_TIMESHEET_TO_TIM_JOB("org.libreplan.importers", "ExportTimesheetToTimJob"),
|
EXPORT_TIMESHEET_TO_TIM_JOB("org.libreplan.importers", "ExportTimesheetToTimJob"),
|
||||||
SYNC_ORDERELEMENTS_WITH_JIRA_ISSUES_JOB("org.libreplan.importers", "JiraOrderElementSynchronizerJob"),
|
SYNC_ORDERELEMENTS_WITH_JIRA_ISSUES_JOB("org.libreplan.importers", "JiraOrderElementSynchronizerJob"),
|
||||||
SEND_EMAIL_JOB("org.libreplan.importers", "SendEmailJob");
|
|
||||||
|
SEND_EMAIL_TASK_ASSIGNED_TO_RESOURCE("org.libreplan.importers.notifications.jobs", "SendEmailOnTaskAssignedToResourceJob"),
|
||||||
|
SEND_EMAIL_RESOURCE_REMOVED_FROM_TASK("org.libreplan.importers.notifications.jobs", "SendEmailOnResourceRemovedFromTaskJob"),
|
||||||
|
SEND_EMAIL_MILESTONE_REACHED("org.libreplan.importers.notifications.jobs", "SendEmailOnMilestoneReachedJob"),
|
||||||
|
SEND_EMAIL_TASK_SHOULD_START("org.libreplan.importers.notifications.jobs", "SendEmailOnTaskShouldStartJob"),
|
||||||
|
SEND_EMAIL_TASK_SHOULD_FINISH("org.libreplan.importers.notifications.jobs", "SendEmailOnTaskShouldFinishJob"),
|
||||||
|
SEND_EMAIL_TIMESHEET_DATA_MISSING("org.libreplan.importers.notifications.jobs", "SendEmailOnTimesheetDataMissingJob");
|
||||||
|
|
||||||
private String packageName;
|
private String packageName;
|
||||||
private String name;
|
private String name;
|
||||||
|
|
|
||||||
|
|
@ -32,10 +32,11 @@ import java.util.List;
|
||||||
*
|
*
|
||||||
* Created by
|
* Created by
|
||||||
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
|
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
|
||||||
* on 19.10.15.
|
* on 19.10.2015.
|
||||||
*/
|
*/
|
||||||
@Repository
|
@Repository
|
||||||
public class EmailNotificationDAO extends GenericDAOHibernate<EmailNotification, Long> implements IEmailNotificationDAO {
|
public class EmailNotificationDAO extends GenericDAOHibernate<EmailNotification, Long>
|
||||||
|
implements IEmailNotificationDAO {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<EmailNotification> getAll() {
|
public List<EmailNotification> getAll() {
|
||||||
|
|
|
||||||
|
|
@ -26,14 +26,19 @@ import static org.libreplan.business.i18n.I18nHelper._;
|
||||||
*
|
*
|
||||||
* Created by
|
* Created by
|
||||||
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
|
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
|
||||||
* on 28.09.15.
|
* on 28.09.2015.
|
||||||
*
|
*
|
||||||
* TEMPLATE_N(_("Template N")) - for i18n
|
* TEMPLATE_N(_("Template N")) - for i18n
|
||||||
* TEMPLATE_A("Template A") - for general use (no internationalizing)
|
* TEMPLATE_A("Template A") - for general use (no internationalizing)
|
||||||
*/
|
*/
|
||||||
public enum EmailTemplateEnum {
|
public enum EmailTemplateEnum {
|
||||||
|
|
||||||
TEMPLATE_TASK_ASSIGNED_TO_RESOURCE(_("Task assigned to resource"));
|
TEMPLATE_TASK_ASSIGNED_TO_RESOURCE(_("Task assigned to resource")),
|
||||||
|
TEMPLATE_RESOURCE_REMOVED_FROM_TASK(_("Resource removed from task")),
|
||||||
|
TEMPLATE_MILESTONE_REACHED(_("Milestone reached")),
|
||||||
|
TEMPLATE_TODAY_TASK_SHOULD_START(_("Task should start")),
|
||||||
|
TEMPLATE_TODAY_TASK_SHOULD_FINISH(_("Task should finish")),
|
||||||
|
TEMPLATE_ENTER_DATA_IN_TIMESHEET(_("Enter data in timesheet"));
|
||||||
|
|
||||||
private final String templateType;
|
private final String templateType;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,9 +37,7 @@ import org.apache.commons.lang.ObjectUtils;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.hibernate.Criteria;
|
import org.hibernate.Criteria;
|
||||||
import org.hibernate.Query;
|
import org.hibernate.Query;
|
||||||
import org.hibernate.SessionFactory;
|
|
||||||
import org.hibernate.criterion.Restrictions;
|
import org.hibernate.criterion.Restrictions;
|
||||||
import org.libreplan.business.common.IAdHocTransactionService;
|
|
||||||
import org.libreplan.business.common.daos.IntegrationEntityDAO;
|
import org.libreplan.business.common.daos.IntegrationEntityDAO;
|
||||||
import org.libreplan.business.common.exceptions.InstanceNotFoundException;
|
import org.libreplan.business.common.exceptions.InstanceNotFoundException;
|
||||||
import org.libreplan.business.expensesheet.daos.IExpenseSheetLineDAO;
|
import org.libreplan.business.expensesheet.daos.IExpenseSheetLineDAO;
|
||||||
|
|
@ -88,15 +86,6 @@ public class OrderElementDAO extends IntegrationEntityDAO<OrderElement>
|
||||||
@Autowired
|
@Autowired
|
||||||
private ITaskSourceDAO taskSourceDAO;
|
private ITaskSourceDAO taskSourceDAO;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private IOrderDAO orderDAO;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private IAdHocTransactionService transactionService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private SessionFactory sessionFactory;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<OrderElement> findWithoutParent() {
|
public List<OrderElement> findWithoutParent() {
|
||||||
Criteria c = getSession().createCriteria(OrderElement.class);
|
Criteria c = getSession().createCriteria(OrderElement.class);
|
||||||
|
|
@ -260,6 +249,7 @@ public class OrderElementDAO extends IntegrationEntityDAO<OrderElement>
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional
|
||||||
public List<OrderElement> getAll() {
|
public List<OrderElement> getAll() {
|
||||||
return list(OrderElement.class);
|
return list(OrderElement.class);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ import org.libreplan.business.planner.entities.TaskGroup;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Óscar González Fernández <ogonzalez@igalia.com>
|
* @author Óscar González Fernández <ogonzalez@igalia.com>
|
||||||
|
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
|
||||||
*/
|
*/
|
||||||
public interface ITaskElementDAO extends IGenericDAO<TaskElement, Long> {
|
public interface ITaskElementDAO extends IGenericDAO<TaskElement, Long> {
|
||||||
|
|
||||||
|
|
@ -39,4 +40,8 @@ public interface ITaskElementDAO extends IGenericDAO<TaskElement, Long> {
|
||||||
|
|
||||||
List<TaskElement> getTaskElementsNoMilestonesWithoutTaskSource();
|
List<TaskElement> getTaskElementsNoMilestonesWithoutTaskSource();
|
||||||
|
|
||||||
|
List<TaskElement> getTaskElementsWithMilestones();
|
||||||
|
|
||||||
|
List<TaskElement> getTaskElementsWithParentsWithoutMilestones();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||||
/**
|
/**
|
||||||
* @author Óscar González Fernández <ogonzalez@igalia.com>
|
* @author Óscar González Fernández <ogonzalez@igalia.com>
|
||||||
* @author Jacobo Aragunde Pérez <jaragunde@igalia.com>
|
* @author Jacobo Aragunde Pérez <jaragunde@igalia.com>
|
||||||
|
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
|
||||||
*/
|
*/
|
||||||
@Repository
|
@Repository
|
||||||
@Scope(BeanDefinition.SCOPE_SINGLETON)
|
@Scope(BeanDefinition.SCOPE_SINGLETON)
|
||||||
|
|
@ -135,4 +136,23 @@ public class TaskElementDAO extends GenericDAOHibernate<TaskElement, Long>
|
||||||
return query.list();
|
return query.list();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public List<TaskElement> getTaskElementsWithMilestones(){
|
||||||
|
String strQuery = "FROM TaskElement "
|
||||||
|
+ "WHERE id IN (SELECT id FROM TaskMilestone)";
|
||||||
|
Query query = getSession().createQuery(strQuery);
|
||||||
|
return query.list();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public List<TaskElement> getTaskElementsWithParentsWithoutMilestones() {
|
||||||
|
String strQuery = "FROM TaskElement "
|
||||||
|
+ "WHERE parent IS NOT NULL AND "
|
||||||
|
+ "id NOT IN (SELECT id FROM TaskMilestone)";
|
||||||
|
Query query = getSession().createQuery(strQuery);
|
||||||
|
return query.list();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,13 +24,13 @@
|
||||||
column="last_sequence_code" />
|
column="last_sequence_code" />
|
||||||
|
|
||||||
<!-- Index created in a database-object section -->
|
<!-- Index created in a database-object section -->
|
||||||
<set name="exceptions" access="field" cascade="all-delete-orphan" batch-size="10">
|
<set name="exceptions" access="field" cascade="all-delete-orphan" batch-size="10" lazy="false">
|
||||||
<key column="base_calendar_id" />
|
<key column="base_calendar_id" />
|
||||||
<one-to-many class="CalendarException" />
|
<one-to-many class="CalendarException" />
|
||||||
</set>
|
</set>
|
||||||
|
|
||||||
<!-- Index created in a database-object section -->
|
<!-- Index created in a database-object section -->
|
||||||
<list name="calendarDataVersions" access="field" cascade="all-delete-orphan" batch-size="10">
|
<list name="calendarDataVersions" access="field" cascade="all-delete-orphan" batch-size="10" lazy="false">
|
||||||
<key column="base_calendar_id" />
|
<key column="base_calendar_id" />
|
||||||
<index column="position_in_calendar" />
|
<index column="position_in_calendar" />
|
||||||
<one-to-many class="CalendarData" />
|
<one-to-many class="CalendarData" />
|
||||||
|
|
@ -43,7 +43,7 @@
|
||||||
<one-to-many class="CalendarAvailability" />
|
<one-to-many class="CalendarAvailability" />
|
||||||
</list>
|
</list>
|
||||||
|
|
||||||
<joined-subclass name="ResourceCalendar" table="resource_calendar">
|
<joined-subclass name="ResourceCalendar" table="resource_calendar" lazy="false">
|
||||||
<key column="base_calendar_id" />
|
<key column="base_calendar_id" />
|
||||||
<property name="capacity" not-null="true" />
|
<property name="capacity" not-null="true" />
|
||||||
<one-to-one name="resource"
|
<one-to-one name="resource"
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
|
|
||||||
</class>
|
</class>
|
||||||
|
|
||||||
<class name="EmailNotification" abstract="true" table="notification_queue">
|
<class name="EmailNotification" abstract="true" table="notification_queue" dynamic-insert="true">
|
||||||
|
|
||||||
<id name="id" access="property" type="long">
|
<id name="id" access="property" type="long">
|
||||||
<generator class="hilo">
|
<generator class="hilo">
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@
|
||||||
|
|
||||||
<!-- Indexed -->
|
<!-- Indexed -->
|
||||||
<many-to-one name="parent" class="TaskGroup" cascade="none" column="parent"
|
<many-to-one name="parent" class="TaskGroup" cascade="none" column="parent"
|
||||||
index="idx_task_element_on_task_group" />
|
index="idx_task_element_on_task_group" lazy="false" />
|
||||||
|
|
||||||
<one-to-one name="taskSource" cascade="delete" />
|
<one-to-one name="taskSource" cascade="delete" />
|
||||||
|
|
||||||
|
|
@ -89,7 +89,7 @@
|
||||||
cascade="all"/>
|
cascade="all"/>
|
||||||
|
|
||||||
<!-- Indexed on the other side -->
|
<!-- Indexed on the other side -->
|
||||||
<set name="resourceAllocations" cascade="all-delete-orphan">
|
<set name="resourceAllocations" cascade="all-delete-orphan" lazy="false">
|
||||||
<key column="task" />
|
<key column="task" />
|
||||||
<one-to-many class="ResourceAllocation" />
|
<one-to-many class="ResourceAllocation" />
|
||||||
</set>
|
</set>
|
||||||
|
|
|
||||||
|
|
@ -1,302 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of LibrePlan
|
|
||||||
*
|
|
||||||
* Copyright (C) 2015 LibrePlan
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program 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 Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.libreplan.importers;
|
|
||||||
|
|
||||||
import org.libreplan.business.common.Configuration;
|
|
||||||
import org.libreplan.business.common.daos.IConnectorDAO;
|
|
||||||
import org.libreplan.business.common.entities.Connector;
|
|
||||||
import org.libreplan.business.common.entities.ConnectorProperty;
|
|
||||||
import org.libreplan.business.email.entities.EmailNotification;
|
|
||||||
import org.libreplan.business.email.entities.EmailTemplate;
|
|
||||||
import org.libreplan.business.email.entities.EmailTemplateEnum;
|
|
||||||
import org.libreplan.business.resources.entities.Resource;
|
|
||||||
import org.libreplan.business.resources.entities.Worker;
|
|
||||||
import org.libreplan.business.settings.entities.Language;
|
|
||||||
import org.libreplan.web.email.IEmailNotificationModel;
|
|
||||||
|
|
||||||
import org.libreplan.web.email.IEmailTemplateModel;
|
|
||||||
import org.libreplan.web.planner.tabs.MultipleTabsPlannerController;
|
|
||||||
import org.libreplan.web.resources.worker.IWorkerModel;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
|
||||||
import org.springframework.context.annotation.Scope;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import javax.mail.Message;
|
|
||||||
import javax.mail.MessagingException;
|
|
||||||
import javax.mail.Transport;
|
|
||||||
import javax.mail.Session;
|
|
||||||
import javax.mail.PasswordAuthentication;
|
|
||||||
import javax.mail.internet.InternetAddress;
|
|
||||||
import javax.mail.internet.MimeMessage;
|
|
||||||
import javax.mail.NoSuchProviderException;
|
|
||||||
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends E-mail to users with data that storing in notification_queue table
|
|
||||||
*
|
|
||||||
* Created by
|
|
||||||
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
|
|
||||||
* on 13.10.15.
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
|
|
||||||
public class SendEmail implements ISendEmail {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private IEmailNotificationModel emailNotificationModel;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private IConnectorDAO connectorDAO;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private IWorkerModel workerModel;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private IEmailTemplateModel emailTemplateModel;
|
|
||||||
|
|
||||||
private List<EmailNotification> notifications;
|
|
||||||
private List<EmailTemplate> emailTemplates;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendEmail() {
|
|
||||||
if ( Configuration.isEmailSendingEnabled() == true ){
|
|
||||||
if (validConnection() == true){
|
|
||||||
notifications = emailNotificationModel.getAll();
|
|
||||||
for (int i = 0; i < notifications.size(); i++) composeMessageForUser(notifications.get(i));
|
|
||||||
deleteAllNotificationsAfterSending();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void composeMessageForUser(EmailNotification notification){
|
|
||||||
|
|
||||||
// Gather data about EmailTemplate needs to be used
|
|
||||||
Resource resource = notification.getResource();
|
|
||||||
EmailTemplateEnum type = notification.getType();
|
|
||||||
Locale locale;
|
|
||||||
Worker currentWorker = getCurrentWorker(resource.getId());
|
|
||||||
|
|
||||||
if ( currentWorker.getUser().getApplicationLanguage().equals(Language.BROWSER_LANGUAGE) ) {
|
|
||||||
locale = new Locale(System.getProperty("user.language"));
|
|
||||||
} else {
|
|
||||||
locale = new Locale(currentWorker.getUser().getApplicationLanguage().getLocale().getLanguage());
|
|
||||||
}
|
|
||||||
|
|
||||||
EmailTemplate currentEmailTemplate = findCurrentEmailTemplate(type, locale);
|
|
||||||
|
|
||||||
|
|
||||||
// Modify text that will be composed
|
|
||||||
String text = currentEmailTemplate.getContent();
|
|
||||||
|
|
||||||
if ( type.equals(EmailTemplateEnum.TEMPLATE_TASK_ASSIGNED_TO_RESOURCE) ){
|
|
||||||
text = text.replaceAll("\\{username\\}", currentWorker.getUser().getLoginName());
|
|
||||||
text = text.replaceAll("\\{firstname\\}", currentWorker.getUser().getFirstName());
|
|
||||||
text = text.replaceAll("\\{lastname\\}", currentWorker.getUser().getLastName());
|
|
||||||
text = text.replaceAll("\\{project\\}", notification.getProject().getName());
|
|
||||||
text = text.replaceAll("\\{resource\\}", notification.getResource().getName());
|
|
||||||
text = text.replaceAll("\\{task\\}", notification.getTask().getName());
|
|
||||||
text = text.replaceAll("\\{url\\}", MultipleTabsPlannerController.WELCOME_URL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get/Set connection properties
|
|
||||||
List<ConnectorProperty> emailConnectorProperties = getEmailConnectorProperties();
|
|
||||||
|
|
||||||
String receiver = currentWorker.getUser().getEmail();
|
|
||||||
String protocol = null;
|
|
||||||
String host = null;
|
|
||||||
String port = null;
|
|
||||||
String sender = null;
|
|
||||||
String usrnme = null;
|
|
||||||
String psswrd = null;
|
|
||||||
|
|
||||||
for (int i = 0; i < emailConnectorProperties.size(); i++){
|
|
||||||
switch (i){
|
|
||||||
case 1: {
|
|
||||||
protocol = emailConnectorProperties.get(1).getValue();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 2: {
|
|
||||||
host = emailConnectorProperties.get(2).getValue();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 3: {
|
|
||||||
port = emailConnectorProperties.get(3).getValue();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 4: {
|
|
||||||
sender = emailConnectorProperties.get(4).getValue();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 5: {
|
|
||||||
usrnme = emailConnectorProperties.get(5).getValue();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 6: {
|
|
||||||
psswrd = emailConnectorProperties.get(6).getValue();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set properties of connection
|
|
||||||
Properties properties = new Properties();
|
|
||||||
|
|
||||||
if ( protocol.equals("STARTTLS") ) {
|
|
||||||
properties.put("mail.smtp.starttls.enable", "true");
|
|
||||||
properties.put("mail.smtp.host", host);
|
|
||||||
properties.put("mail.smtp.socketFactory.port", port);
|
|
||||||
properties.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
|
|
||||||
properties.put("mail.smtp.auth", "true");
|
|
||||||
properties.put("mail.smtp.port", port);
|
|
||||||
}
|
|
||||||
else if ( protocol.equals("SMTP") ) {
|
|
||||||
properties.put("mail.smtp.host", host);
|
|
||||||
properties.put("mail.smtp.port", port);
|
|
||||||
}
|
|
||||||
|
|
||||||
final String username = usrnme;
|
|
||||||
final String password = psswrd;
|
|
||||||
|
|
||||||
/* It is very important to use Session.getInstance instead of Session.getDefaultInstance */
|
|
||||||
Session mailSession = Session.getInstance(properties,
|
|
||||||
new javax.mail.Authenticator() {
|
|
||||||
protected PasswordAuthentication getPasswordAuthentication() {
|
|
||||||
return new PasswordAuthentication(username, password);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Send message
|
|
||||||
try{
|
|
||||||
MimeMessage message = new MimeMessage(mailSession);
|
|
||||||
|
|
||||||
message.setFrom(new InternetAddress(sender));
|
|
||||||
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(receiver));
|
|
||||||
|
|
||||||
String subject = currentEmailTemplate.getSubject();
|
|
||||||
message.setSubject(subject);
|
|
||||||
|
|
||||||
message.setText(text);
|
|
||||||
|
|
||||||
Transport.send(message);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} catch (MessagingException e){throw new RuntimeException(e);}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void deleteAllNotificationsAfterSending(){
|
|
||||||
emailNotificationModel.deleteAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<ConnectorProperty> getEmailConnectorProperties() {
|
|
||||||
|
|
||||||
Connector connector = connectorDAO.findUniqueByName("E-mail");
|
|
||||||
|
|
||||||
List<ConnectorProperty> properties = connector.getProperties();
|
|
||||||
|
|
||||||
return properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
private EmailTemplate findCurrentEmailTemplate(EmailTemplateEnum templateEnum, Locale locale){
|
|
||||||
emailTemplates = emailTemplateModel.getAll();
|
|
||||||
for (EmailTemplate item : emailTemplates)
|
|
||||||
if ( item.getType().equals(templateEnum) && item.getLanguage().getLocale().equals(locale) )
|
|
||||||
return item;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Worker getCurrentWorker(Long resourceID){
|
|
||||||
List<Worker> workerList = workerModel.getWorkers();
|
|
||||||
for(int i = 0; i < workerList.size(); i++)
|
|
||||||
if ( workerList.get(i).getId().equals(resourceID) )
|
|
||||||
return workerList.get(i);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean validConnection(){
|
|
||||||
List<ConnectorProperty> emailConnectorProperties = getEmailConnectorProperties();
|
|
||||||
|
|
||||||
String protocol = null;
|
|
||||||
String host = null;
|
|
||||||
String port = null;
|
|
||||||
String usrnme = null;
|
|
||||||
String psswrd = null;
|
|
||||||
|
|
||||||
for (int i = 0; i < emailConnectorProperties.size(); i++){
|
|
||||||
switch (i){
|
|
||||||
case 1: {
|
|
||||||
protocol = emailConnectorProperties.get(1).getValue();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 2: {
|
|
||||||
host = emailConnectorProperties.get(2).getValue();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 3: {
|
|
||||||
port = emailConnectorProperties.get(3).getValue();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 5: {
|
|
||||||
usrnme = emailConnectorProperties.get(5).getValue();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 6: {
|
|
||||||
psswrd = emailConnectorProperties.get(6).getValue();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set properties of connection
|
|
||||||
Properties properties = new Properties();
|
|
||||||
|
|
||||||
Transport transport = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (protocol.equals("SMTP")) {
|
|
||||||
properties.setProperty("mail.smtp.port", port);
|
|
||||||
properties.setProperty("mail.smtp.host", host);
|
|
||||||
Session session = Session.getInstance(properties, null);
|
|
||||||
|
|
||||||
transport = session.getTransport("smtp");
|
|
||||||
if (usrnme.equals("") && psswrd.equals("")) transport.connect();
|
|
||||||
} else if (protocol.equals("STARTTLS")) {
|
|
||||||
properties.setProperty("mail.smtps.port", port);
|
|
||||||
properties.setProperty("mail.smtps.host", host);
|
|
||||||
Session session = Session.getInstance(properties, null);
|
|
||||||
|
|
||||||
transport = session.getTransport("smtps");
|
|
||||||
if (!usrnme.equals("") && psswrd != null) transport.connect(host, usrnme, psswrd);
|
|
||||||
}
|
|
||||||
if (transport.isConnected()) return true;
|
|
||||||
|
|
||||||
} catch (NoSuchProviderException e) {}
|
|
||||||
catch (MessagingException e) {}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,237 @@
|
||||||
|
package org.libreplan.importers.notifications;
|
||||||
|
|
||||||
|
import org.libreplan.business.common.entities.ConnectorProperty;
|
||||||
|
import org.libreplan.business.email.entities.EmailNotification;
|
||||||
|
import org.libreplan.business.email.entities.EmailTemplate;
|
||||||
|
import org.libreplan.business.email.entities.EmailTemplateEnum;
|
||||||
|
import org.libreplan.business.resources.entities.Resource;
|
||||||
|
import org.libreplan.business.resources.entities.Worker;
|
||||||
|
import org.libreplan.business.settings.entities.Language;
|
||||||
|
import org.libreplan.business.users.entities.UserRole;
|
||||||
|
import org.libreplan.web.email.IEmailTemplateModel;
|
||||||
|
import org.libreplan.web.planner.tabs.MultipleTabsPlannerController;
|
||||||
|
import org.libreplan.web.resources.worker.IWorkerModel;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.zkoss.zul.Messagebox;
|
||||||
|
|
||||||
|
import javax.mail.Message;
|
||||||
|
import javax.mail.MessagingException;
|
||||||
|
import javax.mail.PasswordAuthentication;
|
||||||
|
import javax.mail.Session;
|
||||||
|
import javax.mail.Transport;
|
||||||
|
import javax.mail.internet.InternetAddress;
|
||||||
|
import javax.mail.internet.MimeMessage;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import static org.libreplan.web.I18nHelper._;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends E-mail to users with data that storing in notification_queue table
|
||||||
|
* and that are treat to incoming EmailNotification
|
||||||
|
*
|
||||||
|
* Created by
|
||||||
|
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
|
||||||
|
* on 20.01.2016.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
|
||||||
|
public class ComposeMessage {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IWorkerModel workerModel;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IEmailTemplateModel emailTemplateModel;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private EmailConnectionValidator emailConnectionValidator;
|
||||||
|
|
||||||
|
private String protocol;
|
||||||
|
|
||||||
|
private String host;
|
||||||
|
|
||||||
|
private String port;
|
||||||
|
|
||||||
|
private String sender;
|
||||||
|
|
||||||
|
private String usrnme;
|
||||||
|
|
||||||
|
private String psswrd;
|
||||||
|
|
||||||
|
private Properties properties;
|
||||||
|
|
||||||
|
|
||||||
|
public boolean composeMessageForUser(EmailNotification notification) {
|
||||||
|
// Gather data about EmailTemplate needs to be used
|
||||||
|
Resource resource = notification.getResource();
|
||||||
|
EmailTemplateEnum type = notification.getType();
|
||||||
|
Locale locale;
|
||||||
|
Worker currentWorker = getCurrentWorker(resource.getId());
|
||||||
|
|
||||||
|
UserRole currentUserRole = getCurrentUserRole(notification.getType());
|
||||||
|
|
||||||
|
if ( currentWorker.getUser().isInRole(currentUserRole) ){
|
||||||
|
if ( currentWorker.getUser().getApplicationLanguage().equals(Language.BROWSER_LANGUAGE) ) {
|
||||||
|
locale = new Locale(System.getProperty("user.language"));
|
||||||
|
} else {
|
||||||
|
locale = new Locale(currentWorker.getUser().getApplicationLanguage().getLocale().getLanguage());
|
||||||
|
}
|
||||||
|
|
||||||
|
EmailTemplate currentEmailTemplate = findCurrentEmailTemplate(type, locale);
|
||||||
|
|
||||||
|
// Modify text that will be composed
|
||||||
|
String text = currentEmailTemplate.getContent();
|
||||||
|
text = replaceKeywords(text, currentWorker, notification);
|
||||||
|
|
||||||
|
String receiver = currentWorker.getUser().getEmail();
|
||||||
|
|
||||||
|
setupConnectionProperties();
|
||||||
|
|
||||||
|
final String username = usrnme;
|
||||||
|
final String password = psswrd;
|
||||||
|
|
||||||
|
// It is very important to use Session.getInstance instead of Session.getDefaultInstance
|
||||||
|
Session mailSession = Session.getInstance(properties,
|
||||||
|
new javax.mail.Authenticator() {
|
||||||
|
protected PasswordAuthentication getPasswordAuthentication() {
|
||||||
|
return new PasswordAuthentication(username, password);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Send message
|
||||||
|
try{
|
||||||
|
MimeMessage message = new MimeMessage(mailSession);
|
||||||
|
|
||||||
|
message.setFrom(new InternetAddress(sender));
|
||||||
|
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(receiver));
|
||||||
|
|
||||||
|
String subject = currentEmailTemplate.getSubject();
|
||||||
|
message.setSubject(subject);
|
||||||
|
|
||||||
|
message.setText(text);
|
||||||
|
|
||||||
|
Transport.send(message);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} catch (MessagingException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
} catch (NullPointerException e){
|
||||||
|
if (receiver == null) try {
|
||||||
|
Messagebox.show(_(currentWorker.getUser().getLoginName() + " - this user have not filled E-mail"), _("Error"),
|
||||||
|
Messagebox.OK, Messagebox.ERROR);
|
||||||
|
} catch (InterruptedException e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Worker getCurrentWorker(Long resourceID){
|
||||||
|
List<Worker> workerList = workerModel.getWorkers();
|
||||||
|
for(int i = 0; i < workerList.size(); i++)
|
||||||
|
if ( workerList.get(i).getId().equals(resourceID) )
|
||||||
|
return workerList.get(i);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private EmailTemplate findCurrentEmailTemplate(EmailTemplateEnum templateEnum, Locale locale){
|
||||||
|
List<EmailTemplate> emailTemplates;
|
||||||
|
emailTemplates = emailTemplateModel.getAll();
|
||||||
|
for (EmailTemplate item : emailTemplates)
|
||||||
|
if ( item.getType().equals(templateEnum) && item.getLanguage().getLocale().equals(locale) )
|
||||||
|
return item;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String replaceKeywords(String text, Worker currentWorker, EmailNotification notification){
|
||||||
|
if ( notification.getType().equals(EmailTemplateEnum.TEMPLATE_ENTER_DATA_IN_TIMESHEET) ){
|
||||||
|
// It is because there is no other data for
|
||||||
|
// EmailNotification of TEMPLATE_ENTER_DATA_IN_TIMESHEET notification type
|
||||||
|
text = text.replaceAll("\\{resource\\}", notification.getResource().getName());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
text = text.replaceAll("\\{username\\}", currentWorker.getUser().getLoginName());
|
||||||
|
text = text.replaceAll("\\{firstname\\}", currentWorker.getUser().getFirstName());
|
||||||
|
text = text.replaceAll("\\{lastname\\}", currentWorker.getUser().getLastName());
|
||||||
|
text = text.replaceAll("\\{project\\}", notification.getProject().getName());
|
||||||
|
text = text.replaceAll("\\{resource\\}", notification.getResource().getName());
|
||||||
|
text = text.replaceAll("\\{task\\}", notification.getTask().getName());
|
||||||
|
text = text.replaceAll("\\{url\\}", MultipleTabsPlannerController.WELCOME_URL);
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupConnectionProperties(){
|
||||||
|
List<ConnectorProperty> emailConnectorProperties = emailConnectionValidator.getEmailConnectorProperties();
|
||||||
|
|
||||||
|
for (int i = 0; i < emailConnectorProperties.size(); i++){
|
||||||
|
switch (i){
|
||||||
|
case 1: {
|
||||||
|
protocol = emailConnectorProperties.get(1).getValue();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2: {
|
||||||
|
host = emailConnectorProperties.get(2).getValue();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 3: {
|
||||||
|
port = emailConnectorProperties.get(3).getValue();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 4: {
|
||||||
|
sender = emailConnectorProperties.get(4).getValue();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 5: {
|
||||||
|
usrnme = emailConnectorProperties.get(5).getValue();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 6: {
|
||||||
|
psswrd = emailConnectorProperties.get(6).getValue();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
properties = new Properties();
|
||||||
|
|
||||||
|
if ( protocol.equals("STARTTLS") ) {
|
||||||
|
properties.put("mail.smtp.starttls.enable", "true");
|
||||||
|
properties.put("mail.smtp.host", host);
|
||||||
|
properties.put("mail.smtp.socketFactory.port", port);
|
||||||
|
properties.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
|
||||||
|
properties.put("mail.smtp.auth", "true");
|
||||||
|
properties.put("mail.smtp.port", port);
|
||||||
|
}
|
||||||
|
else if ( protocol.equals("SMTP") ) {
|
||||||
|
properties.put("mail.smtp.host", host);
|
||||||
|
properties.put("mail.smtp.port", port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private UserRole getCurrentUserRole(EmailTemplateEnum type){
|
||||||
|
switch (type){
|
||||||
|
case TEMPLATE_TASK_ASSIGNED_TO_RESOURCE: return UserRole.ROLE_EMAIL_TASK_ASSIGNED_TO_RESOURCE;
|
||||||
|
|
||||||
|
case TEMPLATE_RESOURCE_REMOVED_FROM_TASK: return UserRole.ROLE_EMAIL_RESOURCE_REMOVED_FROM_TASK;
|
||||||
|
|
||||||
|
case TEMPLATE_MILESTONE_REACHED: return UserRole.ROLE_EMAIL_MILESTONE_REACHED;
|
||||||
|
|
||||||
|
case TEMPLATE_TODAY_TASK_SHOULD_START: return UserRole.ROLE_EMAIL_TASK_SHOULD_START;
|
||||||
|
|
||||||
|
case TEMPLATE_TODAY_TASK_SHOULD_FINISH: return UserRole.ROLE_EMAIL_TASK_SHOULD_FINISH;
|
||||||
|
|
||||||
|
case TEMPLATE_ENTER_DATA_IN_TIMESHEET: return UserRole.ROLE_EMAIL_TIMESHEET_DATA_MISSING;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,138 @@
|
||||||
|
/*
|
||||||
|
* This file is part of LibrePlan
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 LibrePlan
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.libreplan.importers.notifications;
|
||||||
|
|
||||||
|
import org.libreplan.business.common.daos.IConnectorDAO;
|
||||||
|
import org.libreplan.business.common.entities.Connector;
|
||||||
|
import org.libreplan.business.common.entities.ConnectorProperty;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.mail.MessagingException;
|
||||||
|
import javax.mail.NoSuchProviderException;
|
||||||
|
import javax.mail.Session;
|
||||||
|
import javax.mail.Transport;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate Email Connection properties
|
||||||
|
*
|
||||||
|
* Created by
|
||||||
|
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
|
||||||
|
* on 20.01.2016.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
|
||||||
|
public class EmailConnectionValidator {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IConnectorDAO connectorDAO;
|
||||||
|
|
||||||
|
public boolean validConnection(){
|
||||||
|
List<ConnectorProperty> emailConnectorProperties = getEmailConnectorProperties();
|
||||||
|
|
||||||
|
String protocol = null;
|
||||||
|
String host = null;
|
||||||
|
String port = null;
|
||||||
|
String usrnme = null;
|
||||||
|
String psswrd = null;
|
||||||
|
|
||||||
|
for (int i = 0; i < emailConnectorProperties.size(); i++){
|
||||||
|
switch (i){
|
||||||
|
case 1: {
|
||||||
|
protocol = emailConnectorProperties.get(1).getValue();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2: {
|
||||||
|
host = emailConnectorProperties.get(2).getValue();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 3: {
|
||||||
|
port = emailConnectorProperties.get(3).getValue();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 5: {
|
||||||
|
usrnme = emailConnectorProperties.get(5).getValue();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 6: {
|
||||||
|
psswrd = emailConnectorProperties.get(6).getValue();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set properties of connection
|
||||||
|
Properties properties = new Properties();
|
||||||
|
|
||||||
|
Transport transport = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (protocol.equals("SMTP")) {
|
||||||
|
properties.setProperty("mail.smtp.port", port);
|
||||||
|
properties.setProperty("mail.smtp.host", host);
|
||||||
|
Session session = Session.getInstance(properties, null);
|
||||||
|
|
||||||
|
transport = session.getTransport("smtp");
|
||||||
|
if (usrnme.equals("") && psswrd.equals("")) transport.connect();
|
||||||
|
} else if (protocol.equals("STARTTLS")) {
|
||||||
|
properties.setProperty("mail.smtps.port", port);
|
||||||
|
properties.setProperty("mail.smtps.host", host);
|
||||||
|
Session session = Session.getInstance(properties, null);
|
||||||
|
|
||||||
|
transport = session.getTransport("smtps");
|
||||||
|
if (!usrnme.equals("") && psswrd != null) transport.connect(host, usrnme, psswrd);
|
||||||
|
}
|
||||||
|
if (transport != null && transport.isConnected()) return true;
|
||||||
|
|
||||||
|
} catch (NoSuchProviderException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
catch (MessagingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ConnectorProperty> getEmailConnectorProperties() {
|
||||||
|
|
||||||
|
Connector connector = connectorDAO.findUniqueByName("E-mail");
|
||||||
|
|
||||||
|
return connector.getProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isConnectionActivated(){
|
||||||
|
List<ConnectorProperty> emailConnectorProperties = getEmailConnectorProperties();
|
||||||
|
|
||||||
|
for (ConnectorProperty item : emailConnectorProperties){
|
||||||
|
if ( item.getKey().equals("Activated") )
|
||||||
|
if ( item.getValue().equals("Y") )
|
||||||
|
return true;
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -17,17 +17,20 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.libreplan.importers;
|
package org.libreplan.importers.notifications;
|
||||||
|
|
||||||
|
import org.libreplan.business.email.entities.EmailNotification;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends E-mail to users with data that storing in notification_queue table
|
* Sends E-mail to users with data that storing in notification_queue table
|
||||||
*
|
*
|
||||||
* Created by
|
* Created by
|
||||||
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
|
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
|
||||||
* on 13.10.15.
|
* on 13.10.2015.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public interface ISendEmail {
|
public interface IEmailNotificationJob {
|
||||||
void sendEmail();
|
void sendEmail();
|
||||||
|
boolean composeMessageForUser(EmailNotification notification);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* This file is part of LibrePlan
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 LibrePlan
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.libreplan.importers.notifications.jobs;
|
||||||
|
|
||||||
|
import org.libreplan.importers.notifications.IEmailNotificationJob;
|
||||||
|
import org.libreplan.importers.notifications.realization.SendEmailOnMilestoneReached;
|
||||||
|
import org.quartz.JobExecutionContext;
|
||||||
|
import org.quartz.JobExecutionException;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.scheduling.quartz.QuartzJobBean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends E-mail to users with data that storing in notification_queue table
|
||||||
|
* and that are treat to {@link EmailTemplateEnum.TEMPLATE_MILESTONE_REACHED}
|
||||||
|
*
|
||||||
|
* Created by
|
||||||
|
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
|
||||||
|
* on 20.01.2016.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class SendEmailOnMilestoneReachedJob extends QuartzJobBean {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
|
||||||
|
ApplicationContext applicationContext = (ApplicationContext) context.getJobDetail().
|
||||||
|
getJobDataMap().get("applicationContext");
|
||||||
|
|
||||||
|
IEmailNotificationJob milestoneReached = (SendEmailOnMilestoneReached) applicationContext
|
||||||
|
.getBean("SendEmailOnMilestoneReached");
|
||||||
|
|
||||||
|
milestoneReached.sendEmail();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* This file is part of LibrePlan
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 LibrePlan
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.libreplan.importers.notifications.jobs;
|
||||||
|
|
||||||
|
import org.libreplan.importers.notifications.IEmailNotificationJob;
|
||||||
|
import org.quartz.JobExecutionContext;
|
||||||
|
import org.quartz.JobExecutionException;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.scheduling.quartz.QuartzJobBean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends E-mail to users with data that storing in notification_queue table
|
||||||
|
* and that are treat to {@link EmailTemplateEnum.TEMPLATE_RESOURCE_REMOVED_FROM_TASK}
|
||||||
|
*
|
||||||
|
* Created by
|
||||||
|
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
|
||||||
|
* on 20.01.2016.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class SendEmailOnResourceRemovedFromTaskJob extends QuartzJobBean {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
|
||||||
|
ApplicationContext applicationContext = (ApplicationContext) context.getJobDetail().
|
||||||
|
getJobDataMap().get("applicationContext");
|
||||||
|
|
||||||
|
IEmailNotificationJob resourceRemovedFromTask = (IEmailNotificationJob) applicationContext
|
||||||
|
.getBean("SendEmailOnResourceRemovedFromTask");
|
||||||
|
|
||||||
|
resourceRemovedFromTask.sendEmail();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -17,8 +17,10 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.libreplan.importers;
|
package org.libreplan.importers.notifications.jobs;
|
||||||
|
|
||||||
|
|
||||||
|
import org.libreplan.importers.notifications.IEmailNotificationJob;
|
||||||
import org.quartz.JobExecutionContext;
|
import org.quartz.JobExecutionContext;
|
||||||
import org.quartz.JobExecutionException;
|
import org.quartz.JobExecutionException;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
|
|
@ -26,22 +28,25 @@ import org.springframework.scheduling.quartz.QuartzJobBean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends E-mail to users with data that storing in notification_queue table
|
* Sends E-mail to users with data that storing in notification_queue table
|
||||||
|
* and that are treat to {@link EmailTemplateEnum.TEMPLATE_TASK_ASSIGNED_TO_RESOURCE}
|
||||||
*
|
*
|
||||||
* Created by
|
* Created by
|
||||||
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
|
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
|
||||||
* on 13.10.15.
|
* on 13.10.2015.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class SendEmailJob extends QuartzJobBean {
|
public class SendEmailOnTaskAssignedToResourceJob extends QuartzJobBean {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
|
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
|
||||||
ApplicationContext applicationContext = (ApplicationContext) context.getJobDetail().
|
ApplicationContext applicationContext = (ApplicationContext) context.getJobDetail().
|
||||||
getJobDataMap().get("applicationContext");
|
getJobDataMap().get("applicationContext");
|
||||||
|
|
||||||
ISendEmail sendEmail = (ISendEmail) applicationContext.getBean("sendEmail");
|
IEmailNotificationJob taskAssignedToResource = (IEmailNotificationJob) applicationContext
|
||||||
sendEmail.sendEmail();
|
.getBean("SendEmailOnTaskAssignedToResource");
|
||||||
|
|
||||||
|
taskAssignedToResource.sendEmail();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* This file is part of LibrePlan
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 LibrePlan
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.libreplan.importers.notifications.jobs;
|
||||||
|
|
||||||
|
import org.libreplan.importers.notifications.IEmailNotificationJob;
|
||||||
|
import org.quartz.JobExecutionContext;
|
||||||
|
import org.quartz.JobExecutionException;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.scheduling.quartz.QuartzJobBean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends E-mail to users with data that storing in notification_queue table
|
||||||
|
* and that are treat to {@link EmailTemplateEnum.TEMPLATE_TODAY_TASK_SHOULD_FINISH}
|
||||||
|
*
|
||||||
|
* Created by
|
||||||
|
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
|
||||||
|
* on 20.01.2016.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class SendEmailOnTaskShouldFinishJob extends QuartzJobBean {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
|
||||||
|
ApplicationContext applicationContext = (ApplicationContext) context.getJobDetail().
|
||||||
|
getJobDataMap().get("applicationContext");
|
||||||
|
|
||||||
|
IEmailNotificationJob taskShouldFinish = (IEmailNotificationJob) applicationContext
|
||||||
|
.getBean("SendEmailOnTaskShouldFinish");
|
||||||
|
|
||||||
|
taskShouldFinish.sendEmail();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* This file is part of LibrePlan
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 LibrePlan
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.libreplan.importers.notifications.jobs;
|
||||||
|
|
||||||
|
import org.libreplan.importers.notifications.IEmailNotificationJob;
|
||||||
|
import org.quartz.JobExecutionContext;
|
||||||
|
import org.quartz.JobExecutionException;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.scheduling.quartz.QuartzJobBean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends E-mail to users with data that storing in notification_queue table
|
||||||
|
* and that are treat to {@link EmailTemplateEnum.TEMPLATE_TODAY_TASK_SHOULD_START}
|
||||||
|
*
|
||||||
|
* Created by
|
||||||
|
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
|
||||||
|
* on 20.01.2016.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class SendEmailOnTaskShouldStartJob extends QuartzJobBean {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
|
||||||
|
ApplicationContext applicationContext = (ApplicationContext) context.getJobDetail().
|
||||||
|
getJobDataMap().get("applicationContext");
|
||||||
|
|
||||||
|
IEmailNotificationJob taskShouldStart = (IEmailNotificationJob) applicationContext
|
||||||
|
.getBean("SendEmailOnTaskShouldStart");
|
||||||
|
|
||||||
|
taskShouldStart.sendEmail();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* This file is part of LibrePlan
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 LibrePlan
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.libreplan.importers.notifications.jobs;
|
||||||
|
|
||||||
|
import org.libreplan.importers.notifications.IEmailNotificationJob;
|
||||||
|
import org.quartz.JobExecutionContext;
|
||||||
|
import org.quartz.JobExecutionException;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.scheduling.quartz.QuartzJobBean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends E-mail to users with data that storing in notification_queue table
|
||||||
|
* and that are treat to {@link EmailTemplateEnum.TEMPLATE_ENTER_DATA_IN_TIMESHEET}
|
||||||
|
*
|
||||||
|
* Created by
|
||||||
|
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
|
||||||
|
* on 20.01.2016.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class SendEmailOnTimesheetDataMissingJob extends QuartzJobBean {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
|
||||||
|
ApplicationContext applicationContext = (ApplicationContext) context.getJobDetail().
|
||||||
|
getJobDataMap().get("applicationContext");
|
||||||
|
|
||||||
|
IEmailNotificationJob timesheetMissing = (IEmailNotificationJob) applicationContext
|
||||||
|
.getBean("SendEmailOnTimesheetDataMissing");
|
||||||
|
|
||||||
|
timesheetMissing.sendEmail();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,155 @@
|
||||||
|
/*
|
||||||
|
* This file is part of LibrePlan
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 LibrePlan
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.libreplan.importers.notifications.realization;
|
||||||
|
|
||||||
|
|
||||||
|
import org.joda.time.LocalDate;
|
||||||
|
import org.libreplan.business.common.Configuration;
|
||||||
|
import org.libreplan.business.common.exceptions.InstanceNotFoundException;
|
||||||
|
import org.libreplan.business.email.entities.EmailNotification;
|
||||||
|
import org.libreplan.business.email.entities.EmailTemplateEnum;
|
||||||
|
import org.libreplan.business.planner.daos.ITaskElementDAO;
|
||||||
|
import org.libreplan.business.planner.entities.TaskElement;
|
||||||
|
import org.libreplan.business.users.daos.IUserDAO;
|
||||||
|
import org.libreplan.business.users.entities.User;
|
||||||
|
import org.libreplan.business.users.entities.UserRole;
|
||||||
|
import org.libreplan.importers.notifications.ComposeMessage;
|
||||||
|
import org.libreplan.importers.notifications.EmailConnectionValidator;
|
||||||
|
import org.libreplan.importers.notifications.IEmailNotificationJob;
|
||||||
|
import org.libreplan.web.email.IEmailNotificationModel;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends E-mail to manager user (it writes in responsible field in project properties)
|
||||||
|
* with data that storing in notification_queue table
|
||||||
|
* and that are treat to {@link EmailTemplateEnum.TEMPLATE_MILESTONE_REACHED}
|
||||||
|
* Date will be send on current date equals to deadline date of {@link Milestone}
|
||||||
|
* But it will be only send to Manager (you can assign him in project properties)
|
||||||
|
*
|
||||||
|
* Created by
|
||||||
|
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
|
||||||
|
* on 20.01.2016.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
|
||||||
|
public class SendEmailOnMilestoneReached implements IEmailNotificationJob {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IEmailNotificationModel emailNotificationModel;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ITaskElementDAO taskElementDAO;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IUserDAO userDAO;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ComposeMessage composeMessage;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
EmailConnectionValidator emailConnectionValidator;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendEmail() {
|
||||||
|
// Gathering data
|
||||||
|
checkMilestoneDate();
|
||||||
|
|
||||||
|
if ( Configuration.isEmailSendingEnabled() ){
|
||||||
|
|
||||||
|
if ( emailConnectionValidator.isConnectionActivated() )
|
||||||
|
|
||||||
|
if ( emailConnectionValidator.validConnection() ){
|
||||||
|
|
||||||
|
List<EmailNotification> notifications = emailNotificationModel
|
||||||
|
.getAllByType(EmailTemplateEnum.TEMPLATE_MILESTONE_REACHED);
|
||||||
|
|
||||||
|
for (int i = 0; i < notifications.size(); i++)
|
||||||
|
if ( composeMessageForUser(notifications.get(i)) )
|
||||||
|
deleteSingleNotification(notifications.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean composeMessageForUser(EmailNotification notification) {
|
||||||
|
return composeMessage.composeMessageForUser(notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteSingleNotification(EmailNotification notification){
|
||||||
|
emailNotificationModel.deleteById(notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendEmailNotificationToManager(TaskElement item){
|
||||||
|
emailNotificationModel.setNewObject();
|
||||||
|
emailNotificationModel.setType(EmailTemplateEnum.TEMPLATE_MILESTONE_REACHED);
|
||||||
|
emailNotificationModel.setUpdated(new Date());
|
||||||
|
|
||||||
|
String responsible = "";
|
||||||
|
if ( item.getParent().getOrderElement().getOrder().getResponsible() != null )
|
||||||
|
responsible = item.getParent().getOrderElement().getOrder().getResponsible();
|
||||||
|
|
||||||
|
User user = null;
|
||||||
|
try {
|
||||||
|
user = userDAO.findByLoginName(responsible);
|
||||||
|
} catch (InstanceNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( user.getWorker() != null && user.isInRole(UserRole.ROLE_EMAIL_MILESTONE_REACHED) ) {
|
||||||
|
emailNotificationModel.setResource(user.getWorker());
|
||||||
|
emailNotificationModel.setTask(item);
|
||||||
|
emailNotificationModel.setProject(item.getParent());
|
||||||
|
emailNotificationModel.confirmSave();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkMilestoneDate() {
|
||||||
|
List<TaskElement> list = taskElementDAO.getTaskElementsWithMilestones();
|
||||||
|
|
||||||
|
LocalDate date = new LocalDate();
|
||||||
|
int currentYear = date.getYear();
|
||||||
|
int currentMonth = date.getMonthOfYear();
|
||||||
|
int currentDay = date.getDayOfMonth();
|
||||||
|
|
||||||
|
for (TaskElement item : list){
|
||||||
|
if ( item.getDeadline() != null ){
|
||||||
|
LocalDate deadline = item.getDeadline();
|
||||||
|
int deadlineYear = deadline.getYear();
|
||||||
|
int deadlineMonth = deadline.getMonthOfYear();
|
||||||
|
int deadlineDay = deadline.getDayOfMonth();
|
||||||
|
|
||||||
|
if (currentYear == deadlineYear &&
|
||||||
|
currentMonth == deadlineMonth &&
|
||||||
|
currentDay == deadlineDay)
|
||||||
|
sendEmailNotificationToManager(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* This file is part of LibrePlan
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 LibrePlan
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.libreplan.importers.notifications.realization;
|
||||||
|
|
||||||
|
|
||||||
|
import org.libreplan.business.common.Configuration;
|
||||||
|
import org.libreplan.business.email.entities.EmailNotification;
|
||||||
|
import org.libreplan.business.email.entities.EmailTemplateEnum;
|
||||||
|
import org.libreplan.importers.notifications.ComposeMessage;
|
||||||
|
import org.libreplan.importers.notifications.EmailConnectionValidator;
|
||||||
|
import org.libreplan.importers.notifications.IEmailNotificationJob;
|
||||||
|
import org.libreplan.web.email.IEmailNotificationModel;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends E-mail to users with data that storing in notification_queue table
|
||||||
|
* and that are treat to TEMPLATE_RESOUCE_REMOVED_FROM_TASK
|
||||||
|
* Data will be send if resource has been removed from task (in resource allocation)
|
||||||
|
*
|
||||||
|
* Created by
|
||||||
|
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
|
||||||
|
* on 20.01.2016.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
|
||||||
|
public class SendEmailOnResourceRemovedFromTask implements IEmailNotificationJob {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IEmailNotificationModel emailNotificationModel;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private EmailConnectionValidator emailConnectionValidator;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ComposeMessage composeMessage;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendEmail() {
|
||||||
|
// At this time all data have gathered, if it exists of course
|
||||||
|
|
||||||
|
if ( Configuration.isEmailSendingEnabled() ){
|
||||||
|
|
||||||
|
if ( emailConnectionValidator.isConnectionActivated() )
|
||||||
|
|
||||||
|
if ( emailConnectionValidator.validConnection() ){
|
||||||
|
|
||||||
|
List<EmailNotification> notifications = emailNotificationModel
|
||||||
|
.getAllByType(EmailTemplateEnum.TEMPLATE_RESOURCE_REMOVED_FROM_TASK);
|
||||||
|
|
||||||
|
for (int i = 0; i < notifications.size(); i++)
|
||||||
|
if ( composeMessageForUser(notifications.get(i)) )
|
||||||
|
deleteSingleNotification(notifications.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean composeMessageForUser(EmailNotification notification) {
|
||||||
|
return composeMessage.composeMessageForUser(notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteSingleNotification(EmailNotification notification){
|
||||||
|
emailNotificationModel.deleteById(notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* This file is part of LibrePlan
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015 LibrePlan
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.libreplan.importers.notifications.realization;
|
||||||
|
|
||||||
|
|
||||||
|
import org.libreplan.business.common.Configuration;
|
||||||
|
import org.libreplan.business.email.entities.EmailNotification;
|
||||||
|
import org.libreplan.business.email.entities.EmailTemplateEnum;
|
||||||
|
import org.libreplan.importers.notifications.ComposeMessage;
|
||||||
|
import org.libreplan.importers.notifications.EmailConnectionValidator;
|
||||||
|
import org.libreplan.importers.notifications.IEmailNotificationJob;
|
||||||
|
import org.libreplan.web.email.IEmailNotificationModel;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends E-mail to users with data that storing in notification_queue table
|
||||||
|
* and that are treat to {@link EmailTemplateEnum.TEMPLATE_ENTER_DATA_IN_TIMESHEET}
|
||||||
|
* Data will be send after user will be assigned to some task.
|
||||||
|
*
|
||||||
|
* Created by
|
||||||
|
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
|
||||||
|
* on 13.10.2015.
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
|
||||||
|
public class SendEmailOnTaskAssignedToResource implements IEmailNotificationJob {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IEmailNotificationModel emailNotificationModel;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private EmailConnectionValidator emailConnectionValidator;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ComposeMessage composeMessage;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public void sendEmail() {
|
||||||
|
if ( Configuration.isEmailSendingEnabled() ){
|
||||||
|
|
||||||
|
if ( emailConnectionValidator.isConnectionActivated() )
|
||||||
|
|
||||||
|
if ( emailConnectionValidator.validConnection() ){
|
||||||
|
|
||||||
|
List<EmailNotification> notifications = emailNotificationModel
|
||||||
|
.getAllByType(EmailTemplateEnum.TEMPLATE_TASK_ASSIGNED_TO_RESOURCE);
|
||||||
|
|
||||||
|
for (int i = 0; i < notifications.size(); i++)
|
||||||
|
if ( composeMessageForUser(notifications.get(i)) )
|
||||||
|
deleteSingleNotification(notifications.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean composeMessageForUser(EmailNotification notification) {
|
||||||
|
return composeMessage.composeMessageForUser(notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteSingleNotification(EmailNotification notification){
|
||||||
|
emailNotificationModel.deleteById(notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,145 @@
|
||||||
|
/*
|
||||||
|
* This file is part of LibrePlan
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 LibrePlan
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.libreplan.importers.notifications.realization;
|
||||||
|
|
||||||
|
|
||||||
|
import org.libreplan.business.common.Configuration;
|
||||||
|
import org.libreplan.business.email.entities.EmailNotification;
|
||||||
|
import org.libreplan.business.email.entities.EmailTemplateEnum;
|
||||||
|
import org.libreplan.business.planner.daos.ITaskElementDAO;
|
||||||
|
import org.libreplan.business.planner.entities.ResourceAllocation;
|
||||||
|
import org.libreplan.business.planner.entities.TaskElement;
|
||||||
|
import org.libreplan.business.resources.entities.Resource;
|
||||||
|
import org.libreplan.importers.notifications.ComposeMessage;
|
||||||
|
import org.libreplan.importers.notifications.EmailConnectionValidator;
|
||||||
|
import org.libreplan.importers.notifications.IEmailNotificationJob;
|
||||||
|
import org.libreplan.web.email.IEmailNotificationModel;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends E-mail to users with data that storing in notification_queue table
|
||||||
|
* and that are treat to {@link EmailTemplateEnum.TEMPLATE_TODAY_TASK_SHOULD_FINISH}
|
||||||
|
* Data will be send when current day equals to finish date.
|
||||||
|
*
|
||||||
|
* Created by
|
||||||
|
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
|
||||||
|
* on 21.01.2016.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
|
||||||
|
public class SendEmailOnTaskShouldFinish implements IEmailNotificationJob {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IEmailNotificationModel emailNotificationModel;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ITaskElementDAO taskElementDAO;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ComposeMessage composeMessage;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private EmailConnectionValidator emailConnectionValidator;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendEmail() {
|
||||||
|
// Gather data for email sending
|
||||||
|
taskShouldFinish();
|
||||||
|
|
||||||
|
if ( Configuration.isEmailSendingEnabled() ){
|
||||||
|
|
||||||
|
if ( emailConnectionValidator.isConnectionActivated() )
|
||||||
|
|
||||||
|
if ( emailConnectionValidator.validConnection() ){
|
||||||
|
|
||||||
|
List<EmailNotification> notifications = emailNotificationModel
|
||||||
|
.getAllByType(EmailTemplateEnum.TEMPLATE_TODAY_TASK_SHOULD_FINISH);
|
||||||
|
|
||||||
|
for (int i = 0; i < notifications.size(); i++)
|
||||||
|
if ( composeMessageForUser(notifications.get(i)) )
|
||||||
|
deleteSingleNotification(notifications.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean composeMessageForUser(EmailNotification notification) {
|
||||||
|
return composeMessage.composeMessageForUser(notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteSingleNotification(EmailNotification notification){
|
||||||
|
emailNotificationModel.deleteById(notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void taskShouldFinish() {
|
||||||
|
// Check if current date equals with item date
|
||||||
|
Date date = new Date();
|
||||||
|
int currentYear = date.getYear();
|
||||||
|
int currentMonth = date.getMonth();
|
||||||
|
int currentDay = date.getDay();
|
||||||
|
|
||||||
|
List<TaskElement> tasks = taskElementDAO.getTaskElementsWithParentsWithoutMilestones();
|
||||||
|
for (TaskElement item : tasks){
|
||||||
|
Date endDate = item.getEndDate();
|
||||||
|
int endYear = endDate.getYear();
|
||||||
|
int endMonth = endDate.getMonth();
|
||||||
|
int endDay = endDate.getDay();
|
||||||
|
|
||||||
|
if ( currentYear == endYear &&
|
||||||
|
currentMonth == endMonth &&
|
||||||
|
currentDay == endDay ){
|
||||||
|
// Get all resources for current task and send them email notification
|
||||||
|
sendEmailNotificationAboutTaskShouldFinish(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void sendEmailNotificationAboutTaskShouldFinish(TaskElement item){
|
||||||
|
List<ResourceAllocation<?>> list = new ArrayList<ResourceAllocation<?>>();
|
||||||
|
list.addAll(item.getAllResourceAllocations());
|
||||||
|
|
||||||
|
List<Resource> resources = new ArrayList<Resource>();
|
||||||
|
for (ResourceAllocation<?> allocation : list)
|
||||||
|
resources.add(allocation.getAssociatedResources().get(0));
|
||||||
|
|
||||||
|
for (Resource resourceItem : resources){
|
||||||
|
emailNotificationModel.setNewObject();
|
||||||
|
emailNotificationModel.setType(EmailTemplateEnum.TEMPLATE_TODAY_TASK_SHOULD_FINISH);
|
||||||
|
emailNotificationModel.setUpdated(new Date());
|
||||||
|
emailNotificationModel.setResource(resourceItem);
|
||||||
|
emailNotificationModel.setTask(item);
|
||||||
|
emailNotificationModel.setProject(item.getParent());
|
||||||
|
emailNotificationModel.confirmSave();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,144 @@
|
||||||
|
/*
|
||||||
|
* This file is part of LibrePlan
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 LibrePlan
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.libreplan.importers.notifications.realization;
|
||||||
|
|
||||||
|
import org.libreplan.business.common.Configuration;
|
||||||
|
|
||||||
|
import org.libreplan.business.email.entities.EmailNotification;
|
||||||
|
import org.libreplan.business.email.entities.EmailTemplateEnum;
|
||||||
|
import org.libreplan.business.planner.daos.ITaskElementDAO;
|
||||||
|
import org.libreplan.business.planner.entities.ResourceAllocation;
|
||||||
|
import org.libreplan.business.planner.entities.TaskElement;
|
||||||
|
import org.libreplan.business.resources.entities.Resource;
|
||||||
|
import org.libreplan.importers.notifications.ComposeMessage;
|
||||||
|
import org.libreplan.importers.notifications.EmailConnectionValidator;
|
||||||
|
import org.libreplan.importers.notifications.IEmailNotificationJob;
|
||||||
|
import org.libreplan.web.email.IEmailNotificationModel;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends E-mail users with data that storing in notification_queue table
|
||||||
|
* and that are treat to {@link EmailTemplateEnum.TEMPLATE_TODAY_TASK_SHOULD_START}
|
||||||
|
* Data will be send if current data equals to start date.
|
||||||
|
*
|
||||||
|
* Created by
|
||||||
|
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
|
||||||
|
* on 20.01.2016.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
|
||||||
|
public class SendEmailOnTaskShouldStart implements IEmailNotificationJob {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IEmailNotificationModel emailNotificationModel;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ITaskElementDAO taskElementDAO;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ComposeMessage composeMessage;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private EmailConnectionValidator emailConnectionValidator;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendEmail() {
|
||||||
|
// Gather data
|
||||||
|
taskShouldStart();
|
||||||
|
|
||||||
|
if ( Configuration.isEmailSendingEnabled() ){
|
||||||
|
|
||||||
|
if ( emailConnectionValidator.isConnectionActivated() )
|
||||||
|
|
||||||
|
if ( emailConnectionValidator.validConnection() ){
|
||||||
|
|
||||||
|
List<EmailNotification> notifications = emailNotificationModel
|
||||||
|
.getAllByType(EmailTemplateEnum.TEMPLATE_TODAY_TASK_SHOULD_START);
|
||||||
|
|
||||||
|
for (int i = 0; i < notifications.size(); i++)
|
||||||
|
if ( composeMessageForUser(notifications.get(i)) )
|
||||||
|
deleteSingleNotification(notifications.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean composeMessageForUser(EmailNotification notification) {
|
||||||
|
return composeMessage.composeMessageForUser(notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteSingleNotification(EmailNotification notification){
|
||||||
|
emailNotificationModel.deleteById(notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void taskShouldStart() {
|
||||||
|
// Check if current date equals with item date
|
||||||
|
Date date = new Date();
|
||||||
|
int currentYear = date.getYear();
|
||||||
|
int currentMonth = date.getMonth();
|
||||||
|
int currentDay = date.getDay();
|
||||||
|
|
||||||
|
List<TaskElement> tasks = taskElementDAO.getTaskElementsWithParentsWithoutMilestones();
|
||||||
|
for (TaskElement item : tasks){
|
||||||
|
Date startDate = item.getStartDate();
|
||||||
|
int startYear = startDate.getYear();
|
||||||
|
int startMonth = startDate.getMonth();
|
||||||
|
int startDay = startDate.getDay();
|
||||||
|
|
||||||
|
if ( currentYear == startYear &&
|
||||||
|
currentMonth == startMonth &&
|
||||||
|
currentDay == startDay){
|
||||||
|
// Get all resources for current task and send them email notification
|
||||||
|
sendEmailNotificationAboutTaskShouldStart(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendEmailNotificationAboutTaskShouldStart(TaskElement item){
|
||||||
|
List<ResourceAllocation<?>> list = new ArrayList<ResourceAllocation<?>>();
|
||||||
|
list.addAll(item.getAllResourceAllocations());
|
||||||
|
|
||||||
|
List<Resource> resources = new ArrayList<Resource>();
|
||||||
|
for (ResourceAllocation<?> allocation : list)
|
||||||
|
resources.add(allocation.getAssociatedResources().get(0));
|
||||||
|
|
||||||
|
for (Resource resourceItem : resources){
|
||||||
|
emailNotificationModel.setNewObject();
|
||||||
|
emailNotificationModel.setType(EmailTemplateEnum.TEMPLATE_TODAY_TASK_SHOULD_START);
|
||||||
|
emailNotificationModel.setUpdated(new Date());
|
||||||
|
emailNotificationModel.setResource(resourceItem);
|
||||||
|
emailNotificationModel.setTask(item);
|
||||||
|
emailNotificationModel.setProject(item.getParent());
|
||||||
|
emailNotificationModel.confirmSave();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,254 @@
|
||||||
|
/*
|
||||||
|
* This file is part of LibrePlan
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 LibrePlan
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.libreplan.importers.notifications.realization;
|
||||||
|
|
||||||
|
|
||||||
|
import org.joda.time.LocalDate;
|
||||||
|
import org.libreplan.business.common.Configuration;
|
||||||
|
import org.libreplan.business.common.daos.IConfigurationDAO;
|
||||||
|
import org.libreplan.business.common.entities.PersonalTimesheetsPeriodicityEnum;
|
||||||
|
|
||||||
|
import org.libreplan.business.email.entities.EmailNotification;
|
||||||
|
import org.libreplan.business.email.entities.EmailTemplateEnum;
|
||||||
|
import org.libreplan.business.orders.entities.OrderElement;
|
||||||
|
|
||||||
|
import org.libreplan.business.resources.entities.Resource;
|
||||||
|
import org.libreplan.business.resources.entities.Worker;
|
||||||
|
|
||||||
|
import org.libreplan.business.users.entities.User;
|
||||||
|
import org.libreplan.business.workingday.EffortDuration;
|
||||||
|
import org.libreplan.business.workingday.IntraDayDate;
|
||||||
|
import org.libreplan.business.workreports.daos.IWorkReportDAO;
|
||||||
|
import org.libreplan.business.workreports.entities.WorkReport;
|
||||||
|
import org.libreplan.business.workreports.entities.WorkReportLine;
|
||||||
|
import org.libreplan.business.workreports.entities.WorkReportType;
|
||||||
|
import org.libreplan.importers.notifications.ComposeMessage;
|
||||||
|
import org.libreplan.importers.notifications.EmailConnectionValidator;
|
||||||
|
import org.libreplan.importers.notifications.IEmailNotificationJob;
|
||||||
|
import org.libreplan.web.calendars.BaseCalendarModel;
|
||||||
|
import org.libreplan.web.common.Util;
|
||||||
|
import org.libreplan.web.email.IEmailNotificationModel;
|
||||||
|
import org.libreplan.web.users.IUserModel;
|
||||||
|
import org.libreplan.web.users.dashboard.PersonalTimesheetDTO;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends E-mail to users with data that storing in notification_queue table
|
||||||
|
* and that are treat to {@link EmailTemplateEnum.TEMPLATE_ENTER_DATA_IN_TIMESHEET}
|
||||||
|
* Data will be send for bound users with empty timesheet lines.
|
||||||
|
*
|
||||||
|
* Created by
|
||||||
|
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
|
||||||
|
* on 20.01.2016.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
|
||||||
|
public class SendEmailOnTimesheetDataMissing implements IEmailNotificationJob {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IEmailNotificationModel emailNotificationModel;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IConfigurationDAO configurationDAO;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IWorkReportDAO workReportDAO;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IUserModel userModel;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ComposeMessage composeMessage;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private EmailConnectionValidator emailConnectionValidator;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public void sendEmail() {
|
||||||
|
checkTimesheet();
|
||||||
|
|
||||||
|
if ( Configuration.isEmailSendingEnabled() ){
|
||||||
|
|
||||||
|
if ( emailConnectionValidator.isConnectionActivated() )
|
||||||
|
|
||||||
|
if ( emailConnectionValidator.validConnection() ){
|
||||||
|
|
||||||
|
List<EmailNotification> notifications = emailNotificationModel
|
||||||
|
.getAllByType(EmailTemplateEnum.TEMPLATE_ENTER_DATA_IN_TIMESHEET);
|
||||||
|
|
||||||
|
for (int i = 0; i < notifications.size(); i++)
|
||||||
|
if ( composeMessageForUser(notifications.get(i)) )
|
||||||
|
deleteSingleNotification(notifications.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean composeMessageForUser(EmailNotification notification) {
|
||||||
|
return composeMessage.composeMessageForUser(notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteSingleNotification(EmailNotification notification){
|
||||||
|
emailNotificationModel.deleteById(notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void checkTimesheet() {
|
||||||
|
List<User> list = getPersonalTimesheets();
|
||||||
|
addRowsToNotificationTable(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
private List<User> getPersonalTimesheets() {
|
||||||
|
List<PersonalTimesheetDTO> personalTimesheetDTO = new ArrayList<PersonalTimesheetDTO>();
|
||||||
|
List<User> usersWithoutTimesheets = new ArrayList<User>();
|
||||||
|
List<User> users = userModel.getUsers();
|
||||||
|
|
||||||
|
for (User user : users)
|
||||||
|
if (user.isBound()) {
|
||||||
|
Resource resource = user.getWorker();
|
||||||
|
BaseCalendarModel.forceLoadBaseCalendar(resource.getCalendar());
|
||||||
|
|
||||||
|
LocalDate activationDate = getActivationDate(user.getWorker());
|
||||||
|
LocalDate currentDate = new LocalDate();
|
||||||
|
personalTimesheetDTO.addAll(getPersonalTimesheets(user.getWorker(), activationDate,
|
||||||
|
currentDate.plusMonths(1), getPersonalTimesheetsPeriodicity()));
|
||||||
|
|
||||||
|
for(PersonalTimesheetDTO item : personalTimesheetDTO){
|
||||||
|
WorkReport workReport = item.getWorkReport();
|
||||||
|
if ( item.getTasksNumber() == 0 && workReport == null )
|
||||||
|
if ( !usersWithoutTimesheets.contains(user) )
|
||||||
|
usersWithoutTimesheets.add(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
personalTimesheetDTO.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
return usersWithoutTimesheets;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addRowsToNotificationTable(List<User> users){
|
||||||
|
for (User user : users){
|
||||||
|
emailNotificationModel.setNewObject();
|
||||||
|
emailNotificationModel.setResource(user.getWorker());
|
||||||
|
emailNotificationModel.setType(EmailTemplateEnum.TEMPLATE_ENTER_DATA_IN_TIMESHEET);
|
||||||
|
emailNotificationModel.setUpdated(new Date());
|
||||||
|
emailNotificationModel.confirmSave();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<PersonalTimesheetDTO> getPersonalTimesheets(Resource resource,
|
||||||
|
LocalDate start, LocalDate end,
|
||||||
|
PersonalTimesheetsPeriodicityEnum periodicity) {
|
||||||
|
start = periodicity.getStart(start);
|
||||||
|
end = periodicity.getEnd(end);
|
||||||
|
int items = periodicity.getItemsBetween(start, end);
|
||||||
|
|
||||||
|
List<PersonalTimesheetDTO> result = new ArrayList<PersonalTimesheetDTO>();
|
||||||
|
|
||||||
|
// In decreasing order to provide a list sorted with the more recent
|
||||||
|
// personal timesheets at the beginning
|
||||||
|
for (int i = items; i >= 0; i--) {
|
||||||
|
LocalDate date = periodicity.getDateForItemFromDate(i, start);
|
||||||
|
|
||||||
|
WorkReport workReport = getWorkReport(resource, date, periodicity);
|
||||||
|
|
||||||
|
EffortDuration hours = EffortDuration.zero();
|
||||||
|
int tasksNumber = 0;
|
||||||
|
if (workReport != null) {
|
||||||
|
hours = workReport.getTotalEffortDuration();
|
||||||
|
tasksNumber = getNumberOfOrderElementsWithTrackedTime(workReport);
|
||||||
|
}
|
||||||
|
|
||||||
|
result.add(new PersonalTimesheetDTO(date, workReport,
|
||||||
|
getResourceCapcity(resource, date, periodicity), hours,
|
||||||
|
tasksNumber));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
private LocalDate getActivationDate(Worker worker) {
|
||||||
|
return worker.getCalendar().getFistCalendarAvailability()
|
||||||
|
.getStartDate();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private PersonalTimesheetsPeriodicityEnum getPersonalTimesheetsPeriodicity() {
|
||||||
|
return configurationDAO.getConfiguration()
|
||||||
|
.getPersonalTimesheetsPeriodicity();
|
||||||
|
}
|
||||||
|
private WorkReport getWorkReport(Resource resource, LocalDate date,
|
||||||
|
PersonalTimesheetsPeriodicityEnum periodicity) {
|
||||||
|
WorkReport workReport = workReportDAO.getPersonalTimesheetWorkReport(
|
||||||
|
resource, date, periodicity);
|
||||||
|
forceLoad(workReport);
|
||||||
|
return workReport;
|
||||||
|
}
|
||||||
|
private void forceLoad(WorkReport workReport) {
|
||||||
|
if (workReport != null) {
|
||||||
|
WorkReportType workReportType = workReport.getWorkReportType();
|
||||||
|
workReportType.getLineFields().size();
|
||||||
|
workReportType.getWorkReportLabelTypeAssigments().size();
|
||||||
|
workReportType.getHeadingFields().size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private int getNumberOfOrderElementsWithTrackedTime(WorkReport workReport) {
|
||||||
|
if (workReport == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<OrderElement> orderElements = new ArrayList<OrderElement>();
|
||||||
|
for (WorkReportLine line : workReport.getWorkReportLines()) {
|
||||||
|
if (!line.getEffort().isZero()) {
|
||||||
|
OrderElement orderElement = line.getOrderElement();
|
||||||
|
if (!Util.contains(orderElements, orderElement)) {
|
||||||
|
orderElements.add(orderElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return orderElements.size();
|
||||||
|
}
|
||||||
|
private EffortDuration getResourceCapcity(Resource resource, LocalDate date,
|
||||||
|
PersonalTimesheetsPeriodicityEnum periodicity) {
|
||||||
|
LocalDate start = periodicity.getStart(date);
|
||||||
|
LocalDate end = periodicity.getEnd(date);
|
||||||
|
|
||||||
|
EffortDuration capacity = EffortDuration.zero();
|
||||||
|
for (LocalDate day = start; day.compareTo(end) <= 0; day = day
|
||||||
|
.plusDays(1)) {
|
||||||
|
capacity = capacity.plus(resource.getCalendar().getCapacityOn(
|
||||||
|
IntraDayDate.PartialDay.wholeDay(day)));
|
||||||
|
}
|
||||||
|
return capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -31,8 +31,6 @@ import java.util.ArrayList;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.ConcurrentModificationException;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
|
@ -1365,6 +1363,11 @@ public class ConfigurationController extends GenericForwardComposer {
|
||||||
emailPasswordTextbox.getValue().length() != 0 &&
|
emailPasswordTextbox.getValue().length() != 0 &&
|
||||||
emailSenderTextbox.getValue().matches("^\\S+@\\S+\\.\\S+$") )
|
emailSenderTextbox.getValue().matches("^\\S+@\\S+\\.\\S+$") )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if ( protocolsCombobox != null && protocolsCombobox.getSelectedItem() != null ){
|
||||||
|
if ( protocolsCombobox.getSelectedItem().getLabel().equals("SMTP") )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,10 +35,11 @@ import org.libreplan.importers.IImportRosterFromTim;
|
||||||
import org.libreplan.importers.IJiraOrderElementSynchronizer;
|
import org.libreplan.importers.IJiraOrderElementSynchronizer;
|
||||||
import org.libreplan.importers.ISchedulerManager;
|
import org.libreplan.importers.ISchedulerManager;
|
||||||
import org.libreplan.importers.SynchronizationInfo;
|
import org.libreplan.importers.SynchronizationInfo;
|
||||||
import org.libreplan.importers.ISendEmail;
|
import org.libreplan.importers.notifications.IEmailNotificationJob;
|
||||||
import org.libreplan.web.common.concurrentdetection.OnConcurrentModification;
|
import org.libreplan.web.common.concurrentdetection.OnConcurrentModification;
|
||||||
import org.quartz.SchedulerException;
|
import org.quartz.SchedulerException;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
import org.springframework.context.annotation.Scope;
|
import org.springframework.context.annotation.Scope;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
@ -51,6 +52,7 @@ import static org.libreplan.web.I18nHelper._;
|
||||||
*
|
*
|
||||||
* @author Manuel Rego Casasnovas <rego@igalia.com>
|
* @author Manuel Rego Casasnovas <rego@igalia.com>
|
||||||
* @author Miciele Ghiorghis <m.ghiorghis@antoniusziekenhuis.nl>
|
* @author Miciele Ghiorghis <m.ghiorghis@antoniusziekenhuis.nl>
|
||||||
|
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
|
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
|
||||||
|
|
@ -79,8 +81,30 @@ public class JobSchedulerModel implements IJobSchedulerModel {
|
||||||
|
|
||||||
private List<SynchronizationInfo> synchronizationInfos;
|
private List<SynchronizationInfo> synchronizationInfos;
|
||||||
|
|
||||||
|
@Qualifier("sendEmailOnTaskAssignedToResource")
|
||||||
@Autowired
|
@Autowired
|
||||||
private ISendEmail email;
|
private IEmailNotificationJob taskAssignedToResource;
|
||||||
|
|
||||||
|
@Qualifier("sendEmailOnMilestoneReached")
|
||||||
|
@Autowired
|
||||||
|
private IEmailNotificationJob milestoneReached;
|
||||||
|
|
||||||
|
@Qualifier("sendEmailOnResourceRemovedFromTask")
|
||||||
|
@Autowired
|
||||||
|
private IEmailNotificationJob resourceRemovedFromTask;
|
||||||
|
|
||||||
|
@Qualifier("sendEmailOnTaskShouldStart")
|
||||||
|
@Autowired
|
||||||
|
private IEmailNotificationJob taskShouldStart;
|
||||||
|
|
||||||
|
@Qualifier("sendEmailOnTaskShouldFinish")
|
||||||
|
@Autowired
|
||||||
|
private IEmailNotificationJob taskShouldFinish;
|
||||||
|
|
||||||
|
@Qualifier("sendEmailOnTimesheetDataMissing")
|
||||||
|
@Autowired
|
||||||
|
private IEmailNotificationJob timesheetDataMissing;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
|
|
@ -112,10 +136,40 @@ public class JobSchedulerModel implements IJobSchedulerModel {
|
||||||
.syncOrderElementsWithJiraIssues();
|
.syncOrderElementsWithJiraIssues();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ( name.equals(JobClassNameEnum.SEND_EMAIL_JOB.getName()) ) {
|
if ( name.equals(JobClassNameEnum.SEND_EMAIL_TASK_ASSIGNED_TO_RESOURCE.getName()) ) {
|
||||||
synchronizationInfos = new ArrayList<SynchronizationInfo>();
|
synchronizationInfos = new ArrayList<SynchronizationInfo>();
|
||||||
synchronizationInfos.add(new SynchronizationInfo(_("Send E-mail")));
|
synchronizationInfos.add(new SynchronizationInfo(_("Task assigned to resource emails")));
|
||||||
email.sendEmail();
|
taskAssignedToResource.sendEmail();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( name.equals(JobClassNameEnum.SEND_EMAIL_RESOURCE_REMOVED_FROM_TASK.getName()) ) {
|
||||||
|
synchronizationInfos = new ArrayList<SynchronizationInfo>();
|
||||||
|
synchronizationInfos.add(new SynchronizationInfo(_("Resource removed from task")));
|
||||||
|
resourceRemovedFromTask.sendEmail();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( name.equals(JobClassNameEnum.SEND_EMAIL_MILESTONE_REACHED.getName()) ) {
|
||||||
|
synchronizationInfos = new ArrayList<SynchronizationInfo>();
|
||||||
|
synchronizationInfos.add(new SynchronizationInfo(_("Milestone reached")));
|
||||||
|
milestoneReached.sendEmail();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( name.equals(JobClassNameEnum.SEND_EMAIL_TASK_SHOULD_START.getName()) ) {
|
||||||
|
synchronizationInfos = new ArrayList<SynchronizationInfo>();
|
||||||
|
synchronizationInfos.add(new SynchronizationInfo(_("Task should start")));
|
||||||
|
taskShouldStart.sendEmail();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( name.equals(JobClassNameEnum.SEND_EMAIL_TASK_SHOULD_FINISH.getName()) ) {
|
||||||
|
synchronizationInfos = new ArrayList<SynchronizationInfo>();
|
||||||
|
synchronizationInfos.add(new SynchronizationInfo(_("Task should finish")));
|
||||||
|
taskShouldFinish.sendEmail();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( name.equals(JobClassNameEnum.SEND_EMAIL_TIMESHEET_DATA_MISSING.getName()) ) {
|
||||||
|
synchronizationInfos = new ArrayList<SynchronizationInfo>();
|
||||||
|
synchronizationInfos.add(new SynchronizationInfo(_("Timesheet data missing")));
|
||||||
|
timesheetDataMissing.sendEmail();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ import java.util.List;
|
||||||
*
|
*
|
||||||
* Created by
|
* Created by
|
||||||
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
|
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
|
||||||
* on 17.12.15.
|
* on 17.12.2015.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,7 @@ import org.zkoss.zul.Window;
|
||||||
* @author Manuel Rego Casasnovas <mrego@igalia.com>
|
* @author Manuel Rego Casasnovas <mrego@igalia.com>
|
||||||
* @author Diego Pino Garcia <dpino@igalia.com>
|
* @author Diego Pino Garcia <dpino@igalia.com>
|
||||||
* @author Javier Moran Rua <jmoran@igalia.com>
|
* @author Javier Moran Rua <jmoran@igalia.com>
|
||||||
|
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
|
||||||
*/
|
*/
|
||||||
@org.springframework.stereotype.Component("resourceAllocationController")
|
@org.springframework.stereotype.Component("resourceAllocationController")
|
||||||
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
|
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
|
||||||
|
|
@ -315,6 +316,12 @@ public class ResourceAllocationController extends GenericForwardComposer {
|
||||||
try {
|
try {
|
||||||
allocationSelector.addChoosen();
|
allocationSelector.addChoosen();
|
||||||
} finally {
|
} finally {
|
||||||
|
// For email notification feature
|
||||||
|
int rowsSize = allocationRows.getCurrentRows().size();
|
||||||
|
editTaskController.getTaskPropertiesController().listToAdd
|
||||||
|
.add(allocationRows.getCurrentRows().get(rowsSize - 1).getAssociatedResources().get(0));
|
||||||
|
editTaskController.getTaskPropertiesController().setResourcesAdded(true);
|
||||||
|
|
||||||
tbResourceAllocation.setSelected(true);
|
tbResourceAllocation.setSelected(true);
|
||||||
applyButton.setVisible(true);
|
applyButton.setVisible(true);
|
||||||
allocationSelector.clearAll();
|
allocationSelector.clearAll();
|
||||||
|
|
@ -618,6 +625,8 @@ public class ResourceAllocationController extends GenericForwardComposer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEvent(Event event) {
|
public void onEvent(Event event) {
|
||||||
|
editTaskController.getTaskPropertiesController().getListToDelete()
|
||||||
|
.add(data.getAssociatedResources().get(0));
|
||||||
removeAllocation(data);
|
removeAllocation(data);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,6 @@ import org.libreplan.business.planner.entities.GenericResourceAllocation;
|
||||||
import org.libreplan.business.planner.entities.IMoneyCostCalculator;
|
import org.libreplan.business.planner.entities.IMoneyCostCalculator;
|
||||||
import org.libreplan.business.planner.entities.ResourceAllocation;
|
import org.libreplan.business.planner.entities.ResourceAllocation;
|
||||||
import org.libreplan.business.planner.entities.ResourceAllocation.IVisitor;
|
import org.libreplan.business.planner.entities.ResourceAllocation.IVisitor;
|
||||||
import org.libreplan.business.planner.entities.HoursCostCalculator;
|
|
||||||
import org.libreplan.business.planner.entities.SpecificResourceAllocation;
|
import org.libreplan.business.planner.entities.SpecificResourceAllocation;
|
||||||
import org.libreplan.business.planner.entities.StretchesFunction;
|
import org.libreplan.business.planner.entities.StretchesFunction;
|
||||||
import org.libreplan.business.planner.entities.SubcontractorDeliverDate;
|
import org.libreplan.business.planner.entities.SubcontractorDeliverDate;
|
||||||
|
|
@ -103,6 +102,7 @@ import org.zkoss.zk.ui.Desktop;
|
||||||
*
|
*
|
||||||
* @author Óscar González Fernández <ogonzalez@igalia.com>
|
* @author Óscar González Fernández <ogonzalez@igalia.com>
|
||||||
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
|
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
|
||||||
|
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@Scope(BeanDefinition.SCOPE_SINGLETON)
|
@Scope(BeanDefinition.SCOPE_SINGLETON)
|
||||||
|
|
@ -233,7 +233,8 @@ public class PlanningStateCreator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PlanningState result = createPlanning(reload(order));
|
PlanningState result = createPlanning(reload(order));
|
||||||
result.onRetrieval();
|
// It was called before, no need to do it one more
|
||||||
|
//result.onRetrieval();
|
||||||
if (desktop != null) {
|
if (desktop != null) {
|
||||||
desktop.setAttribute(ATTRIBUTE_NAME, result);
|
desktop.setAttribute(ATTRIBUTE_NAME, result);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,7 @@ import org.libreplan.web.common.MessagesForUser;
|
||||||
import org.libreplan.web.common.concurrentdetection.ConcurrentModificationHandling;
|
import org.libreplan.web.common.concurrentdetection.ConcurrentModificationHandling;
|
||||||
import org.libreplan.web.planner.TaskElementAdapter;
|
import org.libreplan.web.planner.TaskElementAdapter;
|
||||||
import org.libreplan.web.planner.order.PlanningStateCreator.PlanningState;
|
import org.libreplan.web.planner.order.PlanningStateCreator.PlanningState;
|
||||||
|
import org.libreplan.web.planner.taskedition.TaskPropertiesController;
|
||||||
import org.libreplan.web.security.SecurityUtils;
|
import org.libreplan.web.security.SecurityUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
|
@ -121,6 +122,7 @@ import org.zkoss.zul.Messagebox;
|
||||||
* @author Óscar González Fernández <ogonzalez@igalia.com>
|
* @author Óscar González Fernández <ogonzalez@igalia.com>
|
||||||
* @author Javier Moran Rua <jmoran@igalia.com>
|
* @author Javier Moran Rua <jmoran@igalia.com>
|
||||||
* @author Manuel Rego Casasnovas <rego@igalia.com>
|
* @author Manuel Rego Casasnovas <rego@igalia.com>
|
||||||
|
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@Scope(BeanDefinition.SCOPE_SINGLETON)
|
@Scope(BeanDefinition.SCOPE_SINGLETON)
|
||||||
|
|
@ -217,6 +219,9 @@ public class SaveCommandBuilder {
|
||||||
@Autowired
|
@Autowired
|
||||||
private ISumExpensesRecalculator sumExpensesRecalculator;
|
private ISumExpensesRecalculator sumExpensesRecalculator;
|
||||||
|
|
||||||
|
public static TaskPropertiesController taskPropertiesController;
|
||||||
|
|
||||||
|
|
||||||
private class SaveCommand implements ISaveCommand {
|
private class SaveCommand implements ISaveCommand {
|
||||||
|
|
||||||
private PlanningState state;
|
private PlanningState state;
|
||||||
|
|
@ -263,6 +268,10 @@ public class SaveCommandBuilder {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doActions() {
|
public void doActions() {
|
||||||
|
// A little bit hack
|
||||||
|
if (taskPropertiesController != null)
|
||||||
|
taskPropertiesController.emailNotificationAddNew();
|
||||||
|
|
||||||
notifyUserThatSavingIsDone();
|
notifyUserThatSavingIsDone();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -50,12 +50,13 @@ import org.libreplan.business.workingday.IntraDayDate;
|
||||||
import org.libreplan.web.I18nHelper;
|
import org.libreplan.web.I18nHelper;
|
||||||
import org.libreplan.web.common.Util;
|
import org.libreplan.web.common.Util;
|
||||||
import org.libreplan.web.email.IEmailNotificationModel;
|
import org.libreplan.web.email.IEmailNotificationModel;
|
||||||
import org.libreplan.web.orders.IOrderModel;
|
|
||||||
import org.libreplan.web.planner.allocation.AllocationResult;
|
import org.libreplan.web.planner.allocation.AllocationResult;
|
||||||
|
import org.libreplan.web.planner.order.SaveCommandBuilder;
|
||||||
import org.libreplan.web.resources.worker.IWorkerModel;
|
import org.libreplan.web.resources.worker.IWorkerModel;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
import org.springframework.context.annotation.Scope;
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import org.springframework.dao.DataIntegrityViolationException;
|
||||||
import org.zkoss.ganttz.TaskEditFormComposer;
|
import org.zkoss.ganttz.TaskEditFormComposer;
|
||||||
import org.zkoss.ganttz.TaskEditFormComposer.TaskDTO;
|
import org.zkoss.ganttz.TaskEditFormComposer.TaskDTO;
|
||||||
import org.zkoss.ganttz.data.TaskContainer;
|
import org.zkoss.ganttz.data.TaskContainer;
|
||||||
|
|
@ -82,6 +83,7 @@ import org.zkoss.zul.api.Tabpanel;
|
||||||
* Controller for edit {@link Task} popup.
|
* Controller for edit {@link Task} popup.
|
||||||
*
|
*
|
||||||
* @author Manuel Rego Casasnovas <mrego@igalia.com>
|
* @author Manuel Rego Casasnovas <mrego@igalia.com>
|
||||||
|
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
|
||||||
*/
|
*/
|
||||||
@org.springframework.stereotype.Component("taskPropertiesController")
|
@org.springframework.stereotype.Component("taskPropertiesController")
|
||||||
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
|
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
|
||||||
|
|
@ -130,10 +132,9 @@ public class TaskPropertiesController extends GenericForwardComposer {
|
||||||
|
|
||||||
private IEmailNotificationModel emailNotificationModel;
|
private IEmailNotificationModel emailNotificationModel;
|
||||||
|
|
||||||
private IOrderModel orderModel;
|
|
||||||
|
|
||||||
private IWorkerModel workerModel;
|
private IWorkerModel workerModel;
|
||||||
|
|
||||||
|
private boolean isResourcesAdded = false;
|
||||||
|
|
||||||
|
|
||||||
public void init(final EditTaskController editTaskController,
|
public void init(final EditTaskController editTaskController,
|
||||||
|
|
@ -433,7 +434,9 @@ public class TaskPropertiesController extends GenericForwardComposer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void accept() {
|
public void accept() {
|
||||||
EmailNotificationAddNewWithTaskAssignedToResource();
|
if ( !isResourcesAdded ) listToAdd.clear();
|
||||||
|
|
||||||
|
SaveCommandBuilder.taskPropertiesController = getObject();
|
||||||
|
|
||||||
boolean ok = true;
|
boolean ok = true;
|
||||||
if (currentTaskElement instanceof ITaskPositionConstrained) {
|
if (currentTaskElement instanceof ITaskPositionConstrained) {
|
||||||
|
|
@ -730,49 +733,88 @@ public class TaskPropertiesController extends GenericForwardComposer {
|
||||||
return Util.getMoneyFormat();
|
return Util.getMoneyFormat();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EmailNotificationAddNewWithTaskAssignedToResource(){
|
public List<Resource> listToDelete = new ArrayList<Resource>();
|
||||||
|
public List<Resource> listToAdd = new ArrayList<Resource>();
|
||||||
|
|
||||||
if ( allocationResult.getSpecificAllocations().size() != 0 ) {
|
public void emailNotificationAddNew(){
|
||||||
|
|
||||||
/* Check if resources in allocation are bound by user and are in role ROLE_EMAIL_TASK_ASSIGNED_TO_RESOURCE
|
/**
|
||||||
* setUser method calling manually because, after initialization user will be null
|
* Check if resources in allocation are bound by user and in what ROLE they are
|
||||||
* Then send valid data to notification_queue table */
|
* setUser method calling manually because, after initialization user will be null
|
||||||
|
* Then send valid data to notification_queue table
|
||||||
|
*/
|
||||||
|
|
||||||
|
proceedList(EmailTemplateEnum.TEMPLATE_TASK_ASSIGNED_TO_RESOURCE, listToAdd);
|
||||||
|
proceedList(EmailTemplateEnum.TEMPLATE_RESOURCE_REMOVED_FROM_TASK, listToDelete);
|
||||||
|
listToAdd.clear();
|
||||||
|
listToDelete.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void proceedList(EmailTemplateEnum enumeration, List<Resource> list){
|
||||||
|
if ( list.size() != 0 ){
|
||||||
List<Worker> workersList = workerModel.getWorkers();
|
List<Worker> workersList = workerModel.getWorkers();
|
||||||
Worker currentWorker;
|
Worker currentWorker;
|
||||||
Resource currentResource;
|
Resource currentResource;
|
||||||
User currentUser;
|
|
||||||
|
|
||||||
for (int i = 0; i < workersList.size(); i++)
|
for (int i = 0; i < workersList.size(); i++)
|
||||||
|
|
||||||
for (int j = 0; j < allocationResult.getSpecificAllocations().size(); j++){
|
for (int j = 0; j < list.size(); j++){
|
||||||
|
|
||||||
currentWorker = workersList.get(i);
|
currentWorker = workersList.get(i);
|
||||||
currentResource = allocationResult.getSpecificAllocations().get(j).getResource();
|
currentResource = list.get(j);
|
||||||
|
|
||||||
if ( currentWorker.getId().equals(currentResource.getId()) ){
|
if ( currentWorker.getId().equals(currentResource.getId()) ){
|
||||||
|
|
||||||
workersList.get(i).setUser(workerModel.getBoundUserFromDB(currentWorker));
|
workersList.get(i).setUser(workerModel.getBoundUserFromDB(currentWorker));
|
||||||
currentUser = currentWorker.getUser();
|
User currentUser = currentWorker.getUser();
|
||||||
|
|
||||||
if ( currentUser != null &&
|
if ( currentUser != null
|
||||||
currentUser.isInRole(UserRole.ROLE_EMAIL_TASK_ASSIGNED_TO_RESOURCE) ) {
|
&& (currentUser.isInRole(UserRole.ROLE_EMAIL_TASK_ASSIGNED_TO_RESOURCE)
|
||||||
|
|| currentUser.isInRole(UserRole.ROLE_EMAIL_RESOURCE_REMOVED_FROM_TASK)) )
|
||||||
emailNotificationModel.setType(EmailTemplateEnum.TEMPLATE_TASK_ASSIGNED_TO_RESOURCE);
|
setEmailNotificationEntity(enumeration, currentResource);
|
||||||
|
break;
|
||||||
emailNotificationModel.setUpdated(new Date());
|
|
||||||
|
|
||||||
emailNotificationModel.setResource(allocationResult.getSpecificAllocations().get(j).getResource());
|
|
||||||
|
|
||||||
emailNotificationModel.setTask(currentTaskElement.getTaskSource().getTask());
|
|
||||||
|
|
||||||
emailNotificationModel.setProject(currentTaskElement.getParent().getTaskSource().getTask());
|
|
||||||
|
|
||||||
emailNotificationModel.confirmSave();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private void setEmailNotificationEntity(EmailTemplateEnum enumeration, Resource resource){
|
||||||
|
try{
|
||||||
|
emailNotificationModel.setNewObject();
|
||||||
|
|
||||||
|
if ( enumeration.equals(EmailTemplateEnum.TEMPLATE_TASK_ASSIGNED_TO_RESOURCE) )
|
||||||
|
emailNotificationModel.setType(EmailTemplateEnum.TEMPLATE_TASK_ASSIGNED_TO_RESOURCE);
|
||||||
|
else if ( enumeration.equals(EmailTemplateEnum.TEMPLATE_RESOURCE_REMOVED_FROM_TASK) )
|
||||||
|
emailNotificationModel.setType(EmailTemplateEnum.TEMPLATE_RESOURCE_REMOVED_FROM_TASK);
|
||||||
|
|
||||||
|
emailNotificationModel.setUpdated(new Date());
|
||||||
|
|
||||||
|
emailNotificationModel.setResource(resource);
|
||||||
|
|
||||||
|
emailNotificationModel.setTask(currentTaskElement.getTaskSource().getTask());
|
||||||
|
|
||||||
|
emailNotificationModel.setProject(currentTaskElement.getParent().getTaskSource().getTask());
|
||||||
|
|
||||||
|
emailNotificationModel.confirmSave();
|
||||||
|
} catch (DataIntegrityViolationException e){
|
||||||
|
try {
|
||||||
|
Messagebox.show(_("You cannot email user twice with the same info"), _("Error"),
|
||||||
|
Messagebox.OK, Messagebox.ERROR);
|
||||||
|
} catch (InterruptedException e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Resource> getListToDelete() {
|
||||||
|
return listToDelete;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResourcesAdded(boolean resourcesAdded) {
|
||||||
|
isResourcesAdded = resourcesAdded;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TaskPropertiesController getObject(){
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ public class PersonalTimesheetDTO {
|
||||||
* @param tasksNumber
|
* @param tasksNumber
|
||||||
* Number of tasks in the personal timesheet
|
* Number of tasks in the personal timesheet
|
||||||
*/
|
*/
|
||||||
PersonalTimesheetDTO(LocalDate date, WorkReport workReport,
|
public PersonalTimesheetDTO(LocalDate date, WorkReport workReport,
|
||||||
EffortDuration resourceCapacity, EffortDuration totalHours,
|
EffortDuration resourceCapacity, EffortDuration totalHours,
|
||||||
int tasksNumber) {
|
int tasksNumber) {
|
||||||
this.date = date;
|
this.date = date;
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@
|
||||||
|
|
||||||
package org.libreplan.web.users.services;
|
package org.libreplan.web.users.services;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
import org.springframework.security.authentication.dao.SaltSource;
|
import org.springframework.security.authentication.dao.SaltSource;
|
||||||
|
|
|
||||||
|
|
@ -9364,3 +9364,55 @@ msgstr ""
|
||||||
#: libreplan-webapp/src/main/webapp/orders/imports/projectImport.zul:42
|
#: libreplan-webapp/src/main/webapp/orders/imports/projectImport.zul:42
|
||||||
msgid "Your project could only partially be imported"
|
msgid "Your project could only partially be imported"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: libreplan-business/src/main/java/org/libreplan/business/email/entities/EmailTemplateEnum.java:37
|
||||||
|
msgid "Resource removed from task"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: libreplan-business/src/main/java/org/libreplan/business/email/entities/EmailTemplateEnum.java:38
|
||||||
|
msgid "Milestone reached"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: libreplan-business/src/main/java/org/libreplan/business/email/entities/EmailTemplateEnum.java:39
|
||||||
|
msgid "Task should start"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: libreplan-business/src/main/java/org/libreplan/business/email/entities/EmailTemplateEnum.java:40
|
||||||
|
msgid "Task should finish"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: libreplan-business/src/main/java/org/libreplan/business/email/entities/EmailTemplateEnum.java:41
|
||||||
|
msgid "Enter data in timesheet"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#: libreplan-business/src/main/java/org/libreplan/business/users/entities/UserRole.java:96
|
||||||
|
msgid "Email: task assigned to resource"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: libreplan-business/src/main/java/org/libreplan/business/users/entities/UserRole.java:97
|
||||||
|
msgid "Email: resource removed from task"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: libreplan-business/src/main/java/org/libreplan/business/users/entities/UserRole.java:98
|
||||||
|
msgid "Email: milestone reached"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: libreplan-business/src/main/java/org/libreplan/business/users/entities/UserRole.java:99
|
||||||
|
msgid "Email: task should finish"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: libreplan-business/src/main/java/org/libreplan/business/users/entities/UserRole.java:100
|
||||||
|
msgid "Email: task should start"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: libreplan-business/src/main/java/org/libreplan/business/users/entities/UserRole.java:101
|
||||||
|
msgid "Email: timesheet data missing"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#: libreplan-webapp/src/main/java/org/libreplan/web/planner/taskedition/TaskPropertiesController.java:804
|
||||||
|
msgid "You cannot email user twice with the same info"
|
||||||
|
msgstr ""
|
||||||
Loading…
Add table
Reference in a new issue