diff --git a/libreplan-business/src/main/java/org/libreplan/business/common/entities/JobClassNameEnum.java b/libreplan-business/src/main/java/org/libreplan/business/common/entities/JobClassNameEnum.java index 26f4f041e..539f13c14 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/common/entities/JobClassNameEnum.java +++ b/libreplan-business/src/main/java/org/libreplan/business/common/entities/JobClassNameEnum.java @@ -25,13 +25,20 @@ package org.libreplan.business.common.entities; * {@link JobSchedulerConfiguration} * * @author Miciele Ghiorghis + * @author Vova Perebykivskiy */ public enum JobClassNameEnum { IMPORT_ROSTER_FROM_TIM_JOB("org.libreplan.importers", "ImportRosterFromTimJob"), EXPORT_TIMESHEET_TO_TIM_JOB("org.libreplan.importers", "ExportTimesheetToTimJob"), 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 name; diff --git a/libreplan-business/src/main/java/org/libreplan/business/email/daos/EmailNotificationDAO.java b/libreplan-business/src/main/java/org/libreplan/business/email/daos/EmailNotificationDAO.java index 8324c709b..ad63fd92f 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/email/daos/EmailNotificationDAO.java +++ b/libreplan-business/src/main/java/org/libreplan/business/email/daos/EmailNotificationDAO.java @@ -32,10 +32,11 @@ import java.util.List; * * Created by * @author Vova Perebykivskiy - * on 19.10.15. + * on 19.10.2015. */ @Repository -public class EmailNotificationDAO extends GenericDAOHibernate implements IEmailNotificationDAO { +public class EmailNotificationDAO extends GenericDAOHibernate + implements IEmailNotificationDAO { @Override public List getAll() { diff --git a/libreplan-business/src/main/java/org/libreplan/business/email/entities/EmailTemplateEnum.java b/libreplan-business/src/main/java/org/libreplan/business/email/entities/EmailTemplateEnum.java index 1402115fa..74e4f7ac0 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/email/entities/EmailTemplateEnum.java +++ b/libreplan-business/src/main/java/org/libreplan/business/email/entities/EmailTemplateEnum.java @@ -26,14 +26,19 @@ import static org.libreplan.business.i18n.I18nHelper._; * * Created by * @author Vova Perebykivskiy - * on 28.09.15. + * on 28.09.2015. * * TEMPLATE_N(_("Template N")) - for i18n * TEMPLATE_A("Template A") - for general use (no internationalizing) */ 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; diff --git a/libreplan-business/src/main/java/org/libreplan/business/orders/daos/OrderElementDAO.java b/libreplan-business/src/main/java/org/libreplan/business/orders/daos/OrderElementDAO.java index 869f6959b..88faf4789 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/orders/daos/OrderElementDAO.java +++ b/libreplan-business/src/main/java/org/libreplan/business/orders/daos/OrderElementDAO.java @@ -37,9 +37,7 @@ import org.apache.commons.lang.ObjectUtils; import org.apache.commons.lang.StringUtils; import org.hibernate.Criteria; import org.hibernate.Query; -import org.hibernate.SessionFactory; import org.hibernate.criterion.Restrictions; -import org.libreplan.business.common.IAdHocTransactionService; import org.libreplan.business.common.daos.IntegrationEntityDAO; import org.libreplan.business.common.exceptions.InstanceNotFoundException; import org.libreplan.business.expensesheet.daos.IExpenseSheetLineDAO; @@ -88,15 +86,6 @@ public class OrderElementDAO extends IntegrationEntityDAO @Autowired private ITaskSourceDAO taskSourceDAO; - @Autowired - private IOrderDAO orderDAO; - - @Autowired - private IAdHocTransactionService transactionService; - - @Autowired - private SessionFactory sessionFactory; - @Override public List findWithoutParent() { Criteria c = getSession().createCriteria(OrderElement.class); @@ -260,6 +249,7 @@ public class OrderElementDAO extends IntegrationEntityDAO } @Override + @Transactional public List getAll() { return list(OrderElement.class); } diff --git a/libreplan-business/src/main/java/org/libreplan/business/planner/daos/ITaskElementDAO.java b/libreplan-business/src/main/java/org/libreplan/business/planner/daos/ITaskElementDAO.java index e9f751f3d..ee5df407f 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/planner/daos/ITaskElementDAO.java +++ b/libreplan-business/src/main/java/org/libreplan/business/planner/daos/ITaskElementDAO.java @@ -30,6 +30,7 @@ import org.libreplan.business.planner.entities.TaskGroup; /** * @author Óscar González Fernández + * @author Vova Perebykivskiy */ public interface ITaskElementDAO extends IGenericDAO { @@ -39,4 +40,8 @@ public interface ITaskElementDAO extends IGenericDAO { List getTaskElementsNoMilestonesWithoutTaskSource(); + List getTaskElementsWithMilestones(); + + List getTaskElementsWithParentsWithoutMilestones(); + } diff --git a/libreplan-business/src/main/java/org/libreplan/business/planner/daos/TaskElementDAO.java b/libreplan-business/src/main/java/org/libreplan/business/planner/daos/TaskElementDAO.java index a94271188..15eb05ac3 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/planner/daos/TaskElementDAO.java +++ b/libreplan-business/src/main/java/org/libreplan/business/planner/daos/TaskElementDAO.java @@ -42,6 +42,7 @@ import org.springframework.transaction.annotation.Transactional; /** * @author Óscar González Fernández * @author Jacobo Aragunde Pérez + * @author Vova Perebykivskiy */ @Repository @Scope(BeanDefinition.SCOPE_SINGLETON) @@ -135,4 +136,23 @@ public class TaskElementDAO extends GenericDAOHibernate return query.list(); } + @Override + @Transactional + public List getTaskElementsWithMilestones(){ + String strQuery = "FROM TaskElement " + + "WHERE id IN (SELECT id FROM TaskMilestone)"; + Query query = getSession().createQuery(strQuery); + return query.list(); + } + + @Override + @Transactional + public List 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(); + } + } diff --git a/libreplan-business/src/main/resources/org/libreplan/business/calendars/entities/Calendars.hbm.xml b/libreplan-business/src/main/resources/org/libreplan/business/calendars/entities/Calendars.hbm.xml index 6256709bd..f69814904 100644 --- a/libreplan-business/src/main/resources/org/libreplan/business/calendars/entities/Calendars.hbm.xml +++ b/libreplan-business/src/main/resources/org/libreplan/business/calendars/entities/Calendars.hbm.xml @@ -24,13 +24,13 @@ column="last_sequence_code" /> - + - + @@ -43,7 +43,7 @@ - + - + diff --git a/libreplan-business/src/main/resources/org/libreplan/business/planner/entities/Tasks.hbm.xml b/libreplan-business/src/main/resources/org/libreplan/business/planner/entities/Tasks.hbm.xml index 2b57a4c16..3c7d2c38b 100644 --- a/libreplan-business/src/main/resources/org/libreplan/business/planner/entities/Tasks.hbm.xml +++ b/libreplan-business/src/main/resources/org/libreplan/business/planner/entities/Tasks.hbm.xml @@ -32,7 +32,7 @@ + index="idx_task_element_on_task_group" lazy="false" /> @@ -89,7 +89,7 @@ cascade="all"/> - + diff --git a/libreplan-webapp/src/main/java/org/libreplan/importers/SendEmail.java b/libreplan-webapp/src/main/java/org/libreplan/importers/SendEmail.java deleted file mode 100644 index d9ee56d32..000000000 --- a/libreplan-webapp/src/main/java/org/libreplan/importers/SendEmail.java +++ /dev/null @@ -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 . - */ - -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 - * 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 notifications; - private List 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 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 getEmailConnectorProperties() { - - Connector connector = connectorDAO.findUniqueByName("E-mail"); - - List 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 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 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; - } -} diff --git a/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/ComposeMessage.java b/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/ComposeMessage.java new file mode 100644 index 000000000..eed5d5a9c --- /dev/null +++ b/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/ComposeMessage.java @@ -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 + * 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 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 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 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; + } + +} diff --git a/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/EmailConnectionValidator.java b/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/EmailConnectionValidator.java new file mode 100644 index 000000000..ad44fac3b --- /dev/null +++ b/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/EmailConnectionValidator.java @@ -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 . + */ + +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 + * on 20.01.2016. + */ + +@Component +@Scope(BeanDefinition.SCOPE_PROTOTYPE) +public class EmailConnectionValidator { + + @Autowired + private IConnectorDAO connectorDAO; + + public boolean validConnection(){ + List 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 getEmailConnectorProperties() { + + Connector connector = connectorDAO.findUniqueByName("E-mail"); + + return connector.getProperties(); + } + + public boolean isConnectionActivated(){ + List emailConnectorProperties = getEmailConnectorProperties(); + + for (ConnectorProperty item : emailConnectorProperties){ + if ( item.getKey().equals("Activated") ) + if ( item.getValue().equals("Y") ) + return true; + else break; + } + return false; + } + +} diff --git a/libreplan-webapp/src/main/java/org/libreplan/importers/ISendEmail.java b/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/IEmailNotificationJob.java similarity index 79% rename from libreplan-webapp/src/main/java/org/libreplan/importers/ISendEmail.java rename to libreplan-webapp/src/main/java/org/libreplan/importers/notifications/IEmailNotificationJob.java index 7fe5cbba0..33147a603 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/importers/ISendEmail.java +++ b/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/IEmailNotificationJob.java @@ -17,17 +17,20 @@ * along with this program. If not, see . */ -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 * * Created by * @author Vova Perebykivskiy - * on 13.10.15. + * on 13.10.2015. */ -public interface ISendEmail { +public interface IEmailNotificationJob { void sendEmail(); + boolean composeMessageForUser(EmailNotification notification); + } diff --git a/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/jobs/SendEmailOnMilestoneReachedJob.java b/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/jobs/SendEmailOnMilestoneReachedJob.java new file mode 100644 index 000000000..3cf0a8912 --- /dev/null +++ b/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/jobs/SendEmailOnMilestoneReachedJob.java @@ -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 . + */ + +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 + * 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(); + } + +} diff --git a/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/jobs/SendEmailOnResourceRemovedFromTaskJob.java b/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/jobs/SendEmailOnResourceRemovedFromTaskJob.java new file mode 100644 index 000000000..a49fc199b --- /dev/null +++ b/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/jobs/SendEmailOnResourceRemovedFromTaskJob.java @@ -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 . + */ + +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 + * 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(); + } + +} diff --git a/libreplan-webapp/src/main/java/org/libreplan/importers/SendEmailJob.java b/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/jobs/SendEmailOnTaskAssignedToResourceJob.java similarity index 73% rename from libreplan-webapp/src/main/java/org/libreplan/importers/SendEmailJob.java rename to libreplan-webapp/src/main/java/org/libreplan/importers/notifications/jobs/SendEmailOnTaskAssignedToResourceJob.java index fa7dab5b8..80fd86c30 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/importers/SendEmailJob.java +++ b/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/jobs/SendEmailOnTaskAssignedToResourceJob.java @@ -17,8 +17,10 @@ * along with this program. If not, see . */ -package org.libreplan.importers; +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; @@ -26,22 +28,25 @@ 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_TASK_ASSIGNED_TO_RESOURCE} * * Created by * @author Vova Perebykivskiy - * on 13.10.15. + * on 13.10.2015. * */ -public class SendEmailJob extends QuartzJobBean { +public class SendEmailOnTaskAssignedToResourceJob extends QuartzJobBean { @Override protected void executeInternal(JobExecutionContext context) throws JobExecutionException { ApplicationContext applicationContext = (ApplicationContext) context.getJobDetail(). getJobDataMap().get("applicationContext"); - ISendEmail sendEmail = (ISendEmail) applicationContext.getBean("sendEmail"); - sendEmail.sendEmail(); + IEmailNotificationJob taskAssignedToResource = (IEmailNotificationJob) applicationContext + .getBean("SendEmailOnTaskAssignedToResource"); + + taskAssignedToResource.sendEmail(); } } diff --git a/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/jobs/SendEmailOnTaskShouldFinishJob.java b/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/jobs/SendEmailOnTaskShouldFinishJob.java new file mode 100644 index 000000000..c6451f222 --- /dev/null +++ b/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/jobs/SendEmailOnTaskShouldFinishJob.java @@ -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 . + */ + +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 + * 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(); + } + +} diff --git a/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/jobs/SendEmailOnTaskShouldStartJob.java b/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/jobs/SendEmailOnTaskShouldStartJob.java new file mode 100644 index 000000000..9018af182 --- /dev/null +++ b/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/jobs/SendEmailOnTaskShouldStartJob.java @@ -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 . + */ + +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 + * 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(); + } + +} diff --git a/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/jobs/SendEmailOnTimesheetDataMissingJob.java b/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/jobs/SendEmailOnTimesheetDataMissingJob.java new file mode 100644 index 000000000..37f422b87 --- /dev/null +++ b/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/jobs/SendEmailOnTimesheetDataMissingJob.java @@ -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 . + */ + +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 + * 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(); + } + +} diff --git a/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/realization/SendEmailOnMilestoneReached.java b/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/realization/SendEmailOnMilestoneReached.java new file mode 100644 index 000000000..18cf17c40 --- /dev/null +++ b/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/realization/SendEmailOnMilestoneReached.java @@ -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 . + */ + +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 + * 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 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 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); + } + } + } + +} diff --git a/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/realization/SendEmailOnResourceRemovedFromTask.java b/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/realization/SendEmailOnResourceRemovedFromTask.java new file mode 100644 index 000000000..5a6add39b --- /dev/null +++ b/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/realization/SendEmailOnResourceRemovedFromTask.java @@ -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 . + */ + +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 + * 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 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); + } + +} diff --git a/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/realization/SendEmailOnTaskAssignedToResource.java b/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/realization/SendEmailOnTaskAssignedToResource.java new file mode 100644 index 000000000..926e55ad3 --- /dev/null +++ b/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/realization/SendEmailOnTaskAssignedToResource.java @@ -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 . + */ + +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 + * 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 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); + } + +} diff --git a/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/realization/SendEmailOnTaskShouldFinish.java b/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/realization/SendEmailOnTaskShouldFinish.java new file mode 100644 index 000000000..cbed116e4 --- /dev/null +++ b/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/realization/SendEmailOnTaskShouldFinish.java @@ -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 . + */ + +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 + * 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 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 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> list = new ArrayList>(); + list.addAll(item.getAllResourceAllocations()); + + List resources = new ArrayList(); + 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(); + } + } + +} diff --git a/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/realization/SendEmailOnTaskShouldStart.java b/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/realization/SendEmailOnTaskShouldStart.java new file mode 100644 index 000000000..f4e9e4108 --- /dev/null +++ b/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/realization/SendEmailOnTaskShouldStart.java @@ -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 . + */ + +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 + * 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 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 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> list = new ArrayList>(); + list.addAll(item.getAllResourceAllocations()); + + List resources = new ArrayList(); + 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(); + } + } + +} diff --git a/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/realization/SendEmailOnTimesheetDataMissing.java b/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/realization/SendEmailOnTimesheetDataMissing.java new file mode 100644 index 000000000..effc4c6a4 --- /dev/null +++ b/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/realization/SendEmailOnTimesheetDataMissing.java @@ -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 . + */ + +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 + * 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 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 list = getPersonalTimesheets(); + addRowsToNotificationTable(list); + } + + @Transactional + private List getPersonalTimesheets() { + List personalTimesheetDTO = new ArrayList(); + List usersWithoutTimesheets = new ArrayList(); + List 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 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 getPersonalTimesheets(Resource resource, + LocalDate start, LocalDate end, + PersonalTimesheetsPeriodicityEnum periodicity) { + start = periodicity.getStart(start); + end = periodicity.getEnd(end); + int items = periodicity.getItemsBetween(start, end); + + List result = new ArrayList(); + + // 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 orderElements = new ArrayList(); + 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; + } + +} diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/common/ConfigurationController.java b/libreplan-webapp/src/main/java/org/libreplan/web/common/ConfigurationController.java index 8c0c1824e..33f30b118 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/common/ConfigurationController.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/common/ConfigurationController.java @@ -31,8 +31,6 @@ import java.util.ArrayList; import java.util.Set; import java.util.Map; import java.util.Collections; -import java.util.Comparator; -import java.util.ConcurrentModificationException; import java.util.HashSet; import java.util.Arrays; @@ -1365,6 +1363,11 @@ public class ConfigurationController extends GenericForwardComposer { emailPasswordTextbox.getValue().length() != 0 && emailSenderTextbox.getValue().matches("^\\S+@\\S+\\.\\S+$") ) return true; + + if ( protocolsCombobox != null && protocolsCombobox.getSelectedItem() != null ){ + if ( protocolsCombobox.getSelectedItem().getLabel().equals("SMTP") ) + return true; + } } return false; } diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/common/JobSchedulerModel.java b/libreplan-webapp/src/main/java/org/libreplan/web/common/JobSchedulerModel.java index 0cea1d00a..6f622a85a 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/common/JobSchedulerModel.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/common/JobSchedulerModel.java @@ -35,10 +35,11 @@ import org.libreplan.importers.IImportRosterFromTim; import org.libreplan.importers.IJiraOrderElementSynchronizer; import org.libreplan.importers.ISchedulerManager; 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.quartz.SchedulerException; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service; @@ -51,6 +52,7 @@ import static org.libreplan.web.I18nHelper._; * * @author Manuel Rego Casasnovas * @author Miciele Ghiorghis + * @author Vova Perebykivskiy */ @Service @Scope(BeanDefinition.SCOPE_PROTOTYPE) @@ -79,8 +81,30 @@ public class JobSchedulerModel implements IJobSchedulerModel { private List synchronizationInfos; + @Qualifier("sendEmailOnTaskAssignedToResource") @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 @Transactional(readOnly = true) @@ -112,10 +136,40 @@ public class JobSchedulerModel implements IJobSchedulerModel { .syncOrderElementsWithJiraIssues(); return; } - if ( name.equals(JobClassNameEnum.SEND_EMAIL_JOB.getName()) ) { + if ( name.equals(JobClassNameEnum.SEND_EMAIL_TASK_ASSIGNED_TO_RESOURCE.getName()) ) { synchronizationInfos = new ArrayList(); - synchronizationInfos.add(new SynchronizationInfo(_("Send E-mail"))); - email.sendEmail(); + synchronizationInfos.add(new SynchronizationInfo(_("Task assigned to resource emails"))); + taskAssignedToResource.sendEmail(); + return; + } + if ( name.equals(JobClassNameEnum.SEND_EMAIL_RESOURCE_REMOVED_FROM_TASK.getName()) ) { + synchronizationInfos = new ArrayList(); + synchronizationInfos.add(new SynchronizationInfo(_("Resource removed from task"))); + resourceRemovedFromTask.sendEmail(); + return; + } + if ( name.equals(JobClassNameEnum.SEND_EMAIL_MILESTONE_REACHED.getName()) ) { + synchronizationInfos = new ArrayList(); + synchronizationInfos.add(new SynchronizationInfo(_("Milestone reached"))); + milestoneReached.sendEmail(); + return; + } + if ( name.equals(JobClassNameEnum.SEND_EMAIL_TASK_SHOULD_START.getName()) ) { + synchronizationInfos = new ArrayList(); + synchronizationInfos.add(new SynchronizationInfo(_("Task should start"))); + taskShouldStart.sendEmail(); + return; + } + if ( name.equals(JobClassNameEnum.SEND_EMAIL_TASK_SHOULD_FINISH.getName()) ) { + synchronizationInfos = new ArrayList(); + synchronizationInfos.add(new SynchronizationInfo(_("Task should finish"))); + taskShouldFinish.sendEmail(); + return; + } + if ( name.equals(JobClassNameEnum.SEND_EMAIL_TIMESHEET_DATA_MISSING.getName()) ) { + synchronizationInfos = new ArrayList(); + synchronizationInfos.add(new SynchronizationInfo(_("Timesheet data missing"))); + timesheetDataMissing.sendEmail(); return; } diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/common/LimitsModel.java b/libreplan-webapp/src/main/java/org/libreplan/web/common/LimitsModel.java index 5ee7c81a4..556b0c43d 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/common/LimitsModel.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/common/LimitsModel.java @@ -34,7 +34,7 @@ import java.util.List; * * Created by * @author Vova Perebykivskiy - * on 17.12.15. + * on 17.12.2015. */ @Service diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/planner/allocation/ResourceAllocationController.java b/libreplan-webapp/src/main/java/org/libreplan/web/planner/allocation/ResourceAllocationController.java index 1580f9b39..2859ace14 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/planner/allocation/ResourceAllocationController.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/planner/allocation/ResourceAllocationController.java @@ -87,6 +87,7 @@ import org.zkoss.zul.Window; * @author Manuel Rego Casasnovas * @author Diego Pino Garcia * @author Javier Moran Rua + * @author Vova Perebykivskiy */ @org.springframework.stereotype.Component("resourceAllocationController") @Scope(BeanDefinition.SCOPE_PROTOTYPE) @@ -315,6 +316,12 @@ public class ResourceAllocationController extends GenericForwardComposer { try { allocationSelector.addChoosen(); } 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); applyButton.setVisible(true); allocationSelector.clearAll(); @@ -618,6 +625,8 @@ public class ResourceAllocationController extends GenericForwardComposer { @Override public void onEvent(Event event) { + editTaskController.getTaskPropertiesController().getListToDelete() + .add(data.getAssociatedResources().get(0)); removeAllocation(data); } }); diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/planner/order/PlanningStateCreator.java b/libreplan-webapp/src/main/java/org/libreplan/web/planner/order/PlanningStateCreator.java index 20a49e16c..f7ae2aa5a 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/planner/order/PlanningStateCreator.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/planner/order/PlanningStateCreator.java @@ -59,7 +59,6 @@ import org.libreplan.business.planner.entities.GenericResourceAllocation; import org.libreplan.business.planner.entities.IMoneyCostCalculator; import org.libreplan.business.planner.entities.ResourceAllocation; 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.StretchesFunction; import org.libreplan.business.planner.entities.SubcontractorDeliverDate; @@ -103,6 +102,7 @@ import org.zkoss.zk.ui.Desktop; * * @author Óscar González Fernández * @author Lorenzo Tilve Álvaro + * @author Vova Perebykivskiy */ @Component @Scope(BeanDefinition.SCOPE_SINGLETON) @@ -233,7 +233,8 @@ public class PlanningStateCreator { } } PlanningState result = createPlanning(reload(order)); - result.onRetrieval(); + // It was called before, no need to do it one more + //result.onRetrieval(); if (desktop != null) { desktop.setAttribute(ATTRIBUTE_NAME, result); } diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/planner/order/SaveCommandBuilder.java b/libreplan-webapp/src/main/java/org/libreplan/web/planner/order/SaveCommandBuilder.java index d97288e35..0bf89f0d8 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/planner/order/SaveCommandBuilder.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/planner/order/SaveCommandBuilder.java @@ -93,6 +93,7 @@ import org.libreplan.web.common.MessagesForUser; import org.libreplan.web.common.concurrentdetection.ConcurrentModificationHandling; import org.libreplan.web.planner.TaskElementAdapter; import org.libreplan.web.planner.order.PlanningStateCreator.PlanningState; +import org.libreplan.web.planner.taskedition.TaskPropertiesController; import org.libreplan.web.security.SecurityUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.BeanDefinition; @@ -121,6 +122,7 @@ import org.zkoss.zul.Messagebox; * @author Óscar González Fernández * @author Javier Moran Rua * @author Manuel Rego Casasnovas + * @author Vova Perebykivskiy */ @Component @Scope(BeanDefinition.SCOPE_SINGLETON) @@ -217,6 +219,9 @@ public class SaveCommandBuilder { @Autowired private ISumExpensesRecalculator sumExpensesRecalculator; + public static TaskPropertiesController taskPropertiesController; + + private class SaveCommand implements ISaveCommand { private PlanningState state; @@ -263,6 +268,10 @@ public class SaveCommandBuilder { @Override public void doActions() { + // A little bit hack + if (taskPropertiesController != null) + taskPropertiesController.emailNotificationAddNew(); + notifyUserThatSavingIsDone(); } }); diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/planner/taskedition/TaskPropertiesController.java b/libreplan-webapp/src/main/java/org/libreplan/web/planner/taskedition/TaskPropertiesController.java index e6495d518..248765bf0 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/planner/taskedition/TaskPropertiesController.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/planner/taskedition/TaskPropertiesController.java @@ -50,12 +50,13 @@ import org.libreplan.business.workingday.IntraDayDate; import org.libreplan.web.I18nHelper; import org.libreplan.web.common.Util; import org.libreplan.web.email.IEmailNotificationModel; -import org.libreplan.web.orders.IOrderModel; import org.libreplan.web.planner.allocation.AllocationResult; +import org.libreplan.web.planner.order.SaveCommandBuilder; 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.dao.DataIntegrityViolationException; import org.zkoss.ganttz.TaskEditFormComposer; import org.zkoss.ganttz.TaskEditFormComposer.TaskDTO; import org.zkoss.ganttz.data.TaskContainer; @@ -82,6 +83,7 @@ import org.zkoss.zul.api.Tabpanel; * Controller for edit {@link Task} popup. * * @author Manuel Rego Casasnovas + * @author Vova Perebykivskiy */ @org.springframework.stereotype.Component("taskPropertiesController") @Scope(BeanDefinition.SCOPE_PROTOTYPE) @@ -130,10 +132,9 @@ public class TaskPropertiesController extends GenericForwardComposer { private IEmailNotificationModel emailNotificationModel; - private IOrderModel orderModel; - private IWorkerModel workerModel; + private boolean isResourcesAdded = false; public void init(final EditTaskController editTaskController, @@ -433,7 +434,9 @@ public class TaskPropertiesController extends GenericForwardComposer { } public void accept() { - EmailNotificationAddNewWithTaskAssignedToResource(); + if ( !isResourcesAdded ) listToAdd.clear(); + + SaveCommandBuilder.taskPropertiesController = getObject(); boolean ok = true; if (currentTaskElement instanceof ITaskPositionConstrained) { @@ -730,49 +733,88 @@ public class TaskPropertiesController extends GenericForwardComposer { return Util.getMoneyFormat(); } - private void EmailNotificationAddNewWithTaskAssignedToResource(){ + public List listToDelete = new ArrayList(); + public List listToAdd = new ArrayList(); - 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 - * Then send valid data to notification_queue table */ + /** + * Check if resources in allocation are bound by user and in what ROLE they are + * 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 list){ + if ( list.size() != 0 ){ List workersList = workerModel.getWorkers(); Worker currentWorker; Resource currentResource; - User currentUser; 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); - currentResource = allocationResult.getSpecificAllocations().get(j).getResource(); + currentResource = list.get(j); if ( currentWorker.getId().equals(currentResource.getId()) ){ workersList.get(i).setUser(workerModel.getBoundUserFromDB(currentWorker)); - currentUser = currentWorker.getUser(); + User currentUser = currentWorker.getUser(); - if ( currentUser != null && - currentUser.isInRole(UserRole.ROLE_EMAIL_TASK_ASSIGNED_TO_RESOURCE) ) { - - emailNotificationModel.setType(EmailTemplateEnum.TEMPLATE_TASK_ASSIGNED_TO_RESOURCE); - - emailNotificationModel.setUpdated(new Date()); - - emailNotificationModel.setResource(allocationResult.getSpecificAllocations().get(j).getResource()); - - emailNotificationModel.setTask(currentTaskElement.getTaskSource().getTask()); - - emailNotificationModel.setProject(currentTaskElement.getParent().getTaskSource().getTask()); - - emailNotificationModel.confirmSave(); - } + if ( currentUser != null + && (currentUser.isInRole(UserRole.ROLE_EMAIL_TASK_ASSIGNED_TO_RESOURCE) + || currentUser.isInRole(UserRole.ROLE_EMAIL_RESOURCE_REMOVED_FROM_TASK)) ) + setEmailNotificationEntity(enumeration, currentResource); + break; } } } } + 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 getListToDelete() { + return listToDelete; + } + + public void setResourcesAdded(boolean resourcesAdded) { + isResourcesAdded = resourcesAdded; + } + + private TaskPropertiesController getObject(){ + return this; + } } diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/PersonalTimesheetDTO.java b/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/PersonalTimesheetDTO.java index 3153853dc..0f6c6a6d4 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/PersonalTimesheetDTO.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/users/dashboard/PersonalTimesheetDTO.java @@ -61,7 +61,7 @@ public class PersonalTimesheetDTO { * @param tasksNumber * Number of tasks in the personal timesheet */ - PersonalTimesheetDTO(LocalDate date, WorkReport workReport, + public PersonalTimesheetDTO(LocalDate date, WorkReport workReport, EffortDuration resourceCapacity, EffortDuration totalHours, int tasksNumber) { this.date = date; diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/users/services/DBPasswordEncoderService.java b/libreplan-webapp/src/main/java/org/libreplan/web/users/services/DBPasswordEncoderService.java index 49a3e5c05..07a192498 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/users/services/DBPasswordEncoderService.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/users/services/DBPasswordEncoderService.java @@ -21,7 +21,6 @@ package org.libreplan.web.users.services; -import java.util.Collection; import java.util.Collections; import org.springframework.security.authentication.dao.SaltSource; diff --git a/libreplan-webapp/src/main/resources/i18n/keys.pot b/libreplan-webapp/src/main/resources/i18n/keys.pot index d2aebcc48..5c4cfef63 100644 --- a/libreplan-webapp/src/main/resources/i18n/keys.pot +++ b/libreplan-webapp/src/main/resources/i18n/keys.pot @@ -9363,4 +9363,56 @@ msgstr "" #: libreplan-webapp/src/main/webapp/orders/imports/projectImport.zul:42 msgid "Your project could only partially be imported" +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 "" \ No newline at end of file