Merge pull request #97 from dgray16/master

Add tests for Email functionality
This commit is contained in:
Jeroen Baten 2016-08-04 13:41:46 +02:00 committed by GitHub
commit 16b8ced6c0
52 changed files with 1663 additions and 1689 deletions

View file

@ -28,28 +28,17 @@ import org.libreplan.business.common.Registry;
import org.libreplan.business.common.daos.IJobSchedulerConfigurationDAO;
/**
* JobSchedulerConfiguration entity, represents parameters for the jobs to be
* scheduled. This entity is used by the <code>SchedulerManager</code> to
* JobSchedulerConfiguration entity, represents parameters for the jobs to be scheduled.
* This entity is used by the <code>SchedulerManager</code> to
* schedule jobs and in UI to show the scheduler status.
*
* The <code>jobGroup</code> and <code>jobName</code> together forms a job key
* and non of the fields must be null. Moreover it should contain a valid
* <code>cronExpression</code>
* and non of the fields must be null. Moreover it should contain a valid <code>cronExpression</code>.
*
* @author Miciele Ghiorghis <m.ghiorghis@antoniusziekenhuis.nl>
*/
public class JobSchedulerConfiguration extends BaseEntity implements IHumanIdentifiable {
public static JobSchedulerConfiguration create() {
return create(new JobSchedulerConfiguration());
}
/**
* Constructor for Hibernate. Do not use!
*/
protected JobSchedulerConfiguration() {
}
private String jobGroup;
private String jobName;
@ -62,6 +51,15 @@ public class JobSchedulerConfiguration extends BaseEntity implements IHumanIdent
private String connectorName;
/**
* Constructor for Hibernate. Do not use!
*/
protected JobSchedulerConfiguration() {}
public static JobSchedulerConfiguration create() {
return create(new JobSchedulerConfiguration());
}
@NotNull(message = "job group not specified")
public String getJobGroup() {
return jobGroup;
@ -124,7 +122,9 @@ public class JobSchedulerConfiguration extends BaseEntity implements IHumanIdent
if ( StringUtils.isBlank(jobGroup) && StringUtils.isBlank(jobName) ) {
return true;
}
IJobSchedulerConfigurationDAO jobSchedulerConfigurationDAO = Registry.getJobSchedulerConfigurationDAO();
if ( isNewObject() ) {
return !jobSchedulerConfigurationDAO.existsByJobGroupAndJobNameAnotherTransaction(this);
} else {

View file

@ -30,12 +30,11 @@ import java.util.List;
/**
* Dao for {@link EmailNotification}
*
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 19.10.2015.
* @author Created by Vova Perebykivskiy <vova@libreplan-enterprise.com> on 19.10.2015.
*/
@Repository
public class EmailNotificationDAO extends GenericDAOHibernate<EmailNotification, Long>
public class EmailNotificationDAO
extends GenericDAOHibernate<EmailNotification, Long>
implements IEmailNotificationDAO {
@Override
@ -45,13 +44,16 @@ public class EmailNotificationDAO extends GenericDAOHibernate<EmailNotification,
@Override
public List<EmailNotification> getAllByType(EmailTemplateEnum enumeration) {
return getSession().createCriteria(EmailNotification.class)
.add(Restrictions.eq("type", enumeration)).list();
return getSession()
.createCriteria(EmailNotification.class)
.add(Restrictions.eq("type", enumeration))
.list();
}
@Override
public boolean deleteAll() {
List<EmailNotification> notifications = list(EmailNotification.class);
for (Object item : notifications){
getSession().delete(item);
}
@ -61,23 +63,30 @@ public class EmailNotificationDAO extends GenericDAOHibernate<EmailNotification,
@Override
public boolean deleteAllByType(EmailTemplateEnum enumeration) {
List<EmailNotification> notifications = getSession().createCriteria(EmailNotification.class)
.add(Restrictions.eq("type", enumeration)).list();
List<EmailNotification> notifications = getSession()
.createCriteria(EmailNotification.class)
.add(Restrictions.eq("type", enumeration))
.list();
for (Object item : notifications){
getSession().delete(item);
}
if ( getSession().createCriteria(EmailNotification.class)
.add(Restrictions.eq("type", enumeration.ordinal())).list().size() == 0 ) return true;
return false;
return getSession()
.createCriteria(EmailNotification.class)
.add(Restrictions.eq("type", enumeration.ordinal()))
.list()
.size() == 0;
}
@Override
public boolean deleteById(EmailNotification notification) {
getSession().delete(notification);
if ( getSession().createCriteria(EmailNotification.class).add(Restrictions.eq("id", notification.getId()))
.uniqueResult() != null ) return false;
return true;
return getSession()
.createCriteria(EmailNotification.class)
.add(Restrictions.eq("id", notification.getId()))
.uniqueResult() == null;
}
}

View file

@ -19,60 +19,56 @@
package org.libreplan.business.email.daos;
import org.hibernate.criterion.Restrictions;
import org.libreplan.business.common.daos.GenericDAOHibernate;
import org.libreplan.business.common.exceptions.InstanceNotFoundException;
import org.libreplan.business.email.entities.EmailTemplate;
import org.libreplan.business.email.entities.EmailTemplateEnum;
import org.libreplan.business.settings.entities.Language;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* DAO for {@link EmailTemplate}
*
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 24.09.2015.
* @author Created by Vova Perebykivskiy <vova@libreplan-enterprise.com> on 24.09.2015.
*/
@Repository
public class EmailTemplateDAO extends GenericDAOHibernate<EmailTemplate, Long> implements IEmailTemplateDAO{
@Override
@Transactional(readOnly = true)
public List<EmailTemplate> getAll() {
return list(EmailTemplate.class);
}
@Override
public String getContentBySelectedLanguage(int languageOrdinal, int emailTemplateTypeOrdinal) {
for (int i = 0; i < list(EmailTemplate.class).size(); i++)
if ( list(EmailTemplate.class).get(i).getLanguage().ordinal() == languageOrdinal &&
list(EmailTemplate.class).get(i).getType().ordinal() == emailTemplateTypeOrdinal )
return list(EmailTemplate.class).get(i).getContent();
return "";
@Transactional(readOnly = true)
public List<EmailTemplate> findByType(EmailTemplateEnum type) {
return getSession()
.createCriteria(EmailTemplate.class)
.add(Restrictions.eq("type", type))
.list();
}
@Override
public String getContentBySelectedTemplate(int emailTemplateTypeOrdinal, int languageOrdinal) {
for (int i = 0; i < list(EmailTemplate.class).size(); i++)
if ( list(EmailTemplate.class).get(i).getType().ordinal() == emailTemplateTypeOrdinal &&
list(EmailTemplate.class).get(i).getLanguage().ordinal() == languageOrdinal )
return list(EmailTemplate.class).get(i).getContent();
return "";
@Transactional(readOnly = true)
public EmailTemplate findByTypeAndLanguage(EmailTemplateEnum type, Language language) {
return (EmailTemplate) getSession()
.createCriteria(EmailTemplate.class)
.add(Restrictions.eq("type", type))
.add(Restrictions.eq("language", language))
.uniqueResult();
}
@Override
public String getSubjectBySelectedLanguage(int languageOrdinal, int emailTemplateTypeOrdinal) {
for (int i = 0; i < list(EmailTemplate.class).size(); i++)
if ( list(EmailTemplate.class).get(i).getLanguage().ordinal() == languageOrdinal &&
list(EmailTemplate.class).get(i).getType().ordinal() == emailTemplateTypeOrdinal )
return list(EmailTemplate.class).get(i).getSubject();
return "";
}
@Override
public String getSubjectBySelectedTemplate(int emailTemplateTypeOrdinal, int languageOrdinal) {
for (int i = 0; i < list(EmailTemplate.class).size(); i++)
if ( list(EmailTemplate.class).get(i).getType().ordinal() == emailTemplateTypeOrdinal &&
list(EmailTemplate.class).get(i).getLanguage().ordinal() == languageOrdinal )
return list(EmailTemplate.class).get(i).getSubject();
return "";
@Transactional
public void delete(EmailTemplate entity) {
try {
remove(entity.getId());
} catch (InstanceNotFoundException ignored) {
}
}
}

View file

@ -28,15 +28,17 @@ import java.util.List;
/**
* Contract for {@link EmailNotificationDAO}
*
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 19.10.15.
* @author Created by Vova Perebykivskiy <vova@libreplan-enterprise.com> on 19.10.2015.
*/
public interface IEmailNotificationDAO extends IGenericDAO<EmailNotification, Long> {
List<EmailNotification> getAll();
List<EmailNotification> getAllByType(EmailTemplateEnum enumeration);
boolean deleteAll();
boolean deleteAllByType(EmailTemplateEnum enumeration);
boolean deleteById(EmailNotification notification);
}

View file

@ -21,6 +21,8 @@ package org.libreplan.business.email.daos;
import org.libreplan.business.common.daos.IGenericDAO;
import org.libreplan.business.email.entities.EmailTemplate;
import org.libreplan.business.email.entities.EmailTemplateEnum;
import org.libreplan.business.settings.entities.Language;
import java.util.List;
@ -28,17 +30,15 @@ import java.util.List;
* DAO interface for the <code>EmailTemplate</code> entity.
* Contract for {@link EmailTemplateDAO}
*
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 29.09.2015.
* @author Created by Vova Perebykivskiy <vova@libreplan-enterprise.com> on 29.09.2015.
*/
public interface IEmailTemplateDAO extends IGenericDAO<EmailTemplate, Long>{
List<EmailTemplate> getAll();
String getContentBySelectedLanguage(int languageOrdinal, int emailTemplateTypeOrdinal);
String getContentBySelectedTemplate(int emailTemplateTypeOrdinal, int languageOrdinal);
List<EmailTemplate> findByType(EmailTemplateEnum emailTemplateEnum);
String getSubjectBySelectedLanguage(int languageOrdinal, int emailTemplateTypeOrdinal);
String getSubjectBySelectedTemplate(int emailTemplateTypeOrdinal, int languageOrdinal);
EmailTemplate findByTypeAndLanguage(EmailTemplateEnum emailTemplateEnum, Language language);
void delete(EmailTemplate entity);
}

View file

@ -31,9 +31,7 @@ import java.util.Date;
* This class is intended to work as a Hibernate component.
* It represents the Email notification to be send to user.
*
* Created by
* @author Vova Perebykivskyi <vova@libreplan-enterprise.com>
* on 19.10.2015.
* @author Created by Vova Perebykivskyi <vova@libreplan-enterprise.com> on 19.10.2015.
*/
public class EmailNotification extends BaseEntity {

View file

@ -27,9 +27,7 @@ import org.libreplan.business.settings.entities.Language;
* This class is intended to work as a Hibernate component.
* It represents the E-mail template to be modified by admin and send to user.
*
* Created by
* @author Vova Perebykivskyi <vova@libreplan-enterprise.com>
* on 29.09.2015.
* @author Created by Vova Perebykivskyi <vova@libreplan-enterprise.com> on 29.09.2015.
*/
public class EmailTemplate extends BaseEntity {
@ -56,14 +54,14 @@ public class EmailTemplate extends BaseEntity {
}
public String getContent() {
return content;
return content != null ? content : "";
}
public void setContent(String content) {
this.content = content;
}
public String getSubject() {
return subject;
return subject != null ? subject : "";
}
public void setSubject(String subject) {
this.subject = subject;

View file

@ -24,9 +24,7 @@ import static org.libreplan.business.i18n.I18nHelper._;
/**
* Available E-mail templates.
*
* Created by
* @author Vova Perebykivskyi <vova@libreplan-enterprise.com>
* on 28.09.2015.
* @author Created by Vova Perebykivskyi <vova@libreplan-enterprise.com> on 28.09.2015.
*
* TEMPLATE_N(_("Template N")) - for i18n
* TEMPLATE_A("Template A") - for general use (no internationalizing)

View file

@ -20,8 +20,7 @@ package org.libreplan.business.planner.entities;
/**
* Manual allocation function, it used to represent when user has done a manual
* allocation.
* Manual allocation function, it used to represent when user has done a manual allocation.
*
* @author Manuel Rego Casasnovas <rego@igalia.com>
*/

View file

@ -45,19 +45,20 @@ import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
/**
* DAO for {@link QualityForm}
* DAO for {@link QualityForm}.
*
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
*/
@Repository
@Scope(BeanDefinition.SCOPE_SINGLETON)
public class QualityFormDAO extends GenericDAOHibernate<QualityForm, Long>
implements IQualityFormDAO {
public class QualityFormDAO extends GenericDAOHibernate<QualityForm, Long> implements IQualityFormDAO {
@Autowired
private IAdvanceTypeDAO advanceTypeDAO;
@Override
@Transactional(readOnly = true)
public List<QualityForm> getAll() {
return list(QualityForm.class);
}
@ -67,8 +68,7 @@ public class QualityFormDAO extends GenericDAOHibernate<QualityForm, Long>
public boolean isUnique(QualityForm qualityForm) {
try {
QualityForm result = findUniqueByName(qualityForm);
return (result == null || result.getId()
.equals(qualityForm.getId()));
return result == null || result.getId().equals(qualityForm.getId());
} catch (Exception e) {
e.printStackTrace();
return false;
@ -78,32 +78,33 @@ public class QualityFormDAO extends GenericDAOHibernate<QualityForm, Long>
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
public QualityForm findByNameAndType(String name, QualityFormType type) {
return (QualityForm) getSession().createCriteria(QualityForm.class)
.add(Restrictions.eq("name", name)).add(
Restrictions.eq("qualityFormType", type))
return (QualityForm) getSession()
.createCriteria(QualityForm.class)
.add(Restrictions.eq("name", name))
.add(Restrictions.eq("qualityFormType", type))
.uniqueResult();
}
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
public List<QualityForm> getAllByType(QualityFormType type) {
Criteria c = getSession().createCriteria(QualityForm.class).add(
Restrictions.eq("qualityFormType", type));
return ((List<QualityForm>) c.list());
return getSession()
.createCriteria(QualityForm.class)
.add(Restrictions.eq("qualityFormType", type))
.list();
}
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
public QualityForm findUniqueByName(QualityForm qualityForm)
throws InstanceNotFoundException {
public QualityForm findUniqueByName(QualityForm qualityForm) throws InstanceNotFoundException {
Validate.notNull(qualityForm);
return findUniqueByName(qualityForm.getName());
}
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
public QualityForm findUniqueByName(String name)
throws InstanceNotFoundException, NonUniqueResultException {
public QualityForm findUniqueByName(String name) throws InstanceNotFoundException, NonUniqueResultException {
Criteria c = getSession().createCriteria(QualityForm.class);
c.add(Restrictions.eq("name", name));
QualityForm qualityForm = (QualityForm) c.uniqueResult();
@ -119,7 +120,8 @@ public class QualityFormDAO extends GenericDAOHibernate<QualityForm, Long>
public boolean existsOtherWorkReportTypeByName(QualityForm qualityForm) {
try {
QualityForm t = findUniqueByName(qualityForm);
return (t != null && t != qualityForm);
return t != null && t != qualityForm;
} catch (InstanceNotFoundException e) {
return false;
}
@ -141,8 +143,9 @@ public class QualityFormDAO extends GenericDAOHibernate<QualityForm, Long>
advanceTypeDAO.save(advanceType);
advanceType.setUnitName(name);
} else {
advanceType = AdvanceType.create(name, new BigDecimal(100),
false, new BigDecimal(0.01), true, true, true);
advanceType = AdvanceType.create(
name, new BigDecimal(100), false, BigDecimal.valueOf(0.01), true, true, true);
advanceTypeDAO.save(advanceType);
entity.setAdvanceType(advanceType);
@ -154,14 +157,15 @@ public class QualityFormDAO extends GenericDAOHibernate<QualityForm, Long>
@Override
public void checkHasTasks(QualityForm qualityForm) throws ValidationException {
Query query = getSession().createQuery(
"FROM TaskQualityForm taskQualityForm JOIN taskQualityForm.qualityForm tq WHERE tq IN (:qualityForms)");
String queryString =
"FROM TaskQualityForm taskQualityForm JOIN taskQualityForm.qualityForm tq WHERE tq IN (:qualityForms)";
Query query = getSession().createQuery(queryString);
query.setParameterList("qualityForms", Collections.singleton(qualityForm));
if (!query.list().isEmpty()) {
throw ValidationException
.invalidValueException(
"Cannot delete quality form. It is being used at this moment by some task.",
qualityForm);
throw ValidationException.invalidValueException(
"Cannot delete quality form. It is being used at this moment by some task.", qualityForm);
}
}
}

View file

@ -32,11 +32,6 @@
</createIndex>
<sql>
INSERT INTO email_template VALUES(1, 0, 3, 'Task assigned to resource : Autogenerated content text', 'Autogenerated subject text');
INSERT INTO email_template VALUES(2, 1, 3, 'Resource removed from task : Autogenerated content text', 'Autogenerated subject text');
INSERT INTO email_template VALUES(3, 2, 3, 'Milestone reached : Autogenerated content text', 'Autogenerated subject text');
INSERT INTO email_template VALUES(4, 3, 3, 'Task should start : Autogenerated content text', 'Autogenerated subject text');
INSERT INTO email_template VALUES(5, 4, 3, 'Task should finish : Autogenerated content text', 'Autogenerated subject text');
INSERT INTO email_template VALUES(6, 5, 3, 'Enter data to timesheet : Autogenerated content text', 'Autogenerated subject text');
</sql>
</changeSet>

View file

@ -1,10 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
@ -16,8 +18,8 @@
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"
p:jndiName="${dataSource.jndiName}" p:resourceRef="true" />
<!-- Letting Spring do automatically exception translation -->
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<!-- Letting Spring do automatically exception translation -->
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<!-- Hibernate Session Factory. -->
<bean id="sessionFactory"
@ -110,8 +112,8 @@
<!-- Spring Transaction manager -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory" />
class="org.springframework.orm.hibernate5.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory" />
<!-- Enable configuration of transactional behavior based on annotations -->
<tx:annotation-driven transaction-manager="transactionManager" />

View file

@ -4,7 +4,7 @@
<hibernate-mapping package="org.libreplan.business.email.entities" default-access="field">
<class name="org.libreplan.business.email.entities.EmailTemplate" table="email_template">
<class name="EmailTemplate" table="email_template">
<id name="id" access="property" type="long">
<generator class="increment" >

View file

@ -79,9 +79,9 @@
<many-to-many class="SchedulingDataForVersion" column="scheduling_state_for_version_id" />
</map>
<one-to-one name="sumChargedEffort" class="SumChargedEffort" cascade="delete" property-ref="orderElement" />
<one-to-one name="sumChargedEffort" class="SumChargedEffort" cascade="delete-orphan" property-ref="orderElement" />
<one-to-one name="sumExpenses" class="SumExpenses" cascade="delete" property-ref="orderElement" />
<one-to-one name="sumExpenses" class="SumExpenses" cascade="delete-orphan" property-ref="orderElement" />
<joined-subclass name="OrderLineGroup" table="order_line_group">
<key column="order_element_id"/>

View file

@ -97,6 +97,9 @@
<value>
TestEntities.hbm.xml
</value>
<value>
org/libreplan/business/common/entities/Limits.hbm.xml
</value>
</list>
</property>

View file

@ -394,9 +394,8 @@
<!-- Java mail -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.5.0-b01</version>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
</dependency>
<!-- JAX-RS API -->

View file

@ -34,9 +34,7 @@ import static org.libreplan.web.I18nHelper._;
* Sends E-mail to users with data that storing in notification_queue table
* and that are treat to incoming EmailNotification
*
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 20.01.2016.
* @author Created by Vova Perebykivskiy <vova@libreplan-enterprise.com> on 20.01.2016.
*/
@Component
@ -76,7 +74,8 @@ public class ComposeMessage {
UserRole currentUserRole = getCurrentUserRole(notification.getType());
if ( currentWorker.getUser().isInRole(currentUserRole) ){
if ( currentWorker.getUser().isInRole(currentUserRole) ) {
if ( currentWorker.getUser().getApplicationLanguage().equals(Language.BROWSER_LANGUAGE) ) {
locale = new Locale(System.getProperty("user.language"));
} else {
@ -96,16 +95,15 @@ public class ComposeMessage {
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);
}
});
// 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{
try {
MimeMessage message = new MimeMessage(mailSession);
message.setFrom(new InternetAddress(sender));
@ -122,37 +120,42 @@ public class ComposeMessage {
} 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();
}
} 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){
private Worker getCurrentWorker(Long resourceID) {
List<Worker> workerList = workerModel.getWorkers();
for(int i = 0; i < workerList.size(); i++)
if ( workerList.get(i).getId().equals(resourceID) )
return workerList.get(i);
for (Worker current : workerList)
if ( current.getId().equals(resourceID) )
return current;
return null;
}
private EmailTemplate findCurrentEmailTemplate(EmailTemplateEnum templateEnum, Locale locale){
private EmailTemplate findCurrentEmailTemplate(EmailTemplateEnum templateEnum, Locale locale) {
List<EmailTemplate> emailTemplates;
emailTemplates = emailTemplateModel.getAll();
for (EmailTemplate item : emailTemplates)
if ( item.getType().equals(templateEnum) && item.getLanguage().getLocale().equals(locale) )
return item;
return null;
}
private String replaceKeywords(String text, Worker currentWorker, EmailNotification notification){
if ( notification.getType().equals(EmailTemplateEnum.TEMPLATE_ENTER_DATA_IN_TIMESHEET) ){
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());
@ -172,38 +175,41 @@ public class ComposeMessage {
private void setupConnectionProperties(){
List<ConnectorProperty> emailConnectorProperties = emailConnectionValidator.getEmailConnectorProperties();
for (int i = 0; i < emailConnectorProperties.size(); i++){
switch (i){
case 1: {
for (int i = 0; i < emailConnectorProperties.size(); i++) {
switch (i) {
case 1:
protocol = emailConnectorProperties.get(1).getValue();
break;
}
case 2: {
case 2:
host = emailConnectorProperties.get(2).getValue();
break;
}
case 3: {
case 3:
port = emailConnectorProperties.get(3).getValue();
break;
}
case 4: {
case 4:
sender = emailConnectorProperties.get(4).getValue();
break;
}
case 5: {
case 5:
usrnme = emailConnectorProperties.get(5).getValue();
break;
}
case 6: {
case 6:
psswrd = emailConnectorProperties.get(6).getValue();
break;
}
default:
/* Nothing */
break;
}
}
properties = new Properties();
if ( protocol.equals("STARTTLS") ) {
if ( "STARTTLS".equals(protocol) ) {
properties.put("mail.smtp.starttls.enable", "true");
properties.put("mail.smtp.host", host);
properties.put("mail.smtp.socketFactory.port", port);
@ -211,27 +217,36 @@ public class ComposeMessage {
properties.put("mail.smtp.auth", "true");
properties.put("mail.smtp.port", port);
}
else if ( protocol.equals("SMTP") ) {
else if ( "SMTP".equals(protocol) ) {
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;
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_RESOURCE_REMOVED_FROM_TASK:
return UserRole.ROLE_EMAIL_RESOURCE_REMOVED_FROM_TASK;
case TEMPLATE_MILESTONE_REACHED: return UserRole.ROLE_EMAIL_MILESTONE_REACHED;
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_START:
return UserRole.ROLE_EMAIL_TASK_SHOULD_START;
case TEMPLATE_TODAY_TASK_SHOULD_FINISH: return UserRole.ROLE_EMAIL_TASK_SHOULD_FINISH;
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;
case TEMPLATE_ENTER_DATA_IN_TIMESHEET:
return UserRole.ROLE_EMAIL_TIMESHEET_DATA_MISSING;
default:
/* There is no other template */
return null;
}
return null;
}
}

View file

@ -28,7 +28,6 @@ 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;
@ -37,9 +36,7 @@ import java.util.Properties;
/**
* Validate Email Connection properties
*
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 20.01.2016.
* @author Created by Vova Perebykivskyi <vova@libreplan-enterprise.com> on 20.01.2016.
*/
@Component
@ -49,7 +46,10 @@ public class EmailConnectionValidator {
@Autowired
private IConnectorDAO connectorDAO;
public boolean validConnection(){
/* Needed for EmailTest */
public static Exception exceptionType;
public boolean validConnection() {
List<ConnectorProperty> emailConnectorProperties = getEmailConnectorProperties();
String protocol = null;
@ -58,28 +58,31 @@ public class EmailConnectionValidator {
String usrnme = null;
String psswrd = null;
for (int i = 0; i < emailConnectorProperties.size(); i++){
switch (i){
case 1: {
for (int i = 0; i < emailConnectorProperties.size(); i++) {
switch ( i ) {
case 1:
protocol = emailConnectorProperties.get(1).getValue();
break;
}
case 2: {
case 2:
host = emailConnectorProperties.get(2).getValue();
break;
}
case 3: {
case 3:
port = emailConnectorProperties.get(3).getValue();
break;
}
case 5: {
case 5:
usrnme = emailConnectorProperties.get(5).getValue();
break;
}
case 6: {
case 6:
psswrd = emailConnectorProperties.get(6).getValue();
break;
}
default:
/* Nothing */
break;
}
}
@ -89,48 +92,53 @@ public class EmailConnectionValidator {
Transport transport = null;
try {
if (protocol.equals("SMTP")) {
if ( protocol.equals("SMTP") ) {
properties.setProperty("mail.smtp.port", port);
properties.setProperty("mail.smtp.host", host);
properties.setProperty("mail.smtp.connectiontimeout", Integer.toString(3000));
Session session = Session.getInstance(properties, null);
transport = session.getTransport("smtp");
if (usrnme.equals("") && psswrd.equals("")) transport.connect();
} else if (protocol.equals("STARTTLS")) {
if ( "".equals(usrnme) && "".equals(psswrd) )
transport.connect();
} else if ( protocol.equals("STARTTLS") ) {
properties.setProperty("mail.smtps.port", port);
properties.setProperty("mail.smtps.host", host);
properties.setProperty("mail.smtp.connectiontimeout", Integer.toString(3000));
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) {
if ( !"".equals(usrnme) && psswrd != null )
transport.connect(host, usrnme, psswrd);
}
if ( transport != null && transport.isConnected() )
return true;
} catch (MessagingException e) {
e.printStackTrace();
// FIXME must be a better way to send exception type to test class
exceptionType = e;
}
return false;
}
public List<ConnectorProperty> getEmailConnectorProperties() {
Connector connector = connectorDAO.findUniqueByName("E-mail");
return connector.getProperties();
}
public boolean isConnectionActivated(){
public boolean isConnectionActivated() {
List<ConnectorProperty> emailConnectorProperties = getEmailConnectorProperties();
for (ConnectorProperty item : emailConnectorProperties){
for (ConnectorProperty item : emailConnectorProperties) {
if ( item.getKey().equals("Activated") )
if ( item.getValue().equals("Y") )
return true;
else break;
else break;
}
return false;
}

View file

@ -22,15 +22,15 @@ package org.libreplan.importers.notifications;
import org.libreplan.business.email.entities.EmailNotification;
/**
* Sends E-mail to users with data that storing in notification_queue table
* Sends E-mail to users with data that storing in notification_queue table.
*
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 13.10.2015.
* @author Created by Vova Perebykivskyi <vova@libreplan-enterprise.com> on 13.10.2015.
*/
public interface IEmailNotificationJob {
void sendEmail();
boolean composeMessageForUser(EmailNotification notification);
}

View file

@ -27,22 +27,20 @@ import org.springframework.scheduling.quartz.QuartzJobBean;
/**
* Sends E-mail to users with data that storing in notification_queue table
* and that are treat to {@link EmailTemplateEnum.TEMPLATE_RESOURCE_REMOVED_FROM_TASK}
*
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 20.01.2016.
* and that are treat to
* {@link org.libreplan.business.email.entities.EmailTemplateEnum#TEMPLATE_RESOURCE_REMOVED_FROM_TASK}
*
* @author Created by Vova Perebykivskiy <vova@libreplan-enterprise.com> on 20.01.2016.
*/
public class SendEmailOnResourceRemovedFromTaskJob extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
ApplicationContext applicationContext = (ApplicationContext) context.getJobDetail().
getJobDataMap().get("applicationContext");
ApplicationContext applicationContext =
(ApplicationContext) context.getJobDetail().getJobDataMap().get("applicationContext");
IEmailNotificationJob resourceRemovedFromTask = (IEmailNotificationJob) applicationContext
.getBean("SendEmailOnResourceRemovedFromTask");
IEmailNotificationJob resourceRemovedFromTask =
(IEmailNotificationJob) applicationContext.getBean("SendEmailOnResourceRemovedFromTask");
resourceRemovedFromTask.sendEmail();
}

View file

@ -28,23 +28,21 @@ 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 <vova@libreplan-enterprise.com>
* on 13.10.2015.
* and that are treat to
* {@link org.libreplan.business.email.entities.EmailTemplateEnum#TEMPLATE_TASK_ASSIGNED_TO_RESOURCE}
*
* @author Created by Vova Perebykivskiy <vova@libreplan-enterprise.com> on 13.10.2015.
*/
public class SendEmailOnTaskAssignedToResourceJob extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
ApplicationContext applicationContext = (ApplicationContext) context.getJobDetail().
getJobDataMap().get("applicationContext");
ApplicationContext applicationContext =
(ApplicationContext) context.getJobDetail().getJobDataMap().get("applicationContext");
IEmailNotificationJob taskAssignedToResource = (IEmailNotificationJob) applicationContext
.getBean("SendEmailOnTaskAssignedToResource");
IEmailNotificationJob taskAssignedToResource =
(IEmailNotificationJob) applicationContext.getBean("SendEmailOnTaskAssignedToResource");
taskAssignedToResource.sendEmail();
}

View file

@ -27,22 +27,21 @@ import org.springframework.scheduling.quartz.QuartzJobBean;
/**
* Sends E-mail to users with data that storing in notification_queue table
* and that are treat to {@link EmailTemplateEnum.TEMPLATE_TODAY_TASK_SHOULD_FINISH}
*
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 20.01.2016.
* and that are treat to
* {@link org.libreplan.business.email.entities.EmailTemplateEnum#TEMPLATE_TODAY_TASK_SHOULD_FINISH}
*
* @author Created by Vova Perebykivskiy <vova@libreplan-enterprise.com> on 20.01.2016.
*/
public class SendEmailOnTaskShouldFinishJob extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
ApplicationContext applicationContext = (ApplicationContext) context.getJobDetail().
getJobDataMap().get("applicationContext");
IEmailNotificationJob taskShouldFinish = (IEmailNotificationJob) applicationContext
.getBean("SendEmailOnTaskShouldFinish");
ApplicationContext applicationContext =
(ApplicationContext) context.getJobDetail().getJobDataMap().get("applicationContext");
IEmailNotificationJob taskShouldFinish =
(IEmailNotificationJob) applicationContext.getBean("SendEmailOnTaskShouldFinish");
taskShouldFinish.sendEmail();
}

View file

@ -27,22 +27,22 @@ 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}
* and that are treat to
* {@link org.libreplan.business.email.entities.EmailTemplateEnum#TEMPLATE_TODAY_TASK_SHOULD_START}.
*
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 20.01.2016.
*
* @author Created by Vova Perebykivskyi <vova@libreplan-enterprise.com> on 20.01.2016
*/
public class SendEmailOnTaskShouldStartJob extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
ApplicationContext applicationContext = (ApplicationContext) context.getJobDetail().
getJobDataMap().get("applicationContext");
IEmailNotificationJob taskShouldStart = (IEmailNotificationJob) applicationContext
.getBean("SendEmailOnTaskShouldStart");
ApplicationContext applicationContext = (ApplicationContext)
context.getJobDetail().getJobDataMap().get("applicationContext");
IEmailNotificationJob taskShouldStart =
(IEmailNotificationJob) applicationContext.getBean("SendEmailOnTaskShouldStart");
taskShouldStart.sendEmail();
}

View file

@ -27,22 +27,20 @@ import org.springframework.scheduling.quartz.QuartzJobBean;
/**
* Sends E-mail to users with data that storing in notification_queue table
* and that are treat to {@link EmailTemplateEnum.TEMPLATE_ENTER_DATA_IN_TIMESHEET}
*
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 20.01.2016.
* and that are treat to
* {@link org.libreplan.business.email.entities.EmailTemplateEnum#TEMPLATE_ENTER_DATA_IN_TIMESHEET}
*
* @author Created by Vova Perebykivskiy <vova@libreplan-enterprise.com> on 20.01.2016.
*/
public class SendEmailOnTimesheetDataMissingJob extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
ApplicationContext applicationContext = (ApplicationContext) context.getJobDetail().
getJobDataMap().get("applicationContext");
ApplicationContext applicationContext =
(ApplicationContext) context.getJobDetail().getJobDataMap().get("applicationContext");
IEmailNotificationJob timesheetMissing = (IEmailNotificationJob) applicationContext
.getBean("SendEmailOnTimesheetDataMissing");
IEmailNotificationJob timesheetMissing =
(IEmailNotificationJob) applicationContext.getBean("SendEmailOnTimesheetDataMissing");
timesheetMissing.sendEmail();
}

View file

@ -39,7 +39,6 @@ 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;
@ -51,9 +50,7 @@ import java.util.List;
* Date will be send on current date equals to deadline date of {@link Milestone}
* But it will be only send to Manager (you can assign him in project properties)
*
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 20.01.2016.
* @author Created by Vova Perebykivskyi <vova@libreplan-enterprise.com> on 20.01.2016
*/
@Component
@ -80,18 +77,16 @@ public class SendEmailOnMilestoneReached implements IEmailNotificationJob {
// Gathering data
checkMilestoneDate();
if ( Configuration.isEmailSendingEnabled() ){
if ( Configuration.isEmailSendingEnabled() ) {
if ( emailConnectionValidator.isConnectionActivated() )
if ( emailConnectionValidator.isConnectionActivated() && emailConnectionValidator.validConnection() ) {
if ( emailConnectionValidator.validConnection() ){
List<EmailNotification> notifications =
emailNotificationModel.getAllByType(EmailTemplateEnum.TEMPLATE_MILESTONE_REACHED);
List<EmailNotification> notifications = emailNotificationModel
.getAllByType(EmailTemplateEnum.TEMPLATE_MILESTONE_REACHED);
for (int i = 0; i < notifications.size(); i++)
if ( composeMessageForUser(notifications.get(i)) )
deleteSingleNotification(notifications.get(i));
for (EmailNotification notification : notifications)
if ( composeMessageForUser(notification) )
deleteSingleNotification(notification);
}
}
}
@ -144,9 +139,7 @@ public class SendEmailOnMilestoneReached implements IEmailNotificationJob {
int deadlineMonth = deadline.getMonthOfYear();
int deadlineDay = deadline.getDayOfMonth();
if (currentYear == deadlineYear &&
currentMonth == deadlineMonth &&
currentDay == deadlineDay)
if ( currentYear == deadlineYear && currentMonth == deadlineMonth && currentDay == deadlineDay )
sendEmailNotificationToManager(item);
}
}

View file

@ -36,12 +36,10 @@ 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
* and that are treat to {@link EmailTemplateEnum#TEMPLATE_RESOURCE_REMOVED_FROM_TASK}
* Data will be send if resource has been removed from task (in resource allocation)
*
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 20.01.2016.
* @author Created by Vova Perebykivskiy <vova@libreplan-enterprise.com> on 20.01.2016.
*/
@Component
@ -61,14 +59,11 @@ public class SendEmailOnResourceRemovedFromTask implements IEmailNotificationJob
public void sendEmail() {
// At this time all data have gathered, if it exists of course
if ( Configuration.isEmailSendingEnabled() ){
if ( Configuration.isEmailSendingEnabled() ) {
if ( emailConnectionValidator.isConnectionActivated() && emailConnectionValidator.validConnection() ) {
if ( emailConnectionValidator.isConnectionActivated() )
if ( emailConnectionValidator.validConnection() ){
List<EmailNotification> notifications = emailNotificationModel
.getAllByType(EmailTemplateEnum.TEMPLATE_RESOURCE_REMOVED_FROM_TASK);
List<EmailNotification> notifications =
emailNotificationModel.getAllByType(EmailTemplateEnum.TEMPLATE_RESOURCE_REMOVED_FROM_TASK);
for (int i = 0; i < notifications.size(); i++)
if ( composeMessageForUser(notifications.get(i)) )

View file

@ -38,12 +38,10 @@ 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}
* and that are treat to {@link EmailTemplateEnum#TEMPLATE_ENTER_DATA_IN_TIMESHEET}
* Data will be send after user will be assigned to some task.
*
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 13.10.2015.
* @author Created by Vova Perebykivskyi <vova@libreplan-enterprise.com> on 13.10.2015.
*/
@Component
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
@ -61,18 +59,16 @@ public class SendEmailOnTaskAssignedToResource implements IEmailNotificationJob
@Override
@Transactional
public void sendEmail() {
if ( Configuration.isEmailSendingEnabled() ){
if ( Configuration.isEmailSendingEnabled() ) {
if ( emailConnectionValidator.isConnectionActivated() )
if ( emailConnectionValidator.isConnectionActivated() && emailConnectionValidator.validConnection() ) {
if ( emailConnectionValidator.validConnection() ){
List<EmailNotification> notifications =
emailNotificationModel.getAllByType(EmailTemplateEnum.TEMPLATE_TASK_ASSIGNED_TO_RESOURCE);
List<EmailNotification> notifications = emailNotificationModel
.getAllByType(EmailTemplateEnum.TEMPLATE_TASK_ASSIGNED_TO_RESOURCE);
for (int i = 0; i < notifications.size(); i++)
if ( composeMessageForUser(notifications.get(i)) )
deleteSingleNotification(notifications.get(i));
for (EmailNotification notification : notifications)
if ( composeMessageForUser(notification) )
deleteSingleNotification(notification);
}
}
}

View file

@ -44,12 +44,10 @@ 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}
* and that are treat to {@link EmailTemplateEnum#TEMPLATE_TODAY_TASK_SHOULD_FINISH}
* Data will be send when current day equals to finish date.
*
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 21.01.2016.
* @author Created by Vova Perebykivskiy <vova@libreplan-enterprise.com> on 21.01.2016.
*/
@Component
@ -73,14 +71,11 @@ public class SendEmailOnTaskShouldFinish implements IEmailNotificationJob {
// Gather data for email sending
taskShouldFinish();
if ( Configuration.isEmailSendingEnabled() ){
if ( Configuration.isEmailSendingEnabled() ) {
if ( emailConnectionValidator.isConnectionActivated() && emailConnectionValidator.validConnection() ) {
if ( emailConnectionValidator.isConnectionActivated() )
if ( emailConnectionValidator.validConnection() ){
List<EmailNotification> notifications = emailNotificationModel
.getAllByType(EmailTemplateEnum.TEMPLATE_TODAY_TASK_SHOULD_FINISH);
List<EmailNotification> notifications =
emailNotificationModel.getAllByType(EmailTemplateEnum.TEMPLATE_TODAY_TASK_SHOULD_FINISH);
for (int i = 0; i < notifications.size(); i++)
if ( composeMessageForUser(notifications.get(i)) )
@ -100,6 +95,7 @@ public class SendEmailOnTaskShouldFinish implements IEmailNotificationJob {
@Transactional
public void taskShouldFinish() {
// TODO resolve deprecated
// Check if current date equals with item date
Date date = new Date();
int currentYear = date.getYear();
@ -115,7 +111,7 @@ public class SendEmailOnTaskShouldFinish implements IEmailNotificationJob {
if ( currentYear == endYear &&
currentMonth == endMonth &&
currentDay == endDay ){
currentDay == endDay ) {
// Get all resources for current task and send them email notification
sendEmailNotificationAboutTaskShouldFinish(item);
}
@ -124,10 +120,10 @@ public class SendEmailOnTaskShouldFinish implements IEmailNotificationJob {
private void sendEmailNotificationAboutTaskShouldFinish(TaskElement item){
List<ResourceAllocation<?>> list = new ArrayList<ResourceAllocation<?>>();
List<ResourceAllocation<?>> list = new ArrayList<>();
list.addAll(item.getAllResourceAllocations());
List<Resource> resources = new ArrayList<Resource>();
List<Resource> resources = new ArrayList<>();
for (ResourceAllocation<?> allocation : list)
resources.add(allocation.getAssociatedResources().get(0));

View file

@ -44,12 +44,10 @@ 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}
* and that are treat to {@link EmailTemplateEnum#TEMPLATE_TODAY_TASK_SHOULD_START}
* Data will be send if current data equals to start date.
*
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 20.01.2016.
* @author Created by Vova Perebykivskyi <vova@libreplan-enterprise.com> on 20.01.2016.
*/
@Component
@ -73,18 +71,16 @@ public class SendEmailOnTaskShouldStart implements IEmailNotificationJob {
// Gather data
taskShouldStart();
if ( Configuration.isEmailSendingEnabled() ){
if ( Configuration.isEmailSendingEnabled() ) {
if ( emailConnectionValidator.isConnectionActivated() )
if ( emailConnectionValidator.isConnectionActivated() && emailConnectionValidator.validConnection() ) {
if ( emailConnectionValidator.validConnection() ){
List<EmailNotification> notifications =
emailNotificationModel.getAllByType(EmailTemplateEnum.TEMPLATE_TODAY_TASK_SHOULD_START);
List<EmailNotification> notifications = emailNotificationModel
.getAllByType(EmailTemplateEnum.TEMPLATE_TODAY_TASK_SHOULD_START);
for (int i = 0; i < notifications.size(); i++)
if ( composeMessageForUser(notifications.get(i)) )
deleteSingleNotification(notifications.get(i));
for (EmailNotification notification : notifications)
if ( composeMessageForUser(notification) )
deleteSingleNotification(notification);
}
}
}
@ -102,35 +98,34 @@ public class SendEmailOnTaskShouldStart implements IEmailNotificationJob {
public void taskShouldStart() {
// Check if current date equals with item date
Date date = new Date();
// TODO resolve deprecated
int currentYear = date.getYear();
int currentMonth = date.getMonth();
int currentDay = date.getDay();
List<TaskElement> tasks = taskElementDAO.getTaskElementsWithParentsWithoutMilestones();
for (TaskElement item : tasks){
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){
if ( currentYear == startYear && currentMonth == startMonth && currentDay == startDay ) {
// Get all resources for current task and send them email notification
sendEmailNotificationAboutTaskShouldStart(item);
}
}
}
private void sendEmailNotificationAboutTaskShouldStart(TaskElement item){
List<ResourceAllocation<?>> list = new ArrayList<ResourceAllocation<?>>();
private void sendEmailNotificationAboutTaskShouldStart(TaskElement item) {
List<ResourceAllocation<?>> list = new ArrayList<>();
list.addAll(item.getAllResourceAllocations());
List<Resource> resources = new ArrayList<Resource>();
List<Resource> resources = new ArrayList<>();
for (ResourceAllocation<?> allocation : list)
resources.add(allocation.getAssociatedResources().get(0));
for (Resource resourceItem : resources){
for (Resource resourceItem : resources) {
emailNotificationModel.setNewObject();
emailNotificationModel.setType(EmailTemplateEnum.TEMPLATE_TODAY_TASK_SHOULD_START);
emailNotificationModel.setUpdated(new Date());

View file

@ -60,12 +60,10 @@ 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}
* and that are treat to {@link EmailTemplateEnum#TEMPLATE_ENTER_DATA_IN_TIMESHEET}
* Data will be send for bound users with empty timesheet lines.
*
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 20.01.2016.
* @author Created by Vova Perebykivskiy <vova@libreplan-enterprise.com> on 20.01.2016.
*/
@Component
@ -95,14 +93,11 @@ public class SendEmailOnTimesheetDataMissing implements IEmailNotificationJob {
public void sendEmail() {
checkTimesheet();
if ( Configuration.isEmailSendingEnabled() ){
if ( Configuration.isEmailSendingEnabled() ) {
if ( emailConnectionValidator.isConnectionActivated() && emailConnectionValidator.validConnection() ) {
if ( emailConnectionValidator.isConnectionActivated() )
if ( emailConnectionValidator.validConnection() ){
List<EmailNotification> notifications = emailNotificationModel
.getAllByType(EmailTemplateEnum.TEMPLATE_ENTER_DATA_IN_TIMESHEET);
List<EmailNotification> notifications =
emailNotificationModel.getAllByType(EmailTemplateEnum.TEMPLATE_ENTER_DATA_IN_TIMESHEET);
for (int i = 0; i < notifications.size(); i++)
if ( composeMessageForUser(notifications.get(i)) )
@ -128,8 +123,8 @@ public class SendEmailOnTimesheetDataMissing implements IEmailNotificationJob {
@Transactional
private List<User> getPersonalTimesheets() {
List<PersonalTimesheetDTO> personalTimesheetDTO = new ArrayList<PersonalTimesheetDTO>();
List<User> usersWithoutTimesheets = new ArrayList<User>();
List<PersonalTimesheetDTO> personalTimesheetDTO = new ArrayList<>();
List<User> usersWithoutTimesheets = new ArrayList<>();
List<User> users = userModel.getUsers();
for (User user : users)
@ -139,11 +134,15 @@ public class SendEmailOnTimesheetDataMissing implements IEmailNotificationJob {
LocalDate activationDate = getActivationDate(user.getWorker());
LocalDate currentDate = new LocalDate();
personalTimesheetDTO.addAll(getPersonalTimesheets(user.getWorker(), activationDate,
currentDate.plusMonths(1), getPersonalTimesheetsPeriodicity()));
personalTimesheetDTO.addAll(getPersonalTimesheets(
user.getWorker(),
activationDate,
currentDate.plusMonths(1),
getPersonalTimesheetsPeriodicity()));
for(PersonalTimesheetDTO item : personalTimesheetDTO){
for(PersonalTimesheetDTO item : personalTimesheetDTO) {
WorkReport workReport = item.getWorkReport();
if ( item.getTasksNumber() == 0 && workReport == null )
if ( !usersWithoutTimesheets.contains(user) )
usersWithoutTimesheets.add(user);
@ -173,10 +172,9 @@ public class SendEmailOnTimesheetDataMissing implements IEmailNotificationJob {
end = periodicity.getEnd(end);
int items = periodicity.getItemsBetween(start, end);
List<PersonalTimesheetDTO> result = new ArrayList<PersonalTimesheetDTO>();
List<PersonalTimesheetDTO> result = new ArrayList<>();
// In decreasing order to provide a list sorted with the more recent
// personal timesheets at the beginning
// 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);
@ -189,28 +187,31 @@ public class SendEmailOnTimesheetDataMissing implements IEmailNotificationJob {
tasksNumber = getNumberOfOrderElementsWithTrackedTime(workReport);
}
result.add(new PersonalTimesheetDTO(date, workReport,
getResourceCapcity(resource, date, periodicity), hours,
result.add(new PersonalTimesheetDTO(
date,
workReport,
getResourceCapcity(resource, date, periodicity),
hours,
tasksNumber));
}
return result;
}
private LocalDate getActivationDate(Worker worker) {
return worker.getCalendar().getFistCalendarAvailability()
.getStartDate();
return worker.getCalendar().getFistCalendarAvailability().getStartDate();
}
private PersonalTimesheetsPeriodicityEnum getPersonalTimesheetsPeriodicity() {
return configurationDAO.getConfiguration()
.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) {
@ -226,7 +227,7 @@ public class SendEmailOnTimesheetDataMissing implements IEmailNotificationJob {
return 0;
}
List<OrderElement> orderElements = new ArrayList<OrderElement>();
List<OrderElement> orderElements = new ArrayList<>();
for (WorkReportLine line : workReport.getWorkReportLines()) {
if (!line.getEffort().isZero()) {
OrderElement orderElement = line.getOrderElement();
@ -239,14 +240,13 @@ public class SendEmailOnTimesheetDataMissing implements IEmailNotificationJob {
}
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)));
for (LocalDate day = start; day.compareTo(end) <= 0; day = day.plusDays(1)) {
capacity = capacity.plus(resource.getCalendar().getCapacityOn(IntraDayDate.PartialDay.wholeDay(day)));
}
return capacity;
}

View file

@ -37,15 +37,14 @@ import org.libreplan.importers.SynchronizationInfo;
public interface IJobSchedulerModel {
/**
* returns all job scheduler configurations
* Returns all job scheduler configurations.
*
* @return list of <code>JobSchedulerConfiguration</code>
*/
List<JobSchedulerConfiguration> getJobSchedulerConfigurations();
/**
* returns next fire time for the specified job from
* <code>{@link JobSchedulerConfiguration}</code>
* Returns next fire time for the specified job from <code>{@link JobSchedulerConfiguration}</code>.
*
* @param jobSchedulerConfiguration
* the job scheduler configuration
@ -53,18 +52,17 @@ public interface IJobSchedulerModel {
String getNextFireTime(JobSchedulerConfiguration jobSchedulerConfiguration);
/**
* Do manual action(replacement of scheduling)
* Do manual action(replacement of scheduling).
*
* @param jobSchedulerConfiguration
* the job configuration
* @throws ConnectorException
* if connector is not valid
*/
void doManual(JobSchedulerConfiguration jobSchedulerConfiguration)
throws ConnectorException;
void doManual(JobSchedulerConfiguration jobSchedulerConfiguration) throws ConnectorException;
/**
* Returns synchronization infos. Failures or successes info
* Returns synchronization infos. Failures or successes info.
*/
List<SynchronizationInfo> getSynchronizationInfos();
@ -74,7 +72,7 @@ public interface IJobSchedulerModel {
void initCreate();
/**
* Prepares for edit {@link JobSchedulerConfiguration}
* Prepares for edit {@link JobSchedulerConfiguration}.
*
* @param jobSchedulerConfiguration
* object to be edited
@ -89,7 +87,7 @@ public interface IJobSchedulerModel {
JobSchedulerConfiguration getJobSchedulerConfiguration();
/**
* Saves the current {@link JobSchedulerConfiguration}
* Saves the current {@link JobSchedulerConfiguration}.
*
* @throws ValidationException
* if validation fails
@ -97,12 +95,12 @@ public interface IJobSchedulerModel {
void confirmSave() throws ValidationException;
/**
* Cancels the current {@link JobSchedulerConfiguration}
* Cancels the current {@link JobSchedulerConfiguration}.
*/
void cancel();
/**
* Removes the current {@link JobSchedulerConfiguration}
* Removes the current {@link JobSchedulerConfiguration}.
*
* @param jobSchedulerConfiguration
* object to be removed
@ -110,16 +108,15 @@ public interface IJobSchedulerModel {
void remove(JobSchedulerConfiguration jobSchedulerConfiguration);
/**
* returns list of connectors
* Returns list of connectors
*/
List<Connector> getConnectors();
/**
* Schedule or unschedule jobs for the specified <code>connector</code>
* Schedule or unschedule jobs for the specified <code>connector</code>.
*
* schedule all jobs of the specified <code>connector</code>'s property
* {@link PredefinedConnectorProperties#ACTIVATED} is 'Y', otherwise
* unschedule the jobs
* Schedule all jobs of the specified <code>connector</code>'s property
* {@link PredefinedConnectorProperties#ACTIVATED} is 'Y', otherwise unschedule the jobs.
*
* @param connector
* where to check if property is changed
@ -128,22 +125,20 @@ public interface IJobSchedulerModel {
boolean scheduleOrUnscheduleJobs(Connector connector);
/**
* schedule or unschedule job for the specified job in
* <code>{@link JobSchedulerConfiguration}</code>
* Schedule or unschedule job for the specified job in <code>{@link JobSchedulerConfiguration}</code>.
*
* @return true if scheduling is succeeded, false otherwise
*/
boolean scheduleOrUnscheduleJob();
/**
* Delete job specified in <code>{@link JobSchedulerConfiguration}</code>
* Delete job specified in <code>{@link JobSchedulerConfiguration}</code>.
*
* @param jobSchedulerConfiguration
* configuration for the job to be deleted
* @return true if job is successfully deleted from the scheduler, false
* otherwise
*/
boolean deleteScheduledJob(
JobSchedulerConfiguration jobSchedulerConfiguration);
boolean deleteScheduledJob(JobSchedulerConfiguration jobSchedulerConfiguration);
}

View file

@ -42,7 +42,6 @@ import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.SuspendNotAllowedException;
import org.zkoss.zk.ui.WrongValueException;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zul.Button;
@ -52,7 +51,6 @@ import org.zkoss.zul.Hbox;
import org.zkoss.zul.Label;
import org.zkoss.zul.Listbox;
import org.zkoss.zul.Popup;
import org.zkoss.zul.Row;
import org.zkoss.zul.RowRenderer;
import org.zkoss.zul.SimpleListModel;
import org.zkoss.zul.api.Caption;
@ -64,27 +62,30 @@ import org.zkoss.zul.api.Window;
*
* @author Miciele Ghiorghis <m.ghiorghis@antoniusziekenhuis.nl>
*/
public class JobSchedulerController extends
BaseCRUDController<JobSchedulerConfiguration> {
public class JobSchedulerController extends BaseCRUDController<JobSchedulerConfiguration> {
private static final Log LOG = LogFactory
.getLog(JobSchedulerController.class);
private Grid listJobSchedulings;
private Grid cronExpressionGrid;
private static final Log LOG = LogFactory.getLog(JobSchedulerController.class);
private Popup cronExpressionInputPopup;
private Label jobGroup;
private Label jobName;
private Textbox cronExpressionTextBox;
private Textbox cronExpressionSeconds;
private Textbox cronExpressionMinutes;
private Textbox cronExpressionHours;
private Textbox cronExpressionDayOfMonth;
private Textbox cronExpressionMonth;
private Textbox cronExpressionDayOfWeek;
private Textbox cronExpressionYear;
private IJobSchedulerModel jobSchedulerModel;
@ -92,71 +93,67 @@ public class JobSchedulerController extends
@Override
public void doAfterCompose(Component comp) throws Exception {
super.doAfterCompose(comp);
listJobSchedulings = (Grid) listWindow
.getFellowIfAny("listJobSchedulings");
Grid listJobSchedulings = (Grid) listWindow.getFellowIfAny("listJobSchedulings");
listJobSchedulings.getModel();
initCronExpressionPopup();
}
/**
* initializes cron expressions for popup
* Initializes cron expressions for popup
*/
private void initCronExpressionPopup() {
cronExpressionTextBox = (Textbox) editWindow
.getFellow("cronExpressionTextBox");
cronExpressionTextBox = (Textbox) editWindow.getFellow("cronExpressionTextBox");
cronExpressionInputPopup = (Popup) editWindow
.getFellow("cronExpressionInputPopup");
cronExpressionInputPopup = (Popup) editWindow.getFellow("cronExpressionInputPopup");
jobGroup = (Label) cronExpressionInputPopup.getFellow("jobGroup");
jobName = (Label) cronExpressionInputPopup.getFellow("jobName");
cronExpressionGrid = (Grid) cronExpressionInputPopup
.getFellow("cronExpressionGrid");
Grid cronExpressionGrid = (Grid) cronExpressionInputPopup.getFellow("cronExpressionGrid");
cronExpressionSeconds = (Textbox) cronExpressionGrid
.getFellow("cronExpressionSeconds");
cronExpressionMinutes = (Textbox) cronExpressionGrid
.getFellow("cronExpressionMinutes");
cronExpressionHours = (Textbox) cronExpressionGrid
.getFellow("cronExpressionHours");
cronExpressionDayOfMonth = (Textbox) cronExpressionGrid
.getFellow("cronExpressionDayOfMonth");
cronExpressionMonth = (Textbox) cronExpressionGrid
.getFellow("cronExpressionMonth");
cronExpressionDayOfWeek = (Textbox) cronExpressionGrid
.getFellow("cronExpressionDayOfWeek");
cronExpressionYear = (Textbox) cronExpressionGrid
.getFellow("cronExpressionYear");
cronExpressionSeconds = (Textbox) cronExpressionGrid.getFellow("cronExpressionSeconds");
cronExpressionMinutes = (Textbox) cronExpressionGrid.getFellow("cronExpressionMinutes");
cronExpressionHours = (Textbox) cronExpressionGrid.getFellow("cronExpressionHours");
cronExpressionDayOfMonth = (Textbox) cronExpressionGrid.getFellow("cronExpressionDayOfMonth");
cronExpressionMonth = (Textbox) cronExpressionGrid.getFellow("cronExpressionMonth");
cronExpressionDayOfWeek = (Textbox) cronExpressionGrid.getFellow("cronExpressionDayOfWeek");
cronExpressionYear = (Textbox) cronExpressionGrid.getFellow("cronExpressionYear");
}
/**
* returns a list of {@link JobSchedulerConfiguration}
* Returns a list of {@link JobSchedulerConfiguration}
*/
public List<JobSchedulerConfiguration> getJobSchedulerConfigurations() {
return jobSchedulerModel.getJobSchedulerConfigurations();
}
/**
* returns {@link JobSchedulerConfiguration}
* Returns {@link JobSchedulerConfiguration}
*/
public JobSchedulerConfiguration getJobSchedulerConfiguration() {
return jobSchedulerModel.getJobSchedulerConfiguration();
}
/**
* returns all predefined jobs
* Returns all predefined jobs
*/
public JobClassNameEnum[] getJobNames() {
return JobClassNameEnum.values();
}
/**
* return list of connectorNames
* Return list of connectorNames
*/
public List<String> getConnectorNames() {
List<Connector> connectors = jobSchedulerModel.getConnectors();
List<String> connectorNames = new ArrayList<String>();
List<String> connectorNames = new ArrayList<>();
for (Connector connector : connectors) {
connectorNames.add(connector.getName());
}
@ -164,79 +161,55 @@ public class JobSchedulerController extends
}
/**
* renders job scheduling and returns {@link RowRenderer}
* Renders job scheduling and returns {@link RowRenderer}
*/
public RowRenderer getJobSchedulingRenderer() {
return new RowRenderer() {
return (row, data) -> {
final JobSchedulerConfiguration jobSchedulerConfiguration = (JobSchedulerConfiguration) data;
row.setValue(data);
@Override
public void render(Row row, Object data) {
final JobSchedulerConfiguration jobSchedulerConfiguration = (JobSchedulerConfiguration) data;
row.setValue(data);
Util.appendLabel(row, jobSchedulerConfiguration.getJobGroup());
Util.appendLabel(row, jobSchedulerConfiguration.getJobName());
Util.appendLabel(row, jobSchedulerConfiguration.getCronExpression());
Util.appendLabel(row, getNextFireTime(jobSchedulerConfiguration));
Hbox hbox = new Hbox();
Util.appendLabel(row, jobSchedulerConfiguration.getJobGroup());
Util.appendLabel(row, jobSchedulerConfiguration.getJobName());
Util.appendLabel(row,
jobSchedulerConfiguration.getCronExpression());
Util.appendLabel(row,
getNextFireTime(jobSchedulerConfiguration));
Hbox hbox = new Hbox();
hbox.appendChild(createManualButton(new EventListener() {
hbox.appendChild(createManualButton(event -> {
try {
jobSchedulerModel.doManual(jobSchedulerConfiguration);
showSynchronizationInfo();
} catch (ConnectorException e) {
messagesForUser.showMessage(Level.ERROR, e.getMessage());
}
}));
@Override
public void onEvent(Event event) throws Exception {
try {
jobSchedulerModel.doManual(jobSchedulerConfiguration);
showSynchronizationInfo();
} catch (ConnectorException e) {
messagesForUser.showMessage(Level.ERROR,
e.getMessage());
}
}
}));
hbox.appendChild(Util.createEditButton(new EventListener() {
@Override
public void onEvent(Event event) {
goToEditForm(jobSchedulerConfiguration);
}
}));
hbox.appendChild(Util.createRemoveButton(new EventListener() {
@Override
public void onEvent(Event event) {
confirmDelete(jobSchedulerConfiguration);
}
}));
row.appendChild(hbox);
hbox.appendChild(Util.createEditButton(event -> goToEditForm(jobSchedulerConfiguration)));
}
hbox.appendChild(Util.createRemoveButton(event -> confirmDelete(jobSchedulerConfiguration)));
row.appendChild(hbox);
};
}
public RowRenderer getSynchronizationInfoRenderer() {
return new RowRenderer() {
return (row, data) -> {
final SynchronizationInfo synchronizationInfo = (SynchronizationInfo) data;
row.setValue(data);
@Override
public void render(Row row, Object data) {
final SynchronizationInfo synchronizationInfo = (SynchronizationInfo) data;
row.setValue(data);
Groupbox groupbox = new Groupbox();
groupbox.setClosable(true);
Caption caption = new org.zkoss.zul.Caption();
caption.setLabel(synchronizationInfo.getAction());
groupbox.appendChild(caption);
row.appendChild(groupbox);
Groupbox groupbox = new Groupbox();
groupbox.setClosable(true);
Caption caption = new org.zkoss.zul.Caption();
caption.setLabel(synchronizationInfo.getAction());
groupbox.appendChild(caption);
row.appendChild(groupbox);
if (synchronizationInfo.isSuccessful()) {
groupbox.appendChild(new Label(_("Completed")));
} else {
if (synchronizationInfo.isSuccessful()) {
groupbox.appendChild(new Label(_("Completed")));
} else {
Listbox listbox = new Listbox();
Listbox listbox = new Listbox();
listbox.setModel(new SimpleListModel(synchronizationInfo
.getFailedReasons()));
groupbox.appendChild(listbox);
}
listbox.setModel(new SimpleListModel(synchronizationInfo.getFailedReasons()));
groupbox.appendChild(listbox);
}
};
}
@ -248,10 +221,9 @@ public class JobSchedulerController extends
private void showSynchronizationInfo() {
Map<String, Object> args = new HashMap<String, Object>();
Map<String, Object> args = new HashMap<>();
Window win = (Window) Executions.createComponents(
"/orders/_synchronizationInfo.zul", null, args);
Window win = (Window) Executions.createComponents("/orders/_synchronizationInfo.zul", null, args);
Window syncInfoWin = (Window) win.getFellowIfAny("syncInfoWin");
@ -263,27 +235,23 @@ public class JobSchedulerController extends
try {
win.doModal();
} catch (SuspendNotAllowedException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
} catch (SuspendNotAllowedException | InterruptedException e) {
throw new RuntimeException(e);
}
}
/**
* returns the next fire time for the specified job in
* {@link JobSchedulerConfiguration}
* Returns the next fire time for the specified job in {@link JobSchedulerConfiguration}
*
* @param jobSchedulerConfiguration
* the job scheduler configuration
*/
private String getNextFireTime(
JobSchedulerConfiguration jobSchedulerConfiguration) {
private String getNextFireTime(JobSchedulerConfiguration jobSchedulerConfiguration) {
return jobSchedulerModel.getNextFireTime(jobSchedulerConfiguration);
}
/**
* creates and returns a button
* Creates and returns a button
*
* @param eventListener
* Event listener for this button
@ -292,6 +260,7 @@ public class JobSchedulerController extends
Button button = new Button(_("Manual"));
button.setTooltiptext(_("Manual"));
button.addEventListener(Events.ON_CLICK, eventListener);
return button;
}
@ -309,14 +278,13 @@ public class JobSchedulerController extends
* @param jobSchedulerConfiguration
* where to read the values
*/
private void setupCronExpressionPopup(
final JobSchedulerConfiguration jobSchedulerConfiguration) {
private void setupCronExpressionPopup(final JobSchedulerConfiguration jobSchedulerConfiguration) {
if (jobSchedulerConfiguration != null) {
jobGroup.setValue(jobSchedulerConfiguration.getJobGroup());
jobName.setValue(jobSchedulerConfiguration.getJobName());
String cronExpression = jobSchedulerConfiguration
.getCronExpression();
String cronExpression = jobSchedulerConfiguration.getCronExpression();
if (cronExpression == null || cronExpression.isEmpty()) {
return;
}
@ -337,8 +305,7 @@ public class JobSchedulerController extends
}
/**
* sets the <code>cronExpressionTextBox</code> value from the
* <code>cronExpressionInputPopup</code>
* Sets the <code>cronExpressionTextBox</code> value from the <code>cronExpressionInputPopup</code>
*/
public void updateCronExpression() {
String cronExpression = getCronExpressionString();
@ -347,9 +314,9 @@ public class JobSchedulerController extends
new CronExpression(cronExpression);
} catch (ParseException e) {
LOG.info("Unable to parse cron expression", e);
throw new WrongValueException(cronExpressionInputPopup,
_("Unable to parse cron expression") + ":\n"
+ e.getMessage());
throw new WrongValueException(
cronExpressionInputPopup, _("Unable to parse cron expression") + ":\n" + e.getMessage());
}
cronExpressionTextBox.setValue(cronExpression);
cronExpressionInputPopup.close();
@ -371,15 +338,12 @@ public class JobSchedulerController extends
cronExpression += StringUtils.trimToEmpty(cronExpressionDayOfWeek.getValue());
String year = StringUtils.trimToEmpty(cronExpressionYear.getValue());
if (!year.isEmpty()) {
cronExpression += " " + year;
}
return cronExpression;
return !year.isEmpty() ? cronExpression + " " + year : cronExpression;
}
/**
* closes the popup
* Closes the popup
*/
public void cancelPopup() {
cronExpressionInputPopup.close();
@ -410,8 +374,7 @@ public class JobSchedulerController extends
protected void save() throws ValidationException {
jobSchedulerModel.confirmSave();
if (jobSchedulerModel.scheduleOrUnscheduleJob()) {
messagesForUser.showMessage(Level.INFO,
_("Job is scheduled/unscheduled"));
messagesForUser.showMessage(Level.INFO, _("Job is scheduled/unscheduled"));
}
}
@ -426,12 +389,10 @@ public class JobSchedulerController extends
}
@Override
protected void delete(JobSchedulerConfiguration entity)
throws InstanceNotFoundException {
protected void delete(JobSchedulerConfiguration entity) throws InstanceNotFoundException {
jobSchedulerModel.remove(entity);
if (jobSchedulerModel.deleteScheduledJob(entity)) {
messagesForUser.showMessage(Level.INFO,
_("Job is deleted from scheduler"));
messagesForUser.showMessage(Level.INFO, _("Job is deleted from scheduler"));
}
}

View file

@ -52,7 +52,7 @@ import static org.libreplan.web.I18nHelper._;
*
* @author Manuel Rego Casasnovas <rego@igalia.com>
* @author Miciele Ghiorghis <m.ghiorghis@antoniusziekenhuis.nl>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* @author Vova Perebykivskyi <vova@libreplan-enterprise.com>
*/
@Service
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
@ -79,8 +79,6 @@ public class JobSchedulerModel implements IJobSchedulerModel {
@Autowired
private IJiraOrderElementSynchronizer jiraOrderElementSynchronizer;
private List<SynchronizationInfo> synchronizationInfos;
@Qualifier("sendEmailOnTaskAssignedToResource")
@Autowired
private IEmailNotificationJob taskAssignedToResource;
@ -105,6 +103,8 @@ public class JobSchedulerModel implements IJobSchedulerModel {
@Autowired
private IEmailNotificationJob timesheetDataMissing;
private List<SynchronizationInfo> synchronizationInfos = new ArrayList<>();
@Override
@Transactional(readOnly = true)
@ -113,63 +113,77 @@ public class JobSchedulerModel implements IJobSchedulerModel {
}
@Override
public String getNextFireTime(
JobSchedulerConfiguration jobSchedulerConfiguration) {
public String getNextFireTime(JobSchedulerConfiguration jobSchedulerConfiguration) {
return schedulerManager.getNextFireTime(jobSchedulerConfiguration);
}
@Override
public void doManual(JobSchedulerConfiguration jobSchedulerConfiguration)
throws ConnectorException {
public void doManual(JobSchedulerConfiguration jobSchedulerConfiguration) throws ConnectorException {
String name = jobSchedulerConfiguration.getJobClassName().getName();
if (name.equals(JobClassNameEnum.IMPORT_ROSTER_FROM_TIM_JOB.getName())) {
if ( name.equals(JobClassNameEnum.IMPORT_ROSTER_FROM_TIM_JOB.getName()) ) {
synchronizationInfos = importRosterFromTim.importRosters();
return;
}
if (name.equals(JobClassNameEnum.EXPORT_TIMESHEET_TO_TIM_JOB.getName())) {
if ( name.equals(JobClassNameEnum.EXPORT_TIMESHEET_TO_TIM_JOB.getName()) ) {
synchronizationInfos = exportTimesheetsToTim.exportTimesheets();
return;
}
if (name.equals(JobClassNameEnum.SYNC_ORDERELEMENTS_WITH_JIRA_ISSUES_JOB
.getName())) {
synchronizationInfos = jiraOrderElementSynchronizer
.syncOrderElementsWithJiraIssues();
if ( name.equals(JobClassNameEnum.SYNC_ORDERELEMENTS_WITH_JIRA_ISSUES_JOB.getName()) ) {
synchronizationInfos = jiraOrderElementSynchronizer.syncOrderElementsWithJiraIssues();
return;
}
if ( name.equals(JobClassNameEnum.SEND_EMAIL_TASK_ASSIGNED_TO_RESOURCE.getName()) ) {
synchronizationInfos = new ArrayList<SynchronizationInfo>();
synchronizationInfos = new ArrayList<>();
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<SynchronizationInfo>();
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<SynchronizationInfo>();
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<SynchronizationInfo>();
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<SynchronizationInfo>();
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<SynchronizationInfo>();
synchronizationInfos = new ArrayList<>();
synchronizationInfos.add(new SynchronizationInfo(_("Timesheet data missing")));
timesheetDataMissing.sendEmail();
return;
}
@ -211,8 +225,7 @@ public class JobSchedulerModel implements IJobSchedulerModel {
@Transactional
public void remove(JobSchedulerConfiguration jobSchedulerConfiguration) {
try {
jobSchedulerConfigurationDAO.remove(jobSchedulerConfiguration
.getId());
jobSchedulerConfigurationDAO.remove(jobSchedulerConfiguration.getId());
} catch (InstanceNotFoundException e) {
throw new RuntimeException(e);
}
@ -226,8 +239,9 @@ public class JobSchedulerModel implements IJobSchedulerModel {
@Override
public boolean scheduleOrUnscheduleJobs(Connector connector) {
List<JobSchedulerConfiguration> jobSchedulerConfigurations = jobSchedulerConfigurationDAO
.findByConnectorName(connector.getName());
List<JobSchedulerConfiguration> jobSchedulerConfigurations =
jobSchedulerConfigurationDAO.findByConnectorName(connector.getName());
for (JobSchedulerConfiguration jobSchedulerConfiguration : jobSchedulerConfigurations) {
try {
@ -250,8 +264,7 @@ public class JobSchedulerModel implements IJobSchedulerModel {
}
@Override
public boolean deleteScheduledJob(
JobSchedulerConfiguration jobSchedulerConfiguration) {
public boolean deleteScheduledJob(JobSchedulerConfiguration jobSchedulerConfiguration) {
try {
schedulerManager.deleteJob(jobSchedulerConfiguration);
} catch (SchedulerException e) {

View file

@ -40,9 +40,7 @@ import java.util.List;
/**
* Model for operations related to {@link EmailNotification}.
*
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 21.10.15.
* @author Created by Vova Perebykivskiy <vova@libreplan-enterprise.com> on 21.10.2015.
*/
@Service

View file

@ -38,22 +38,20 @@ import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.Listitem;
import org.zkoss.zul.ListitemRenderer;
import org.zkoss.zul.Textbox;
import java.util.List;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import static org.libreplan.web.I18nHelper._;
/**
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 25.09.15.
* Controller for page Edit email templates.
*
* @author Created by Vova Perebykivskiy <vova@libreplan-enterprise.com> on 25.09.2015.
*/
public class EmailTemplateController extends GenericForwardComposer{
@ -73,42 +71,41 @@ public class EmailTemplateController extends GenericForwardComposer{
private Textbox subjectTextbox;
public static ListitemRenderer languagesRenderer = new ListitemRenderer() {
@Override
public void render(Listitem item, Object data) throws Exception {
Language language = (Language) data;
String displayName = language.getDisplayName();
item.setLabel(displayName);
}
public static ListitemRenderer languagesRenderer = (item, data) -> {
Language language = (Language) data;
String displayName = language.getDisplayName();
item.setLabel(displayName);
};
@Override
public void doAfterCompose(Component comp) throws Exception {
super.doAfterCompose(comp);
// TODO resolve deprecated
comp.setVariable("emailTemplateController", this, true);
messages = new MessagesForUser(messagesContainer);
// Set default template and language for user
// And content and subject for that language & template
// Set default template and language for user.
// And content and subject for that language & template.
setUser();
setSelectedLanguage(user.getApplicationLanguage());
setSelectedLanguage(Language.ENGLISH_LANGUAGE);
getContentDataBySelectedLanguage();
getSubjectDataBySelectedLanguage();
}
public boolean save(){
public boolean save() {
try {
setSelectedContent();
setSelectedSubject();
emailTemplateModel.confirmSave();
messages.clearMessages();
messages.showMessage(Level.INFO, _("E-mail template saved"));
return true;
} catch (ValidationException e) {
messages.showInvalidValues(e);
} catch (InstanceNotFoundException e) {
e.printStackTrace();
}
return false;
}
@ -121,7 +118,7 @@ public class EmailTemplateController extends GenericForwardComposer{
return emailTemplateModel.getLanguage();
}
public void setSelectedLanguage(Language language){
public void setSelectedLanguage(Language language) {
emailTemplateModel.setLanguage(language);
getSubjectDataBySelectedLanguage();
@ -132,20 +129,18 @@ public class EmailTemplateController extends GenericForwardComposer{
return languagesRenderer;
}
public List<Language> getLanguages() {
List<Language> languages = new LinkedList<Language>(Arrays.asList(Language.values()));
Collections.sort(languages, new Comparator<Language>() {
@Override
public int compare(Language o1, Language o2) {
if (o1.equals(Language.BROWSER_LANGUAGE)) {
return -1;
}
if (o2.equals(Language.BROWSER_LANGUAGE)) {
return 1;
}
return o1.getDisplayName().compareTo(o2.getDisplayName());
List<Language> languages = new LinkedList<>(Arrays.asList(Language.values()));
Collections.sort(languages, (o1, o2) -> {
if ( o1.equals(Language.BROWSER_LANGUAGE) ) {
return -1;
}
if ( o2.equals(Language.BROWSER_LANGUAGE) ) {
return 1;
}
return o1.getDisplayName().compareTo(o2.getDisplayName());
});
languages.remove(0);
return languages;
}
@ -153,7 +148,7 @@ public class EmailTemplateController extends GenericForwardComposer{
public EmailTemplateEnum getSelectedEmailTemplateEnum() {
return emailTemplateModel.getEmailTemplateEnum();
}
public void setSelectedEmailTemplateEnum(EmailTemplateEnum emailTemplateEnum){
public void setSelectedEmailTemplateEnum(EmailTemplateEnum emailTemplateEnum) {
emailTemplateModel.setEmailTemplateEnum(emailTemplateEnum);
getSubjectDataBySelectedTemplate();
@ -161,13 +156,10 @@ public class EmailTemplateController extends GenericForwardComposer{
}
public ListitemRenderer getEmailTemplateEnumRenderer() {
return new ListitemRenderer() {
@Override
public void render(Listitem item, Object data) throws Exception {
EmailTemplateEnum template = (EmailTemplateEnum) data;
item.setLabel(_(template.getTemplateType()));
item.setValue(template);
}
return (item, data) -> {
EmailTemplateEnum template = (EmailTemplateEnum) data;
item.setLabel(_(template.getTemplateType()));
item.setValue(template);
};
}
public List<EmailTemplateEnum> getEmailTemplateEnum() {
@ -175,30 +167,30 @@ public class EmailTemplateController extends GenericForwardComposer{
}
public void setSelectedContent(){
public void setSelectedContent() {
emailTemplateModel.setContent(contentsTextbox.getValue());
}
public void setSelectedSubject(){
public void setSelectedSubject() {
emailTemplateModel.setSubject(subjectTextbox.getValue());
}
private void getContentDataBySelectedLanguage(){
contentsTextbox.setValue(emailTemplateModel.getContentBySelectedLanguage(getSelectedLanguage().ordinal(), getSelectedEmailTemplateEnum().ordinal()));
private void getContentDataBySelectedLanguage() {
contentsTextbox.setValue(emailTemplateModel.getContent(getSelectedLanguage(), getSelectedEmailTemplateEnum()));
}
private void getContentDataBySelectedTemplate(){
contentsTextbox.setValue( emailTemplateModel.getContentBySelectedTemplate(getSelectedEmailTemplateEnum().ordinal(), getSelectedLanguage().ordinal()) );
private void getContentDataBySelectedTemplate() {
contentsTextbox.setValue(emailTemplateModel.getContent(getSelectedLanguage(), getSelectedEmailTemplateEnum()));
}
private void getSubjectDataBySelectedLanguage(){
subjectTextbox.setValue(emailTemplateModel.getSubjectBySelectedLanguage(getSelectedLanguage().ordinal(), getSelectedEmailTemplateEnum().ordinal()));
private void getSubjectDataBySelectedLanguage() {
subjectTextbox.setValue(emailTemplateModel.getSubject(getSelectedLanguage(), getSelectedEmailTemplateEnum()));
}
private void getSubjectDataBySelectedTemplate(){
subjectTextbox.setValue( emailTemplateModel.getSubjectBySelectedTemplate(getSelectedEmailTemplateEnum().ordinal(), getSelectedLanguage().ordinal()) );
private void getSubjectDataBySelectedTemplate() {
subjectTextbox.setValue(emailTemplateModel.getSubject(getSelectedLanguage(), getSelectedEmailTemplateEnum()));
}
@Transactional
private void setUser(){
private void setUser() {
try {
user = userDAO.findByLoginName(SecurityUtils.getSessionUserLoginName());
} catch (InstanceNotFoundException e) {

View file

@ -36,9 +36,7 @@ import java.util.List;
/**
* Model for operations related to {@link EmailTemplate}.
*
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 25.09.15.
* @author Created by Vova Perebykivskiy <vova@libreplan-enterprise.com> on 25.09.2015.
*/
@Service
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
@ -52,22 +50,31 @@ public class EmailTemplateModel implements IEmailTemplateModel {
@Override
@Transactional
public void confirmSave() throws InstanceNotFoundException {
public void confirmSave() {
/* If current EmailTemplate entity (id) is existing in DB than it needs to be updated.
* Else current EmailTemplate entity (id) is creating and getting new values from form.
*/
/*
* If current EmailTemplate entity (id) is existing in DB than it needs to be updated.
* Else current EmailTemplate entity (id) is creating and getting new values from form.
*/
List<EmailTemplate> emailTemplates = emailTemplateDAO.getAll();
EmailTemplate emailTemplateFromDatabase = null;
boolean condition;
for (int i = 0; i < emailTemplates.size(); i++) {
if ( emailTemplate.getLanguage() == emailTemplates.get(i).getLanguage() &&
emailTemplate.getType() == emailTemplates.get(i).getType() ) {
emailTemplateFromDatabase = emailTemplateDAO.find(emailTemplates.get(i).getId());
for (EmailTemplate emailTemplate1 : emailTemplates) {
condition = emailTemplate.getLanguage() == emailTemplate1.getLanguage() &&
emailTemplate.getType() == emailTemplate1.getType();
if ( condition ) {
try {
emailTemplateFromDatabase = emailTemplateDAO.find(emailTemplate1.getId());
} catch (InstanceNotFoundException e) {
e.printStackTrace();
}
}
}
if ( emailTemplateFromDatabase != null ){
if ( emailTemplateFromDatabase != null ) {
EmailTemplate temporaryEntity = emailTemplate;
emailTemplate = emailTemplateFromDatabase;
@ -89,13 +96,11 @@ public class EmailTemplateModel implements IEmailTemplateModel {
}
@Override
@Transactional
public List<EmailTemplate> getAll() {
return emailTemplateDAO.getAll();
}
@Override
@Transactional
public Language getLanguage() {
return this.emailTemplate.getLanguage();
}
@ -113,46 +118,37 @@ public class EmailTemplateModel implements IEmailTemplateModel {
this.emailTemplate.setType(emailTemplateEnum);
}
@Override
public String getContent() {
return this.emailTemplate.getContent();
}
@Override
public void setContent(String content) {
this.emailTemplate.setContent(content);
}
@Override
public String getSubject() {
return this.emailTemplate.getSubject();
}
@Override
public void setSubject(String subject) {
this.emailTemplate.setSubject(subject);
}
@Override
@Transactional
public String getContentBySelectedLanguage(int languageOrdinal, int emailTemplateTypeOrdinal) {
return emailTemplateDAO.getContentBySelectedLanguage(languageOrdinal, emailTemplateTypeOrdinal);
public String getContent(Language language, EmailTemplateEnum type) {
EmailTemplate template = getEmailTemplateByTypeAndLanguage(type, language);
return template != null ? template.getContent() : "";
}
@Override
@Transactional
public String getContentBySelectedTemplate(int emailTemplateTypeOrdinal, int languageOrdinal) {
return emailTemplateDAO.getContentBySelectedTemplate(emailTemplateTypeOrdinal, languageOrdinal);
public String getSubject(Language language, EmailTemplateEnum type) {
EmailTemplate template = getEmailTemplateByTypeAndLanguage(type, language);
return template != null ? template.getSubject() : "";
}
public EmailTemplate getEmailTemplateByTypeAndLanguage(EmailTemplateEnum type, Language language) {
return emailTemplateDAO.findByTypeAndLanguage(type, language);
}
@Override
@Transactional
public String getSubjectBySelectedLanguage(int languageOrdinal, int emailTemplateTypeOrdinal) {
return emailTemplateDAO.getSubjectBySelectedLanguage(languageOrdinal, emailTemplateTypeOrdinal);
}
@Override
@Transactional
public String getSubjectBySelectedTemplate(int emailTemplateTypeOrdinal, int languageOrdinal) {
return emailTemplateDAO.getSubjectBySelectedTemplate(emailTemplateTypeOrdinal, languageOrdinal);
public void delete() {
emailTemplateDAO.delete(this.emailTemplate);
}
}

View file

@ -31,25 +31,30 @@ import java.util.List;
/**
* Contract for {@link EmailNotification}
*
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 21.10.15.
* @author Created by Vova Perebykivskiy <vova@libreplan-enterprise.com> on 21.10.2015.
*/
public interface IEmailNotificationModel {
void confirmSave() throws ValidationException;
List<EmailNotification> getAll();
List<EmailNotification> getAllByType(EmailTemplateEnum enumeration);
boolean deleteAll();
boolean deleteAllByType(EmailTemplateEnum enumeration);
boolean deleteById(EmailNotification notification);
void setType(EmailTemplateEnum type);
void setUpdated(Date date);
void setResource(Resource resource);
void setTask(TaskElement task);
void setProject(TaskElement project);
EmailNotification getEmailNotification();

View file

@ -19,8 +19,6 @@
package org.libreplan.web.email;
import org.libreplan.business.common.exceptions.InstanceNotFoundException;
import org.libreplan.business.common.exceptions.ValidationException;
import org.libreplan.business.email.entities.EmailTemplate;
import org.libreplan.business.settings.entities.Language;
import org.libreplan.business.email.entities.EmailTemplateEnum;
@ -30,31 +28,31 @@ import java.util.List;
/**
* Contract for {@link EmailTemplate}
*
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 28.09.2015.
* @author Created by Vova Perebykivskyi <vova@libreplan-enterprise.com> on 28.09.2015.
*/
public interface IEmailTemplateModel {
void confirmSave() throws ValidationException, InstanceNotFoundException;
void confirmSave();
List<EmailTemplate> getAll();
String getContentBySelectedLanguage(int languageOrdinal, int emailTemplateTypeOrdinal);
String getContentBySelectedTemplate(int emailTemplateTypeOrdinal, int languageOrdinal);
String getContent(Language language, EmailTemplateEnum emailTemplateEnum);
String getSubjectBySelectedLanguage(int languageOrdinal, int emailTemplateTypeOrdinal);
String getSubjectBySelectedTemplate(int emailTemplateTypeOrdinal, int languageOrdinal);
String getContent();
String getSubject(Language language, EmailTemplateEnum emailTemplateEnum);
void setContent(String content);
Language getLanguage();
void setLanguage(Language language);
EmailTemplateEnum getEmailTemplateEnum();
void setEmailTemplateEnum(EmailTemplateEnum emailTemplateEnum);
String getSubject();
void setSubject(String subject);
EmailTemplate getEmailTemplateByTypeAndLanguage(EmailTemplateEnum emailTemplateEnum, Language language);
void delete();
}

View file

@ -52,7 +52,7 @@ import org.springframework.transaction.annotation.Transactional;
/**
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* @author Vova Perebykivskyi <vova@libreplan-enterprise.com>
*/
@Service
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
@ -116,15 +116,11 @@ public class AssignedTaskQualityFormsToOrderElementModel implements IAssignedTas
@Override
public List<QualityForm> getNotAssignedQualityForms() {
List<QualityForm> result = new ArrayList<QualityForm>();
if ( orderElement != null ) {
return getListNotAssignedQualityForms();
}
return result;
return orderElement != null ? getListNotAssignedQualityForms() : new ArrayList<>();
}
private List<QualityForm> getListNotAssignedQualityForms() {
List<QualityForm> result = new ArrayList<QualityForm>();
List<QualityForm> result = new ArrayList<>();
for (QualityForm qualityForm : orderModel.getQualityForms()) {
if ( !isAssigned(qualityForm) ) {
result.add(qualityForm);
@ -135,7 +131,7 @@ public class AssignedTaskQualityFormsToOrderElementModel implements IAssignedTas
@Override
public List<QualityForm> getAssignedQualityForms() {
List<QualityForm> result = new ArrayList<QualityForm>();
List<QualityForm> result = new ArrayList<>();
for (QualityForm qualityForm : qualityFormDAO.getAll()) {
if ( isAssigned(qualityForm) ) {
result.add(qualityForm);
@ -146,7 +142,7 @@ public class AssignedTaskQualityFormsToOrderElementModel implements IAssignedTas
@Override
public List<TaskQualityForm> getTaskQualityForms() {
List<TaskQualityForm> result = new ArrayList<TaskQualityForm>();
List<TaskQualityForm> result = new ArrayList<>();
if ( orderElement != null ) {
result.addAll(orderElement.getTaskQualityForms());
}
@ -176,10 +172,10 @@ public class AssignedTaskQualityFormsToOrderElementModel implements IAssignedTas
@Override
public boolean isAssigned(QualityForm qualityForm) {
// orderDAO used for gathered data to be sent to LibrePlan server
// In general case orderElement will be not null and only that part of code will be triggered
// orderDAO used for gathered data to be sent to LibrePlan server.
// In general case orderElement will be not null and only that part of code will be triggered.
if ( orderElement != null ){
if ( orderElement != null ) {
for (TaskQualityForm taskQualityForm : orderElement.getTaskQualityForms()) {
if ( qualityForm.equals(taskQualityForm.getQualityForm()) ) {
return true;
@ -203,37 +199,27 @@ public class AssignedTaskQualityFormsToOrderElementModel implements IAssignedTas
}
public boolean isDisabledPassedItem(TaskQualityForm taskQualityForm, TaskQualityFormItem item) {
if ( (taskQualityForm == null) || ((item == null)) ) {
return true;
}
if ( !taskQualityForm.isByItems() ) {
return (!(item.getPassed() || taskQualityForm.isPassedPreviousItem(item)));
}
return false;
return (taskQualityForm == null) ||
(item == null) ||
!taskQualityForm.isByItems() && !(item.getPassed() ||
taskQualityForm.isPassedPreviousItem(item));
}
public boolean isDisabledDateItem(TaskQualityForm taskQualityForm, TaskQualityFormItem item) {
if ( (taskQualityForm == null) || ((item == null)) ) {
return true;
}
return (!taskQualityForm.isByItems() && (!item.getPassed()));
return (taskQualityForm == null) || (item == null) || !taskQualityForm.isByItems() && !item.getPassed();
}
public boolean isCorrectConsecutiveDate(TaskQualityForm taskQualityForm, TaskQualityFormItem item) {
if ( (taskQualityForm == null) || ((item == null)) ) {
return true;
}
if ( taskQualityForm.isByItems() ) {
return true;
}
return (taskQualityForm.isCorrectConsecutiveDate(item));
return (taskQualityForm == null) ||
(item == null) ||
taskQualityForm.isByItems() ||
taskQualityForm.isCorrectConsecutiveDate(item);
}
public void updatePassedTaskQualityFormItems(TaskQualityForm taskQualityForm) {
if (taskQualityForm != null) {
Integer position = getFirstNotPassedPosition(taskQualityForm);
List<TaskQualityFormItem> items = taskQualityForm
.getTaskQualityFormItems();
List<TaskQualityFormItem> items = taskQualityForm.getTaskQualityFormItems();
for (int i = position; i < items.size(); i++) {
items.get(i).setPassed(false);
items.get(i).setDate(null);
@ -243,8 +229,7 @@ public class AssignedTaskQualityFormsToOrderElementModel implements IAssignedTas
private Integer getFirstNotPassedPosition(TaskQualityForm taskQualityForm) {
Integer position = 0;
for (TaskQualityFormItem item : taskQualityForm
.getTaskQualityFormItems()) {
for (TaskQualityFormItem item : taskQualityForm.getTaskQualityFormItems()) {
if (!item.getPassed()) {
return position;
}
@ -254,12 +239,10 @@ public class AssignedTaskQualityFormsToOrderElementModel implements IAssignedTas
}
// Operation to confirm and validate
@Override
public void validate() {
if (getOrderElement() != null) {
for (TaskQualityForm taskQualityForm : orderElement
.getTaskQualityForms()) {
for (TaskQualityForm taskQualityForm : orderElement.getTaskQualityForms()) {
validateTaskQualityForm(taskQualityForm);
}
}
@ -270,19 +253,15 @@ public class AssignedTaskQualityFormsToOrderElementModel implements IAssignedTas
}
private void validateTaskQualityFormItems(TaskQualityForm taskQualityForm) {
for (TaskQualityFormItem item : taskQualityForm
.getTaskQualityFormItems()) {
for (TaskQualityFormItem item : taskQualityForm.getTaskQualityFormItems()) {
if ((!taskQualityForm.isByItems())
&& (!taskQualityForm.isCorrectConsecutivePassed(item))) {
throw new ValidationException(
invalidValue(
if ( (!taskQualityForm.isByItems()) && (!taskQualityForm.isCorrectConsecutivePassed(item)) ) {
throw new ValidationException(invalidValue(
_("cannot be checked until the previous item is checked before"),
"passed", item.getName(), taskQualityForm));
}
if ((!taskQualityForm.isByItems())
&& (!taskQualityForm.isCorrectConsecutiveDate(item))) {
if ( (!taskQualityForm.isByItems()) && (!taskQualityForm.isCorrectConsecutiveDate(item)) ) {
throw new ValidationException(invalidValue(
_("must be after the previous date"),
"date", item.getName(), taskQualityForm));
@ -299,8 +278,7 @@ public class AssignedTaskQualityFormsToOrderElementModel implements IAssignedTas
@Override
@Transactional(readOnly = true)
public void addAdvanceAssignmentIfNeeded(TaskQualityForm taskQualityForm)
throws DuplicateValueTrueReportGlobalAdvanceException,
DuplicateAdvanceAssignmentForOrderElementException {
throws DuplicateValueTrueReportGlobalAdvanceException, DuplicateAdvanceAssignmentForOrderElementException {
AdvanceType advanceType = taskQualityForm.getQualityForm().getAdvanceType();
advanceTypeDAO.reattach(advanceType);
@ -340,8 +318,7 @@ public class AssignedTaskQualityFormsToOrderElementModel implements IAssignedTas
}
private void showMessageDeleteSpread() throws ValidationException {
throw new ValidationException(
_("Quality form cannot be removed as it is spreading progress"));
throw new ValidationException(_("Quality form cannot be removed as it is spreading progress"));
}
@Override

View file

@ -33,33 +33,31 @@ import org.libreplan.business.qualityforms.entities.TaskQualityFormItem;
/**
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* @author Vova Perebykivskyi <vova@libreplan-enterprise.com>
*/
public interface IAssignedTaskQualityFormsToOrderElementModel {
/**
* Assigns {@link TaskQualityForm} to {@link OrderElement}
* Assigns {@link TaskQualityForm} to {@link OrderElement}.
* @param @ QualityForm}
*/
void assignTaskQualityForm(QualityForm qualityForm);
/**
* Delete {@link TaskQualityForm}
* Delete {@link TaskQualityForm}.
* @param taskQualityForm
*/
void deleteTaskQualityForm(TaskQualityForm taskQualityForm);
/**
* Gets all {@link TaskQualityForm} assigned to the current
* {@link OrderElement}
* @return
* Gets all {@link TaskQualityForm} assigned to the current {@link OrderElement}.
* @return {@link List<TaskQualityForm>}
*/
List<TaskQualityForm> getTaskQualityForms();
/**
* Returns all the unallocated {@link QualityForm} to the current
* {@link OrderElement}
* @return
* Returns all the unallocated {@link QualityForm} to the current {@link OrderElement}.
* @return {@link List<QualityForm>}
*/
List<QualityForm> getNotAssignedQualityForms();
@ -69,22 +67,20 @@ public interface IAssignedTaskQualityFormsToOrderElementModel {
List<QualityForm> getAssignedQualityForms();
/**
* Returns {@link OrderElement}
* @return
* @return {@link OrderElement}
*/
OrderElement getOrderElement();
void init(OrderElement orderElement);
/**
* Check whether {@link QualityForm} has been already assigned to
* {@link OrderElement} or not
* Check whether {@link QualityForm} has been already assigned to {@link OrderElement} or not.
* @param qualityForm
*/
boolean isAssigned(QualityForm qualityForm);
/**
* Set {@link OrderElement}
* Set {@link OrderElement}.
* @param orderElement
*/
void setOrderElement(OrderElement orderElement);
@ -95,47 +91,36 @@ public interface IAssignedTaskQualityFormsToOrderElementModel {
void setOrderModel(IOrderModel orderModel);
/**
* Update the date and the property passed of all the
* {@link TaskQualityFormItem} of the {@ TaskQualityForm}
* Update the date and the property passed of all the {@link TaskQualityFormItem} of the {@link TaskQualityForm}.
* @param taskQualityForm
*/
void updatePassedTaskQualityFormItems(TaskQualityForm taskQualityForm);
/**
* Check whether {@link QualityFormItem} the property passed must be
* disabled
* @param taskQualityForm
* ,item
* Check whether {@link QualityFormItem} the property passed must be disabled.
* @param taskQualityForm, item
*/
boolean isDisabledPassedItem(TaskQualityForm taskQualityForm,
TaskQualityFormItem item);
boolean isDisabledPassedItem(TaskQualityForm taskQualityForm, TaskQualityFormItem item);
/**
* Check whether {@link QualityFormItem} date must be disabled
* @param taskQualityForm
* ,item
* Check whether {@link QualityFormItem} date must be disabled.
* @param taskQualityForm, item
*/
boolean isDisabledDateItem(TaskQualityForm taskQualityForm,
TaskQualityFormItem item);
boolean isDisabledDateItem(TaskQualityForm taskQualityForm, TaskQualityFormItem item);
/**
* Check whether {@link QualityFormItem} date is consecutive
* @param taskQualityForm
* ,item
* Check whether {@link QualityFormItem} date is consecutive.
* @param taskQualityForm, item
*/
boolean isCorrectConsecutiveDate(TaskQualityForm taskQualityForm,
TaskQualityFormItem item);
boolean isCorrectConsecutiveDate(TaskQualityForm taskQualityForm, TaskQualityFormItem item);
/**
* Check whether all {@link QualityForm} and its {@link QualityFormItem} are
* valid.
* @param
* Check whether all {@link QualityForm} and its {@link QualityFormItem} are valid.
*/
void validate();
void addAdvanceAssignmentIfNeeded(TaskQualityForm taskQualityForm)
throws DuplicateValueTrueReportGlobalAdvanceException,
DuplicateAdvanceAssignmentForOrderElementException;
throws DuplicateValueTrueReportGlobalAdvanceException, DuplicateAdvanceAssignmentForOrderElementException;
void removeAdvanceAssignmentIfNeeded(TaskQualityForm taskQualityForm);

View file

@ -48,7 +48,6 @@ import org.libreplan.web.common.components.AllocationSelector;
import org.libreplan.web.common.components.NewAllocationSelector;
import org.libreplan.web.common.components.NewAllocationSelectorCombo;
import org.libreplan.web.common.components.ResourceAllocationBehaviour;
import org.libreplan.web.planner.allocation.TaskInformation.ITotalHoursCalculationListener;
import org.libreplan.web.planner.order.PlanningStateCreator.PlanningState;
import org.libreplan.web.planner.taskedition.EditTaskController;
import org.libreplan.web.planner.taskedition.TaskPropertiesController;
@ -61,7 +60,6 @@ import org.zkoss.ganttz.timetracker.OnColumnsRowRenderer;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.WrongValueException;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.Button;
@ -88,7 +86,7 @@ import org.zkoss.zul.Window;
* @author Manuel Rego Casasnovas <mrego@igalia.com>
* @author Diego Pino Garcia <dpino@igalia.com>
* @author Javier Moran Rua <jmoran@igalia.com>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* @author Vova Perebykivskyi <vova@libreplan-enterprise.com>
*/
@org.springframework.stereotype.Component("resourceAllocationController")
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
@ -117,10 +115,13 @@ public class ResourceAllocationController extends GenericForwardComposer {
private Decimalbox allResourcesPerDay;
private Label allOriginalEffort;
private Label allTotalEffort;
private Label allConsolidatedEffort;
private Label allTotalResourcesPerDay;
private Label allConsolidatedResourcesPerDay;
private Button applyButton;
@ -172,12 +173,15 @@ public class ResourceAllocationController extends GenericForwardComposer {
}
/**
* Shows Resource Allocation window
* Shows Resource Allocation window.
* @param context
* @param task
* @param ganttTask
* @param planningState
* @param messagesForUser
*/
public void init(IContextWithPlannerTask<TaskElement> context, Task task, PlanningState planningState,
public void init(IContextWithPlannerTask<TaskElement> context,
Task task,
PlanningState planningState,
IMessagesForUser messagesForUser) {
try {
if ( formBinder != null ) {
@ -240,13 +244,7 @@ public class ResourceAllocationController extends GenericForwardComposer {
private void initializeTaskInformationComponent() {
taskInformation.initializeGridTaskRows(resourceAllocationModel.getHoursAggregatedByCriterions());
formBinder.setRecommendedAllocation(taskInformation.getBtnRecommendedAllocation());
taskInformation.onCalculateTotalHours(new ITotalHoursCalculationListener() {
@Override
public Integer getTotalHours() {
return resourceAllocationModel.getOrderHours();
}
});
taskInformation.onCalculateTotalHours(() -> resourceAllocationModel.getOrderHours());
}
private void initializeAllocationConfigurationComponent() {
@ -261,18 +259,18 @@ public class ResourceAllocationController extends GenericForwardComposer {
return new Label(data.getCriterionsJoinedByComma());
}
},
RESOURCE_TYPE{
RESOURCE_TYPE{
@Override
public Component cell(HoursRendererColumn column, AggregatedHoursGroup data) {
return new Label(asString(data.getResourceType()));
}
},
HOURS {
@Override
public Component cell(HoursRendererColumn column, AggregatedHoursGroup data) {
Label result = new Label(Integer.toString(data.getHours()));
return result;
return new Label(Integer.toString(data.getHours()));
}
};
@ -286,6 +284,7 @@ public class ResourceAllocationController extends GenericForwardComposer {
default:
LOG.warn("no i18n for " + resourceType.name());
return resourceType.name();
}
}
@ -294,8 +293,7 @@ public class ResourceAllocationController extends GenericForwardComposer {
}
/**
* Pick resources selected from {@link NewAllocationSelector} and add them to
* resource allocation list
* Pick resources selected from {@link NewAllocationSelector} and add them to resource allocation list.
*
* @param e
*/
@ -305,8 +303,12 @@ public class ResourceAllocationController extends GenericForwardComposer {
} finally {
// For email notification feature
int rowsSize = allocationRows.getCurrentRows().size();
editTaskController.getTaskPropertiesController().listToAdd
editTaskController
.getTaskPropertiesController()
.getListToAdd()
.add(allocationRows.getCurrentRows().get(rowsSize - 1).getAssociatedResources().get(0));
editTaskController.getTaskPropertiesController().setResourcesAdded(true);
tbResourceAllocation.setSelected(true);
@ -320,15 +322,13 @@ public class ResourceAllocationController extends GenericForwardComposer {
applyButton.setVisible(false);
workerSearchTab.setSelected(true);
LocalDate start = LocalDate
.fromDateFields(resourceAllocationModel.getTaskStart());
LocalDate end = LocalDate
.fromDateFields(resourceAllocationModel.getTaskEnd());
LocalDate start = LocalDate.fromDateFields(resourceAllocationModel.getTaskStart());
LocalDate end = LocalDate.fromDateFields(resourceAllocationModel.getTaskEnd());
newAllocationSelector.open(start, end);
}
/**
* Shows the extended view of the resources allocations
* Shows the extended view of the resources allocations.
*/
public void onCheckExtendedView() {
if (isExtendedView()) {
@ -345,21 +345,14 @@ public class ResourceAllocationController extends GenericForwardComposer {
}
public int getColspanHours() {
if (isExtendedView()) {
return 4;
}
return 1;
return isExtendedView() ? 4 : 1;
}
public int getColspanResources() {
if (isExtendedView()) {
return 3;
}
return 1;
return isExtendedView() ? 3 : 1;
}
/**
* Close search worker in worker search tab
* @param e
* Close search worker in worker search tab.
*/
public void onCloseSelectWorkers() {
tbResourceAllocation.setSelected(true);
@ -380,6 +373,7 @@ public class ResourceAllocationController extends GenericForwardComposer {
return resourceAllocationController.getTaskWorkableDays();
}
},
NUMBER_OF_HOURS(CalculatedValue.NUMBER_OF_HOURS) {
@Override
public String getName() {
@ -392,8 +386,8 @@ public class ResourceAllocationController extends GenericForwardComposer {
return resourceAllocationController.assignedEffortComponent;
}
},
RESOURCES_PER_DAY(CalculatedValue.RESOURCES_PER_DAY) {
RESOURCES_PER_DAY(CalculatedValue.RESOURCES_PER_DAY) {
@Override
public String getName() {
return _("Calculate Resources per Day");
@ -406,36 +400,34 @@ public class ResourceAllocationController extends GenericForwardComposer {
}
};
private final CalculatedValue calculatedValue;
CalculationTypeRadio(CalculatedValue calculatedValue) {
this.calculatedValue = calculatedValue;
}
public static CalculationTypeRadio from(CalculatedValue calculatedValue) {
Validate.notNull(calculatedValue);
for (CalculationTypeRadio calculationTypeRadio : CalculationTypeRadio
.values()) {
for (CalculationTypeRadio calculationTypeRadio : CalculationTypeRadio.values()) {
if (calculationTypeRadio.getCalculatedValue() == calculatedValue) {
return calculationTypeRadio;
}
}
throw new RuntimeException("not found "
+ CalculationTypeRadio.class.getSimpleName() + " for "
+ calculatedValue);
throw new RuntimeException(
"not found " + CalculationTypeRadio.class.getSimpleName() + " for " + calculatedValue);
}
public abstract Component input(
ResourceAllocationController resourceAllocationController);
public abstract Component input(ResourceAllocationController resourceAllocationController);
public Radio createRadio() {
Radio result = new Radio();
result.setLabel(getName());
result.setValue(toString());
return result;
}
private final CalculatedValue calculatedValue;
private CalculationTypeRadio(CalculatedValue calculatedValue) {
this.calculatedValue = calculatedValue;
}
public abstract String getName();
public CalculatedValue getCalculatedValue() {
@ -451,32 +443,37 @@ public class ResourceAllocationController extends GenericForwardComposer {
return new Label(data.getName());
}
},
ALPHA(_("Alpha")) {
@Override
public Component cellFor(DerivedAllocation data) {
return new Label(String.format("%3.2f", data.getAlpha()));
}
},
HOURS(_("Total Hours")) {
@Override
public Component cellFor(DerivedAllocation data) {
return new Label(data.getHours() + "");
return new Label(Integer.toString(data.getHours()));
}
};
private final String name;
private static final ICellForDetailItemRenderer<DerivedAllocationColumn, DerivedAllocation> cellRenderer =
(column, data) -> column.cellFor(data);
DerivedAllocationColumn(String name) {
this.name = name;
}
/**
* Forces to mark the string as needing translation
* Forces to mark the string as needing translation.
*/
private static String _(String string) {
return string;
}
private final String name;
private DerivedAllocationColumn(String name) {
this.name = name;
}
public String getName() {
return I18nHelper._(name);
}
@ -489,26 +486,16 @@ public class ResourceAllocationController extends GenericForwardComposer {
public static void appendColumnsTo(Grid grid) {
Columns columns = new Columns();
grid.appendChild(columns);
for (DerivedAllocationColumn each : values()) {
columns.appendChild(each.toColumn());
}
}
public static RowRenderer createRenderer() {
return OnColumnsRowRenderer.create(cellRenderer, Arrays
.asList(DerivedAllocationColumn.values()));
return OnColumnsRowRenderer.create(cellRenderer, Arrays.asList(DerivedAllocationColumn.values()));
}
private static final ICellForDetailItemRenderer<DerivedAllocationColumn, DerivedAllocation> cellRenderer= new ICellForDetailItemRenderer<DerivedAllocationColumn, DerivedAllocation>() {
@Override
public Component cellFor(
DerivedAllocationColumn column,
DerivedAllocation data) {
return column.cellFor(data);
}
};
abstract Component cellFor(DerivedAllocation data);
}
@ -516,15 +503,16 @@ public class ResourceAllocationController extends GenericForwardComposer {
return Arrays.asList(CalculationTypeRadio.values());
}
public List<? extends Object> getResourceAllocations() {
return formBinder != null ? plusAggregatingRow(formBinder
.getCurrentRows()) : Collections
.<AllocationRow> emptyList();
public List<?> getResourceAllocations() {
return formBinder != null
? plusAggregatingRow(formBinder.getCurrentRows())
: Collections.<AllocationRow> emptyList();
}
private List<Object> plusAggregatingRow(List<AllocationRow> currentRows) {
List<Object> result = new ArrayList<Object>(currentRows);
List<Object> result = new ArrayList<>(currentRows);
result.add(null);
return result;
}
@ -548,7 +536,6 @@ public class ResourceAllocationController extends GenericForwardComposer {
}
/**
*
* @return <code>true</code> if it must exist <code>false</code> if exit
* must be prevented
*/
@ -572,50 +559,39 @@ public class ResourceAllocationController extends GenericForwardComposer {
}
}
private void renderResourceAllocation(Row row, final AllocationRow data)
{
private void renderResourceAllocation(Row row, final AllocationRow data) {
row.setValue(data);
append(row, data.createDetail());
append(row, new Label(data.getName()));
append(row, new Label(data.getOriginalEffort().toFormattedString()));
append(row, new Label(data.getTotalEffort().toFormattedString()));
append(row, new Label(data.getConsolidatedEffort()
.toFormattedString()));
append(row, new Label(data.getConsolidatedEffort().toFormattedString()));
append(row, data.getEffortInput());
append(row, new Label(data.getTotalResourcesPerDay().getAmount()
.toString()));
append(row, new Label(data.getConsolidatedResourcesPerDay()
.getAmount().toString()));
append(row, new Label(data.getTotalResourcesPerDay().getAmount().toString()));
append(row, new Label(data.getConsolidatedResourcesPerDay().getAmount().toString()));
Div resourcesPerDayContainer = append(row, new Div());
append(resourcesPerDayContainer,
data.getIntendedResourcesPerDayInput());
Label realResourcesPerDay = append(resourcesPerDayContainer,
data.getRealResourcesPerDay());
append(resourcesPerDayContainer, data.getIntendedResourcesPerDayInput());
Label realResourcesPerDay = append(resourcesPerDayContainer, data.getRealResourcesPerDay());
realResourcesPerDay.setStyle("float: right; padding-right: 1em;");
Listbox assignmentFunctionListbox = data.getAssignmentFunctionListbox();
append(row, assignmentFunctionListbox);
assignmentFunctionListbox.addEventListener(Events.ON_SELECT,
new EventListener() {
@Override
public void onEvent(Event arg0) throws Exception {
data.resetAssignmentFunction();
}
});
assignmentFunctionListbox.addEventListener(Events.ON_SELECT, event -> data.resetAssignmentFunction());
// On click delete button
Button deleteButton = appendDeleteButton(row);
deleteButton.setDisabled(isAnyManualOrTaskUpdatedFromTimesheets());
formBinder.setDeleteButtonFor(data, deleteButton);
deleteButton.addEventListener("onClick", new EventListener() {
@Override
public void onEvent(Event event) {
editTaskController.getTaskPropertiesController().getListToDelete()
.add(data.getAssociatedResources().get(0));
removeAllocation(data);
}
deleteButton.addEventListener("onClick", event -> {
editTaskController
.getTaskPropertiesController()
.getListToDelete()
.add(data.getAssociatedResources().get(0));
removeAllocation(data);
});
if (!data.isSatisfied()) {
@ -632,12 +608,10 @@ public class ResourceAllocationController extends GenericForwardComposer {
append(row, allOriginalEffort);
append(row, allTotalEffort);
append(row, allConsolidatedEffort);
append(row, CalculationTypeRadio.NUMBER_OF_HOURS
.input(controller));
append(row, CalculationTypeRadio.NUMBER_OF_HOURS.input(controller));
append(row, allTotalResourcesPerDay);
append(row, allConsolidatedResourcesPerDay);
append(row, CalculationTypeRadio.RESOURCES_PER_DAY
.input(controller));
append(row, CalculationTypeRadio.RESOURCES_PER_DAY.input(controller));
append(row, new Label());
}
@ -652,6 +626,7 @@ public class ResourceAllocationController extends GenericForwardComposer {
button.setImage("/common/img/ico_borrar1.png");
button.setHoverImage("/common/img/ico_borrar.png");
button.setTooltiptext(_("Delete"));
return append(row, button);
}
@ -670,7 +645,7 @@ public class ResourceAllocationController extends GenericForwardComposer {
}
public boolean hasResourceAllocations() {
return ((getResourceAllocations().size() > 1));
return getResourceAllocations().size() > 1;
}
public boolean isAnyNotFlat() {
@ -678,11 +653,7 @@ public class ResourceAllocationController extends GenericForwardComposer {
}
public boolean isAnyManualOrTaskUpdatedFromTimesheets() {
if (formBinder == null) {
return false;
}
return formBinder.isAnyManual()
|| formBinder.isTaskUpdatedFromTimesheets();
return formBinder != null && (formBinder.isAnyManual() || formBinder.isTaskUpdatedFromTimesheets());
}
}

View file

@ -157,8 +157,6 @@ public class MultipleTabsPlannerController implements Composer, IGlobalViewEntry
@Autowired
private OrderCRUDController orderCRUDController;
@Autowired
private PlanningStateCreator planningStateCreator;

View file

@ -25,7 +25,6 @@ import static org.libreplan.web.I18nHelper._;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import org.joda.time.LocalDate;
@ -83,7 +82,7 @@ import org.zkoss.zul.api.Tabpanel;
* Controller for edit {@link Task} popup.
*
* @author Manuel Rego Casasnovas <mrego@igalia.com>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* @author Vova Perebykivskyi <vova@libreplan-enterprise.com>
*/
@org.springframework.stereotype.Component("taskPropertiesController")
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
@ -136,33 +135,36 @@ public class TaskPropertiesController extends GenericForwardComposer {
private boolean isResourcesAdded = false;
private List<Resource> listToDelete = new ArrayList<>();
private List<Resource> listToAdd = new ArrayList<>();
public void init(final EditTaskController editTaskController,
IContextWithPlannerTask<TaskElement> context,
TaskElement taskElement) {
IContextWithPlannerTask<TaskElement> context,
TaskElement taskElement) {
this.editTaskController = editTaskController;
this.currentContext = context;
this.currentTaskElement = taskElement;
Order order = null;
Order order;
if (context != null) {
order = findOrderIn(context);
} else {
order = taskElement.getOrderElement().getOrder();
}
// WebStartConstraintType.setItems(startConstraintTypes, order);
setItemsStartConstraintTypesCombo(order);
originalState = getResourceAllocationType(currentTaskElement);
setOldState(originalState);
disabledConstraintsAndAllocations = currentTaskElement
.isSubcontractedAndWasAlreadySent()
|| currentTaskElement.isLimitingAndHasDayAssignments()
|| currentTaskElement.isUpdatedFromTimesheets();
disabledConstraintsAndAllocations = currentTaskElement.isSubcontractedAndWasAlreadySent() ||
currentTaskElement.isLimitingAndHasDayAssignments() ||
currentTaskElement.isUpdatedFromTimesheets();
if (!disabledConstraintsAndAllocations && (currentTaskElement.isTask())) {
disabledConstraintsAndAllocations = ((Task) currentTaskElement)
.isManualAnyAllocation();
disabledConstraintsAndAllocations = ((Task) currentTaskElement).isManualAnyAllocation();
}
startConstraintTypes.setDisabled(disabledConstraintsAndAllocations);
startConstraintDate.setDisabled(disabledConstraintsAndAllocations);
@ -177,13 +179,16 @@ public class TaskPropertiesController extends GenericForwardComposer {
private void setItemsStartConstraintTypesCombo(Order order) {
startConstraintTypes.getChildren().clear();
for (PositionConstraintType type : PositionConstraintType.values()) {
if ((type != PositionConstraintType.AS_LATE_AS_POSSIBLE &&
if ( (type != PositionConstraintType.AS_LATE_AS_POSSIBLE &&
type != PositionConstraintType.AS_SOON_AS_POSSIBLE) ||
(type == PositionConstraintType.AS_LATE_AS_POSSIBLE &&
order.getDeadline() != null) ||
(type == PositionConstraintType.AS_SOON_AS_POSSIBLE &&
order.getInitDate() != null)) {
order.getInitDate() != null) ) {
Comboitem comboitem = new Comboitem(_(type.getName()));
comboitem.setValue(type);
startConstraintTypes.appendChild(comboitem);
@ -192,32 +197,31 @@ public class TaskPropertiesController extends GenericForwardComposer {
}
private Order findOrderIn(IContextWithPlannerTask<TaskElement> context) {
TaskElement topTask = context.getMapper().findAssociatedDomainObject(
findTopMostTask(context));
TaskElement topTask = context.getMapper().findAssociatedDomainObject(findTopMostTask(context));
return topTask.getParent().getOrderElement().getOrder();
}
private OrderElement findOrderElementIn(IContextWithPlannerTask<TaskElement> context) {
TaskElement topTask = context.getMapper().findAssociatedDomainObject(
findTopMostTask(context));
TaskElement topTask = context.getMapper().findAssociatedDomainObject(findTopMostTask(context));
return topTask.getOrderElement();
}
private org.zkoss.ganttz.data.Task findTopMostTask(
IContextWithPlannerTask<TaskElement> context) {
List<? extends TaskContainer> parents = context.getMapper().getParents(
context.getTask());
return parents.isEmpty() ? context.getTask() : parents.get(parents
.size() - 1);
private org.zkoss.ganttz.data.Task findTopMostTask(IContextWithPlannerTask<TaskElement> context) {
List<? extends TaskContainer> parents = context.getMapper().getParents(context.getTask());
return parents.isEmpty() ? context.getTask() : parents.get(parents.size() - 1);
}
private void setOldState(ResourceAllocationTypeEnum state) {
// TODO resolve deprecated
lbResourceAllocationType.setVariable("oldState", state, true);
}
private ResourceAllocationTypeEnum getOldState() {
return (ResourceAllocationTypeEnum) lbResourceAllocationType
.getVariable("oldState", true);
// TODO resolve deprecated
return (ResourceAllocationTypeEnum) lbResourceAllocationType.getVariable("oldState", true);
}
private void setResourceAllocationType(Listbox listbox, ResourceAllocationTypeEnum value) {
@ -225,10 +229,11 @@ public class TaskPropertiesController extends GenericForwardComposer {
}
private void setResourceAllocationType(Listbox listbox, String label) {
for (Iterator i = listbox.getChildren().iterator(); i.hasNext(); ) {
Listitem item = (Listitem) i.next();
for (Object o : listbox.getChildren()) {
Listitem item = (Listitem) o;
Listcell cell = (Listcell) item.getFirstChild();
if (cell.getLabel() != null && cell.getLabel().equals(label)) {
if ( cell.getLabel() != null && cell.getLabel().equals(label) ) {
item.setSelected(true);
}
}
@ -239,7 +244,7 @@ public class TaskPropertiesController extends GenericForwardComposer {
Task task = (Task) currentTaskElement;
showDurationRow(task);
showStartConstraintRow(task);
showResourceAllocationTypeRow(task);
showResourceAllocationTypeRow();
} else {
hideDurationRow();
if (currentTaskElement instanceof ITaskPositionConstrained) {
@ -258,7 +263,7 @@ public class TaskPropertiesController extends GenericForwardComposer {
resourceAllocationType.setVisible(false);
}
private void showResourceAllocationTypeRow(Task task) {
private void showResourceAllocationTypeRow() {
resourceAllocationType.setVisible(true);
}
@ -268,8 +273,7 @@ public class TaskPropertiesController extends GenericForwardComposer {
private void showStartConstraintRow(ITaskPositionConstrained task) {
startConstraint.setVisible(true);
PositionConstraintType type = task.getPositionConstraint()
.getConstraintType();
PositionConstraintType type = task.getPositionConstraint().getConstraintType();
startConstraintTypes.setSelectedItemApi(findComboWithType(type));
updateStartConstraint(type);
}
@ -278,7 +282,7 @@ public class TaskPropertiesController extends GenericForwardComposer {
for (Object component : startConstraintTypes.getChildren()) {
if (component instanceof Comboitem) {
Comboitem item = (Comboitem) component;
if (((PositionConstraintType) item.getValue()) == type) {
if ( item.getValue() == type) {
return item;
}
}
@ -292,29 +296,28 @@ public class TaskPropertiesController extends GenericForwardComposer {
}
private void updateStartConstraint(PositionConstraintType type) {
TaskPositionConstraint taskStartConstraint = currentTaskElementAsTaskLeafConstraint()
.getPositionConstraint();
TaskPositionConstraint taskStartConstraint = currentTaskElementAsTaskLeafConstraint().getPositionConstraint();
startConstraintDate.setVisible(type.isAssociatedDateRequired());
if (taskStartConstraint.getConstraintDateAsDate() != null) {
startConstraintDate.setValue(taskStartConstraint
.getConstraintDateAsDate());
startConstraintDate.setValue(taskStartConstraint.getConstraintDateAsDate());
}
}
private boolean saveConstraintChanges() {
TaskPositionConstraint taskConstraint = currentTaskElementAsTaskLeafConstraint()
.getPositionConstraint();
PositionConstraintType type = (PositionConstraintType) startConstraintTypes
.getSelectedItemApi().getValue();
IntraDayDate inputDate = type.isAssociatedDateRequired() ? IntraDayDate
.startOfDay(LocalDate.fromDateFields(startConstraintDate
.getValue())) : null;
TaskPositionConstraint taskConstraint = currentTaskElementAsTaskLeafConstraint().getPositionConstraint();
PositionConstraintType type = (PositionConstraintType) startConstraintTypes.getSelectedItemApi().getValue();
IntraDayDate inputDate = type.isAssociatedDateRequired()
? IntraDayDate.startOfDay(LocalDate.fromDateFields(startConstraintDate.getValue()))
: null;
if (taskConstraint.isValid(type, inputDate)) {
taskConstraint.update(type, inputDate);
//at this point we could call currentContext.recalculatePosition(currentTaskElement)
//to trigger the scheduling algorithm, but we don't do it because
//the ResourceAllocationController, which is attached to the other
//tab of the same window, will do it anyway.
// At this point we could call currentContext.recalculatePosition(currentTaskElement)
// to trigger the scheduling algorithm, but we don't do it because
// the ResourceAllocationController, which is attached to the other
// tab of the same window, will do it anyway.
return true;
} else {
return false;
@ -339,16 +342,14 @@ public class TaskPropertiesController extends GenericForwardComposer {
super.doAfterCompose(comp);
tabpanel = (Tabpanel) comp;
taskEditFormComposer.doAfterCompose(comp);
startConstraintTypes.addEventListener(Events.ON_SELECT,
new EventListener() {
@Override
public void onEvent(Event event) {
PositionConstraintType constraint = (PositionConstraintType) startConstraintTypes
.getSelectedItemApi().getValue();
constraintTypeChoosen(constraint);
}
});
startConstraintTypes.addEventListener(Events.ON_SELECT, event -> {
PositionConstraintType constraint =
(PositionConstraintType) startConstraintTypes.getSelectedItemApi().getValue();
constraintTypeChoosen(constraint);
});
lbResourceAllocationType.addEventListener(Events.ON_SELECT, new EventListener() {
@ -358,19 +359,22 @@ public class TaskPropertiesController extends GenericForwardComposer {
final ResourceAllocationTypeEnum oldState = getOldState();
ResourceAllocationTypeEnum newState = getSelectedValue(new ArrayList(se.getSelectedItems()));
if (thereIsTransition(newState)) {
if (isConsolidatedTask()) {
restoreOldState();
editTaskController.showNonPermitChangeResourceAllocationType();
} else {
if(newState.equals(ResourceAllocationTypeEnum.SUBCONTRACT)
&& !checkCompatibleAllocation()){
if (newState.equals(ResourceAllocationTypeEnum.SUBCONTRACT) && !checkCompatibleAllocation()) {
try {
restoreOldState();
Messagebox.show(_("This resource allocation type is incompatible. The task has an associated order element which has a progress that is of type subcontractor. "),
Messagebox.show(
_("This resource allocation type is incompatible. " +
"The task has an associated order element which has a progress that " +
"is of type subcontractor. "),
_("Error"), Messagebox.OK , Messagebox.ERROR);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
@ -379,27 +383,28 @@ public class TaskPropertiesController extends GenericForwardComposer {
}
}
}
if (oldState == null) {
setOldState(newState);
}
}
private ResourceAllocationTypeEnum getSelectedValue(List<Listitem> selectedItems) {
final Listitem item = (Listitem) selectedItems.get(0);
final Listitem item = selectedItems.get(0);
final Listcell cell = (Listcell) item.getChildren().get(0);
return ResourceAllocationTypeEnum.asEnum(cell.getLabel());
}
private void restoreOldState() {
Util.reloadBindings(lbResourceAllocationType);
}
private void restoreOldState() {
Util.reloadBindings(lbResourceAllocationType);
}
});
}
private boolean checkCompatibleAllocation(){
OrderElement orderElement = null;
OrderElement orderElement;
AdvanceType advanceType = PredefinedAdvancedTypes.SUBCONTRACTOR.getType();
if (this.currentContext != null) {
@ -407,15 +412,16 @@ public class TaskPropertiesController extends GenericForwardComposer {
} else {
orderElement = this.currentTaskElement.getOrderElement();
}
if(orderElement.getAdvanceAssignmentByType(advanceType) != null){
if (orderElement.getAdvanceAssignmentByType(advanceType) != null) {
return false;
}
try {
DirectAdvanceAssignment newAdvanceAssignment = DirectAdvanceAssignment
.create();
DirectAdvanceAssignment newAdvanceAssignment = DirectAdvanceAssignment.create();
newAdvanceAssignment.setAdvanceType(advanceType);
orderElement.checkAncestorsNoOtherAssignmentWithSameAdvanceType(
orderElement.getParent(), newAdvanceAssignment);
} catch (DuplicateAdvanceAssignmentForOrderElementException e) {
return false;
}
@ -427,10 +433,7 @@ public class TaskPropertiesController extends GenericForwardComposer {
}
public TaskDTO getGanttTaskDTO() {
if (taskEditFormComposer == null) {
return null;
}
return taskEditFormComposer.getTaskDTO();
return taskEditFormComposer == null ? null : taskEditFormComposer.getTaskDTO();
}
public void accept() {
@ -456,36 +459,40 @@ public class TaskPropertiesController extends GenericForwardComposer {
}
/**
* Enum for showing type of resource assignation option list
* Enum for showing type of resource assignation option list.
*
* @author Diego Pino Garcia <dpino@igalia.com>
*
*/
public enum ResourceAllocationTypeEnum {
NON_LIMITING_RESOURCES(_("Normal resource assignment")),
LIMITING_RESOURCES(_("Queue-based resource assignation")),
SUBCONTRACT(_("Subcontract"));
private String option;
private static final List<ResourceAllocationTypeEnum> nonMasterOptionList =
new ArrayList<ResourceAllocationTypeEnum>() {
{
add(NON_LIMITING_RESOURCES);
add(SUBCONTRACT);
}
};
ResourceAllocationTypeEnum(String option) {
this.option = option;
}
/**
* Forces to mark the string as needing translation
* Forces to mark the string as needing translation.
*/
private static String _(String string) {
return string;
}
private String option;
private static final List<ResourceAllocationTypeEnum> nonMasterOptionList = new ArrayList<ResourceAllocationTypeEnum>() {
{
add(NON_LIMITING_RESOURCES);
add(SUBCONTRACT);
}
};
private ResourceAllocationTypeEnum(String option) {
this.option = option;
}
@Override
public String toString() {
return I18nHelper._(option);
}
@ -505,8 +512,10 @@ public class TaskPropertiesController extends GenericForwardComposer {
public static ResourceAllocationTypeEnum asEnum(String label) {
if (NON_LIMITING_RESOURCES.toString().equals(label)) {
return NON_LIMITING_RESOURCES;
} else if (LIMITING_RESOURCES.toString().equals(label)) {
return LIMITING_RESOURCES;
} else if (SUBCONTRACT.toString().equals(label)) {
return SUBCONTRACT;
}
@ -516,11 +525,9 @@ public class TaskPropertiesController extends GenericForwardComposer {
}
public List<ResourceAllocationTypeEnum> getResourceAllocationTypeOptionList() {
if (scenarioManager.getCurrent().isMaster()) {
return ResourceAllocationTypeEnum.getOptionList();
} else {
return ResourceAllocationTypeEnum.getOptionListForNonMasterBranch();
}
return scenarioManager.getCurrent().isMaster()
? ResourceAllocationTypeEnum.getOptionList()
: ResourceAllocationTypeEnum.getOptionListForNonMasterBranch();
}
public ResourceAllocationTypeEnum getResourceAllocationType() {
@ -528,13 +535,11 @@ public class TaskPropertiesController extends GenericForwardComposer {
}
/**
* Does nothing, but it must exist for receiving selected value from listbox
* Does nothing, but it must exist for receiving selected value from ListBox.
*
* @param resourceAllocation
*/
public void setResourceAllocationType(ResourceAllocationTypeEnum resourceAllocation) {
}
public void setResourceAllocationType(ResourceAllocationTypeEnum resourceAllocation) {}
public ResourceAllocationTypeEnum getResourceAllocationType(TaskElement taskElement) {
if ( taskElement == null || !isTask(taskElement) ) {
@ -544,13 +549,13 @@ public class TaskPropertiesController extends GenericForwardComposer {
}
/**
* Returns type of resource allocation depending on state of task
* Returns type of resource allocation depending on state of task.
*
* If task is subcontracted, return a SUBCONTRACT state
* If task has at least one limiting resource, returns a LIMITING RESOURCE state
* Otherwise, return default state (NON-LIMITING RESOURCE)
* If task is subcontracted, return a SUBCONTRACT state.
* If task has at least one limiting resource, returns a LIMITING RESOURCE state.
* Otherwise, return default state (NON-LIMITING RESOURCE).
*
* @return
* @return {@link ResourceAllocationTypeEnum}
*/
public ResourceAllocationTypeEnum getResourceAllocationType(Task task) {
ResourceAllocationTypeEnum result = ResourceAllocationTypeEnum.NON_LIMITING_RESOURCES;
@ -583,7 +588,7 @@ public class TaskPropertiesController extends GenericForwardComposer {
}
/**
* Change state from NonLimitingResource assignation type to a new state (limiting, subcontract)
* Change state from NonLimitingResource assignation type to a new state (limiting, subcontract).
*
* @param newState
*/
@ -595,17 +600,17 @@ public class TaskPropertiesController extends GenericForwardComposer {
Task task = asTask(currentTaskElement);
if (task.hasResourceAllocations()) {
try {
if (Messagebox.show(_("Assigned resources for this task will be deleted. Are you sure?"),
if (Messagebox.show(
_("Assigned resources for this task will be deleted. Are you sure?"),
_("Warning"), Messagebox.OK | Messagebox.CANCEL, Messagebox.QUESTION) == Messagebox.OK) {
task.removeAllResourceAllocations();
setStateTo(newState);
} else {
resetStateTo(ResourceAllocationTypeEnum.NON_LIMITING_RESOURCES);
}
return;
} catch (InterruptedException e) {
}
} catch (InterruptedException ignored) {}
}
setStateTo(newState);
}
@ -621,7 +626,7 @@ public class TaskPropertiesController extends GenericForwardComposer {
}
/**
* Change state from LimitingResource assignation type to a new state (non-limiting, subcontract)
* Change state from LimitingResource assignation type to a new state (non-limiting, subcontract).
*
* @param newState
*/
@ -633,23 +638,23 @@ public class TaskPropertiesController extends GenericForwardComposer {
Task task = asTask(currentTaskElement);
if (task.hasResourceAllocations()) {
try {
if (Messagebox.show(_("Assigned resources for this task will be deleted. Are you sure?"),
if (Messagebox.show(
_("Assigned resources for this task will be deleted. Are you sure?"),
_("Warning"), Messagebox.OK | Messagebox.CANCEL, Messagebox.QUESTION) == Messagebox.OK) {
task.removeAllResourceAllocations();
setStateTo(newState);
} else {
resetStateTo(ResourceAllocationTypeEnum.LIMITING_RESOURCES);
}
return;
} catch (InterruptedException e) {
}
} catch (InterruptedException ignored) {}
}
setStateTo(newState);
}
/**
* Change state from Subcontract assignation type to a new state (non-limiting, limiting)
* Change state from Subcontract assignation type to a new state (non-limiting, limiting).
*
* @param newState
*/
@ -657,23 +662,25 @@ public class TaskPropertiesController extends GenericForwardComposer {
Task task = asTask(currentTaskElement);
if (task.isSubcontracted()) {
final Date communicationDate = (task.getSubcontractedTaskData() != null) ?
task.getSubcontractedTaskData().getSubcontractCommunicationDate()
final Date communicationDate = (task.getSubcontractedTaskData() != null)
? task.getSubcontractedTaskData().getSubcontractCommunicationDate()
: null;
// Notification has been sent
if (communicationDate != null) {
try {
if (Messagebox.show(_("IMPORTANT: Don't forget to communicate to subcontractor that his contract has been cancelled"),
if (Messagebox.show(
_("IMPORTANT: Don't forget to communicate to subcontractor " +
"that his contract has been cancelled"),
_("Warning"), Messagebox.OK, Messagebox.EXCLAMATION) == Messagebox.OK) {
setStateTo(newState);
} else {
resetStateTo(ResourceAllocationTypeEnum.SUBCONTRACT);
}
return;
} catch (InterruptedException e) {
}
} catch (InterruptedException ignored) {}
}
}
setStateTo(newState);
@ -704,10 +711,8 @@ public class TaskPropertiesController extends GenericForwardComposer {
public boolean isConsolidatedTask() {
Task task = asTask(currentTaskElement);
if (task != null) {
return task.hasConsolidations();
}
return false;
return task != null && task.hasConsolidations();
}
public void updateTaskEndDate(LocalDate endDate) {
@ -716,8 +721,7 @@ public class TaskPropertiesController extends GenericForwardComposer {
}
public void updateTaskStartDate(LocalDate newStart) {
getGanttTaskDTO().beginDate = newStart.toDateTimeAtStartOfDay()
.toDate();
getGanttTaskDTO().beginDate = newStart.toDateTimeAtStartOfDay().toDate();
Util.reloadBindings(startDateBox);
}
@ -733,14 +737,11 @@ public class TaskPropertiesController extends GenericForwardComposer {
return Util.getMoneyFormat();
}
public List<Resource> listToDelete = new ArrayList<Resource>();
public List<Resource> listToAdd = new ArrayList<Resource>();
public void emailNotificationAddNew() {
public void emailNotificationAddNew(){
/**
* 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
/*
* 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
*/
@ -751,14 +752,14 @@ public class TaskPropertiesController extends GenericForwardComposer {
}
private void proceedList(EmailTemplateEnum enumeration, List<Resource> list){
if ( list.size() != 0 ){
if ( !list.isEmpty() ) {
List<Worker> workersList = workerModel.getWorkers();
Worker currentWorker;
Resource currentResource;
for (int i = 0; i < workersList.size(); i++)
for (int j = 0; j < list.size(); j++){
for (int j = 0; j < list.size(); j++) {
currentWorker = workersList.get(i);
currentResource = list.get(j);
@ -783,6 +784,7 @@ public class TaskPropertiesController extends GenericForwardComposer {
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);
@ -797,8 +799,10 @@ public class TaskPropertiesController extends GenericForwardComposer {
emailNotificationModel.confirmSave();
} catch (DataIntegrityViolationException e){
try {
Messagebox.show(_("You cannot email user twice with the same info"), _("Error"),
Messagebox.show(
_("You cannot email user twice with the same info"), _("Error"),
Messagebox.OK, Messagebox.ERROR);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
@ -809,11 +813,15 @@ public class TaskPropertiesController extends GenericForwardComposer {
return listToDelete;
}
public List<Resource> getListToAdd() {
return listToAdd;
}
public void setResourcesAdded(boolean resourcesAdded) {
isResourcesAdded = resourcesAdded;
}
private TaskPropertiesController getObject(){
private TaskPropertiesController getObject() {
return this;
}

View file

@ -1,119 +0,0 @@
/*
* This file is part of LibrePlan
*
* Copyright (C) 2012 Igalia, S.L.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*//*
package org.libreplan.web.users.services;
import javax.servlet.http.HttpServletRequest;
import org.libreplan.business.common.IAdHocTransactionService;
import org.libreplan.business.common.IOnTransaction;
import org.libreplan.business.common.exceptions.InstanceNotFoundException;
import org.libreplan.business.users.daos.IOrderAuthorizationDAO;
import org.libreplan.business.users.daos.IUserDAO;
import org.libreplan.business.users.entities.User;
import org.libreplan.business.users.entities.UserRole;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.Authentication;
import org.springframework.security.ui.TargetUrlResolverImpl;
import org.springframework.security.ui.savedrequest.SavedRequest;
import org.springframework.security.userdetails.UserDetails;
*/
/**
* Determines the URL for authenticated users depending on if user is bound or
* not to any resource.<br />
*
* If the user is bound to a resource then the target URL will be the user
* dashboard.
*
* @author Manuel Rego Casasnovas <mrego@igalia.com>
*//*
public class CustomTargetUrlResolver extends TargetUrlResolverImpl {
public final static String USER_DASHBOARD_URL = "/myaccount/userDashboard.zul";
public static final String PLANNING_URL = "/planner/index.zul";
public static final String SETTINGS_URL = "/myaccount/settings.zul";
@Autowired
private IUserDAO userDAO;
@Autowired
private IOrderAuthorizationDAO orderAuthorizationDAO;
@Autowired
private IAdHocTransactionService transactionServiceDAO;
@Override
public String determineTargetUrl(SavedRequest savedRequest,
HttpServletRequest currentRequest, final Authentication auth) {
if (isUserInRole(auth, UserRole.ROLE_SUPERUSER.name())) {
return super.determineTargetUrl(savedRequest, currentRequest, auth);
}
if (isUserInRole(auth, UserRole.ROLE_BOUND_USER.name())) {
return USER_DASHBOARD_URL;
}
if (isUserInRole(auth, UserRole.ROLE_PLANNING.name())) {
return PLANNING_URL;
}
boolean userOrItsProfilesHaveAnyAuthorization = transactionServiceDAO
.runOnReadOnlyTransaction(new IOnTransaction<Boolean>() {
@Override
public Boolean execute() {
try {
UserDetails userDetails = (UserDetails) auth.getPrincipal();
User user = userDAO.findByLoginName(userDetails.getUsername());
user.getProfiles().size();
return orderAuthorizationDAO
.userOrItsProfilesHaveAnyAuthorization(user);
} catch (InstanceNotFoundException e) {
throw new RuntimeException(e);
}
}
});
if (userOrItsProfilesHaveAnyAuthorization) {
return PLANNING_URL;
}
return SETTINGS_URL;
}
private boolean isUserInRole(Authentication auth, String role) {
if ((auth == null) || (auth.getPrincipal() == null)
|| (auth.getAuthorities() == null)) {
return false;
}
for (int i = 0; i < auth.getAuthorities().length; i++) {
if (role.equals(auth.getAuthorities()[i].getAuthority())) {
return true;
}
}
return false;
}
}
*/

View file

@ -63,9 +63,9 @@ import org.springframework.transaction.annotation.Transactional;
@Path("/orderelements/")
@Produces("application/xml")
@Service("orderElementServiceREST")
public class OrderElementServiceREST extends
GenericRESTService<Order, OrderDTO> implements
IOrderElementService {
public class OrderElementServiceREST
extends GenericRESTService<Order, OrderDTO>
implements IOrderElementService {
@Autowired
private IOrderDAO orderDAO;
@ -86,15 +86,13 @@ public class OrderElementServiceREST extends
@Override
@POST
@Consumes("application/xml")
public InstanceConstraintViolationsListDTO addOrders(
OrderListDTO orderListDTO) {
public InstanceConstraintViolationsListDTO addOrders(OrderListDTO orderListDTO) {
return save(orderListDTO.orderDTOs);
}
@Override
protected OrderDTO toDTO(Order entity) {
return (OrderDTO) OrderElementConverter.toDTO(entity,
ConfigurationOrderElementConverter.all());
return (OrderDTO) OrderElementConverter.toDTO(entity, ConfigurationOrderElementConverter.all());
}
@Override
@ -103,17 +101,15 @@ public class OrderElementServiceREST extends
}
@Override
protected Order toEntity(OrderDTO entityDTO) throws ValidationException,
RecoverableErrorException {
return (Order) OrderElementConverter.toEntity(entityDTO,
ConfigurationOrderElementConverter.all());
protected Order toEntity(OrderDTO entityDTO) throws ValidationException, RecoverableErrorException {
return (Order) OrderElementConverter.toEntity(entityDTO, ConfigurationOrderElementConverter.all());
}
@Override
protected void updateEntity(Order entity, OrderDTO entityDTO)
throws ValidationException, RecoverableErrorException {
OrderElementConverter.update(entity, entityDTO,
ConfigurationOrderElementConverter.all());
OrderElementConverter.update(entity, entityDTO, ConfigurationOrderElementConverter.all());
}
@Override
@ -133,8 +129,7 @@ public class OrderElementServiceREST extends
OrderElement orderElement = orderElementDAO.findByCode(code);
String errorMessage = checkRemovalValidation(orderElement);
if (errorMessage != null) {
return Response.status(Status.FORBIDDEN)
.entity(new ErrorDTO(errorMessage)).build();
return Response.status(Status.FORBIDDEN).entity(new ErrorDTO(errorMessage)).build();
}
if (orderElement.isOrder()) {
@ -152,6 +147,7 @@ public class OrderElementServiceREST extends
if (!parent.isOrder() && parent.getChildren().isEmpty()) {
OrderElement newElement = parent.toLeaf();
if (!order.isCodeAutogenerated()) {
newElement.setCode(UUID.randomUUID().toString());
}
@ -170,12 +166,12 @@ public class OrderElementServiceREST extends
private String checkRemovalValidation(OrderElement orderElement) {
try {
if (orderElementDAO
.isAlreadyInUseThisOrAnyOfItsChildren(orderElement)) {
if (orderElementDAO.isAlreadyInUseThisOrAnyOfItsChildren(orderElement)) {
return "You cannot remove the order element '"
+ orderElement.getName()
+ "' because it or any of its children have tracked time in some work report";
}
if (orderElementDAO.hasImputedExpenseSheetThisOrAnyOfItsChildren(orderElement.getId())) {
return "You cannot remove the order element '"
+ orderElement.getName()
@ -183,13 +179,13 @@ public class OrderElementServiceREST extends
}
OrderLineGroup parent = orderElement.getParent();
if (parent != null && !parent.isOrder()
&& parent.getChildren().size() == 1) {
if (parent != null && !parent.isOrder() && parent.getChildren().size() == 1) {
if (orderElementDAO.isAlreadyInUse(parent)) {
return "You cannot remove the order element '"
+ orderElement.getName()
+ "' because it is the only child of its parent and its parent has tracked time in some work report";
}
if (orderElementDAO.hasImputedExpenseSheet(parent.getId())) {
return "You cannot remove the order element '"
+ orderElement.getName()
@ -207,6 +203,7 @@ public class OrderElementServiceREST extends
if (orderElement.getId().equals(id)) {
return orderElement;
}
for (OrderElement child : orderElement.getChildren()) {
OrderElement found = findOrderElement(child, id);
if (found != null) {

View file

@ -38,7 +38,7 @@
<!-- Pages -->
<intercept-url pattern="/templates/*" access="hasAnyRole('ROLE_SUPERUSER', 'ROLE_TEMPLATES')" />
<intercept-url pattern="/email/*" access="ROLE_SUPERUSER"/>
<intercept-url pattern="/email/*" access="hasAnyRole('ROLE_SUPERUSER', 'ROLE_EDIT_EMAIL_TEMPLATES')"/>
<intercept-url pattern="/resources/worker/worker.zul" access="hasAnyRole('ROLE_SUPERUSER', 'ROLE_WORKERS')" />
<intercept-url pattern="/resources/machine/*" access="hasAnyRole('ROLE_SUPERUSER', 'ROLE_MACHINES')" />

View file

@ -1,20 +1,20 @@
<!--
This file is part of LibrePlan
<!--
This file is part of LibrePlan
Copyright (C) 2015 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 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.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
@ -32,104 +32,107 @@
<window self="@{define(content)}" apply="org.libreplan.web.email.EmailTemplateController"
title="${i18n:_('Edit E-mail template')}">
<vbox id="messagesContainer" />
<tabbox>
<tabs>
<tab label="${i18n:_('Template data')}"/>
</tabs>
<tabpanels>
<tabpanel>
<groupbox>
<caption label="${i18n:_('General user data')}" />
<grid>
<columns>
<column width="220px"></column>
<column width="420px"></column>
</columns>
<rows>
<row>
<label value="${i18n:_('Select template language')}"/>
<listbox mold="select"
id="templateLanguageListbox"
model="@{emailTemplateController.languages}"
itemRenderer="@{emailTemplateController.languagesRenderer}"
selectedItem="@{emailTemplateController.selectedLanguage}">
</listbox>
</row>
<row>
<label value="${i18n:_('Select template type')}"/>
<listbox id="emailTemplateTypeListbox"
mold="select"
model="@{emailTemplateController.emailTemplateEnum}"
itemRenderer="@{emailTemplateController.emailTemplateEnumRenderer}"
selectedItem="@{emailTemplateController.selectedEmailTemplateEnum}"/>
</row>
<row>
<label value="${i18n:_('E-mail subject')}"/>
<textbox id="subjectTextbox"
width="400px;" />
</row>
<row>
<label value="${i18n:_('Template contents')}"/>
<tabbox>
<tabs>
<tab label="${i18n:_('Template data')}"/>
</tabs>
<tabpanels>
<tabpanel>
<groupbox>
<caption label="${i18n:_('General user data')}" />
<grid>
<columns>
<column width="220px"/>
<column width="420px"/>
</columns>
<rows>
<row>
<label value="${i18n:_('Select template language')}"/>
<listbox mold="select"
id="templateLanguageListbox"
model="@{emailTemplateController.languages}"
itemRenderer="@{emailTemplateController.languagesRenderer}"
selectedItem="@{emailTemplateController.selectedLanguage}">
</listbox>
</row>
<row>
<label value="${i18n:_('Select template type')}"/>
<listbox id="emailTemplateTypeListbox"
mold="select"
model="@{emailTemplateController.emailTemplateEnum}"
itemRenderer="@{emailTemplateController.emailTemplateEnumRenderer}"
selectedItem="@{emailTemplateController.selectedEmailTemplateEnum}"/>
</row>
<row>
<label value="${i18n:_('E-mail subject')}"/>
<textbox id="subjectTextbox"
width="400px;" />
</row>
<row>
<label value="${i18n:_('Template contents')}"/>
<textbox id="contentsTextbox"
rows="15" width="400px;"
tabindex="11"/>
<groupbox closable="false" width="270px">
<caption label="${i18n:_('Possible content keywords')}"/>
<grid width="250px">
<columns>
<column label="${i18n:_('Keyword')}"/>
<column label="${i18n:_('Description')}"/>
</columns>
<textbox id="contentsTextbox"
rows="15" width="400px;"
tabindex="11"/>
<groupbox closable="false" width="270px">
<caption label="${i18n:_('Possible content keywords')}"/>
<grid width="250px">
<columns>
<column label="${i18n:_('Keyword')}"/>
<column label="${i18n:_('Description')}"/>
</columns>
<rows>
<row>
<label value="{username}"/>
<label value="${i18n:_('Username of user')}"/>
</row>
<rows>
<row>
<label value="{username}"/>
<label value="${i18n:_('Username of user')}"/>
</row>
<row>
<label value="{firstname}"/>
<label value="${i18n:_('First name of user')}"/>
</row>
<row>
<label value="{firstname}"/>
<label value="${i18n:_('First name of user')}"/>
</row>
<row>
<label value="{lastname}"/>
<label value="${i18n:_('Last name of user')}"/>
</row>
<row>
<label value="{lastname}"/>
<label value="${i18n:_('Last name of user')}"/>
</row>
<row>
<label value="{project}"/>
<label value="${i18n:_('Name of project')}"/>
</row>
<row>
<label value="{project}"/>
<label value="${i18n:_('Name of project')}"/>
</row>
<row>
<label value="{resource}"/>
<label value="${i18n:_('Name of resource')}"/>
</row>
<row>
<label value="{resource}"/>
<label value="${i18n:_('Name of resource')}"/>
</row>
<row>
<label value="{task}"/>
<label value="${i18n:_('Name of task')}"/>
</row>
<row>
<label value="{task}"/>
<label value="${i18n:_('Name of task')}"/>
</row>
<row>
<label value="{url}"/>
<label value="${i18n:_('Welcome page')}"/>
</row>
</rows>
<row>
<label value="{url}"/>
<label value="${i18n:_('Welcome page')}"/>
</row>
</rows>
</grid>
</groupbox>
</row>
</rows>
</grid>
</groupbox>
</tabpanel>
</tabpanels>
</tabbox>
<button onClick="emailTemplateController.save()" autodisable="self" label="${i18n:_('Save')}" sclass="save-button global-action"/>
<button onClick="emailTemplateController.cancel()" label="${i18n:_('Cancel')}" sclass="cancel-button global-action"/>
</grid>
</groupbox>
</row>
</rows>
</grid>
</groupbox>
</tabpanel>
</tabpanels>
</tabbox>
<button onClick="emailTemplateController.save()" autodisable="self" label="${i18n:_('Save')}"
sclass="save-button global-action"/>
<button onClick="emailTemplateController.cancel()" label="${i18n:_('Cancel')}"
sclass="cancel-button global-action"/>
</window>
</zk>

View file

@ -0,0 +1,298 @@
package org.libreplan.web.test.ws.email;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.libreplan.business.common.Registry;
import org.libreplan.business.common.entities.Connector;
import org.libreplan.business.common.entities.ConnectorProperty;
import org.libreplan.business.common.exceptions.InstanceNotFoundException;
import org.libreplan.business.email.daos.IEmailNotificationDAO;
import org.libreplan.business.email.daos.IEmailTemplateDAO;
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.orders.entities.HoursGroup;
import org.libreplan.business.orders.entities.Order;
import org.libreplan.business.orders.entities.OrderLine;
import org.libreplan.business.orders.entities.SchedulingDataForVersion;
import org.libreplan.business.orders.entities.TaskSource;
import org.libreplan.business.orders.entities.OrderElement;
import org.libreplan.business.planner.daos.ITaskElementDAO;
import org.libreplan.business.planner.entities.Task;
import org.libreplan.business.planner.entities.TaskGroup;
import org.libreplan.business.resources.daos.IWorkerDAO;
import org.libreplan.business.resources.entities.Worker;
import org.libreplan.business.scenarios.bootstrap.IScenariosBootstrap;
import org.libreplan.business.scenarios.entities.OrderVersion;
import org.libreplan.business.settings.entities.Language;
import org.libreplan.business.users.daos.IUserDAO;
import org.libreplan.business.users.entities.User;
import org.libreplan.business.users.entities.UserRole;
import org.libreplan.business.workingday.IntraDayDate;
import org.libreplan.importers.notifications.EmailConnectionValidator;
import org.libreplan.importers.notifications.IEmailNotificationJob;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
import javax.mail.MessagingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import static org.easymock.EasyMock.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.libreplan.business.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_FILE;
import static org.libreplan.web.WebappGlobalNames.WEBAPP_SPRING_CONFIG_FILE;
import static org.libreplan.web.WebappGlobalNames.WEBAPP_SPRING_SECURITY_CONFIG_FILE;
import static org.libreplan.web.test.WebappGlobalNames.WEBAPP_SPRING_CONFIG_TEST_FILE;
import static org.libreplan.web.test.WebappGlobalNames.WEBAPP_SPRING_SECURITY_CONFIG_TEST_FILE;
/**
* Tests for {@link EmailTemplate}, {@link EmailNotification}.
*
* @author Created by Vova Perebykivskyi on 06.22.2016.
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
BUSINESS_SPRING_CONFIG_FILE,
WEBAPP_SPRING_CONFIG_FILE,
WEBAPP_SPRING_CONFIG_TEST_FILE,
WEBAPP_SPRING_SECURITY_CONFIG_FILE,
WEBAPP_SPRING_SECURITY_CONFIG_TEST_FILE })
public class EmailTest {
@Autowired
private IEmailTemplateDAO emailTemplateDAO;
@Autowired
private IScenariosBootstrap scenariosBootstrap;
@Autowired
private IEmailNotificationDAO emailNotificationDAO;
@Qualifier("sendEmailOnTaskShouldStart")
@Autowired
private IEmailNotificationJob taskShouldStart;
@Autowired
private IWorkerDAO workerDAO;
@Autowired
private ITaskElementDAO taskElementDAO;
@Autowired
private IUserDAO userDAO;
@Before
public void loadRequiredData() {
scenariosBootstrap.loadRequiredData();
}
@Test
@Transactional
public void testACreateEmailTemplate() {
EmailTemplate emailTemplate = createEmailTemplate();
emailTemplateDAO.save(emailTemplate);
EmailTemplate newEmailTemplate = emailTemplateDAO.findByTypeAndLanguage(
EmailTemplateEnum.TEMPLATE_TODAY_TASK_SHOULD_START, Language.ENGLISH_LANGUAGE);
assertEquals(emailTemplate, newEmailTemplate);
}
@Test
@Transactional
public void testBCreateEmailNotification() {
emailTemplateDAO.save(createEmailTemplate());
EmailNotification emailNotification = createEmailNotification();
emailNotificationDAO.save(emailNotification);
try {
EmailNotification newEmailNotification = emailNotificationDAO.find(emailNotification.getId());
assertEquals(emailNotification, newEmailNotification);
} catch (InstanceNotFoundException e) {
e.printStackTrace();
}
}
@Test
@Transactional
public void testCSendEmail() {
EmailTemplate emailTemplate = createEmailTemplate();
emailTemplateDAO.save(emailTemplate);
EmailNotification emailNotification = createEmailNotification();
emailNotificationDAO.save(emailNotification);
// Before sending an Email I should specify email connector properties
createEmailConnector();
/*
* Now I should call taskShouldStart.sendEmail();
* But I will drop on checking email connection properties.
* So I will get exception. Test is over.
* There is no possibility to send message without real connection data.
*/
taskShouldStart.sendEmail();
emailTemplateDAO.delete(emailTemplate);
emailNotificationDAO.deleteAll();
assertTrue(EmailConnectionValidator.exceptionType instanceof MessagingException);
}
private EmailTemplate createEmailTemplate() {
EmailTemplate emailTemplate = new EmailTemplate();
emailTemplate.setType(EmailTemplateEnum.TEMPLATE_TODAY_TASK_SHOULD_START);
emailTemplate.setLanguage(Language.ENGLISH_LANGUAGE);
emailTemplate.setSubject("Last words of Dunkan");
emailTemplate.setContent("May He watch over us all...");
return emailTemplate;
}
private EmailNotification createEmailNotification() {
EmailTemplate emailTemplate = emailTemplateDAO.findByTypeAndLanguage(
EmailTemplateEnum.TEMPLATE_TODAY_TASK_SHOULD_START, Language.ENGLISH_LANGUAGE);
EmailNotification emailNotification = new EmailNotification();
emailNotification.setType(emailTemplate.getType());
emailNotification.setUpdated(new Date());
emailNotification.setResource(createWorker());
emailNotification.setProject(createProjectWithTask());
emailNotification.setTask(emailNotification.getProject().getChildren().get(0));
return emailNotification;
}
private Worker createWorker() {
Worker warden = Worker.create();
warden.setFirstName("Alistair");
warden.setSurname("Theirin");
warden.setNif("9:10 Dragon");
warden.setUser(createUser());
workerDAO.save(warden);
return warden;
}
private User createUser() {
User user = User.create("Cole", "Spirit", "vova235@gmail.com");
user.addRole(UserRole.ROLE_EMAIL_TASK_SHOULD_START);
userDAO.save(user);
return user;
}
private TaskGroup createProjectWithTask() {
TaskGroup parent = createTaskGroup();
Task child = createTask();
parent.addTaskElement(child);
taskElementDAO.save(parent);
return parent;
}
private TaskGroup createTaskGroup() {
HoursGroup hoursGroup = new HoursGroup();
hoursGroup.setWorkingHours(6);
Order order = new Order();
order.useSchedulingDataFor(mockOrderVersion());
order.setInitDate(new Date());
OrderLine orderLine = OrderLine.create();
orderLine.setName("Project: Send Email");
order.add(orderLine);
SchedulingDataForVersion version = mockSchedulingDataForVersion(orderLine);
TaskSource taskSource = TaskSource.create(version, Collections.singletonList(hoursGroup));
TaskGroup result = TaskGroup.create(taskSource);
result.setIntraDayEndDate(IntraDayDate.startOfDay(result.getIntraDayStartDate().getDate().plusDays(10)));
return result;
}
private OrderVersion mockOrderVersion() {
OrderVersion result = createNiceMock(OrderVersion.class);
replay(result);
return result;
}
private SchedulingDataForVersion mockSchedulingDataForVersion(OrderElement orderElement) {
SchedulingDataForVersion result = createNiceMock(SchedulingDataForVersion.class);
TaskSource taskSource = createNiceMock(TaskSource.class);
expect(result.getOrderElement()).andReturn(orderElement).anyTimes();
expect(taskSource.getOrderElement()).andReturn(orderElement).anyTimes();
expect(result.getTaskSource()).andReturn(taskSource).anyTimes();
replay(result, taskSource);
return result;
}
private Task createTask() {
HoursGroup hoursGroup = new HoursGroup();
hoursGroup.setWorkingHours(5);
OrderLine orderLine = OrderLine.create();
orderLine.setName("Task: use Quartz");
Order order = new Order();
order.useSchedulingDataFor(mockOrderVersion());
order.setInitDate(new Date());
order.add(orderLine);
SchedulingDataForVersion version = mockSchedulingDataForVersion(orderLine);
TaskSource taskSource = TaskSource.create(version, Collections.singletonList(hoursGroup));
return Task.createTask(taskSource);
}
private void createEmailConnector() {
Connector connector = Connector.create("E-mail");
List<ConnectorProperty> properties = new ArrayList<>();
properties.add(ConnectorProperty.create("Activated", "Y"));
properties.add(ConnectorProperty.create("Protocol", "SMTP"));
properties.add(ConnectorProperty.create("Host", "127.0.0.2"));
properties.add(ConnectorProperty.create("Port", "25"));
properties.add(ConnectorProperty.create("Email sender", "dunkan@libreplan-enterprise.com"));
properties.add(ConnectorProperty.create("Email username", ""));
properties.add(ConnectorProperty.create("Email password", ""));
connector.setProperties(properties);
Registry.getConnectorDAO().save(connector);
}
}

View file

@ -643,6 +643,12 @@ public class OrderElementServiceTest {
assertThat(response.getStatus(), equalTo(Status.OK.getStatusCode()));
try {
/*
* Flush is needed because
* before there were errors that after removing object some references were still present.
*/
sessionFactory.getCurrentSession().flush();
orderElementDAO.findByCode(codeToRemove);
} catch (InstanceNotFoundException e) {
assertTrue(true);

View file

@ -91,6 +91,12 @@
<value>
org/libreplan/business/scenarios/entities/Scenarios.hbm.xml
</value>
<value>
org/libreplan/business/email/entities/Email.hbm.xml
</value>
<value>
org/libreplan/business/common/entities/Connector.hbm.xml
</value>
</list>
</property>

58
pom.xml
View file

@ -125,7 +125,7 @@
<dataSource.url>jdbc:postgresql://localhost/libreplan${libreplan.mode}</dataSource.url>
<testDataSource.url>${dataSource.url}test</testDataSource.url>
<!-- Hibernate properties -->
<hibernate.dialect>org.hibernate.dialect.PostgreSQL9Dialect</hibernate.dialect>
<hibernate.dialect>org.hibernate.dialect.PostgreSQL82Dialect</hibernate.dialect>
<databasetable.prefix>public.</databasetable.prefix>
</properties>
</profile>
@ -521,7 +521,7 @@
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.1.6</version>
<version>3.1.7</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
@ -541,10 +541,11 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>3.1.6</version>
<version>3.1.7</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
@ -560,24 +561,11 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-client</artifactId>
<version>3.1.6</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</exclusion>
</exclusions>
<version>3.1.7</version>
</dependency>
<!-- Jackson provider -->
@ -645,19 +633,27 @@
<!-- Quartz framework -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.3</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.3</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Java mail -->
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.5.5</version>
</dependency>
</dependencies>