sepa export DWC

This commit is contained in:
Ralph Soika 2024-07-28 16:24:06 +02:00
parent e6a234bcb8
commit 3d4bbb03e0
3 changed files with 233 additions and 37 deletions

View file

@ -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.
*
* *
*
* <pre>
* {@code
<imixs-sepa name="CONFIG">
<textblock>....</textblock>
<template>....</template>
</imixs-sepa>
* }
* </pre>
*
* @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<ItemCollection> 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<String> refList = sepaExport.getItemValue("$workitemref");
List<ItemCollection> data = new ArrayList<ItemCollection>();
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
* <p>
* The method copies the Row A16 as a reference row
* <p>
* 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<ItemCollection> 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<ItemCollection> 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;
}
}

Binary file not shown.

View file

@ -460,15 +460,14 @@
<imixs:item name="keyupdateacl" type="xs:boolean">
<imixs:value>false</imixs:value>
</imixs:item>
<imixs:item name="txtbusinessrule" type="CDATA">
<imixs:item name="txtbusinessrule" type="xs:string">
<imixs:value><![CDATA[var result={};
var refField="txtcomment";
result.isValid=true;
if ( ( workitem.get(refField) == null || ''==workitem.get(refField)[0]) ) {
result.isValid=false;
result.errorMessage='Bitte geben Sie einen Kommentar ein.';
}]]></imixs:value>
if (workitem.getItemValueString('txtcomment') == '') {
result.isValid=false;
result.errorMessage='Bitte geben Sie einen Kommentar ein.';
}]]></imixs:value>
</imixs:item>
</bpmn2:extensionElements>
<bpmn2:documentation id="Documentation_28"/>
@ -565,7 +564,10 @@ result.isValid=true;
<imixs:value/>
</imixs:item>
<imixs:item name="txtactivityresult" type="xs:string">
<imixs:value/>
<imixs:value><![CDATA[<imixs-sepa name="CONFIG">
<textblock>SEPA-DWC</textblock>
<template>sepa-dwc.xlsx</template>
</imixs-sepa>]]></imixs:value>
</imixs:item>
<imixs:item name="keyownershipmode" type="xs:string">
<imixs:value><![CDATA[0]]></imixs:value>
@ -674,7 +676,10 @@ result.isValid=true;
<imixs:value/>
</imixs:item>
<imixs:item name="txtactivityresult" type="xs:string">
<imixs:value/>
<imixs:value><![CDATA[<imixs-sepa name="CONFIG">
<textblock>SEPA-DWC</textblock>
<template>sepa-dwc.xlsx</template>
</imixs-sepa>]]></imixs:value>
</imixs:item>
<imixs:item name="keyownershipmode" type="xs:string">
<imixs:value><![CDATA[0]]></imixs:value>
@ -688,15 +693,14 @@ result.isValid=true;
<imixs:item name="txtreportname" type="xs:string">
<imixs:value><![CDATA[sepa]]></imixs:value>
</imixs:item>
<imixs:item name="txtbusinessrule" type="CDATA">
<imixs:item name="txtbusinessrule" type="xs:string">
<imixs:value><![CDATA[var result={};
var refField="txtcomment";
result.isValid=true;
if ( ( workitem.get(refField) == null || ''==workitem.get(refField)[0]) ) {
result.isValid=false;
result.errorMessage='Bitte geben Sie einen Kommentar ein.';
}]]></imixs:value>
if (workitem.getItemValueString('txtcomment') == '') {
result.isValid=false;
result.errorMessage='Bitte geben Sie einen Kommentar ein.';
}]]></imixs:value>
</imixs:item>
<imixs:item name="nammailreceiver" type="xs:string">
<imixs:value/>
@ -854,9 +858,9 @@ result.isValid=true;
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="IntermediateCatchEvent_7" id="BPMNShape_IntermediateCatchEvent_7">
<dc:Bounds height="36.0" width="36.0" x="1112.0" y="435.0"/>
<dc:Bounds height="36.0" width="36.0" x="1112.0" y="434.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_39" labelStyle="BPMNLabelStyle_1">
<dc:Bounds height="20.0" width="100.0" x="1080.5" y="471.0"/>
<dc:Bounds height="20.0" width="100.0" x="1080.5" y="470.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="Task_1" id="BPMNShape_Task_1">
@ -940,11 +944,12 @@ result.isValid=true;
<bpmndi:BPMNLabel id="BPMNLabel_40"/>
<di:waypoint x="738.0" y="399.0"/>
<di:waypoint x="738.0" y="453.0"/>
<di:waypoint x="1112.0" y="453.0"/>
<di:waypoint x="1112.0277992443885" y="453.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="SequenceFlow_19" id="BPMNEdge_SequenceFlow_19" sourceElement="BPMNShape_IntermediateCatchEvent_7" targetElement="BPMNShape_Task_6">
<bpmndi:BPMNLabel id="BPMNLabel_41"/>
<di:waypoint x="1148.0" y="453.0"/>
<di:waypoint x="1148.0" y="452.0"/>
<di:waypoint x="1174.0" y="452.0"/>
<di:waypoint x="1174.0" y="453.0"/>
<di:waypoint x="1200.0" y="453.0"/>
</bpmndi:BPMNEdge>
@ -971,7 +976,7 @@ result.isValid=true;
<di:waypoint x="968.0" y="309.0"/>
<di:waypoint x="968.0" y="372.0"/>
<di:waypoint x="1130.0" y="372.0"/>
<di:waypoint x="1130.0" y="435.0"/>
<di:waypoint x="1130.0" y="434.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="SequenceFlow_11" id="BPMNEdge_SequenceFlow_11" sourceElement="BPMNShape_IntermediateCatchEvent_4" targetElement="BPMNShape_Task_1">
<bpmndi:BPMNLabel id="BPMNLabel_17"/>