Add tests for Email functionality.

Resolve minor issues with email functionality.
Resolve issue with test failing.
Update Java Mail library, Apache CXF.
Code refactoring.
This commit is contained in:
Vova Perebykivskyi 2016-08-04 14:17:35 +03:00 committed by Dgray16
parent cb0b44adb2
commit 39f5df1d30
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; import org.libreplan.business.common.daos.IJobSchedulerConfigurationDAO;
/** /**
* JobSchedulerConfiguration entity, represents parameters for the jobs to be * JobSchedulerConfiguration entity, represents parameters for the jobs to be scheduled.
* scheduled. This entity is used by the <code>SchedulerManager</code> to * This entity is used by the <code>SchedulerManager</code> to
* schedule jobs and in UI to show the scheduler status. * schedule jobs and in UI to show the scheduler status.
* *
* The <code>jobGroup</code> and <code>jobName</code> together forms a job key * 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 * and non of the fields must be null. Moreover it should contain a valid <code>cronExpression</code>.
* <code>cronExpression</code>
* *
* @author Miciele Ghiorghis <m.ghiorghis@antoniusziekenhuis.nl> * @author Miciele Ghiorghis <m.ghiorghis@antoniusziekenhuis.nl>
*/ */
public class JobSchedulerConfiguration extends BaseEntity implements IHumanIdentifiable { 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 jobGroup;
private String jobName; private String jobName;
@ -62,6 +51,15 @@ public class JobSchedulerConfiguration extends BaseEntity implements IHumanIdent
private String connectorName; 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") @NotNull(message = "job group not specified")
public String getJobGroup() { public String getJobGroup() {
return jobGroup; return jobGroup;
@ -124,7 +122,9 @@ public class JobSchedulerConfiguration extends BaseEntity implements IHumanIdent
if ( StringUtils.isBlank(jobGroup) && StringUtils.isBlank(jobName) ) { if ( StringUtils.isBlank(jobGroup) && StringUtils.isBlank(jobName) ) {
return true; return true;
} }
IJobSchedulerConfigurationDAO jobSchedulerConfigurationDAO = Registry.getJobSchedulerConfigurationDAO(); IJobSchedulerConfigurationDAO jobSchedulerConfigurationDAO = Registry.getJobSchedulerConfigurationDAO();
if ( isNewObject() ) { if ( isNewObject() ) {
return !jobSchedulerConfigurationDAO.existsByJobGroupAndJobNameAnotherTransaction(this); return !jobSchedulerConfigurationDAO.existsByJobGroupAndJobNameAnotherTransaction(this);
} else { } else {

View file

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

View file

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

View file

@ -28,15 +28,17 @@ import java.util.List;
/** /**
* Contract for {@link EmailNotificationDAO} * Contract for {@link EmailNotificationDAO}
* *
* Created by * @author Created by Vova Perebykivskiy <vova@libreplan-enterprise.com> on 19.10.2015.
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 19.10.15.
*/ */
public interface IEmailNotificationDAO extends IGenericDAO<EmailNotification, Long> { public interface IEmailNotificationDAO extends IGenericDAO<EmailNotification, Long> {
List<EmailNotification> getAll(); List<EmailNotification> getAll();
List<EmailNotification> getAllByType(EmailTemplateEnum enumeration); List<EmailNotification> getAllByType(EmailTemplateEnum enumeration);
boolean deleteAll(); boolean deleteAll();
boolean deleteAllByType(EmailTemplateEnum enumeration); boolean deleteAllByType(EmailTemplateEnum enumeration);
boolean deleteById(EmailNotification notification); 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.common.daos.IGenericDAO;
import org.libreplan.business.email.entities.EmailTemplate; 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; import java.util.List;
@ -28,17 +30,15 @@ import java.util.List;
* DAO interface for the <code>EmailTemplate</code> entity. * DAO interface for the <code>EmailTemplate</code> entity.
* Contract for {@link EmailTemplateDAO} * Contract for {@link EmailTemplateDAO}
* *
* Created by * @author Created by Vova Perebykivskiy <vova@libreplan-enterprise.com> on 29.09.2015.
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 29.09.2015.
*/ */
public interface IEmailTemplateDAO extends IGenericDAO<EmailTemplate, Long>{ public interface IEmailTemplateDAO extends IGenericDAO<EmailTemplate, Long>{
List<EmailTemplate> getAll(); List<EmailTemplate> getAll();
String getContentBySelectedLanguage(int languageOrdinal, int emailTemplateTypeOrdinal); List<EmailTemplate> findByType(EmailTemplateEnum emailTemplateEnum);
String getContentBySelectedTemplate(int emailTemplateTypeOrdinal, int languageOrdinal);
String getSubjectBySelectedLanguage(int languageOrdinal, int emailTemplateTypeOrdinal); EmailTemplate findByTypeAndLanguage(EmailTemplateEnum emailTemplateEnum, Language language);
String getSubjectBySelectedTemplate(int emailTemplateTypeOrdinal, int languageOrdinal);
void delete(EmailTemplate entity);
} }

View file

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

View file

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

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

View file

@ -32,11 +32,6 @@
</createIndex> </createIndex>
<sql> <sql>
INSERT INTO email_template VALUES(1, 0, 3, 'Task assigned to resource : Autogenerated content text', 'Autogenerated subject text'); 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> </sql>
</changeSet> </changeSet>

View file

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

View file

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

View file

@ -79,9 +79,9 @@
<many-to-many class="SchedulingDataForVersion" column="scheduling_state_for_version_id" /> <many-to-many class="SchedulingDataForVersion" column="scheduling_state_for_version_id" />
</map> </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"> <joined-subclass name="OrderLineGroup" table="order_line_group">
<key column="order_element_id"/> <key column="order_element_id"/>

View file

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

View file

@ -394,9 +394,8 @@
<!-- Java mail --> <!-- Java mail -->
<dependency> <dependency>
<groupId>javax.mail</groupId> <groupId>com.sun.mail</groupId>
<artifactId>mail</artifactId> <artifactId>javax.mail</artifactId>
<version>1.5.0-b01</version>
</dependency> </dependency>
<!-- JAX-RS API --> <!-- 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 * Sends E-mail to users with data that storing in notification_queue table
* and that are treat to incoming EmailNotification * and that are treat to incoming EmailNotification
* *
* Created by * @author Created by Vova Perebykivskiy <vova@libreplan-enterprise.com> on 20.01.2016.
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 20.01.2016.
*/ */
@Component @Component
@ -76,7 +74,8 @@ public class ComposeMessage {
UserRole currentUserRole = getCurrentUserRole(notification.getType()); UserRole currentUserRole = getCurrentUserRole(notification.getType());
if ( currentWorker.getUser().isInRole(currentUserRole) ){ if ( currentWorker.getUser().isInRole(currentUserRole) ) {
if ( currentWorker.getUser().getApplicationLanguage().equals(Language.BROWSER_LANGUAGE) ) { if ( currentWorker.getUser().getApplicationLanguage().equals(Language.BROWSER_LANGUAGE) ) {
locale = new Locale(System.getProperty("user.language")); locale = new Locale(System.getProperty("user.language"));
} else { } else {
@ -96,16 +95,15 @@ public class ComposeMessage {
final String username = usrnme; final String username = usrnme;
final String password = psswrd; final String password = psswrd;
// It is very important to use Session.getInstance instead of Session.getDefaultInstance // It is very important to use Session.getInstance() instead of Session.getDefaultInstance()
Session mailSession = Session.getInstance(properties, Session mailSession = Session.getInstance(properties, new javax.mail.Authenticator() {
new javax.mail.Authenticator() { protected PasswordAuthentication getPasswordAuthentication() {
protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(username, password);
return new PasswordAuthentication(username, password); }
} });
});
// Send message // Send message
try{ try {
MimeMessage message = new MimeMessage(mailSession); MimeMessage message = new MimeMessage(mailSession);
message.setFrom(new InternetAddress(sender)); message.setFrom(new InternetAddress(sender));
@ -122,37 +120,42 @@ public class ComposeMessage {
} catch (MessagingException e) { } catch (MessagingException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} catch (NullPointerException e){ } catch (NullPointerException e) {
if (receiver == null) try { if (receiver == null)
Messagebox.show(_(currentWorker.getUser().getLoginName() + " - this user have not filled E-mail"), _("Error"), try {
Messagebox.OK, Messagebox.ERROR); Messagebox.show(
} catch (InterruptedException e1) { _(currentWorker.getUser().getLoginName() + " - this user have not filled E-mail"),
e1.printStackTrace(); _("Error"), Messagebox.OK, Messagebox.ERROR);
} } catch (InterruptedException e1) {
e1.printStackTrace();
}
} }
} }
return false; return false;
} }
private Worker getCurrentWorker(Long resourceID){ private Worker getCurrentWorker(Long resourceID) {
List<Worker> workerList = workerModel.getWorkers(); List<Worker> workerList = workerModel.getWorkers();
for(int i = 0; i < workerList.size(); i++) for (Worker current : workerList)
if ( workerList.get(i).getId().equals(resourceID) ) if ( current.getId().equals(resourceID) )
return workerList.get(i); return current;
return null; return null;
} }
private EmailTemplate findCurrentEmailTemplate(EmailTemplateEnum templateEnum, Locale locale){ private EmailTemplate findCurrentEmailTemplate(EmailTemplateEnum templateEnum, Locale locale) {
List<EmailTemplate> emailTemplates; List<EmailTemplate> emailTemplates;
emailTemplates = emailTemplateModel.getAll(); emailTemplates = emailTemplateModel.getAll();
for (EmailTemplate item : emailTemplates) for (EmailTemplate item : emailTemplates)
if ( item.getType().equals(templateEnum) && item.getLanguage().getLocale().equals(locale) ) if ( item.getType().equals(templateEnum) && item.getLanguage().getLocale().equals(locale) )
return item; return item;
return null; return null;
} }
private String replaceKeywords(String text, Worker currentWorker, EmailNotification notification){ private String replaceKeywords(String text, Worker currentWorker, EmailNotification notification) {
if ( notification.getType().equals(EmailTemplateEnum.TEMPLATE_ENTER_DATA_IN_TIMESHEET) ){ if ( notification.getType().equals(EmailTemplateEnum.TEMPLATE_ENTER_DATA_IN_TIMESHEET) ) {
// It is because there is no other data for // It is because there is no other data for
// EmailNotification of TEMPLATE_ENTER_DATA_IN_TIMESHEET notification type // EmailNotification of TEMPLATE_ENTER_DATA_IN_TIMESHEET notification type
text = text.replaceAll("\\{resource\\}", notification.getResource().getName()); text = text.replaceAll("\\{resource\\}", notification.getResource().getName());
@ -172,38 +175,41 @@ public class ComposeMessage {
private void setupConnectionProperties(){ private void setupConnectionProperties(){
List<ConnectorProperty> emailConnectorProperties = emailConnectionValidator.getEmailConnectorProperties(); List<ConnectorProperty> emailConnectorProperties = emailConnectionValidator.getEmailConnectorProperties();
for (int i = 0; i < emailConnectorProperties.size(); i++){ for (int i = 0; i < emailConnectorProperties.size(); i++) {
switch (i){ switch (i) {
case 1: { case 1:
protocol = emailConnectorProperties.get(1).getValue(); protocol = emailConnectorProperties.get(1).getValue();
break; break;
}
case 2: { case 2:
host = emailConnectorProperties.get(2).getValue(); host = emailConnectorProperties.get(2).getValue();
break; break;
}
case 3: { case 3:
port = emailConnectorProperties.get(3).getValue(); port = emailConnectorProperties.get(3).getValue();
break; break;
}
case 4: { case 4:
sender = emailConnectorProperties.get(4).getValue(); sender = emailConnectorProperties.get(4).getValue();
break; break;
}
case 5: { case 5:
usrnme = emailConnectorProperties.get(5).getValue(); usrnme = emailConnectorProperties.get(5).getValue();
break; break;
}
case 6: { case 6:
psswrd = emailConnectorProperties.get(6).getValue(); psswrd = emailConnectorProperties.get(6).getValue();
break; break;
}
default:
/* Nothing */
break;
} }
} }
properties = new Properties(); properties = new Properties();
if ( protocol.equals("STARTTLS") ) { if ( "STARTTLS".equals(protocol) ) {
properties.put("mail.smtp.starttls.enable", "true"); properties.put("mail.smtp.starttls.enable", "true");
properties.put("mail.smtp.host", host); properties.put("mail.smtp.host", host);
properties.put("mail.smtp.socketFactory.port", port); properties.put("mail.smtp.socketFactory.port", port);
@ -211,27 +217,36 @@ public class ComposeMessage {
properties.put("mail.smtp.auth", "true"); properties.put("mail.smtp.auth", "true");
properties.put("mail.smtp.port", port); 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.host", host);
properties.put("mail.smtp.port", port); properties.put("mail.smtp.port", port);
} }
} }
private UserRole getCurrentUserRole(EmailTemplateEnum type){ private UserRole getCurrentUserRole(EmailTemplateEnum type) {
switch (type){ switch (type) {
case TEMPLATE_TASK_ASSIGNED_TO_RESOURCE: return UserRole.ROLE_EMAIL_TASK_ASSIGNED_TO_RESOURCE; 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 org.springframework.stereotype.Component;
import javax.mail.MessagingException; import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.Session; import javax.mail.Session;
import javax.mail.Transport; import javax.mail.Transport;
import java.util.List; import java.util.List;
@ -37,9 +36,7 @@ import java.util.Properties;
/** /**
* Validate Email Connection properties * Validate Email Connection properties
* *
* Created by * @author Created by Vova Perebykivskyi <vova@libreplan-enterprise.com> on 20.01.2016.
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 20.01.2016.
*/ */
@Component @Component
@ -49,7 +46,10 @@ public class EmailConnectionValidator {
@Autowired @Autowired
private IConnectorDAO connectorDAO; private IConnectorDAO connectorDAO;
public boolean validConnection(){ /* Needed for EmailTest */
public static Exception exceptionType;
public boolean validConnection() {
List<ConnectorProperty> emailConnectorProperties = getEmailConnectorProperties(); List<ConnectorProperty> emailConnectorProperties = getEmailConnectorProperties();
String protocol = null; String protocol = null;
@ -58,28 +58,31 @@ public class EmailConnectionValidator {
String usrnme = null; String usrnme = null;
String psswrd = null; String psswrd = null;
for (int i = 0; i < emailConnectorProperties.size(); i++){ for (int i = 0; i < emailConnectorProperties.size(); i++) {
switch (i){ switch ( i ) {
case 1: { case 1:
protocol = emailConnectorProperties.get(1).getValue(); protocol = emailConnectorProperties.get(1).getValue();
break; break;
}
case 2: { case 2:
host = emailConnectorProperties.get(2).getValue(); host = emailConnectorProperties.get(2).getValue();
break; break;
}
case 3: { case 3:
port = emailConnectorProperties.get(3).getValue(); port = emailConnectorProperties.get(3).getValue();
break; break;
}
case 5: { case 5:
usrnme = emailConnectorProperties.get(5).getValue(); usrnme = emailConnectorProperties.get(5).getValue();
break; break;
}
case 6: { case 6:
psswrd = emailConnectorProperties.get(6).getValue(); psswrd = emailConnectorProperties.get(6).getValue();
break; break;
}
default:
/* Nothing */
break;
} }
} }
@ -89,48 +92,53 @@ public class EmailConnectionValidator {
Transport transport = null; Transport transport = null;
try { try {
if (protocol.equals("SMTP")) { if ( protocol.equals("SMTP") ) {
properties.setProperty("mail.smtp.port", port); properties.setProperty("mail.smtp.port", port);
properties.setProperty("mail.smtp.host", host); properties.setProperty("mail.smtp.host", host);
properties.setProperty("mail.smtp.connectiontimeout", Integer.toString(3000));
Session session = Session.getInstance(properties, null); Session session = Session.getInstance(properties, null);
transport = session.getTransport("smtp"); transport = session.getTransport("smtp");
if (usrnme.equals("") && psswrd.equals("")) transport.connect(); if ( "".equals(usrnme) && "".equals(psswrd) )
} else if (protocol.equals("STARTTLS")) { transport.connect();
} else if ( protocol.equals("STARTTLS") ) {
properties.setProperty("mail.smtps.port", port); properties.setProperty("mail.smtps.port", port);
properties.setProperty("mail.smtps.host", host); properties.setProperty("mail.smtps.host", host);
properties.setProperty("mail.smtp.connectiontimeout", Integer.toString(3000));
Session session = Session.getInstance(properties, null); Session session = Session.getInstance(properties, null);
transport = session.getTransport("smtps"); transport = session.getTransport("smtps");
if (!usrnme.equals("") && psswrd != null) transport.connect(host, usrnme, psswrd);
}
if (transport != null && transport.isConnected()) return true;
} catch (NoSuchProviderException e) { if ( !"".equals(usrnme) && psswrd != null )
e.printStackTrace(); transport.connect(host, usrnme, psswrd);
} }
catch (MessagingException e) { if ( transport != null && transport.isConnected() )
return true;
} catch (MessagingException e) {
e.printStackTrace(); e.printStackTrace();
// FIXME must be a better way to send exception type to test class
exceptionType = e;
} }
return false; return false;
} }
public List<ConnectorProperty> getEmailConnectorProperties() { public List<ConnectorProperty> getEmailConnectorProperties() {
Connector connector = connectorDAO.findUniqueByName("E-mail"); Connector connector = connectorDAO.findUniqueByName("E-mail");
return connector.getProperties(); return connector.getProperties();
} }
public boolean isConnectionActivated(){ public boolean isConnectionActivated() {
List<ConnectorProperty> emailConnectorProperties = getEmailConnectorProperties(); List<ConnectorProperty> emailConnectorProperties = getEmailConnectorProperties();
for (ConnectorProperty item : emailConnectorProperties){ for (ConnectorProperty item : emailConnectorProperties) {
if ( item.getKey().equals("Activated") ) if ( item.getKey().equals("Activated") )
if ( item.getValue().equals("Y") ) if ( item.getValue().equals("Y") )
return true; return true;
else break; else break;
} }
return false; return false;
} }

View file

@ -22,15 +22,15 @@ package org.libreplan.importers.notifications;
import org.libreplan.business.email.entities.EmailNotification; 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 Created by Vova Perebykivskyi <vova@libreplan-enterprise.com> on 13.10.2015.
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 13.10.2015.
*/ */
public interface IEmailNotificationJob { public interface IEmailNotificationJob {
void sendEmail(); void sendEmail();
boolean composeMessageForUser(EmailNotification notification); 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 * 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} * and that are treat to
* * {@link org.libreplan.business.email.entities.EmailTemplateEnum#TEMPLATE_RESOURCE_REMOVED_FROM_TASK}
* 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.
*/ */
public class SendEmailOnResourceRemovedFromTaskJob extends QuartzJobBean { public class SendEmailOnResourceRemovedFromTaskJob extends QuartzJobBean {
@Override @Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException { protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
ApplicationContext applicationContext = (ApplicationContext) context.getJobDetail(). ApplicationContext applicationContext =
getJobDataMap().get("applicationContext"); (ApplicationContext) context.getJobDetail().getJobDataMap().get("applicationContext");
IEmailNotificationJob resourceRemovedFromTask = (IEmailNotificationJob) applicationContext IEmailNotificationJob resourceRemovedFromTask =
.getBean("SendEmailOnResourceRemovedFromTask"); (IEmailNotificationJob) applicationContext.getBean("SendEmailOnResourceRemovedFromTask");
resourceRemovedFromTask.sendEmail(); 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 * 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} * and that are treat to
* * {@link org.libreplan.business.email.entities.EmailTemplateEnum#TEMPLATE_TASK_ASSIGNED_TO_RESOURCE}
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 13.10.2015.
* *
* @author Created by Vova Perebykivskiy <vova@libreplan-enterprise.com> on 13.10.2015.
*/ */
public class SendEmailOnTaskAssignedToResourceJob extends QuartzJobBean { public class SendEmailOnTaskAssignedToResourceJob extends QuartzJobBean {
@Override @Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException { protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
ApplicationContext applicationContext = (ApplicationContext) context.getJobDetail(). ApplicationContext applicationContext =
getJobDataMap().get("applicationContext"); (ApplicationContext) context.getJobDetail().getJobDataMap().get("applicationContext");
IEmailNotificationJob taskAssignedToResource = (IEmailNotificationJob) applicationContext IEmailNotificationJob taskAssignedToResource =
.getBean("SendEmailOnTaskAssignedToResource"); (IEmailNotificationJob) applicationContext.getBean("SendEmailOnTaskAssignedToResource");
taskAssignedToResource.sendEmail(); 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 * 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 org.libreplan.business.email.entities.EmailTemplateEnum#TEMPLATE_TODAY_TASK_SHOULD_FINISH}
* 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.
*/ */
public class SendEmailOnTaskShouldFinishJob extends QuartzJobBean { public class SendEmailOnTaskShouldFinishJob extends QuartzJobBean {
@Override @Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException { protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
ApplicationContext applicationContext = (ApplicationContext) context.getJobDetail().
getJobDataMap().get("applicationContext");
IEmailNotificationJob taskShouldFinish = (IEmailNotificationJob) applicationContext ApplicationContext applicationContext =
.getBean("SendEmailOnTaskShouldFinish"); (ApplicationContext) context.getJobDetail().getJobDataMap().get("applicationContext");
IEmailNotificationJob taskShouldFinish =
(IEmailNotificationJob) applicationContext.getBean("SendEmailOnTaskShouldFinish");
taskShouldFinish.sendEmail(); 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 * 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 { public class SendEmailOnTaskShouldStartJob extends QuartzJobBean {
@Override @Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException { protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
ApplicationContext applicationContext = (ApplicationContext) context.getJobDetail().
getJobDataMap().get("applicationContext");
IEmailNotificationJob taskShouldStart = (IEmailNotificationJob) applicationContext ApplicationContext applicationContext = (ApplicationContext)
.getBean("SendEmailOnTaskShouldStart"); context.getJobDetail().getJobDataMap().get("applicationContext");
IEmailNotificationJob taskShouldStart =
(IEmailNotificationJob) applicationContext.getBean("SendEmailOnTaskShouldStart");
taskShouldStart.sendEmail(); 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 * 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 org.libreplan.business.email.entities.EmailTemplateEnum#TEMPLATE_ENTER_DATA_IN_TIMESHEET}
* 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.
*/ */
public class SendEmailOnTimesheetDataMissingJob extends QuartzJobBean { public class SendEmailOnTimesheetDataMissingJob extends QuartzJobBean {
@Override @Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException { protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
ApplicationContext applicationContext = (ApplicationContext) context.getJobDetail(). ApplicationContext applicationContext =
getJobDataMap().get("applicationContext"); (ApplicationContext) context.getJobDetail().getJobDataMap().get("applicationContext");
IEmailNotificationJob timesheetMissing = (IEmailNotificationJob) applicationContext IEmailNotificationJob timesheetMissing =
.getBean("SendEmailOnTimesheetDataMissing"); (IEmailNotificationJob) applicationContext.getBean("SendEmailOnTimesheetDataMissing");
timesheetMissing.sendEmail(); timesheetMissing.sendEmail();
} }

View file

@ -39,7 +39,6 @@ import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.Date; import java.util.Date;
import java.util.List; 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} * 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) * But it will be only send to Manager (you can assign him in project properties)
* *
* Created by * @author Created by Vova Perebykivskyi <vova@libreplan-enterprise.com> on 20.01.2016
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 20.01.2016.
*/ */
@Component @Component
@ -80,18 +77,16 @@ public class SendEmailOnMilestoneReached implements IEmailNotificationJob {
// Gathering data // Gathering data
checkMilestoneDate(); 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 for (EmailNotification notification : notifications)
.getAllByType(EmailTemplateEnum.TEMPLATE_MILESTONE_REACHED); if ( composeMessageForUser(notification) )
deleteSingleNotification(notification);
for (int i = 0; i < notifications.size(); i++)
if ( composeMessageForUser(notifications.get(i)) )
deleteSingleNotification(notifications.get(i));
} }
} }
} }
@ -144,9 +139,7 @@ public class SendEmailOnMilestoneReached implements IEmailNotificationJob {
int deadlineMonth = deadline.getMonthOfYear(); int deadlineMonth = deadline.getMonthOfYear();
int deadlineDay = deadline.getDayOfMonth(); int deadlineDay = deadline.getDayOfMonth();
if (currentYear == deadlineYear && if ( currentYear == deadlineYear && currentMonth == deadlineMonth && currentDay == deadlineDay )
currentMonth == deadlineMonth &&
currentDay == deadlineDay)
sendEmailNotificationToManager(item); 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 * 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) * Data will be send if resource has been removed from task (in resource allocation)
* *
* Created by * @author Created by Vova Perebykivskiy <vova@libreplan-enterprise.com> on 20.01.2016.
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 20.01.2016.
*/ */
@Component @Component
@ -61,14 +59,11 @@ public class SendEmailOnResourceRemovedFromTask implements IEmailNotificationJob
public void sendEmail() { public void sendEmail() {
// At this time all data have gathered, if it exists of course // 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() ) List<EmailNotification> notifications =
emailNotificationModel.getAllByType(EmailTemplateEnum.TEMPLATE_RESOURCE_REMOVED_FROM_TASK);
if ( emailConnectionValidator.validConnection() ){
List<EmailNotification> notifications = emailNotificationModel
.getAllByType(EmailTemplateEnum.TEMPLATE_RESOURCE_REMOVED_FROM_TASK);
for (int i = 0; i < notifications.size(); i++) for (int i = 0; i < notifications.size(); i++)
if ( composeMessageForUser(notifications.get(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 * 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. * Data will be send after user will be assigned to some task.
* *
* Created by * @author Created by Vova Perebykivskyi <vova@libreplan-enterprise.com> on 13.10.2015.
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 13.10.2015.
*/ */
@Component @Component
@Scope(BeanDefinition.SCOPE_PROTOTYPE) @Scope(BeanDefinition.SCOPE_PROTOTYPE)
@ -61,18 +59,16 @@ public class SendEmailOnTaskAssignedToResource implements IEmailNotificationJob
@Override @Override
@Transactional @Transactional
public void sendEmail() { 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 for (EmailNotification notification : notifications)
.getAllByType(EmailTemplateEnum.TEMPLATE_TASK_ASSIGNED_TO_RESOURCE); if ( composeMessageForUser(notification) )
deleteSingleNotification(notification);
for (int i = 0; i < notifications.size(); i++)
if ( composeMessageForUser(notifications.get(i)) )
deleteSingleNotification(notifications.get(i));
} }
} }
} }

View file

@ -44,12 +44,10 @@ import java.util.List;
/** /**
* Sends E-mail to users with data that storing in notification_queue table * Sends E-mail to users with data that storing in notification_queue table
* and that are treat to {@link EmailTemplateEnum.TEMPLATE_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. * Data will be send when current day equals to finish date.
* *
* Created by * @author Created by Vova Perebykivskiy <vova@libreplan-enterprise.com> on 21.01.2016.
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 21.01.2016.
*/ */
@Component @Component
@ -73,14 +71,11 @@ public class SendEmailOnTaskShouldFinish implements IEmailNotificationJob {
// Gather data for email sending // Gather data for email sending
taskShouldFinish(); taskShouldFinish();
if ( Configuration.isEmailSendingEnabled() ){ if ( Configuration.isEmailSendingEnabled() ) {
if ( emailConnectionValidator.isConnectionActivated() && emailConnectionValidator.validConnection() ) {
if ( emailConnectionValidator.isConnectionActivated() ) List<EmailNotification> notifications =
emailNotificationModel.getAllByType(EmailTemplateEnum.TEMPLATE_TODAY_TASK_SHOULD_FINISH);
if ( emailConnectionValidator.validConnection() ){
List<EmailNotification> notifications = emailNotificationModel
.getAllByType(EmailTemplateEnum.TEMPLATE_TODAY_TASK_SHOULD_FINISH);
for (int i = 0; i < notifications.size(); i++) for (int i = 0; i < notifications.size(); i++)
if ( composeMessageForUser(notifications.get(i)) ) if ( composeMessageForUser(notifications.get(i)) )
@ -100,6 +95,7 @@ public class SendEmailOnTaskShouldFinish implements IEmailNotificationJob {
@Transactional @Transactional
public void taskShouldFinish() { public void taskShouldFinish() {
// TODO resolve deprecated
// Check if current date equals with item date // Check if current date equals with item date
Date date = new Date(); Date date = new Date();
int currentYear = date.getYear(); int currentYear = date.getYear();
@ -115,7 +111,7 @@ public class SendEmailOnTaskShouldFinish implements IEmailNotificationJob {
if ( currentYear == endYear && if ( currentYear == endYear &&
currentMonth == endMonth && currentMonth == endMonth &&
currentDay == endDay ){ currentDay == endDay ) {
// Get all resources for current task and send them email notification // Get all resources for current task and send them email notification
sendEmailNotificationAboutTaskShouldFinish(item); sendEmailNotificationAboutTaskShouldFinish(item);
} }
@ -124,10 +120,10 @@ public class SendEmailOnTaskShouldFinish implements IEmailNotificationJob {
private void sendEmailNotificationAboutTaskShouldFinish(TaskElement item){ private void sendEmailNotificationAboutTaskShouldFinish(TaskElement item){
List<ResourceAllocation<?>> list = new ArrayList<ResourceAllocation<?>>(); List<ResourceAllocation<?>> list = new ArrayList<>();
list.addAll(item.getAllResourceAllocations()); list.addAll(item.getAllResourceAllocations());
List<Resource> resources = new ArrayList<Resource>(); List<Resource> resources = new ArrayList<>();
for (ResourceAllocation<?> allocation : list) for (ResourceAllocation<?> allocation : list)
resources.add(allocation.getAssociatedResources().get(0)); 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 * 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. * Data will be send if current data equals to start date.
* *
* Created by * @author Created by Vova Perebykivskyi <vova@libreplan-enterprise.com> on 20.01.2016.
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 20.01.2016.
*/ */
@Component @Component
@ -73,18 +71,16 @@ public class SendEmailOnTaskShouldStart implements IEmailNotificationJob {
// Gather data // Gather data
taskShouldStart(); 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 for (EmailNotification notification : notifications)
.getAllByType(EmailTemplateEnum.TEMPLATE_TODAY_TASK_SHOULD_START); if ( composeMessageForUser(notification) )
deleteSingleNotification(notification);
for (int i = 0; i < notifications.size(); i++)
if ( composeMessageForUser(notifications.get(i)) )
deleteSingleNotification(notifications.get(i));
} }
} }
} }
@ -102,35 +98,34 @@ public class SendEmailOnTaskShouldStart implements IEmailNotificationJob {
public void taskShouldStart() { public void taskShouldStart() {
// Check if current date equals with item date // Check if current date equals with item date
Date date = new Date(); Date date = new Date();
// TODO resolve deprecated
int currentYear = date.getYear(); int currentYear = date.getYear();
int currentMonth = date.getMonth(); int currentMonth = date.getMonth();
int currentDay = date.getDay(); int currentDay = date.getDay();
List<TaskElement> tasks = taskElementDAO.getTaskElementsWithParentsWithoutMilestones(); List<TaskElement> tasks = taskElementDAO.getTaskElementsWithParentsWithoutMilestones();
for (TaskElement item : tasks){ for (TaskElement item : tasks) {
Date startDate = item.getStartDate(); Date startDate = item.getStartDate();
int startYear = startDate.getYear(); int startYear = startDate.getYear();
int startMonth = startDate.getMonth(); int startMonth = startDate.getMonth();
int startDay = startDate.getDay(); int startDay = startDate.getDay();
if ( currentYear == startYear && if ( currentYear == startYear && currentMonth == startMonth && currentDay == startDay ) {
currentMonth == startMonth &&
currentDay == startDay){
// Get all resources for current task and send them email notification // Get all resources for current task and send them email notification
sendEmailNotificationAboutTaskShouldStart(item); sendEmailNotificationAboutTaskShouldStart(item);
} }
} }
} }
private void sendEmailNotificationAboutTaskShouldStart(TaskElement item){ private void sendEmailNotificationAboutTaskShouldStart(TaskElement item) {
List<ResourceAllocation<?>> list = new ArrayList<ResourceAllocation<?>>(); List<ResourceAllocation<?>> list = new ArrayList<>();
list.addAll(item.getAllResourceAllocations()); list.addAll(item.getAllResourceAllocations());
List<Resource> resources = new ArrayList<Resource>(); List<Resource> resources = new ArrayList<>();
for (ResourceAllocation<?> allocation : list) for (ResourceAllocation<?> allocation : list)
resources.add(allocation.getAssociatedResources().get(0)); resources.add(allocation.getAssociatedResources().get(0));
for (Resource resourceItem : resources){ for (Resource resourceItem : resources) {
emailNotificationModel.setNewObject(); emailNotificationModel.setNewObject();
emailNotificationModel.setType(EmailTemplateEnum.TEMPLATE_TODAY_TASK_SHOULD_START); emailNotificationModel.setType(EmailTemplateEnum.TEMPLATE_TODAY_TASK_SHOULD_START);
emailNotificationModel.setUpdated(new Date()); 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 * 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. * Data will be send for bound users with empty timesheet lines.
* *
* Created by * @author Created by Vova Perebykivskiy <vova@libreplan-enterprise.com> on 20.01.2016.
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 20.01.2016.
*/ */
@Component @Component
@ -95,14 +93,11 @@ public class SendEmailOnTimesheetDataMissing implements IEmailNotificationJob {
public void sendEmail() { public void sendEmail() {
checkTimesheet(); checkTimesheet();
if ( Configuration.isEmailSendingEnabled() ){ if ( Configuration.isEmailSendingEnabled() ) {
if ( emailConnectionValidator.isConnectionActivated() && emailConnectionValidator.validConnection() ) {
if ( emailConnectionValidator.isConnectionActivated() ) List<EmailNotification> notifications =
emailNotificationModel.getAllByType(EmailTemplateEnum.TEMPLATE_ENTER_DATA_IN_TIMESHEET);
if ( emailConnectionValidator.validConnection() ){
List<EmailNotification> notifications = emailNotificationModel
.getAllByType(EmailTemplateEnum.TEMPLATE_ENTER_DATA_IN_TIMESHEET);
for (int i = 0; i < notifications.size(); i++) for (int i = 0; i < notifications.size(); i++)
if ( composeMessageForUser(notifications.get(i)) ) if ( composeMessageForUser(notifications.get(i)) )
@ -128,8 +123,8 @@ public class SendEmailOnTimesheetDataMissing implements IEmailNotificationJob {
@Transactional @Transactional
private List<User> getPersonalTimesheets() { private List<User> getPersonalTimesheets() {
List<PersonalTimesheetDTO> personalTimesheetDTO = new ArrayList<PersonalTimesheetDTO>(); List<PersonalTimesheetDTO> personalTimesheetDTO = new ArrayList<>();
List<User> usersWithoutTimesheets = new ArrayList<User>(); List<User> usersWithoutTimesheets = new ArrayList<>();
List<User> users = userModel.getUsers(); List<User> users = userModel.getUsers();
for (User user : users) for (User user : users)
@ -139,11 +134,15 @@ public class SendEmailOnTimesheetDataMissing implements IEmailNotificationJob {
LocalDate activationDate = getActivationDate(user.getWorker()); LocalDate activationDate = getActivationDate(user.getWorker());
LocalDate currentDate = new LocalDate(); LocalDate currentDate = new LocalDate();
personalTimesheetDTO.addAll(getPersonalTimesheets(user.getWorker(), activationDate, personalTimesheetDTO.addAll(getPersonalTimesheets(
currentDate.plusMonths(1), getPersonalTimesheetsPeriodicity())); user.getWorker(),
activationDate,
currentDate.plusMonths(1),
getPersonalTimesheetsPeriodicity()));
for(PersonalTimesheetDTO item : personalTimesheetDTO){ for(PersonalTimesheetDTO item : personalTimesheetDTO) {
WorkReport workReport = item.getWorkReport(); WorkReport workReport = item.getWorkReport();
if ( item.getTasksNumber() == 0 && workReport == null ) if ( item.getTasksNumber() == 0 && workReport == null )
if ( !usersWithoutTimesheets.contains(user) ) if ( !usersWithoutTimesheets.contains(user) )
usersWithoutTimesheets.add(user); usersWithoutTimesheets.add(user);
@ -173,10 +172,9 @@ public class SendEmailOnTimesheetDataMissing implements IEmailNotificationJob {
end = periodicity.getEnd(end); end = periodicity.getEnd(end);
int items = periodicity.getItemsBetween(start, 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 // In decreasing order to provide a list sorted with the more recent personal timesheets at the beginning
// personal timesheets at the beginning
for (int i = items; i >= 0; i--) { for (int i = items; i >= 0; i--) {
LocalDate date = periodicity.getDateForItemFromDate(i, start); LocalDate date = periodicity.getDateForItemFromDate(i, start);
@ -189,28 +187,31 @@ public class SendEmailOnTimesheetDataMissing implements IEmailNotificationJob {
tasksNumber = getNumberOfOrderElementsWithTrackedTime(workReport); tasksNumber = getNumberOfOrderElementsWithTrackedTime(workReport);
} }
result.add(new PersonalTimesheetDTO(date, workReport, result.add(new PersonalTimesheetDTO(
getResourceCapcity(resource, date, periodicity), hours, date,
workReport,
getResourceCapcity(resource, date, periodicity),
hours,
tasksNumber)); tasksNumber));
} }
return result; return result;
} }
private LocalDate getActivationDate(Worker worker) { private LocalDate getActivationDate(Worker worker) {
return worker.getCalendar().getFistCalendarAvailability() return worker.getCalendar().getFistCalendarAvailability().getStartDate();
.getStartDate();
} }
private PersonalTimesheetsPeriodicityEnum getPersonalTimesheetsPeriodicity() { private PersonalTimesheetsPeriodicityEnum getPersonalTimesheetsPeriodicity() {
return configurationDAO.getConfiguration() return configurationDAO.getConfiguration().getPersonalTimesheetsPeriodicity();
.getPersonalTimesheetsPeriodicity();
} }
private WorkReport getWorkReport(Resource resource, LocalDate date, private WorkReport getWorkReport(Resource resource, LocalDate date,
PersonalTimesheetsPeriodicityEnum periodicity) { PersonalTimesheetsPeriodicityEnum periodicity) {
WorkReport workReport = workReportDAO.getPersonalTimesheetWorkReport( WorkReport workReport = workReportDAO.getPersonalTimesheetWorkReport(
resource, date, periodicity); resource, date, periodicity);
forceLoad(workReport); forceLoad(workReport);
return workReport; return workReport;
} }
private void forceLoad(WorkReport workReport) { private void forceLoad(WorkReport workReport) {
@ -226,7 +227,7 @@ public class SendEmailOnTimesheetDataMissing implements IEmailNotificationJob {
return 0; return 0;
} }
List<OrderElement> orderElements = new ArrayList<OrderElement>(); List<OrderElement> orderElements = new ArrayList<>();
for (WorkReportLine line : workReport.getWorkReportLines()) { for (WorkReportLine line : workReport.getWorkReportLines()) {
if (!line.getEffort().isZero()) { if (!line.getEffort().isZero()) {
OrderElement orderElement = line.getOrderElement(); OrderElement orderElement = line.getOrderElement();
@ -239,14 +240,13 @@ public class SendEmailOnTimesheetDataMissing implements IEmailNotificationJob {
} }
private EffortDuration getResourceCapcity(Resource resource, LocalDate date, private EffortDuration getResourceCapcity(Resource resource, LocalDate date,
PersonalTimesheetsPeriodicityEnum periodicity) { PersonalTimesheetsPeriodicityEnum periodicity) {
LocalDate start = periodicity.getStart(date); LocalDate start = periodicity.getStart(date);
LocalDate end = periodicity.getEnd(date); LocalDate end = periodicity.getEnd(date);
EffortDuration capacity = EffortDuration.zero(); EffortDuration capacity = EffortDuration.zero();
for (LocalDate day = start; day.compareTo(end) <= 0; day = day for (LocalDate day = start; day.compareTo(end) <= 0; day = day.plusDays(1)) {
.plusDays(1)) { capacity = capacity.plus(resource.getCalendar().getCapacityOn(IntraDayDate.PartialDay.wholeDay(day)));
capacity = capacity.plus(resource.getCalendar().getCapacityOn(
IntraDayDate.PartialDay.wholeDay(day)));
} }
return capacity; return capacity;
} }

View file

@ -37,15 +37,14 @@ import org.libreplan.importers.SynchronizationInfo;
public interface IJobSchedulerModel { public interface IJobSchedulerModel {
/** /**
* returns all job scheduler configurations * Returns all job scheduler configurations.
* *
* @return list of <code>JobSchedulerConfiguration</code> * @return list of <code>JobSchedulerConfiguration</code>
*/ */
List<JobSchedulerConfiguration> getJobSchedulerConfigurations(); List<JobSchedulerConfiguration> getJobSchedulerConfigurations();
/** /**
* returns next fire time for the specified job from * Returns next fire time for the specified job from <code>{@link JobSchedulerConfiguration}</code>.
* <code>{@link JobSchedulerConfiguration}</code>
* *
* @param jobSchedulerConfiguration * @param jobSchedulerConfiguration
* the job scheduler configuration * the job scheduler configuration
@ -53,18 +52,17 @@ public interface IJobSchedulerModel {
String getNextFireTime(JobSchedulerConfiguration jobSchedulerConfiguration); String getNextFireTime(JobSchedulerConfiguration jobSchedulerConfiguration);
/** /**
* Do manual action(replacement of scheduling) * Do manual action(replacement of scheduling).
* *
* @param jobSchedulerConfiguration * @param jobSchedulerConfiguration
* the job configuration * the job configuration
* @throws ConnectorException * @throws ConnectorException
* if connector is not valid * if connector is not valid
*/ */
void doManual(JobSchedulerConfiguration jobSchedulerConfiguration) void doManual(JobSchedulerConfiguration jobSchedulerConfiguration) throws ConnectorException;
throws ConnectorException;
/** /**
* Returns synchronization infos. Failures or successes info * Returns synchronization infos. Failures or successes info.
*/ */
List<SynchronizationInfo> getSynchronizationInfos(); List<SynchronizationInfo> getSynchronizationInfos();
@ -74,7 +72,7 @@ public interface IJobSchedulerModel {
void initCreate(); void initCreate();
/** /**
* Prepares for edit {@link JobSchedulerConfiguration} * Prepares for edit {@link JobSchedulerConfiguration}.
* *
* @param jobSchedulerConfiguration * @param jobSchedulerConfiguration
* object to be edited * object to be edited
@ -89,7 +87,7 @@ public interface IJobSchedulerModel {
JobSchedulerConfiguration getJobSchedulerConfiguration(); JobSchedulerConfiguration getJobSchedulerConfiguration();
/** /**
* Saves the current {@link JobSchedulerConfiguration} * Saves the current {@link JobSchedulerConfiguration}.
* *
* @throws ValidationException * @throws ValidationException
* if validation fails * if validation fails
@ -97,12 +95,12 @@ public interface IJobSchedulerModel {
void confirmSave() throws ValidationException; void confirmSave() throws ValidationException;
/** /**
* Cancels the current {@link JobSchedulerConfiguration} * Cancels the current {@link JobSchedulerConfiguration}.
*/ */
void cancel(); void cancel();
/** /**
* Removes the current {@link JobSchedulerConfiguration} * Removes the current {@link JobSchedulerConfiguration}.
* *
* @param jobSchedulerConfiguration * @param jobSchedulerConfiguration
* object to be removed * object to be removed
@ -110,16 +108,15 @@ public interface IJobSchedulerModel {
void remove(JobSchedulerConfiguration jobSchedulerConfiguration); void remove(JobSchedulerConfiguration jobSchedulerConfiguration);
/** /**
* returns list of connectors * Returns list of connectors
*/ */
List<Connector> getConnectors(); 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 * Schedule all jobs of the specified <code>connector</code>'s property
* {@link PredefinedConnectorProperties#ACTIVATED} is 'Y', otherwise * {@link PredefinedConnectorProperties#ACTIVATED} is 'Y', otherwise unschedule the jobs.
* unschedule the jobs
* *
* @param connector * @param connector
* where to check if property is changed * where to check if property is changed
@ -128,22 +125,20 @@ public interface IJobSchedulerModel {
boolean scheduleOrUnscheduleJobs(Connector connector); boolean scheduleOrUnscheduleJobs(Connector connector);
/** /**
* schedule or unschedule job for the specified job in * Schedule or unschedule job for the specified job in <code>{@link JobSchedulerConfiguration}</code>.
* <code>{@link JobSchedulerConfiguration}</code>
* *
* @return true if scheduling is succeeded, false otherwise * @return true if scheduling is succeeded, false otherwise
*/ */
boolean scheduleOrUnscheduleJob(); boolean scheduleOrUnscheduleJob();
/** /**
* Delete job specified in <code>{@link JobSchedulerConfiguration}</code> * Delete job specified in <code>{@link JobSchedulerConfiguration}</code>.
* *
* @param jobSchedulerConfiguration * @param jobSchedulerConfiguration
* configuration for the job to be deleted * configuration for the job to be deleted
* @return true if job is successfully deleted from the scheduler, false * @return true if job is successfully deleted from the scheduler, false
* otherwise * otherwise
*/ */
boolean deleteScheduledJob( boolean deleteScheduledJob(JobSchedulerConfiguration jobSchedulerConfiguration);
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.Executions;
import org.zkoss.zk.ui.SuspendNotAllowedException; import org.zkoss.zk.ui.SuspendNotAllowedException;
import org.zkoss.zk.ui.WrongValueException; 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.EventListener;
import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.event.Events;
import org.zkoss.zul.Button; import org.zkoss.zul.Button;
@ -52,7 +51,6 @@ import org.zkoss.zul.Hbox;
import org.zkoss.zul.Label; import org.zkoss.zul.Label;
import org.zkoss.zul.Listbox; import org.zkoss.zul.Listbox;
import org.zkoss.zul.Popup; import org.zkoss.zul.Popup;
import org.zkoss.zul.Row;
import org.zkoss.zul.RowRenderer; import org.zkoss.zul.RowRenderer;
import org.zkoss.zul.SimpleListModel; import org.zkoss.zul.SimpleListModel;
import org.zkoss.zul.api.Caption; import org.zkoss.zul.api.Caption;
@ -64,27 +62,30 @@ import org.zkoss.zul.api.Window;
* *
* @author Miciele Ghiorghis <m.ghiorghis@antoniusziekenhuis.nl> * @author Miciele Ghiorghis <m.ghiorghis@antoniusziekenhuis.nl>
*/ */
public class JobSchedulerController extends public class JobSchedulerController extends BaseCRUDController<JobSchedulerConfiguration> {
BaseCRUDController<JobSchedulerConfiguration> {
private static final Log LOG = LogFactory private static final Log LOG = LogFactory.getLog(JobSchedulerController.class);
.getLog(JobSchedulerController.class);
private Grid listJobSchedulings;
private Grid cronExpressionGrid;
private Popup cronExpressionInputPopup; private Popup cronExpressionInputPopup;
private Label jobGroup; private Label jobGroup;
private Label jobName; private Label jobName;
private Textbox cronExpressionTextBox; private Textbox cronExpressionTextBox;
private Textbox cronExpressionSeconds; private Textbox cronExpressionSeconds;
private Textbox cronExpressionMinutes; private Textbox cronExpressionMinutes;
private Textbox cronExpressionHours; private Textbox cronExpressionHours;
private Textbox cronExpressionDayOfMonth; private Textbox cronExpressionDayOfMonth;
private Textbox cronExpressionMonth; private Textbox cronExpressionMonth;
private Textbox cronExpressionDayOfWeek; private Textbox cronExpressionDayOfWeek;
private Textbox cronExpressionYear; private Textbox cronExpressionYear;
private IJobSchedulerModel jobSchedulerModel; private IJobSchedulerModel jobSchedulerModel;
@ -92,71 +93,67 @@ public class JobSchedulerController extends
@Override @Override
public void doAfterCompose(Component comp) throws Exception { public void doAfterCompose(Component comp) throws Exception {
super.doAfterCompose(comp); super.doAfterCompose(comp);
listJobSchedulings = (Grid) listWindow Grid listJobSchedulings = (Grid) listWindow.getFellowIfAny("listJobSchedulings");
.getFellowIfAny("listJobSchedulings");
listJobSchedulings.getModel(); listJobSchedulings.getModel();
initCronExpressionPopup(); initCronExpressionPopup();
} }
/** /**
* initializes cron expressions for popup * Initializes cron expressions for popup
*/ */
private void initCronExpressionPopup() { private void initCronExpressionPopup() {
cronExpressionTextBox = (Textbox) editWindow cronExpressionTextBox = (Textbox) editWindow.getFellow("cronExpressionTextBox");
.getFellow("cronExpressionTextBox");
cronExpressionInputPopup = (Popup) editWindow cronExpressionInputPopup = (Popup) editWindow.getFellow("cronExpressionInputPopup");
.getFellow("cronExpressionInputPopup");
jobGroup = (Label) cronExpressionInputPopup.getFellow("jobGroup"); jobGroup = (Label) cronExpressionInputPopup.getFellow("jobGroup");
jobName = (Label) cronExpressionInputPopup.getFellow("jobName"); jobName = (Label) cronExpressionInputPopup.getFellow("jobName");
cronExpressionGrid = (Grid) cronExpressionInputPopup Grid cronExpressionGrid = (Grid) cronExpressionInputPopup.getFellow("cronExpressionGrid");
.getFellow("cronExpressionGrid");
cronExpressionSeconds = (Textbox) cronExpressionGrid cronExpressionSeconds = (Textbox) cronExpressionGrid.getFellow("cronExpressionSeconds");
.getFellow("cronExpressionSeconds");
cronExpressionMinutes = (Textbox) cronExpressionGrid cronExpressionMinutes = (Textbox) cronExpressionGrid.getFellow("cronExpressionMinutes");
.getFellow("cronExpressionMinutes");
cronExpressionHours = (Textbox) cronExpressionGrid cronExpressionHours = (Textbox) cronExpressionGrid.getFellow("cronExpressionHours");
.getFellow("cronExpressionHours");
cronExpressionDayOfMonth = (Textbox) cronExpressionGrid cronExpressionDayOfMonth = (Textbox) cronExpressionGrid.getFellow("cronExpressionDayOfMonth");
.getFellow("cronExpressionDayOfMonth");
cronExpressionMonth = (Textbox) cronExpressionGrid cronExpressionMonth = (Textbox) cronExpressionGrid.getFellow("cronExpressionMonth");
.getFellow("cronExpressionMonth");
cronExpressionDayOfWeek = (Textbox) cronExpressionGrid cronExpressionDayOfWeek = (Textbox) cronExpressionGrid.getFellow("cronExpressionDayOfWeek");
.getFellow("cronExpressionDayOfWeek");
cronExpressionYear = (Textbox) cronExpressionGrid cronExpressionYear = (Textbox) cronExpressionGrid.getFellow("cronExpressionYear");
.getFellow("cronExpressionYear");
} }
/** /**
* returns a list of {@link JobSchedulerConfiguration} * Returns a list of {@link JobSchedulerConfiguration}
*/ */
public List<JobSchedulerConfiguration> getJobSchedulerConfigurations() { public List<JobSchedulerConfiguration> getJobSchedulerConfigurations() {
return jobSchedulerModel.getJobSchedulerConfigurations(); return jobSchedulerModel.getJobSchedulerConfigurations();
} }
/** /**
* returns {@link JobSchedulerConfiguration} * Returns {@link JobSchedulerConfiguration}
*/ */
public JobSchedulerConfiguration getJobSchedulerConfiguration() { public JobSchedulerConfiguration getJobSchedulerConfiguration() {
return jobSchedulerModel.getJobSchedulerConfiguration(); return jobSchedulerModel.getJobSchedulerConfiguration();
} }
/** /**
* returns all predefined jobs * Returns all predefined jobs
*/ */
public JobClassNameEnum[] getJobNames() { public JobClassNameEnum[] getJobNames() {
return JobClassNameEnum.values(); return JobClassNameEnum.values();
} }
/** /**
* return list of connectorNames * Return list of connectorNames
*/ */
public List<String> getConnectorNames() { public List<String> getConnectorNames() {
List<Connector> connectors = jobSchedulerModel.getConnectors(); List<Connector> connectors = jobSchedulerModel.getConnectors();
List<String> connectorNames = new ArrayList<String>(); List<String> connectorNames = new ArrayList<>();
for (Connector connector : connectors) { for (Connector connector : connectors) {
connectorNames.add(connector.getName()); 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() { public RowRenderer getJobSchedulingRenderer() {
return new RowRenderer() { return (row, data) -> {
final JobSchedulerConfiguration jobSchedulerConfiguration = (JobSchedulerConfiguration) data;
row.setValue(data);
@Override Util.appendLabel(row, jobSchedulerConfiguration.getJobGroup());
public void render(Row row, Object data) { Util.appendLabel(row, jobSchedulerConfiguration.getJobName());
final JobSchedulerConfiguration jobSchedulerConfiguration = (JobSchedulerConfiguration) data; Util.appendLabel(row, jobSchedulerConfiguration.getCronExpression());
row.setValue(data); Util.appendLabel(row, getNextFireTime(jobSchedulerConfiguration));
Hbox hbox = new Hbox();
Util.appendLabel(row, jobSchedulerConfiguration.getJobGroup()); hbox.appendChild(createManualButton(event -> {
Util.appendLabel(row, jobSchedulerConfiguration.getJobName()); try {
Util.appendLabel(row, jobSchedulerModel.doManual(jobSchedulerConfiguration);
jobSchedulerConfiguration.getCronExpression()); showSynchronizationInfo();
Util.appendLabel(row, } catch (ConnectorException e) {
getNextFireTime(jobSchedulerConfiguration)); messagesForUser.showMessage(Level.ERROR, e.getMessage());
Hbox hbox = new Hbox(); }
hbox.appendChild(createManualButton(new EventListener() { }));
@Override hbox.appendChild(Util.createEditButton(event -> goToEditForm(jobSchedulerConfiguration)));
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.createRemoveButton(event -> confirmDelete(jobSchedulerConfiguration)));
row.appendChild(hbox);
}; };
} }
public RowRenderer getSynchronizationInfoRenderer() { public RowRenderer getSynchronizationInfoRenderer() {
return new RowRenderer() { return (row, data) -> {
final SynchronizationInfo synchronizationInfo = (SynchronizationInfo) data;
row.setValue(data);
@Override Groupbox groupbox = new Groupbox();
public void render(Row row, Object data) { groupbox.setClosable(true);
final SynchronizationInfo synchronizationInfo = (SynchronizationInfo) data; Caption caption = new org.zkoss.zul.Caption();
row.setValue(data); caption.setLabel(synchronizationInfo.getAction());
groupbox.appendChild(caption);
row.appendChild(groupbox);
Groupbox groupbox = new Groupbox(); if (synchronizationInfo.isSuccessful()) {
groupbox.setClosable(true); groupbox.appendChild(new Label(_("Completed")));
Caption caption = new org.zkoss.zul.Caption(); } else {
caption.setLabel(synchronizationInfo.getAction());
groupbox.appendChild(caption);
row.appendChild(groupbox);
if (synchronizationInfo.isSuccessful()) { Listbox listbox = new Listbox();
groupbox.appendChild(new Label(_("Completed")));
} else {
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() { private void showSynchronizationInfo() {
Map<String, Object> args = new HashMap<String, Object>(); Map<String, Object> args = new HashMap<>();
Window win = (Window) Executions.createComponents( Window win = (Window) Executions.createComponents("/orders/_synchronizationInfo.zul", null, args);
"/orders/_synchronizationInfo.zul", null, args);
Window syncInfoWin = (Window) win.getFellowIfAny("syncInfoWin"); Window syncInfoWin = (Window) win.getFellowIfAny("syncInfoWin");
@ -263,27 +235,23 @@ public class JobSchedulerController extends
try { try {
win.doModal(); win.doModal();
} catch (SuspendNotAllowedException e) { } catch (SuspendNotAllowedException | InterruptedException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
/** /**
* returns the next fire time for the specified job in * Returns the next fire time for the specified job in {@link JobSchedulerConfiguration}
* {@link JobSchedulerConfiguration}
* *
* @param jobSchedulerConfiguration * @param jobSchedulerConfiguration
* the job scheduler configuration * the job scheduler configuration
*/ */
private String getNextFireTime( private String getNextFireTime(JobSchedulerConfiguration jobSchedulerConfiguration) {
JobSchedulerConfiguration jobSchedulerConfiguration) {
return jobSchedulerModel.getNextFireTime(jobSchedulerConfiguration); return jobSchedulerModel.getNextFireTime(jobSchedulerConfiguration);
} }
/** /**
* creates and returns a button * Creates and returns a button
* *
* @param eventListener * @param eventListener
* Event listener for this button * Event listener for this button
@ -292,6 +260,7 @@ public class JobSchedulerController extends
Button button = new Button(_("Manual")); Button button = new Button(_("Manual"));
button.setTooltiptext(_("Manual")); button.setTooltiptext(_("Manual"));
button.addEventListener(Events.ON_CLICK, eventListener); button.addEventListener(Events.ON_CLICK, eventListener);
return button; return button;
} }
@ -309,14 +278,13 @@ public class JobSchedulerController extends
* @param jobSchedulerConfiguration * @param jobSchedulerConfiguration
* where to read the values * where to read the values
*/ */
private void setupCronExpressionPopup( private void setupCronExpressionPopup(final JobSchedulerConfiguration jobSchedulerConfiguration) {
final JobSchedulerConfiguration jobSchedulerConfiguration) {
if (jobSchedulerConfiguration != null) { if (jobSchedulerConfiguration != null) {
jobGroup.setValue(jobSchedulerConfiguration.getJobGroup()); jobGroup.setValue(jobSchedulerConfiguration.getJobGroup());
jobName.setValue(jobSchedulerConfiguration.getJobName()); jobName.setValue(jobSchedulerConfiguration.getJobName());
String cronExpression = jobSchedulerConfiguration String cronExpression = jobSchedulerConfiguration.getCronExpression();
.getCronExpression();
if (cronExpression == null || cronExpression.isEmpty()) { if (cronExpression == null || cronExpression.isEmpty()) {
return; return;
} }
@ -337,8 +305,7 @@ public class JobSchedulerController extends
} }
/** /**
* sets the <code>cronExpressionTextBox</code> value from the * Sets the <code>cronExpressionTextBox</code> value from the <code>cronExpressionInputPopup</code>
* <code>cronExpressionInputPopup</code>
*/ */
public void updateCronExpression() { public void updateCronExpression() {
String cronExpression = getCronExpressionString(); String cronExpression = getCronExpressionString();
@ -347,9 +314,9 @@ public class JobSchedulerController extends
new CronExpression(cronExpression); new CronExpression(cronExpression);
} catch (ParseException e) { } catch (ParseException e) {
LOG.info("Unable to parse cron expression", e); LOG.info("Unable to parse cron expression", e);
throw new WrongValueException(cronExpressionInputPopup,
_("Unable to parse cron expression") + ":\n" throw new WrongValueException(
+ e.getMessage()); cronExpressionInputPopup, _("Unable to parse cron expression") + ":\n" + e.getMessage());
} }
cronExpressionTextBox.setValue(cronExpression); cronExpressionTextBox.setValue(cronExpression);
cronExpressionInputPopup.close(); cronExpressionInputPopup.close();
@ -371,15 +338,12 @@ public class JobSchedulerController extends
cronExpression += StringUtils.trimToEmpty(cronExpressionDayOfWeek.getValue()); cronExpression += StringUtils.trimToEmpty(cronExpressionDayOfWeek.getValue());
String year = StringUtils.trimToEmpty(cronExpressionYear.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() { public void cancelPopup() {
cronExpressionInputPopup.close(); cronExpressionInputPopup.close();
@ -410,8 +374,7 @@ public class JobSchedulerController extends
protected void save() throws ValidationException { protected void save() throws ValidationException {
jobSchedulerModel.confirmSave(); jobSchedulerModel.confirmSave();
if (jobSchedulerModel.scheduleOrUnscheduleJob()) { if (jobSchedulerModel.scheduleOrUnscheduleJob()) {
messagesForUser.showMessage(Level.INFO, messagesForUser.showMessage(Level.INFO, _("Job is scheduled/unscheduled"));
_("Job is scheduled/unscheduled"));
} }
} }
@ -426,12 +389,10 @@ public class JobSchedulerController extends
} }
@Override @Override
protected void delete(JobSchedulerConfiguration entity) protected void delete(JobSchedulerConfiguration entity) throws InstanceNotFoundException {
throws InstanceNotFoundException {
jobSchedulerModel.remove(entity); jobSchedulerModel.remove(entity);
if (jobSchedulerModel.deleteScheduledJob(entity)) { if (jobSchedulerModel.deleteScheduledJob(entity)) {
messagesForUser.showMessage(Level.INFO, messagesForUser.showMessage(Level.INFO, _("Job is deleted from scheduler"));
_("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 Manuel Rego Casasnovas <rego@igalia.com>
* @author Miciele Ghiorghis <m.ghiorghis@antoniusziekenhuis.nl> * @author Miciele Ghiorghis <m.ghiorghis@antoniusziekenhuis.nl>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com> * @author Vova Perebykivskyi <vova@libreplan-enterprise.com>
*/ */
@Service @Service
@Scope(BeanDefinition.SCOPE_PROTOTYPE) @Scope(BeanDefinition.SCOPE_PROTOTYPE)
@ -79,8 +79,6 @@ public class JobSchedulerModel implements IJobSchedulerModel {
@Autowired @Autowired
private IJiraOrderElementSynchronizer jiraOrderElementSynchronizer; private IJiraOrderElementSynchronizer jiraOrderElementSynchronizer;
private List<SynchronizationInfo> synchronizationInfos;
@Qualifier("sendEmailOnTaskAssignedToResource") @Qualifier("sendEmailOnTaskAssignedToResource")
@Autowired @Autowired
private IEmailNotificationJob taskAssignedToResource; private IEmailNotificationJob taskAssignedToResource;
@ -105,6 +103,8 @@ public class JobSchedulerModel implements IJobSchedulerModel {
@Autowired @Autowired
private IEmailNotificationJob timesheetDataMissing; private IEmailNotificationJob timesheetDataMissing;
private List<SynchronizationInfo> synchronizationInfos = new ArrayList<>();
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
@ -113,63 +113,77 @@ public class JobSchedulerModel implements IJobSchedulerModel {
} }
@Override @Override
public String getNextFireTime( public String getNextFireTime(JobSchedulerConfiguration jobSchedulerConfiguration) {
JobSchedulerConfiguration jobSchedulerConfiguration) {
return schedulerManager.getNextFireTime(jobSchedulerConfiguration); return schedulerManager.getNextFireTime(jobSchedulerConfiguration);
} }
@Override @Override
public void doManual(JobSchedulerConfiguration jobSchedulerConfiguration) public void doManual(JobSchedulerConfiguration jobSchedulerConfiguration) throws ConnectorException {
throws ConnectorException {
String name = jobSchedulerConfiguration.getJobClassName().getName(); 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(); synchronizationInfos = importRosterFromTim.importRosters();
return; return;
} }
if (name.equals(JobClassNameEnum.EXPORT_TIMESHEET_TO_TIM_JOB.getName())) {
if ( name.equals(JobClassNameEnum.EXPORT_TIMESHEET_TO_TIM_JOB.getName()) ) {
synchronizationInfos = exportTimesheetsToTim.exportTimesheets(); synchronizationInfos = exportTimesheetsToTim.exportTimesheets();
return; return;
} }
if (name.equals(JobClassNameEnum.SYNC_ORDERELEMENTS_WITH_JIRA_ISSUES_JOB
.getName())) { if ( name.equals(JobClassNameEnum.SYNC_ORDERELEMENTS_WITH_JIRA_ISSUES_JOB.getName()) ) {
synchronizationInfos = jiraOrderElementSynchronizer synchronizationInfos = jiraOrderElementSynchronizer.syncOrderElementsWithJiraIssues();
.syncOrderElementsWithJiraIssues();
return; return;
} }
if ( name.equals(JobClassNameEnum.SEND_EMAIL_TASK_ASSIGNED_TO_RESOURCE.getName()) ) { 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"))); synchronizationInfos.add(new SynchronizationInfo(_("Task assigned to resource emails")));
taskAssignedToResource.sendEmail(); taskAssignedToResource.sendEmail();
return; return;
} }
if ( name.equals(JobClassNameEnum.SEND_EMAIL_RESOURCE_REMOVED_FROM_TASK.getName()) ) { 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"))); synchronizationInfos.add(new SynchronizationInfo(_("Resource removed from task")));
resourceRemovedFromTask.sendEmail(); resourceRemovedFromTask.sendEmail();
return; return;
} }
if ( name.equals(JobClassNameEnum.SEND_EMAIL_MILESTONE_REACHED.getName()) ) { if ( name.equals(JobClassNameEnum.SEND_EMAIL_MILESTONE_REACHED.getName()) ) {
synchronizationInfos = new ArrayList<SynchronizationInfo>(); synchronizationInfos = new ArrayList<>();
synchronizationInfos.add(new SynchronizationInfo(_("Milestone reached"))); synchronizationInfos.add(new SynchronizationInfo(_("Milestone reached")));
milestoneReached.sendEmail(); milestoneReached.sendEmail();
return; return;
} }
if ( name.equals(JobClassNameEnum.SEND_EMAIL_TASK_SHOULD_START.getName()) ) { if ( name.equals(JobClassNameEnum.SEND_EMAIL_TASK_SHOULD_START.getName()) ) {
synchronizationInfos = new ArrayList<SynchronizationInfo>(); synchronizationInfos = new ArrayList<>();
synchronizationInfos.add(new SynchronizationInfo(_("Task should start"))); synchronizationInfos.add(new SynchronizationInfo(_("Task should start")));
taskShouldStart.sendEmail(); taskShouldStart.sendEmail();
return; return;
} }
if ( name.equals(JobClassNameEnum.SEND_EMAIL_TASK_SHOULD_FINISH.getName()) ) { if ( name.equals(JobClassNameEnum.SEND_EMAIL_TASK_SHOULD_FINISH.getName()) ) {
synchronizationInfos = new ArrayList<SynchronizationInfo>(); synchronizationInfos = new ArrayList<>();
synchronizationInfos.add(new SynchronizationInfo(_("Task should finish"))); synchronizationInfos.add(new SynchronizationInfo(_("Task should finish")));
taskShouldFinish.sendEmail(); taskShouldFinish.sendEmail();
return; return;
} }
if ( name.equals(JobClassNameEnum.SEND_EMAIL_TIMESHEET_DATA_MISSING.getName()) ) { if ( name.equals(JobClassNameEnum.SEND_EMAIL_TIMESHEET_DATA_MISSING.getName()) ) {
synchronizationInfos = new ArrayList<SynchronizationInfo>(); synchronizationInfos = new ArrayList<>();
synchronizationInfos.add(new SynchronizationInfo(_("Timesheet data missing"))); synchronizationInfos.add(new SynchronizationInfo(_("Timesheet data missing")));
timesheetDataMissing.sendEmail(); timesheetDataMissing.sendEmail();
return; return;
} }
@ -211,8 +225,7 @@ public class JobSchedulerModel implements IJobSchedulerModel {
@Transactional @Transactional
public void remove(JobSchedulerConfiguration jobSchedulerConfiguration) { public void remove(JobSchedulerConfiguration jobSchedulerConfiguration) {
try { try {
jobSchedulerConfigurationDAO.remove(jobSchedulerConfiguration jobSchedulerConfigurationDAO.remove(jobSchedulerConfiguration.getId());
.getId());
} catch (InstanceNotFoundException e) { } catch (InstanceNotFoundException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@ -226,8 +239,9 @@ public class JobSchedulerModel implements IJobSchedulerModel {
@Override @Override
public boolean scheduleOrUnscheduleJobs(Connector connector) { public boolean scheduleOrUnscheduleJobs(Connector connector) {
List<JobSchedulerConfiguration> jobSchedulerConfigurations = jobSchedulerConfigurationDAO
.findByConnectorName(connector.getName()); List<JobSchedulerConfiguration> jobSchedulerConfigurations =
jobSchedulerConfigurationDAO.findByConnectorName(connector.getName());
for (JobSchedulerConfiguration jobSchedulerConfiguration : jobSchedulerConfigurations) { for (JobSchedulerConfiguration jobSchedulerConfiguration : jobSchedulerConfigurations) {
try { try {
@ -250,8 +264,7 @@ public class JobSchedulerModel implements IJobSchedulerModel {
} }
@Override @Override
public boolean deleteScheduledJob( public boolean deleteScheduledJob(JobSchedulerConfiguration jobSchedulerConfiguration) {
JobSchedulerConfiguration jobSchedulerConfiguration) {
try { try {
schedulerManager.deleteJob(jobSchedulerConfiguration); schedulerManager.deleteJob(jobSchedulerConfiguration);
} catch (SchedulerException e) { } catch (SchedulerException e) {

View file

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

View file

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

View file

@ -36,9 +36,7 @@ import java.util.List;
/** /**
* Model for operations related to {@link EmailTemplate}. * Model for operations related to {@link EmailTemplate}.
* *
* Created by * @author Created by Vova Perebykivskiy <vova@libreplan-enterprise.com> on 25.09.2015.
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 25.09.15.
*/ */
@Service @Service
@Scope(BeanDefinition.SCOPE_PROTOTYPE) @Scope(BeanDefinition.SCOPE_PROTOTYPE)
@ -52,22 +50,31 @@ public class EmailTemplateModel implements IEmailTemplateModel {
@Override @Override
@Transactional @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(); List<EmailTemplate> emailTemplates = emailTemplateDAO.getAll();
EmailTemplate emailTemplateFromDatabase = null; EmailTemplate emailTemplateFromDatabase = null;
boolean condition;
for (int i = 0; i < emailTemplates.size(); i++) { for (EmailTemplate emailTemplate1 : emailTemplates) {
if ( emailTemplate.getLanguage() == emailTemplates.get(i).getLanguage() &&
emailTemplate.getType() == emailTemplates.get(i).getType() ) { condition = emailTemplate.getLanguage() == emailTemplate1.getLanguage() &&
emailTemplateFromDatabase = emailTemplateDAO.find(emailTemplates.get(i).getId()); 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 temporaryEntity = emailTemplate;
emailTemplate = emailTemplateFromDatabase; emailTemplate = emailTemplateFromDatabase;
@ -89,13 +96,11 @@ public class EmailTemplateModel implements IEmailTemplateModel {
} }
@Override @Override
@Transactional
public List<EmailTemplate> getAll() { public List<EmailTemplate> getAll() {
return emailTemplateDAO.getAll(); return emailTemplateDAO.getAll();
} }
@Override @Override
@Transactional
public Language getLanguage() { public Language getLanguage() {
return this.emailTemplate.getLanguage(); return this.emailTemplate.getLanguage();
} }
@ -113,46 +118,37 @@ public class EmailTemplateModel implements IEmailTemplateModel {
this.emailTemplate.setType(emailTemplateEnum); this.emailTemplate.setType(emailTemplateEnum);
} }
@Override
public String getContent() {
return this.emailTemplate.getContent();
}
@Override @Override
public void setContent(String content) { public void setContent(String content) {
this.emailTemplate.setContent(content); this.emailTemplate.setContent(content);
} }
@Override
public String getSubject() {
return this.emailTemplate.getSubject();
}
@Override @Override
public void setSubject(String subject) { public void setSubject(String subject) {
this.emailTemplate.setSubject(subject); this.emailTemplate.setSubject(subject);
} }
@Override @Override
@Transactional public String getContent(Language language, EmailTemplateEnum type) {
public String getContentBySelectedLanguage(int languageOrdinal, int emailTemplateTypeOrdinal) { EmailTemplate template = getEmailTemplateByTypeAndLanguage(type, language);
return emailTemplateDAO.getContentBySelectedLanguage(languageOrdinal, emailTemplateTypeOrdinal);
return template != null ? template.getContent() : "";
} }
@Override @Override
@Transactional public String getSubject(Language language, EmailTemplateEnum type) {
public String getContentBySelectedTemplate(int emailTemplateTypeOrdinal, int languageOrdinal) { EmailTemplate template = getEmailTemplateByTypeAndLanguage(type, language);
return emailTemplateDAO.getContentBySelectedTemplate(emailTemplateTypeOrdinal, languageOrdinal);
return template != null ? template.getSubject() : "";
}
public EmailTemplate getEmailTemplateByTypeAndLanguage(EmailTemplateEnum type, Language language) {
return emailTemplateDAO.findByTypeAndLanguage(type, language);
} }
@Override @Override
@Transactional public void delete() {
public String getSubjectBySelectedLanguage(int languageOrdinal, int emailTemplateTypeOrdinal) { emailTemplateDAO.delete(this.emailTemplate);
return emailTemplateDAO.getSubjectBySelectedLanguage(languageOrdinal, emailTemplateTypeOrdinal);
}
@Override
@Transactional
public String getSubjectBySelectedTemplate(int emailTemplateTypeOrdinal, int languageOrdinal) {
return emailTemplateDAO.getSubjectBySelectedTemplate(emailTemplateTypeOrdinal, languageOrdinal);
} }
} }

View file

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

View file

@ -19,8 +19,6 @@
package org.libreplan.web.email; 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.email.entities.EmailTemplate;
import org.libreplan.business.settings.entities.Language; import org.libreplan.business.settings.entities.Language;
import org.libreplan.business.email.entities.EmailTemplateEnum; import org.libreplan.business.email.entities.EmailTemplateEnum;
@ -30,31 +28,31 @@ import java.util.List;
/** /**
* Contract for {@link EmailTemplate} * Contract for {@link EmailTemplate}
* *
* Created by * @author Created by Vova Perebykivskyi <vova@libreplan-enterprise.com> on 28.09.2015.
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 28.09.2015.
*/ */
public interface IEmailTemplateModel { public interface IEmailTemplateModel {
void confirmSave() throws ValidationException, InstanceNotFoundException; void confirmSave();
List<EmailTemplate> getAll(); List<EmailTemplate> getAll();
String getContentBySelectedLanguage(int languageOrdinal, int emailTemplateTypeOrdinal); String getContent(Language language, EmailTemplateEnum emailTemplateEnum);
String getContentBySelectedTemplate(int emailTemplateTypeOrdinal, int languageOrdinal);
String getSubjectBySelectedLanguage(int languageOrdinal, int emailTemplateTypeOrdinal); String getSubject(Language language, EmailTemplateEnum emailTemplateEnum);
String getSubjectBySelectedTemplate(int emailTemplateTypeOrdinal, int languageOrdinal);
String getContent();
void setContent(String content); void setContent(String content);
Language getLanguage(); Language getLanguage();
void setLanguage(Language language); void setLanguage(Language language);
EmailTemplateEnum getEmailTemplateEnum(); EmailTemplateEnum getEmailTemplateEnum();
void setEmailTemplateEnum(EmailTemplateEnum emailTemplateEnum); void setEmailTemplateEnum(EmailTemplateEnum emailTemplateEnum);
String getSubject();
void setSubject(String subject); 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 Susana Montes Pedreira <smontes@wirelessgalicia.com>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com> * @author Vova Perebykivskyi <vova@libreplan-enterprise.com>
*/ */
@Service @Service
@Scope(BeanDefinition.SCOPE_PROTOTYPE) @Scope(BeanDefinition.SCOPE_PROTOTYPE)
@ -116,15 +116,11 @@ public class AssignedTaskQualityFormsToOrderElementModel implements IAssignedTas
@Override @Override
public List<QualityForm> getNotAssignedQualityForms() { public List<QualityForm> getNotAssignedQualityForms() {
List<QualityForm> result = new ArrayList<QualityForm>(); return orderElement != null ? getListNotAssignedQualityForms() : new ArrayList<>();
if ( orderElement != null ) {
return getListNotAssignedQualityForms();
}
return result;
} }
private List<QualityForm> getListNotAssignedQualityForms() { private List<QualityForm> getListNotAssignedQualityForms() {
List<QualityForm> result = new ArrayList<QualityForm>(); List<QualityForm> result = new ArrayList<>();
for (QualityForm qualityForm : orderModel.getQualityForms()) { for (QualityForm qualityForm : orderModel.getQualityForms()) {
if ( !isAssigned(qualityForm) ) { if ( !isAssigned(qualityForm) ) {
result.add(qualityForm); result.add(qualityForm);
@ -135,7 +131,7 @@ public class AssignedTaskQualityFormsToOrderElementModel implements IAssignedTas
@Override @Override
public List<QualityForm> getAssignedQualityForms() { public List<QualityForm> getAssignedQualityForms() {
List<QualityForm> result = new ArrayList<QualityForm>(); List<QualityForm> result = new ArrayList<>();
for (QualityForm qualityForm : qualityFormDAO.getAll()) { for (QualityForm qualityForm : qualityFormDAO.getAll()) {
if ( isAssigned(qualityForm) ) { if ( isAssigned(qualityForm) ) {
result.add(qualityForm); result.add(qualityForm);
@ -146,7 +142,7 @@ public class AssignedTaskQualityFormsToOrderElementModel implements IAssignedTas
@Override @Override
public List<TaskQualityForm> getTaskQualityForms() { public List<TaskQualityForm> getTaskQualityForms() {
List<TaskQualityForm> result = new ArrayList<TaskQualityForm>(); List<TaskQualityForm> result = new ArrayList<>();
if ( orderElement != null ) { if ( orderElement != null ) {
result.addAll(orderElement.getTaskQualityForms()); result.addAll(orderElement.getTaskQualityForms());
} }
@ -176,10 +172,10 @@ public class AssignedTaskQualityFormsToOrderElementModel implements IAssignedTas
@Override @Override
public boolean isAssigned(QualityForm qualityForm) { public boolean isAssigned(QualityForm qualityForm) {
// orderDAO used for gathered data to be sent to LibrePlan server // 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 // 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()) { for (TaskQualityForm taskQualityForm : orderElement.getTaskQualityForms()) {
if ( qualityForm.equals(taskQualityForm.getQualityForm()) ) { if ( qualityForm.equals(taskQualityForm.getQualityForm()) ) {
return true; return true;
@ -203,37 +199,27 @@ public class AssignedTaskQualityFormsToOrderElementModel implements IAssignedTas
} }
public boolean isDisabledPassedItem(TaskQualityForm taskQualityForm, TaskQualityFormItem item) { public boolean isDisabledPassedItem(TaskQualityForm taskQualityForm, TaskQualityFormItem item) {
if ( (taskQualityForm == null) || ((item == null)) ) { return (taskQualityForm == null) ||
return true; (item == null) ||
} !taskQualityForm.isByItems() && !(item.getPassed() ||
if ( !taskQualityForm.isByItems() ) { taskQualityForm.isPassedPreviousItem(item));
return (!(item.getPassed() || taskQualityForm.isPassedPreviousItem(item)));
}
return false;
} }
public boolean isDisabledDateItem(TaskQualityForm taskQualityForm, TaskQualityFormItem item) { public boolean isDisabledDateItem(TaskQualityForm taskQualityForm, TaskQualityFormItem item) {
if ( (taskQualityForm == null) || ((item == null)) ) { return (taskQualityForm == null) || (item == null) || !taskQualityForm.isByItems() && !item.getPassed();
return true;
}
return (!taskQualityForm.isByItems() && (!item.getPassed()));
} }
public boolean isCorrectConsecutiveDate(TaskQualityForm taskQualityForm, TaskQualityFormItem item) { public boolean isCorrectConsecutiveDate(TaskQualityForm taskQualityForm, TaskQualityFormItem item) {
if ( (taskQualityForm == null) || ((item == null)) ) { return (taskQualityForm == null) ||
return true; (item == null) ||
} taskQualityForm.isByItems() ||
if ( taskQualityForm.isByItems() ) { taskQualityForm.isCorrectConsecutiveDate(item);
return true;
}
return (taskQualityForm.isCorrectConsecutiveDate(item));
} }
public void updatePassedTaskQualityFormItems(TaskQualityForm taskQualityForm) { public void updatePassedTaskQualityFormItems(TaskQualityForm taskQualityForm) {
if (taskQualityForm != null) { if (taskQualityForm != null) {
Integer position = getFirstNotPassedPosition(taskQualityForm); Integer position = getFirstNotPassedPosition(taskQualityForm);
List<TaskQualityFormItem> items = taskQualityForm List<TaskQualityFormItem> items = taskQualityForm.getTaskQualityFormItems();
.getTaskQualityFormItems();
for (int i = position; i < items.size(); i++) { for (int i = position; i < items.size(); i++) {
items.get(i).setPassed(false); items.get(i).setPassed(false);
items.get(i).setDate(null); items.get(i).setDate(null);
@ -243,8 +229,7 @@ public class AssignedTaskQualityFormsToOrderElementModel implements IAssignedTas
private Integer getFirstNotPassedPosition(TaskQualityForm taskQualityForm) { private Integer getFirstNotPassedPosition(TaskQualityForm taskQualityForm) {
Integer position = 0; Integer position = 0;
for (TaskQualityFormItem item : taskQualityForm for (TaskQualityFormItem item : taskQualityForm.getTaskQualityFormItems()) {
.getTaskQualityFormItems()) {
if (!item.getPassed()) { if (!item.getPassed()) {
return position; return position;
} }
@ -254,12 +239,10 @@ public class AssignedTaskQualityFormsToOrderElementModel implements IAssignedTas
} }
// Operation to confirm and validate // Operation to confirm and validate
@Override @Override
public void validate() { public void validate() {
if (getOrderElement() != null) { if (getOrderElement() != null) {
for (TaskQualityForm taskQualityForm : orderElement for (TaskQualityForm taskQualityForm : orderElement.getTaskQualityForms()) {
.getTaskQualityForms()) {
validateTaskQualityForm(taskQualityForm); validateTaskQualityForm(taskQualityForm);
} }
} }
@ -270,19 +253,15 @@ public class AssignedTaskQualityFormsToOrderElementModel implements IAssignedTas
} }
private void validateTaskQualityFormItems(TaskQualityForm taskQualityForm) { private void validateTaskQualityFormItems(TaskQualityForm taskQualityForm) {
for (TaskQualityFormItem item : taskQualityForm for (TaskQualityFormItem item : taskQualityForm.getTaskQualityFormItems()) {
.getTaskQualityFormItems()) {
if ((!taskQualityForm.isByItems()) if ( (!taskQualityForm.isByItems()) && (!taskQualityForm.isCorrectConsecutivePassed(item)) ) {
&& (!taskQualityForm.isCorrectConsecutivePassed(item))) { throw new ValidationException(invalidValue(
throw new ValidationException(
invalidValue(
_("cannot be checked until the previous item is checked before"), _("cannot be checked until the previous item is checked before"),
"passed", item.getName(), taskQualityForm)); "passed", item.getName(), taskQualityForm));
} }
if ((!taskQualityForm.isByItems()) if ( (!taskQualityForm.isByItems()) && (!taskQualityForm.isCorrectConsecutiveDate(item)) ) {
&& (!taskQualityForm.isCorrectConsecutiveDate(item))) {
throw new ValidationException(invalidValue( throw new ValidationException(invalidValue(
_("must be after the previous date"), _("must be after the previous date"),
"date", item.getName(), taskQualityForm)); "date", item.getName(), taskQualityForm));
@ -299,8 +278,7 @@ public class AssignedTaskQualityFormsToOrderElementModel implements IAssignedTas
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public void addAdvanceAssignmentIfNeeded(TaskQualityForm taskQualityForm) public void addAdvanceAssignmentIfNeeded(TaskQualityForm taskQualityForm)
throws DuplicateValueTrueReportGlobalAdvanceException, throws DuplicateValueTrueReportGlobalAdvanceException, DuplicateAdvanceAssignmentForOrderElementException {
DuplicateAdvanceAssignmentForOrderElementException {
AdvanceType advanceType = taskQualityForm.getQualityForm().getAdvanceType(); AdvanceType advanceType = taskQualityForm.getQualityForm().getAdvanceType();
advanceTypeDAO.reattach(advanceType); advanceTypeDAO.reattach(advanceType);
@ -340,8 +318,7 @@ public class AssignedTaskQualityFormsToOrderElementModel implements IAssignedTas
} }
private void showMessageDeleteSpread() throws ValidationException { private void showMessageDeleteSpread() throws ValidationException {
throw new ValidationException( throw new ValidationException(_("Quality form cannot be removed as it is spreading progress"));
_("Quality form cannot be removed as it is spreading progress"));
} }
@Override @Override

View file

@ -33,33 +33,31 @@ import org.libreplan.business.qualityforms.entities.TaskQualityFormItem;
/** /**
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com> * @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com> * @author Vova Perebykivskyi <vova@libreplan-enterprise.com>
*/ */
public interface IAssignedTaskQualityFormsToOrderElementModel { public interface IAssignedTaskQualityFormsToOrderElementModel {
/** /**
* Assigns {@link TaskQualityForm} to {@link OrderElement} * Assigns {@link TaskQualityForm} to {@link OrderElement}.
* @param @ QualityForm} * @param @ QualityForm}
*/ */
void assignTaskQualityForm(QualityForm qualityForm); void assignTaskQualityForm(QualityForm qualityForm);
/** /**
* Delete {@link TaskQualityForm} * Delete {@link TaskQualityForm}.
* @param taskQualityForm * @param taskQualityForm
*/ */
void deleteTaskQualityForm(TaskQualityForm taskQualityForm); void deleteTaskQualityForm(TaskQualityForm taskQualityForm);
/** /**
* Gets all {@link TaskQualityForm} assigned to the current * Gets all {@link TaskQualityForm} assigned to the current {@link OrderElement}.
* {@link OrderElement} * @return {@link List<TaskQualityForm>}
* @return
*/ */
List<TaskQualityForm> getTaskQualityForms(); List<TaskQualityForm> getTaskQualityForms();
/** /**
* Returns all the unallocated {@link QualityForm} to the current * Returns all the unallocated {@link QualityForm} to the current {@link OrderElement}.
* {@link OrderElement} * @return {@link List<QualityForm>}
* @return
*/ */
List<QualityForm> getNotAssignedQualityForms(); List<QualityForm> getNotAssignedQualityForms();
@ -69,22 +67,20 @@ public interface IAssignedTaskQualityFormsToOrderElementModel {
List<QualityForm> getAssignedQualityForms(); List<QualityForm> getAssignedQualityForms();
/** /**
* Returns {@link OrderElement} * @return {@link OrderElement}
* @return
*/ */
OrderElement getOrderElement(); OrderElement getOrderElement();
void init(OrderElement orderElement); void init(OrderElement orderElement);
/** /**
* Check whether {@link QualityForm} has been already assigned to * Check whether {@link QualityForm} has been already assigned to {@link OrderElement} or not.
* {@link OrderElement} or not
* @param qualityForm * @param qualityForm
*/ */
boolean isAssigned(QualityForm qualityForm); boolean isAssigned(QualityForm qualityForm);
/** /**
* Set {@link OrderElement} * Set {@link OrderElement}.
* @param orderElement * @param orderElement
*/ */
void setOrderElement(OrderElement orderElement); void setOrderElement(OrderElement orderElement);
@ -95,47 +91,36 @@ public interface IAssignedTaskQualityFormsToOrderElementModel {
void setOrderModel(IOrderModel orderModel); void setOrderModel(IOrderModel orderModel);
/** /**
* Update the date and the property passed of all the * Update the date and the property passed of all the {@link TaskQualityFormItem} of the {@link TaskQualityForm}.
* {@link TaskQualityFormItem} of the {@ TaskQualityForm}
* @param taskQualityForm * @param taskQualityForm
*/ */
void updatePassedTaskQualityFormItems(TaskQualityForm taskQualityForm); void updatePassedTaskQualityFormItems(TaskQualityForm taskQualityForm);
/** /**
* Check whether {@link QualityFormItem} the property passed must be * Check whether {@link QualityFormItem} the property passed must be disabled.
* disabled * @param taskQualityForm, item
* @param taskQualityForm
* ,item
*/ */
boolean isDisabledPassedItem(TaskQualityForm taskQualityForm, boolean isDisabledPassedItem(TaskQualityForm taskQualityForm, TaskQualityFormItem item);
TaskQualityFormItem item);
/** /**
* Check whether {@link QualityFormItem} date must be disabled * Check whether {@link QualityFormItem} date must be disabled.
* @param taskQualityForm * @param taskQualityForm, item
* ,item
*/ */
boolean isDisabledDateItem(TaskQualityForm taskQualityForm, boolean isDisabledDateItem(TaskQualityForm taskQualityForm, TaskQualityFormItem item);
TaskQualityFormItem item);
/** /**
* Check whether {@link QualityFormItem} date is consecutive * Check whether {@link QualityFormItem} date is consecutive.
* @param taskQualityForm * @param taskQualityForm, item
* ,item
*/ */
boolean isCorrectConsecutiveDate(TaskQualityForm taskQualityForm, boolean isCorrectConsecutiveDate(TaskQualityForm taskQualityForm, TaskQualityFormItem item);
TaskQualityFormItem item);
/** /**
* Check whether all {@link QualityForm} and its {@link QualityFormItem} are * Check whether all {@link QualityForm} and its {@link QualityFormItem} are valid.
* valid.
* @param
*/ */
void validate(); void validate();
void addAdvanceAssignmentIfNeeded(TaskQualityForm taskQualityForm) void addAdvanceAssignmentIfNeeded(TaskQualityForm taskQualityForm)
throws DuplicateValueTrueReportGlobalAdvanceException, throws DuplicateValueTrueReportGlobalAdvanceException, DuplicateAdvanceAssignmentForOrderElementException;
DuplicateAdvanceAssignmentForOrderElementException;
void removeAdvanceAssignmentIfNeeded(TaskQualityForm taskQualityForm); 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.NewAllocationSelector;
import org.libreplan.web.common.components.NewAllocationSelectorCombo; import org.libreplan.web.common.components.NewAllocationSelectorCombo;
import org.libreplan.web.common.components.ResourceAllocationBehaviour; 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.order.PlanningStateCreator.PlanningState;
import org.libreplan.web.planner.taskedition.EditTaskController; import org.libreplan.web.planner.taskedition.EditTaskController;
import org.libreplan.web.planner.taskedition.TaskPropertiesController; 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.Component;
import org.zkoss.zk.ui.WrongValueException; import org.zkoss.zk.ui.WrongValueException;
import org.zkoss.zk.ui.event.Event; 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.event.Events;
import org.zkoss.zk.ui.util.GenericForwardComposer; import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.Button; import org.zkoss.zul.Button;
@ -88,7 +86,7 @@ import org.zkoss.zul.Window;
* @author Manuel Rego Casasnovas <mrego@igalia.com> * @author Manuel Rego Casasnovas <mrego@igalia.com>
* @author Diego Pino Garcia <dpino@igalia.com> * @author Diego Pino Garcia <dpino@igalia.com>
* @author Javier Moran Rua <jmoran@igalia.com> * @author Javier Moran Rua <jmoran@igalia.com>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com> * @author Vova Perebykivskyi <vova@libreplan-enterprise.com>
*/ */
@org.springframework.stereotype.Component("resourceAllocationController") @org.springframework.stereotype.Component("resourceAllocationController")
@Scope(BeanDefinition.SCOPE_PROTOTYPE) @Scope(BeanDefinition.SCOPE_PROTOTYPE)
@ -117,10 +115,13 @@ public class ResourceAllocationController extends GenericForwardComposer {
private Decimalbox allResourcesPerDay; private Decimalbox allResourcesPerDay;
private Label allOriginalEffort; private Label allOriginalEffort;
private Label allTotalEffort; private Label allTotalEffort;
private Label allConsolidatedEffort; private Label allConsolidatedEffort;
private Label allTotalResourcesPerDay; private Label allTotalResourcesPerDay;
private Label allConsolidatedResourcesPerDay; private Label allConsolidatedResourcesPerDay;
private Button applyButton; 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 task
* @param ganttTask
* @param planningState * @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) { IMessagesForUser messagesForUser) {
try { try {
if ( formBinder != null ) { if ( formBinder != null ) {
@ -240,13 +244,7 @@ public class ResourceAllocationController extends GenericForwardComposer {
private void initializeTaskInformationComponent() { private void initializeTaskInformationComponent() {
taskInformation.initializeGridTaskRows(resourceAllocationModel.getHoursAggregatedByCriterions()); taskInformation.initializeGridTaskRows(resourceAllocationModel.getHoursAggregatedByCriterions());
formBinder.setRecommendedAllocation(taskInformation.getBtnRecommendedAllocation()); formBinder.setRecommendedAllocation(taskInformation.getBtnRecommendedAllocation());
taskInformation.onCalculateTotalHours(new ITotalHoursCalculationListener() { taskInformation.onCalculateTotalHours(() -> resourceAllocationModel.getOrderHours());
@Override
public Integer getTotalHours() {
return resourceAllocationModel.getOrderHours();
}
});
} }
private void initializeAllocationConfigurationComponent() { private void initializeAllocationConfigurationComponent() {
@ -261,18 +259,18 @@ public class ResourceAllocationController extends GenericForwardComposer {
return new Label(data.getCriterionsJoinedByComma()); return new Label(data.getCriterionsJoinedByComma());
} }
}, },
RESOURCE_TYPE{
RESOURCE_TYPE{
@Override @Override
public Component cell(HoursRendererColumn column, AggregatedHoursGroup data) { public Component cell(HoursRendererColumn column, AggregatedHoursGroup data) {
return new Label(asString(data.getResourceType())); return new Label(asString(data.getResourceType()));
} }
}, },
HOURS { HOURS {
@Override @Override
public Component cell(HoursRendererColumn column, AggregatedHoursGroup data) { public Component cell(HoursRendererColumn column, AggregatedHoursGroup data) {
Label result = new Label(Integer.toString(data.getHours())); return new Label(Integer.toString(data.getHours()));
return result;
} }
}; };
@ -286,6 +284,7 @@ public class ResourceAllocationController extends GenericForwardComposer {
default: default:
LOG.warn("no i18n for " + resourceType.name()); LOG.warn("no i18n for " + resourceType.name());
return resourceType.name(); return resourceType.name();
} }
} }
@ -294,8 +293,7 @@ public class ResourceAllocationController extends GenericForwardComposer {
} }
/** /**
* Pick resources selected from {@link NewAllocationSelector} and add them to * Pick resources selected from {@link NewAllocationSelector} and add them to resource allocation list.
* resource allocation list
* *
* @param e * @param e
*/ */
@ -305,8 +303,12 @@ public class ResourceAllocationController extends GenericForwardComposer {
} finally { } finally {
// For email notification feature // For email notification feature
int rowsSize = allocationRows.getCurrentRows().size(); int rowsSize = allocationRows.getCurrentRows().size();
editTaskController.getTaskPropertiesController().listToAdd
editTaskController
.getTaskPropertiesController()
.getListToAdd()
.add(allocationRows.getCurrentRows().get(rowsSize - 1).getAssociatedResources().get(0)); .add(allocationRows.getCurrentRows().get(rowsSize - 1).getAssociatedResources().get(0));
editTaskController.getTaskPropertiesController().setResourcesAdded(true); editTaskController.getTaskPropertiesController().setResourcesAdded(true);
tbResourceAllocation.setSelected(true); tbResourceAllocation.setSelected(true);
@ -320,15 +322,13 @@ public class ResourceAllocationController extends GenericForwardComposer {
applyButton.setVisible(false); applyButton.setVisible(false);
workerSearchTab.setSelected(true); workerSearchTab.setSelected(true);
LocalDate start = LocalDate LocalDate start = LocalDate.fromDateFields(resourceAllocationModel.getTaskStart());
.fromDateFields(resourceAllocationModel.getTaskStart()); LocalDate end = LocalDate.fromDateFields(resourceAllocationModel.getTaskEnd());
LocalDate end = LocalDate
.fromDateFields(resourceAllocationModel.getTaskEnd());
newAllocationSelector.open(start, end); newAllocationSelector.open(start, end);
} }
/** /**
* Shows the extended view of the resources allocations * Shows the extended view of the resources allocations.
*/ */
public void onCheckExtendedView() { public void onCheckExtendedView() {
if (isExtendedView()) { if (isExtendedView()) {
@ -345,21 +345,14 @@ public class ResourceAllocationController extends GenericForwardComposer {
} }
public int getColspanHours() { public int getColspanHours() {
if (isExtendedView()) { return isExtendedView() ? 4 : 1;
return 4;
}
return 1;
} }
public int getColspanResources() { public int getColspanResources() {
if (isExtendedView()) { return isExtendedView() ? 3 : 1;
return 3;
}
return 1;
} }
/** /**
* Close search worker in worker search tab * Close search worker in worker search tab.
* @param e
*/ */
public void onCloseSelectWorkers() { public void onCloseSelectWorkers() {
tbResourceAllocation.setSelected(true); tbResourceAllocation.setSelected(true);
@ -380,6 +373,7 @@ public class ResourceAllocationController extends GenericForwardComposer {
return resourceAllocationController.getTaskWorkableDays(); return resourceAllocationController.getTaskWorkableDays();
} }
}, },
NUMBER_OF_HOURS(CalculatedValue.NUMBER_OF_HOURS) { NUMBER_OF_HOURS(CalculatedValue.NUMBER_OF_HOURS) {
@Override @Override
public String getName() { public String getName() {
@ -392,8 +386,8 @@ public class ResourceAllocationController extends GenericForwardComposer {
return resourceAllocationController.assignedEffortComponent; return resourceAllocationController.assignedEffortComponent;
} }
}, },
RESOURCES_PER_DAY(CalculatedValue.RESOURCES_PER_DAY) {
RESOURCES_PER_DAY(CalculatedValue.RESOURCES_PER_DAY) {
@Override @Override
public String getName() { public String getName() {
return _("Calculate Resources per Day"); 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) { public static CalculationTypeRadio from(CalculatedValue calculatedValue) {
Validate.notNull(calculatedValue); Validate.notNull(calculatedValue);
for (CalculationTypeRadio calculationTypeRadio : CalculationTypeRadio for (CalculationTypeRadio calculationTypeRadio : CalculationTypeRadio.values()) {
.values()) {
if (calculationTypeRadio.getCalculatedValue() == calculatedValue) { if (calculationTypeRadio.getCalculatedValue() == calculatedValue) {
return calculationTypeRadio; return calculationTypeRadio;
} }
} }
throw new RuntimeException("not found " throw new RuntimeException(
+ CalculationTypeRadio.class.getSimpleName() + " for " "not found " + CalculationTypeRadio.class.getSimpleName() + " for " + calculatedValue);
+ calculatedValue);
} }
public abstract Component input( public abstract Component input(ResourceAllocationController resourceAllocationController);
ResourceAllocationController resourceAllocationController);
public Radio createRadio() { public Radio createRadio() {
Radio result = new Radio(); Radio result = new Radio();
result.setLabel(getName()); result.setLabel(getName());
result.setValue(toString()); result.setValue(toString());
return result; return result;
} }
private final CalculatedValue calculatedValue;
private CalculationTypeRadio(CalculatedValue calculatedValue) {
this.calculatedValue = calculatedValue;
}
public abstract String getName(); public abstract String getName();
public CalculatedValue getCalculatedValue() { public CalculatedValue getCalculatedValue() {
@ -451,32 +443,37 @@ public class ResourceAllocationController extends GenericForwardComposer {
return new Label(data.getName()); return new Label(data.getName());
} }
}, },
ALPHA(_("Alpha")) { ALPHA(_("Alpha")) {
@Override @Override
public Component cellFor(DerivedAllocation data) { public Component cellFor(DerivedAllocation data) {
return new Label(String.format("%3.2f", data.getAlpha())); return new Label(String.format("%3.2f", data.getAlpha()));
} }
}, },
HOURS(_("Total Hours")) { HOURS(_("Total Hours")) {
@Override @Override
public Component cellFor(DerivedAllocation data) { 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) { private static String _(String string) {
return string; return string;
} }
private final String name;
private DerivedAllocationColumn(String name) {
this.name = name;
}
public String getName() { public String getName() {
return I18nHelper._(name); return I18nHelper._(name);
} }
@ -489,26 +486,16 @@ public class ResourceAllocationController extends GenericForwardComposer {
public static void appendColumnsTo(Grid grid) { public static void appendColumnsTo(Grid grid) {
Columns columns = new Columns(); Columns columns = new Columns();
grid.appendChild(columns); grid.appendChild(columns);
for (DerivedAllocationColumn each : values()) { for (DerivedAllocationColumn each : values()) {
columns.appendChild(each.toColumn()); columns.appendChild(each.toColumn());
} }
} }
public static RowRenderer createRenderer() { public static RowRenderer createRenderer() {
return OnColumnsRowRenderer.create(cellRenderer, Arrays return OnColumnsRowRenderer.create(cellRenderer, Arrays.asList(DerivedAllocationColumn.values()));
.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); abstract Component cellFor(DerivedAllocation data);
} }
@ -516,15 +503,16 @@ public class ResourceAllocationController extends GenericForwardComposer {
return Arrays.asList(CalculationTypeRadio.values()); return Arrays.asList(CalculationTypeRadio.values());
} }
public List<? extends Object> getResourceAllocations() { public List<?> getResourceAllocations() {
return formBinder != null ? plusAggregatingRow(formBinder return formBinder != null
.getCurrentRows()) : Collections ? plusAggregatingRow(formBinder.getCurrentRows())
.<AllocationRow> emptyList(); : Collections.<AllocationRow> emptyList();
} }
private List<Object> plusAggregatingRow(List<AllocationRow> currentRows) { private List<Object> plusAggregatingRow(List<AllocationRow> currentRows) {
List<Object> result = new ArrayList<Object>(currentRows); List<Object> result = new ArrayList<>(currentRows);
result.add(null); result.add(null);
return result; return result;
} }
@ -548,7 +536,6 @@ public class ResourceAllocationController extends GenericForwardComposer {
} }
/** /**
*
* @return <code>true</code> if it must exist <code>false</code> if exit * @return <code>true</code> if it must exist <code>false</code> if exit
* must be prevented * 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); row.setValue(data);
append(row, data.createDetail()); append(row, data.createDetail());
append(row, new Label(data.getName())); append(row, new Label(data.getName()));
append(row, new Label(data.getOriginalEffort().toFormattedString())); append(row, new Label(data.getOriginalEffort().toFormattedString()));
append(row, new Label(data.getTotalEffort().toFormattedString())); append(row, new Label(data.getTotalEffort().toFormattedString()));
append(row, new Label(data.getConsolidatedEffort() append(row, new Label(data.getConsolidatedEffort().toFormattedString()));
.toFormattedString()));
append(row, data.getEffortInput()); append(row, data.getEffortInput());
append(row, new Label(data.getTotalResourcesPerDay().getAmount() append(row, new Label(data.getTotalResourcesPerDay().getAmount().toString()));
.toString())); append(row, new Label(data.getConsolidatedResourcesPerDay().getAmount().toString()));
append(row, new Label(data.getConsolidatedResourcesPerDay()
.getAmount().toString()));
Div resourcesPerDayContainer = append(row, new Div()); Div resourcesPerDayContainer = append(row, new Div());
append(resourcesPerDayContainer, append(resourcesPerDayContainer, data.getIntendedResourcesPerDayInput());
data.getIntendedResourcesPerDayInput()); Label realResourcesPerDay = append(resourcesPerDayContainer, data.getRealResourcesPerDay());
Label realResourcesPerDay = append(resourcesPerDayContainer,
data.getRealResourcesPerDay());
realResourcesPerDay.setStyle("float: right; padding-right: 1em;"); realResourcesPerDay.setStyle("float: right; padding-right: 1em;");
Listbox assignmentFunctionListbox = data.getAssignmentFunctionListbox(); Listbox assignmentFunctionListbox = data.getAssignmentFunctionListbox();
append(row, assignmentFunctionListbox); append(row, assignmentFunctionListbox);
assignmentFunctionListbox.addEventListener(Events.ON_SELECT, assignmentFunctionListbox.addEventListener(Events.ON_SELECT, event -> data.resetAssignmentFunction());
new EventListener() {
@Override
public void onEvent(Event arg0) throws Exception {
data.resetAssignmentFunction();
}
});
// On click delete button // On click delete button
Button deleteButton = appendDeleteButton(row); Button deleteButton = appendDeleteButton(row);
deleteButton.setDisabled(isAnyManualOrTaskUpdatedFromTimesheets()); deleteButton.setDisabled(isAnyManualOrTaskUpdatedFromTimesheets());
formBinder.setDeleteButtonFor(data, deleteButton); formBinder.setDeleteButtonFor(data, deleteButton);
deleteButton.addEventListener("onClick", new EventListener() {
@Override deleteButton.addEventListener("onClick", event -> {
public void onEvent(Event event) {
editTaskController.getTaskPropertiesController().getListToDelete() editTaskController
.add(data.getAssociatedResources().get(0)); .getTaskPropertiesController()
removeAllocation(data); .getListToDelete()
} .add(data.getAssociatedResources().get(0));
removeAllocation(data);
}); });
if (!data.isSatisfied()) { if (!data.isSatisfied()) {
@ -632,12 +608,10 @@ public class ResourceAllocationController extends GenericForwardComposer {
append(row, allOriginalEffort); append(row, allOriginalEffort);
append(row, allTotalEffort); append(row, allTotalEffort);
append(row, allConsolidatedEffort); append(row, allConsolidatedEffort);
append(row, CalculationTypeRadio.NUMBER_OF_HOURS append(row, CalculationTypeRadio.NUMBER_OF_HOURS.input(controller));
.input(controller));
append(row, allTotalResourcesPerDay); append(row, allTotalResourcesPerDay);
append(row, allConsolidatedResourcesPerDay); append(row, allConsolidatedResourcesPerDay);
append(row, CalculationTypeRadio.RESOURCES_PER_DAY append(row, CalculationTypeRadio.RESOURCES_PER_DAY.input(controller));
.input(controller));
append(row, new Label()); append(row, new Label());
} }
@ -652,6 +626,7 @@ public class ResourceAllocationController extends GenericForwardComposer {
button.setImage("/common/img/ico_borrar1.png"); button.setImage("/common/img/ico_borrar1.png");
button.setHoverImage("/common/img/ico_borrar.png"); button.setHoverImage("/common/img/ico_borrar.png");
button.setTooltiptext(_("Delete")); button.setTooltiptext(_("Delete"));
return append(row, button); return append(row, button);
} }
@ -670,7 +645,7 @@ public class ResourceAllocationController extends GenericForwardComposer {
} }
public boolean hasResourceAllocations() { public boolean hasResourceAllocations() {
return ((getResourceAllocations().size() > 1)); return getResourceAllocations().size() > 1;
} }
public boolean isAnyNotFlat() { public boolean isAnyNotFlat() {
@ -678,11 +653,7 @@ public class ResourceAllocationController extends GenericForwardComposer {
} }
public boolean isAnyManualOrTaskUpdatedFromTimesheets() { public boolean isAnyManualOrTaskUpdatedFromTimesheets() {
if (formBinder == null) { return formBinder != null && (formBinder.isAnyManual() || formBinder.isTaskUpdatedFromTimesheets());
return false;
}
return formBinder.isAnyManual()
|| formBinder.isTaskUpdatedFromTimesheets();
} }
} }

View file

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

View file

@ -25,7 +25,6 @@ import static org.libreplan.web.I18nHelper._;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.Iterator;
import java.util.List; import java.util.List;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
@ -83,7 +82,7 @@ import org.zkoss.zul.api.Tabpanel;
* Controller for edit {@link Task} popup. * Controller for edit {@link Task} popup.
* *
* @author Manuel Rego Casasnovas <mrego@igalia.com> * @author Manuel Rego Casasnovas <mrego@igalia.com>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com> * @author Vova Perebykivskyi <vova@libreplan-enterprise.com>
*/ */
@org.springframework.stereotype.Component("taskPropertiesController") @org.springframework.stereotype.Component("taskPropertiesController")
@Scope(BeanDefinition.SCOPE_PROTOTYPE) @Scope(BeanDefinition.SCOPE_PROTOTYPE)
@ -136,33 +135,36 @@ public class TaskPropertiesController extends GenericForwardComposer {
private boolean isResourcesAdded = false; private boolean isResourcesAdded = false;
private List<Resource> listToDelete = new ArrayList<>();
private List<Resource> listToAdd = new ArrayList<>();
public void init(final EditTaskController editTaskController, public void init(final EditTaskController editTaskController,
IContextWithPlannerTask<TaskElement> context, IContextWithPlannerTask<TaskElement> context,
TaskElement taskElement) { TaskElement taskElement) {
this.editTaskController = editTaskController; this.editTaskController = editTaskController;
this.currentContext = context; this.currentContext = context;
this.currentTaskElement = taskElement; this.currentTaskElement = taskElement;
Order order = null; Order order;
if (context != null) { if (context != null) {
order = findOrderIn(context); order = findOrderIn(context);
} else { } else {
order = taskElement.getOrderElement().getOrder(); order = taskElement.getOrderElement().getOrder();
} }
// WebStartConstraintType.setItems(startConstraintTypes, order);
setItemsStartConstraintTypesCombo(order); setItemsStartConstraintTypesCombo(order);
originalState = getResourceAllocationType(currentTaskElement); originalState = getResourceAllocationType(currentTaskElement);
setOldState(originalState); setOldState(originalState);
disabledConstraintsAndAllocations = currentTaskElement disabledConstraintsAndAllocations = currentTaskElement.isSubcontractedAndWasAlreadySent() ||
.isSubcontractedAndWasAlreadySent() currentTaskElement.isLimitingAndHasDayAssignments() ||
|| currentTaskElement.isLimitingAndHasDayAssignments() currentTaskElement.isUpdatedFromTimesheets();
|| currentTaskElement.isUpdatedFromTimesheets();
if (!disabledConstraintsAndAllocations && (currentTaskElement.isTask())) { if (!disabledConstraintsAndAllocations && (currentTaskElement.isTask())) {
disabledConstraintsAndAllocations = ((Task) currentTaskElement) disabledConstraintsAndAllocations = ((Task) currentTaskElement).isManualAnyAllocation();
.isManualAnyAllocation();
} }
startConstraintTypes.setDisabled(disabledConstraintsAndAllocations); startConstraintTypes.setDisabled(disabledConstraintsAndAllocations);
startConstraintDate.setDisabled(disabledConstraintsAndAllocations); startConstraintDate.setDisabled(disabledConstraintsAndAllocations);
@ -177,13 +179,16 @@ public class TaskPropertiesController extends GenericForwardComposer {
private void setItemsStartConstraintTypesCombo(Order order) { private void setItemsStartConstraintTypesCombo(Order order) {
startConstraintTypes.getChildren().clear(); startConstraintTypes.getChildren().clear();
for (PositionConstraintType type : PositionConstraintType.values()) { 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_SOON_AS_POSSIBLE) ||
(type == PositionConstraintType.AS_LATE_AS_POSSIBLE && (type == PositionConstraintType.AS_LATE_AS_POSSIBLE &&
order.getDeadline() != null) || order.getDeadline() != null) ||
(type == PositionConstraintType.AS_SOON_AS_POSSIBLE && (type == PositionConstraintType.AS_SOON_AS_POSSIBLE &&
order.getInitDate() != null)) { order.getInitDate() != null) ) {
Comboitem comboitem = new Comboitem(_(type.getName())); Comboitem comboitem = new Comboitem(_(type.getName()));
comboitem.setValue(type); comboitem.setValue(type);
startConstraintTypes.appendChild(comboitem); startConstraintTypes.appendChild(comboitem);
@ -192,32 +197,31 @@ public class TaskPropertiesController extends GenericForwardComposer {
} }
private Order findOrderIn(IContextWithPlannerTask<TaskElement> context) { private Order findOrderIn(IContextWithPlannerTask<TaskElement> context) {
TaskElement topTask = context.getMapper().findAssociatedDomainObject( TaskElement topTask = context.getMapper().findAssociatedDomainObject(findTopMostTask(context));
findTopMostTask(context));
return topTask.getParent().getOrderElement().getOrder(); return topTask.getParent().getOrderElement().getOrder();
} }
private OrderElement findOrderElementIn(IContextWithPlannerTask<TaskElement> context) { private OrderElement findOrderElementIn(IContextWithPlannerTask<TaskElement> context) {
TaskElement topTask = context.getMapper().findAssociatedDomainObject( TaskElement topTask = context.getMapper().findAssociatedDomainObject(findTopMostTask(context));
findTopMostTask(context));
return topTask.getOrderElement(); return topTask.getOrderElement();
} }
private org.zkoss.ganttz.data.Task findTopMostTask( private org.zkoss.ganttz.data.Task findTopMostTask(IContextWithPlannerTask<TaskElement> context) {
IContextWithPlannerTask<TaskElement> context) { List<? extends TaskContainer> parents = context.getMapper().getParents(context.getTask());
List<? extends TaskContainer> parents = context.getMapper().getParents(
context.getTask()); return parents.isEmpty() ? context.getTask() : parents.get(parents.size() - 1);
return parents.isEmpty() ? context.getTask() : parents.get(parents
.size() - 1);
} }
private void setOldState(ResourceAllocationTypeEnum state) { private void setOldState(ResourceAllocationTypeEnum state) {
// TODO resolve deprecated
lbResourceAllocationType.setVariable("oldState", state, true); lbResourceAllocationType.setVariable("oldState", state, true);
} }
private ResourceAllocationTypeEnum getOldState() { private ResourceAllocationTypeEnum getOldState() {
return (ResourceAllocationTypeEnum) lbResourceAllocationType // TODO resolve deprecated
.getVariable("oldState", true); return (ResourceAllocationTypeEnum) lbResourceAllocationType.getVariable("oldState", true);
} }
private void setResourceAllocationType(Listbox listbox, ResourceAllocationTypeEnum value) { private void setResourceAllocationType(Listbox listbox, ResourceAllocationTypeEnum value) {
@ -225,10 +229,11 @@ public class TaskPropertiesController extends GenericForwardComposer {
} }
private void setResourceAllocationType(Listbox listbox, String label) { private void setResourceAllocationType(Listbox listbox, String label) {
for (Iterator i = listbox.getChildren().iterator(); i.hasNext(); ) { for (Object o : listbox.getChildren()) {
Listitem item = (Listitem) i.next(); Listitem item = (Listitem) o;
Listcell cell = (Listcell) item.getFirstChild(); Listcell cell = (Listcell) item.getFirstChild();
if (cell.getLabel() != null && cell.getLabel().equals(label)) {
if ( cell.getLabel() != null && cell.getLabel().equals(label) ) {
item.setSelected(true); item.setSelected(true);
} }
} }
@ -239,7 +244,7 @@ public class TaskPropertiesController extends GenericForwardComposer {
Task task = (Task) currentTaskElement; Task task = (Task) currentTaskElement;
showDurationRow(task); showDurationRow(task);
showStartConstraintRow(task); showStartConstraintRow(task);
showResourceAllocationTypeRow(task); showResourceAllocationTypeRow();
} else { } else {
hideDurationRow(); hideDurationRow();
if (currentTaskElement instanceof ITaskPositionConstrained) { if (currentTaskElement instanceof ITaskPositionConstrained) {
@ -258,7 +263,7 @@ public class TaskPropertiesController extends GenericForwardComposer {
resourceAllocationType.setVisible(false); resourceAllocationType.setVisible(false);
} }
private void showResourceAllocationTypeRow(Task task) { private void showResourceAllocationTypeRow() {
resourceAllocationType.setVisible(true); resourceAllocationType.setVisible(true);
} }
@ -268,8 +273,7 @@ public class TaskPropertiesController extends GenericForwardComposer {
private void showStartConstraintRow(ITaskPositionConstrained task) { private void showStartConstraintRow(ITaskPositionConstrained task) {
startConstraint.setVisible(true); startConstraint.setVisible(true);
PositionConstraintType type = task.getPositionConstraint() PositionConstraintType type = task.getPositionConstraint().getConstraintType();
.getConstraintType();
startConstraintTypes.setSelectedItemApi(findComboWithType(type)); startConstraintTypes.setSelectedItemApi(findComboWithType(type));
updateStartConstraint(type); updateStartConstraint(type);
} }
@ -278,7 +282,7 @@ public class TaskPropertiesController extends GenericForwardComposer {
for (Object component : startConstraintTypes.getChildren()) { for (Object component : startConstraintTypes.getChildren()) {
if (component instanceof Comboitem) { if (component instanceof Comboitem) {
Comboitem item = (Comboitem) component; Comboitem item = (Comboitem) component;
if (((PositionConstraintType) item.getValue()) == type) { if ( item.getValue() == type) {
return item; return item;
} }
} }
@ -292,29 +296,28 @@ public class TaskPropertiesController extends GenericForwardComposer {
} }
private void updateStartConstraint(PositionConstraintType type) { private void updateStartConstraint(PositionConstraintType type) {
TaskPositionConstraint taskStartConstraint = currentTaskElementAsTaskLeafConstraint() TaskPositionConstraint taskStartConstraint = currentTaskElementAsTaskLeafConstraint().getPositionConstraint();
.getPositionConstraint();
startConstraintDate.setVisible(type.isAssociatedDateRequired()); startConstraintDate.setVisible(type.isAssociatedDateRequired());
if (taskStartConstraint.getConstraintDateAsDate() != null) { if (taskStartConstraint.getConstraintDateAsDate() != null) {
startConstraintDate.setValue(taskStartConstraint startConstraintDate.setValue(taskStartConstraint.getConstraintDateAsDate());
.getConstraintDateAsDate());
} }
} }
private boolean saveConstraintChanges() { private boolean saveConstraintChanges() {
TaskPositionConstraint taskConstraint = currentTaskElementAsTaskLeafConstraint() TaskPositionConstraint taskConstraint = currentTaskElementAsTaskLeafConstraint().getPositionConstraint();
.getPositionConstraint(); PositionConstraintType type = (PositionConstraintType) startConstraintTypes.getSelectedItemApi().getValue();
PositionConstraintType type = (PositionConstraintType) startConstraintTypes
.getSelectedItemApi().getValue(); IntraDayDate inputDate = type.isAssociatedDateRequired()
IntraDayDate inputDate = type.isAssociatedDateRequired() ? IntraDayDate ? IntraDayDate.startOfDay(LocalDate.fromDateFields(startConstraintDate.getValue()))
.startOfDay(LocalDate.fromDateFields(startConstraintDate : null;
.getValue())) : null;
if (taskConstraint.isValid(type, inputDate)) { if (taskConstraint.isValid(type, inputDate)) {
taskConstraint.update(type, inputDate); taskConstraint.update(type, inputDate);
//at this point we could call currentContext.recalculatePosition(currentTaskElement) // At this point we could call currentContext.recalculatePosition(currentTaskElement)
//to trigger the scheduling algorithm, but we don't do it because // to trigger the scheduling algorithm, but we don't do it because
//the ResourceAllocationController, which is attached to the other // the ResourceAllocationController, which is attached to the other
//tab of the same window, will do it anyway. // tab of the same window, will do it anyway.
return true; return true;
} else { } else {
return false; return false;
@ -339,16 +342,14 @@ public class TaskPropertiesController extends GenericForwardComposer {
super.doAfterCompose(comp); super.doAfterCompose(comp);
tabpanel = (Tabpanel) comp; tabpanel = (Tabpanel) comp;
taskEditFormComposer.doAfterCompose(comp); taskEditFormComposer.doAfterCompose(comp);
startConstraintTypes.addEventListener(Events.ON_SELECT,
new EventListener() {
@Override startConstraintTypes.addEventListener(Events.ON_SELECT, event -> {
public void onEvent(Event event) {
PositionConstraintType constraint = (PositionConstraintType) startConstraintTypes PositionConstraintType constraint =
.getSelectedItemApi().getValue(); (PositionConstraintType) startConstraintTypes.getSelectedItemApi().getValue();
constraintTypeChoosen(constraint);
} constraintTypeChoosen(constraint);
}); });
lbResourceAllocationType.addEventListener(Events.ON_SELECT, new EventListener() { lbResourceAllocationType.addEventListener(Events.ON_SELECT, new EventListener() {
@ -358,19 +359,22 @@ public class TaskPropertiesController extends GenericForwardComposer {
final ResourceAllocationTypeEnum oldState = getOldState(); final ResourceAllocationTypeEnum oldState = getOldState();
ResourceAllocationTypeEnum newState = getSelectedValue(new ArrayList(se.getSelectedItems())); ResourceAllocationTypeEnum newState = getSelectedValue(new ArrayList(se.getSelectedItems()));
if (thereIsTransition(newState)) { if (thereIsTransition(newState)) {
if (isConsolidatedTask()) { if (isConsolidatedTask()) {
restoreOldState(); restoreOldState();
editTaskController.showNonPermitChangeResourceAllocationType(); editTaskController.showNonPermitChangeResourceAllocationType();
} else { } else {
if(newState.equals(ResourceAllocationTypeEnum.SUBCONTRACT) if (newState.equals(ResourceAllocationTypeEnum.SUBCONTRACT) && !checkCompatibleAllocation()) {
&& !checkCompatibleAllocation()){
try { try {
restoreOldState(); 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); _("Error"), Messagebox.OK , Messagebox.ERROR);
} catch (InterruptedException e) { } catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} }
}else{ }else{
@ -379,27 +383,28 @@ public class TaskPropertiesController extends GenericForwardComposer {
} }
} }
} }
if (oldState == null) { if (oldState == null) {
setOldState(newState); setOldState(newState);
} }
} }
private ResourceAllocationTypeEnum getSelectedValue(List<Listitem> selectedItems) { 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); final Listcell cell = (Listcell) item.getChildren().get(0);
return ResourceAllocationTypeEnum.asEnum(cell.getLabel()); return ResourceAllocationTypeEnum.asEnum(cell.getLabel());
} }
private void restoreOldState() { private void restoreOldState() {
Util.reloadBindings(lbResourceAllocationType); Util.reloadBindings(lbResourceAllocationType);
} }
}); });
} }
private boolean checkCompatibleAllocation(){ private boolean checkCompatibleAllocation(){
OrderElement orderElement = null; OrderElement orderElement;
AdvanceType advanceType = PredefinedAdvancedTypes.SUBCONTRACTOR.getType(); AdvanceType advanceType = PredefinedAdvancedTypes.SUBCONTRACTOR.getType();
if (this.currentContext != null) { if (this.currentContext != null) {
@ -407,15 +412,16 @@ public class TaskPropertiesController extends GenericForwardComposer {
} else { } else {
orderElement = this.currentTaskElement.getOrderElement(); orderElement = this.currentTaskElement.getOrderElement();
} }
if(orderElement.getAdvanceAssignmentByType(advanceType) != null){ if (orderElement.getAdvanceAssignmentByType(advanceType) != null) {
return false; return false;
} }
try { try {
DirectAdvanceAssignment newAdvanceAssignment = DirectAdvanceAssignment DirectAdvanceAssignment newAdvanceAssignment = DirectAdvanceAssignment.create();
.create();
newAdvanceAssignment.setAdvanceType(advanceType); newAdvanceAssignment.setAdvanceType(advanceType);
orderElement.checkAncestorsNoOtherAssignmentWithSameAdvanceType( orderElement.checkAncestorsNoOtherAssignmentWithSameAdvanceType(
orderElement.getParent(), newAdvanceAssignment); orderElement.getParent(), newAdvanceAssignment);
} catch (DuplicateAdvanceAssignmentForOrderElementException e) { } catch (DuplicateAdvanceAssignmentForOrderElementException e) {
return false; return false;
} }
@ -427,10 +433,7 @@ public class TaskPropertiesController extends GenericForwardComposer {
} }
public TaskDTO getGanttTaskDTO() { public TaskDTO getGanttTaskDTO() {
if (taskEditFormComposer == null) { return taskEditFormComposer == null ? null : taskEditFormComposer.getTaskDTO();
return null;
}
return taskEditFormComposer.getTaskDTO();
} }
public void accept() { 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> * @author Diego Pino Garcia <dpino@igalia.com>
* *
*/ */
public enum ResourceAllocationTypeEnum { public enum ResourceAllocationTypeEnum {
NON_LIMITING_RESOURCES(_("Normal resource assignment")), NON_LIMITING_RESOURCES(_("Normal resource assignment")),
LIMITING_RESOURCES(_("Queue-based resource assignation")), LIMITING_RESOURCES(_("Queue-based resource assignation")),
SUBCONTRACT(_("Subcontract")); 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) { private static String _(String string) {
return string; return string;
} }
private String option; @Override
private static final List<ResourceAllocationTypeEnum> nonMasterOptionList = new ArrayList<ResourceAllocationTypeEnum>() {
{
add(NON_LIMITING_RESOURCES);
add(SUBCONTRACT);
}
};
private ResourceAllocationTypeEnum(String option) {
this.option = option;
}
public String toString() { public String toString() {
return I18nHelper._(option); return I18nHelper._(option);
} }
@ -505,8 +512,10 @@ public class TaskPropertiesController extends GenericForwardComposer {
public static ResourceAllocationTypeEnum asEnum(String label) { public static ResourceAllocationTypeEnum asEnum(String label) {
if (NON_LIMITING_RESOURCES.toString().equals(label)) { if (NON_LIMITING_RESOURCES.toString().equals(label)) {
return NON_LIMITING_RESOURCES; return NON_LIMITING_RESOURCES;
} else if (LIMITING_RESOURCES.toString().equals(label)) { } else if (LIMITING_RESOURCES.toString().equals(label)) {
return LIMITING_RESOURCES; return LIMITING_RESOURCES;
} else if (SUBCONTRACT.toString().equals(label)) { } else if (SUBCONTRACT.toString().equals(label)) {
return SUBCONTRACT; return SUBCONTRACT;
} }
@ -516,11 +525,9 @@ public class TaskPropertiesController extends GenericForwardComposer {
} }
public List<ResourceAllocationTypeEnum> getResourceAllocationTypeOptionList() { public List<ResourceAllocationTypeEnum> getResourceAllocationTypeOptionList() {
if (scenarioManager.getCurrent().isMaster()) { return scenarioManager.getCurrent().isMaster()
return ResourceAllocationTypeEnum.getOptionList(); ? ResourceAllocationTypeEnum.getOptionList()
} else { : ResourceAllocationTypeEnum.getOptionListForNonMasterBranch();
return ResourceAllocationTypeEnum.getOptionListForNonMasterBranch();
}
} }
public ResourceAllocationTypeEnum getResourceAllocationType() { 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 * @param resourceAllocation
*/ */
public void setResourceAllocationType(ResourceAllocationTypeEnum resourceAllocation) { public void setResourceAllocationType(ResourceAllocationTypeEnum resourceAllocation) {}
}
public ResourceAllocationTypeEnum getResourceAllocationType(TaskElement taskElement) { public ResourceAllocationTypeEnum getResourceAllocationType(TaskElement taskElement) {
if ( taskElement == null || !isTask(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 is subcontracted, return a SUBCONTRACT state.
* If task has at least one limiting resource, returns a LIMITING RESOURCE state * If task has at least one limiting resource, returns a LIMITING RESOURCE state.
* Otherwise, return default state (NON-LIMITING RESOURCE) * Otherwise, return default state (NON-LIMITING RESOURCE).
* *
* @return * @return {@link ResourceAllocationTypeEnum}
*/ */
public ResourceAllocationTypeEnum getResourceAllocationType(Task task) { public ResourceAllocationTypeEnum getResourceAllocationType(Task task) {
ResourceAllocationTypeEnum result = ResourceAllocationTypeEnum.NON_LIMITING_RESOURCES; 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 * @param newState
*/ */
@ -595,17 +600,17 @@ public class TaskPropertiesController extends GenericForwardComposer {
Task task = asTask(currentTaskElement); Task task = asTask(currentTaskElement);
if (task.hasResourceAllocations()) { if (task.hasResourceAllocations()) {
try { 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) { _("Warning"), Messagebox.OK | Messagebox.CANCEL, Messagebox.QUESTION) == Messagebox.OK) {
task.removeAllResourceAllocations(); task.removeAllResourceAllocations();
setStateTo(newState); setStateTo(newState);
} else { } else {
resetStateTo(ResourceAllocationTypeEnum.NON_LIMITING_RESOURCES); resetStateTo(ResourceAllocationTypeEnum.NON_LIMITING_RESOURCES);
} }
return; return;
} catch (InterruptedException e) { } catch (InterruptedException ignored) {}
}
} }
setStateTo(newState); 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 * @param newState
*/ */
@ -633,23 +638,23 @@ public class TaskPropertiesController extends GenericForwardComposer {
Task task = asTask(currentTaskElement); Task task = asTask(currentTaskElement);
if (task.hasResourceAllocations()) { if (task.hasResourceAllocations()) {
try { 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) { _("Warning"), Messagebox.OK | Messagebox.CANCEL, Messagebox.QUESTION) == Messagebox.OK) {
task.removeAllResourceAllocations(); task.removeAllResourceAllocations();
setStateTo(newState); setStateTo(newState);
} else { } else {
resetStateTo(ResourceAllocationTypeEnum.LIMITING_RESOURCES); resetStateTo(ResourceAllocationTypeEnum.LIMITING_RESOURCES);
} }
return; return;
} catch (InterruptedException e) { } catch (InterruptedException ignored) {}
}
} }
setStateTo(newState); 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 * @param newState
*/ */
@ -657,23 +662,25 @@ public class TaskPropertiesController extends GenericForwardComposer {
Task task = asTask(currentTaskElement); Task task = asTask(currentTaskElement);
if (task.isSubcontracted()) { if (task.isSubcontracted()) {
final Date communicationDate = (task.getSubcontractedTaskData() != null) ?
task.getSubcontractedTaskData().getSubcontractCommunicationDate() final Date communicationDate = (task.getSubcontractedTaskData() != null)
? task.getSubcontractedTaskData().getSubcontractCommunicationDate()
: null; : null;
// Notification has been sent // Notification has been sent
if (communicationDate != null) { if (communicationDate != null) {
try { 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) { _("Warning"), Messagebox.OK, Messagebox.EXCLAMATION) == Messagebox.OK) {
setStateTo(newState); setStateTo(newState);
} else { } else {
resetStateTo(ResourceAllocationTypeEnum.SUBCONTRACT); resetStateTo(ResourceAllocationTypeEnum.SUBCONTRACT);
} }
return; return;
} catch (InterruptedException e) { } catch (InterruptedException ignored) {}
}
} }
} }
setStateTo(newState); setStateTo(newState);
@ -704,10 +711,8 @@ public class TaskPropertiesController extends GenericForwardComposer {
public boolean isConsolidatedTask() { public boolean isConsolidatedTask() {
Task task = asTask(currentTaskElement); Task task = asTask(currentTaskElement);
if (task != null) {
return task.hasConsolidations(); return task != null && task.hasConsolidations();
}
return false;
} }
public void updateTaskEndDate(LocalDate endDate) { public void updateTaskEndDate(LocalDate endDate) {
@ -716,8 +721,7 @@ public class TaskPropertiesController extends GenericForwardComposer {
} }
public void updateTaskStartDate(LocalDate newStart) { public void updateTaskStartDate(LocalDate newStart) {
getGanttTaskDTO().beginDate = newStart.toDateTimeAtStartOfDay() getGanttTaskDTO().beginDate = newStart.toDateTimeAtStartOfDay().toDate();
.toDate();
Util.reloadBindings(startDateBox); Util.reloadBindings(startDateBox);
} }
@ -733,14 +737,11 @@ public class TaskPropertiesController extends GenericForwardComposer {
return Util.getMoneyFormat(); return Util.getMoneyFormat();
} }
public List<Resource> listToDelete = new ArrayList<Resource>(); public void emailNotificationAddNew() {
public List<Resource> listToAdd = new ArrayList<Resource>();
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 * 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){ private void proceedList(EmailTemplateEnum enumeration, List<Resource> list){
if ( list.size() != 0 ){ if ( !list.isEmpty() ) {
List<Worker> workersList = workerModel.getWorkers(); List<Worker> workersList = workerModel.getWorkers();
Worker currentWorker; Worker currentWorker;
Resource currentResource; Resource currentResource;
for (int i = 0; i < workersList.size(); i++) 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); currentWorker = workersList.get(i);
currentResource = list.get(j); currentResource = list.get(j);
@ -783,6 +784,7 @@ public class TaskPropertiesController extends GenericForwardComposer {
if ( enumeration.equals(EmailTemplateEnum.TEMPLATE_TASK_ASSIGNED_TO_RESOURCE) ) if ( enumeration.equals(EmailTemplateEnum.TEMPLATE_TASK_ASSIGNED_TO_RESOURCE) )
emailNotificationModel.setType(EmailTemplateEnum.TEMPLATE_TASK_ASSIGNED_TO_RESOURCE); emailNotificationModel.setType(EmailTemplateEnum.TEMPLATE_TASK_ASSIGNED_TO_RESOURCE);
else if ( enumeration.equals(EmailTemplateEnum.TEMPLATE_RESOURCE_REMOVED_FROM_TASK) ) else if ( enumeration.equals(EmailTemplateEnum.TEMPLATE_RESOURCE_REMOVED_FROM_TASK) )
emailNotificationModel.setType(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(); emailNotificationModel.confirmSave();
} catch (DataIntegrityViolationException e){ } catch (DataIntegrityViolationException e){
try { 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); Messagebox.OK, Messagebox.ERROR);
} catch (InterruptedException e1) { } catch (InterruptedException e1) {
e1.printStackTrace(); e1.printStackTrace();
} }
@ -809,11 +813,15 @@ public class TaskPropertiesController extends GenericForwardComposer {
return listToDelete; return listToDelete;
} }
public List<Resource> getListToAdd() {
return listToAdd;
}
public void setResourcesAdded(boolean resourcesAdded) { public void setResourcesAdded(boolean resourcesAdded) {
isResourcesAdded = resourcesAdded; isResourcesAdded = resourcesAdded;
} }
private TaskPropertiesController getObject(){ private TaskPropertiesController getObject() {
return this; 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/") @Path("/orderelements/")
@Produces("application/xml") @Produces("application/xml")
@Service("orderElementServiceREST") @Service("orderElementServiceREST")
public class OrderElementServiceREST extends public class OrderElementServiceREST
GenericRESTService<Order, OrderDTO> implements extends GenericRESTService<Order, OrderDTO>
IOrderElementService { implements IOrderElementService {
@Autowired @Autowired
private IOrderDAO orderDAO; private IOrderDAO orderDAO;
@ -86,15 +86,13 @@ public class OrderElementServiceREST extends
@Override @Override
@POST @POST
@Consumes("application/xml") @Consumes("application/xml")
public InstanceConstraintViolationsListDTO addOrders( public InstanceConstraintViolationsListDTO addOrders(OrderListDTO orderListDTO) {
OrderListDTO orderListDTO) {
return save(orderListDTO.orderDTOs); return save(orderListDTO.orderDTOs);
} }
@Override @Override
protected OrderDTO toDTO(Order entity) { protected OrderDTO toDTO(Order entity) {
return (OrderDTO) OrderElementConverter.toDTO(entity, return (OrderDTO) OrderElementConverter.toDTO(entity, ConfigurationOrderElementConverter.all());
ConfigurationOrderElementConverter.all());
} }
@Override @Override
@ -103,17 +101,15 @@ public class OrderElementServiceREST extends
} }
@Override @Override
protected Order toEntity(OrderDTO entityDTO) throws ValidationException, protected Order toEntity(OrderDTO entityDTO) throws ValidationException, RecoverableErrorException {
RecoverableErrorException { return (Order) OrderElementConverter.toEntity(entityDTO, ConfigurationOrderElementConverter.all());
return (Order) OrderElementConverter.toEntity(entityDTO,
ConfigurationOrderElementConverter.all());
} }
@Override @Override
protected void updateEntity(Order entity, OrderDTO entityDTO) protected void updateEntity(Order entity, OrderDTO entityDTO)
throws ValidationException, RecoverableErrorException { throws ValidationException, RecoverableErrorException {
OrderElementConverter.update(entity, entityDTO,
ConfigurationOrderElementConverter.all()); OrderElementConverter.update(entity, entityDTO, ConfigurationOrderElementConverter.all());
} }
@Override @Override
@ -133,8 +129,7 @@ public class OrderElementServiceREST extends
OrderElement orderElement = orderElementDAO.findByCode(code); OrderElement orderElement = orderElementDAO.findByCode(code);
String errorMessage = checkRemovalValidation(orderElement); String errorMessage = checkRemovalValidation(orderElement);
if (errorMessage != null) { if (errorMessage != null) {
return Response.status(Status.FORBIDDEN) return Response.status(Status.FORBIDDEN).entity(new ErrorDTO(errorMessage)).build();
.entity(new ErrorDTO(errorMessage)).build();
} }
if (orderElement.isOrder()) { if (orderElement.isOrder()) {
@ -152,6 +147,7 @@ public class OrderElementServiceREST extends
if (!parent.isOrder() && parent.getChildren().isEmpty()) { if (!parent.isOrder() && parent.getChildren().isEmpty()) {
OrderElement newElement = parent.toLeaf(); OrderElement newElement = parent.toLeaf();
if (!order.isCodeAutogenerated()) { if (!order.isCodeAutogenerated()) {
newElement.setCode(UUID.randomUUID().toString()); newElement.setCode(UUID.randomUUID().toString());
} }
@ -170,12 +166,12 @@ public class OrderElementServiceREST extends
private String checkRemovalValidation(OrderElement orderElement) { private String checkRemovalValidation(OrderElement orderElement) {
try { try {
if (orderElementDAO if (orderElementDAO.isAlreadyInUseThisOrAnyOfItsChildren(orderElement)) {
.isAlreadyInUseThisOrAnyOfItsChildren(orderElement)) {
return "You cannot remove the order element '" return "You cannot remove the order element '"
+ orderElement.getName() + orderElement.getName()
+ "' because it or any of its children have tracked time in some work report"; + "' because it or any of its children have tracked time in some work report";
} }
if (orderElementDAO.hasImputedExpenseSheetThisOrAnyOfItsChildren(orderElement.getId())) { if (orderElementDAO.hasImputedExpenseSheetThisOrAnyOfItsChildren(orderElement.getId())) {
return "You cannot remove the order element '" return "You cannot remove the order element '"
+ orderElement.getName() + orderElement.getName()
@ -183,13 +179,13 @@ public class OrderElementServiceREST extends
} }
OrderLineGroup parent = orderElement.getParent(); OrderLineGroup parent = orderElement.getParent();
if (parent != null && !parent.isOrder() if (parent != null && !parent.isOrder() && parent.getChildren().size() == 1) {
&& parent.getChildren().size() == 1) {
if (orderElementDAO.isAlreadyInUse(parent)) { if (orderElementDAO.isAlreadyInUse(parent)) {
return "You cannot remove the order element '" return "You cannot remove the order element '"
+ orderElement.getName() + orderElement.getName()
+ "' because it is the only child of its parent and its parent has tracked time in some work report"; + "' because it is the only child of its parent and its parent has tracked time in some work report";
} }
if (orderElementDAO.hasImputedExpenseSheet(parent.getId())) { if (orderElementDAO.hasImputedExpenseSheet(parent.getId())) {
return "You cannot remove the order element '" return "You cannot remove the order element '"
+ orderElement.getName() + orderElement.getName()
@ -207,6 +203,7 @@ public class OrderElementServiceREST extends
if (orderElement.getId().equals(id)) { if (orderElement.getId().equals(id)) {
return orderElement; return orderElement;
} }
for (OrderElement child : orderElement.getChildren()) { for (OrderElement child : orderElement.getChildren()) {
OrderElement found = findOrderElement(child, id); OrderElement found = findOrderElement(child, id);
if (found != null) { if (found != null) {

View file

@ -38,7 +38,7 @@
<!-- Pages --> <!-- Pages -->
<intercept-url pattern="/templates/*" access="hasAnyRole('ROLE_SUPERUSER', 'ROLE_TEMPLATES')" /> <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/worker/worker.zul" access="hasAnyRole('ROLE_SUPERUSER', 'ROLE_WORKERS')" />
<intercept-url pattern="/resources/machine/*" access="hasAnyRole('ROLE_SUPERUSER', 'ROLE_MACHINES')" /> <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 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 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 the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details. GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License 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/>. 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" <window self="@{define(content)}" apply="org.libreplan.web.email.EmailTemplateController"
title="${i18n:_('Edit E-mail template')}"> title="${i18n:_('Edit E-mail template')}">
<vbox id="messagesContainer" /> <vbox id="messagesContainer" />
<tabbox> <tabbox>
<tabs> <tabs>
<tab label="${i18n:_('Template data')}"/> <tab label="${i18n:_('Template data')}"/>
</tabs> </tabs>
<tabpanels> <tabpanels>
<tabpanel> <tabpanel>
<groupbox> <groupbox>
<caption label="${i18n:_('General user data')}" /> <caption label="${i18n:_('General user data')}" />
<grid> <grid>
<columns> <columns>
<column width="220px"></column> <column width="220px"/>
<column width="420px"></column> <column width="420px"/>
</columns> </columns>
<rows> <rows>
<row> <row>
<label value="${i18n:_('Select template language')}"/> <label value="${i18n:_('Select template language')}"/>
<listbox mold="select" <listbox mold="select"
id="templateLanguageListbox" id="templateLanguageListbox"
model="@{emailTemplateController.languages}" model="@{emailTemplateController.languages}"
itemRenderer="@{emailTemplateController.languagesRenderer}" itemRenderer="@{emailTemplateController.languagesRenderer}"
selectedItem="@{emailTemplateController.selectedLanguage}"> selectedItem="@{emailTemplateController.selectedLanguage}">
</listbox> </listbox>
</row> </row>
<row> <row>
<label value="${i18n:_('Select template type')}"/> <label value="${i18n:_('Select template type')}"/>
<listbox id="emailTemplateTypeListbox" <listbox id="emailTemplateTypeListbox"
mold="select" mold="select"
model="@{emailTemplateController.emailTemplateEnum}" model="@{emailTemplateController.emailTemplateEnum}"
itemRenderer="@{emailTemplateController.emailTemplateEnumRenderer}" itemRenderer="@{emailTemplateController.emailTemplateEnumRenderer}"
selectedItem="@{emailTemplateController.selectedEmailTemplateEnum}"/> selectedItem="@{emailTemplateController.selectedEmailTemplateEnum}"/>
</row> </row>
<row> <row>
<label value="${i18n:_('E-mail subject')}"/> <label value="${i18n:_('E-mail subject')}"/>
<textbox id="subjectTextbox" <textbox id="subjectTextbox"
width="400px;" /> width="400px;" />
</row> </row>
<row> <row>
<label value="${i18n:_('Template contents')}"/> <label value="${i18n:_('Template contents')}"/>
<textbox id="contentsTextbox" <textbox id="contentsTextbox"
rows="15" width="400px;" rows="15" width="400px;"
tabindex="11"/> tabindex="11"/>
<groupbox closable="false" width="270px"> <groupbox closable="false" width="270px">
<caption label="${i18n:_('Possible content keywords')}"/> <caption label="${i18n:_('Possible content keywords')}"/>
<grid width="250px"> <grid width="250px">
<columns> <columns>
<column label="${i18n:_('Keyword')}"/> <column label="${i18n:_('Keyword')}"/>
<column label="${i18n:_('Description')}"/> <column label="${i18n:_('Description')}"/>
</columns> </columns>
<rows> <rows>
<row> <row>
<label value="{username}"/> <label value="{username}"/>
<label value="${i18n:_('Username of user')}"/> <label value="${i18n:_('Username of user')}"/>
</row> </row>
<row> <row>
<label value="{firstname}"/> <label value="{firstname}"/>
<label value="${i18n:_('First name of user')}"/> <label value="${i18n:_('First name of user')}"/>
</row> </row>
<row> <row>
<label value="{lastname}"/> <label value="{lastname}"/>
<label value="${i18n:_('Last name of user')}"/> <label value="${i18n:_('Last name of user')}"/>
</row> </row>
<row> <row>
<label value="{project}"/> <label value="{project}"/>
<label value="${i18n:_('Name of project')}"/> <label value="${i18n:_('Name of project')}"/>
</row> </row>
<row> <row>
<label value="{resource}"/> <label value="{resource}"/>
<label value="${i18n:_('Name of resource')}"/> <label value="${i18n:_('Name of resource')}"/>
</row> </row>
<row> <row>
<label value="{task}"/> <label value="{task}"/>
<label value="${i18n:_('Name of task')}"/> <label value="${i18n:_('Name of task')}"/>
</row> </row>
<row> <row>
<label value="{url}"/> <label value="{url}"/>
<label value="${i18n:_('Welcome page')}"/> <label value="${i18n:_('Welcome page')}"/>
</row> </row>
</rows> </rows>
</grid> </grid>
</groupbox> </groupbox>
</row> </row>
</rows> </rows>
</grid> </grid>
</groupbox> </groupbox>
</tabpanel> </tabpanel>
</tabpanels> </tabpanels>
</tabbox> </tabbox>
<button onClick="emailTemplateController.save()" autodisable="self" label="${i18n:_('Save')}" sclass="save-button global-action"/> <button onClick="emailTemplateController.save()" autodisable="self" label="${i18n:_('Save')}"
<button onClick="emailTemplateController.cancel()" label="${i18n:_('Cancel')}" sclass="cancel-button global-action"/> sclass="save-button global-action"/>
<button onClick="emailTemplateController.cancel()" label="${i18n:_('Cancel')}"
sclass="cancel-button global-action"/>
</window> </window>
</zk> </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())); assertThat(response.getStatus(), equalTo(Status.OK.getStatusCode()));
try { try {
/*
* Flush is needed because
* before there were errors that after removing object some references were still present.
*/
sessionFactory.getCurrentSession().flush();
orderElementDAO.findByCode(codeToRemove); orderElementDAO.findByCode(codeToRemove);
} catch (InstanceNotFoundException e) { } catch (InstanceNotFoundException e) {
assertTrue(true); assertTrue(true);

View file

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

58
pom.xml
View file

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