diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/OPListExportAdapter.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/OPListExportAdapter.java
new file mode 100644
index 0000000..7dd40a1
--- /dev/null
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/OPListExportAdapter.java
@@ -0,0 +1,335 @@
+package com.alexanderlogistics;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Logger;
+
+import javax.inject.Inject;
+
+import org.apache.poi.ss.usermodel.CellCopyPolicy;
+import org.apache.poi.ss.util.CellReference;
+import org.apache.poi.xssf.usermodel.XSSFRow;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.imixs.archive.core.SnapshotService;
+import org.imixs.workflow.FileData;
+import org.imixs.workflow.ItemCollection;
+import org.imixs.workflow.engine.DocumentService;
+import org.imixs.workflow.engine.WorkflowService;
+import org.imixs.workflow.exceptions.AdapterException;
+import org.imixs.workflow.exceptions.PluginException;
+import org.imixs.workflow.exceptions.QueryException;
+import org.imixs.workflow.poi.POIFindReplaceAdapter;
+
+/**
+ * Der OPListExportAdapter importiert eine Excel Datei aus einem Textblock
+ *
+ *
+ * {@code
+ textblock-ref
+ filename
+ filename
+ }
+ *
+ *
+ * Der Adapter erweitert den POIAdapter somit können felder aktualisiert werden
+ * (siehe POIFineReplaceAdapter).
+ *
+ *
+ * Der Adapter kopiert die Rechnungsdaten in neue Zeilen, welche ab Zeilnenummer
+ * 16 eingefügt werden.
+ *
+ *
+ * Abschliessend wird die Zelle 'TOTAL' noch aktualisiert.
+ *
+ * @version 1.0
+ * @author rsoika
+ */
+public class OPListExportAdapter extends POIFindReplaceAdapter {
+
+ private static Logger logger = Logger.getLogger(OPListExportAdapter.class.getName());
+
+ public static final String ERROR_CONFIG = "CONFIG_ERROR";
+ final String TYPE_TEXTBLOCK = "textblock";
+
+ @Inject
+ WorkflowService workflowService;
+
+ @Inject
+ DocumentService documentService;
+
+ @Inject
+ SnapshotService snapshotService;
+
+ /**
+ * This method finds or create the Zahlungsavis and adds a reference
+ * ($workitemref) to the current invoice.
+ *
+ * @throws PluginException
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public ItemCollection execute(ItemCollection document, ItemCollection event)
+ throws AdapterException, PluginException {
+
+ // read the zahlungsavis options
+ ItemCollection evalItemCollection = workflowService.evalWorkflowResult(event, "opliste", document, false);
+ if (evalItemCollection == null) {
+ throw new PluginException(OPListExportAdapter.class.getSimpleName(), ERROR_CONFIG,
+ "missing op-list configuration in model event - please check model configuration");
+ }
+ String textblock = evalItemCollection.getItemValueString("textblock");
+ String template = evalItemCollection.getItemValueString("template");
+ String targetName = evalItemCollection.getItemValueString("target-name");
+ // adapt text....
+ targetName = workflowService.adaptText(targetName, document);
+
+ appendExcelTemplate(document, textblock, template, targetName);
+
+ // Process POI instructions
+ // read the config
+ ItemCollection poiConfig = workflowService.evalWorkflowResult(event, "poi-update", document, false);
+ if (poiConfig == null || !poiConfig.hasItem("findreplace")) {
+ throw new PluginException(POIFindReplaceAdapter.class.getSimpleName(), CONFIG_ERROR,
+ "missing poi configuration");
+ }
+ List replaceDevList = poiConfig.getItemValue("findreplace");
+ String eval = poiConfig.getItemValueString("eval");
+ try {
+ this.updateFileData(document.getFileData(targetName), document, replaceDevList, eval);
+
+ // now we add separate lines for each invoice....
+ insertInvoiceRows(document, targetName);
+ } catch (PluginException | IOException | QueryException e) {
+ throw new PluginException(OPListExportAdapter.class.getSimpleName(), ERROR_CONFIG,
+ "failed to update op-liste: " + e.getMessage());
+ }
+ return document;
+ }
+
+ /**
+ * This helper method inserts a row for each invoice of the current Zahlunsavis
+ * at row 16 into the excel template file
+ *
+ * The method copies the Row A16 as a reference row
+ *
+ * The named cell 'TOTAL' should contain the summary formula. It will be
+ * evaluated at the end.
+ *
+ * @throws PluginException
+ * @throws QueryException
+ */
+ private void insertInvoiceRows(ItemCollection document, String fileName) throws PluginException, QueryException {
+
+ double saldo = 0;
+ // load dummy rechnungen
+ String spaceID = document.getItemValueString("space.ref");
+
+ Map> invoiceMap = groupInvoicesBySpaceID(spaceID);
+
+ FileData fileData = document.getFileData(fileName);
+
+ // load XSSFWorkbook
+ try (InputStream imputStream = new ByteArrayInputStream(fileData.getContent())) {
+ XSSFWorkbook doc = new XSSFWorkbook(imputStream);
+ // NOTE: we only take the first sheet !
+ XSSFSheet sheet = doc.getSheetAt(0);
+ CellReference cr = new CellReference("A12");
+ XSSFRow referenceRow = sheet.getRow(cr.getRow());
+ int referenceRowPos = 12;
+ int rowPos = 12;
+ // int lastRow = sheet.getLastRowNum();
+ int lastRow = 9999;
+ logger.finest("Last rownum=" + lastRow);
+
+ int totalRowCount = invoiceMap.size();
+ for (List> list : invoiceMap.values()) {
+ totalRowCount = totalRowCount + list.size();
+ }
+
+ sheet.shiftRows(rowPos, lastRow, totalRowCount, true, true);
+ for (Map.Entry> entry : invoiceMap.entrySet()) {
+ String dbtrNumber = entry.getKey();
+ List invoices = entry.getValue();
+
+ // erzeuge eine Zwischenüberschrift für den Debitor....
+ XSSFRow categoryRow = sheet.createRow(rowPos);
+ categoryRow.copyRowFrom(referenceRow, new CellCopyPolicy());
+ // insert values
+ categoryRow.getCell(0).setCellValue(dbtrNumber);
+ String debitorName = invoices.get(0).getItemValueString("dbtr.name");
+ categoryRow.getCell(1).setCellValue(debitorName);
+
+ // calculate summ of all invoices
+ double catSum = 0;
+ for (ItemCollection invoice : invoices) {
+ catSum = catSum + invoice.getItemValueDouble("invoice.total");
+ }
+ if (catSum < 0) {
+ // SOLL
+ categoryRow.getCell(6).setCellValue(catSum);
+ } else {
+ categoryRow.getCell(8).setCellValue(catSum);
+ }
+
+ rowPos++;
+ // jetzt füge alle Rechnungen an.
+ for (ItemCollection invoice : invoices) {
+ logger.finest("......copy row...");
+
+ // now create a new line..
+ XSSFRow row = sheet.createRow(rowPos);
+ row.copyRowFrom(referenceRow, new CellCopyPolicy());
+ // insert values
+ row.getCell(2).setCellValue(invoice.getItemValueString("invoice.number"));
+ row.getCell(3).setCellValue(invoice.getItemValueString("invoice.text"));
+ row.getCell(4).setCellValue(invoice.getItemValueDate("invoice.date"));
+ row.getCell(5).setCellValue(invoice.getItemValueDate("invoice.duedate"));
+ double total = invoice.getItemValueDouble("invoice.total");
+ if (total < 0) {
+ // SOLL
+ row.getCell(6).setCellValue(total);
+ row.getCell(7).setCellValue(invoice.getItemValueString("invoice.currency"));
+ } else {
+ // HABEN
+ row.getCell(8).setCellValue(total);
+ row.getCell(9).setCellValue(invoice.getItemValueString("invoice.currency"));
+ }
+
+ saldo = saldo + total;
+ rowPos++;
+ }
+ }
+ // delete reference row 12
+ sheet.shiftRows(referenceRowPos, lastRow + totalRowCount, -1, true, true);
+
+ // finally update the total formula...
+ evalXSSFSheet(doc, sheet, "TOTAL");
+
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ // write back the file
+
+ doc.write(byteArrayOutputStream);
+ doc.close();
+ byte[] newContent = byteArrayOutputStream.toByteArray();
+ FileData fileDataNew = new FileData(fileData.getName(), newContent, fileData.getContentType(), null);
+ // update the fileData
+ document.addFileData(fileDataNew);
+ document.setItemValue("space.saldo", saldo);
+ logger.finest("......new document added");
+
+ } catch (IOException e) {
+ throw new PluginException(OPListExportAdapter.class.getSimpleName(), ERROR_CONFIG,
+ "failed to update zahlungsavis: " + e.getMessage());
+ }
+ }
+
+ /**
+ * This method loads a text-block for a specified ref and appends the named
+ * fileData object of this document.
+ *
+ * @param document
+ * @throws PluginException
+ */
+ private void appendExcelTemplate(ItemCollection document, String textblockRef, String template, String targetName)
+ throws PluginException {
+
+ if ((template == null || template.isEmpty()) || (textblockRef == null || textblockRef.isEmpty())) {
+ throw new PluginException(OPListExportAdapter.class.getSimpleName(), ERROR_CONFIG,
+ "invalid op-list configuration in model event - textblock/template reference not defined!");
+ }
+
+ // load the text block
+ FileData fileData = loadTextBlockFileData(textblockRef, template);
+
+ // do we found the document?
+ if (fileData == null) {
+ throw new PluginException(OPListExportAdapter.class.getSimpleName(), ERROR_CONFIG,
+ "invalid op-list configuration in model event - template=" + template + " not found!");
+ }
+ fileData.setName(targetName);
+ // append document
+ logger.info("...append new op-list Template: " + targetName);
+
+ document.addFileData(fileData);
+
+ }
+
+ /**
+ * This method returns a text-block ItemCollection for a specified name.
+ *
+ * @param name in attribute txtname
+ *
+ *
+ */
+ public FileData loadTextBlockFileData(String name, String fileName) {
+ ItemCollection textBlockItemCollection = null;
+
+ // load text-block by name....
+ String sQuery = "(type:\"" + TYPE_TEXTBLOCK + "\" AND txtname:\"" + name + "\")";
+ Collection col;
+ try {
+ // find the textblock...
+ col = documentService.find(sQuery, 1, 0);
+ if (col.size() > 0) {
+ textBlockItemCollection = col.iterator().next();
+ // fetch the fileData...
+ return snapshotService.getWorkItemFile(textBlockItemCollection.getUniqueID(), fileName);
+
+ } else {
+ logger.warning("Missing text-block : '" + name + "'");
+ }
+ } catch (QueryException e) {
+ logger.warning("getTextBlock - invalid query: " + e.getMessage());
+ }
+
+ return null;
+ }
+
+ /**
+ * Diese Methode groupiert eine Rechnugnsliste nach Debitorennummern
+ *
+ * @param spaceID
+ * @return
+ */
+ private Map> groupInvoicesBySpaceID(String spaceID) {
+
+ Map> result = new HashMap<>();
+
+ try {
+ List invoices = documentService.find(
+ "$modelversion:rechnungsausgang-de-1.0 AND type:workitem AND $uniqueidref:" + spaceID, 9999, 0);
+
+ for (ItemCollection invoice : invoices) {
+
+ String dbtrNumber = invoice.getItemValueString("dbtr.number");
+ // haben wir shon ein listchen?
+ List invoiceList = result.get(dbtrNumber);
+ if (invoiceList == null) {
+ // erzeuge eine neue liste
+ invoiceList = new ArrayList();
+ }
+
+ invoiceList.add(invoice);
+
+ // speicher wieder die neue liste
+ result.put(dbtrNumber, invoiceList);
+
+ }
+
+ } catch (QueryException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ return result;
+ }
+
+}
\ No newline at end of file
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/OPListExportController.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/OPListExportController.java
new file mode 100644
index 0000000..ff053d1
--- /dev/null
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/OPListExportController.java
@@ -0,0 +1,81 @@
+package com.alexanderlogistics;
+/*******************************************************************************
+ * Imixs Workflow Technology
+ * Copyright (C) 2003, 2008 Imixs Software Solutions GmbH,
+ * http://www.imixs.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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
+ * General Public License for more details.
+ *
+ * You can receive a copy of the GNU General Public
+ * License at http://www.gnu.org/licenses/gpl.html
+ *
+ * Contributors:
+ * Imixs Software Solutions GmbH - initial API and implementation
+ * Ralph Soika
+ *
+ *******************************************************************************/
+
+import java.util.logging.Logger;
+
+import javax.enterprise.context.RequestScoped;
+import javax.inject.Named;
+
+
+import org.imixs.workflow.engine.scheduler.SchedulerController;
+
+/**
+ * The DatevController is used to configure the DatevScheduler. This service is
+ * used to generate datev export workitems.
+ *
+ * The Controller creates a configuration entity "type=configuration;
+ * txtname=datev".
+ *
+ * The following config items are defined:
+ *
+ * The following config items are defined:
+ *
+ *
+ * _model_version = model version for the SEPA export
+ * _initial_task = inital task ID
+ *
+ *
+ *
+ * @author rsoika
+ *
+ */
+@Named(value = "oplistExportController")
+@RequestScoped
+public class OPListExportController extends SchedulerController {
+
+ public static final String OPLIST_EXPORT_CONFIGURATION = "OPLIST_EXPORT_CONFIGURATION";
+
+ private static final long serialVersionUID = 1L;
+ private static Logger logger = Logger.getLogger(OPListExportController.class.getName());
+
+ @Override
+ public String getName() {
+ return OPLIST_EXPORT_CONFIGURATION;
+ }
+
+ /**
+ * Returns the sepa scheduler class name. This name depends on the _export_type.
+ *
+ * There are two export interfaces available - csv and XML
+ *
+ */
+ @Override
+ public String getSchedulerClass() {
+ String schedulerClass = OPListExportScheduler.class.getName();
+ logger.finest("...... scheduler: " + schedulerClass);
+ return schedulerClass;
+ }
+
+}
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/OPListExportScheduler.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/OPListExportScheduler.java
new file mode 100644
index 0000000..5fcc169
--- /dev/null
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/OPListExportScheduler.java
@@ -0,0 +1,140 @@
+/*******************************************************************************
+ * Imixs Workflow Technology
+ * Copyright (C) 2001, 2008 Imixs Software Solutions GmbH,
+ * http://www.imixs.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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
+ * General Public License for more details.
+ *
+ * You can receive a copy of the GNU General Public
+ * License at http://www.gnu.org/licenses/gpl.html
+ *
+ * Contributors:
+ * Imixs Software Solutions GmbH - initial API and implementation
+ * Ralph Soika
+ *******************************************************************************/
+package com.alexanderlogistics;
+
+import java.text.DateFormat;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.logging.Logger;
+
+import javax.ejb.EJB;
+
+import org.imixs.marty.team.TeamService;
+import org.imixs.workflow.FileData;
+import org.imixs.workflow.ItemCollection;
+import org.imixs.workflow.engine.DocumentService;
+import org.imixs.workflow.engine.ModelService;
+import org.imixs.workflow.engine.ReportService;
+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.AccessDeniedException;
+import org.imixs.workflow.exceptions.ModelException;
+import org.imixs.workflow.exceptions.PluginException;
+import org.imixs.workflow.exceptions.ProcessingErrorException;
+import org.imixs.workflow.exceptions.QueryException;
+
+/**
+ * The OPListExportScheduler erzeugt für jeden Berich ein neues Workitem mit
+ * einer Excel Datei mit allen offenen Rechnungen.
+ *
+ * The class implements the interface
+ * _org.imixs.workflow.engine.scheduler.Scheduler_ and can be used in
+ * combination with the Imxis-Workflow Scheduler Service.
+ *
+ * @see SchedulerService
+ * @author rsoika
+ *
+ */
+public class OPListExportScheduler implements Scheduler {
+
+ public static final int MAX_COUNT = 999;
+ public static final String OPLIST_ERROR = "OPLIST_ERROR";
+
+ public static DateFormat dateFormat = new SimpleDateFormat("ddMMyyyy");
+ public static DecimalFormat decimalFormat = new DecimalFormat("0.00",
+ new DecimalFormatSymbols(java.util.Locale.GERMANY));
+
+ @EJB
+ DocumentService documentService;
+
+ @EJB
+ WorkflowService workflowService;
+
+ @EJB
+ ModelService modelService;
+
+ @EJB
+ TeamService teamService;
+
+ @EJB
+ ReportService reportService;
+
+ private static Logger logger = Logger.getLogger(OPListExportScheduler.class.getName());
+
+ /**
+ * This is the method which processes the timeout event depending on the running
+ * timer settings.
+ *
+ *
+ *
+ * @param timer
+ * @throws QueryException
+ */
+ public ItemCollection run(ItemCollection configuration) throws SchedulerException {
+ List invoices = null;
+ StringBuffer buffer = new StringBuffer();
+ int lines = 0;
+
+ configuration.removeItem("_scheduler_logmessage");
+ logMessage(configuration, "....export OP-Listen...");
+
+ // Hole dir alle Bereiche
+
+ List spaces = teamService.getSpaces();
+ // Jezt erzeugen wir für jeden Berich ein neues Workitem falls offene Rechnungen
+ for (ItemCollection space : spaces) {
+
+ ItemCollection workitem = new ItemCollection();
+ workitem.setItemValue("space.ref", space.getUniqueID());
+
+ try {
+ workflowService.processWorkItem( //
+ workitem.task(1000). //
+ event(100). //
+ model("opliste-de-1.0"));
+ } catch (AccessDeniedException | ProcessingErrorException | PluginException | ModelException e) {
+ e.printStackTrace();
+ }
+ }
+
+ // transfer file via FTP...
+ DateFormat formatter = new SimpleDateFormat("yyyyMMddHHmm");
+ // MMM d, yyyy HH:mm a
+ FileData fileData = new FileData("OPD_" + formatter.format(new Date()) + ".txt",
+ String.valueOf(buffer).getBytes(), null, null);
+
+ logMessage(configuration, "...completed: " + lines + " lines");
+ return configuration;
+ }
+
+ private void logMessage(ItemCollection configuration, String message) {
+ configuration.appendItemValue("_scheduler_logmessage", message);
+ logger.info(message);
+ }
+
+}
diff --git a/office-alexander-logistics-app/src/main/webapp/layout/commandbox_admin_custom.xhtml b/office-alexander-logistics-app/src/main/webapp/layout/commandbox_admin_custom.xhtml
index 15a47ee..9e3c874 100644
--- a/office-alexander-logistics-app/src/main/webapp/layout/commandbox_admin_custom.xhtml
+++ b/office-alexander-logistics-app/src/main/webapp/layout/commandbox_admin_custom.xhtml
@@ -9,6 +9,7 @@
Cargosoft Export
Analyse Rechnungseingang
Kreditoren/Debitoren
+ OP Listen Export
diff --git a/office-alexander-logistics-app/src/main/webapp/pages/admin/oplist_export.xhtml b/office-alexander-logistics-app/src/main/webapp/pages/admin/oplist_export.xhtml
new file mode 100644
index 0000000..ccf45a9
--- /dev/null
+++ b/office-alexander-logistics-app/src/main/webapp/pages/admin/oplist_export.xhtml
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/templates/op-liste_template.xlsx b/templates/op-liste_template.xlsx
new file mode 100644
index 0000000..033c0d8
Binary files /dev/null and b/templates/op-liste_template.xlsx differ
diff --git a/workflow/opliste-de-1.0.0.bpmn b/workflow/opliste-de-1.0.0.bpmn
new file mode 100644
index 0000000..bce14e2
--- /dev/null
+++ b/workflow/opliste-de-1.0.0.bpmn
@@ -0,0 +1,514 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+$workflowstatus
+
+]]>
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+ StartEvent_1
+ Task_1
+ EndEvent_3
+ Task_2
+ Task_4
+ IntermediateCatchEvent_8
+ IntermediateCatchEvent_3
+ IntermediateCatchEvent_1
+ IntermediateCatchEvent_2
+
+
+
+ SequenceFlow_4
+
+
+
+
+ sequencenumber $created - space.name]]>
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $workflowgroup - $workflowstatus]]>
+ SequenceFlow_16
+ SequenceFlow_1
+ SequenceFlow_17
+
+
+ SequenceFlow_19
+
+
+
+
+ sequencenumber $created - space.name]]>
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $workflowgroup - $workflowstatus]]>
+ SequenceFlow_4
+ SequenceFlow_3
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ home
+- Mahnwesen
+OP-Liste Template
+ op-liste_template.xlsx
+op-liste_space.name_$lasteventdate.xlsx
+
+
+ C6
+ sequencenumber
+ text
+
+
+ C8
+ space.name
+ text
+
+
+
+ I6
+ $lasteventdate
+ date
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+ false
+
+
+
+
+
+
+
+ SequenceFlow_5
+ SequenceFlow_16
+
+
+ DataOutput_2
+
+
+ DataOutput_2
+
+
+
+
+
+
+
+ sequencenumber $created - space.name]]>
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $workflowgroup - $workflowstatus]]>
+ SequenceFlow_18
+ SequenceFlow_19
+
+
+
+
+
+
+
+ SequenceFlow_17
+ SequenceFlow_18
+
+
+
+
+
+
+
+
+
+
+ SequenceFlow_1
+
+
+
+
+
+
+
+
+
+
+
+
+ SequenceFlow_3
+ SequenceFlow_5
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file