diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/datev/CargosoftExportScheduler.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/datev/CargosoftExportScheduler.java
index 74dbf44..342e0ce 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/datev/CargosoftExportScheduler.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/datev/CargosoftExportScheduler.java
@@ -22,7 +22,9 @@
*******************************************************************************/
package com.alexanderlogistics.datev;
-import java.io.ByteArrayOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
@@ -31,6 +33,10 @@ import java.util.logging.Logger;
import javax.ejb.EJB;
+import org.apache.commons.net.ftp.FTP;
+import org.apache.commons.net.ftp.FTPClient;
+import org.apache.commons.net.ftp.FTPSClient;
+import org.imixs.workflow.FileData;
import org.imixs.workflow.ItemCollection;
import org.imixs.workflow.engine.DocumentService;
import org.imixs.workflow.engine.ModelService;
@@ -39,10 +45,16 @@ import org.imixs.workflow.engine.WorkflowService;
import org.imixs.workflow.engine.scheduler.Scheduler;
import org.imixs.workflow.engine.scheduler.SchedulerException;
import org.imixs.workflow.engine.scheduler.SchedulerService;
+import org.imixs.workflow.exceptions.PluginException;
import org.imixs.workflow.exceptions.QueryException;
/**
- * The CargosoftExportScheduler exports a csv file with kreditor data
+ * The CargosoftExportScheduler exportier eine csv Datei auf eine FTP Laufwerk
+ * mit allen noch offenen Rechnungen. Diese Datei wird von Cargosoft ann
+ * verwendet um den Kreditramen für einen kunden zu ermitteln. Es werden
+ * praktisch von Cargosoft nur die offenen Salen aus unserer CSV Datei pro
+ * Kreditor ermittelt. (Wir könnten sozusagen auch direkt das ergeniss liefern,
+ * aber so ist die aktuelel Carhosoft Schnittstelle implementiert).
*
* The class implements the interface
* _org.imixs.workflow.engine.scheduler.Scheduler_ and can be used in
@@ -55,6 +67,7 @@ import org.imixs.workflow.exceptions.QueryException;
public class CargosoftExportScheduler implements Scheduler {
public static final int MAX_COUNT = 999;
+ public static final String FTP_ERROR = "FTP_ERROR";
public static DateFormat dateFormat = new SimpleDateFormat("ddMMyyyy");
public static DecimalFormat decimalFormat = new DecimalFormat("0.00");
@@ -84,16 +97,12 @@ public class CargosoftExportScheduler implements Scheduler {
* @throws QueryException
*/
public ItemCollection run(ItemCollection configuration) throws SchedulerException {
- ByteArrayOutputStream outputStream = null;
List invoices = null;
- String reportName = "";
- ItemCollection datevExport = null;
- int maxCount = configuration.getItemValueInteger("_maxcount");
- if (maxCount == 0) {
- maxCount = -1;
- }
+ StringBuffer buffer = new StringBuffer();
+ int lines = 0;
- logger.info("....export to Cargosoft...");
+ configuration.removeItem("_scheduler_logmessage");
+ logMessage(configuration, "....export to Cargosoft...");
// $taskID<5900
String sQuery = "(type:workitem AND $modelversion:rechnungsausgang* AND $taskid:[5000 TO 5899])";
@@ -101,7 +110,7 @@ public class CargosoftExportScheduler implements Scheduler {
// find the textblock...
invoices = documentService.find(sQuery, 9999, 0);
} catch (QueryException e) {
- logger.warning("failed to search invoices by query: " + e.getMessage());
+ logMessage(configuration, "failed to search invoices by query: " + e.getMessage());
}
if (invoices != null && invoices.size() > 0) {
@@ -143,20 +152,105 @@ public class CargosoftExportScheduler implements Scheduler {
line = line + ";0,000000;0,00;";
}
-
- //77 ;
- int i=77;
- while(i>0) {
+ // auffüllen mit 77 mal ';'
+ int i = 77;
+ while (i > 0) {
line = line + ";";
i--;
}
-
- logger.info(line);
+ buffer.append(line + "\n");
+ lines++;
}
}
+ // transfer file via FTP...
+ FileData fileData = new FileData("OPD28.txt", String.valueOf(buffer).getBytes(), null, null);
+
+ put(configuration, fileData);
+
+ logMessage(configuration, "...Export completed: " + lines + " lines");
return configuration;
}
+ private void logMessage(ItemCollection configuration, String message) {
+ configuration.appendItemValue("_scheduler_logmessage", message);
+ logger.info(message);
+ }
+
+ /**
+ * Diese Hilfsmehtode überträgt eine Datei an einen FTP Server. Die
+ * Verbindugnsdaten stehen im Configuraiton Workitem.
+ *
+ * @param fileData object
+ * @throws PluginException
+ */
+ public void put(ItemCollection configuration, FileData fileData) {
+
+ String ftpServer = configuration.getItemValueString("_datev_ftp_host");
+ String ftpUser = configuration.getItemValueString("_datev_ftp_userid");
+ String ftpPassword = configuration.getItemValueString("_datev_ftp_password");
+ String ftpWorkingPath = configuration.getItemValueString("_datev_ftp_path_buchungsstapel");
+ int ftpPort = configuration.getItemValueInteger("_datev_ftp_port");
+ if (ftpPort <= 0) {
+ // set default port
+ ftpPort = 21;
+ }
+
+ String fileName = fileData.getName();
+
+ // Compute file path
+ if (!ftpWorkingPath.startsWith("/")) {
+ ftpWorkingPath = "/" + ftpWorkingPath;
+ }
+ if (!ftpWorkingPath.endsWith("/")) {
+ ftpWorkingPath = ftpWorkingPath + "/";
+ }
+ InputStream writer = null;
+
+ FTPClient ftpClient = null;
+ try {
+ logMessage(configuration, "......put " + fileName + " to FTP server: " + ftpServer + "...");
+ ftpClient = new FTPSClient("TLS", false);
+ ftpClient.setBufferSize(8192);
+ ftpClient.connect(ftpServer, ftpPort);
+ if (ftpClient.login(ftpUser, ftpPassword) == false) {
+ logMessage(configuration, "FTP file transfer failed: login failed!");
+ }
+ ftpClient.enterLocalPassiveMode();
+ ftpClient.setFileType(FTP.ASCII_FILE_TYPE);
+ ftpClient.setControlEncoding("UTF-8");
+
+ // verify directories
+ if (!ftpClient.changeWorkingDirectory(ftpWorkingPath)) {
+ logMessage(configuration, "FTP file transfer failed: missing working directory '" + ftpWorkingPath
+ + "' : " + ftpClient.getReplyString());
+ }
+
+ // upload file to FTP server.
+ writer = new ByteArrayInputStream(fileData.getContent());
+
+ if (!ftpClient.storeFile(fileName, writer)) {
+ logMessage(configuration, "FTP file transfer failed: unable to write '" + ftpWorkingPath + fileName
+ + "' : " + ftpClient.getReplyString());
+ }
+
+ logMessage(configuration, "...." + ftpWorkingPath + fileName + " transfered successfull to " + ftpServer);
+
+ } catch (IOException e) {
+ logMessage(configuration, "FTP file transfer failed: " + e.getMessage());
+ } finally {
+ // do logout....
+ try {
+ if (writer != null) {
+ writer.close();
+ }
+ ftpClient.logout();
+ ftpClient.disconnect();
+ } catch (IOException e) {
+ logMessage(configuration, "FTP file transfer failed: " + e.getMessage());
+ }
+ }
+ }
+
}
diff --git a/office-alexander-logistics-app/src/main/webapp/pages/admin/cargosoft_export.xhtml b/office-alexander-logistics-app/src/main/webapp/pages/admin/cargosoft_export.xhtml
index 29f9c23..fa5a403 100644
--- a/office-alexander-logistics-app/src/main/webapp/pages/admin/cargosoft_export.xhtml
+++ b/office-alexander-logistics-app/src/main/webapp/pages/admin/cargosoft_export.xhtml
@@ -94,18 +94,10 @@
-
- - FTP Verzeichnis
- -
-
-
-
-
+
- Die Verzeichnisse
- werden mit der DATEV Mandanten ID ergänzt und müssen vor dem
- Export angelegt worden sein!
+ In diesem Verzeichniss werden die Belegdaten
+ im DATEV Format abgelegt.
Scheduler