385 lines
No EOL
13 KiB
Java
385 lines
No EOL
13 KiB
Java
package com.alexanderlogistics.dataview;
|
|
|
|
import java.util.List;
|
|
import java.util.logging.Logger;
|
|
|
|
import org.apache.poi.ss.usermodel.CellCopyPolicy;
|
|
import org.apache.poi.ss.usermodel.Row.MissingCellPolicy;
|
|
import org.apache.poi.ss.util.CellReference;
|
|
import org.apache.poi.xssf.usermodel.XSSFCell;
|
|
import org.apache.poi.xssf.usermodel.XSSFFormulaEvaluator;
|
|
import org.apache.poi.xssf.usermodel.XSSFRow;
|
|
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
|
import org.imixs.workflow.ItemCollection;
|
|
import org.imixs.workflow.dataview.DataViewExportEvent;
|
|
import org.imixs.workflow.engine.DocumentService;
|
|
import org.imixs.workflow.engine.WorkflowService;
|
|
import org.imixs.workflow.exceptions.PluginException;
|
|
import org.imixs.workflow.exceptions.QueryException;
|
|
import org.imixs.workflow.office.config.ConfigService;
|
|
import org.imixs.workflow.poi.POIFindReplaceAdapter;
|
|
import org.imixs.workflow.poi.XSSFUtil;
|
|
|
|
import com.alexanderlogistics.InvoiceService;
|
|
|
|
import jakarta.enterprise.event.Observes;
|
|
import jakarta.inject.Inject;
|
|
|
|
/**
|
|
* Der AGLDataViewDebitorAdapter exportiert eine Dateview in eine Excel Datei
|
|
* und berücksichtigt dabei separate Spalten für die Währungen
|
|
*
|
|
*
|
|
* @version 1.0
|
|
* @author rsoika
|
|
*/
|
|
public class AGLDataViewDebitorAdapter extends POIFindReplaceAdapter {
|
|
|
|
private static Logger logger = Logger.getLogger(AGLDataViewDebitorAdapter.class.getName());
|
|
|
|
@Inject
|
|
WorkflowService workflowService;
|
|
|
|
@Inject
|
|
InvoiceService invoiceService;
|
|
|
|
@Inject
|
|
DocumentService documentService;
|
|
|
|
@Inject
|
|
ConfigService configService;
|
|
|
|
/**
|
|
* Spezial Adapter der den Debitor exporteirt.
|
|
*
|
|
* @param event
|
|
*/
|
|
public void onEvent(@Observes DataViewExportEvent event) {
|
|
|
|
if ("Debitor SOA".equals(event.getDataViewDefinition().getItemValueString("name"))) {
|
|
try {
|
|
logger.info("Custom Insert Rows for Debitor SOA");
|
|
// ermittle die Hauptwährungen
|
|
List<String> currencyList;
|
|
|
|
currencyList = invoiceService.getCurrenciesOut();
|
|
|
|
// NOTE: we only take the first sheet !
|
|
XSSFSheet sheet = event.getXssfWorkbook().getSheetAt(0);
|
|
|
|
// first add the columns for the currency list
|
|
addCurrencyColumns(event.getXssfWorkbook(), sheet, currencyList);
|
|
// add rows
|
|
insertInvoiceRows(sheet, event.getDataset(), currencyList);
|
|
|
|
event.setCompleted(true);
|
|
} catch (PluginException | QueryException e) {
|
|
logger.severe("Failed to insert rows: " + e.getMessage());
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// /**
|
|
// * This method
|
|
// *
|
|
// * @throws PluginException
|
|
// */
|
|
// @SuppressWarnings("unchecked")
|
|
// @Override
|
|
// public ItemCollection execute(ItemCollection document, ItemCollection event)
|
|
// throws AdapterException, PluginException {
|
|
|
|
// // ermittle die Hauptwährungen
|
|
// List<String> currencyList = invoiceService.getCurrenciesOut();
|
|
|
|
// // read the options
|
|
// ItemCollection ausgangsrechnungConfig =
|
|
// workflowService.evalWorkflowResult(event, "soa", document, false);
|
|
// if (ausgangsrechnungConfig == null ||
|
|
// !ausgangsrechnungConfig.hasItem("excel-export")) {
|
|
// throw new PluginException(AGLDataViewAdapterDebitor.class.getSimpleName(),
|
|
// CONFIG_ERROR,
|
|
// "missing soa configuration in model event - please check model
|
|
// configuration");
|
|
// }
|
|
// List<String> excelDefList =
|
|
// ausgangsrechnungConfig.getItemValue("excel-export");
|
|
// ItemCollection excelDefCollection =
|
|
// XMLParser.parseItemStructure(excelDefList.get(0));
|
|
|
|
// String textblock = excelDefCollection.getItemValueString("textblock");
|
|
// String template = excelDefCollection.getItemValueString("template");
|
|
// String targetName = excelDefCollection.getItemValueString("target-name");
|
|
|
|
// // adapt text....
|
|
// targetName = workflowService.adaptText(targetName, document);
|
|
|
|
// try {
|
|
// FileData fileData = appendExcelTemplate(document, textblock, template,
|
|
// targetName);
|
|
|
|
// // get workbook
|
|
// XSSFWorkbook doc = null;
|
|
// try (InputStream imputStream = new
|
|
// ByteArrayInputStream(fileData.getContent())) {
|
|
// doc = new XSSFWorkbook(imputStream);
|
|
// // NOTE: we only take the first sheet !
|
|
// XSSFSheet sheet = doc.getSheetAt(0);
|
|
|
|
// // first add the columns for the currency list
|
|
// addCurrencyColumns(doc, sheet, currencyList);
|
|
// // add rows
|
|
// insertInvoiceRows(sheet, document, currencyList);
|
|
|
|
// // write back the updated excel file
|
|
// ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
|
// doc.write(byteArrayOutputStream);
|
|
|
|
// byte[] newContent = byteArrayOutputStream.toByteArray();
|
|
// FileData fileDataNew = new FileData(fileData.getName(), newContent,
|
|
// fileData.getContentType(), null);
|
|
// document.addFileData(fileDataNew);
|
|
// logger.finest("......new document added");
|
|
|
|
// } catch (IOException | QueryException e) {
|
|
// throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(),
|
|
// InvoiceService.ERROR_CONFIG,
|
|
// "failed to update opliste: " + e.getMessage());
|
|
// } finally {
|
|
// if (doc != null) {
|
|
// try {
|
|
// doc.close();
|
|
// } catch (IOException e) {
|
|
// logger.severe("Failed to close workbook: " + e.getMessage());
|
|
// e.printStackTrace();
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
// // Finally process POI instructions
|
|
// processPOIUpdate(document, event, targetName);
|
|
|
|
// } catch (PluginException e) {
|
|
// throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(),
|
|
// InvoiceService.ERROR_CONFIG,
|
|
// "failed to update steuerbescheide: " + e.getMessage());
|
|
// }
|
|
// logger.info("... completed!");
|
|
// return document;
|
|
// }
|
|
|
|
/**
|
|
* A SOA can be created for one or multiple currencies. This helper method adds
|
|
* the Total and Saldo Colum for each currency
|
|
*
|
|
* The template provided only the columns for the first currency.
|
|
*
|
|
* @param sheet
|
|
* @param currencyList
|
|
*/
|
|
private void addCurrencyColumns(XSSFWorkbook doc, XSSFSheet sheet, List<String> currencyList) {
|
|
if (currencyList == null || currencyList.size() <= 1) {
|
|
// no extra currencies defined!
|
|
return;
|
|
}
|
|
|
|
// zusaetzliche Zellen einfuegen...
|
|
int newColumns = (currencyList.size() - 1) * 2;
|
|
for (int i = 0; i < newColumns; i++) {
|
|
logger.info(".. add currency column...");
|
|
XSSFUtil.insertColumn(sheet, 6, 8 + i);
|
|
}
|
|
|
|
// Beschriftungen eintragen
|
|
int col = 6;
|
|
XSSFCell cell = null;
|
|
XSSFRow labelRow = sheet.getRow(9);
|
|
for (String currency : currencyList) {
|
|
|
|
cell = labelRow.getCell(col);
|
|
cell.setCellValue("Total " + currency);
|
|
col++;
|
|
|
|
cell = labelRow.getCell(col);
|
|
cell.setCellValue("Balance " + currency);
|
|
col++;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Hilfsmethode die das fuehrende K/D aus der Debitorennummer entfernt
|
|
*
|
|
* @return
|
|
*/
|
|
private String getDbtNr(ItemCollection workitem) {
|
|
String dbtNr = workitem.getItemValueString("dbtr.number");
|
|
if (dbtNr.startsWith("D") || dbtNr.startsWith("K")) {
|
|
dbtNr = dbtNr.substring(1);
|
|
}
|
|
return dbtNr;
|
|
}
|
|
|
|
/**
|
|
* Hilfsmethode die auch alte Rechnungen ohne D/K findet
|
|
*
|
|
* @return
|
|
*/
|
|
private String getDbtNrQuery(ItemCollection workitem) {
|
|
String dbtNr = workitem.getItemValueString("dbtr.number");
|
|
String shortDbtNr = dbtNr.substring(1);
|
|
String query = " (dbtr.number:" + dbtNr + " OR dbtr.number:" + shortDbtNr + ") ";
|
|
return query;
|
|
}
|
|
|
|
/**
|
|
* This helper method inserts a row for each invoice 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(XSSFSheet sheet, List<ItemCollection> invoices, List<String> currencyList)
|
|
throws PluginException, QueryException {
|
|
|
|
// load XSSFWorkbook
|
|
|
|
CellReference invoiceRefCell = new CellReference("A11");
|
|
XSSFRow referenceRowInvoice = sheet.getRow(invoiceRefCell.getRow());
|
|
int referenceRowPos = 10;
|
|
int rowPos = referenceRowPos;
|
|
int lastRow = 2999;
|
|
logger.finest("Last rownum=" + lastRow);
|
|
|
|
// jetzt füge alle Rechnungen an.
|
|
int totalRowCount = invoices.size();
|
|
XSSFUtil.insertRows(sheet, "A11", totalRowCount - 0);
|
|
|
|
for (ItemCollection invoice : invoices) {
|
|
logger.fine("......add invoice " + invoice.getUniqueID());
|
|
// now create a new line..
|
|
XSSFRow row = sheet.createRow(rowPos);
|
|
row.copyRowFrom(referenceRowInvoice, new CellCopyPolicy());
|
|
// insert values
|
|
row.getCell(0).setCellValue(invoice.getItemValueDate("$created"));
|
|
row.getCell(1, MissingCellPolicy.CREATE_NULL_AS_BLANK)
|
|
.setCellValue(invoice.getItemValueString("invoice.number"));
|
|
row.getCell(2, MissingCellPolicy.CREATE_NULL_AS_BLANK)
|
|
.setCellValue(invoice.getItemValueDate("invoice.date"));
|
|
row.getCell(3, MissingCellPolicy.CREATE_NULL_AS_BLANK)
|
|
.setCellValue(invoice.getItemValueDate("invoice.duedate"));
|
|
row.getCell(4, MissingCellPolicy.CREATE_NULL_AS_BLANK)
|
|
.setCellValue(invoice.getItemValueString("space.name"));
|
|
row.getCell(5, MissingCellPolicy.CREATE_NULL_AS_BLANK)
|
|
.setCellValue(invoice.getItemValueString("invoice.text"));
|
|
|
|
// Waehrung?
|
|
String currency = invoice.getItemValueString("invoice.currency");
|
|
int totalCol = findTotalPos(currency, currencyList);
|
|
|
|
row.getCell(totalCol, MissingCellPolicy.CREATE_NULL_AS_BLANK)
|
|
.setCellValue(invoice.getItemValueDouble("invoice.total"));
|
|
row.getCell(totalCol + 1, MissingCellPolicy.CREATE_NULL_AS_BLANK)
|
|
.setCellValue(invoice.getItemValueDouble("invoice.saldo"));
|
|
// Status
|
|
row.getCell(6 + (currencyList.size() * 2), MissingCellPolicy.CREATE_NULL_AS_BLANK)
|
|
.setCellValue(invoice.getItemValueString("$workflowstatus"));
|
|
|
|
rowPos++;
|
|
}
|
|
|
|
// setze Summen Formeln
|
|
for (int column = 6; column < currencyList.size() * 2 + 6; column++) {
|
|
XSSFCell cell = sheet.getRow(totalRowCount + 11).getCell(column); // G11
|
|
String cellRefFrom = XSSFUtil.getCellReference(column, 10);
|
|
String cellRefTo = XSSFUtil.getCellReference(column, totalRowCount + 10);
|
|
String formula = "SUM(" + cellRefFrom + ":" + cellRefTo + ")";
|
|
cell.setCellFormula(formula);
|
|
}
|
|
|
|
// Optional: Formel direkt evaluieren
|
|
XSSFFormulaEvaluator.evaluateAllFormulaCells(sheet.getWorkbook());
|
|
|
|
}
|
|
|
|
/**
|
|
* Findet die Total Spalte für eine Währung
|
|
*
|
|
* @param currency
|
|
* @return
|
|
*/
|
|
private int findTotalPos(String currency, List<String> currencyList) {
|
|
int result = 6;
|
|
if (currency != null) {
|
|
for (String cur : currencyList) {
|
|
if (currency.equals(cur)) {
|
|
return result;
|
|
}
|
|
result = result + 2;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* This method loads a text-block for a specified ref and appends the named
|
|
* fileData object of this document.
|
|
*
|
|
* @param document
|
|
* @throws PluginException
|
|
*/
|
|
// private FileData appendExcelTemplate(ItemCollection document, String
|
|
// textblockRef, String template,
|
|
// String targetName) throws PluginException {
|
|
|
|
// if ((template == null || template.isEmpty()) || (textblockRef == null ||
|
|
// textblockRef.isEmpty())) {
|
|
// throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(),
|
|
// InvoiceService.ERROR_CONFIG,
|
|
// "invalid SOA configuration in model event - textblock/template reference not
|
|
// defined!");
|
|
// }
|
|
|
|
// // load the text block
|
|
// FileData fileData = invoiceService.loadTextBlockFileData(textblockRef,
|
|
// template);
|
|
|
|
// // do we found the document?
|
|
// if (fileData == null) {
|
|
// throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(),
|
|
// InvoiceService.ERROR_CONFIG,
|
|
// "invalid SOA configuration in model event - template=" + template + " not
|
|
// found!");
|
|
// }
|
|
// fileData.setName(targetName);
|
|
// // append document
|
|
// logger.info("...append new SOA Template: " + targetName);
|
|
// document.addFileData(fileData);
|
|
// return fileData;
|
|
// }
|
|
|
|
/**
|
|
* Diese Methode läd alle offenen Steuerbescheide
|
|
*
|
|
* @return
|
|
*/
|
|
// private List<ItemCollection> loadInvoices(ItemCollection workitem) {
|
|
// List<ItemCollection> result = new ArrayList<>();
|
|
|
|
// String query = "(type:workitem) AND " + getDbtNrQuery(workitem) + " AND
|
|
// $modelversion:rechnungsausgang-*";
|
|
// try {
|
|
// result = documentService.find(query, 9999, 0, "invoice.number", false);
|
|
// } catch (QueryException e) {
|
|
// e.printStackTrace();
|
|
// }
|
|
// return result;
|
|
// }
|
|
|
|
} |