diff --git a/libreplan-business/src/main/java/org/libreplan/business/common/entities/Connector.java b/libreplan-business/src/main/java/org/libreplan/business/common/entities/Connector.java
index b1a621618..e57458358 100644
--- a/libreplan-business/src/main/java/org/libreplan/business/common/entities/Connector.java
+++ b/libreplan-business/src/main/java/org/libreplan/business/common/entities/Connector.java
@@ -19,6 +19,8 @@
package org.libreplan.business.common.entities;
+import java.net.MalformedURLException;
+import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -118,4 +120,29 @@ public class Connector extends BaseEntity {
"Y");
}
+ /**
+ * Check if connector's connections values are valid
+ *
+ * @return true if connection values are valid
+ */
+ public boolean areConnectionValuesValid() {
+ String serverUrl = getPropertiesAsMap().get(
+ PredefinedConnectorProperties.SERVER_URL);
+ try {
+ new URL(serverUrl);
+ } catch (MalformedURLException e) {
+ return false;
+ }
+
+ if (StringUtils.isBlank(getPropertiesAsMap().get(
+ PredefinedConnectorProperties.USERNAME))) {
+ return false;
+ }
+
+ if (StringUtils.isBlank(getPropertiesAsMap().get(
+ PredefinedConnectorProperties.PASSWORD))) {
+ return false;
+ }
+ return true;
+ }
}
diff --git a/libreplan-business/src/main/java/org/libreplan/business/common/entities/ConnectorException.java b/libreplan-business/src/main/java/org/libreplan/business/common/entities/ConnectorException.java
new file mode 100644
index 000000000..062666893
--- /dev/null
+++ b/libreplan-business/src/main/java/org/libreplan/business/common/entities/ConnectorException.java
@@ -0,0 +1,33 @@
+/*
+ * This file is part of LibrePlan
+ *
+ * Copyright (C) 2013 St. Antoniusziekenhuis
+ *
+ * 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.common.entities;
+
+/**
+ * Exception to ecapsulate connector(values) exceptions
+ *
+ * @author Miciele Ghiorghis
+ */
+public class ConnectorException extends Exception {
+
+ public ConnectorException(String message) {
+ super(message);
+ }
+
+}
diff --git a/libreplan-business/src/main/resources/org/libreplan/business/common/entities/Connector.hbm.xml b/libreplan-business/src/main/resources/org/libreplan/business/common/entities/Connector.hbm.xml
index f85f60867..4a1b86870 100644
--- a/libreplan-business/src/main/resources/org/libreplan/business/common/entities/Connector.hbm.xml
+++ b/libreplan-business/src/main/resources/org/libreplan/business/common/entities/Connector.hbm.xml
@@ -14,7 +14,7 @@
-
+
diff --git a/libreplan-webapp/src/main/java/org/libreplan/importers/ExportTimesheetToTimJob.java b/libreplan-webapp/src/main/java/org/libreplan/importers/ExportTimesheetToTimJob.java
index 20d45268e..31c8b1cf6 100644
--- a/libreplan-webapp/src/main/java/org/libreplan/importers/ExportTimesheetToTimJob.java
+++ b/libreplan-webapp/src/main/java/org/libreplan/importers/ExportTimesheetToTimJob.java
@@ -19,6 +19,9 @@
package org.libreplan.importers;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.libreplan.business.common.entities.ConnectorException;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.context.ApplicationContext;
@@ -30,6 +33,8 @@ import org.springframework.scheduling.quartz.QuartzJobBean;
* @author Miciele Ghiorghis
*/
public class ExportTimesheetToTimJob extends QuartzJobBean {
+ private static final Log LOG = LogFactory
+ .getLog(ExportTimesheetToTimJob.class);
@Override
protected void executeInternal(JobExecutionContext context)
@@ -40,7 +45,14 @@ public class ExportTimesheetToTimJob extends QuartzJobBean {
IExportTimesheetsToTim exportTimesheetsToTim = (IExportTimesheetsToTim) applicationContext
.getBean("exportTimesheetsToTim");
- exportTimesheetsToTim.exportTimesheets();
+ try {
+ exportTimesheetsToTim.exportTimesheets();
+ LOG.info("Export scuccessful: "
+ + exportTimesheetsToTim.getExportProcessInfo()
+ .isSuccessful());
+ } catch (ConnectorException e) {
+ LOG.error("Export timesheet to Tim failed", e);
+ }
}
}
diff --git a/libreplan-webapp/src/main/java/org/libreplan/importers/ExportTimesheetsToTim.java b/libreplan-webapp/src/main/java/org/libreplan/importers/ExportTimesheetsToTim.java
index ff236c4be..a05ad0eab 100644
--- a/libreplan-webapp/src/main/java/org/libreplan/importers/ExportTimesheetsToTim.java
+++ b/libreplan-webapp/src/main/java/org/libreplan/importers/ExportTimesheetsToTim.java
@@ -33,6 +33,7 @@ import org.libreplan.business.common.IOnTransaction;
import org.libreplan.business.common.daos.IConfigurationDAO;
import org.libreplan.business.common.daos.IConnectorDAO;
import org.libreplan.business.common.entities.Connector;
+import org.libreplan.business.common.entities.ConnectorException;
import org.libreplan.business.common.entities.PredefinedConnectorProperties;
import org.libreplan.business.common.entities.PredefinedConnectors;
import org.libreplan.business.common.exceptions.InstanceNotFoundException;
@@ -91,47 +92,67 @@ public class ExportTimesheetsToTim implements IExportTimesheetsToTim {
@Autowired
private IOrderDAO orderDAO;
+ private TimImpExpInfo timImpExpInfo;
+
+ /**
+ * Action name
+ */
+ private static final String EXPORT = "Export";
+
@Override
@Transactional(readOnly = true)
- public void exportTimesheets() {
- String name = PredefinedConnectors.TIM.getName();
- Connector connector = connectorDAO.findUniqueByName(name);
+ public void exportTimesheets() throws ConnectorException {
+ Connector connector = getTimConnector();
if (connector == null) {
- return;
+ throw new ConnectorException("Tim connector not found");
}
+ if (!connector.areConnectionValuesValid()) {
+ throw new ConnectorException(
+ "Connection values of Tim connector are invalid");
+ }
+
+ timImpExpInfo = new TimImpExpInfo(EXPORT);
List orders = orderDAO.getOrders();
for (Order order : orders) {
- OrderSyncInfo orderSyncInfo = orderSyncInfoDAO
- .findLastSynchronizedInfoByOrderAndConnectorId(order,
- name);
+ OrderSyncInfo orderSyncInfo = getOrderLastSyncInfo(order);
if (orderSyncInfo == null) {
LOG.warn("Order '" + order.getName()
+ "' is not yet synchronized");
+ timImpExpInfo.addFailedReason("Order '" + order.getName()
+ + "' is not yet synchronized");
} else {
- boolean result = exportTimesheets(orderSyncInfo.getKey(),
+ LOG.info("Exporting '" + order.getName() + "'");
+ exportTimesheets(orderSyncInfo.getKey(),
orderSyncInfo.getOrder(), connector);
- LOG.info("Export successful: " + result);
}
}
}
@Override
@Transactional(readOnly = true)
- public boolean exportTimesheets(String productCode, Order order) {
+ public void exportTimesheets(String productCode, Order order)
+ throws ConnectorException {
if (productCode == null || productCode.isEmpty()) {
throw new RuntimeException("Product code should not be empty");
}
if (order == null) {
throw new RuntimeException("Order should not be empty");
}
- Connector connector = connectorDAO
- .findUniqueByName(PredefinedConnectors.TIM.getName());
+
+ Connector connector = getTimConnector();
if (connector == null) {
- throw new RuntimeException("Tim connector not found");
+ throw new ConnectorException("Tim connector not found");
}
- return exportTimesheets(productCode, order, connector);
+ if (!connector.areConnectionValuesValid()) {
+ throw new ConnectorException(
+ "Connection values of Tim connector are invalid");
+ }
+
+ timImpExpInfo = new TimImpExpInfo(EXPORT);
+
+ exportTimesheets(productCode, order, connector);
}
/**
@@ -146,7 +167,7 @@ public class ExportTimesheetsToTim implements IExportTimesheetsToTim {
*
* @return true if export is succeeded, false otherwise
*/
- private boolean exportTimesheets(String productCode, Order order,
+ private void exportTimesheets(String productCode, Order order,
Connector connector) {
Map properties = connector.getPropertiesAsMap();
@@ -165,8 +186,12 @@ public class ExportTimesheetsToTim implements IExportTimesheetsToTim {
dateNrOfDaysBack.toDateTimeAtStartOfDay().toDate(), new Date(),
true);
if (workReportLines == null || workReportLines.isEmpty()) {
- LOG.warn("No work reportlines are found");
- return false;
+ LOG.warn("No work reportlines are found for order: '"
+ + order.getName() + "'");
+ timImpExpInfo
+ .addFailedReason("No work reportlines are found for order: '"
+ + order.getName() + "'");
+ return;
}
List timeRegistrationDTOs = new ArrayList();
@@ -181,7 +206,9 @@ public class ExportTimesheetsToTim implements IExportTimesheetsToTim {
if (timeRegistrationDTOs.isEmpty()) {
LOG.warn("Unable to crate timeregistration for request");
- return false;
+ timImpExpInfo
+ .addFailedReason("Unable to crate timeregistration for request");
+ return;
}
TimeRegistrationRequestDTO timeRegistrationRequestDTO = new TimeRegistrationRequestDTO();
@@ -191,12 +218,20 @@ public class ExportTimesheetsToTim implements IExportTimesheetsToTim {
.sendRequestReceiveResponse(url, userName, password,
timeRegistrationRequestDTO, TimeRegistrationResponseDTO.class);
+ if (timeRegistrationResponseDTO == null) {
+ LOG.error("No response or exception in response");
+ timImpExpInfo
+ .addFailedReason("No response or exception in response");
+ return;
+ }
+
if (isRefsListEmpty(timeRegistrationResponseDTO.getRefs())) {
LOG.warn("Registration response with empty refs");
- return false;
+ timImpExpInfo
+ .addFailedReason("Registration response with empty refs");
+ return;
}
saveSyncInfoOnAnotherTransaction(productCode, order);
- return true;
}
/**
@@ -254,6 +289,8 @@ public class ExportTimesheetsToTim implements IExportTimesheetsToTim {
worker = workerDAO.findByCode(workerCode);
} catch (InstanceNotFoundException e) {
LOG.warn("Worker \"" + workerCode + "\" not found!");
+ timImpExpInfo.addFailedReason("Worker \"" + workerCode
+ + "\" not found!");
return null;
}
@@ -289,4 +326,17 @@ public class ExportTimesheetsToTim implements IExportTimesheetsToTim {
order, PredefinedConnectors.TIM.getName());
}
+ /**
+ * finds and returns a Tim connector
+ */
+ private Connector getTimConnector() {
+ return connectorDAO
+ .findUniqueByName(PredefinedConnectors.TIM.getName());
+ }
+
+ @Override
+ public TimImpExpInfo getExportProcessInfo() {
+ return timImpExpInfo;
+ }
+
}
diff --git a/libreplan-webapp/src/main/java/org/libreplan/importers/IExportTimesheetsToTim.java b/libreplan-webapp/src/main/java/org/libreplan/importers/IExportTimesheetsToTim.java
index 7a8645384..fd3df810e 100644
--- a/libreplan-webapp/src/main/java/org/libreplan/importers/IExportTimesheetsToTim.java
+++ b/libreplan-webapp/src/main/java/org/libreplan/importers/IExportTimesheetsToTim.java
@@ -20,6 +20,7 @@
package org.libreplan.importers;
import org.libreplan.business.common.entities.Connector;
+import org.libreplan.business.common.entities.ConnectorException;
import org.libreplan.business.orders.entities.Order;
import org.libreplan.business.orders.entities.OrderSyncInfo;
@@ -43,15 +44,20 @@ public interface IExportTimesheetsToTim {
* the Tim's productCode
* @param order
* an existing order
+ * @throws ConnectorException
+ * if connector is not valid
*/
- boolean exportTimesheets(String productCode, Order order);
+ void exportTimesheets(String productCode, Order order) throws ConnectorException;
/**
* Loops through all existing {@link Order}s and searches for last
* synchronized order. if found, start exporting the time sheets of that
* order to Tim SOAP server. if not found write info to the log file.
+ *
+ * @throws ConnectorException
+ * if connector is not valid
*/
- void exportTimesheets();
+ void exportTimesheets() throws ConnectorException;
/**
* Gets the most recent synchronized time sheet info
@@ -62,4 +68,9 @@ public interface IExportTimesheetsToTim {
*/
OrderSyncInfo getOrderLastSyncInfo(Order order);
+ /**
+ * Returns export process info, success of fail info
+ */
+ TimImpExpInfo getExportProcessInfo();
+
}
diff --git a/libreplan-webapp/src/main/java/org/libreplan/importers/IImportRosterFromTim.java b/libreplan-webapp/src/main/java/org/libreplan/importers/IImportRosterFromTim.java
index a7f500f1f..20db1f873 100644
--- a/libreplan-webapp/src/main/java/org/libreplan/importers/IImportRosterFromTim.java
+++ b/libreplan-webapp/src/main/java/org/libreplan/importers/IImportRosterFromTim.java
@@ -21,6 +21,7 @@ package org.libreplan.importers;
import org.libreplan.business.calendars.entities.CalendarException;
import org.libreplan.business.common.entities.Connector;
+import org.libreplan.business.common.entities.ConnectorException;
/**
* Import Rosters from Tim SOAP server using {@link TimSoapClient} and updates
@@ -38,6 +39,14 @@ public interface IImportRosterFromTim {
*
* If worker calendar exception already exists it will be removed and added
* new one, in other cases a new calendar exception will be created
+ *
+ * @throws ConnectorException
+ * if connector is not valid
*/
- void importRosters();
+ void importRosters() throws ConnectorException;
+
+ /**
+ * Returns import process info, success of fail info
+ */
+ TimImpExpInfo getImportProcessInfo();
}
diff --git a/libreplan-webapp/src/main/java/org/libreplan/importers/ImportRosterFromTim.java b/libreplan-webapp/src/main/java/org/libreplan/importers/ImportRosterFromTim.java
index 10b5556ef..f4963fb81 100644
--- a/libreplan-webapp/src/main/java/org/libreplan/importers/ImportRosterFromTim.java
+++ b/libreplan-webapp/src/main/java/org/libreplan/importers/ImportRosterFromTim.java
@@ -41,6 +41,7 @@ import org.libreplan.business.common.IOnTransaction;
import org.libreplan.business.common.daos.IConfigurationDAO;
import org.libreplan.business.common.daos.IConnectorDAO;
import org.libreplan.business.common.entities.Connector;
+import org.libreplan.business.common.entities.ConnectorException;
import org.libreplan.business.common.entities.PredefinedConnectorProperties;
import org.libreplan.business.common.entities.PredefinedConnectors;
import org.libreplan.business.common.exceptions.InstanceNotFoundException;
@@ -103,6 +104,13 @@ public class ImportRosterFromTim implements IImportRosterFromTim {
@Qualifier("subclass")
private IBaseCalendarModel baseCalendarModel;
+ private TimImpExpInfo timImpExpInfo;
+
+ /**
+ * Action name
+ */
+ private static final String IMPORT = "Import";
+
/**
* Search criteria for roster exception days in RESPONSE message
* {@link RosterDTO}
@@ -124,18 +132,24 @@ public class ImportRosterFromTim implements IImportRosterFromTim {
@Override
@Transactional
- public void importRosters() {
+ public void importRosters() throws ConnectorException {
Connector connector = connectorDAO
- .findUniqueByName(
- PredefinedConnectors.TIM.getName());
+ .findUniqueByName(PredefinedConnectors.TIM.getName());
if (connector == null) {
- return;
+ throw new ConnectorException("Tim Connector not found");
+ }
+
+ if (!connector.areConnectionValuesValid()) {
+ throw new ConnectorException(
+ "Connection values of Tim connector are invalid");
}
Map properties = connector.getPropertiesAsMap();
String url = properties.get(PredefinedConnectorProperties.SERVER_URL);
+
String userName = properties
.get(PredefinedConnectorProperties.USERNAME);
+
String password = properties
.get(PredefinedConnectorProperties.PASSWORD);
@@ -149,14 +163,16 @@ public class ImportRosterFromTim implements IImportRosterFromTim {
String departmentIds = properties
.get(PredefinedConnectorProperties.TIM_DEPARTAMENTS_IMPORT_ROSTER);
- if (StringUtils.isEmpty(departmentIds)) {
+ if (StringUtils.isBlank(departmentIds)) {
LOG.warn("No departments configured");
- return;
+ throw new ConnectorException("No departments configured");
}
String[] departmentIdsArray = StringUtils.stripAll(StringUtils.split(
departmentIds, ","));
+ timImpExpInfo = new TimImpExpInfo(IMPORT);
+
for (String department : departmentIdsArray) {
LOG.info("Department: " + department);
RosterRequestDTO rosterRequestDTO = createRosterRequest(department,
@@ -165,12 +181,18 @@ public class ImportRosterFromTim implements IImportRosterFromTim {
.sendRequestReceiveResponse(url, userName, password,
rosterRequestDTO, RosterResponseDTO.class);
- updateWorkersCalendarException(rosterResponseDTO,
- productivityFactor);
+ if (rosterResponseDTO != null) {
+ updateWorkersCalendarException(rosterResponseDTO,
+ productivityFactor);
+ } else {
+ LOG.error("No valid response for department " + department);
+ timImpExpInfo
+ .addFailedReason("No valid response for department "
+ + department);
+ }
}
}
-
/**
* updates workers Exception calendar
*
@@ -190,6 +212,8 @@ public class ImportRosterFromTim implements IImportRosterFromTim {
updateCalendarException(rosterExceptions);
} else {
LOG.info("No roster-exceptions found in the response");
+ timImpExpInfo
+ .addFailedReason("No roster-exceptions found in the response");
}
return null;
}
@@ -217,6 +241,8 @@ public class ImportRosterFromTim implements IImportRosterFromTim {
worker = workerDAO.findUniqueByNif(workerCode);
} catch (InstanceNotFoundException e) {
LOG.warn("Worker \"" + workerCode + "\" not found!");
+ timImpExpInfo.addFailedReason("Worker \"" + workerCode
+ + "\" not found!");
}
if (worker != null) {
List list = entry.getValue();
@@ -331,6 +357,7 @@ public class ImportRosterFromTim implements IImportRosterFromTim {
private CalendarExceptionType getCalendarExceptionType(String name) {
if (name == null || name.isEmpty()) {
LOG.error("Exception name should not be empty");
+ timImpExpInfo.addFailedReason("Exception name should not be empty");
return null;
}
try {
@@ -345,6 +372,7 @@ public class ImportRosterFromTim implements IImportRosterFromTim {
return calendarExceptionTypeDAO.findUniqueByName(nameToSearch);
} catch (InstanceNotFoundException e) {
LOG.error("Calendar exceptionType not found", e);
+ timImpExpInfo.addFailedReason("Calendar exceptionType not found");
}
return null;
}
@@ -437,4 +465,9 @@ public class ImportRosterFromTim implements IImportRosterFromTim {
rosterDTO.setConcept(false);
return rosterDTO;
}
+
+ @Override
+ public TimImpExpInfo getImportProcessInfo() {
+ return timImpExpInfo;
+ }
}
diff --git a/libreplan-webapp/src/main/java/org/libreplan/importers/ImportRosterFromTimJob.java b/libreplan-webapp/src/main/java/org/libreplan/importers/ImportRosterFromTimJob.java
index fe8cc12b7..cc296ad7f 100644
--- a/libreplan-webapp/src/main/java/org/libreplan/importers/ImportRosterFromTimJob.java
+++ b/libreplan-webapp/src/main/java/org/libreplan/importers/ImportRosterFromTimJob.java
@@ -19,6 +19,9 @@
package org.libreplan.importers;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.libreplan.business.common.entities.ConnectorException;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.config.BeanDefinition;
@@ -35,6 +38,8 @@ import org.springframework.stereotype.Component;
@Component
@Scope(BeanDefinition.SCOPE_SINGLETON)
public class ImportRosterFromTimJob extends QuartzJobBean {
+ private static final Log LOG = LogFactory
+ .getLog(ImportRosterFromTimJob.class);
@Override
protected void executeInternal(JobExecutionContext context)
@@ -45,7 +50,13 @@ public class ImportRosterFromTimJob extends QuartzJobBean {
IImportRosterFromTim importRosterFromTim = (IImportRosterFromTim) applicationContext
.getBean("importRosterFromTim");
- importRosterFromTim.importRosters();
+ try {
+ importRosterFromTim.importRosters();
+ LOG.info("Import scuccessful: "
+ + importRosterFromTim.getImportProcessInfo().isSuccessful());
+ } catch (ConnectorException e) {
+ LOG.error("Import roster from Tim failed", e);
+ }
}
diff --git a/libreplan-webapp/src/main/java/org/libreplan/importers/TimImpExpInfo.java b/libreplan-webapp/src/main/java/org/libreplan/importers/TimImpExpInfo.java
new file mode 100644
index 000000000..777922f58
--- /dev/null
+++ b/libreplan-webapp/src/main/java/org/libreplan/importers/TimImpExpInfo.java
@@ -0,0 +1,79 @@
+/*
+ * This file is part of LibrePlan
+ *
+ * Copyright (C) 2013 St. Antoniusziekenhuis
+ *
+ * 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 java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Keeps track the success/failure of Tim's import and/or export process
+ *
+ * @author Miciele Ghiorghis
+ */
+public class TimImpExpInfo {
+
+ /**
+ * action, import or export process
+ */
+ private String action;
+
+ /**
+ * Holds failed reasons
+ */
+ private List failedReasons = new ArrayList();
+
+ public TimImpExpInfo(String action) {
+ this.action = action;
+ }
+
+ /**
+ * Returns the action
+ */
+ public String getAction() {
+ return action;
+ }
+
+ /**
+ * Adds the specified reason to failedReasons list
+ *
+ * @param reason
+ * reason why import/export failed
+ */
+ public void addFailedReason(String reason) {
+ failedReasons.add(reason);
+ }
+
+ /**
+ * Is import or export succeeded
+ *
+ * @return true if failedReasons is empty
+ */
+ public boolean isSuccessful() {
+ return failedReasons.isEmpty();
+ }
+
+ /**
+ * returns reasons why import or export failed
+ */
+ public List getFailedReasons() {
+ return Collections.unmodifiableList(failedReasons);
+ }
+}
diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/common/IJobSchedulerModel.java b/libreplan-webapp/src/main/java/org/libreplan/web/common/IJobSchedulerModel.java
index 6ce07428b..071edc0d3 100644
--- a/libreplan-webapp/src/main/java/org/libreplan/web/common/IJobSchedulerModel.java
+++ b/libreplan-webapp/src/main/java/org/libreplan/web/common/IJobSchedulerModel.java
@@ -22,9 +22,11 @@ package org.libreplan.web.common;
import java.util.List;
import org.libreplan.business.common.entities.Connector;
+import org.libreplan.business.common.entities.ConnectorException;
import org.libreplan.business.common.entities.JobSchedulerConfiguration;
import org.libreplan.business.common.entities.PredefinedConnectorProperties;
import org.libreplan.business.common.exceptions.ValidationException;
+import org.libreplan.importers.TimImpExpInfo;
/**
* Contract for {@link JobSchedulerModel}.
@@ -55,9 +57,16 @@ public interface IJobSchedulerModel {
*
* @param jobSchedulerConfiguration
* the job configuration
+ * @throws ConnectorException
+ * if connector is not valid
*/
- void doManual(JobSchedulerConfiguration jobSchedulerConfiguration);
+ void doManual(JobSchedulerConfiguration jobSchedulerConfiguration)
+ throws ConnectorException;
+ /**
+ * Returns import/export info. Failure or success info
+ */
+ TimImpExpInfo getImportExportInfo();
/**
* Prepares for create a new {@link JobSchedulerConfiguration}.
diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/common/JobSchedulerController.java b/libreplan-webapp/src/main/java/org/libreplan/web/common/JobSchedulerController.java
index 37e5755e1..01788e217 100644
--- a/libreplan-webapp/src/main/java/org/libreplan/web/common/JobSchedulerController.java
+++ b/libreplan-webapp/src/main/java/org/libreplan/web/common/JobSchedulerController.java
@@ -23,18 +23,24 @@ import static org.libreplan.web.I18nHelper._;
import java.text.ParseException;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.libreplan.business.common.entities.Connector;
+import org.libreplan.business.common.entities.ConnectorException;
import org.libreplan.business.common.entities.JobClassNameEnum;
import org.libreplan.business.common.entities.JobSchedulerConfiguration;
import org.libreplan.business.common.exceptions.InstanceNotFoundException;
import org.libreplan.business.common.exceptions.ValidationException;
+import org.libreplan.importers.TimImpExpInfo;
import org.quartz.CronExpression;
import org.zkoss.zk.ui.Component;
+import org.zkoss.zk.ui.Executions;
+import org.zkoss.zk.ui.SuspendNotAllowedException;
import org.zkoss.zk.ui.WrongValueException;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
@@ -46,7 +52,9 @@ import org.zkoss.zul.Label;
import org.zkoss.zul.Popup;
import org.zkoss.zul.Row;
import org.zkoss.zul.RowRenderer;
+import org.zkoss.zul.SimpleListModel;
import org.zkoss.zul.api.Textbox;
+import org.zkoss.zul.api.Window;
/**
* Controller for job scheduler manager
@@ -174,7 +182,13 @@ public class JobSchedulerController extends
@Override
public void onEvent(Event event) throws Exception {
- jobSchedulerModel.doManual(jobSchedulerConfiguration);
+ try {
+ jobSchedulerModel.doManual(jobSchedulerConfiguration);
+ shwoImpExpInfo();
+ } catch (ConnectorException e) {
+ messagesForUser.showMessage(Level.ERROR,
+ _(e.getMessage()));
+ }
}
}));
hbox.appendChild(Util.createEditButton(new EventListener() {
@@ -195,6 +209,27 @@ public class JobSchedulerController extends
};
}
+ private void shwoImpExpInfo() {
+ Map args = new HashMap();
+
+ TimImpExpInfo timImpExpInfo = jobSchedulerModel.getImportExportInfo();
+ args.put("action", _(timImpExpInfo.getAction()));
+ args.put("showSuccess", timImpExpInfo.isSuccessful());
+ args.put("failedReasons",
+ new SimpleListModel(timImpExpInfo.getFailedReasons()));
+
+ Window timImpExpInfoWindow = (Window) Executions.createComponents(
+ "/orders/_timImpExpInfo.zul", null, args);
+
+ try {
+ timImpExpInfoWindow.doModal();
+ } catch (SuspendNotAllowedException e) {
+ throw new RuntimeException(e);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
/**
* returns the next fire time for the specified job in
* {@link JobSchedulerConfiguration}
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 06e483d88..06838bf81 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
@@ -24,6 +24,7 @@ import java.util.List;
import org.libreplan.business.common.daos.IConnectorDAO;
import org.libreplan.business.common.daos.IJobSchedulerConfigurationDAO;
import org.libreplan.business.common.entities.Connector;
+import org.libreplan.business.common.entities.ConnectorException;
import org.libreplan.business.common.entities.JobClassNameEnum;
import org.libreplan.business.common.entities.JobSchedulerConfiguration;
import org.libreplan.business.common.exceptions.InstanceNotFoundException;
@@ -31,6 +32,7 @@ import org.libreplan.business.common.exceptions.ValidationException;
import org.libreplan.importers.IExportTimesheetsToTim;
import org.libreplan.importers.IImportRosterFromTim;
import org.libreplan.importers.ISchedulerManager;
+import org.libreplan.importers.TimImpExpInfo;
import org.libreplan.web.common.concurrentdetection.OnConcurrentModification;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
@@ -67,6 +69,8 @@ public class JobSchedulerModel implements IJobSchedulerModel {
@Autowired
private IExportTimesheetsToTim exportTimesheetsToTim;
+ private TimImpExpInfo timImpExpInfo;
+
@Override
@Transactional(readOnly = true)
public List getJobSchedulerConfigurations() {
@@ -80,18 +84,26 @@ public class JobSchedulerModel implements IJobSchedulerModel {
}
@Override
- public void doManual(JobSchedulerConfiguration jobSchedulerConfiguration) {
+ public void doManual(JobSchedulerConfiguration jobSchedulerConfiguration)
+ throws ConnectorException {
String name = jobSchedulerConfiguration.getJobClassName().getName();
if (name.equals(JobClassNameEnum.IMPORT_ROSTER_FROM_TIM_JOB.getName())) {
importRosterFromTim.importRosters();
+ timImpExpInfo = importRosterFromTim.getImportProcessInfo();
return;
}
if (name.equals(JobClassNameEnum.EXPORT_TIMESHEET_TO_TIM_JOB.getName())) {
exportTimesheetsToTim.exportTimesheets();
+ timImpExpInfo = exportTimesheetsToTim.getExportProcessInfo();
return;
}
}
+ @Override
+ public TimImpExpInfo getImportExportInfo() {
+ return timImpExpInfo;
+ }
+
@Override
public void initCreate() {
this.jobSchedulerConfiguration = JobSchedulerConfiguration.create();
diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/orders/TimSynchronizationController.java b/libreplan-webapp/src/main/java/org/libreplan/web/orders/TimSynchronizationController.java
index b39188e81..70a04a66e 100644
--- a/libreplan-webapp/src/main/java/org/libreplan/web/orders/TimSynchronizationController.java
+++ b/libreplan-webapp/src/main/java/org/libreplan/web/orders/TimSynchronizationController.java
@@ -21,21 +21,30 @@ package org.libreplan.web.orders;
import static org.libreplan.web.I18nHelper._;
+import java.util.HashMap;
+import java.util.Map;
+
import org.apache.commons.logging.LogFactory;
import org.libreplan.business.common.daos.IConnectorDAO;
import org.libreplan.business.common.entities.Connector;
+import org.libreplan.business.common.entities.ConnectorException;
import org.libreplan.business.common.entities.PredefinedConnectors;
import org.libreplan.business.orders.entities.OrderSyncInfo;
import org.libreplan.importers.IExportTimesheetsToTim;
+import org.libreplan.importers.TimImpExpInfo;
import org.libreplan.web.common.IMessagesForUser;
import org.libreplan.web.common.Level;
import org.libreplan.web.common.MessagesForUser;
import org.libreplan.web.common.Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.zkoss.zk.ui.Component;
+import org.zkoss.zk.ui.Executions;
+import org.zkoss.zk.ui.SuspendNotAllowedException;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.Label;
+import org.zkoss.zul.SimpleListModel;
import org.zkoss.zul.Textbox;
+import org.zkoss.zul.api.Window;
/**
* Controller for Tim synchronization
@@ -76,15 +85,18 @@ public class TimSynchronizationController extends GenericForwardComposer {
public void startExportToTim() {
LOG.info("startExportToTim(): " + orderController.getOrder().getName());
txtProductCode.setConstraint("no empty:" + _("cannot be empty"));
- if (exportTimesheetsToTim.exportTimesheets(txtProductCode.getValue(),
- orderController.getOrder())) {
- messagesForUser.showMessage(Level.INFO,
- "Exporting timesheets to Tim is completed successfully");
- } else {
+ try {
+ exportTimesheetsToTim.exportTimesheets(txtProductCode.getValue(),
+ orderController.getOrder());
+
+ updateOrderLastSyncInfoScreen();
+
+ shwoImpExpInfo();
+
+ } catch (ConnectorException e) {
messagesForUser.showMessage(Level.ERROR,
- _("Exporting timesheets to Tim failed"));
+ _("Exporting timesheets to Tim failed. Check the Tim connector"));
}
- updateOrderLastSyncInfoScreen();
}
private void updateOrderLastSyncInfoScreen() {
@@ -109,4 +121,26 @@ public class TimSynchronizationController extends GenericForwardComposer {
}
return connector.isActivated();
}
+
+ private void shwoImpExpInfo() {
+ Map args = new HashMap();
+
+ TimImpExpInfo timImpExpInfo = exportTimesheetsToTim.getExportProcessInfo();
+ args.put("action", _(timImpExpInfo.getAction()));
+ args.put("showSuccess", timImpExpInfo.isSuccessful());
+ args.put("failedReasons",
+ new SimpleListModel(timImpExpInfo.getFailedReasons()));
+
+ Window timImpExpInfoWindow = (Window) Executions.createComponents(
+ "/orders/_timImpExpInfo.zul", null, args);
+
+ try {
+ timImpExpInfoWindow.doModal();
+ } catch (SuspendNotAllowedException e) {
+ throw new RuntimeException(e);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
}
diff --git a/libreplan-webapp/src/main/webapp/orders/_timImpExpInfo.zul b/libreplan-webapp/src/main/webapp/orders/_timImpExpInfo.zul
new file mode 100644
index 000000000..15b04336d
--- /dev/null
+++ b/libreplan-webapp/src/main/webapp/orders/_timImpExpInfo.zul
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/libreplan-webapp/src/test/java/org/libreplan/importers/ExportTimesheetsToTimTest.java b/libreplan-webapp/src/test/java/org/libreplan/importers/ExportTimesheetsToTimTest.java
index 1b2c8fe40..06c0fd90c 100644
--- a/libreplan-webapp/src/test/java/org/libreplan/importers/ExportTimesheetsToTimTest.java
+++ b/libreplan-webapp/src/test/java/org/libreplan/importers/ExportTimesheetsToTimTest.java
@@ -44,14 +44,13 @@ import org.libreplan.business.IDataBootstrap;
import org.libreplan.business.common.IAdHocTransactionService;
import org.libreplan.business.common.IOnTransaction;
import org.libreplan.business.common.daos.IConfigurationDAO;
+import org.libreplan.business.common.entities.ConnectorException;
import org.libreplan.business.common.exceptions.InstanceNotFoundException;
import org.libreplan.business.orders.daos.IOrderDAO;
import org.libreplan.business.orders.entities.Order;
import org.libreplan.business.scenarios.IScenarioManager;
import org.libreplan.business.scenarios.entities.OrderVersion;
import org.libreplan.business.scenarios.entities.Scenario;
-import org.libreplan.importers.ExportTimesheetsToTim;
-import org.libreplan.importers.IExportTimesheetsToTim;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@@ -160,9 +159,12 @@ public class ExportTimesheetsToTimTest {
@Test
@Ignore("Only working if you have a Tim server configured")
- public void testExportTimesheetsToTimWithValidCodeAndOrder() {
+ public void testExportTimesheetsToTimWithValidCodeAndOrder()
+ throws ConnectorException {
Order order = givenOrder();
- boolean result = exportTimesheetsToTim.exportTimesheets("5160", order);
+ exportTimesheetsToTim.exportTimesheets("5160", order);
+ boolean result = exportTimesheetsToTim.getExportProcessInfo()
+ .isSuccessful();
if (!result) {
fail("Export timesheets to tim failed");
}
@@ -170,13 +172,15 @@ public class ExportTimesheetsToTimTest {
}
@Test(expected = RuntimeException.class)
- public void testExportTimesheetsToTimWithInvalidCode() {
+ public void testExportTimesheetsToTimWithInvalidCode()
+ throws ConnectorException {
Order order = givenOrder();
exportTimesheetsToTim.exportTimesheets("", order);
}
@Test(expected = RuntimeException.class)
- public void testExportTimesheetsToTimWithOrderNull() {
+ public void testExportTimesheetsToTimWithOrderNull()
+ throws ConnectorException {
exportTimesheetsToTim.exportTimesheets("5160", null);
}
}
diff --git a/libreplan-webapp/src/test/java/org/libreplan/importers/ImportRosterFromTimTest.java b/libreplan-webapp/src/test/java/org/libreplan/importers/ImportRosterFromTimTest.java
index 6745cf6d8..67e3b06b0 100644
--- a/libreplan-webapp/src/test/java/org/libreplan/importers/ImportRosterFromTimTest.java
+++ b/libreplan-webapp/src/test/java/org/libreplan/importers/ImportRosterFromTimTest.java
@@ -35,8 +35,7 @@ import org.junit.runner.RunWith;
import org.libreplan.business.IDataBootstrap;
import org.libreplan.business.common.IAdHocTransactionService;
import org.libreplan.business.common.IOnTransaction;
-import org.libreplan.importers.IImportRosterFromTim;
-import org.libreplan.importers.ImportRosterFromTim;
+import org.libreplan.business.common.entities.ConnectorException;
import org.libreplan.web.calendars.IBaseCalendarModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@@ -93,7 +92,7 @@ public class ImportRosterFromTimTest {
@Test
@Ignore("Only working if you have a Tim server configured")
- public void testImportRosters() {
+ public void testImportRosters() throws ConnectorException {
importRosterFromTim.importRosters();
assertTrue(baseCalendarModel.getCalendarExceptionType() != null);
}