office-alexander-logistics/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/dwc/SEPAExportAdapterNBD.java
2024-07-28 16:24:06 +02:00

262 lines
No EOL
9.8 KiB
Java

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;
/**
* TheSEPAExportAdapterNBD is an extension of the SEPAExportAdapter.
*
* 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
*/
public class SEPAExportAdapterNBD implements SignalAdapter {
private static Logger logger = Logger.getLogger(SEPAExportAdapterNBD.class.getName());
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
*
* @throws PluginException
*/
@SuppressWarnings("unchecked")
@Override
public ItemCollection execute(ItemCollection sepaExport, ItemCollection event)
throws AdapterException, PluginException {
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;
}
}