diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/dwc/SEPAExportAdapterNBD.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/dwc/SEPAExportAdapterNBD.java index ce85ecf..3c30897 100644 --- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/dwc/SEPAExportAdapterNBD.java +++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/dwc/SEPAExportAdapterNBD.java @@ -1,14 +1,37 @@ package com.alexanderlogistics.dwc; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.List; import java.util.logging.Logger; +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.ai.workflow.OpenAIAPIAdapter; +import org.imixs.archive.core.SnapshotService; +import org.imixs.workflow.FileData; import org.imixs.workflow.ItemCollection; import org.imixs.workflow.SignalAdapter; +import org.imixs.workflow.engine.DocumentService; import org.imixs.workflow.engine.ReportService; +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.sepa.services.SepaWorkflowService; +import com.alexanderlogistics.OPListExportAdapterByWeek; + import jakarta.ejb.EJB; import jakarta.inject.Inject; @@ -18,6 +41,17 @@ import jakarta.inject.Inject; * This adapter export the payment information in a Excel Sheet acording to the * 'businessONLINE NBD' interface description. * + * * + * + *
+ * {@code
+        
+            ....
+            
+        
+ * }
+ * 
+ * * @version 1.0 * @author rsoika */ @@ -28,12 +62,23 @@ public class SEPAExportAdapterNBD implements SignalAdapter { public static final String ERROR_CONFIG = "CONFIG_ERROR"; public static final String ERROR_MISSING_INVOICE = "ERROR_MISSING_INVOICE"; + final String TYPE_TEXTBLOCK = "textblock"; + @EJB ReportService reportService; @Inject SepaWorkflowService sepaWorkflowService; + @Inject + DocumentService documentService; + + @Inject + WorkflowService workflowService; + + @Inject + SnapshotService snapshotService; + /** * This method collects a data set with all invoices and computes a NBA Excel * File. The templated is loaded from a text block @@ -45,27 +90,173 @@ public class SEPAExportAdapterNBD implements SignalAdapter { public ItemCollection execute(ItemCollection sepaExport, ItemCollection event) throws AdapterException, PluginException { - // Textblock laden - // load the text block - // FileData fileData = loadTextBlockFileData(textblockRef, template); - - // // do we found the document? - // if (fileData == null) { - // throw new PluginException(OPListExportAdapterByWeek.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); - - /* Processing .... */ String key = sepaExport.getItemValueString("name"); + // Textblock laden + List sepaConfigList = workflowService.evalWorkflowResultXML(event, "imixs-sepa", "CONFIG", + sepaExport, + false); + if (sepaConfigList == null || sepaConfigList.size() != 1) { + // no configuration found! + throw new PluginException(OpenAIAPIAdapter.class.getSimpleName(), ERROR_CONFIG, + "Missing or invalid imixs-sepa definition in Event " + sepaExport.getTaskID() + "." + + sepaExport.getEventID()); + } + + ItemCollection sepaConf = sepaConfigList.get(0); + String template = sepaConf.getItemValueString("template"); + FileData fileData = loadTextBlockFileData(sepaConf.getItemValueString("textblock"), template); + + // do we found the document? + if (fileData == null) { + throw new PluginException(OPListExportAdapterByWeek.class.getSimpleName(), + ERROR_CONFIG, + "invalid sepa configuration in model event - template not found!"); + } + fileData.setName(template); + // create the attachment based on the report definition + // attach a file to the current workitem + // create a harmonized debitor name for the filename..... + String sDepName = sepaExport.getItemValueString(SepaWorkflowService.ITEM_DBTR_NAME); + sDepName = sDepName.replace("&", "_"); + sDepName = sDepName.replace(">", "_"); + sDepName = sDepName.replace("<", "_"); + sDepName = sDepName.replace(" ", "_"); + // build a timestamp for the filename + DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HHmm"); + String sepaFileName = "sepa_" + sDepName + "_" + df.format(new Date()) + ".xlsx"; + + fileData.setName(sepaFileName); + + // append document + logger.info("...append invoices to Template: " + template); + + // get the data source based on the $workitemref .... + List refList = sepaExport.getItemValue("$workitemref"); + List data = new ArrayList(); + logger.info("...SEPA export started - " + refList.size() + " invoices found..."); + + for (String ref : refList) { + // load invoice + ItemCollection invoice = sepaWorkflowService.loadInvoice(ref); + if (invoice == null) { + logger.warning("Invoice '" + ref + "' not found! SEPA Export can not be executed"); + continue; + } + // avoid unsupported characters in sepa fields + invoice = sepaWorkflowService.harmonizeSEPAItem(invoice, SepaWorkflowService.ITEM_CDTR_NAME); + invoice = sepaWorkflowService.harmonizeSEPAItem(invoice, SepaWorkflowService.ITEM_DBTR_NAME); + data.add(invoice); + } + + // finally we add the teh invoices + try { + insertInvoiceRows(sepaExport, fileData, data); + } catch (PluginException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (QueryException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return sepaExport; } + /** + * This helper method inserts a row for each invoice of the OPListe 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 workitem, FileData fileData, List invoices) + throws PluginException, QueryException { + + // 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("A2"); + XSSFRow referenceRow = sheet.getRow(cr.getRow()); + + int rowPos = 1; + + // int lastRow = sheet.getLastRowNum(); + int lastRow = 999; + logger.finest("Last rownum=" + lastRow); + sheet.shiftRows(rowPos, lastRow, invoices.size(), true, true); + + 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(0).setCellValue(invoice.getItemValueString("numsequencenumber")); + row.getCell(1).setCellValue(invoice.getItemValueDate("invoice.date")); + row.getCell(2).setCellValue(invoice.getItemValueString("invoice.number")); + row.getCell(3).setCellValue(invoice.getItemValueDate("invoice.duedate")); + + row.getCell(4).setCellValue(invoice.getItemValueDouble("invoice.total")); + + rowPos++; + } + // delete reference row A2 + // sheet.shiftRows(1, 1 + invoices.size(), -1, true, true); + // sheet.shiftRows(1, lastRow + invoices.size(), -1, true, true); + + 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 + workitem.addFileData(fileDataNew); + logger.finest("......new document added"); + + } catch (IOException e) { + throw new PluginException(SEPAExportAdapterNBD.class.getSimpleName(), ERROR_CONFIG, + "failed to update sepa export: " + e.getMessage()); + } + } + + /** + * 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; + } } \ No newline at end of file diff --git a/templates/sepa/sepa-dwc.xlsx b/templates/sepa/sepa-dwc.xlsx new file mode 100644 index 0000000..030a609 Binary files /dev/null and b/templates/sepa/sepa-dwc.xlsx differ diff --git a/workflow/sepa-export-manual-dwc-3.0.0.bpmn b/workflow/sepa-export-manual-dwc-3.0.0.bpmn index 3d5ac75..933bc83 100644 --- a/workflow/sepa-export-manual-dwc-3.0.0.bpmn +++ b/workflow/sepa-export-manual-dwc-3.0.0.bpmn @@ -460,15 +460,14 @@ false - + +if (workitem.getItemValueString('txtcomment') == '') { + result.isValid=false; + result.errorMessage='Bitte geben Sie einen Kommentar ein.'; +}]]> @@ -565,7 +564,10 @@ result.isValid=true; - + + SEPA-DWC + +]]> @@ -674,7 +676,10 @@ result.isValid=true; - + + SEPA-DWC + +]]> @@ -688,15 +693,14 @@ result.isValid=true; - + +if (workitem.getItemValueString('txtcomment') == '') { + result.isValid=false; + result.errorMessage='Bitte geben Sie einen Kommentar ein.'; +}]]> @@ -854,9 +858,9 @@ result.isValid=true; - + - + @@ -940,11 +944,12 @@ result.isValid=true; - + - + + @@ -971,7 +976,7 @@ result.isValid=true; - +