diff --git a/HACKING.rst b/HACKING.rst
index 8326ba0b9..082212cb7 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -208,10 +208,6 @@ openSUSE
Microsoft Windows
~~~~~~~~
-* Download and install latest Java Runtime Environment 7u79 (JRE7u79)::
-
- # http://www.oracle.com/technetwork/java/javase/downloads/jre7-downloads-1880261.html
-
* Download and install latest Java Development Kit 7u80 (JDK7u80)::
# http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html
@@ -244,13 +240,31 @@ Microsoft Windows
CREATE USER libreplan WITH PASSWORD 'libreplan';
GRANT ALL PRIVILEGES ON DATABASE libreplan TO libreplan;
+* Download and install Git
- REVOKE ALL
- ON ALL TABLES IN SCHEMA public
- FROM PUBLIC;
- GRANT SELECT, INSERT, UPDATE, DELETE
- ON ALL TABLES IN SCHEMA public
- TO libreplan;
+ # https://git-scm.com/download/win
+
+* Download Maven
+
+ # https://maven.apache.org/download.cgi
+
+.. WARNING::
+
+ Check if latest Maven version is compatible with your JDK
+
+* Connect to database::
+
+ # Go to PostgreSQL bin folder and command window from here
+ # psql -U postgres
+
+* Use SQL sentences::
+
+ CREATE DATABASE libreplandev;
+ CREATE DATABASE libreplandevtest;
+
+ CREATE USER libreplan WITH PASSWORD 'libreplan';
+
+ GRANT ALL PRIVILEGES ON DATABASE libreplan TO libreplan;
* Restore PostgreSQL dump - scripts/database/postgresql_1.4.1.backup::
@@ -279,6 +293,33 @@ Microsoft Windows
# Possible location: C:\Program Files\Apache Software Foundation\Tomcat 6.0\bin\Tomcat6.exe
* Go to http://localhost:8080/libreplan
+=======
+* Restore PostgreSQL dump - scripts/database/postgresql_1.4.1.backup
+
+* Download source code::
+
+ # Open GitBash
+ # git clone https://github.com/LibrePlan/libreplan.git
+
+* Set JAVA_HOME environment variable::
+
+ # You need to set it to your JDK installed directory (e.g. C:\Program Files\Java\jdk1.7.0_80)
+
+* Add path of unpacked distributions bin directory of Maven to 'Path' environment variable
+
+ # (e.g. C:\Program Files\apache-maven-3.3.3\bin)
+
+* Compile project::
+
+ # cd libreplan
+ # mvn clean install
+
+* Launch application::
+
+ # cd libreplan-webapp
+ # mvn jetty:run
+
+* Go to http://localhost:8080/libreplan-webapp/
CutyCapt compilation
@@ -509,6 +550,9 @@ example:
mvn -Ddefault.passwordsControl=false -Ddefault.exampleUsersDisabled=false clean install
+* Set *default.emailSendingEnabled* to false::
+
+ mvn -Ddefault.emailSendingEnabled=false clean install
Tests
-----
diff --git a/INSTALL.rst b/INSTALL.rst
index 93be682a6..ab8a3d74b 100644
--- a/INSTALL.rst
+++ b/INSTALL.rst
@@ -117,6 +117,11 @@ Instructions depending on the distribution:
If you have memory problems review the section `Fix memory errors`_.
+Microsoft Windows
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+
RPM Packages
~~~~~~~~~~~~
@@ -316,6 +321,78 @@ openSUSE
* Go to http://localhost:8080/libreplan/
+Microsoft Windows
+~~~~~~~~~~~
+
+Instructions:
+
+* Download and install latest Java Runtime Environment 7u79 (JRE7u79)::
+
+ # http://www.oracle.com/technetwork/java/javase/downloads/jre7-downloads-1880261.html
+
+* Download and install latest PostgreSQL database::
+
+ # http://www.enterprisedb.com/products-services-training/pgdownload#windows
+
+* Download and install Apache Tomcat 6::
+
+ # http://tomcat.apache.org/download-60.cgi
+
+.. NOTE::
+
+ In JDK folder there is JRE folder
+
+* Set up JDBC41 PostgreSQL Driver::
+
+ # Download latest driver: https://jdbc.postgresql.org/download.html
+ # Copy downloaded *.jar file to JRE location: (e.g. C:\Program Files\Java\jre7\lib\ext)
+
+* Download latest ``.war`` file from SourceForge.net (for PostgreSQL) and rename it to libreplan.war::
+
+ # http://sourceforge.net/projects/libreplan/files/LibrePlan/
+
+* Create database::
+
+ CREATE DATABASE libreplan;
+
+* Use SQL sentences::
+
+ CREATE USER libreplan WITH PASSWORD 'libreplan';
+ GRANT ALL PRIVILEGES ON DATABASE libreplan TO libreplan;
+
+ REVOKE ALL
+ ON ALL TABLES IN SCHEMA public
+ FROM PUBLIC;
+ GRANT SELECT, INSERT, UPDATE, DELETE
+ ON ALL TABLES IN SCHEMA public
+ TO libreplan;
+
+* Restore PostgreSQL dump - scripts/database/postgresql_1.4.1.backup::
+
+* Create an Environment Variable JRE_HOME
+
+# You need to set it to your JRE installed directory
+
+* Configure Apache Tomcat Server
+
+ # Put libreplan.war file to Apache Tomcat webapps folder (e.g. C:\Program Files\Apache Software Foundation\Tomcat 6.0\webapps\)
+ # Go to localhost folder (e.g. C:\Program Files\Apache Software Foundation\Tomcat 6.0\conf\Catalina\localhost\) and create there libreplan.xml file with this lines of code:
+
+
+
+
+
+
+* Start Apache Tomcat server
+
+ # Example location: C:\Program Files\Apache Software Foundation\Tomcat 6.0\bin\Tomcat6.exe
+
+* Go to http://localhost:8080/libreplan
Logs
----
diff --git a/doc/src/technical/howto-start-development-with-intellij-idea.rst b/doc/src/technical/howto-start-development-with-intellij-idea.rst
index 00f341db4..d33d7c3a5 100644
--- a/doc/src/technical/howto-start-development-with-intellij-idea.rst
+++ b/doc/src/technical/howto-start-development-with-intellij-idea.rst
@@ -1,103 +1,103 @@
-How To Start Development With JetBrains Intellij IDEA
-======================================================
-
-.. sectnum::
-
-:Author: Perebykivskiy Vova
-:Contact: vova@libreplan-enterprise.com
-:Date: 09/09/2015
-:Copyright:
- Some rights reserved. This document is distributed under the Creative
- Commons Attribution-ShareAlike 3.0 licence, available in
- http://creativecommons.org/licenses/by-sa/3.0/.
-:Abstract:
- Quick guide to start the development of LibrePlan_ using JetBrains Intellij IDEA_ IDE.
- As this is the most common way of work among LibrePlan developers team.
-
-.. contents:: Table of Contents
-
-Download LibrePlan source code
-------------------------------
-
-* You need to download LibrePlan_ source code to start hacking on it. You have two
-options:
-
-a) Clone Git repository (recommended)::
-
- git clone git://github.com/LibrePlan/libreplan.git
-
-b) Download last version source code::
-
- http://sourceforge.net/projects/libreplan/files/LibrePlan/libreplan_*.tar.gz
-
-* Download latest libreplan_*.war file for your database (PostgreSQL or MySQL)
-
- http://sourceforge.net/projects/libreplan/files/LibrePlan/
-
-You should review ``HACKING`` file to check that you have installed all the
-requirements.
-
-Import LibrePlan project
-------------------------
-* Run Intellij IDEA
-
-* Select Import Project
-
-* Select directory with source code of Libreplan
-
- # e.g. C\Users\PC-User\IdeaProjects\libreplan
-
-* Select *Import project from external model* > *Maven* and click *Next*
-
-* Then leave all as default
-
-* Then select profiles: dev and for PostgreSQL users - postgresql / Mysql users - mysql
-
-* Then leave all by default
-
-* Then choose your JDK(SDK), 1.7 strongly prefered
-
-* Then define project name or leave default name
-
-
-Configure project to run
-------------------------
-
-* Go to *Run* > *Edit Configurations...*
-
-* Create a new *Maven Build* called *MavenConfig*
-
-* Change the following values:
-
- * Working directory: Choose ``libreplan-webapp`` folder in your workspace
- * Command line: ``jetty:stop jetty:run``
- * Profiles (optional): ``-userguide -reports -i18n``
- (to disable userguide,reports and i18n profiles to save compilation time
- as they are not mandatory to run LibrePlan)
- * Mark the following checkboxes (recommended):
-
-* Resolve Workspace artifacts
-
-* In "Before launch" section choose "+" and add Build Artifact (war file)
-
- By the next compilation you may remove this Build Artifact from configuration
-
-* Click *Run* and application will be available at
- http://localhost:8080/libreplan-webapp/
-
-Develop LibrePlan in Intellij IDEA using MySQL
-----------------------------------------
-
-* This tutorial works properly with PostgreSQL, but if you want to develop
- LibrePlan using MySQL you have to do 2 small changes:
-
- * In section `Configure project to run`_ you have to set the *Profiles* to:
- ``-dev -mysql -userguide -reports -i18n``
-
-* Remember that the three last profiles that are being disabled is just to save
- compilation time and not mandatory. However, to develop using MySQL you have
- to set at least the first two: ``-dev`` and ``-mysql``.
-
-
-.. _LibrePlan: http://www.libreplan.com/
-.. _JetBrains Intellij IDEA: https://www.jetbrains.com/idea/
\ No newline at end of file
+======================================================
+How To Start Development With JetBrains Intellij IDEA
+======================================================
+
+.. sectnum::
+
+:Author: Perebykivskiy Vova
+:Contact: vova@libreplan-enterprise.com
+:Date: 09/09/2015
+:Copyright:
+ Some rights reserved. This document is distributed under the Creative
+ Commons Attribution-ShareAlike 3.0 licence, available in
+ http://creativecommons.org/licenses/by-sa/3.0/.
+:Abstract:
+ Quick guide to start the development of LibrePlan_ using JetBrains Intellij IDEA_ IDE.
+ As this is the most common way of work among LibrePlan developers team.
+
+.. contents:: Table of Contents
+
+Download LibrePlan source code
+------------------------------
+
+* You need to download LibrePlan_ source code to start hacking on it. You have two
+options:
+
+a) Clone Git repository (recommended)::
+
+ git clone git://github.com/LibrePlan/libreplan.git
+
+b) Download last version source code::
+
+ http://sourceforge.net/projects/libreplan/files/LibrePlan/libreplan_*.tar.gz
+
+* Download latest libreplan_*.war file for your database (PostgreSQL or MySQL)
+
+ http://sourceforge.net/projects/libreplan/files/LibrePlan/
+
+You should review ``HACKING`` file to check that you have installed all the
+requirements.
+
+Import LibrePlan project
+------------------------
+* Run Intellij IDEA
+
+* Select Import Project
+
+* Select directory with source code of Libreplan
+
+ # e.g. C\Users\PC-User\IdeaProjects\libreplan
+
+* Select *Import project from external model* > *Maven* and click *Next*
+
+* Then leave all as default
+
+* Then select profiles: dev and for PostgreSQL users - postgresql / Mysql users - mysql
+
+* Then leave all by default
+
+* Then choose your JDK(SDK), 1.7 strongly prefered
+
+* Then define project name or leave default name
+
+
+Configure project to run
+------------------------
+
+* Go to *Run* > *Edit Configurations...*
+
+* Create a new *Maven Build* called *MavenConfig*
+
+* Change the following values:
+
+ * Working directory: Choose ``libreplan-webapp`` folder in your workspace
+ * Command line: ``jetty:stop jetty:run``
+ * Profiles (optional): ``-userguide -reports -i18n``
+ (to disable userguide,reports and i18n profiles to save compilation time
+ as they are not mandatory to run LibrePlan)
+ * Mark the following checkboxes (recommended):
+
+* Resolve Workspace artifacts
+
+* In "Before launch" section choose "+" and add Build Artifact (war file)
+
+ By the next compilation you may remove this Build Artifact from configuration
+
+* Click *Run* and application will be available at
+ http://localhost:8080/libreplan-webapp/
+
+Develop LibrePlan in Intellij IDEA using MySQL
+----------------------------------------
+
+* This tutorial works properly with PostgreSQL, but if you want to develop
+ LibrePlan using MySQL you have to do 2 small changes:
+
+ * In section `Configure project to run`_ you have to set the *Profiles* to:
+ ``-dev -mysql -userguide -reports -i18n``
+
+* Remember that the three last profiles that are being disabled is just to save
+ compilation time and not mandatory. However, to develop using MySQL you have
+ to set at least the first two: ``-dev`` and ``-mysql``.
+
+
+.. _LibrePlan: http://www.libreplan.com/
diff --git a/doc/src/user/en/18-connectors.rst b/doc/src/user/en/18-connectors.rst
index 7206ec0fa..ca302cb57 100644
--- a/doc/src/user/en/18-connectors.rst
+++ b/doc/src/user/en/18-connectors.rst
@@ -4,7 +4,7 @@ Connectors
.. contents::
Connectors are Libreplan client applications that could be used to communicate with (web) servers to get
-data, process and store them. At this moment there are two connectors, JIRA connector and Tim Enterprise Connector.
+data, process and store them. At this moment there are three connectors, JIRA connector, Tim Enterprise Connector and E-mail Connector.
Configuration
=============
@@ -171,9 +171,9 @@ in Tim Enterprise server.
Scheduling export
------------------
-Export process can also take place through the scheduler. Go to ``Job scheduling`` screen.
+Export process can also take place through the scheduler. Go to ``Job Scheduling`` screen.
In that screen you can configure a Tim Export ``job``. The ``job`` searches for last exported
-time sheets in the database and re-export them accordingly. see also the Scheduler manual.
+time sheets in the database and re-export them accordingly. See also the Scheduler manual.
Import
------
@@ -211,5 +211,66 @@ assumed to be a valid ``Exception type`` but the total duration is the sum of al
Contrary to the Libreplan, in Tim Enterprise, the ``total duration`` in case that the worker is on holiday means the worker is
not available for that ``total duration``. But in Libreplan if the worker is on holiday the total duration should be ``Zero``.
-The Tim connector also takes care of this translation.
+The Tim connector also takes care of this translation.
+
+E-mail connector
+==============
+E-mail is a method of exchanging digital messages from an author to one or more recipients.
+
+E-mail connector can be used to set Simple Main Transfer Protocol (SMTP) server connection properties.
+
+The *E-mail connector* should be configured properly before being used.
+
+Configuration
+-------------
+
+From the configuration's ``Main Settings`` screen choose the tab ``Connectors``.
+In the connectors screen select the E-mail connector from the ``pull-down`` list. A ``property editor screen``
+is displayed now.
+
+In this screen you can configure the following property values:
+
+* ``Activated``: Y/N, whether you want to use the E-mail connector or not. Default is ``N``.
+* ``Protocol``: type of SMTP protocol.
+* ``Host``: the absolute path to SMTP server.
+* ``Port``: port of SMTP server.
+* ``From address``: e-mail address of messages sender.
+* ``Username``: username for SMTP server.
+* ``Password``: password for SMTP server.
+
+Finally click the ``Test connection`` button to test if you are able to connect to
+SMTP server and that your configurations are right.
+
+Edit E-mail template
+--------------------
+
+From the project window ``Configuration`` and then ``Edit E-mail Templates`` you are able to modify E-mail templates of
+messages.
+
+You are able to choose:
+
+* Template language
+* Template type
+* E-mail subject
+* Template contents
+
+You need to specify language because web application will send e-mail to user in language that user have chosen in
+preferences.
+You need to choose template type, type is user role, it means that this e-mail will be send only to users who are in\
+selected role (type).
+You need to set e-mail subject. Subject - a brief summary of the topic of the message.
+You need to set e-mail contents. Any information that you want to send to user. Also there are some keywords that you
+may use in message; web application will parse it and set a new value instead of keyword.
+
+Scheduling e-mails
+------------------
+
+Sending e-mails process can take place only through the scheduler. Go to ``Configuration`` then ``Job Scheduling``
+screen.
+In that screen you can configure a e-mail sending ``job``. The ``job`` is taking a list of e-mail notifications,
+gathering data and sending it to user`s e-mail. See also the Scheduler manual.
+
+
+.. NOTE::
+The success or failure information would be displayed in pop-up window.
\ No newline at end of file
diff --git a/libreplan-business/src/main/java/org/libreplan/business/common/Configuration.java b/libreplan-business/src/main/java/org/libreplan/business/common/Configuration.java
index 80c084ffd..90709ff25 100644
--- a/libreplan-business/src/main/java/org/libreplan/business/common/Configuration.java
+++ b/libreplan-business/src/main/java/org/libreplan/business/common/Configuration.java
@@ -26,16 +26,19 @@ import org.apache.commons.lang.BooleanUtils;
/**
* This is a singleton that contains the compilation options passed from Maven.
*
- * Currently we have two options:
+ * Currently we have three options:
*
*
Enable/Disable the warning changing default password
*
Enable/Disable default users (such as wsreader, wswriter,
* wssubcontracting, manager, hresources, outsourcing and reports)
+ *
Enable/Disable E-mail sending functionality
*
*
* @author Susana Montes Pedreira
* @author Manuel Rego Casasnovas
+ * @author Vova Perebykivskiy
*/
+
public class Configuration {
private static final Configuration singleton = new Configuration();
@@ -44,6 +47,8 @@ public class Configuration {
private Boolean exampleUsersDisabled;
+ private Boolean emailSendingEnabled;
+
private Configuration() {
}
@@ -59,22 +64,13 @@ public class Configuration {
return singleton.getDefaultPasswordsControl() != null ? singleton
.getDefaultPasswordsControl() : true;
}
-
+ public Boolean getDefaultPasswordsControl() {
+ return defaultPasswordsControl;
+ }
public void setDefaultPasswordsControl(Boolean defaultPasswordsControl) {
this.defaultPasswordsControl = defaultPasswordsControl;
}
- public Boolean getDefaultPasswordsControl() {
- return defaultPasswordsControl;
- }
-
- public void setExampleUsersDisabled(Boolean exampleUsersDisabled) {
- this.exampleUsersDisabled = exampleUsersDisabled;
- }
-
- public Boolean getExampleUsersDisabled() {
- return exampleUsersDisabled;
- }
/**
* Returns the value of example users disabled compilation option
@@ -82,5 +78,25 @@ public class Configuration {
public static boolean isExampleUsersDisabled() {
return BooleanUtils.isNotFalse(singleton.getExampleUsersDisabled());
}
+ public Boolean getExampleUsersDisabled() {
+ return exampleUsersDisabled;
+ }
+ public void setExampleUsersDisabled(Boolean exampleUsersDisabled) {
+ this.exampleUsersDisabled = exampleUsersDisabled;
+ }
+
+
+ /**
+ * Returns the value of E-mail sending disabled compilation option
+ */
+ public static boolean isEmailSendingEnabled(){
+ return BooleanUtils.isNotFalse(singleton.getEmailSendingEnabled());
+ }
+ public Boolean getEmailSendingEnabled(){
+ return emailSendingEnabled;
+ }
+ public void setEmailSendingEnabled(Boolean emailSendingEnabled){
+ this.emailSendingEnabled = emailSendingEnabled;
+ }
}
diff --git a/libreplan-business/src/main/java/org/libreplan/business/common/daos/IntegrationEntityDAO.java b/libreplan-business/src/main/java/org/libreplan/business/common/daos/IntegrationEntityDAO.java
index 02dc456b8..3d5b913d0 100644
--- a/libreplan-business/src/main/java/org/libreplan/business/common/daos/IntegrationEntityDAO.java
+++ b/libreplan-business/src/main/java/org/libreplan/business/common/daos/IntegrationEntityDAO.java
@@ -28,6 +28,7 @@ import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.libreplan.business.common.IntegrationEntity;
import org.libreplan.business.common.exceptions.InstanceNotFoundException;
+import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
diff --git a/libreplan-business/src/main/java/org/libreplan/business/common/entities/JobClassNameEnum.java b/libreplan-business/src/main/java/org/libreplan/business/common/entities/JobClassNameEnum.java
index 038d7c413..26f4f041e 100644
--- a/libreplan-business/src/main/java/org/libreplan/business/common/entities/JobClassNameEnum.java
+++ b/libreplan-business/src/main/java/org/libreplan/business/common/entities/JobClassNameEnum.java
@@ -29,8 +29,9 @@ package org.libreplan.business.common.entities;
public enum JobClassNameEnum {
IMPORT_ROSTER_FROM_TIM_JOB("org.libreplan.importers", "ImportRosterFromTimJob"),
- EXPORT_TIMESHEET_TO_TIM_JOB("org.libreplan.importers","ExportTimesheetToTimJob"),
- SYNC_ORDERELEMENTS_WITH_JIRA_ISSUES_JOB("org.libreplan.importers","JiraOrderElementSynchronizerJob");
+ EXPORT_TIMESHEET_TO_TIM_JOB("org.libreplan.importers", "ExportTimesheetToTimJob"),
+ SYNC_ORDERELEMENTS_WITH_JIRA_ISSUES_JOB("org.libreplan.importers", "JiraOrderElementSynchronizerJob"),
+ SEND_EMAIL_JOB("org.libreplan.importers", "SendEmailJob");
private String packageName;
private String name;
diff --git a/libreplan-business/src/main/java/org/libreplan/business/common/entities/PredefinedConnectorProperties.java b/libreplan-business/src/main/java/org/libreplan/business/common/entities/PredefinedConnectorProperties.java
index ef0b84200..9611c0384 100644
--- a/libreplan-business/src/main/java/org/libreplan/business/common/entities/PredefinedConnectorProperties.java
+++ b/libreplan-business/src/main/java/org/libreplan/business/common/entities/PredefinedConnectorProperties.java
@@ -27,6 +27,7 @@ import static org.libreplan.business.i18n.I18nHelper._;
*
* @author Miciele Ghiorghis
* @author Manuel Rego Casasnovas
+ * @author Vova Perebykivskiy
*/
public class PredefinedConnectorProperties {
@@ -51,4 +52,12 @@ public class PredefinedConnectorProperties {
*/
public static final String JIRA_CODE_PREFIX = "JIRA-";
+ // Specific for E-mail
+ public static String PROTOCOL = _("Protocol");
+ public static String HOST = _("Host");
+ public static String PORT = _("Port");
+ public static String EMAIL_SENDER = _("From address (no reply)");
+ public static String EMAIL_USERNAME = _("Username (optional)");
+ public static String EMAIL_PASSWORD = _("Password (optional)");
+
}
diff --git a/libreplan-business/src/main/java/org/libreplan/business/common/entities/PredefinedConnectors.java b/libreplan-business/src/main/java/org/libreplan/business/common/entities/PredefinedConnectors.java
index b51adc8a1..1d44db2ad 100644
--- a/libreplan-business/src/main/java/org/libreplan/business/common/entities/PredefinedConnectors.java
+++ b/libreplan-business/src/main/java/org/libreplan/business/common/entities/PredefinedConnectors.java
@@ -28,6 +28,7 @@ import java.util.List;
*
* @author Miciele Ghiorghis
* @author Manuel Rego Casasnovas
+ * @author Vova Perebykivskiy
*/
public enum PredefinedConnectors {
@@ -50,7 +51,16 @@ public enum PredefinedConnectors {
ConnectorProperty
.create(PredefinedConnectorProperties.JIRA_LABELS, ""),
ConnectorProperty.create(
- PredefinedConnectorProperties.JIRA_HOURS_TYPE, "Default"));
+ PredefinedConnectorProperties.JIRA_HOURS_TYPE, "Default")),
+ EMAIL("E-mail",
+ ConnectorProperty.create(PredefinedConnectorProperties.ACTIVATED, "N"),
+ ConnectorProperty.create(PredefinedConnectorProperties.PROTOCOL, ""),
+ ConnectorProperty.create(PredefinedConnectorProperties.HOST, ""),
+ ConnectorProperty.create(PredefinedConnectorProperties.PORT, ""),
+ ConnectorProperty.create(PredefinedConnectorProperties.EMAIL_USERNAME, ""),
+ ConnectorProperty.create(PredefinedConnectorProperties.EMAIL_PASSWORD, "")
+
+ );
private String name;
private List properties;
diff --git a/libreplan-business/src/main/java/org/libreplan/business/email/daos/EmailNotificationDAO.java b/libreplan-business/src/main/java/org/libreplan/business/email/daos/EmailNotificationDAO.java
new file mode 100644
index 000000000..e67a9047b
--- /dev/null
+++ b/libreplan-business/src/main/java/org/libreplan/business/email/daos/EmailNotificationDAO.java
@@ -0,0 +1,54 @@
+/*
+ * This file is part of LibrePlan
+ *
+ * Copyright (C) 2015 LibrePlan
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package org.libreplan.business.email.daos;
+
+import org.libreplan.business.common.daos.GenericDAOHibernate;
+import org.libreplan.business.email.entities.EmailNotification;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * Dao for {@link EmailNotification}
+ *
+ * Created by
+ * @author Vova Perebykivskiy
+ * on 19.10.15.
+ */
+@Repository
+public class EmailNotificationDAO extends GenericDAOHibernate implements IEmailNotificationDAO {
+
+ @Override
+ public List getAll() {
+ return list(EmailNotification.class);
+ }
+
+ @Override
+ public boolean deleteAll() {
+ List notifications = list(EmailNotification.class);
+ for (Object item : notifications){
+ getSession().delete(item);
+ }
+
+ if ( list(EmailNotification.class).size() == 0 ) return true;
+ return false;
+ }
+
+}
diff --git a/libreplan-business/src/main/java/org/libreplan/business/email/daos/EmailTemplateDAO.java b/libreplan-business/src/main/java/org/libreplan/business/email/daos/EmailTemplateDAO.java
new file mode 100644
index 000000000..df4751ff5
--- /dev/null
+++ b/libreplan-business/src/main/java/org/libreplan/business/email/daos/EmailTemplateDAO.java
@@ -0,0 +1,90 @@
+/*
+ * This file is part of LibrePlan
+ *
+ * Copyright (C) 2015 LibrePlan
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package org.libreplan.business.email.daos;
+
+import org.libreplan.business.common.daos.GenericDAOHibernate;
+import org.libreplan.business.email.entities.EmailTemplate;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * DAO for {@link EmailTemplate}
+ *
+ * Created by
+ * @author Vova Perebykivskiy
+ * on 24.09.15.
+ */
+@Repository
+public class EmailTemplateDAO extends GenericDAOHibernate implements IEmailTemplateDAO{
+
+ @Override
+ public List getAll() {
+ return list(EmailTemplate.class);
+ }
+
+ @Override
+ public String initializeContent() {
+ try{
+ List emailTemplates = list(EmailTemplate.class);
+ for ( int i = 0; i < emailTemplates.size(); i++)
+ // language.ordinal.equals(3) - English
+ if ( emailTemplates.get(i).getType().ordinal() == 0 && emailTemplates.get(i).getLanguage().ordinal() == 3)
+ return emailTemplates.get(i).getContent();
+ }catch (Exception e){}
+
+ return " ";
+ }
+
+ @Override
+ public String initializeSubject() {
+ try{
+ List emailTemplates = list(EmailTemplate.class);
+ for ( int i = 0; i < emailTemplates.size(); i++)
+ // language.ordinal.equals(3) - English
+ if ( emailTemplates.get(i).getType().ordinal() == 0 && emailTemplates.get(i).getLanguage().ordinal() == 3)
+ return emailTemplates.get(i).getSubject();
+ }catch (Exception e){}
+
+ return " ";
+ }
+
+
+ @Override
+ public String getContentBySelectedLanguage(int languageOrdinal, int emailTemplateTypeOrdinal) {
+ for (int i = 0; i < list(EmailTemplate.class).size(); i++)
+ if (list(EmailTemplate.class).get(i).getLanguage().ordinal() == languageOrdinal &&
+ // emailTemplateTypeOrdinal + 1, because first value is 0
+ list(EmailTemplate.class).get(i).getType().ordinal() == emailTemplateTypeOrdinal + 1)
+ return list(EmailTemplate.class).get(i).getContent();
+ return "";
+ }
+
+ @Override
+ public String getContentBySelectedTemplate(int emailTemplateTypeOrdinal, int languageOrdinal) {
+ for (int i = 0; i < list(EmailTemplate.class).size(); i++)
+ // emailTemplateTypeOrdinal + 1, because first value is 0
+ if ( list(EmailTemplate.class).get(i).getType().ordinal() == emailTemplateTypeOrdinal + 1 &&
+ list(EmailTemplate.class).get(i).getLanguage().ordinal() == languageOrdinal )
+ return list(EmailTemplate.class).get(i).getContent();
+ return "";
+ }
+
+}
diff --git a/libreplan-business/src/main/java/org/libreplan/business/email/daos/IEmailNotificationDAO.java b/libreplan-business/src/main/java/org/libreplan/business/email/daos/IEmailNotificationDAO.java
new file mode 100644
index 000000000..5b4a545a1
--- /dev/null
+++ b/libreplan-business/src/main/java/org/libreplan/business/email/daos/IEmailNotificationDAO.java
@@ -0,0 +1,37 @@
+/*
+ * This file is part of LibrePlan
+ *
+ * Copyright (C) 2015 LibrePlan
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package org.libreplan.business.email.daos;
+
+import org.libreplan.business.common.daos.IGenericDAO;
+import org.libreplan.business.email.entities.EmailNotification;
+
+import java.util.List;
+
+/**
+ * Contract for {@link EmailNotificationDAO}
+ *
+ * Created by
+ * @author Vova Perebykivskiy
+ * on 19.10.15.
+ */
+public interface IEmailNotificationDAO extends IGenericDAO {
+ List getAll();
+ boolean deleteAll();
+}
diff --git a/libreplan-business/src/main/java/org/libreplan/business/email/daos/IEmailTemplateDAO.java b/libreplan-business/src/main/java/org/libreplan/business/email/daos/IEmailTemplateDAO.java
new file mode 100644
index 000000000..57acd30a9
--- /dev/null
+++ b/libreplan-business/src/main/java/org/libreplan/business/email/daos/IEmailTemplateDAO.java
@@ -0,0 +1,44 @@
+/*
+ * This file is part of LibrePlan
+ *
+ * Copyright (C) 2015 LibrePlan
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package org.libreplan.business.email.daos;
+
+import org.libreplan.business.common.daos.IGenericDAO;
+import org.libreplan.business.email.entities.EmailTemplate;
+
+import java.util.List;
+
+/**
+ * DAO interface for the EmailTemplate entity.
+ * Contract for {@link EmailTemplateDAO}
+ *
+ * Created by
+ * @author Vova Perebykivskiy
+ * on 29.09.15.
+ */
+public interface IEmailTemplateDAO extends IGenericDAO{
+
+ List getAll();
+
+ String initializeContent();
+ String initializeSubject();
+
+ String getContentBySelectedLanguage(int languageOrdinal, int emailTemplateTypeOrdinal);
+ String getContentBySelectedTemplate(int emailTemplateTypeOrdinal, int languageOrdinal);
+}
diff --git a/libreplan-business/src/main/java/org/libreplan/business/email/entities/EmailNotification.java b/libreplan-business/src/main/java/org/libreplan/business/email/entities/EmailNotification.java
new file mode 100644
index 000000000..817fb4dc2
--- /dev/null
+++ b/libreplan-business/src/main/java/org/libreplan/business/email/entities/EmailNotification.java
@@ -0,0 +1,85 @@
+/*
+ * This file is part of LibrePlan
+ *
+ * Copyright (C) 2015 LibrePlan
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package org.libreplan.business.email.entities;
+
+import org.libreplan.business.common.BaseEntity;
+
+import org.libreplan.business.planner.entities.TaskElement;
+import org.libreplan.business.resources.entities.Resource;
+
+import java.util.Date;
+
+/**
+ * EmailNotification entity representing table: notification_queue.
+ * This class is intended to work as a Hibernate component.
+ * It represents the Email notification to be send to user.
+ *
+ * Created by
+ * @author Vova Perebykivskiy
+ * on 19.10.15.
+ */
+public class EmailNotification extends BaseEntity {
+
+ private EmailTemplateEnum type;
+
+ private Date updated;
+
+ private Resource resource;
+
+ private TaskElement task;
+
+ private TaskElement project;
+
+
+ public EmailTemplateEnum getType() {
+ return type;
+ }
+ public void setType(EmailTemplateEnum type) {
+ this.type = type;
+ }
+
+ public Date getUpdated() {
+ return updated;
+ }
+ public void setUpdated(Date updated) {
+ this.updated = updated;
+ }
+
+ public Resource getResource() {
+ return resource;
+ }
+ public void setResource(Resource resource) {
+ this.resource = resource;
+ }
+
+ public TaskElement getTask() {
+ return task;
+ }
+ public void setTask(TaskElement task) {
+ this.task = task;
+ }
+
+ public TaskElement getProject() {
+ return project;
+ }
+ public void setProject(TaskElement project) {
+ this.project = project;
+ }
+}
diff --git a/libreplan-business/src/main/java/org/libreplan/business/email/entities/EmailTemplate.java b/libreplan-business/src/main/java/org/libreplan/business/email/entities/EmailTemplate.java
new file mode 100644
index 000000000..a4f6d2c10
--- /dev/null
+++ b/libreplan-business/src/main/java/org/libreplan/business/email/entities/EmailTemplate.java
@@ -0,0 +1,71 @@
+/*
+ * This file is part of LibrePlan
+ *
+ * Copyright (C) 2015 LibrePlan
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package org.libreplan.business.email.entities;
+
+import org.libreplan.business.common.BaseEntity;
+import org.libreplan.business.settings.entities.Language;
+
+/**
+ * EmailTemplate entity, represents a template that LibrePlan user may use.
+ * This class is intended to work as a Hibernate component.
+ * It represents the E-mail template to be modified by admin and send to user.
+ *
+ * Created by
+ * @author Vova Perebykivskiy
+ * on 29.09.15.
+ */
+public class EmailTemplate extends BaseEntity {
+
+ private EmailTemplateEnum type = EmailTemplateEnum.TEMPLATE_TASK_ASSIGNED_TO_RESOURCE;
+
+ private Language language = Language.ENGLISH_LANGUAGE;
+
+ private String content;
+
+ private String subject;
+
+ public EmailTemplateEnum getType() {
+ return type;
+ }
+ public void setType(EmailTemplateEnum type) {
+ this.type = type;
+ }
+
+ public Language getLanguage() {
+ return language;
+ }
+ public void setLanguage(Language language) {
+ this.language = language;
+ }
+
+ public String getContent() {
+ return content;
+ }
+ public void setContent(String content) {
+ this.content = content;
+ }
+
+ public String getSubject() {
+ return subject;
+ }
+ public void setSubject(String subject) {
+ this.subject = subject;
+ }
+}
diff --git a/libreplan-business/src/main/java/org/libreplan/business/email/entities/EmailTemplateEnum.java b/libreplan-business/src/main/java/org/libreplan/business/email/entities/EmailTemplateEnum.java
new file mode 100644
index 000000000..1402115fa
--- /dev/null
+++ b/libreplan-business/src/main/java/org/libreplan/business/email/entities/EmailTemplateEnum.java
@@ -0,0 +1,47 @@
+/*
+ * This file is part of LibrePlan
+ *
+ * Copyright (C) 2015 LibrePlan
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package org.libreplan.business.email.entities;
+
+import static org.libreplan.business.i18n.I18nHelper._;
+
+/**
+ * Available E-mail templates.
+ *
+ * Created by
+ * @author Vova Perebykivskiy
+ * on 28.09.15.
+ *
+ * TEMPLATE_N(_("Template N")) - for i18n
+ * TEMPLATE_A("Template A") - for general use (no internationalizing)
+ */
+public enum EmailTemplateEnum {
+
+ TEMPLATE_TASK_ASSIGNED_TO_RESOURCE(_("Task assigned to resource"));
+
+ private final String templateType;
+
+ EmailTemplateEnum(String templateType) {
+ this.templateType = templateType;
+ }
+
+ public String getTemplateType() {
+ return templateType;
+ }
+}
diff --git a/libreplan-business/src/main/java/org/libreplan/business/orders/entities/OrderStatusEnum.java b/libreplan-business/src/main/java/org/libreplan/business/orders/entities/OrderStatusEnum.java
index 9f9386ef1..70084e8f7 100644
--- a/libreplan-business/src/main/java/org/libreplan/business/orders/entities/OrderStatusEnum.java
+++ b/libreplan-business/src/main/java/org/libreplan/business/orders/entities/OrderStatusEnum.java
@@ -40,7 +40,7 @@ public enum OrderStatusEnum {
ON_HOLD(_("ON HOLD")),
FINISHED(_("FINISHED")),
CANCELLED(_("CANCELLED")),
- STORED(_("STORED"));
+ STORED(_("ARCHIVED"));
private String description;
diff --git a/libreplan-business/src/main/java/org/libreplan/business/users/bootstrap/PredefinedProfiles.java b/libreplan-business/src/main/java/org/libreplan/business/users/bootstrap/PredefinedProfiles.java
index b7c0f7fee..fbeb451a4 100644
--- a/libreplan-business/src/main/java/org/libreplan/business/users/bootstrap/PredefinedProfiles.java
+++ b/libreplan-business/src/main/java/org/libreplan/business/users/bootstrap/PredefinedProfiles.java
@@ -18,47 +18,6 @@
*/
package org.libreplan.business.users.bootstrap;
-import static org.libreplan.business.users.entities.UserRole.ROLE_CALENDARS;
-import static org.libreplan.business.users.entities.UserRole.ROLE_CALENDAR_EXCEPTION_DAYS;
-import static org.libreplan.business.users.entities.UserRole.ROLE_COMPANIES;
-import static org.libreplan.business.users.entities.UserRole.ROLE_COST_CATEGORIES;
-import static org.libreplan.business.users.entities.UserRole.ROLE_CREATE_PROJECTS;
-import static org.libreplan.business.users.entities.UserRole.ROLE_CRITERIA;
-import static org.libreplan.business.users.entities.UserRole.ROLE_EDIT_ALL_PROJECTS;
-import static org.libreplan.business.users.entities.UserRole.ROLE_ESTIMATED_PLANNED_HOURS_PER_TASK_REPORT;
-import static org.libreplan.business.users.entities.UserRole.ROLE_EXPENSES;
-import static org.libreplan.business.users.entities.UserRole.ROLE_HOURS_TYPES;
-import static org.libreplan.business.users.entities.UserRole.ROLE_HOURS_WORKED_PER_RESOURCE_REPORT;
-import static org.libreplan.business.users.entities.UserRole.ROLE_JOB_SCHEDULING;
-import static org.libreplan.business.users.entities.UserRole.ROLE_LABELS;
-import static org.libreplan.business.users.entities.UserRole.ROLE_MACHINES;
-import static org.libreplan.business.users.entities.UserRole.ROLE_MAIN_SETTINGS;
-import static org.libreplan.business.users.entities.UserRole.ROLE_MATERIALS;
-import static org.libreplan.business.users.entities.UserRole.ROLE_MATERIALS_NEED_AT_DATE_REPORT;
-import static org.libreplan.business.users.entities.UserRole.ROLE_MATERIAL_UNITS;
-import static org.libreplan.business.users.entities.UserRole.ROLE_PLANNING;
-import static org.libreplan.business.users.entities.UserRole.ROLE_PROFILES;
-import static org.libreplan.business.users.entities.UserRole.ROLE_PROGRESS_TYPES;
-import static org.libreplan.business.users.entities.UserRole.ROLE_PROJECT_COSTS_REPORT;
-import static org.libreplan.business.users.entities.UserRole.ROLE_PROJECT_STATUS_REPORT;
-import static org.libreplan.business.users.entities.UserRole.ROLE_QUALITY_FORMS;
-import static org.libreplan.business.users.entities.UserRole.ROLE_READ_ALL_PROJECTS;
-import static org.libreplan.business.users.entities.UserRole.ROLE_RECEIVED_FROM_CUSTOMERS;
-import static org.libreplan.business.users.entities.UserRole.ROLE_RECEIVED_FROM_SUBCONTRACTORS;
-import static org.libreplan.business.users.entities.UserRole.ROLE_SEND_TO_CUSTOMERS;
-import static org.libreplan.business.users.entities.UserRole.ROLE_SEND_TO_SUBCONTRACTORS;
-import static org.libreplan.business.users.entities.UserRole.ROLE_TASK_SCHEDULING_STATUS_IN_PROJECT_REPORT;
-import static org.libreplan.business.users.entities.UserRole.ROLE_TEMPLATES;
-import static org.libreplan.business.users.entities.UserRole.ROLE_TIMESHEETS;
-import static org.libreplan.business.users.entities.UserRole.ROLE_TIMESHEETS_TEMPLATES;
-import static org.libreplan.business.users.entities.UserRole.ROLE_TIMESHEET_LINES_LIST;
-import static org.libreplan.business.users.entities.UserRole.ROLE_TOTAL_WORKED_HOURS_BY_RESOURCE_IN_A_MONTH_REPORT;
-import static org.libreplan.business.users.entities.UserRole.ROLE_USER_ACCOUNTS;
-import static org.libreplan.business.users.entities.UserRole.ROLE_VIRTUAL_WORKERS;
-import static org.libreplan.business.users.entities.UserRole.ROLE_WORKERS;
-import static org.libreplan.business.users.entities.UserRole.ROLE_WORK_AND_PROGRESS_PER_PROJECT_REPORT;
-import static org.libreplan.business.users.entities.UserRole.ROLE_WORK_AND_PROGRESS_PER_TASK_REPORT;
-
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
@@ -66,16 +25,18 @@ import java.util.Set;
import org.libreplan.business.users.entities.Profile;
import org.libreplan.business.users.entities.UserRole;
+import static org.libreplan.business.users.entities.UserRole.*;
/**
* Defines the default {@link org.libreplan.business.users.entities.Profile
* Profiles}
*
* @author Manuel Rego Casasnovas
+ * @author Vova Perebykivskiy
*/
public enum PredefinedProfiles {
SYSTEMS_ADMINISTRATOR("Systems Administrator", ROLE_MAIN_SETTINGS,
- ROLE_USER_ACCOUNTS, ROLE_PROFILES, ROLE_JOB_SCHEDULING),
+ ROLE_USER_ACCOUNTS, ROLE_PROFILES, ROLE_JOB_SCHEDULING, ROLE_EDIT_EMAIL_TEMPLATES),
PROJECT_MANAGER("Project Manager", ROLE_READ_ALL_PROJECTS,
ROLE_EDIT_ALL_PROJECTS, ROLE_CREATE_PROJECTS, ROLE_PLANNING,
diff --git a/libreplan-business/src/main/java/org/libreplan/business/users/entities/UserRole.java b/libreplan-business/src/main/java/org/libreplan/business/users/entities/UserRole.java
index 9010c7b8f..dc7994017 100644
--- a/libreplan-business/src/main/java/org/libreplan/business/users/entities/UserRole.java
+++ b/libreplan-business/src/main/java/org/libreplan/business/users/entities/UserRole.java
@@ -28,21 +28,26 @@ import static org.libreplan.business.i18n.I18nHelper._;
*
* @author Fernando Bellas Permuy
* @author Manuel Rego Casasnovas
+ * @author Vova Perebykivskiy
*/
public enum UserRole {
// Access to all pages
ROLE_SUPERUSER(_("Superuser")),
+
// Web services roles
ROLE_WS_READER(_("Web service reader")),
ROLE_WS_WRITER(_("Web service writer")),
ROLE_WS_SUBCONTRACTING(_("Web service subcontractor operations")),
+
// Project operations roles
ROLE_READ_ALL_PROJECTS(_("Read all projects")),
ROLE_EDIT_ALL_PROJECTS(_("Edit all projects")),
ROLE_CREATE_PROJECTS(_("Create projects")),
+
// Special role for bound users
ROLE_BOUND_USER(_("Bound user")),
+
// Page roles
ROLE_PLANNING(_("Planning")),
ROLE_TEMPLATES(_("Templates")),
@@ -81,7 +86,11 @@ public enum UserRole {
ROLE_PROJECT_COSTS_REPORT(_("Project Costs Report")),
ROLE_TASK_SCHEDULING_STATUS_IN_PROJECT_REPORT(_("Task Scheduling Status In Project Report")),
ROLE_MATERIALS_NEED_AT_DATE_REPORT(_("Materials Needed At Date Report")),
- ROLE_PROJECT_STATUS_REPORT(_("Project Status Report"));
+ ROLE_PROJECT_STATUS_REPORT(_("Project Status Report")),
+
+ ROLE_EDIT_EMAIL_TEMPLATES(_("Edit E-mail Templates")),
+
+ ROLE_EMAIL_TASK_ASSIGNED_TO_RESOURCE(_("Email task assigned to resource"));
private final String displayName;
diff --git a/libreplan-business/src/main/resources/libreplan-business-spring-config.xml b/libreplan-business/src/main/resources/libreplan-business-spring-config.xml
index 8e739f774..c7e391a87 100644
--- a/libreplan-business/src/main/resources/libreplan-business-spring-config.xml
+++ b/libreplan-business/src/main/resources/libreplan-business-spring-config.xml
@@ -94,6 +94,9 @@
org/libreplan/business/common/entities/JobSchedulerConfiguration.hbm.xml
+
+ org/libreplan/business/email/entities/Email.hbm.xml
+
@@ -143,6 +146,9 @@
${default.exampleUsersDisabled}
+
+ ${default.emailSendingEnabled}
+
+
+
+
+
+
+
+
+ 100
+
+
+
+
+
+ org.libreplan.business.email.entities.EmailTemplateEnum
+
+
+
+
+
+ org.libreplan.business.settings.entities.Language
+
+
+
+
+
+
+
+
+
+
+
+
+ 100
+
+
+
+
+
+ org.libreplan.business.email.entities.EmailTemplateEnum
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/libreplan-business/src/main/resources/org/libreplan/business/resources/entities/Resources.hbm.xml b/libreplan-business/src/main/resources/org/libreplan/business/resources/entities/Resources.hbm.xml
index 85eb2b513..833b6495e 100644
--- a/libreplan-business/src/main/resources/org/libreplan/business/resources/entities/Resources.hbm.xml
+++ b/libreplan-business/src/main/resources/org/libreplan/business/resources/entities/Resources.hbm.xml
@@ -59,7 +59,7 @@
-
diff --git a/libreplan-business/src/main/resources/org/libreplan/business/templates/entities/Templates.hbm.xml b/libreplan-business/src/main/resources/org/libreplan/business/templates/entities/Templates.hbm.xml
index 16025d827..1d5b2dbbf 100644
--- a/libreplan-business/src/main/resources/org/libreplan/business/templates/entities/Templates.hbm.xml
+++ b/libreplan-business/src/main/resources/org/libreplan/business/templates/entities/Templates.hbm.xml
@@ -90,5 +90,4 @@
-
diff --git a/libreplan-business/src/test/resources/libreplan-business-spring-config-test.xml b/libreplan-business/src/test/resources/libreplan-business-spring-config-test.xml
index fa7a5ee8b..32ad8eb9c 100644
--- a/libreplan-business/src/test/resources/libreplan-business-spring-config-test.xml
+++ b/libreplan-business/src/test/resources/libreplan-business-spring-config-test.xml
@@ -40,9 +40,6 @@
org/libreplan/business/orders/entities/Orders.hbm.xml
-
- org/libreplan/business/templates/entities/Templates.hbm.xml
-
org/libreplan/business/planner/entities/Tasks.hbm.xml
diff --git a/libreplan-webapp/pom.xml b/libreplan-webapp/pom.xml
index 078cb252d..f80cf8816 100644
--- a/libreplan-webapp/pom.xml
+++ b/libreplan-webapp/pom.xml
@@ -11,6 +11,7 @@
LibrePlan Web Client Module
+
reports
@@ -71,6 +72,7 @@
+
userguide
@@ -195,6 +197,7 @@
+
i18n
@@ -430,6 +433,14 @@
javax.servletservlet-api
+
+
+
+ javax.mail
+ mail
+ 1.5.0-b01
+
+
javax.ws.rs
diff --git a/libreplan-webapp/src/main/java/org/libreplan/importers/ISendEmail.java b/libreplan-webapp/src/main/java/org/libreplan/importers/ISendEmail.java
new file mode 100644
index 000000000..7fe5cbba0
--- /dev/null
+++ b/libreplan-webapp/src/main/java/org/libreplan/importers/ISendEmail.java
@@ -0,0 +1,33 @@
+/*
+ * This file is part of LibrePlan
+ *
+ * Copyright (C) 2015 LibrePlan
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package org.libreplan.importers;
+
+
+/**
+ * Sends E-mail to users with data that storing in notification_queue table
+ *
+ * Created by
+ * @author Vova Perebykivskiy
+ * on 13.10.15.
+ */
+
+public interface ISendEmail {
+ void sendEmail();
+}
diff --git a/libreplan-webapp/src/main/java/org/libreplan/importers/SendEmail.java b/libreplan-webapp/src/main/java/org/libreplan/importers/SendEmail.java
new file mode 100644
index 000000000..d9ee56d32
--- /dev/null
+++ b/libreplan-webapp/src/main/java/org/libreplan/importers/SendEmail.java
@@ -0,0 +1,302 @@
+/*
+ * This file is part of LibrePlan
+ *
+ * Copyright (C) 2015 LibrePlan
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package org.libreplan.importers;
+
+import org.libreplan.business.common.Configuration;
+import org.libreplan.business.common.daos.IConnectorDAO;
+import org.libreplan.business.common.entities.Connector;
+import org.libreplan.business.common.entities.ConnectorProperty;
+import org.libreplan.business.email.entities.EmailNotification;
+import org.libreplan.business.email.entities.EmailTemplate;
+import org.libreplan.business.email.entities.EmailTemplateEnum;
+import org.libreplan.business.resources.entities.Resource;
+import org.libreplan.business.resources.entities.Worker;
+import org.libreplan.business.settings.entities.Language;
+import org.libreplan.web.email.IEmailNotificationModel;
+
+import org.libreplan.web.email.IEmailTemplateModel;
+import org.libreplan.web.planner.tabs.MultipleTabsPlannerController;
+import org.libreplan.web.resources.worker.IWorkerModel;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.Transport;
+import javax.mail.Session;
+import javax.mail.PasswordAuthentication;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage;
+import javax.mail.NoSuchProviderException;
+
+
+import java.util.List;
+import java.util.Locale;
+import java.util.Properties;
+
+/**
+ * Sends E-mail to users with data that storing in notification_queue table
+ *
+ * Created by
+ * @author Vova Perebykivskiy
+ * on 13.10.15.
+ */
+@Component
+@Scope(BeanDefinition.SCOPE_PROTOTYPE)
+public class SendEmail implements ISendEmail {
+
+ @Autowired
+ private IEmailNotificationModel emailNotificationModel;
+
+ @Autowired
+ private IConnectorDAO connectorDAO;
+
+ @Autowired
+ private IWorkerModel workerModel;
+
+ @Autowired
+ private IEmailTemplateModel emailTemplateModel;
+
+ private List notifications;
+ private List emailTemplates;
+
+ @Override
+ public void sendEmail() {
+ if ( Configuration.isEmailSendingEnabled() == true ){
+ if (validConnection() == true){
+ notifications = emailNotificationModel.getAll();
+ for (int i = 0; i < notifications.size(); i++) composeMessageForUser(notifications.get(i));
+ deleteAllNotificationsAfterSending();
+ }
+ }
+ }
+
+ private void composeMessageForUser(EmailNotification notification){
+
+ // Gather data about EmailTemplate needs to be used
+ Resource resource = notification.getResource();
+ EmailTemplateEnum type = notification.getType();
+ Locale locale;
+ Worker currentWorker = getCurrentWorker(resource.getId());
+
+ if ( currentWorker.getUser().getApplicationLanguage().equals(Language.BROWSER_LANGUAGE) ) {
+ locale = new Locale(System.getProperty("user.language"));
+ } else {
+ locale = new Locale(currentWorker.getUser().getApplicationLanguage().getLocale().getLanguage());
+ }
+
+ EmailTemplate currentEmailTemplate = findCurrentEmailTemplate(type, locale);
+
+
+ // Modify text that will be composed
+ String text = currentEmailTemplate.getContent();
+
+ if ( type.equals(EmailTemplateEnum.TEMPLATE_TASK_ASSIGNED_TO_RESOURCE) ){
+ text = text.replaceAll("\\{username\\}", currentWorker.getUser().getLoginName());
+ text = text.replaceAll("\\{firstname\\}", currentWorker.getUser().getFirstName());
+ text = text.replaceAll("\\{lastname\\}", currentWorker.getUser().getLastName());
+ text = text.replaceAll("\\{project\\}", notification.getProject().getName());
+ text = text.replaceAll("\\{resource\\}", notification.getResource().getName());
+ text = text.replaceAll("\\{task\\}", notification.getTask().getName());
+ text = text.replaceAll("\\{url\\}", MultipleTabsPlannerController.WELCOME_URL);
+ }
+
+ // Get/Set connection properties
+ List emailConnectorProperties = getEmailConnectorProperties();
+
+ String receiver = currentWorker.getUser().getEmail();
+ String protocol = null;
+ String host = null;
+ String port = null;
+ String sender = null;
+ String usrnme = null;
+ String psswrd = null;
+
+ for (int i = 0; i < emailConnectorProperties.size(); i++){
+ switch (i){
+ case 1: {
+ protocol = emailConnectorProperties.get(1).getValue();
+ break;
+ }
+ case 2: {
+ host = emailConnectorProperties.get(2).getValue();
+ break;
+ }
+ case 3: {
+ port = emailConnectorProperties.get(3).getValue();
+ break;
+ }
+ case 4: {
+ sender = emailConnectorProperties.get(4).getValue();
+ break;
+ }
+ case 5: {
+ usrnme = emailConnectorProperties.get(5).getValue();
+ break;
+ }
+ case 6: {
+ psswrd = emailConnectorProperties.get(6).getValue();
+ break;
+ }
+ }
+ }
+
+ // Set properties of connection
+ Properties properties = new Properties();
+
+ if ( protocol.equals("STARTTLS") ) {
+ properties.put("mail.smtp.starttls.enable", "true");
+ properties.put("mail.smtp.host", host);
+ properties.put("mail.smtp.socketFactory.port", port);
+ properties.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
+ properties.put("mail.smtp.auth", "true");
+ properties.put("mail.smtp.port", port);
+ }
+ else if ( protocol.equals("SMTP") ) {
+ properties.put("mail.smtp.host", host);
+ properties.put("mail.smtp.port", port);
+ }
+
+ final String username = usrnme;
+ final String password = psswrd;
+
+ /* It is very important to use Session.getInstance instead of Session.getDefaultInstance */
+ Session mailSession = Session.getInstance(properties,
+ new javax.mail.Authenticator() {
+ protected PasswordAuthentication getPasswordAuthentication() {
+ return new PasswordAuthentication(username, password);
+ }
+ });
+
+ // Send message
+ try{
+ MimeMessage message = new MimeMessage(mailSession);
+
+ message.setFrom(new InternetAddress(sender));
+ message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(receiver));
+
+ String subject = currentEmailTemplate.getSubject();
+ message.setSubject(subject);
+
+ message.setText(text);
+
+ Transport.send(message);
+
+
+
+ } catch (MessagingException e){throw new RuntimeException(e);}
+
+ }
+
+ private void deleteAllNotificationsAfterSending(){
+ emailNotificationModel.deleteAll();
+ }
+
+ private List getEmailConnectorProperties() {
+
+ Connector connector = connectorDAO.findUniqueByName("E-mail");
+
+ List properties = connector.getProperties();
+
+ return properties;
+ }
+
+ private EmailTemplate findCurrentEmailTemplate(EmailTemplateEnum templateEnum, Locale locale){
+ emailTemplates = emailTemplateModel.getAll();
+ for (EmailTemplate item : emailTemplates)
+ if ( item.getType().equals(templateEnum) && item.getLanguage().getLocale().equals(locale) )
+ return item;
+ return null;
+ }
+
+ private Worker getCurrentWorker(Long resourceID){
+ List workerList = workerModel.getWorkers();
+ for(int i = 0; i < workerList.size(); i++)
+ if ( workerList.get(i).getId().equals(resourceID) )
+ return workerList.get(i);
+ return null;
+ }
+
+ private boolean validConnection(){
+ List emailConnectorProperties = getEmailConnectorProperties();
+
+ String protocol = null;
+ String host = null;
+ String port = null;
+ String usrnme = null;
+ String psswrd = null;
+
+ for (int i = 0; i < emailConnectorProperties.size(); i++){
+ switch (i){
+ case 1: {
+ protocol = emailConnectorProperties.get(1).getValue();
+ break;
+ }
+ case 2: {
+ host = emailConnectorProperties.get(2).getValue();
+ break;
+ }
+ case 3: {
+ port = emailConnectorProperties.get(3).getValue();
+ break;
+ }
+ case 5: {
+ usrnme = emailConnectorProperties.get(5).getValue();
+ break;
+ }
+ case 6: {
+ psswrd = emailConnectorProperties.get(6).getValue();
+ break;
+ }
+ }
+ }
+
+ // Set properties of connection
+ Properties properties = new Properties();
+
+ Transport transport = null;
+
+ try {
+ if (protocol.equals("SMTP")) {
+ properties.setProperty("mail.smtp.port", port);
+ properties.setProperty("mail.smtp.host", host);
+ Session session = Session.getInstance(properties, null);
+
+ transport = session.getTransport("smtp");
+ if (usrnme.equals("") && psswrd.equals("")) transport.connect();
+ } else if (protocol.equals("STARTTLS")) {
+ properties.setProperty("mail.smtps.port", port);
+ properties.setProperty("mail.smtps.host", host);
+ Session session = Session.getInstance(properties, null);
+
+ transport = session.getTransport("smtps");
+ if (!usrnme.equals("") && psswrd != null) transport.connect(host, usrnme, psswrd);
+ }
+ if (transport.isConnected()) return true;
+
+ } catch (NoSuchProviderException e) {}
+ catch (MessagingException e) {}
+
+ return false;
+ }
+}
diff --git a/libreplan-webapp/src/main/java/org/libreplan/importers/SendEmailJob.java b/libreplan-webapp/src/main/java/org/libreplan/importers/SendEmailJob.java
new file mode 100644
index 000000000..fa7dab5b8
--- /dev/null
+++ b/libreplan-webapp/src/main/java/org/libreplan/importers/SendEmailJob.java
@@ -0,0 +1,47 @@
+/*
+ * This file is part of LibrePlan
+ *
+ * Copyright (C) 2015 LibrePlan
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package org.libreplan.importers;
+
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.scheduling.quartz.QuartzJobBean;
+
+/**
+ * Sends E-mail to users with data that storing in notification_queue table
+ *
+ * Created by
+ * @author Vova Perebykivskiy
+ * on 13.10.15.
+ *
+ */
+
+public class SendEmailJob extends QuartzJobBean {
+
+ @Override
+ protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
+ ApplicationContext applicationContext = (ApplicationContext) context.getJobDetail().
+ getJobDataMap().get("applicationContext");
+
+ ISendEmail sendEmail = (ISendEmail) applicationContext.getBean("sendEmail");
+ sendEmail.sendEmail();
+ }
+
+}
diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/calendars/BaseCalendarEditionController.java b/libreplan-webapp/src/main/java/org/libreplan/web/calendars/BaseCalendarEditionController.java
index ff8060ac1..11c623946 100644
--- a/libreplan-webapp/src/main/java/org/libreplan/web/calendars/BaseCalendarEditionController.java
+++ b/libreplan-webapp/src/main/java/org/libreplan/web/calendars/BaseCalendarEditionController.java
@@ -835,8 +835,8 @@ public abstract class BaseCalendarEditionController extends
comboItem.setLabel(parent.getName());
comboItem.setParent(comboParents);
- if ((version.getParent()) != null
- && (parent.getId().equals(version.getParent().getId()))) {
+ if ( (version.getParent() ) != null &&
+ (parent.getId().equals(version.getParent().getId())) ) {
comboParents.setSelectedItem(comboItem);
}
}
@@ -845,7 +845,7 @@ public abstract class BaseCalendarEditionController extends
new EventListener() {
@Override
public void onEvent(Event event) throws Exception {
- if (comboParents.getSelectedItem() != null) {
+ if ( comboParents.getSelectedItem() != null ) {
BaseCalendar parent = (BaseCalendar) comboParents
.getSelectedItem().getValue();
version.setParent(parent);
@@ -861,7 +861,7 @@ public abstract class BaseCalendarEditionController extends
}, new Util.Setter() {
@Override
public void set(Comboitem comboItem) {
- if (((comboItem != null)) && (comboItem.getValue() != null)
+ if ( ((comboItem != null)) && (comboItem.getValue() != null )
&& (comboItem.getValue() instanceof BaseCalendar)) {
BaseCalendar parent = (BaseCalendar) comboItem
.getValue();
diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/common/BaseCRUDController.java b/libreplan-webapp/src/main/java/org/libreplan/web/common/BaseCRUDController.java
index 4589ee6fb..d9203150f 100644
--- a/libreplan-webapp/src/main/java/org/libreplan/web/common/BaseCRUDController.java
+++ b/libreplan-webapp/src/main/java/org/libreplan/web/common/BaseCRUDController.java
@@ -227,9 +227,8 @@ public abstract class BaseCRUDController extends
*/
private void saveCommonActions() throws ValidationException {
beforeSaving();
-
+ messagesForUser.clearMessages();
save();
-
messagesForUser.showMessage(
Level.INFO,
_("{0} \"{1}\" saved", getEntityType(), getEntityBeingEdited()
diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/common/ConfigurationController.java b/libreplan-webapp/src/main/java/org/libreplan/web/common/ConfigurationController.java
index a1ef7b11d..d2187e6cc 100644
--- a/libreplan-webapp/src/main/java/org/libreplan/web/common/ConfigurationController.java
+++ b/libreplan-webapp/src/main/java/org/libreplan/web/common/ConfigurationController.java
@@ -23,15 +23,22 @@ package org.libreplan.web.common;
import static org.libreplan.web.I18nHelper._;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.ConcurrentModificationException;
-import java.util.HashSet;
import java.util.List;
-import java.util.Map;
+import java.util.ConcurrentModificationException;
+import java.util.Comparator;
+import java.util.Properties;
+import java.util.ArrayList;
import java.util.Set;
+import java.util.Map;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Arrays;
+
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.AuthenticationFailedException;
+import javax.mail.MessagingException;
+
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@@ -70,23 +77,27 @@ import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.event.SelectEvent;
import org.zkoss.zk.ui.util.GenericForwardComposer;
-import org.zkoss.zul.Button;
-import org.zkoss.zul.Combobox;
-import org.zkoss.zul.Constraint;
-import org.zkoss.zul.Grid;
-import org.zkoss.zul.Intbox;
-import org.zkoss.zul.Label;
-import org.zkoss.zul.Listbox;
-import org.zkoss.zul.Listitem;
+
+
import org.zkoss.zul.ListitemRenderer;
-import org.zkoss.zul.Messagebox;
-import org.zkoss.zul.Radio;
+import org.zkoss.zul.Listbox;
+import org.zkoss.zul.Grid;
+import org.zkoss.zul.Combobox;
+import org.zkoss.zul.Intbox;
+import org.zkoss.zul.Textbox;
import org.zkoss.zul.Radiogroup;
+import org.zkoss.zul.Listitem;
import org.zkoss.zul.Row;
+import org.zkoss.zul.Constraint;
import org.zkoss.zul.RowRenderer;
+import org.zkoss.zul.Comboitem;
+import org.zkoss.zul.Radio;
+import org.zkoss.zul.Button;
+import org.zkoss.zul.Label;
import org.zkoss.zul.Rows;
import org.zkoss.zul.SimpleListModel;
-import org.zkoss.zul.Textbox;
+import org.zkoss.zul.Messagebox;
+
import org.zkoss.zul.api.Window;
import org.zkoss.zul.impl.InputElement;
@@ -97,6 +108,7 @@ import org.zkoss.zul.impl.InputElement;
* @author Susana Montes Pedreira
* @author Cristina Alavarino Perez
* @author Ignacio Diaz Teijido
+ * @author Vova Perebykivskiy
*/
public class ConfigurationController extends GenericForwardComposer {
@@ -137,6 +149,14 @@ public class ConfigurationController extends GenericForwardComposer {
private Connector selectedConnector;
+ private Combobox protocolsCombobox;
+
+ private Textbox emailUsernameTextbox;
+
+ private Textbox emailPasswordTextbox;
+
+ private Textbox emailSenderTextbox;
+
@Override
public void doAfterCompose(Component comp) throws Exception {
super.doAfterCompose(comp);
@@ -221,36 +241,43 @@ public class ConfigurationController extends GenericForwardComposer {
}
public void save() throws InterruptedException {
- ConstraintChecker.isValid(configurationWindow);
- if (checkValidEntitySequenceRows()) {
- try {
- configurationModel.confirm();
- configurationModel.init();
- messages.showMessage(Level.INFO, _("Changes saved"));
- if (getSelectedConnector() != null
- && !configurationModel
- .scheduleOrUnscheduleJobs(getSelectedConnector())) {
- messages.showMessage(
- Level.ERROR,
- _("Scheduling or unscheduling of jobs for this connector is not completed"));
+
+ if ( getSelectedConnector().getName().equals("E-mail") && isEmailFieldsValid() == false) {
+ messages.showMessage(Level.ERROR, _("Check username/password/sender fields"));
+ } else {
+ ConstraintChecker.isValid(configurationWindow);
+ if (checkValidEntitySequenceRows()) {
+ try {
+ configurationModel.confirm();
+ configurationModel.init();
+ messages.showMessage(Level.INFO, _("Changes saved"));
+ if (getSelectedConnector() != null
+ && !configurationModel
+ .scheduleOrUnscheduleJobs(getSelectedConnector())) {
+ messages.showMessage(
+ Level.ERROR,
+ _("Scheduling or unscheduling of jobs for this connector is not completed"));
+ }
+ reloadWindow();
+ reloadEntitySequences();
+ reloadConnectors();
+ } catch (ValidationException e) {
+ messages.showInvalidValues(e);
+ } catch (ConcurrentModificationException e) {
+ messages.showMessage(Level.ERROR, e.getMessage());
+ configurationModel.init();
+ reloadWindow();
+ reloadEntitySequences();
+ reloadConnectors();
}
- reloadWindow();
- reloadEntitySequences();
- reloadConnectors();
- } catch (ValidationException e) {
- messages.showInvalidValues(e);
- } catch (ConcurrentModificationException e) {
- messages.showMessage(Level.ERROR, e.getMessage());
- configurationModel.init();
- reloadWindow();
- reloadEntitySequences();
- reloadConnectors();
}
}
+
}
public void cancel() throws InterruptedException {
configurationModel.cancel();
+ messages.clearMessages();
messages.showMessage(Level.INFO, _("Changes have been canceled"));
reloadWindow();
reloadEntitySequences();
@@ -305,12 +332,19 @@ public class ConfigurationController extends GenericForwardComposer {
String password = properties
.get(PredefinedConnectorProperties.PASSWORD);
- if (selectedConnector.getName().equals(
- PredefinedConnectors.TIM.getName())) {
+ if ( selectedConnector.getName().equals(
+ PredefinedConnectors.TIM.getName()) ) {
testTimConnection(url, username, password);
- } else if (selectedConnector.getName().equals(
- PredefinedConnectors.JIRA.getName())) {
+ } else if ( selectedConnector.getName().equals(
+ PredefinedConnectors.JIRA.getName()) ) {
testJiraConnection(url, username, password);
+ } else if( selectedConnector.getName().equals(
+ PredefinedConnectors.EMAIL.getName()) ){
+ String host = properties.get(PredefinedConnectorProperties.HOST);
+ username = properties.get(PredefinedConnectorProperties.EMAIL_USERNAME);
+ password = properties.get(PredefinedConnectorProperties.EMAIL_PASSWORD);
+ String port = properties.get(PredefinedConnectorProperties.PORT);
+ testEmailConnection(host, port, username, password);
} else {
throw new RuntimeException("Unknown connector");
}
@@ -373,6 +407,58 @@ public class ConfigurationController extends GenericForwardComposer {
}
}
+ /**
+ * Test E-mail connection
+ *
+ * @param host
+ * the host
+ * @param port
+ * the port
+ * @param username
+ * the username
+ * @param password
+ * the password
+ */
+ private void testEmailConnection(String host, String port, String username, String password){
+ Properties props = System.getProperties();
+ Transport transport = null;
+
+ try {
+ if ( protocolsCombobox.getSelectedItem().getLabel().equals("SMTP") ){
+ props.setProperty("mail.smtp.port", port);
+ props.setProperty("mail.smtp.host", host);
+ Session session = Session.getInstance(props, null);
+
+ transport = session.getTransport("smtp");
+ if ( username.equals("") && password.equals("")) transport.connect();
+ }
+ else if ( protocolsCombobox.getSelectedItem().getLabel().equals("STARTTLS") ) {
+ props.setProperty("mail.smtps.port", port);
+ props.setProperty("mail.smtps.host", host);
+ Session session = Session.getInstance(props, null);
+
+ transport = session.getTransport("smtps");
+ if ( !username.equals("") && password != null ) transport.connect(host, username, password);
+ }
+
+ messages.clearMessages();
+ if ( transport.isConnected() ) messages.showMessage(Level.INFO, _("Connection successful!"));
+ else if ( transport.isConnected() == false ) messages.showMessage(Level.WARNING, _("Connection unsuccessful"));
+ }
+ catch (AuthenticationFailedException e){
+ LOG.error(e);
+ messages.showMessage(Level.ERROR, _("Invalid credentials"));
+ }
+ catch (MessagingException e){
+ LOG.error(e);
+ messages.showMessage(Level.ERROR, _("Cannot connect"));
+ }
+ catch (Exception e){
+ LOG.error(e);
+ messages.showMessage(Level.ERROR, _("Failed to connect"));
+ }
+ }
+
private boolean checkValidEntitySequenceRows() {
Rows rows = entitySequencesGrid.getRows();
for (Row row : (List) rows.getChildren()) {
@@ -1090,11 +1176,15 @@ public class ConfigurationController extends GenericForwardComposer {
row.setValue(property);
Util.appendLabel(row, _(property.getKey()));
- appendValueTextbox(row, property);
+
+ // FIXME this is not perfect solution
+ if ( property.getKey().equals("Protocol") ) appendValueCombobox(row, property);
+ else appendValueTextbox(row, property);
}
private void appendValueTextbox(Row row,
final ConnectorProperty property) {
+
final Textbox textbox = new Textbox();
textbox.setWidth("400px");
textbox.setConstraint(checkPropertyValue(property));
@@ -1112,37 +1202,108 @@ public class ConfigurationController extends GenericForwardComposer {
property.setValue(value);
}
});
- if (property.getKey().equals(
- PredefinedConnectorProperties.PASSWORD)) {
+
+ if ( property.getKey().equals(
+ PredefinedConnectorProperties.PASSWORD) ||
+ property.getKey().equals(
+ PredefinedConnectorProperties.EMAIL_PASSWORD) ) {
textbox.setType("password");
}
+ // Need for method validateEmailFields()
+ if ( property.getKey().equals(
+ PredefinedConnectorProperties.EMAIL_USERNAME) ) emailUsernameTextbox = textbox;
+
+ if ( property.getKey().equals(
+ PredefinedConnectorProperties.EMAIL_PASSWORD) ) emailPasswordTextbox = textbox;
+
+ if ( property.getKey().equals(
+ PredefinedConnectorProperties.EMAIL_SENDER) ) emailSenderTextbox = textbox;
+
row.appendChild(textbox);
}
+ private void appendValueCombobox(Row row,
+ final ConnectorProperty property){
+
+ final Combobox combobox = new Combobox();
+ combobox.setWidth("400px");
+ final List protocols = new ArrayList();
+ protocols.add("SMTP");
+ protocols.add("STARTTLS");
+
+ for (String item : protocols){
+ Comboitem comboitem = new Comboitem();
+ comboitem.setValue(item);
+ comboitem.setLabel(item);
+ comboitem.setParent(combobox);
+
+ if ( (!property.getValue().equals("")) &&
+ (item.equals(property.getValue())) ){
+ combobox.setSelectedItem(comboitem);
+ }
+ }
+
+ combobox.addEventListener(Events.ON_SELECT,
+ new EventListener() {
+ @Override
+ public void onEvent(Event event) throws Exception {
+ if (combobox.getSelectedItem() != null){
+ property.setValue(combobox.getSelectedItem().getValue().toString());
+ }
+ }
+ });
+
+ Util.bind(combobox, new Util.Getter() {
+ @Override
+ public Comboitem get() {
+ return combobox.getSelectedItem();
+ }
+ }, new Util.Setter(){
+
+ @Override
+ public void set(Comboitem item) {
+ if ( (item != null) && (item.getValue() != null) &&
+ (item.getValue() instanceof String) ){
+ property.setValue(combobox.getSelectedItem().getValue().toString());
+ }
+ }
+ });
+
+
+ row.appendChild(combobox);
+
+ // Need for testing E-mail connection
+ protocolsCombobox = combobox;
+ }
+
public Constraint checkPropertyValue(
final ConnectorProperty property) {
final String key = property.getKey();
return new Constraint() {
@Override
public void validate(Component comp, Object value) {
- if (key.equals(PredefinedConnectorProperties.ACTIVATED)) {
- if (!((String) value).equalsIgnoreCase("Y")
- && !((String) value).equalsIgnoreCase("N")) {
+ if ( key.equals(PredefinedConnectorProperties.ACTIVATED) ) {
+ if ( !((String) value).equalsIgnoreCase("Y")
+ && !((String) value).equalsIgnoreCase("N") ) {
throw new WrongValueException(comp, _(
"Only {0} allowed", "Y/N"));
}
- } else if (key
- .equals(PredefinedConnectorProperties.SERVER_URL)
- || key.equals(PredefinedConnectorProperties.USERNAME)
- || key.equals(PredefinedConnectorProperties.PASSWORD)
- || key.equals(PredefinedConnectorProperties.JIRA_HOURS_TYPE)) {
+ } else if ( key
+ .equals(PredefinedConnectorProperties.SERVER_URL) ||
+ key.equals(PredefinedConnectorProperties.USERNAME) ||
+ key.equals(PredefinedConnectorProperties.PASSWORD) ||
+ key.equals(PredefinedConnectorProperties.JIRA_HOURS_TYPE) ||
+ key.equals(PredefinedConnectorProperties.HOST) ||
+ key.equals(PredefinedConnectorProperties.PORT) ||
+ key.equals(PredefinedConnectorProperties.EMAIL_SENDER) ) {
((InputElement) comp).setConstraint("no empty:"
+ _("cannot be empty"));
- } else if (key
- .equals(PredefinedConnectorProperties.TIM_NR_DAYS_TIMESHEET)
- || key.equals(PredefinedConnectorProperties.TIM_NR_DAYS_ROSTER)) {
- if (!isNumeric((String) value)) {
+ } else if ( key
+ .equals(PredefinedConnectorProperties.TIM_NR_DAYS_TIMESHEET) ||
+ key.equals(PredefinedConnectorProperties.TIM_NR_DAYS_ROSTER) ||
+ key.equals(PredefinedConnectorProperties.PORT) ) {
+ if ( !isNumeric((String) value) ) {
throw new WrongValueException(comp,
_("Only digits allowed"));
}
@@ -1163,4 +1324,17 @@ public class ConfigurationController extends GenericForwardComposer {
};
}
+ private boolean isEmailFieldsValid(){
+
+ if ( protocolsCombobox.getSelectedItem().getLabel().equals("STARTTLS") &&
+ emailUsernameTextbox.getValue() != null &&
+ emailPasswordTextbox.getValue() != null &&
+ emailUsernameTextbox.getValue().length() != 0 &&
+ emailPasswordTextbox.getValue().length() != 0 &&
+ emailSenderTextbox.getValue().matches("^\\S+@\\S+\\.\\S+$") )
+ return true;
+
+ else return false;
+ }
+
}
diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/common/CustomMenuController.java b/libreplan-webapp/src/main/java/org/libreplan/web/common/CustomMenuController.java
index c680966fb..c62280ee5 100644
--- a/libreplan-webapp/src/main/java/org/libreplan/web/common/CustomMenuController.java
+++ b/libreplan-webapp/src/main/java/org/libreplan/web/common/CustomMenuController.java
@@ -59,6 +59,7 @@ import org.zkoss.zul.Vbox;
* Controller for customMenu
* @author Lorenzo Tilve Álvaro
* @author Fernando Bellas Permuy
+ * @author Vova Perebykivskiy
*/
public class CustomMenuController extends Div implements IMenuItemsRegister {
@@ -420,6 +421,11 @@ public class CustomMenuController extends Div implements IMenuItemsRegister {
"/common/job_scheduling.zul",
"19-scheduler.html"));
}
+ if (SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_EDIT_EMAIL_TEMPLATES)) {
+ configurationItems.add(subItem(_("Edit E-mail Templates"),
+ "/email/email_templates.zul",
+ "email-templates.html"));
+ }
if (!configurationItems.isEmpty()) {
topItem(_("Configuration"), "/common/configuration.zul", "",
diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/common/JobSchedulerModel.java b/libreplan-webapp/src/main/java/org/libreplan/web/common/JobSchedulerModel.java
index 5601cd3cb..0cea1d00a 100644
--- a/libreplan-webapp/src/main/java/org/libreplan/web/common/JobSchedulerModel.java
+++ b/libreplan-webapp/src/main/java/org/libreplan/web/common/JobSchedulerModel.java
@@ -19,6 +19,7 @@
package org.libreplan.web.common;
+import java.util.ArrayList;
import java.util.List;
import org.libreplan.business.common.daos.IConnectorDAO;
@@ -34,6 +35,7 @@ import org.libreplan.importers.IImportRosterFromTim;
import org.libreplan.importers.IJiraOrderElementSynchronizer;
import org.libreplan.importers.ISchedulerManager;
import org.libreplan.importers.SynchronizationInfo;
+import org.libreplan.importers.ISendEmail;
import org.libreplan.web.common.concurrentdetection.OnConcurrentModification;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
@@ -42,6 +44,8 @@ import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
+import static org.libreplan.web.I18nHelper._;
+
/**
* Model for UI operations related to {@link JobSchedulerConfiguration}.
*
@@ -75,6 +79,9 @@ public class JobSchedulerModel implements IJobSchedulerModel {
private List synchronizationInfos;
+ @Autowired
+ private ISendEmail email;
+
@Override
@Transactional(readOnly = true)
public List getJobSchedulerConfigurations() {
@@ -105,6 +112,13 @@ public class JobSchedulerModel implements IJobSchedulerModel {
.syncOrderElementsWithJiraIssues();
return;
}
+ if ( name.equals(JobClassNameEnum.SEND_EMAIL_JOB.getName()) ) {
+ synchronizationInfos = new ArrayList();
+ synchronizationInfos.add(new SynchronizationInfo(_("Send E-mail")));
+ email.sendEmail();
+ return;
+ }
+
throw new RuntimeException("Unknown action");
}
diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/dashboard/DashboardControllerGlobal.java b/libreplan-webapp/src/main/java/org/libreplan/web/dashboard/DashboardControllerGlobal.java
new file mode 100644
index 000000000..71d9c793b
--- /dev/null
+++ b/libreplan-webapp/src/main/java/org/libreplan/web/dashboard/DashboardControllerGlobal.java
@@ -0,0 +1,299 @@
+package org.libreplan.web.dashboard;
+
+import org.libreplan.business.orders.entities.Order;
+
+import org.libreplan.web.orders.IOrderModel;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.context.annotation.Scope;
+import org.zkoss.zk.ui.Component;
+import org.zkoss.zk.ui.util.GenericForwardComposer;
+import org.zkoss.zul.Checkbox;
+import org.zkoss.zul.Grid;
+import org.zkoss.zul.Label;
+import org.zkoss.zul.Rows;
+import org.zkoss.zul.Row;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Created
+ * @author Vova Perebykivskiy
+ * on 20.11.15.
+ */
+
+@org.springframework.stereotype.Component
+@Scope(BeanDefinition.SCOPE_PROTOTYPE)
+public class DashboardControllerGlobal extends GenericForwardComposer {
+
+ @Autowired
+ private IOrderModel orderModel;
+
+ private Grid pipelineGrid;
+ private Checkbox storedColumnVisible;
+
+ private List preSalesOrders = new ArrayList();
+ private List offeredOrders = new ArrayList();
+ private List outsourcedOrders = new ArrayList();
+ private List acceptedOrders = new ArrayList();
+ private List startedOrders = new ArrayList();
+ private List onHoldOrders = new ArrayList();
+ private List finishedOrders = new ArrayList();
+ private List cancelledOrders = new ArrayList();
+ private List storedOrders = new ArrayList();
+
+ @Override
+ public void doAfterCompose(Component component) throws Exception {
+ super.doAfterCompose(component);
+ component.setVariable("dashboardControllerGlobal", this, true);
+ fillOrderLists();
+ setupPipelineGrid();
+ showStoredColumn();
+ }
+
+ public List getOrders(){
+ return orderModel.getOrders();
+ }
+
+ private void fillOrderLists() {
+ for (Order orderItem : getOrders()){
+ switch (orderItem.getState()){
+ case PRE_SALES: {
+ preSalesOrders.add(orderItem);
+ break;
+ }
+ case OFFERED: {
+ offeredOrders.add(orderItem);
+ break;
+ }
+ case OUTSOURCED: {
+ outsourcedOrders.add(orderItem);
+ break;
+ }
+ case ACCEPTED: {
+ acceptedOrders.add(orderItem);
+ break;
+ }
+ case STARTED: {
+ startedOrders.add(orderItem);
+ break;
+ }
+ case ON_HOLD: {
+ onHoldOrders.add(orderItem);
+ break;
+ }
+ case FINISHED: {
+ finishedOrders.add(orderItem);
+ break;
+ }
+ case CANCELLED: {
+ cancelledOrders.add(orderItem);
+ break;
+ }
+ case STORED: {
+ storedOrders.add(orderItem);
+ break;
+ }
+ }
+ }
+ }
+
+ private void setupPipelineGrid() throws ParseException {
+ int rowsCount = findMaxList(preSalesOrders.size(), offeredOrders.size(), outsourcedOrders.size(), acceptedOrders.size(),
+ startedOrders.size(), onHoldOrders.size(), finishedOrders.size(), cancelledOrders.size(), storedOrders.size());
+
+ Rows rows = new Rows();
+ for (int i = 0; i < rowsCount; i++){
+ Row row = new Row();
+ for (int columns = 0; columns < 9; columns++) row.appendChild(new Label());
+ rows.appendChild(row);
+ }
+
+ pipelineGrid.appendChild(rows);
+
+ // Fill data into first column and so on with other columns divided by Enter in code
+
+ if ( preSalesOrders.size() > 0 )
+ for (int i = 0; i < preSalesOrders.size(); i++){
+ String outputInit = getOrderInitDate(preSalesOrders.get(i));
+ String outputDeadline = getOrderDeadline(preSalesOrders.get(i));
+
+ ( (Label) pipelineGrid.getCell(i, 0) ).setValue(preSalesOrders.get(i).getName());
+ String tooltipText = "Start date: " + outputInit +
+ "\n" + "End date: " + outputDeadline +
+ "\n" + "Progress: " + preSalesOrders.get(i).getAdvancePercentage() + " %";
+ ( (Label) pipelineGrid.getCell(i, 0) ).setTooltiptext(tooltipText);
+ ( (Label) pipelineGrid.getCell(i, 0) ).setClass("label-highlight");
+ }
+
+
+ if ( offeredOrders.size() > 0 )
+ for (int i = 0; i < offeredOrders.size(); i++){
+ String outputInit = getOrderInitDate(offeredOrders.get(i));
+ String outputDeadline = getOrderDeadline(offeredOrders.get(i));
+
+ ( (Label) pipelineGrid.getCell(i, 1) ).setValue(offeredOrders.get(i).getName());
+ String tooltipText = "Start date: " + outputInit +
+ "\n" + "End date: " + outputDeadline +
+ "\n" + "Progress: " + offeredOrders.get(i).getAdvancePercentage() + " %";
+ ( (Label) pipelineGrid.getCell(i, 1) ).setTooltiptext(tooltipText);
+ ( (Label) pipelineGrid.getCell(i, 1) ).setClass("label-highlight");
+ }
+
+
+ if ( outsourcedOrders.size() > 0 )
+ for (int i = 0; i < outsourcedOrders.size(); i++){
+ String outputInit = getOrderInitDate(outsourcedOrders.get(i));
+ String outputDeadline = getOrderDeadline(outsourcedOrders.get(i));
+
+ ( (Label) pipelineGrid.getCell(i, 2) ).setValue(outsourcedOrders.get(i).getName());
+ String tooltipText = "Start date: " + outputInit +
+ "\n" + "End date: " + outputDeadline +
+ "\n" + "Progress: " + outsourcedOrders.get(i).getAdvancePercentage() + " %";
+ ( (Label) pipelineGrid.getCell(i, 2) ).setTooltiptext(tooltipText);
+ ( (Label) pipelineGrid.getCell(i, 2) ).setClass("label-highlight");
+ }
+
+
+ if ( acceptedOrders.size() > 0 )
+ for (int i = 0; i < acceptedOrders.size(); i++){
+ String outputInit = getOrderInitDate(acceptedOrders.get(i));
+ String outputDeadline = getOrderDeadline(acceptedOrders.get(i));
+
+ ( (Label) pipelineGrid.getCell(i, 3) ).setValue(acceptedOrders.get(i).getName());
+ String tooltipText = "Start date: " + outputInit +
+ "\n" + "End date: " + outputDeadline +
+ "\n" + "Progress: " + acceptedOrders.get(i).getAdvancePercentage() + " %";
+ ( (Label) pipelineGrid.getCell(i, 3) ).setTooltiptext(tooltipText);
+ ( (Label) pipelineGrid.getCell(i, 3) ).setClass("label-highlight");
+ }
+
+
+ if ( startedOrders.size() > 0 )
+ for (int i = 0; i < startedOrders.size(); i++){
+ String outputInit = getOrderInitDate(startedOrders.get(i));
+ String outputDeadline = getOrderDeadline(startedOrders.get(i));
+
+ ( (Label) pipelineGrid.getCell(i, 4) ).setValue(startedOrders.get(i).getName());
+ String tooltipText = "Start date: " + outputInit +
+ "\n" + "End date: " + outputDeadline +
+ "\n" + "Progress: " + startedOrders.get(i).getAdvancePercentage() + " %";
+ ( (Label) pipelineGrid.getCell(i, 4) ).setTooltiptext(tooltipText);
+ ( (Label) pipelineGrid.getCell(i, 4) ).setClass("label-highlight");
+ }
+
+
+ if ( onHoldOrders.size() > 0 )
+ for (int i = 0; i < onHoldOrders.size(); i++){
+ String outputInit = getOrderInitDate(onHoldOrders.get(i));
+ String outputDeadline = getOrderDeadline(onHoldOrders.get(i));
+
+ ( (Label) pipelineGrid.getCell(i, 5) ).setValue(onHoldOrders.get(i).getName());
+ String tooltipText = "Start date: " + outputInit +
+ "\n" + "End date: " + outputDeadline +
+ "\n" + "Progress: " + onHoldOrders.get(i).getAdvancePercentage() + " %";
+ ( (Label) pipelineGrid.getCell(i, 5) ).setTooltiptext(tooltipText);
+ ( (Label) pipelineGrid.getCell(i, 5) ).setClass("label-highlight");
+ }
+
+
+ if ( finishedOrders.size() > 0 )
+ for (int i = 0; i < finishedOrders.size(); i++){
+ String outputInit = getOrderInitDate(finishedOrders.get(i));
+ String outputDeadline = getOrderDeadline(finishedOrders.get(i));
+
+ ( (Label) pipelineGrid.getCell(i, 6) ).setValue(finishedOrders.get(i).getName());
+ String tooltipText = "Start date: " + outputInit +
+ "\n" + "End date: " + outputDeadline +
+ "\n" + "Progress: " + finishedOrders.get(i).getAdvancePercentage() + " %";
+ ( (Label) pipelineGrid.getCell(i, 6) ).setTooltiptext(tooltipText);
+ ( (Label) pipelineGrid.getCell(i, 6) ).setClass("label-highlight");
+ }
+
+
+ if ( cancelledOrders.size() > 0 )
+ for (int i = 0; i < cancelledOrders.size(); i++){
+ String outputInit = getOrderInitDate(cancelledOrders.get(i));
+ String outputDeadline = getOrderDeadline(cancelledOrders.get(i));
+
+
+ ( (Label) pipelineGrid.getCell(i, 7) ).setValue(cancelledOrders.get(i).getName());
+ String tooltipText = "Start date: " + outputInit +
+ "\n" + "End date: " + outputDeadline +
+ "\n" + "Progress: " + cancelledOrders.get(i).getAdvancePercentage() + " %";
+ ( (Label) pipelineGrid.getCell(i, 7) ).setTooltiptext(tooltipText);
+ ( (Label) pipelineGrid.getCell(i, 7) ).setClass("label-highlight");
+ }
+ }
+
+ private String getOrderInitDate(Order order) throws ParseException {
+ // Remove time, timezone from full-date string
+ DateFormat inputFormatter = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
+ DateFormat outputFormatter = new SimpleDateFormat("EEE MMM dd yyyy");
+ String input = "";
+ String outputInit = "";
+ String outputDeadline = "";
+ Date date = null;
+
+ input = order.getInitDate().toString();
+ date = inputFormatter.parse(input);
+
+ return outputInit = outputFormatter.format(date);
+ }
+
+ private String getOrderDeadline(Order order) throws ParseException {
+ // Remove time, timezone from full-date string
+ DateFormat inputFormatter = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
+ DateFormat outputFormatter = new SimpleDateFormat("EEE MMM dd yyyy");
+ String input = "";
+ String outputInit = "";
+ String outputDeadline = "";
+ Date date = null;
+
+ input = order.getDeadline().toString();
+ date = inputFormatter.parse(input);
+
+ return outputDeadline = outputFormatter.format(date);
+ }
+
+ public void showStoredColumn() throws ParseException {
+ if ( storedColumnVisible.isChecked() ){
+ if ( storedOrders.size() > 0 ){
+ for (int i = 0; i < storedOrders.size(); i++){
+ String outputInit = getOrderInitDate(storedOrders.get(i));
+ String outputDeadline = getOrderDeadline(storedOrders.get(i));
+
+ pipelineGrid.getCell(i, 8).setVisible(true);
+
+ ( (Label) pipelineGrid.getCell(i, 8) ).setValue(storedOrders.get(i).getName());
+ String tooltipText = "Start date: " + outputInit +
+ "\n" + "End date: " + outputDeadline +
+ "\n" + "Progress: " + storedOrders.get(i).getAdvancePercentage() + " %";
+ ( (Label) pipelineGrid.getCell(i, 8) ).setTooltiptext(tooltipText);
+ ( (Label) pipelineGrid.getCell(i, 8) ).setClass("label-highlight");
+ }
+ }
+ }
+ else if ( !storedColumnVisible.isChecked() ){
+ for (int i = 0; i < storedOrders.size(); i++)
+ pipelineGrid.getCell(i, 8).setVisible(false);
+ }
+ }
+
+ private int findMaxList(int preSales, int offered, int outsourced, int accepted, int started, int onHold, int finished,
+ int cancelled, int stored){
+
+ int[] sizes = {preSales, offered, outsourced, accepted, started, onHold, finished, cancelled, stored};
+ int max = sizes[0];
+
+ for (int i = 1; i < sizes.length; i++)
+ if ( sizes[i] > max ) max = sizes[i];
+
+ return max;
+ }
+}
diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/email/EmailNotificationModel.java b/libreplan-webapp/src/main/java/org/libreplan/web/email/EmailNotificationModel.java
new file mode 100644
index 000000000..d40b15a92
--- /dev/null
+++ b/libreplan-webapp/src/main/java/org/libreplan/web/email/EmailNotificationModel.java
@@ -0,0 +1,110 @@
+/*
+ * This file is part of LibrePlan
+ *
+ * Copyright (C) 2015 LibrePlan
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package org.libreplan.web.email;
+
+import org.libreplan.business.common.exceptions.ValidationException;
+
+import org.libreplan.business.email.daos.IEmailNotificationDAO;
+
+import org.libreplan.business.email.entities.EmailTemplateEnum;
+import org.libreplan.business.email.entities.EmailNotification;
+
+import org.libreplan.business.planner.entities.TaskElement;
+import org.libreplan.business.resources.entities.Resource;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Model for operations related to {@link EmailNotification}.
+ *
+ * Created by
+ * @author Vova Perebykivskiy
+ * on 21.10.15.
+ */
+
+@Service
+@Scope(BeanDefinition.SCOPE_PROTOTYPE)
+public class EmailNotificationModel implements IEmailNotificationModel {
+
+ @Autowired
+ private IEmailNotificationDAO emailNotificationDAO;
+
+ private EmailTemplateEnum type;
+
+ private Date updated;
+
+ private Resource resource;
+
+ private TaskElement task;
+
+ private TaskElement project;
+
+ private EmailNotification emailNotification = new EmailNotification();
+
+ @Override
+ @Transactional
+ public void confirmSave() throws ValidationException {
+ emailNotificationDAO.save(emailNotification);
+ }
+
+ @Override
+ @Transactional
+ public List getAll() {
+ return emailNotificationDAO.getAll();
+ }
+
+ @Override
+ @Transactional
+ public boolean deleteAll() {
+ return emailNotificationDAO.deleteAll();
+ }
+
+ @Override
+ public void setType(EmailTemplateEnum type) {
+ this.emailNotification.setType(type);
+ }
+
+ @Override
+ public void setUpdated(Date updated) {
+ this.emailNotification.setUpdated(updated);
+ }
+
+ @Override
+ public void setResource(Resource resource) {
+ this.emailNotification.setResource(resource);
+ }
+
+ @Override
+ public void setTask(TaskElement task) {
+ this.emailNotification.setTask(task);
+ }
+
+ @Override
+ public void setProject(TaskElement project) {
+ this.emailNotification.setProject(project);
+ }
+
+}
diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/email/EmailTemplateController.java b/libreplan-webapp/src/main/java/org/libreplan/web/email/EmailTemplateController.java
new file mode 100644
index 000000000..69e4b82aa
--- /dev/null
+++ b/libreplan-webapp/src/main/java/org/libreplan/web/email/EmailTemplateController.java
@@ -0,0 +1,180 @@
+/*
+ * This file is part of LibrePlan
+ *
+ * Copyright (C) 2015 LibrePlan
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package org.libreplan.web.email;
+
+import org.libreplan.business.common.exceptions.InstanceNotFoundException;
+import org.libreplan.business.common.exceptions.ValidationException;
+import org.libreplan.business.settings.entities.Language;
+
+import org.libreplan.business.email.entities.EmailTemplateEnum;
+import org.libreplan.web.common.IMessagesForUser;
+import org.libreplan.web.common.Level;
+import org.libreplan.web.common.MessagesForUser;
+import org.zkoss.zk.ui.Component;
+
+
+import org.zkoss.zk.ui.Executions;
+import org.zkoss.zk.ui.util.GenericForwardComposer;
+
+import org.zkoss.zul.Listitem;
+import org.zkoss.zul.ListitemRenderer;
+import org.zkoss.zul.Textbox;
+
+import java.util.List;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.LinkedList;
+
+import static org.libreplan.web.I18nHelper._;
+
+/**
+ * Created by
+ * @author Vova Perebykivskiy
+ * on 25.09.15.
+ */
+public class EmailTemplateController extends GenericForwardComposer{
+
+ private IEmailTemplateModel emailTemplateModel;
+
+
+ private IMessagesForUser messages;
+
+ private Component messagesContainer;
+
+ private Textbox contentsTextbox;
+
+ private Textbox subjectTextbox;
+
+
+ public static ListitemRenderer languagesRenderer = new ListitemRenderer() {
+ @Override
+ public void render(org.zkoss.zul.Listitem item, Object data)
+ throws Exception {
+ Language language = (Language) data;
+ String displayName = language.getDisplayName();
+ item.setLabel(displayName);
+ }
+ };
+
+ @Override
+ public void doAfterCompose(Component comp) throws Exception {
+ super.doAfterCompose(comp);
+ comp.setVariable("emailTemplateController", this, true);
+ messages = new MessagesForUser(messagesContainer);
+ contentsTextbox.setValue(getInitialContentData());
+ subjectTextbox.setValue(getInitialSubjectData());
+ }
+
+ public boolean save(){
+ try {
+ setSelectedContent();
+ setSelectedSubject();
+ emailTemplateModel.confirmSave();
+ messages.clearMessages();
+ messages.showMessage(Level.INFO, _("E-mail template saved"));
+ return true;
+ } catch (ValidationException e) {
+ messages.showInvalidValues(e);
+ } catch (InstanceNotFoundException e) {}
+ return false;
+ }
+
+ public void cancel() throws InterruptedException {
+ Executions.getCurrent().sendRedirect("../planner/index.zul");
+ }
+
+ public Language getSelectedLanguage() {
+ return emailTemplateModel.getLanguage();
+ }
+
+ public void setSelectedLanguage(Language language){
+ emailTemplateModel.setLanguage(language);
+
+ getContentDataBySelectedLanguage();
+ }
+
+ public static ListitemRenderer getLanguagesRenderer() {
+ return languagesRenderer;
+ }
+ public List getLanguages() {
+ List languages = new LinkedList(Arrays.asList(Language.values()));
+ Collections.sort(languages, new Comparator() {
+ @Override
+ public int compare(Language o1, Language o2) {
+ if (o1.equals(Language.BROWSER_LANGUAGE)) {
+ return -1;
+ }
+ if (o2.equals(Language.BROWSER_LANGUAGE)) {
+ return 1;
+ }
+ return o1.getDisplayName().compareTo(o2.getDisplayName());
+ }
+ });
+ languages.remove(0);
+ return languages;
+ }
+
+
+ public EmailTemplateEnum getSelectedEmailTemplateEnum() {
+ return emailTemplateModel.getEmailTemplateEnum();
+ }
+ public void setSelectedEmailTemplateEnum(EmailTemplateEnum emailTemplateEnum){
+ emailTemplateModel.setEmailTemplateEnum(emailTemplateEnum);
+
+ getContentDataBySelectedTemplate();
+ }
+
+ public ListitemRenderer getEmailTemplateEnumRenderer() {
+ return new ListitemRenderer() {
+ @Override
+ public void render(Listitem item, Object data) throws Exception {
+ EmailTemplateEnum template = (EmailTemplateEnum) data;
+ item.setLabel(_(template.getTemplateType()));
+ item.setValue(template);
+ }
+ };
+ }
+ public List getEmailTemplateEnum() {
+ return Arrays.asList(EmailTemplateEnum.values());
+ }
+
+
+ public void setSelectedContent(){
+ emailTemplateModel.setContent(contentsTextbox.getValue());
+ }
+ public String getInitialContentData(){
+ return emailTemplateModel.initializeContent();
+ }
+
+ public void setSelectedSubject(){
+ emailTemplateModel.setSubject(subjectTextbox.getValue());
+ }
+ public String getInitialSubjectData(){
+ return emailTemplateModel.initializeSubject();
+ }
+
+ private void getContentDataBySelectedLanguage(){
+ contentsTextbox.setValue(emailTemplateModel.getContentBySelectedLanguage(getSelectedLanguage().ordinal(), getSelectedEmailTemplateEnum().ordinal()));
+ }
+ private void getContentDataBySelectedTemplate(){
+ contentsTextbox.setValue( emailTemplateModel.getContentBySelectedTemplate( getSelectedEmailTemplateEnum().ordinal(), getSelectedLanguage().ordinal() ) );
+ }
+}
diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/email/EmailTemplateModel.java b/libreplan-webapp/src/main/java/org/libreplan/web/email/EmailTemplateModel.java
new file mode 100644
index 000000000..c54985bf2
--- /dev/null
+++ b/libreplan-webapp/src/main/java/org/libreplan/web/email/EmailTemplateModel.java
@@ -0,0 +1,162 @@
+/*
+ * This file is part of LibrePlan
+ *
+ * Copyright (C) 2015 LibrePlan
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package org.libreplan.web.email;
+
+import org.libreplan.business.common.exceptions.InstanceNotFoundException;
+import org.libreplan.business.settings.entities.Language;
+import org.libreplan.business.email.daos.IEmailTemplateDAO;
+import org.libreplan.business.email.entities.EmailTemplate;
+import org.libreplan.business.email.entities.EmailTemplateEnum;
+import org.libreplan.web.common.concurrentdetection.OnConcurrentModification;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+/**
+ * Model for operations related to {@link EmailTemplate}.
+ *
+ * Created by
+ * @author Vova Perebykivskiy
+ * on 25.09.15.
+ */
+@Service
+@Scope(BeanDefinition.SCOPE_PROTOTYPE)
+@OnConcurrentModification(goToPage = "/email/email_templates.zul")
+public class EmailTemplateModel implements IEmailTemplateModel {
+
+ @Autowired
+ private IEmailTemplateDAO emailTemplateDAO;
+
+ private Language language = Language.ENGLISH_LANGUAGE;
+
+ private EmailTemplateEnum emailTemplateEnum = EmailTemplateEnum.TEMPLATE_TASK_ASSIGNED_TO_RESOURCE;
+
+ private String content;
+
+ private String subject;
+
+ private EmailTemplate emailTemplate = new EmailTemplate();
+
+ @Override
+ @Transactional
+ public void confirmSave() throws InstanceNotFoundException {
+
+ /* If current EmailTemplate entity (id) is existing in DB than it needs to update.
+ * Else current EmailTemplate entity (id) is creating and getting new values from form.
+ */
+ List emailTemplates = emailTemplateDAO.getAll();
+ EmailTemplate emailTemplateFromDatabase = null;
+
+ for (int i = 0; i < emailTemplates.size(); i++) {
+ if ( emailTemplate.getLanguage() == emailTemplates.get(i).getLanguage() &&
+ emailTemplate.getType() == emailTemplates.get(i).getType() ) {
+ emailTemplateFromDatabase = emailTemplateDAO.find(emailTemplates.get(i).getId());
+ }
+ }
+
+ if ( emailTemplateFromDatabase != null ){
+ EmailTemplate temporaryEntity = emailTemplate;
+ emailTemplate = emailTemplateFromDatabase;
+
+ emailTemplate.setType(temporaryEntity.getType());
+ emailTemplate.setLanguage(temporaryEntity.getLanguage());
+ emailTemplate.setContent(temporaryEntity.getContent());
+ emailTemplate.setSubject(temporaryEntity.getSubject());
+ } else {
+ EmailTemplate temporaryEntity = emailTemplate;
+ emailTemplate = new EmailTemplate();
+
+ emailTemplate.setType(temporaryEntity.getType());
+ emailTemplate.setLanguage(temporaryEntity.getLanguage());
+ emailTemplate.setContent(temporaryEntity.getContent());
+ emailTemplate.setSubject(temporaryEntity.getSubject());
+ }
+
+ emailTemplateDAO.save(emailTemplate);
+ }
+
+ @Override
+ @Transactional
+ public List getAll() {
+ return emailTemplateDAO.getAll();
+ }
+
+ @Override
+ public Language getLanguage() {
+ return this.emailTemplate.getLanguage();
+ }
+ @Override
+ public void setLanguage(Language language){ this.emailTemplate.setLanguage(language);}
+
+ @Override
+ public EmailTemplateEnum getEmailTemplateEnum() {
+ return this.emailTemplate.getType();
+ }
+ @Override
+ public void setEmailTemplateEnum(EmailTemplateEnum emailTemplateEnum) {
+ this.emailTemplate.setType(emailTemplateEnum);
+ }
+
+ @Override
+ public String getContent() {
+ return this.emailTemplate.getContent();
+ }
+ @Override
+ public void setContent(String content) {
+ this.emailTemplate.setContent(content);
+ }
+
+ @Override
+ public String getSubject() {
+ return this.emailTemplate.getSubject();
+ }
+ @Override
+ public void setSubject(String subject) {
+ this.emailTemplate.setSubject(subject);
+ }
+
+ @Override
+ @Transactional
+ public String initializeContent() {
+ return emailTemplateDAO.initializeContent();
+ }
+
+ @Override
+ @Transactional
+ public String initializeSubject() { return emailTemplateDAO.initializeSubject(); }
+
+ @Override
+ @Transactional
+ public String getContentBySelectedLanguage(int languageOrdinal, int emailTemplateTypeOrdinal) {
+ return emailTemplateDAO.getContentBySelectedLanguage(languageOrdinal, emailTemplateTypeOrdinal);
+ }
+
+ @Override
+ @Transactional
+ public String getContentBySelectedTemplate(int emailTemplateTypeOrdinal, int languageOrdinal) {
+ return emailTemplateDAO.getContentBySelectedTemplate(emailTemplateTypeOrdinal, languageOrdinal);
+ }
+}
+
+
diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/email/IEmailNotificationModel.java b/libreplan-webapp/src/main/java/org/libreplan/web/email/IEmailNotificationModel.java
new file mode 100644
index 000000000..f4ed94648
--- /dev/null
+++ b/libreplan-webapp/src/main/java/org/libreplan/web/email/IEmailNotificationModel.java
@@ -0,0 +1,52 @@
+/*
+ * This file is part of LibrePlan
+ *
+ * Copyright (C) 2015 LibrePlan
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package org.libreplan.web.email;
+
+import org.libreplan.business.common.exceptions.ValidationException;
+import org.libreplan.business.email.entities.EmailTemplateEnum;
+import org.libreplan.business.email.entities.EmailNotification;
+import org.libreplan.business.planner.entities.TaskElement;
+import org.libreplan.business.resources.entities.Resource;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Contract for {@link EmailNotification}
+ *
+ * Created by
+ * @author Vova Perebykivskiy
+ * on 21.10.15.
+ */
+public interface IEmailNotificationModel {
+
+ void confirmSave() throws ValidationException;
+
+ List getAll();
+
+ boolean deleteAll();
+
+ void setType(EmailTemplateEnum type);
+ void setUpdated(Date date);
+ void setResource(Resource resource);
+ void setTask(TaskElement task);
+ void setProject(TaskElement project);
+
+}
diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/email/IEmailTemplateModel.java b/libreplan-webapp/src/main/java/org/libreplan/web/email/IEmailTemplateModel.java
new file mode 100644
index 000000000..09f9f0491
--- /dev/null
+++ b/libreplan-webapp/src/main/java/org/libreplan/web/email/IEmailTemplateModel.java
@@ -0,0 +1,60 @@
+/*
+ * This file is part of LibrePlan
+ *
+ * Copyright (C) 2015 LibrePlan
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package org.libreplan.web.email;
+
+import org.libreplan.business.common.exceptions.InstanceNotFoundException;
+import org.libreplan.business.common.exceptions.ValidationException;
+import org.libreplan.business.email.entities.EmailTemplate;
+import org.libreplan.business.settings.entities.Language;
+import org.libreplan.business.email.entities.EmailTemplateEnum;
+
+import java.util.List;
+
+/**
+ * Contract for {@link EmailTemplate}
+ *
+ * Created by
+ * @author Vova Perebykivskiy
+ * on 28.09.15.
+ */
+public interface IEmailTemplateModel {
+
+ void confirmSave() throws ValidationException, InstanceNotFoundException;
+
+ List getAll();
+
+ String initializeContent();
+ String initializeSubject();
+
+ String getContentBySelectedLanguage(int languageOrdinal, int emailTemplateTypeOrdinal);
+ String getContentBySelectedTemplate(int emailTemplateTypeOrdinal, int languageOrdinal);
+
+ String getContent();
+ void setContent(String content);
+
+ Language getLanguage();
+ void setLanguage(Language language);
+
+ EmailTemplateEnum getEmailTemplateEnum();
+ void setEmailTemplateEnum(EmailTemplateEnum emailTemplateEnum);
+
+ String getSubject();
+ void setSubject(String subject);
+}
diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/planner/allocation/FormBinder.java b/libreplan-webapp/src/main/java/org/libreplan/web/planner/allocation/FormBinder.java
index 177db8c36..a11c78919 100644
--- a/libreplan-webapp/src/main/java/org/libreplan/web/planner/allocation/FormBinder.java
+++ b/libreplan-webapp/src/main/java/org/libreplan/web/planner/allocation/FormBinder.java
@@ -523,6 +523,8 @@ public class FormBinder {
}
});
allocationProduced(allocationResult);
+
+ TaskPropertiesController.allocationResult = allocationResult;
}
/**
diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/planner/tabs/DashboardTabCreator.java b/libreplan-webapp/src/main/java/org/libreplan/web/planner/tabs/DashboardTabCreator.java
index 25084ad33..21ecc1c92 100644
--- a/libreplan-webapp/src/main/java/org/libreplan/web/planner/tabs/DashboardTabCreator.java
+++ b/libreplan-webapp/src/main/java/org/libreplan/web/planner/tabs/DashboardTabCreator.java
@@ -33,6 +33,7 @@ import org.libreplan.business.orders.entities.Order;
import org.libreplan.business.planner.entities.TaskElement;
import org.libreplan.business.resources.daos.IResourcesSearcher;
import org.libreplan.web.dashboard.DashboardController;
+import org.libreplan.web.dashboard.DashboardControllerGlobal;
import org.libreplan.web.planner.order.OrderPlanningController;
import org.libreplan.web.planner.order.PlanningStateCreator;
import org.libreplan.web.planner.order.PlanningStateCreator.PlanningState;
@@ -55,17 +56,19 @@ public class DashboardTabCreator {
public static ITab create(Mode mode,
PlanningStateCreator planningStateCreator,
DashboardController dashboardController,
+ DashboardControllerGlobal dashboardControllerGlobal,
OrderPlanningController orderPlanningController,
Component breadcrumbs,
IResourcesSearcher resourcesSearcher) {
return new DashboardTabCreator(mode, planningStateCreator,
- dashboardController, orderPlanningController, breadcrumbs,
- resourcesSearcher).build();
+ dashboardController, dashboardControllerGlobal, orderPlanningController,
+ breadcrumbs, resourcesSearcher).build();
}
private final PlanningStateCreator planningStateCreator;
private final Mode mode;
private final DashboardController dashboardController;
+ private final DashboardControllerGlobal dashboardControllerGlobal;
private final OrderPlanningController orderPlanningController;
private final Component breadcrumbs;
private final IResourcesSearcher resourcesSearcher;
@@ -73,12 +76,14 @@ public class DashboardTabCreator {
private DashboardTabCreator(Mode mode,
PlanningStateCreator planningStateCreator,
DashboardController dashboardController,
+ DashboardControllerGlobal dashboardControllerGlobal,
OrderPlanningController orderPlanningController,
Component breadcrumbs,
IResourcesSearcher resourcesSearcher) {
this.mode = mode;
this.planningStateCreator = planningStateCreator;
this.dashboardController = dashboardController;
+ this.dashboardControllerGlobal = dashboardControllerGlobal;
this.orderPlanningController = orderPlanningController;
this.breadcrumbs = breadcrumbs;
this.resourcesSearcher = resourcesSearcher;
@@ -86,7 +91,7 @@ public class DashboardTabCreator {
private ITab build() {
return TabOnModeType.forMode(mode)
- .forType(ModeType.GLOBAL, createDashboardTab())
+ .forType(ModeType.GLOBAL, createDashboardGlobalTab())
.forType(ModeType.ORDER, createDashboardTab())
.create();
}
@@ -129,6 +134,34 @@ public class DashboardTabCreator {
}
};
}
+ private ITab createDashboardGlobalTab(){
+ IComponentCreator componentCreator = new IComponentCreator() {
+
+ @Override
+ public org.zkoss.zk.ui.Component create(
+ org.zkoss.zk.ui.Component parent) {
+ Map arguments = new HashMap();
+ arguments.put("dashboardControllerGlobal", dashboardControllerGlobal);
+ return Executions.createComponents(
+ "/dashboard/_dashboardforglobal.zul", parent,
+ arguments);
+ }
+
+ };
+ return new CreatedOnDemandTab(_("Dashboard"), "global-dashboard",
+ componentCreator) {
+
+ @Override
+ protected void afterShowAction() {
+ breadcrumbs.getChildren().clear();
+ breadcrumbs.appendChild(new Image(BREADCRUMBS_SEPARATOR));
+ breadcrumbs.appendChild(new Label(getSchedulingLabel()));
+ breadcrumbs.appendChild(new Image(BREADCRUMBS_SEPARATOR));
+ breadcrumbs.appendChild(new Label(_("Dashboard")));
+ }
+ };
+
+ }
private List getCriticalPath(final Order order, final Desktop desktop) {
CriticalPathBuilder builder = CriticalPathBuilder.create(
diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/planner/tabs/MultipleTabsPlannerController.java b/libreplan-webapp/src/main/java/org/libreplan/web/planner/tabs/MultipleTabsPlannerController.java
index de74b9be5..7b5db901a 100644
--- a/libreplan-webapp/src/main/java/org/libreplan/web/planner/tabs/MultipleTabsPlannerController.java
+++ b/libreplan-webapp/src/main/java/org/libreplan/web/planner/tabs/MultipleTabsPlannerController.java
@@ -40,6 +40,7 @@ import org.libreplan.web.common.ConfirmCloseUtil;
import org.libreplan.web.common.entrypoints.EntryPointsHandler;
import org.libreplan.web.common.entrypoints.URLHandlerRegistry;
import org.libreplan.web.dashboard.DashboardController;
+import org.libreplan.web.dashboard.DashboardControllerGlobal;
import org.libreplan.web.limitingresources.LimitingResourcesController;
import org.libreplan.web.montecarlo.MonteCarloController;
import org.libreplan.web.orders.OrderCRUDController;
@@ -67,6 +68,7 @@ import org.zkoss.ganttz.extensions.TabProxy;
import org.zkoss.ganttz.util.LongOperationFeedback;
import org.zkoss.ganttz.util.LongOperationFeedback.ILongOperation;
import org.zkoss.zk.ui.Desktop;
+import org.zkoss.zk.ui.Execution;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
@@ -84,6 +86,8 @@ import org.zkoss.zk.ui.util.Composer;
public class MultipleTabsPlannerController implements Composer,
IGlobalViewEntryPoints {
+ public static String WELCOME_URL = "-- no URL provided --";
+
private final class TabWithLoadingFeedback extends TabProxy {
private boolean feedback = true;
@@ -183,6 +187,9 @@ public class MultipleTabsPlannerController implements Composer,
@Autowired
private DashboardController dashboardController;
+ @Autowired
+ private DashboardControllerGlobal dashboardControllerGlobal;
+
private org.zkoss.zk.ui.Component breadcrumbs;
@Autowired
@@ -293,7 +300,7 @@ public class MultipleTabsPlannerController implements Composer,
}, parameters);
dashboardTab = DashboardTabCreator.create(mode, planningStateCreator,
- dashboardController, orderPlanningController, breadcrumbs,
+ dashboardController, dashboardControllerGlobal, orderPlanningController, breadcrumbs,
resourcesSearcher);
final boolean isMontecarloVisible = isMonteCarloVisible();
@@ -321,7 +328,7 @@ public class MultipleTabsPlannerController implements Composer,
resourceLoadTab, typeChanged));
}
tabsConfiguration.add(visibleOnlyAtOrderMode(advancedAllocationTab))
- .add(visibleOnlyAtOrderMode(dashboardTab));
+ .add(tabWithNameReloading(dashboardTab, typeChanged));
if (isMontecarloVisible) {
tabsConfiguration.add(visibleOnlyAtOrderMode(monteCarloTab));
@@ -419,6 +426,10 @@ public class MultipleTabsPlannerController implements Composer,
@Override
@Transactional(readOnly=true)
public void doAfterCompose(org.zkoss.zk.ui.Component comp) {
+
+ Execution execution = Executions.getCurrent();
+ WELCOME_URL = "http://" + execution.getServerName() + ":" + execution.getServerPort() + Executions.encodeURL("/planner/index.zul");
+
tabsSwitcher = (TabSwitcher) comp;
breadcrumbs = comp.getPage().getFellow("breadcrumbs");
tabsSwitcher
diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/planner/taskedition/TaskPropertiesController.java b/libreplan-webapp/src/main/java/org/libreplan/web/planner/taskedition/TaskPropertiesController.java
index ea07b713e..4934390af 100644
--- a/libreplan-webapp/src/main/java/org/libreplan/web/planner/taskedition/TaskPropertiesController.java
+++ b/libreplan-webapp/src/main/java/org/libreplan/web/planner/taskedition/TaskPropertiesController.java
@@ -33,6 +33,7 @@ import org.libreplan.business.advance.bootstrap.PredefinedAdvancedTypes;
import org.libreplan.business.advance.entities.AdvanceType;
import org.libreplan.business.advance.entities.DirectAdvanceAssignment;
import org.libreplan.business.advance.exceptions.DuplicateAdvanceAssignmentForOrderElementException;
+import org.libreplan.business.email.entities.EmailTemplateEnum;
import org.libreplan.business.orders.entities.Order;
import org.libreplan.business.orders.entities.OrderElement;
import org.libreplan.business.planner.entities.ITaskPositionConstrained;
@@ -40,10 +41,18 @@ import org.libreplan.business.planner.entities.PositionConstraintType;
import org.libreplan.business.planner.entities.Task;
import org.libreplan.business.planner.entities.TaskElement;
import org.libreplan.business.planner.entities.TaskPositionConstraint;
+import org.libreplan.business.resources.entities.Resource;
+import org.libreplan.business.resources.entities.Worker;
import org.libreplan.business.scenarios.IScenarioManager;
+import org.libreplan.business.users.entities.User;
+import org.libreplan.business.users.entities.UserRole;
import org.libreplan.business.workingday.IntraDayDate;
import org.libreplan.web.I18nHelper;
import org.libreplan.web.common.Util;
+import org.libreplan.web.email.IEmailNotificationModel;
+import org.libreplan.web.orders.IOrderModel;
+import org.libreplan.web.planner.allocation.AllocationResult;
+import org.libreplan.web.resources.worker.IWorkerModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
@@ -117,6 +126,16 @@ public class TaskPropertiesController extends GenericForwardComposer {
private boolean disabledConstraintsAndAllocations = false;
+ public static AllocationResult allocationResult;
+
+ private IEmailNotificationModel emailNotificationModel;
+
+ private IOrderModel orderModel;
+
+ private IWorkerModel workerModel;
+
+
+
public void init(final EditTaskController editTaskController,
IContextWithPlannerTask context,
TaskElement taskElement) {
@@ -414,6 +433,8 @@ public class TaskPropertiesController extends GenericForwardComposer {
}
public void accept() {
+ EmailNotificationAddNewWithTaskAssignedToResource();
+
boolean ok = true;
if (currentTaskElement instanceof ITaskPositionConstrained) {
ok = saveConstraintChanges();
@@ -709,4 +730,49 @@ public class TaskPropertiesController extends GenericForwardComposer {
return Util.getMoneyFormat();
}
+ private void EmailNotificationAddNewWithTaskAssignedToResource(){
+
+ if ( allocationResult != null ) {
+
+ /* Check if resources in allocation are bound by user and are in role ROLE_EMAIL_TASK_ASSIGNED_TO_RESOURCE
+ * setUser method calling manually because, after initialization user will be null
+ * Then send valid data to notification_queue table */
+
+ List workersList = workerModel.getWorkers();
+ Worker currentWorker;
+ Resource currentResource;
+ User currentUser;
+
+ for (int i = 0; i < workersList.size(); i++)
+
+ for (int j = 0; j < allocationResult.getSpecificAllocations().size(); j++){
+
+ currentWorker = workersList.get(i);
+ currentResource = allocationResult.getSpecificAllocations().get(j).getResource();
+
+ if ( currentWorker.getId().equals(currentResource.getId()) ){
+
+ workersList.get(i).setUser(workerModel.getBoundUserFromDB(currentWorker));
+ currentUser = currentWorker.getUser();
+
+ if ( currentUser != null &&
+ currentUser.isInRole(UserRole.ROLE_EMAIL_TASK_ASSIGNED_TO_RESOURCE) ) {
+
+ emailNotificationModel.setType(EmailTemplateEnum.TEMPLATE_TASK_ASSIGNED_TO_RESOURCE);
+
+ emailNotificationModel.setUpdated(new Date());
+
+ emailNotificationModel.setResource(allocationResult.getSpecificAllocations().get(j).getResource());
+
+ emailNotificationModel.setTask(currentTaskElement.getTaskSource().getTask());
+
+ emailNotificationModel.setProject(currentTaskElement.getParent().getTaskSource().getTask());
+
+ emailNotificationModel.confirmSave();
+ }
+ }
+ }
+ }
+ }
+
}
diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/users/settings/SettingsController.java b/libreplan-webapp/src/main/java/org/libreplan/web/users/settings/SettingsController.java
index abf2f1625..6cfa2cf61 100644
--- a/libreplan-webapp/src/main/java/org/libreplan/web/users/settings/SettingsController.java
+++ b/libreplan-webapp/src/main/java/org/libreplan/web/users/settings/SettingsController.java
@@ -26,7 +26,6 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
-import java.util.logging.Filter;
import org.libreplan.business.common.exceptions.ValidationException;
import org.libreplan.business.labels.entities.Label;
@@ -38,8 +37,6 @@ import org.libreplan.web.common.Level;
import org.libreplan.web.common.MessagesForUser;
import org.libreplan.web.common.components.bandboxsearch.BandboxSearch;
import org.zkoss.zk.ui.Component;
-import org.zkoss.zk.ui.Session;
-import org.zkoss.zk.ui.Sessions;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
diff --git a/libreplan-webapp/src/main/resources/i18n/ca.po b/libreplan-webapp/src/main/resources/i18n/ca.po
index 19e33dfc6..b55907eb0 100644
--- a/libreplan-webapp/src/main/resources/i18n/ca.po
+++ b/libreplan-webapp/src/main/resources/i18n/ca.po
@@ -8474,8 +8474,8 @@ msgid "CANCELLED"
msgstr "CANCEL·LAT"
#: libreplan-business/src/main/java/org/libreplan/business/orders/entities/OrderStatusEnum.java:41
-msgid "STORED"
-msgstr "EMMAGATZEMAT"
+msgid "ARCHIVED"
+msgstr ""
#: libreplan-business/src/main/java/org/libreplan/business/orders/entities/SchedulingState.java:366
msgid "Fully scheduled"
diff --git a/libreplan-webapp/src/main/resources/i18n/cs.po b/libreplan-webapp/src/main/resources/i18n/cs.po
index 673917ffd..0d33c9645 100644
--- a/libreplan-webapp/src/main/resources/i18n/cs.po
+++ b/libreplan-webapp/src/main/resources/i18n/cs.po
@@ -8361,8 +8361,8 @@ msgid "SUBCONTRACTED PENDING PROJECT"
msgstr "SUBKONTRAKTOVANÝ NEVYŘÍZENÝ PROJEKT"
#: libreplan-business/src/main/java/org/libreplan/business/orders/entities/OrderStatusEnum.java:35
-msgid "STORED"
-msgstr "ULOŽENO"
+msgid "ARCHIVED"
+msgstr ""
#: libreplan-business/src/main/java/org/libreplan/business/orders/entities/SchedulingState.java:366
msgid "Fully scheduled"
diff --git a/libreplan-webapp/src/main/resources/i18n/de.po b/libreplan-webapp/src/main/resources/i18n/de.po
index 3bfe4ed56..55c76e3a3 100644
--- a/libreplan-webapp/src/main/resources/i18n/de.po
+++ b/libreplan-webapp/src/main/resources/i18n/de.po
@@ -8362,7 +8362,7 @@ msgid "SUBCONTRACTED PENDING PROJECT"
msgstr "UNTERVERGEBENES, AUSTEHENDES PROJEKT "
#: libreplan-business/src/main/java/org/libreplan/business/orders/entities/OrderStatusEnum.java:35
-msgid "STORED"
+msgid "ARCHIVED"
msgstr "GESPEICHERT"
#: libreplan-business/src/main/java/org/libreplan/business/orders/entities/SchedulingState.java:366
diff --git a/libreplan-webapp/src/main/resources/i18n/es.po b/libreplan-webapp/src/main/resources/i18n/es.po
index 7aff1ea06..46f9d3706 100644
--- a/libreplan-webapp/src/main/resources/i18n/es.po
+++ b/libreplan-webapp/src/main/resources/i18n/es.po
@@ -9191,8 +9191,8 @@ msgid "CANCELLED"
msgstr "CANCELADO"
#: libreplan-business/src/main/java/org/libreplan/business/orders/entities/OrderStatusEnum.java:43
-msgid "STORED"
-msgstr "ARCHIVADO"
+msgid "ARCHIVED"
+msgstr ""
#: libreplan-business/src/main/java/org/libreplan/business/orders/entities/CriterionRequirementHandler.java:539
msgid "The criterion already exists into another task"
diff --git a/libreplan-webapp/src/main/resources/i18n/fr.po b/libreplan-webapp/src/main/resources/i18n/fr.po
index 7df3a8513..555eb2c9a 100644
--- a/libreplan-webapp/src/main/resources/i18n/fr.po
+++ b/libreplan-webapp/src/main/resources/i18n/fr.po
@@ -9191,8 +9191,8 @@ msgid "CANCELLED"
msgstr "ANNULE"
#: libreplan-business/src/main/java/org/libreplan/business/orders/entities/OrderStatusEnum.java:43
-msgid "STORED"
-msgstr "ENREGISTRE"
+msgid "ARCHIVED"
+msgstr ""
#: libreplan-business/src/main/java/org/libreplan/business/orders/entities/CriterionRequirementHandler.java:539
msgid "The criterion already exists into another task"
diff --git a/libreplan-webapp/src/main/resources/i18n/gl.po b/libreplan-webapp/src/main/resources/i18n/gl.po
index d64a556c7..46178db1e 100644
--- a/libreplan-webapp/src/main/resources/i18n/gl.po
+++ b/libreplan-webapp/src/main/resources/i18n/gl.po
@@ -9190,8 +9190,8 @@ msgid "CANCELLED"
msgstr "CANCELADO"
#: libreplan-business/src/main/java/org/libreplan/business/orders/entities/OrderStatusEnum.java:43
-msgid "STORED"
-msgstr "ARCHIVADO"
+msgid "ARCHIVED"
+msgstr ""
#: libreplan-business/src/main/java/org/libreplan/business/orders/entities/CriterionRequirementHandler.java:539
msgid "The criterion already exists into another task"
diff --git a/libreplan-webapp/src/main/resources/i18n/it.po b/libreplan-webapp/src/main/resources/i18n/it.po
index 059fe0574..8c2b38a34 100644
--- a/libreplan-webapp/src/main/resources/i18n/it.po
+++ b/libreplan-webapp/src/main/resources/i18n/it.po
@@ -9188,7 +9188,7 @@ msgid "CANCELLED"
msgstr "CANCELLATO"
#: libreplan-business/src/main/java/org/libreplan/business/orders/entities/OrderStatusEnum.java:43
-msgid "STORED"
+msgid "ARCHIVED"
msgstr "IMMAGAZZINATO"
#: libreplan-business/src/main/java/org/libreplan/business/orders/entities/CriterionRequirementHandler.java:539
diff --git a/libreplan-webapp/src/main/resources/i18n/keys.pot b/libreplan-webapp/src/main/resources/i18n/keys.pot
index 5f9ef0927..abbce181b 100644
--- a/libreplan-webapp/src/main/resources/i18n/keys.pot
+++ b/libreplan-webapp/src/main/resources/i18n/keys.pot
@@ -889,6 +889,7 @@ msgstr ""
#: libreplan-webapp/src/main/webapp/resources/worker/_edition.zul:122
#: libreplan-webapp/src/main/webapp/resources/worker/_edition.zul:158
#: libreplan-webapp/src/main/webapp/users/_editUser.zul:84
+#: libreplan-business/src/main/java/org/libreplan/business/common/entities/PredefinedConnectorProperties.java:56
msgid "E-mail"
msgstr ""
@@ -1363,6 +1364,7 @@ msgid "First expense"
msgstr ""
#: libreplan-webapp/src/main/webapp/common/configuration.zul:296
+#: libreplan-business/src/main/java/org/libreplan/business/common/entities/PredefinedConnectorProperties.java:55
msgid "Host"
msgstr ""
@@ -7762,6 +7764,7 @@ msgstr ""
#: libreplan-webapp/src/main/webapp/orders/_orderElementDetails.zul:59
#: libreplan-webapp/src/main/webapp/qualityforms/_listQualityForm.zul:37
#: libreplan-webapp/src/main/webapp/qualityforms/_editQualityForm.zul:49
+#: libreplan-webapp/src/main/webapp/email/email_templates.zul:83
msgid "Description"
msgstr ""
@@ -9185,7 +9188,7 @@ msgid "CANCELLED"
msgstr ""
#: libreplan-business/src/main/java/org/libreplan/business/orders/entities/OrderStatusEnum.java:43
-msgid "STORED"
+msgid "ARCHIVED"
msgstr ""
#: libreplan-business/src/main/java/org/libreplan/business/orders/entities/CriterionRequirementHandler.java:539
@@ -9212,3 +9215,75 @@ msgstr ""
#: libreplan-business/src/main/java/org/libreplan/business/settings/entities/Language.java:36
msgid "Use browser language configuration"
msgstr ""
+
+#: libreplan-business/src/main/java/org/libreplan/business/templates/entities/EmailTemplateEnum.java:17
+msgid "Task assigned to resource"
+msgstr ""
+
+#: libreplan-webapp/src/main/java/org/libreplan/web/common/CustomMenuController.java:425
+msgid "Edit E-mail Templates"
+msgstr ""
+
+#: libreplan-webapp/src/main/java/org/libreplan/web/templates/EmailTemplateController.java:72
+msgid "E-mail template saved"
+msgstr ""
+
+#: libreplan-business/src/main/java/org/libreplan/business/common/entities/PredefinedConnectorProperties.java:57
+msgid "Port"
+msgstr ""
+
+#: libreplan-business/src/main/java/org/libreplan/business/common/entities/PredefinedConnectorProperties.java:56
+msgid "Protocol"
+msgstr ""
+
+#: libreplan-webapp/src/main/webapp/email/email_templates.zul:79
+msgid "Possible content keywords"
+msgstr ""
+
+#: libreplan-webapp/src/main/webapp/java/org/libreplan/web/planner/tabs/MultipleTabsPlannerController:90
+msgid "-- no URL provided --"
+msgstr ""
+
+#: libreplan-webapp/src/main/java/org/libreplan/web/common/ConfigurationController.java:1307
+msgid "Not correct E-mail address"
+msgstr ""
+
+#: libreplan-webapp/src/main/webapp/email/email_templates.zul:82
+msgid "Keyword"
+msgstr ""
+
+#: libreplan-webapp/src/main/webapp/email/email_templates.zul:89
+msgid "Username of user"
+msgstr ""
+
+#: libreplan-webapp/src/main/webapp/email/email_templates.zul:94
+msgid "First name of user"
+msgstr ""
+
+#: libreplan-webapp/src/main/webapp/email/email_templates.zul:99
+msgid "Last name of user"
+msgstr ""
+
+#: libreplan-webapp/src/main/webapp/email/email_templates.zul:104
+msgid "Name of project"
+msgstr ""
+
+#: libreplan-webapp/src/main/webapp/email/email_templates.zul:109
+msgid "Name of resource"
+msgstr ""
+
+#: libreplan-webapp/src/main/webapp/email/email_templates.zul:114
+msgid "Name of task"
+msgstr ""
+
+#: libreplan-webapp/src/main/webapp/email/email_templates.zul:119
+msgid "Welcome page"
+msgstr ""
+
+#: libreplan-business/src/main/java/org/libreplan/business/orders/entities/OrderStatusEnum.java:43
+msgid "ARCHIVED"
+msgstr ""
+
+#: libreplan-webapp/src/main/webapp/dashboard/_pipeline.zul:2
+msgid "Show archived column data"
+msgstr ""
diff --git a/libreplan-webapp/src/main/resources/i18n/nb.po b/libreplan-webapp/src/main/resources/i18n/nb.po
index 6bf45d399..2e5407cf7 100644
--- a/libreplan-webapp/src/main/resources/i18n/nb.po
+++ b/libreplan-webapp/src/main/resources/i18n/nb.po
@@ -9006,8 +9006,8 @@ msgid "CANCELLED"
msgstr "AVLYST"
#: libreplan-business/src/main/java/org/libreplan/business/orders/entities/OrderStatusEnum.java:43
-msgid "STORED"
-msgstr "LAGRET"
+msgid "ARCHIVED"
+msgstr ""
#: libreplan-business/src/main/java/org/libreplan/business/orders/entities/SchedulingState.java:366
msgid "Fully scheduled"
diff --git a/libreplan-webapp/src/main/resources/i18n/nl.po b/libreplan-webapp/src/main/resources/i18n/nl.po
index 80c57ee0a..e2c0da5b5 100644
--- a/libreplan-webapp/src/main/resources/i18n/nl.po
+++ b/libreplan-webapp/src/main/resources/i18n/nl.po
@@ -9188,8 +9188,8 @@ msgid "CANCELLED"
msgstr "AFGEBROKEN"
#: libreplan-business/src/main/java/org/libreplan/business/orders/entities/OrderStatusEnum.java:43
-msgid "STORED"
-msgstr "OPGESLAGEN"
+msgid "ARCHIVED"
+msgstr ""
#: libreplan-business/src/main/java/org/libreplan/business/orders/entities/CriterionRequirementHandler.java:539
msgid "The criterion already exists into another task"
diff --git a/libreplan-webapp/src/main/resources/i18n/pl.po b/libreplan-webapp/src/main/resources/i18n/pl.po
index f6dc79f3f..4a5033559 100644
--- a/libreplan-webapp/src/main/resources/i18n/pl.po
+++ b/libreplan-webapp/src/main/resources/i18n/pl.po
@@ -7109,8 +7109,8 @@ msgid "SUBCONTRACTED PENDING PROJECT"
msgstr "Nierozstrzygnięty pracowany"
#: libreplan-business/src/main/java/org/libreplan/business/orders/entities/OrderStatusEnum.java:35
-msgid "STORED"
-msgstr "Przechowywane"
+msgid "ARCHIVED"
+msgstr ""
#: libreplan-business/src/main/java/org/libreplan/business/orders/entities/SchedulingState.java:215
msgid "it's already somewhat scheduled"
diff --git a/libreplan-webapp/src/main/resources/i18n/pt.po b/libreplan-webapp/src/main/resources/i18n/pt.po
index bab7846da..4686264bf 100644
--- a/libreplan-webapp/src/main/resources/i18n/pt.po
+++ b/libreplan-webapp/src/main/resources/i18n/pt.po
@@ -8476,8 +8476,8 @@ msgid "CANCELLED"
msgstr "CANCELADO"
#: libreplan-business/src/main/java/org/libreplan/business/orders/entities/OrderStatusEnum.java:41
-msgid "STORED"
-msgstr "Arquivado"
+msgid "ARCHIVED"
+msgstr ""
#: libreplan-business/src/main/java/org/libreplan/business/orders/entities/SchedulingState.java:366
msgid "Fully scheduled"
diff --git a/libreplan-webapp/src/main/resources/i18n/ru.po b/libreplan-webapp/src/main/resources/i18n/ru.po
index 55c22ce77..948e3dbac 100644
--- a/libreplan-webapp/src/main/resources/i18n/ru.po
+++ b/libreplan-webapp/src/main/resources/i18n/ru.po
@@ -6711,3 +6711,7 @@ msgstr "Итоговая стоимость"
#: libreplan-webapp/src/main/webapp/excetiondays/_listExceptionDayTypes.zul:54
msgid "Delete"
msgstr "Удалить"
+
+#: libreplan-business/src/main/java/org/libreplan/business/orders/entities/OrderStatusEnum.java:43
+msgid "ARCHIVED"
+msgstr "Заархивированный"
diff --git a/libreplan-webapp/src/main/resources/i18n/zh.po b/libreplan-webapp/src/main/resources/i18n/zh.po
index 05c8efeab..091933f81 100644
--- a/libreplan-webapp/src/main/resources/i18n/zh.po
+++ b/libreplan-webapp/src/main/resources/i18n/zh.po
@@ -8474,8 +8474,8 @@ msgid "CANCELLED"
msgstr "已取消"
#: libreplan-business/src/main/java/org/libreplan/business/orders/entities/OrderStatusEnum.java:41
-msgid "STORED"
-msgstr "STORED"
+msgid "ARCHIVED"
+msgstr ""
#: libreplan-business/src/main/java/org/libreplan/business/orders/entities/SchedulingState.java:366
msgid "Fully scheduled"
diff --git a/libreplan-webapp/src/main/resources/libreplan-webapp-spring-security-config.xml b/libreplan-webapp/src/main/resources/libreplan-webapp-spring-security-config.xml
index 76c1333e1..8cea71490 100644
--- a/libreplan-webapp/src/main/resources/libreplan-webapp-spring-security-config.xml
+++ b/libreplan-webapp/src/main/resources/libreplan-webapp-spring-security-config.xml
@@ -55,6 +55,8 @@
+
+
+
+
+
+
1-12 ( [JAN-DEC])
+
- 0-7 ( [SUN-SAT])
+ 1-7 ( [SUN-SAT])
+
+
+
+ ${i18n:_("The '?' character is allowed for the day-of-month and day-of-week fields. It is used to specify “no specific value”. ")}
+
+
${i18n:_("For more details on cron expression click")}
${i18n:_('here')}.