This commit is contained in:
Ralph Soika 2025-05-22 16:11:01 +02:00
parent 73731c89ea
commit 981ccfc41b
20 changed files with 845 additions and 244 deletions

View file

@ -10,6 +10,7 @@
- Encoding für CSV Import aus cargosoft muss auf `encoding=UTF-8` stehen! - Encoding für CSV Import aus cargosoft muss auf `encoding=UTF-8` stehen!
- Neues Businesspartner BPMN Modell einspielen - Neues Businesspartner BPMN Modell einspielen
- Lucene Index neu berechenne wegen 'partner.id'
#### Daten Synchronisation #### Daten Synchronisation

View file

@ -199,7 +199,7 @@ public class AGLAnalyticControllerDebitor implements Serializable {
stats = null; stats = null;
} else { } else {
logger.info(" ├──load invoices for " + getDbtNr() + "...."); logger.info(" ├──load invoices for " + getDbtNr() + "....");
String query = "(type:workitem) AND dbtr.number:" + getDbtNr() + " AND $modelversion:rechnungsausgang-*"; String query = "(type:workitem) AND " + getDbtNrQuery() + " AND $modelversion:rechnungsausgang-*";
try { try {
logger.info(" ├──refresh invoice stats for " + getDbtNr() + "...."); logger.info(" ├──refresh invoice stats for " + getDbtNr() + "....");
invoices = documentService.find(query, 999, 0, "$created", false); invoices = documentService.find(query, 999, 0, "$created", false);
@ -371,12 +371,31 @@ public class AGLAnalyticControllerDebitor implements Serializable {
*/ */
private String getDbtNr() { private String getDbtNr() {
String dbtNr = workflowController.getWorkitem().getItemValueString("dbtr.number"); String dbtNr = workflowController.getWorkitem().getItemValueString("dbtr.number");
if (dbtNr.startsWith("D") || dbtNr.startsWith("K")) { // if (dbtNr.startsWith("D") || dbtNr.startsWith("K")) {
dbtNr = dbtNr.substring(1); // dbtNr = dbtNr.substring(1);
} // }
return dbtNr; return dbtNr;
} }
/**
* Hilfsmethode die auch alte Rechnungen ohne D/K findet
*
* @return
*/
private String getDbtNrQuery() {
String dbtNr = workflowController.getWorkitem().getItemValueString("dbtr.number");
String shortDbtNr = dbtNr.substring(1);
String query = " (dbtr.number:" + dbtNr + " OR dbtr.number:" + shortDbtNr + ") ";
return query;
}
private String getCdtrNrQuery() {
String cdtrNr = workflowController.getWorkitem().getItemValueString("cdtr.number");
String shortCdtrNr = cdtrNr.substring(1);
String query = " (cdtr.number:" + cdtrNr + " OR cdtr.number:" + shortCdtrNr + ") ";
return query;
}
/** /**
* Sucht alle Rechnugnen aus einem Zeitraum und sammelt Zahlungsziel und * Sucht alle Rechnugnen aus einem Zeitraum und sammelt Zahlungsziel und
* Zahlungszeitspanne gruppiert nach monaten * Zahlungszeitspanne gruppiert nach monaten
@ -403,7 +422,7 @@ public class AGLAnalyticControllerDebitor implements Serializable {
String endDateStr = endDate.format(formatter); String endDateStr = endDate.format(formatter);
String query = "(type:workitemarchive) AND " + " invoice.date:[" + startDateStr + " TO " + endDateStr + "] AND " String query = "(type:workitemarchive) AND " + " invoice.date:[" + startDateStr + " TO " + endDateStr + "] AND "
+ "dbtr.number:" + getDbtNr() + " AND $modelversion:rechnungsausgang-* AND ($taskid:[5900 TO 5999])"; + getDbtNrQuery() + " AND $modelversion:rechnungsausgang-* AND ($taskid:[5900 TO 5999])";
logger.fine("query = " + query); logger.fine("query = " + query);
try { try {

View file

@ -206,6 +206,18 @@ public class AGLAnalyticExcelAdapterDebitor extends POIFindReplaceAdapter {
return dbtNr; 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 * This helper method inserts a row for each invoice at row 16 into the excel
* template file * template file
@ -222,7 +234,7 @@ public class AGLAnalyticExcelAdapterDebitor extends POIFindReplaceAdapter {
throws PluginException, QueryException { throws PluginException, QueryException {
// load dummy rechnungen // load dummy rechnungen
List<ItemCollection> invoices = loadInvoices(getDbtNr(document)); List<ItemCollection> invoices = loadInvoices(document);
// load XSSFWorkbook // load XSSFWorkbook
@ -338,10 +350,10 @@ public class AGLAnalyticExcelAdapterDebitor extends POIFindReplaceAdapter {
* *
* @return * @return
*/ */
private List<ItemCollection> loadInvoices(String dbtrNumber) { private List<ItemCollection> loadInvoices(ItemCollection workitem) {
List<ItemCollection> result = new ArrayList<>(); List<ItemCollection> result = new ArrayList<>();
String query = "(type:workitem) AND dbtr.number:" + dbtrNumber + " AND $modelversion:rechnungsausgang-*"; String query = "(type:workitem) AND " + getDbtNrQuery(workitem) + " AND $modelversion:rechnungsausgang-*";
try { try {
result = documentService.find(query, 9999, 0, "invoice.number", false); result = documentService.find(query, 9999, 0, "invoice.number", false);
} catch (QueryException e) { } catch (QueryException e) {

View file

@ -37,7 +37,6 @@ import org.imixs.workflow.ItemCollection;
import org.imixs.workflow.engine.DocumentService; import org.imixs.workflow.engine.DocumentService;
import org.imixs.workflow.exceptions.AccessDeniedException; import org.imixs.workflow.exceptions.AccessDeniedException;
import org.imixs.workflow.exceptions.QueryException; import org.imixs.workflow.exceptions.QueryException;
import org.imixs.workflow.faces.data.WorkflowController;
import org.imixs.workflow.faces.data.WorkflowEvent; import org.imixs.workflow.faces.data.WorkflowEvent;
import jakarta.enterprise.context.ConversationScoped; import jakarta.enterprise.context.ConversationScoped;
@ -68,9 +67,6 @@ public class BusinessPartnerController implements Serializable {
protected List<ItemCollection> invoicesIn = null; protected List<ItemCollection> invoicesIn = null;
protected List<ItemCollection> dunnings = null; protected List<ItemCollection> dunnings = null;
@Inject
protected WorkflowController workflowController;
@Inject @Inject
DocumentService documentService; DocumentService documentService;
@ -330,51 +326,67 @@ public class BusinessPartnerController implements Serializable {
* dbtr/cdtr depending on the workflow type. A form will than rerender the * dbtr/cdtr depending on the workflow type. A form will than rerender the
* opList section. * opList section.
*/ */
public void updateMetaData() { public void updateMetaData(ItemCollection workitem) {
FacesContext fc = FacesContext.getCurrentInstance(); FacesContext fc = FacesContext.getCurrentInstance();
String bpid = fc.getExternalContext().getRequestParameterMap().get("partnerID"); String bpid = fc.getExternalContext().getRequestParameterMap().get("partnerID");
logger.info("....update metadata.....bpid = " + bpid); logger.info("....update metadata.....bpid = " + bpid);
ItemCollection businessPartner = businessPartnerService.getBusinessPartnerByID(bpid); ItemCollection businessPartner = businessPartnerService.getBusinessPartnerByID(bpid);
searchResult = null;
if (businessPartner != null) { if (businessPartner != null) {
// Eingangsrechnung // Eingangsrechnung
if (InvoiceUtil.isCreditorInvoice(workflowController.getWorkitem())) { if (InvoiceUtil.isCreditorInvoice(workitem)) {
workflowController.getWorkitem().setItemValue("cdtr.number", workitem.setItemValue("cdtr.number",
businessPartner.getItemValueString("cdtr.number")); businessPartner.getItemValueString("cdtr.number"));
workflowController.getWorkitem().setItemValue("cdtr.name", workitem.setItemValue("cdtr.name",
businessPartner.getItemValueString("partner.name")); businessPartner.getItemValueString("partner.name"));
workflowController.getWorkitem().setItemValue("cdtr.mail", businessPartner.getItemValue("cdtr.mail")); workitem.setItemValue("cdtr.mail", businessPartner.getItemValue("cdtr.mail"));
} } else
// Ausgangsrechnung // Ausgangsrechnung
if (InvoiceUtil.isDebitorInvoice(workflowController.getWorkitem())) { if (InvoiceUtil.isDebitorInvoice(workitem)) {
workflowController.getWorkitem().setItemValue("dbtr.number", workitem.setItemValue("dbtr.number",
businessPartner.getItemValueString("dbtr.number")); businessPartner.getItemValueString("dbtr.number"));
workflowController.getWorkitem().setItemValue("dbtr.name", workitem.setItemValue("dbtr.name",
businessPartner.getItemValueString("partner.name")); businessPartner.getItemValueString("partner.name"));
workflowController.getWorkitem().setItemValue("dbtr.mail", businessPartner.getItemValue("dbtr.mail")); workitem.setItemValue("dbtr.mail", businessPartner.getItemValue("dbtr.mail"));
} } else
// Zahlungseingang // Zahlungseingang
if (workflowController.getWorkitem().getModelVersion().startsWith("zahlungseingang")) { if (workitem.getModelVersion().startsWith("zahlungseingang")) {
workflowController.getWorkitem().setItemValue("dbtr.number", workitem.setItemValue("dbtr.number",
businessPartner.getItemValueString("dbtr.number")); businessPartner.getItemValueString("dbtr.number"));
workflowController.getWorkitem().setItemValue("dbtr.name", workitem.setItemValue("dbtr.name",
businessPartner.getItemValueString("partner.name")); businessPartner.getItemValueString("partner.name"));
workflowController.getWorkitem().setItemValue("dbtr.mail", businessPartner.getItemValue("dbtr.mail")); workitem.setItemValue("dbtr.mail", businessPartner.getItemValue("dbtr.mail"));
} } else
// Analyse Debitor // Analyse Debitor
if (workflowController.getWorkitem().getModelVersion().startsWith("analyse-debitor")) { if (workitem.getModelVersion().startsWith("analyse-debitor")) {
workflowController.getWorkitem().setItemValue("dbtr.number", workitem.setItemValue("dbtr.number",
businessPartner.getItemValueString("dbtr.number")); businessPartner.getItemValueString("dbtr.number"));
workflowController.getWorkitem().setItemValue("dbtr.name", workitem.setItemValue("dbtr.name",
businessPartner.getItemValueString("partner.name")); businessPartner.getItemValueString("partner.name"));
workflowController.getWorkitem().setItemValue("dbtr.mail", businessPartner.getItemValue("dbtr.mail")); workitem.setItemValue("dbtr.mail", businessPartner.getItemValue("dbtr.mail"));
} else {
// default behavior
if (workitem.getItemValueString("dbtr.number").isEmpty()) {
String number = businessPartner.getItemValueString("dbtr.number");
workitem.setItemValue("dbtr.number", number);
if (number.length() > 1) {
workitem.setItemValue("dbtr.number.short",
number.substring(1));
}
}
if (workitem.getItemValueString("cdtr.number").isEmpty()) {
String number = businessPartner.getItemValueString("cdtr.number");
workitem.setItemValue("cdtr.number", number);
if (number.length() > 1) {
workitem.setItemValue("cdtr.number.short",
number.substring(1));
}
}
} }
} }
searchResult = null;
} }

View file

@ -0,0 +1,385 @@
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.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.office.dataview.DataViewExportEvent;
import org.imixs.workflow.poi.POIFindReplaceAdapter;
import org.imixs.workflow.poi.POIUtil;
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...");
POIUtil.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();
POIUtil.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 = POIUtil.getCellReference(column, 10);
String cellRefTo = POIUtil.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;
// }
}

View file

@ -25,6 +25,7 @@ package org.imixs.workflow.office.dataview;
import java.io.IOException; import java.io.IOException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -42,6 +43,7 @@ import org.imixs.workflow.exceptions.PluginException;
import org.imixs.workflow.exceptions.QueryException; import org.imixs.workflow.exceptions.QueryException;
import org.imixs.workflow.faces.data.ViewController; import org.imixs.workflow.faces.data.ViewController;
import org.imixs.workflow.faces.data.ViewHandler; import org.imixs.workflow.faces.data.ViewHandler;
import org.imixs.workflow.faces.data.WorkflowController;
import org.imixs.workflow.office.forms.CustomFormController; import org.imixs.workflow.office.forms.CustomFormController;
import org.imixs.workflow.office.forms.CustomFormSection; import org.imixs.workflow.office.forms.CustomFormSection;
@ -78,11 +80,11 @@ public class DataViewController extends ViewController {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public static final String ERROR_CONFIG = "CONFIG_ERROR"; public static final String ERROR_CONFIG = "CONFIG_ERROR";
public static final int MAX_ROWS = 3000; public static final int MAX_ROWS = 9999;
private List<CustomFormSection> sections = null; private List<CustomFormSection> sections = null;
private List<ItemCollection> viewItemDefinitions = null; private List<ItemCollection> viewItemDefinitions = null;
protected ItemCollection dataDefinition = null; protected ItemCollection dataViewDefinition = null;
private ItemCollection filter; private ItemCollection filter;
private String query; private String query;
private String errorMessage; private String errorMessage;
@ -105,6 +107,12 @@ public class DataViewController extends ViewController {
@Inject @Inject
CustomFormController customFormController; CustomFormController customFormController;
@Inject
WorkflowController workflowController;
@Inject
DataViewDefaultExporter dataViewDefaultExporter;
@Inject @Inject
ViewHandler viewHandler; ViewHandler viewHandler;
@ -145,7 +153,7 @@ public class DataViewController extends ViewController {
// alternative 'workitem=...' // alternative 'workitem=...'
uniqueid = paramMap.get("workitem"); uniqueid = paramMap.get("workitem");
} }
dataDefinition = documentService.load(uniqueid); dataViewDefinition = documentService.load(uniqueid);
} }
if (uniqueid != null && !uniqueid.isEmpty()) { if (uniqueid != null && !uniqueid.isEmpty()) {
@ -156,23 +164,23 @@ public class DataViewController extends ViewController {
try { try {
// Init new Filter.... // Init new Filter....
if (dataDefinition != null) { if (dataViewDefinition != null) {
filter.setItemValue("txtWorkflowEditorCustomForm", dataDefinition.getItemValue("form")); filter.setItemValue("txtWorkflowEditorCustomForm", dataViewDefinition.getItemValue("form"));
filter.setItemValue("name", dataDefinition.getItemValueString("name")); filter.setItemValue("name", dataViewDefinition.getItemValueString("name"));
filter.setItemValue("description", dataDefinition.getItemValueString("description")); filter.setItemValue("description", dataViewDefinition.getItemValueString("description"));
viewItemDefinitions = DataViewDefinitionController viewItemDefinitions = DataViewDefinitionController
.computeDataViewItemDefinitions(dataDefinition); .computeDataViewItemDefinitions(dataViewDefinition);
customFormController.computeFieldDefinition(filter); customFormController.computeFieldDefinition(filter);
sections = customFormController.getSections(); sections = customFormController.getSections();
// Update View Handler settings // Update View Handler settings
String sortBy = dataDefinition.getItemValueString("sort.by"); String sortBy = dataViewDefinition.getItemValueString("sort.by");
if (sortBy.isEmpty()) { if (sortBy.isEmpty()) {
sortBy = "$modified"; sortBy = "$modified";
} }
this.setSortBy(sortBy); this.setSortBy(sortBy);
this.setSortReverse(dataDefinition.getItemValueBoolean("sort.reverse")); this.setSortReverse(dataViewDefinition.getItemValueBoolean("sort.reverse"));
this.setPageIndex(filter.getItemValueInteger("pageIndex")); this.setPageIndex(filter.getItemValueInteger("pageIndex"));
if (!filter.getItemValueString("query").isEmpty()) { if (!filter.getItemValueString("query").isEmpty()) {
query = filter.getItemValueString("query"); query = filter.getItemValueString("query");
@ -186,8 +194,22 @@ public class DataViewController extends ViewController {
} }
public ItemCollection getDefinition() { @Override
return dataDefinition; public List<ItemCollection> loadData() throws QueryException {
try {
return super.loadData();
} catch (Exception e) {
logger.severe("Failed to load view: " + e.getMessage());
return new ArrayList<>();
}
}
public ItemCollection getDataViewDefinition() {
return dataViewDefinition;
} }
public List<CustomFormSection> getSections() { public List<CustomFormSection> getSections() {
@ -224,13 +246,27 @@ public class DataViewController extends ViewController {
* *
* @throws QueryException * @throws QueryException
*/ */
public void run() throws QueryException { public void run() throws PluginException, QueryException {
reset(); reset();
// build new query from template // build new query from template
query = dataDefinition.getItemValueString("query"); query = dataViewDefinition.getItemValueString("query");
query = parseQuery(query, filter);
query = parseQuery(query, workflowController.getWorkitem());
logger.info("query=" + query);
filter.setItemValue("query", query);
// Prefetch data to update total count and page count
viewHandler.getData(this);
// cache filter
dataViewCache.put(dataViewDefinition.getUniqueID(), filter);
}
private String parseQuery(String query, ItemCollection filter) {
List<String> filterItems = filter.getItemNames(); List<String> filterItems = filter.getItemNames();
for (String itemName : filterItems) { for (String itemName : filterItems) {
String itemValue = filter.getItemValueString(itemName); String itemValue = filter.getItemValueString(itemName);
@ -251,14 +287,7 @@ public class DataViewController extends ViewController {
// Replace all occurrences in the query case-insensitive. // Replace all occurrences in the query case-insensitive.
query = query.replaceAll("(?i)\\{" + Pattern.quote(itemName) + "\\}", itemValue); query = query.replaceAll("(?i)\\{" + Pattern.quote(itemName) + "\\}", itemValue);
} }
logger.finest("query=" + query); return query;
filter.setItemValue("query", query);
// Prefetch data to update total count and page count
viewHandler.getData(this);
// cache filter
dataViewCache.put(dataDefinition.getUniqueID(), filter);
} }
/** /**
@ -304,7 +333,11 @@ public class DataViewController extends ViewController {
} }
/** /**
* Exports data into a excel template processed by apache-poi * Exports data into a excel template processed by apache-poi.
* The method sends a DataViewExport event to allow clients to adapt the export
* process.
*
* @see DataViewExportEvent
* *
* @throws PluginException * @throws PluginException
* @throws QueryException * @throws QueryException
@ -315,7 +348,7 @@ public class DataViewController extends ViewController {
run(); run();
SimpleDateFormat dateformat = new SimpleDateFormat("yyyyMMddHHmm"); SimpleDateFormat dateformat = new SimpleDateFormat("yyyyMMddHHmm");
String targetFileName = dataDefinition.getItemValueString("poi.targetFilename"); String targetFileName = dataViewDefinition.getItemValueString("poi.targetFilename");
if (targetFileName.isEmpty()) { if (targetFileName.isEmpty()) {
throw new PluginException(InkassoExportAdapter.class.getSimpleName(), ERROR_CONFIG, throw new PluginException(InkassoExportAdapter.class.getSimpleName(), ERROR_CONFIG,
"Missing Excel Export definition - check configuration!"); "Missing Excel Export definition - check configuration!");
@ -339,22 +372,25 @@ public class DataViewController extends ViewController {
throw new PluginException(InkassoExportAdapter.class.getSimpleName(), ERROR_CONFIG, throw new PluginException(InkassoExportAdapter.class.getSimpleName(), ERROR_CONFIG,
"Data can not be exported into Excel because dataset exceeds " + MAX_ROWS + " rows!"); "Data can not be exported into Excel because dataset exceeds " + MAX_ROWS + " rows!");
} }
String sortBy = dataDefinition.getItemValueString("sort.by"); String sortBy = dataViewDefinition.getItemValueString("sort.by");
if (sortBy.isEmpty()) { if (sortBy.isEmpty()) {
sortBy = "$modified"; // default sortBy = "$modified"; // default
} }
List<ItemCollection> invoices = documentService.find(query, MAX_ROWS, 0, sortBy, List<ItemCollection> invoices = documentService.find(query, MAX_ROWS, 0, sortBy,
dataDefinition.getItemValueBoolean("sort.reverse")); dataViewDefinition.getItemValueBoolean("sort.reverse"));
if (invoices.size() > 0) { if (invoices.size() > 0) {
String referenceCell = dataDefinition.getItemValueString("poi.referenceCell"); dataViewDefaultExporter.insertDataRows(invoices, dataViewDefinition, viewItemDefinitions, fileData);
DataViewPOIHelper.insertDataRows(invoices, referenceCell, viewItemDefinitions, fileData);
} }
// create a temp event // create a temp event
ItemCollection event = new ItemCollection().setItemValue("txtActivityResult", ItemCollection event = new ItemCollection().setItemValue("txtActivityResult",
dataDefinition.getItemValue("poi.update")); dataViewDefinition.getItemValue("poi.update"));
ItemCollection poiConfig = workflowService.evalWorkflowResult(event, "poi-update", dataDefinition, ItemCollection poiConfig = workflowService.evalWorkflowResult(event, "poi-update", dataViewDefinition,
false); false);
// merge workitem fields (Workaround because custom forms did hard coded map to
// workflowController instead of workitem
filter.copy(workflowController.getWorkitem());
DataViewPOIHelper.poiUpdate(filter, fileData, poiConfig, workflowService); DataViewPOIHelper.poiUpdate(filter, fileData, poiConfig, workflowService);
fileData.setName(targetFileName); fileData.setName(targetFileName);
@ -381,10 +417,10 @@ public class DataViewController extends ViewController {
private FileData loadTemplate() { private FileData loadTemplate() {
// first filename // first filename
List<FileData> fileDataList = dataDefinition.getFileData(); List<FileData> fileDataList = dataViewDefinition.getFileData();
if (fileDataList != null && fileDataList.size() > 0) { if (fileDataList != null && fileDataList.size() > 0) {
String fileName = fileDataList.get(0).getName(); String fileName = fileDataList.get(0).getName();
return snapshotService.getWorkItemFile(dataDefinition.getUniqueID(), fileName); return snapshotService.getWorkItemFile(dataViewDefinition.getUniqueID(), fileName);
} }
// no file data available! // no file data available!
return null; return null;

View file

@ -0,0 +1,145 @@
package org.imixs.workflow.office.dataview;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
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.workflow.FileData;
import org.imixs.workflow.ItemCollection;
import org.imixs.workflow.exceptions.PluginException;
import org.imixs.workflow.office.forms.AnalyticController;
import jakarta.enterprise.context.ConversationScoped;
import jakarta.enterprise.event.Event;
import jakarta.inject.Inject;
import jakarta.inject.Named;
/**
* The DataViewDefaultExporter exports a dataset into a excel template. The
* exporter sends a DataViewExportEvent. An observer CID bean can implement
* alternative exporters.
* With the event property 'completed' a client can signal that the export
* process is completed. Otherwise the default behavior will be adapted.
*
* @author rsoika
*
*/
@Named
@ConversationScoped
public class DataViewDefaultExporter implements Serializable {
public static final String ERROR_CONFIG = "CONFIG_ERROR";
private static final long serialVersionUID = 1L;
private static Logger logger = Logger.getLogger(AnalyticController.class.getName());
@Inject
protected Event<DataViewExportEvent> dataViewExportEvents;
/**
* This helper method inserts a row for each invoice
*
* @throws PluginException
*/
public void insertDataRows(List<ItemCollection> dataset, ItemCollection dataViewDefinition,
List<ItemCollection> viewItemDefinitions,
FileData fileData) throws PluginException {
// load XSSFWorkbook
try (InputStream imputStream = new ByteArrayInputStream(fileData.getContent())) {
XSSFWorkbook doc = new XSSFWorkbook(imputStream);
// send DataViewExportEvent....
if (dataViewExportEvents != null) {
DataViewExportEvent event = new DataViewExportEvent(dataset, dataViewDefinition, viewItemDefinitions,
doc);
dataViewExportEvents.fire(event); // found FileData?
if (!event.isCompleted()) {
// Default behavior
defaultExport(dataset, dataViewDefinition, viewItemDefinitions, doc);
}
}
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
// write back the file
doc.write(byteArrayOutputStream);
doc.close();
byte[] newContent = byteArrayOutputStream.toByteArray();
fileData.setContent(newContent);
} catch (IOException e) {
throw new PluginException(DataViewPOIHelper.class.getSimpleName(), ERROR_CONFIG,
"failed to update excel export: " + e.getMessage());
}
}
/**
* This is the default implementation to insert a dataset into a XSSFSheet
*
* @param dataset
* @param referenceCell
* @param viewItemDefinitions
* @param doc
*/
private void defaultExport(List<ItemCollection> dataset, ItemCollection dataViewDefinition,
List<ItemCollection> viewItemDefinitions, XSSFWorkbook doc) {
String referenceCell = dataViewDefinition.getItemValueString("poi.referenceCell");
// NOTE: we only take the first sheet !
XSSFSheet sheet = doc.getSheetAt(0);
CellReference cr = new CellReference(referenceCell);
XSSFRow referenceRow = sheet.getRow(cr.getRow());
int referenceRowPos = referenceRow.getRowNum() + 1;
int rowPos = referenceRowPos;
// int lastRow = sheet.getLastRowNum();
int lastRow = 999;
logger.finest("Last rownum=" + lastRow);
sheet.shiftRows(rowPos, lastRow, dataset.size(), true, true);
for (ItemCollection workitem : dataset) {
logger.finest("......copy row...");
// now create a new line..
XSSFRow row = sheet.createRow(rowPos);
row.copyRowFrom(referenceRow, new CellCopyPolicy());
// insert values
int cellNum = 0;
for (ItemCollection itemDef : viewItemDefinitions) {
String type = itemDef.getItemValueString("item.type");
String name = itemDef.getItemValueString("item.name");
switch (type) {
case "xs:double":
row.getCell(cellNum).setCellValue(workitem.getItemValueDouble(name));
break;
case "xs:float":
row.getCell(cellNum).setCellValue(workitem.getItemValueFloat(name));
break;
case "xs:int":
row.getCell(cellNum).setCellValue(workitem.getItemValueInteger(name));
break;
case "xs:date":
row.getCell(cellNum).setCellValue(workitem.getItemValueDate(name));
break;
default:
row.getCell(cellNum).setCellValue(workitem.getItemValueString(name));
}
cellNum++;
}
rowPos++;
}
// delete reference row
sheet.shiftRows(referenceRowPos, lastRow + dataset.size(), -1, true, true);
}
}

View file

@ -0,0 +1,72 @@
package org.imixs.workflow.office.dataview;
import java.util.List;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.imixs.workflow.ItemCollection;
/**
* An DataViewExportEvent is send by the DataViewController during exporting a
* data view into a Excel Template.
* An observer can customize the export behavior and mark an export as
* completed by setting the flag 'completed' to true
*
*/
public class DataViewExportEvent {
private List<ItemCollection> dataset = null;
private ItemCollection dataViewDefinition = null;
private List<ItemCollection> viewItemDefinitions = null;
private XSSFWorkbook xssfWorkbook = null;
private boolean completed = false;
public DataViewExportEvent(List<ItemCollection> dataset, ItemCollection dataViewDefinition,
List<ItemCollection> viewItemDefinitions,
XSSFWorkbook xssfWorkbook) {
this.dataset = dataset;
this.dataViewDefinition = dataViewDefinition;
this.xssfWorkbook = xssfWorkbook;
this.viewItemDefinitions = viewItemDefinitions;
}
public boolean isCompleted() {
return completed;
}
public void setCompleted(boolean completed) {
this.completed = completed;
}
public List<ItemCollection> getDataset() {
return dataset;
}
public void setDataset(List<ItemCollection> dataset) {
this.dataset = dataset;
}
public ItemCollection getDataViewDefinition() {
return dataViewDefinition;
}
public void setDataViewDefinition(ItemCollection dataViewDefinition) {
this.dataViewDefinition = dataViewDefinition;
}
public List<ItemCollection> getViewItemDefinitions() {
return viewItemDefinitions;
}
public void setViewItemDefinitions(List<ItemCollection> viewItemDefinitions) {
this.viewItemDefinitions = viewItemDefinitions;
}
public XSSFWorkbook getXssfWorkbook() {
return xssfWorkbook;
}
public void setXssfWorkbook(XSSFWorkbook xssfWorkbook) {
this.xssfWorkbook = xssfWorkbook;
}
}

View file

@ -32,7 +32,6 @@ import java.util.Date;
import java.util.List; import java.util.List;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.apache.poi.ss.usermodel.CellCopyPolicy;
import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.FormulaEvaluator; import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.ss.usermodel.Name; import org.apache.poi.ss.usermodel.Name;
@ -93,72 +92,75 @@ public class DataViewPOIHelper {
* *
* @throws PluginException * @throws PluginException
*/ */
public static void insertDataRows(List<ItemCollection> dataset, String referenceCell, // public static void insertDataRows(List<ItemCollection> dataset, String
List<ItemCollection> viewItemDefinitions, // referenceCell,
FileData fileData) throws PluginException { // List<ItemCollection> viewItemDefinitions,
// load XSSFWorkbook // FileData fileData) throws PluginException {
try (InputStream imputStream = new ByteArrayInputStream(fileData.getContent())) { // // load XSSFWorkbook
XSSFWorkbook doc = new XSSFWorkbook(imputStream); // try (InputStream imputStream = new
// NOTE: we only take the first sheet ! // ByteArrayInputStream(fileData.getContent())) {
XSSFSheet sheet = doc.getSheetAt(0); // XSSFWorkbook doc = new XSSFWorkbook(imputStream);
// // NOTE: we only take the first sheet !
// XSSFSheet sheet = doc.getSheetAt(0);
CellReference cr = new CellReference(referenceCell); // CellReference cr = new CellReference(referenceCell);
XSSFRow referenceRow = sheet.getRow(cr.getRow()); // XSSFRow referenceRow = sheet.getRow(cr.getRow());
int referenceRowPos = referenceRow.getRowNum() + 1; // int referenceRowPos = referenceRow.getRowNum() + 1;
int rowPos = referenceRowPos; // int rowPos = referenceRowPos;
// int lastRow = sheet.getLastRowNum(); // // int lastRow = sheet.getLastRowNum();
int lastRow = 999; // int lastRow = 999;
logger.finest("Last rownum=" + lastRow); // logger.finest("Last rownum=" + lastRow);
sheet.shiftRows(rowPos, lastRow, dataset.size(), true, true); // sheet.shiftRows(rowPos, lastRow, dataset.size(), true, true);
for (ItemCollection workitem : dataset) { // for (ItemCollection workitem : dataset) {
logger.finest("......copy row..."); // logger.finest("......copy row...");
// now create a new line.. // // now create a new line..
XSSFRow row = sheet.createRow(rowPos); // XSSFRow row = sheet.createRow(rowPos);
row.copyRowFrom(referenceRow, new CellCopyPolicy()); // row.copyRowFrom(referenceRow, new CellCopyPolicy());
// insert values // // insert values
int cellNum = 0; // int cellNum = 0;
for (ItemCollection itemDef : viewItemDefinitions) { // for (ItemCollection itemDef : viewItemDefinitions) {
String type = itemDef.getItemValueString("item.type"); // String type = itemDef.getItemValueString("item.type");
String name = itemDef.getItemValueString("item.name"); // String name = itemDef.getItemValueString("item.name");
switch (type) { // switch (type) {
case "xs:double": // case "xs:double":
row.getCell(cellNum).setCellValue(workitem.getItemValueDouble(name)); // row.getCell(cellNum).setCellValue(workitem.getItemValueDouble(name));
break; // break;
case "xs:float": // case "xs:float":
row.getCell(cellNum).setCellValue(workitem.getItemValueFloat(name)); // row.getCell(cellNum).setCellValue(workitem.getItemValueFloat(name));
break; // break;
case "xs:int": // case "xs:int":
row.getCell(cellNum).setCellValue(workitem.getItemValueInteger(name)); // row.getCell(cellNum).setCellValue(workitem.getItemValueInteger(name));
break; // break;
case "xs:date": // case "xs:date":
row.getCell(cellNum).setCellValue(workitem.getItemValueDate(name)); // row.getCell(cellNum).setCellValue(workitem.getItemValueDate(name));
break; // break;
default: // default:
row.getCell(cellNum).setCellValue(workitem.getItemValueString(name)); // row.getCell(cellNum).setCellValue(workitem.getItemValueString(name));
} // }
cellNum++; // cellNum++;
} // }
rowPos++; // rowPos++;
} // }
// delete reference row // // delete reference row
sheet.shiftRows(referenceRowPos, lastRow + dataset.size(), -1, true, true); // sheet.shiftRows(referenceRowPos, lastRow + dataset.size(), -1, true, true);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); // ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
// write back the file // // write back the file
doc.write(byteArrayOutputStream); // doc.write(byteArrayOutputStream);
doc.close(); // doc.close();
byte[] newContent = byteArrayOutputStream.toByteArray(); // byte[] newContent = byteArrayOutputStream.toByteArray();
fileData.setContent(newContent); // fileData.setContent(newContent);
} catch (IOException e) { // } catch (IOException e) {
throw new PluginException(DataViewPOIHelper.class.getSimpleName(), ERROR_CONFIG, // throw new PluginException(DataViewPOIHelper.class.getSimpleName(),
"failed to update excel export: " + e.getMessage()); // ERROR_CONFIG,
} // "failed to update excel export: " + e.getMessage());
} // }
// }
/** /**
* This helper method applies the POI update defintiions a row for each invoice * This helper method applies the POI update defintiions a row for each invoice

View file

@ -2,9 +2,9 @@
# Imixs Lucene Plugin # Imixs Lucene Plugin
############################## ##############################
lucence.indexDir=${imixs-office.IndexDir} lucence.indexDir=${imixs-office.IndexDir}
index.fields=txtsearchstring,txtSubject,txtname,txtEmail,txtUserName,namCreator,txtworkflowgroup,txtworkflowstatus,txtWorkflowAbstract,txtWorkflowSummary,txtworkflowhistory,txtspacename,txtprocessname,_subject,_description,_name,_projectnumber,_projectname,_ordernumber,_contractnumber,datDueDate,txtcommentlog,htmldescription,htmldocumentation,dms,dms_names,invoice.number.stripped,_childitems,$file.names,_VENDOR_NAME,dbtr.number,cdtr.number,invoice.positions,invoice.atc.number index.fields=txtsearchstring,txtSubject,txtname,txtEmail,txtUserName,namCreator,txtworkflowgroup,txtworkflowstatus,txtWorkflowAbstract,txtWorkflowSummary,txtworkflowhistory,txtspacename,txtprocessname,_subject,_description,_name,_projectnumber,_projectname,_ordernumber,_contractnumber,datDueDate,txtcommentlog,htmldescription,htmldocumentation,dms,dms_names,invoice.number.stripped,_childitems,$file.names,_VENDOR_NAME,dbtr.number,partner.id,cdtr.number,invoice.positions,invoice.atc.number
index.fields.analyze=txtUsername index.fields.analyze=txtUsername
index.fields.noanalyze=type,$UniqueIDRef,$created,$modified,$ModelVersion,$participants,namCreator,$ProcessID,datDate,txtWorkflowGroup,txtemail, datdate, datfrom, datto, numsequencenumber,sequencenumber,dms_count,invoice.number,invoice.number.stripped,invoice.date,invoice.duedate,taxonomy.verteilung.stop,taxonomy.sachpruefung.stop,taxonomy.verteilung.start,taxonomy.sachpruefung.start,taxonomy.buchhaltung.start,taxonomy.buchhaltung.stop,dbtr.number,cdtr.number,payment.date,invoice.total,invoice.currency,invoice.positions,$lasteventdate,payment.type,cdtr.name,document.company,invoice.atc.number index.fields.noanalyze=type,$UniqueIDRef,$created,$modified,$ModelVersion,$participants,namCreator,$ProcessID,datDate,txtWorkflowGroup,txtemail, datdate, datfrom, datto, numsequencenumber,sequencenumber,dms_count,invoice.number,invoice.number.stripped,invoice.date,invoice.duedate,taxonomy.verteilung.stop,taxonomy.sachpruefung.stop,taxonomy.verteilung.start,taxonomy.sachpruefung.start,taxonomy.buchhaltung.start,taxonomy.buchhaltung.stop,dbtr.number,partner.id,cdtr.number,payment.date,invoice.total,invoice.currency,invoice.positions,$lasteventdate,payment.type,cdtr.name,document.company,invoice.atc.number
index.fields.store=process.name,txtProcessName,txtWorkflowImageURL,payment.date,invoice.number,invoice.date,invoice.duedate,invoice.total,invoice.currency,dbtr.name,cdtr.name index.fields.store=process.name,txtProcessName,txtWorkflowImageURL,payment.date,invoice.number,invoice.date,invoice.duedate,invoice.total,invoice.currency,dbtr.name,cdtr.name
index.fields.category=space.name,space.ref,taxonomy.verteilung.stop.by,taxonomy.sachpruefung.stop.by,taxonomy.buchhaltung.stop.by index.fields.category=space.name,space.ref,taxonomy.verteilung.stop.by,taxonomy.sachpruefung.stop.by,taxonomy.buchhaltung.stop.by
office.search.noanalyze=invoice.number,invoice.number.stripped,invoice.positions office.search.noanalyze=invoice.number,invoice.number.stripped,invoice.positions

View file

@ -46,34 +46,25 @@
<div class="imixs-header"> <div class="imixs-header">
<h1> <h1>
<h:outputText value="Data View: " /> <h:outputText value="Data View: " />
<h:outputText value="#{dataViewController.definition.item['name']} " /> <h:outputText value="#{dataViewController.dataViewDefinition.item['name']} " />
</h1> </h1>
</div> </div>
<h:panelGroup styleClass="imixs-form-panel imixs-view" layout="block" id="dataview_form_id"> <h:panelGroup styleClass="imixs-form-panel imixs-view" layout="block" id="dataview_form_id">
<div class=" imixs-form-section"> <div class=" imixs-form-section">
<ui:include src="/pages/workitems/forms/custom_sections.xhtml"> <ui:include src="/pages/workitems/forms/custom_sections.xhtml">
<ui:param name="customFormSections" value="#{customFormController.sections}" /> <ui:param name="customFormSections" value="#{customFormController.sections}" />
<ui:param name="workitem" value="#{dataViewController.filter}" /> <ui:param name="workitem" value="#{dataViewController.filter}" />
<ui:param name="readonly" value="#{section.readonly}" /> <ui:param name="readonly" value="#{section.readonly}" />
</ui:include> </ui:include>
</div> </div>
</h:panelGroup> </h:panelGroup>
<h:panelGroup styleClass="imixs-view imixs-search" layout="block" id="dataview_result_id"> <h:panelGroup styleClass="imixs-view imixs-search" layout="block" id="dataview_result_id">
<ui:param name="searchResult" value="#{viewHandler.getData(dataViewController)}" /> <ui:param name="searchResult" value="#{viewHandler.getData(dataViewController)}" />
<ui:param name="searchPage" <ui:param name="searchPage"
value="#{(dataViewController.getPageIndex()+1)}/#{(dataViewController.getTotalPages())}" /> value="#{(dataViewController.getPageIndex()+1)}/#{(dataViewController.getTotalPages())}" />
<!-- Buttons --> <!-- Buttons -->
<div id="dataview-controlls-id" class="imixs-form-section"> <div id="dataview-controlls-id" class="imixs-form-section">
<div style="float:left;"> <div style="float:left;">

View file

@ -17,7 +17,7 @@
<ui:fragment rendered="#{!readonly}"> <ui:fragment rendered="#{!readonly}">
<h:commandScript name="updateBPForm" action="#{businessPartnerController.updateMetaData()}" <h:commandScript name="updateBPForm" action="#{businessPartnerController.updateMetaData(workitem)}"
onevent="handleUpdateEvent" onevent="handleUpdateEvent"
execute="#{businessPartnerController.isRerenderMode(options)?customFormComponents.clientId:''}" execute="#{businessPartnerController.isRerenderMode(options)?customFormComponents.clientId:''}"
render="#{businessPartnerController.isRerenderMode(options)?customFormComponents.clientId:''}" /> render="#{businessPartnerController.isRerenderMode(options)?customFormComponents.clientId:''}" />

View file

@ -256,7 +256,7 @@
</imixs-form-section> </imixs-form-section>
<imixs-form-section columns="1" label="Payment History"> <imixs-form-section columns="1" label="Payment History">
<item name="analytic.invoices.trend" type="custom" path="alexander/analyze_chart" <item name="analytic.invoices.trend" type="custom" path="alexander/analyze_chart"
label="Trend der letzten 6 Monate:" /> label="The trend over the last 6 months:" />
</imixs-form-section> </imixs-form-section>
</imixs-subform> </imixs-subform>
@ -710,13 +710,23 @@
<modelversion>mahnlauf-en-1.0</modelversion> <modelversion>mahnlauf-en-1.0</modelversion>
<task>1000</task> <task>1000</task>
<event>10</event> <event>10</event>
<items>partner.id,partner.name,dbtr.number,partner.name|dbtr.name</items> <items>partner.id,partner.name,dbtr.number,dbtr.mail,partner.name|dbtr.name</items>
<action>/pages/workitems/workitem.jsf?id=<itemvalue>$uniqueid</itemvalue></action> <action>/pages/workitems/workitem.jsf?id=<itemvalue>$uniqueid</itemvalue></action>
</split>]]></imixs:value> </split>]]></imixs:value>
</imixs:item> </imixs:item>
<imixs:item name="txtbusinessrule" type="xs:string">
<imixs:value><![CDATA[var result={};
result.isValid=true;
if (workitem.getItemValueString('dbtr.mail')==='') {
result.isValid=false;
result.errorMessage='Please enter a valid debitor e-mail address in the section base data!';
}]]></imixs:value>
</imixs:item>
</bpmn2:extensionElements> </bpmn2:extensionElements>
<bpmn2:documentation id="documentation_Pkda2Q"/> <bpmn2:documentation id="documentation_Pkda2Q"/>
<bpmn2:outgoing>sequenceFlow_ZTiO7w</bpmn2:outgoing> <bpmn2:outgoing>sequenceFlow_ZTiO7w</bpmn2:outgoing>
<bpmn2:compensationEventDefinition id="compensationEventDefinition_EDy4KA"/>
</bpmn2:intermediateCatchEvent> </bpmn2:intermediateCatchEvent>
<bpmn2:sequenceFlow id="sequenceFlow_ZTiO7w" sourceRef="event_zzWQSA" targetRef="task_Q80A1Q"> <bpmn2:sequenceFlow id="sequenceFlow_ZTiO7w" sourceRef="event_zzWQSA" targetRef="task_Q80A1Q">
<bpmn2:documentation id="documentation_S2i1Tg"/> <bpmn2:documentation id="documentation_S2i1Tg"/>
@ -742,7 +752,7 @@
</poi-update> </poi-update>
<poi-update name="findreplace"> <poi-update name="findreplace">
<find>A7</find> <find>A7</find>
<replace><itemvalue>dbtr.name</itemvalue></replace> <replace><itemvalue>partner.name</itemvalue></replace>
</poi-update>]]></imixs:value> </poi-update>]]></imixs:value>
</imixs:item> </imixs:item>
</bpmn2:extensionElements> </bpmn2:extensionElements>

View file

@ -483,7 +483,7 @@ Debitor: <itemvalue>dbtr.name</itemvalue> (<itemvalue>dbtr.number</itemvalue>)
<imixs:value><![CDATA[0]]></imixs:value> <imixs:value><![CDATA[0]]></imixs:value>
</imixs:item> </imixs:item>
<imixs:item name="nammailreceiverbcc" type="xs:string"> <imixs:item name="nammailreceiverbcc" type="xs:string">
<imixs:value><![CDATA[ausgangsmahnungen@alexander-logistics.com]]></imixs:value> <imixs:value/>
</imixs:item> </imixs:item>
<imixs:item name="keymailreceiverfields" type="xs:string"> <imixs:item name="keymailreceiverfields" type="xs:string">
<imixs:value><![CDATA[dbtr.mail]]></imixs:value> <imixs:value><![CDATA[dbtr.mail]]></imixs:value>
@ -491,8 +491,11 @@ Debitor: <itemvalue>dbtr.name</itemvalue> (<itemvalue>dbtr.number</itemvalue>)
<imixs:item name="nammailreceivercc" type="xs:string"> <imixs:item name="nammailreceivercc" type="xs:string">
<imixs:value/> <imixs:value/>
</imixs:item> </imixs:item>
<imixs:item name="keymailreceiverfieldsbcc" type="xs:string">
<imixs:value><![CDATA[namprocessmanager]]></imixs:value>
</imixs:item>
</bpmn2:extensionElements> </bpmn2:extensionElements>
<bpmn2:messageEventDefinition id="MessageEventDefinition_2"/> <bpmn2:messageEventDefinition id="MessageEventDefinition_2" messageRef="Message_2"/>
<bpmn2:documentation id="documentation_B7FClw"/> <bpmn2:documentation id="documentation_B7FClw"/>
<bpmn2:incoming>sequenceFlow_9Q3CYw</bpmn2:incoming> <bpmn2:incoming>sequenceFlow_9Q3CYw</bpmn2:incoming>
<bpmn2:outgoing>sequenceFlow_mDFboQ</bpmn2:outgoing> <bpmn2:outgoing>sequenceFlow_mDFboQ</bpmn2:outgoing>

View file

@ -1379,7 +1379,7 @@ Betrag: <itemvalue>_amount</itemvalue> (Brutto € <itemvalue>_amount_brutto</it
</imixs:item> </imixs:item>
<imixs:item name="txtactivityresult" type="xs:string"> <imixs:item name="txtactivityresult" type="xs:string">
<imixs:value><![CDATA[<model> <imixs:value><![CDATA[<model>
<version>(^rechnungseingang-sachrechnung-\d+(?:\.\d+)?$)</version> <version>(^rechnungseingang-sachrechnung-dwc-\d+(?:\.\d+)?$)</version>
<task>5001</task> <task>5001</task>
<event>980</event> <event>980</event>
</model>]]></imixs:value> </model>]]></imixs:value>

View file

@ -141,7 +141,6 @@ th { font-weight: bold;}
<bpmn2:documentation id="documentation_N3gEbw"/> <bpmn2:documentation id="documentation_N3gEbw"/>
<bpmn2:flowNodeRef>TextAnnotation_2</bpmn2:flowNodeRef> <bpmn2:flowNodeRef>TextAnnotation_2</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>IntermediateCatchEvent_1</bpmn2:flowNodeRef> <bpmn2:flowNodeRef>IntermediateCatchEvent_1</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>event_orShLw</bpmn2:flowNodeRef>
</bpmn2:lane> </bpmn2:lane>
</bpmn2:laneSet> </bpmn2:laneSet>
<bpmn2:intermediateCatchEvent id="IntermediateCatchEvent_5000-20" imixs:activityid="50" name="[Due date]"> <bpmn2:intermediateCatchEvent id="IntermediateCatchEvent_5000-20" imixs:activityid="50" name="[Due date]">
@ -471,7 +470,6 @@ Bei Fragen wenden Sie sich bitte an info@imixs.com
<bpmn2:outgoing>SequenceFlow_18</bpmn2:outgoing> <bpmn2:outgoing>SequenceFlow_18</bpmn2:outgoing>
<bpmn2:outgoing>SequenceFlow_34</bpmn2:outgoing> <bpmn2:outgoing>SequenceFlow_34</bpmn2:outgoing>
<bpmn2:incoming>sequenceFlow_zhcE7Q</bpmn2:incoming> <bpmn2:incoming>sequenceFlow_zhcE7Q</bpmn2:incoming>
<bpmn2:incoming>sequenceFlow_0D6BEw</bpmn2:incoming>
</bpmn2:task> </bpmn2:task>
<bpmn2:endEvent id="EndEvent_1" name="Ende"> <bpmn2:endEvent id="EndEvent_1" name="Ende">
<bpmn2:incoming>SequenceFlow_61</bpmn2:incoming> <bpmn2:incoming>SequenceFlow_61</bpmn2:incoming>
@ -1192,7 +1190,7 @@ Wiedervorlage wird um 7 bzw. 5 Tage erhöht</bpmn2:text>
<imixs:value><![CDATA[2]]></imixs:value> <imixs:value><![CDATA[2]]></imixs:value>
</imixs:item> </imixs:item>
<imixs:item name="keypublicresult" type="xs:string"> <imixs:item name="keypublicresult" type="xs:string">
<imixs:value><![CDATA[0]]></imixs:value> <imixs:value><![CDATA[1]]></imixs:value>
</imixs:item> </imixs:item>
<imixs:item name="keylogdateformat" type="xs:string"> <imixs:item name="keylogdateformat" type="xs:string">
<imixs:value><![CDATA[2]]></imixs:value> <imixs:value><![CDATA[2]]></imixs:value>
@ -1336,79 +1334,6 @@ Wiedervorlage wird um 7 bzw. 5 Tage erhöht</bpmn2:text>
<bpmn2:association id="association_xVkeww" sourceRef="DataObject_2" targetRef="Task_1"> <bpmn2:association id="association_xVkeww" sourceRef="DataObject_2" targetRef="Task_1">
<bpmn2:documentation id="documentation_euQGuA"/> <bpmn2:documentation id="documentation_euQGuA"/>
</bpmn2:association> </bpmn2:association>
<bpmn2:intermediateCatchEvent id="event_orShLw" imixs:activityid="10" name="testSave">
<bpmn2:extensionElements>
<imixs:item name="keylogtimeformat" type="xs:string">
<imixs:value><![CDATA[2]]></imixs:value>
</imixs:item>
<imixs:item name="keyarchive" type="xs:string">
<imixs:value><![CDATA[0]]></imixs:value>
</imixs:item>
<imixs:item name="txtmailsubject" type="xs:string">
<imixs:value/>
</imixs:item>
<imixs:item name="keyaccessmode" type="xs:string">
<imixs:value><![CDATA[0]]></imixs:value>
</imixs:item>
<imixs:item name="keyscheduledactivity" type="xs:string">
<imixs:value><![CDATA[0]]></imixs:value>
</imixs:item>
<imixs:item name="rtfmailbody" type="xs:string">
<imixs:value/>
</imixs:item>
<imixs:item name="keyversion" type="xs:string">
<imixs:value><![CDATA[0]]></imixs:value>
</imixs:item>
<imixs:item name="keyaddwritefields" type="xs:string">
<imixs:value><![CDATA[$creator]]></imixs:value>
<imixs:value><![CDATA[$editor]]></imixs:value>
<imixs:value><![CDATA[process.manager]]></imixs:value>
<imixs:value><![CDATA[process.team]]></imixs:value>
</imixs:item>
<imixs:item name="numnextactivityid" type="xs:int">
<imixs:value><![CDATA[0]]></imixs:value>
</imixs:item>
<imixs:item name="keyfollowup" type="xs:string">
<imixs:value><![CDATA[2]]></imixs:value>
</imixs:item>
<imixs:item name="keypublicresult" type="xs:string">
<imixs:value><![CDATA[1]]></imixs:value>
</imixs:item>
<imixs:item name="keylogdateformat" type="xs:string">
<imixs:value><![CDATA[2]]></imixs:value>
</imixs:item>
<imixs:item name="keyownershipfields" type="xs:string">
<imixs:value><![CDATA[$editor]]></imixs:value>
<imixs:value><![CDATA[$creator]]></imixs:value>
</imixs:item>
<imixs:item name="numnextid" type="xs:int">
<imixs:value><![CDATA[5000]]></imixs:value>
</imixs:item>
<imixs:item name="txtnextprocesstree" type="xs:string">
<imixs:value/>
</imixs:item>
<imixs:item name="txtactivityresult" type="xs:string">
<imixs:value><![CDATA[<item name="comment" ignore="true"/>]]></imixs:value>
</imixs:item>
<imixs:item name="txtname" type="xs:string">
<imixs:value><![CDATA[Speichern]]></imixs:value>
</imixs:item>
<imixs:item name="keyownershipmode" type="xs:string">
<imixs:value><![CDATA[0]]></imixs:value>
</imixs:item>
<imixs:item name="rtfresultlog" type="xs:string">
<imixs:value/>
</imixs:item>
<imixs:item name="keyupdateacl" type="xs:boolean">
<imixs:value>false</imixs:value>
</imixs:item>
</bpmn2:extensionElements>
<bpmn2:documentation id="documentation_L08SPA"><![CDATA[Zwischenspeichern]]></bpmn2:documentation>
<bpmn2:outgoing>sequenceFlow_0D6BEw</bpmn2:outgoing>
</bpmn2:intermediateCatchEvent>
<bpmn2:sequenceFlow id="sequenceFlow_0D6BEw" sourceRef="event_orShLw" targetRef="Task_1">
<bpmn2:documentation id="documentation_STlpCw"/>
</bpmn2:sequenceFlow>
<bpmn2:association id="association_xWTDhQ" sourceRef="DataObject_2" targetRef="Task_5"> <bpmn2:association id="association_xWTDhQ" sourceRef="DataObject_2" targetRef="Task_5">
<bpmn2:documentation id="documentation_JNVSMg"/> <bpmn2:documentation id="documentation_JNVSMg"/>
</bpmn2:association> </bpmn2:association>
@ -1578,9 +1503,9 @@ Wiedervorlage wird um 7 bzw. 5 Tage erhöht</bpmn2:text>
</bpmndi:BPMNLabel> </bpmndi:BPMNLabel>
</bpmndi:BPMNShape> </bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="IntermediateCatchEvent_9" id="BPMNShape_IntermediateCatchEvent_8"> <bpmndi:BPMNShape bpmnElement="IntermediateCatchEvent_9" id="BPMNShape_IntermediateCatchEvent_8">
<dc:Bounds height="36.0" width="36.0" x="677.0" y="817.0"/> <dc:Bounds height="36.0" width="36.0" x="687.0" y="827.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_84"> <bpmndi:BPMNLabel id="BPMNLabel_84">
<dc:Bounds height="20.0" width="100.0" x="647.5" y="855.0"/> <dc:Bounds height="20.0" width="100.0" x="657.5" y="865.0"/>
</bpmndi:BPMNLabel> </bpmndi:BPMNLabel>
</bpmndi:BPMNShape> </bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="TextAnnotation_2" id="BPMNShape_TextAnnotation_3"> <bpmndi:BPMNShape bpmnElement="TextAnnotation_2" id="BPMNShape_TextAnnotation_3">
@ -1777,14 +1702,14 @@ Wiedervorlage wird um 7 bzw. 5 Tage erhöht</bpmn2:text>
<di:waypoint x="1317.0" y="215.0"/> <di:waypoint x="1317.0" y="215.0"/>
</bpmndi:BPMNEdge> </bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_zhcE7Q" id="BPMNEdge_oQt4SA" sourceElement="BPMNShape_IntermediateCatchEvent_8" targetElement="BPMNShape_Task_3"> <bpmndi:BPMNEdge bpmnElement="sequenceFlow_zhcE7Q" id="BPMNEdge_oQt4SA" sourceElement="BPMNShape_IntermediateCatchEvent_8" targetElement="BPMNShape_Task_3">
<di:waypoint x="695.0" y="817.0"/> <di:waypoint x="705.0" y="827.0"/>
<di:waypoint x="695.0" y="805.0"/> <di:waypoint x="705.0" y="805.0"/>
<di:waypoint x="710.0" y="805.0"/> <di:waypoint x="745.0" y="805.0"/>
<di:waypoint x="710.0" y="780.0"/> <di:waypoint x="745.0" y="780.0"/>
</bpmndi:BPMNEdge> </bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="association_P36Fzw" id="BPMNEdge_QtxjNQ" sourceElement="BPMNShape_IntermediateCatchEvent_8" targetElement="BPMNShape_TextAnnotation_3"> <bpmndi:BPMNEdge bpmnElement="association_P36Fzw" id="BPMNEdge_QtxjNQ" sourceElement="BPMNShape_IntermediateCatchEvent_8" targetElement="BPMNShape_TextAnnotation_3">
<di:waypoint x="677.0" y="835.0"/> <di:waypoint x="687.0" y="845.0"/>
<di:waypoint x="575.0" y="835.0"/> <di:waypoint x="575.0" y="845.0"/>
<di:waypoint x="575.0" y="920.0"/> <di:waypoint x="575.0" y="920.0"/>
</bpmndi:BPMNEdge> </bpmndi:BPMNEdge>
<bpmndi:BPMNShape bpmnElement="task_LqbtSQ" id="BPMNShape_PXTHfw"> <bpmndi:BPMNShape bpmnElement="task_LqbtSQ" id="BPMNShape_PXTHfw">
@ -1861,18 +1786,6 @@ Wiedervorlage wird um 7 bzw. 5 Tage erhöht</bpmn2:text>
<di:waypoint x="648.0" y="755.0"/> <di:waypoint x="648.0" y="755.0"/>
<di:waypoint x="690.0" y="755.0"/> <di:waypoint x="690.0" y="755.0"/>
</bpmndi:BPMNEdge> </bpmndi:BPMNEdge>
<bpmndi:BPMNShape bpmnElement="event_orShLw" id="BPMNShape_Gm3gkg">
<dc:Bounds height="36.0" width="36.0" x="777.0" y="817.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_3YjJZA">
<dc:Bounds height="20.0" width="100.0" x="745.0" y="856.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_0D6BEw" id="BPMNEdge_oxlHKQ" sourceElement="BPMNShape_Gm3gkg" targetElement="BPMNShape_Task_3">
<di:waypoint x="795.0" y="817.0"/>
<di:waypoint x="795.0" y="799.0"/>
<di:waypoint x="745.0" y="799.0"/>
<di:waypoint x="745.0" y="780.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="association_xWTDhQ" id="BPMNEdge_lix3mw" sourceElement="BPMNShape_DataObject_1" targetElement="BPMNShape_Task_11"> <bpmndi:BPMNEdge bpmnElement="association_xWTDhQ" id="BPMNEdge_lix3mw" sourceElement="BPMNShape_DataObject_1" targetElement="BPMNShape_Task_11">
<di:waypoint x="605.0" y="195.0"/> <di:waypoint x="605.0" y="195.0"/>
<di:waypoint x="1088.0" y="195.0"/> <di:waypoint x="1088.0" y="195.0"/>

View file

@ -3308,7 +3308,7 @@ Betrag: <itemvalue>_amount</itemvalue> (Brutto € <itemvalue>_amount_brutto</it
<imixs:value><![CDATA[2]]></imixs:value> <imixs:value><![CDATA[2]]></imixs:value>
</imixs:item> </imixs:item>
<imixs:item name="keypublicresult" type="xs:string"> <imixs:item name="keypublicresult" type="xs:string">
<imixs:value><![CDATA[1]]></imixs:value> <imixs:value><![CDATA[0]]></imixs:value>
</imixs:item> </imixs:item>
<imixs:item name="keylogdateformat" type="xs:string"> <imixs:item name="keylogdateformat" type="xs:string">
<imixs:value><![CDATA[2]]></imixs:value> <imixs:value><![CDATA[2]]></imixs:value>