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 @@ + + + +
+ + +
+