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. * * * * *
 * {@code
        
            ....
            
        
 * }
 * 
* * @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 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; } }