+ *
+ * @return
+ */
+ private String accumulateSteuerbescheideAbteilungByWeek() {
+ logger.fine("accumulate steuer by Abteilung week...");
+
+ String[] colors = { "#36a2eb", "#ff6384", "#4bc0c0", "#ff9f40", "#96f", "#ffcd56", "#c9cbcf" };
+
+ List list = getSteuerbescheide();
+ Map totalByWeek = new HashMap<>();
+ Calendar calendar = Calendar.getInstance();
+ int earliestWeek = Integer.MAX_VALUE;
+ int latestWeek = Integer.MIN_VALUE;
+
+ List abteilungsListe = new ArrayList<>();
+
+ // Step 1: Group total by week
+ for (ItemCollection steuerItemCol : list) {
+ String abteilung = steuerItemCol.getItemValueString("space.name");
+ if (abteilung.isEmpty()) {
+ abteilung = "Keine Zuordnung";
+ }
+ if (!abteilungsListe.contains(abteilung)) {
+ abteilungsListe.add(abteilung);
+ }
+ double saldo = steuerItemCol.getItemValueDouble("invoice.saldo");
+ double total = steuerItemCol.getItemValueDouble("invoice.total.net");
+ Date date = steuerItemCol.getItemValueDate("invoice.date");
+
+ logger.fine(".... " + steuerItemCol.getItemValueString("$workflowSummary") + " = " + total);
+ // Get the week number and year from the date
+ calendar.setTime(date);
+ int weekNumber = calendar.get(Calendar.WEEK_OF_YEAR);
+ int year = calendar.get(Calendar.YEAR);
+ int yearWeek = year * 100 + weekNumber;
+ String key = abteilung + "~" + yearWeek;// Unique key Import Forest~202405
+
+ // Accumulate the total per week
+ SteuerData steuerDataByWeek = totalByWeek.getOrDefault(key, new SteuerData());
+ double eust = getZollBySteuerBeleg(steuerItemCol, "EUST");
+ double zoll = getZollBySteuerBeleg(steuerItemCol, "ZOLL");
+ steuerDataByWeek.add(eust, zoll, total, saldo, abteilung);
+
+ totalByWeek.put(key, steuerDataByWeek);
+
+ // Track the earliest and latest weeks
+ earliestWeek = Math.min(earliestWeek, yearWeek);
+ latestWeek = Math.max(latestWeek, yearWeek);
+ }
+
+ // Step 2: Prepare the JSON structure and ensure we have all weeks from earliest
+ // to latest
+ JsonArrayBuilder labelsBuilder = Json.createArrayBuilder();
+ Calendar startCal = Calendar.getInstance();
+ startCal.set(Calendar.YEAR, earliestWeek / 100);
+ startCal.set(Calendar.WEEK_OF_YEAR, earliestWeek % 100);
+
+ Calendar endCal = Calendar.getInstance();
+ endCal.set(Calendar.YEAR, latestWeek / 100);
+ endCal.set(Calendar.WEEK_OF_YEAR, latestWeek % 100);
+
+ // Build labels - je eines pro woche
+ while (!startCal.after(endCal)) {
+ int weekNumber = startCal.get(Calendar.WEEK_OF_YEAR);
+ int year = startCal.get(Calendar.YEAR);
+ labelsBuilder.add(weekNumber + "/" + year); // Label as 'week/year'
+ // Move to the next week
+ startCal.add(Calendar.WEEK_OF_YEAR, 1);
+ }
+
+ // Step 3: Baue die Balken pro abrteilung
+ JsonArrayBuilder datasets = Json.createArrayBuilder();
+
+ JsonObjectBuilder jsonBuilder = Json.createObjectBuilder().add("type", "bar");
+
+ JsonObjectBuilder dataDing = Json.createObjectBuilder();
+ int iColor = 0;
+ for (String _abteilung : abteilungsListe) {
+ JsonArrayBuilder dataBuilderTotals = Json.createArrayBuilder();
+
+ startCal = Calendar.getInstance();
+ startCal.set(Calendar.YEAR, earliestWeek / 100);
+ startCal.set(Calendar.WEEK_OF_YEAR, earliestWeek % 100);
+
+ endCal = Calendar.getInstance();
+ endCal.set(Calendar.YEAR, latestWeek / 100);
+ endCal.set(Calendar.WEEK_OF_YEAR, latestWeek % 100);
+
+ while (!startCal.after(endCal)) {
+ int weekNumber = startCal.get(Calendar.WEEK_OF_YEAR);
+ int year = startCal.get(Calendar.YEAR);
+ int yearWeek = year * 100 + weekNumber;
+ String key = _abteilung + "~" + yearWeek;// Unique key Import Forest~202405
+ // Add the total for the week or 0.0 if no data
+ SteuerData steuerData = totalByWeek.getOrDefault(key, new SteuerData());
+ logger.fine(" " + yearWeek + "=" + steuerData.total);
+ dataBuilderTotals.add(steuerData.total);
+ // Move to the next week
+ startCal.add(Calendar.WEEK_OF_YEAR, 1);
+ }
+
+ datasets.add(Json.createObjectBuilder() // First dataset for 'tax'
+ .add("label", _abteilung).add("backgroundColor", colors[iColor]).add("borderWidth", 1)
+ .add("data", dataBuilderTotals));
+
+ iColor++;
+ if (iColor > colors.length) {
+ iColor = 0;
+ }
+ }
+
+ dataDing.add("datasets", datasets);
+ dataDing.add("labels", labelsBuilder);
+
+ jsonBuilder.add("data", dataDing);
+
+ // Step 4: Return the JSON structure as a string
+ JsonObject chartCfg = jsonBuilder.build();
+ return chartCfg.toString();
+ }
+
+ /**
+ * Helper method to hold zoll and eust totals in an object. Needed to build
+ * totals per week.
+ */
+ class SteuerData {
+ double total = 0.0;
+ double zoll = 0.0;
+ double eust = 0.0;
+ double saldo = 0.0;
+ String abteilung = "";
+
+ public SteuerData() {
+ // default constructor
+ }
+
+ /**
+ * Adds new zoll and eust values and updates the total
+ *
+ * @param eustNew eust value to be added
+ * @param zollNew zoll value to be added
+ */
+ public void add(double eustNew, double zollNew, double totalNew, double saldoNew, String abteilungNew) {
+ eust = eust + eustNew;
+ zoll = zoll + zollNew;
+ saldo = saldo + saldoNew;
+ total = total + totalNew;
+ abteilung = abteilungNew;
+ }
+
+ }
}
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/AGLAnalyticExcelAdapter.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/AGLAnalyticExcelAdapter.java
index 8af8716..0c6cb79 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/AGLAnalyticExcelAdapter.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/AGLAnalyticExcelAdapter.java
@@ -32,274 +32,260 @@ import jakarta.inject.Inject;
* Textblock und fügt die offenen Steuerbescheid Daten ein
*
* Der Adapter wird im Modell wie folgt konfiguriert
- *
+ *
*
* {@code
textblock-ref
filename
filename
-
+
}
*
- *
+ *
*
* Der Adapter erweitert den POIAdapter somit können Felder aktualisiert werden
* (siehe POIFineReplaceAdapter).
- *
+ *
*
* Der Adapter kopiert die Steuerbescheiddaten in neue Zeilen, welche ab
- * Zeilennummer
- * 16 eingefügt werden.
+ * Zeilennummer 16 eingefügt werden.
*
- *
+ *
* Abschliessend wird die Zelle 'TOTAL' noch aktualisiert.
- *
- *
+ *
+ *
* @version 1.0
* @author rsoika
*/
public class AGLAnalyticExcelAdapter extends POIFindReplaceAdapter {
- private static Logger logger = Logger.getLogger(AGLAnalyticExcelAdapter.class.getName());
+ private static Logger logger = Logger.getLogger(AGLAnalyticExcelAdapter.class.getName());
- @Inject
- WorkflowService workflowService;
+ @Inject
+ WorkflowService workflowService;
- @Inject
- InvoiceService opListExportService;
+ @Inject
+ InvoiceService opListExportService;
- @Inject
- DocumentService documentService;
+ @Inject
+ DocumentService documentService;
- @Inject
- ConfigService configService;
+ @Inject
+ ConfigService configService;
- /**
- * This method finds or create the Zahlungsavis and adds a reference
- * ($workitemref) to the current invoice.
- *
- * @throws PluginException
- */
- @SuppressWarnings("unchecked")
- @Override
- public ItemCollection execute(ItemCollection document, ItemCollection event)
- throws AdapterException, PluginException {
+ /**
+ * This method finds or create the Zahlungsavis and adds a reference
+ * ($workitemref) to the current invoice.
+ *
+ * @throws PluginException
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public ItemCollection execute(ItemCollection document, ItemCollection event)
+ throws AdapterException, PluginException {
- // ermittle die Hauptwährungen
- ItemCollection configItemCollection = configService.loadConfiguration("AGL_CONFIGURATION");
- List currencyList = configItemCollection.getItemValue("currency.out");
- if (currencyList == null || currencyList.size() < 2) {
- throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(),
- InvoiceService.ERROR_CONFIG,
- "missing Currency configuration - please check parameters");
- }
-
- // read the Steuerbescheide options
- ItemCollection steuerbescheideConfig = workflowService.evalWorkflowResult(event, "steuerbescheide",
- document,
- false);
- if (steuerbescheideConfig == null || !steuerbescheideConfig.hasItem("excel-export")) {
- throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(), CONFIG_ERROR,
- "missing Steuerbescheide configuration in model event - please check model configuration");
- }
- List excelDefList = steuerbescheideConfig.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 {
- appendExcelTemplate(document, textblock, template, targetName);
- insertInvoiceRows(document, targetName);
-
- logger.info("... loading poi configuration..");
- // Process POI instructions
- // read the config
- ItemCollection poiConfig = workflowService.evalWorkflowResult(event, "poi-update", document,
- false);
- if (poiConfig == null || !poiConfig.hasItem("findreplace")) {
- throw new PluginException(POIFindReplaceAdapter.class.getSimpleName(), CONFIG_ERROR,
- "missing poi configuration");
- }
- List replaceDevList = poiConfig.getItemValue("findreplace");
- String eval = poiConfig.getItemValueString("eval");
-
- logger.info("... update template with normal poi information..");
- this.updateFileData(document.getFileData(targetName), document, replaceDevList, eval);
-
- } catch (PluginException | IOException | QueryException e) {
- throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(),
- InvoiceService.ERROR_CONFIG,
- "failed to update steuerbescheide: " + e.getMessage());
- }
- logger.info("... completed!");
- return document;
+ // ermittle die Hauptwährungen
+ ItemCollection configItemCollection = configService.loadConfiguration("AGL_CONFIGURATION");
+ List currencyList = configItemCollection.getItemValue("currency.out");
+ if (currencyList == null || currencyList.size() < 2) {
+ throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
+ "missing Currency configuration - please check parameters");
}
- /**
- * This helper method inserts a row for each invoice 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 document, String fileName)
- throws PluginException, QueryException {
+ // read the Steuerbescheide options
+ ItemCollection steuerbescheideConfig = workflowService.evalWorkflowResult(event, "steuerbescheide", document,
+ false);
+ if (steuerbescheideConfig == null || !steuerbescheideConfig.hasItem("excel-export")) {
+ throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(), CONFIG_ERROR,
+ "missing Steuerbescheide configuration in model event - please check model configuration");
+ }
+ List excelDefList = steuerbescheideConfig.getItemValue("excel-export");
+ ItemCollection excelDefCollection = XMLParser.parseItemStructure(excelDefList.get(0));
- // load dummy rechnungen
- List invoices = loadSteuerbescheide();
+ String textblock = excelDefCollection.getItemValueString("textblock");
+ String template = excelDefCollection.getItemValueString("template");
+ String targetName = excelDefCollection.getItemValueString("target-name");
- FileData fileData = document.getFileData(fileName);
+ // adapt text....
+ targetName = workflowService.adaptText(targetName, document);
- // load XSSFWorkbook
- 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);
- 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);
+ try {
+ appendExcelTemplate(document, textblock, template, targetName);
+ insertInvoiceRows(document, targetName);
- // jetzt füge alle Rechnungen an.
- int totalRowCount = invoices.size();
- sheet.shiftRows(referenceRowPos, lastRow, totalRowCount, true, true);
- 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.booking_date"));
+ logger.info("... loading poi configuration..");
+ // Process POI instructions
+ // read the config
+ ItemCollection poiConfig = workflowService.evalWorkflowResult(event, "poi-update", document, false);
+ if (poiConfig == null || !poiConfig.hasItem("findreplace")) {
+ throw new PluginException(POIFindReplaceAdapter.class.getSimpleName(), CONFIG_ERROR,
+ "missing poi configuration");
+ }
+ List replaceDevList = poiConfig.getItemValue("findreplace");
+ String eval = poiConfig.getItemValueString("eval");
- // Änderung Frau Mwangi am 5.12.2025
- // Nun soll anstatt des Departments der Anmelder ausgegeben werden
- // row.getCell(4, MissingCellPolicy.CREATE_NULL_AS_BLANK)
- // .setCellValue(invoice.getItemValueString("space.name"));
- row.getCell(4, MissingCellPolicy.CREATE_NULL_AS_BLANK)
- .setCellValue(invoice.getItemValueString("steuer.anmelder"));
+ logger.info("... update template with normal poi information..");
+ this.updateFileData(document.getFileData(targetName), document, replaceDevList, eval);
- row.getCell(5, MissingCellPolicy.CREATE_NULL_AS_BLANK)
- .setCellValue(invoice.getItemValueString("invoice.text"));
- row.getCell(6, MissingCellPolicy.CREATE_NULL_AS_BLANK)
- .setCellValue(invoice.getItemValueString("invoice.atc.number"));
- row.getCell(7, MissingCellPolicy.CREATE_NULL_AS_BLANK)
- .setCellValue(invoice.getItemValueDouble("invoice.total.net"));
- row.getCell(8, MissingCellPolicy.CREATE_NULL_AS_BLANK)
- .setCellValue(invoice.getItemValueDouble("invoice.saldo"));
- row.getCell(9, MissingCellPolicy.CREATE_NULL_AS_BLANK)
- .setCellValue(invoice.getItemValueDouble("steuer.eust"));
- row.getCell(10, MissingCellPolicy.CREATE_NULL_AS_BLANK)
- .setCellValue(invoice.getItemValueDate("steuer.eust.due"));
- row.getCell(11, MissingCellPolicy.CREATE_NULL_AS_BLANK)
- .setCellValue(invoice.getItemValueDouble("steuer.zoll"));
- row.getCell(12, MissingCellPolicy.CREATE_NULL_AS_BLANK)
- .setCellValue(invoice.getItemValueDate("steuer.zoll.due"));
+ } catch (PluginException | IOException | QueryException e) {
+ throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
+ "failed to update steuerbescheide: " + e.getMessage());
+ }
+ logger.info("... completed!");
+ return document;
+ }
- rowPos++;
- }
+ /**
+ * This helper method inserts a row for each invoice 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 document, String fileName) throws PluginException, QueryException {
- // Leerzeile
- // categoryRow = sheet.createRow(rowPos);
- rowPos++;
+ // load dummy rechnungen
+ List invoices = loadSteuerbescheide();
- // write back the file
- ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
- doc.write(byteArrayOutputStream);
+ FileData fileData = document.getFileData(fileName);
- byte[] newContent = byteArrayOutputStream.toByteArray();
- FileData fileDataNew = new FileData(fileData.getName(), newContent, fileData.getContentType(),
- null);
- // update the fileData
- document.addFileData(fileDataNew);
+ // load XSSFWorkbook
+ 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);
+ 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);
- logger.finest("......new document added");
+ // jetzt füge alle Rechnungen an.
+ int totalRowCount = invoices.size();
+ sheet.shiftRows(referenceRowPos, lastRow, totalRowCount, true, true);
+ 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.booking_date"));
+ // Änderung Frau Mwangi am 5.12.2025
+ // Nun soll anstatt des Departments der Anmelder ausgegeben werden
+ // row.getCell(4, MissingCellPolicy.CREATE_NULL_AS_BLANK)
+ // .setCellValue(invoice.getItemValueString("space.name"));
+ row.getCell(4, MissingCellPolicy.CREATE_NULL_AS_BLANK)
+ .setCellValue(invoice.getItemValueString("steuer.anmelder"));
+
+ row.getCell(5, MissingCellPolicy.CREATE_NULL_AS_BLANK)
+ .setCellValue(invoice.getItemValueString("invoice.text"));
+ row.getCell(6, MissingCellPolicy.CREATE_NULL_AS_BLANK)
+ .setCellValue(invoice.getItemValueString("invoice.atc.number"));
+ row.getCell(7, MissingCellPolicy.CREATE_NULL_AS_BLANK)
+ .setCellValue(invoice.getItemValueDouble("invoice.total.net"));
+ row.getCell(8, MissingCellPolicy.CREATE_NULL_AS_BLANK)
+ .setCellValue(invoice.getItemValueDouble("invoice.saldo"));
+ row.getCell(9, MissingCellPolicy.CREATE_NULL_AS_BLANK)
+ .setCellValue(invoice.getItemValueDouble("steuer.eust"));
+ row.getCell(10, MissingCellPolicy.CREATE_NULL_AS_BLANK)
+ .setCellValue(invoice.getItemValueDate("steuer.eust.due"));
+ row.getCell(11, MissingCellPolicy.CREATE_NULL_AS_BLANK)
+ .setCellValue(invoice.getItemValueDouble("steuer.zoll"));
+ row.getCell(12, MissingCellPolicy.CREATE_NULL_AS_BLANK)
+ .setCellValue(invoice.getItemValueDate("steuer.zoll.due"));
+
+ rowPos++;
+ }
+
+ // Leerzeile
+ // categoryRow = sheet.createRow(rowPos);
+ rowPos++;
+
+ // write back the file
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ doc.write(byteArrayOutputStream);
+
+ byte[] newContent = byteArrayOutputStream.toByteArray();
+ FileData fileDataNew = new FileData(fileData.getName(), newContent, fileData.getContentType(), null);
+ // update the fileData
+ document.addFileData(fileDataNew);
+
+ logger.finest("......new document added");
+
+ } catch (IOException 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) {
- 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();
- }
- }
+ logger.severe("Failed to close workbook: " + e.getMessage());
+ e.printStackTrace();
}
+ }
+ }
+ }
+
+ /**
+ * This method loads a text-block for a specified ref and appends the named
+ * fileData object of this document.
+ *
+ * @param document
+ * @throws PluginException
+ */
+ private void 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 steuerbescheide configuration in model event - textblock/template reference not defined!");
}
- /**
- * This method loads a text-block for a specified ref and appends the named
- * fileData object of this document.
- *
- * @param document
- * @throws PluginException
- */
- private void 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 steuerbescheide configuration in model event - textblock/template reference not defined!");
- }
-
- // load the text block
- FileData fileData = opListExportService.loadTextBlockFileData(textblockRef, template);
-
- // do we found the document?
- if (fileData == null) {
- throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(),
- InvoiceService.ERROR_CONFIG,
- "invalid steuerbescheide configuration in model event - template=" + template
- + " not found!");
- }
- fileData.setName(targetName);
- // append document
- logger.info("...append new steuerbescheide Template: " + targetName);
- document.addFileData(fileData);
+ // load the text block
+ FileData fileData = opListExportService.loadTextBlockFileData(textblockRef, template);
+ // do we found the document?
+ if (fileData == null) {
+ throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
+ "invalid steuerbescheide configuration in model event - template=" + template + " not found!");
}
+ fileData.setName(targetName);
+ // append document
+ logger.info("...append new steuerbescheide Template: " + targetName);
+ document.addFileData(fileData);
- /**
- * Diese Methode läd alle offenen Steuerbescheide
- *
- * @return
- */
- private List loadSteuerbescheide() {
- List result = new ArrayList<>();
- try {
- result = documentService.find(
- "$modelversion:steuerbescheid-* AND type:workitem", 9999, 0,
- "invoice.number", false);
- } catch (QueryException e) {
- e.printStackTrace();
- }
- return result;
+ }
+
+ /**
+ * Diese Methode läd alle offenen Steuerbescheide
+ *
+ * @return
+ */
+ private List loadSteuerbescheide() {
+ List result = new ArrayList<>();
+ try {
+ result = documentService.find("$modelversion:steuerbescheid-* AND type:workitem", 9999, 0, "invoice.number",
+ false);
+ } catch (QueryException e) {
+ e.printStackTrace();
}
+ return result;
+ }
}
\ No newline at end of file
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/AGLAnalyticExcelAdapterDebitor.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/AGLAnalyticExcelAdapterDebitor.java
index 2cd4b18..a761ca0 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/AGLAnalyticExcelAdapterDebitor.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/AGLAnalyticExcelAdapterDebitor.java
@@ -35,30 +35,29 @@ import jakarta.inject.Inject;
* Textblock und fügt die offenen Recnungen ein
*
* Der Adapter wird im Modell wie folgt konfiguriert
- *
+ *
*
* {@code
textblock-ref
filename
filename
-
+
}
*
- *
+ *
*
* Der Adapter erweitert den POIAdapter somit können Felder aktualisiert werden
* (siehe POIFineReplaceAdapter).
- *
+ *
*
* Der Adapter kopiert die ausgangsrechnungen in neue Zeilen, welche ab
- * Zeilennummer
- * 16 eingefügt werden.
+ * Zeilennummer 16 eingefügt werden.
*
- *
+ *
* Abschliessend wird die Zelle 'TOTAL' noch aktualisiert.
- *
- *
+ *
+ *
* @version 1.0
* @author rsoika
*/
@@ -80,7 +79,7 @@ public class AGLAnalyticExcelAdapterDebitor extends POIFindReplaceAdapter {
/**
* This method
- *
+ *
* @throws PluginException
*/
@SuppressWarnings("unchecked")
@@ -92,9 +91,7 @@ public class AGLAnalyticExcelAdapterDebitor extends POIFindReplaceAdapter {
List currencyList = invoiceService.getCurrenciesOut();
// read the options
- ItemCollection ausgangsrechnungConfig = workflowService.evalWorkflowResult(event, "soa",
- document,
- false);
+ ItemCollection ausgangsrechnungConfig = workflowService.evalWorkflowResult(event, "soa", document, false);
if (ausgangsrechnungConfig == null || !ausgangsrechnungConfig.hasItem("excel-export")) {
throw new PluginException(AGLAnalyticExcelAdapterDebitor.class.getSimpleName(), CONFIG_ERROR,
"missing soa configuration in model event - please check model configuration");
@@ -129,14 +126,12 @@ public class AGLAnalyticExcelAdapterDebitor extends POIFindReplaceAdapter {
doc.write(byteArrayOutputStream);
byte[] newContent = byteArrayOutputStream.toByteArray();
- FileData fileDataNew = new FileData(fileData.getName(), newContent, fileData.getContentType(),
- null);
+ 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,
+ throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
"failed to update opliste: " + e.getMessage());
} finally {
if (doc != null) {
@@ -153,8 +148,7 @@ public class AGLAnalyticExcelAdapterDebitor extends POIFindReplaceAdapter {
processPOIUpdate(document, event, targetName);
} catch (PluginException e) {
- throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(),
- InvoiceService.ERROR_CONFIG,
+ throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
"failed to update steuerbescheide: " + e.getMessage());
}
logger.info("... completed!");
@@ -166,7 +160,7 @@ public class AGLAnalyticExcelAdapterDebitor extends POIFindReplaceAdapter {
* the Total and Saldo Colum for each currency
*
* The template provided only the columns for the first currency.
- *
+ *
* @param sheet
* @param currencyList
*/
@@ -201,7 +195,7 @@ public class AGLAnalyticExcelAdapterDebitor extends POIFindReplaceAdapter {
/**
* Hilfsmethode die das fuehrende K/D aus der Debitorennummer entfernt
- *
+ *
* @return
*/
private String getDbtNr(ItemCollection workitem) {
@@ -213,14 +207,14 @@ public class AGLAnalyticExcelAdapterDebitor extends POIFindReplaceAdapter {
}
/**
- * This helper method inserts a row for each invoice at row 16
- * into the excel template file
+ * This helper method inserts a row for each invoice 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
*/
@@ -249,8 +243,7 @@ public class AGLAnalyticExcelAdapterDebitor extends POIFindReplaceAdapter {
XSSFRow row = sheet.createRow(rowPos);
row.copyRowFrom(referenceRowInvoice, new CellCopyPolicy());
// insert values
- row.getCell(0)
- .setCellValue(invoice.getItemValueDate("$created"));
+ 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)
@@ -293,7 +286,7 @@ public class AGLAnalyticExcelAdapterDebitor extends POIFindReplaceAdapter {
/**
* Findet die Total Spalte für eine Währung
- *
+ *
* @param currency
* @return
*/
@@ -313,17 +306,15 @@ public class AGLAnalyticExcelAdapterDebitor extends POIFindReplaceAdapter {
/**
* 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 {
+ String targetName) throws PluginException {
if ((template == null || template.isEmpty()) || (textblockRef == null || textblockRef.isEmpty())) {
- throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(),
- InvoiceService.ERROR_CONFIG,
+ throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
"invalid SOA configuration in model event - textblock/template reference not defined!");
}
@@ -332,10 +323,8 @@ public class AGLAnalyticExcelAdapterDebitor extends POIFindReplaceAdapter {
// 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!");
+ throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
+ "invalid SOA configuration in model event - template=" + template + " not found!");
}
fileData.setName(targetName);
// append document
@@ -346,18 +335,15 @@ public class AGLAnalyticExcelAdapterDebitor extends POIFindReplaceAdapter {
/**
* Diese Methode läd alle offenen Steuerbescheide
- *
+ *
* @return
*/
private List loadInvoices(String dbtrNumber) {
List result = new ArrayList<>();
- String query = "(type:workitem) AND dbtr.number:" + dbtrNumber
- + " AND $modelversion:rechnungsausgang-*";
+ String query = "(type:workitem) AND dbtr.number:" + dbtrNumber + " AND $modelversion:rechnungsausgang-*";
try {
- result = documentService.find(
- query, 9999, 0,
- "invoice.number", false);
+ result = documentService.find(query, 9999, 0, "invoice.number", false);
} catch (QueryException e) {
e.printStackTrace();
}
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/AGLConfigController.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/AGLConfigController.java
index 09cbac6..a2212bd 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/AGLConfigController.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/AGLConfigController.java
@@ -1,51 +1,51 @@
-/*******************************************************************************
- * Imixs Workflow Technology
- * Copyright (C) 2003, 2008 Imixs Software Solutions GmbH,
- * http://www.imixs.com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You can receive a copy of the GNU General Public
- * License at http://www.gnu.org/licenses/gpl.html
- *
- * Contributors:
- * Imixs Software Solutions GmbH - initial API and implementation
- * Ralph Soika
- *
- *******************************************************************************/
-package com.alexanderlogistics;
-
-import org.imixs.workflow.office.config.ConfigController;
-
-import jakarta.enterprise.context.ApplicationScoped;
-import jakarta.inject.Named;
-
-/**
- * The Custom Config Controller for TAXES and Invoice typs
- *
- *
- * @author rsoika
- * @version 1.0
- */
-
-@Named("aglConfigController")
-// @RequestScoped
-@ApplicationScoped
-public class AGLConfigController extends ConfigController {
-
- private static final long serialVersionUID = 1L;
-
- public AGLConfigController() {
- super();
- setName("AGL_CONFIGURATION");
- }
-
-}
+/*******************************************************************************
+ * Imixs Workflow Technology
+ * Copyright (C) 2003, 2008 Imixs Software Solutions GmbH,
+ * http://www.imixs.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You can receive a copy of the GNU General Public
+ * License at http://www.gnu.org/licenses/gpl.html
+ *
+ * Contributors:
+ * Imixs Software Solutions GmbH - initial API and implementation
+ * Ralph Soika
+ *
+ *******************************************************************************/
+package com.alexanderlogistics;
+
+import org.imixs.workflow.office.config.ConfigController;
+
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Named;
+
+/**
+ * The Custom Config Controller for TAXES and Invoice typs
+ *
+ *
+ * @author rsoika
+ * @version 1.0
+ */
+
+@Named("aglConfigController")
+// @RequestScoped
+@ApplicationScoped
+public class AGLConfigController extends ConfigController {
+
+ private static final long serialVersionUID = 1L;
+
+ public AGLConfigController() {
+ super();
+ setName("AGL_CONFIGURATION");
+ }
+
+}
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/BusinessPartnerController.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/BusinessPartnerController.java
index e22ec66..749cc60 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/BusinessPartnerController.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/BusinessPartnerController.java
@@ -1,433 +1,427 @@
-/*******************************************************************************
- * Imixs Workflow Technology
- * Copyright (C) 2003, 2008 Imixs Software Solutions GmbH,
- * http://www.imixs.com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You can receive a copy of the GNU General Public
- * License at http://www.gnu.org/licenses/gpl.html
- *
- * Contributors:
- * Imixs Software Solutions GmbH - initial API and implementation
- * Ralph Soika
- *
- *******************************************************************************/
-package com.alexanderlogistics;
-
-import java.io.IOException;
-import java.io.Serializable;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.logging.Logger;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.imixs.workflow.ItemCollection;
-import org.imixs.workflow.engine.DocumentService;
-import org.imixs.workflow.exceptions.AccessDeniedException;
-import org.imixs.workflow.exceptions.QueryException;
-import org.imixs.workflow.faces.data.WorkflowController;
-import org.imixs.workflow.faces.data.WorkflowEvent;
-
-import jakarta.enterprise.context.ConversationScoped;
-import jakarta.enterprise.event.Observes;
-import jakarta.faces.context.FacesContext;
-import jakarta.inject.Inject;
-import jakarta.inject.Named;
-import jakarta.json.Json;
-import jakarta.json.JsonObject;
-import jakarta.json.JsonObjectBuilder;
-
-/**
- * Der BusinessPartnerController stellt Methoden für die BusinessPartner Forms
- * sowie für die das Suche-Widget 'businesspartner_search' bereit.
- *
- *
- * @author rsoika
- * @version 1.0
- */
-@Named
-@ConversationScoped
-public class BusinessPartnerController implements Serializable {
-
- private static final long serialVersionUID = 1L;
-
- protected List ibanList = null;
- protected List invoicesOut = null;
- protected List invoicesIn = null;
- protected List dunnings = null;
-
- @Inject
- protected WorkflowController workflowController;
-
- @Inject
- DocumentService documentService;
-
- @Inject
- BusinessPartnerService businessPartnerService;
-
- private List searchResult = null;
-
- private static Logger logger = Logger.getLogger(BusinessPartnerController.class.getName());
-
- public List getInvoicesOut() {
- if (invoicesOut == null) {
- invoicesOut = new ArrayList<>();
- }
- return invoicesOut;
- }
-
- public List getInvoicesIn() {
- if (invoicesIn == null) {
- invoicesIn = new ArrayList<>();
- }
- return invoicesIn;
- }
-
- public List getDunnings() {
- if (dunnings == null) {
- dunnings = new ArrayList<>();
- }
- return dunnings;
- }
-
- /**
- * This method searches a text phrase within the list of DATEV kreditoren
- *
- * JSF Integration:
- *
- * {@code
-
- * }
- */
- public void search(String options) {
- List resultList = null;
- searchResult = new ArrayList();
- // get the param from faces context....
- FacesContext fc = FacesContext.getCurrentInstance();
- String phrase = fc.getExternalContext().getRequestParameterMap().get("phrase");
- if (phrase == null) {
- return;
- }
-
- logger.fine("search prase '" + phrase + "'");
- if (phrase == null || phrase.length() < 2) {
- return;
- }
- logger.fine("search for=" + phrase);
- Pattern pattern = null;
- resultList = businessPartnerService.search(phrase);
- // Compile the regex pattern if available
- if (options.contains("regexPattern=")) {
- String regexPattern = options.substring(options.indexOf("regexPattern=") + 13);
- logger.fine("regex=" + regexPattern);
- pattern = Pattern.compile(regexPattern);
- }
-
- // Filter by Regex and convert ItemCollection into a BusinessPartnerSearchEntry
- for (ItemCollection businessPartner : resultList) {
- String name = businessPartner.getItemValueString("name");
- // Prüfen, ob der name der Regex entspricht
- if (pattern != null) {
- Matcher matcher = pattern.matcher(name);
- if (!matcher.matches()) {
- // Kein passendes Konto
- continue;
- }
- }
- String display = businessPartner.getItemValueString("$workflowsummary");
-
- display = display.replace("\"", "");
- display = display.replace("'", "");
-
- searchResult.add(new BusinessPartnerSearchEntry(name, display, buildJsonData(businessPartner)));
-
- }
- }
-
- /**
- * Diese Helper Method liefert true wenn in den Options von Form Part 'reRender'
- * angegeben wurde.
- * Damit löst die Suchmaske businesspartner_search.xhtml eine komplette rerender
- * Phase der Form aus.
- * Dies ist z.b. für den workflow 'analyse-debitor.bpmn' nützlich
- *
- * @param options
- * @return
- */
- public boolean isRerenderMode(String options) {
- return options.toLowerCase().contains("rerender");
- }
-
- /**
- * Die Resultliste wird als eine Liste einen Arrays zurückgegeben. Der Erste
- * Eintrag
- *
- * @return
- */
- public List getSearchResult() {
- return searchResult;
- }
-
- public ItemCollection getBusinessPartnerByID(String bpid) {
- ItemCollection partner = businessPartnerService.getBusinessPartnerByID(bpid);
- return partner;
- }
-
- /**
- * WorkflowEvent listener resolved additional data.
- *
- * For businesspartner the method converts the IBAN child list embeded HashMaps
- * into ItemCollections and reconvert them before processing
- *
- * for invoices the method resolve the partner.id and partner.name
- *
- * @param workflowEvent
- * @throws AccessDeniedException
- */
- public void onWorkflowEvent(@Observes WorkflowEvent workflowEvent) throws AccessDeniedException {
-
- int eventType = workflowEvent.getEventType();
- ItemCollection workitem = workflowEvent.getWorkitem();
- if (workitem == null) {
- return;
- }
- if (workitem.getModelVersion().startsWith("businesspartner-")) {
- // reset orderItems if workItem has changed
- if (WorkflowEvent.WORKITEM_CHANGED == eventType || WorkflowEvent.WORKITEM_CREATED == eventType) {
- // reset state
- ibanList = BusinessPartnerService.explodeBanks(workitem);
- loadStats(workitem);
- }
-
- // before the workitem is saved we update the field txtOrderItems
- if (WorkflowEvent.WORKITEM_BEFORE_PROCESS == eventType) {
- BusinessPartnerService.implodeBanks(workitem, ibanList);
- }
-
- if (WorkflowEvent.WORKITEM_AFTER_PROCESS == eventType) {
- // reset state
- ibanList = BusinessPartnerService.explodeBanks(workitem);
- }
- }
-
- if (workitem.getModelVersion().startsWith("rechnungsausgang-")) {
- // resolve partner.id and partner.name
- if (workitem.getItemValueString("partner.id").isEmpty()) {
- // try to resolve the data
- ItemCollection bpWorkitem = getBusinessPartnerByID(InvoiceUtil.getBPID(workitem));
- if (bpWorkitem != null) {
- workitem.setItemValue("partner.id", bpWorkitem.getItemValueString("partner.id"));
- workitem.setItemValue("partner.name", bpWorkitem.getItemValueString("partner.name"));
- }
- }
- }
-
- if (workitem.getModelVersion().startsWith("rechnungseingang-")) {
- // resolve partner.id and partner.name
- if (workitem.getItemValueString("partner.id").isEmpty()) {
- // try to resolve the data
- ItemCollection bpWorkitem = getBusinessPartnerByID(InvoiceUtil.getBPID(workitem));
- if (bpWorkitem != null) {
- workitem.setItemValue("partner.id", bpWorkitem.getItemValueString("partner.id"));
- workitem.setItemValue("partner.name", bpWorkitem.getItemValueString("partner.name"));
- }
- }
- }
-
- if (workitem.getModelVersion().startsWith("zahlungseingang-")) {
- // resolve partner.id and partner.name
- if (workitem.getItemValueString("partner.id").isEmpty()) {
- // try to resolve the data
- ItemCollection bpWorkitem = getBusinessPartnerByID(
- InvoiceUtil.buildBPID(workitem.getItemValueString("dbtr.number")));
- if (bpWorkitem != null) {
- workitem.setItemValue("partner.id", bpWorkitem.getItemValueString("partner.id"));
- workitem.setItemValue("partner.name", bpWorkitem.getItemValueString("partner.name"));
- }
- }
- }
-
- }
-
- /**
- * Hilfsmethode die die offenen Rechnungen läd. Wird von WorktiemChanged Event
- * aufgerufen.
- *
- * @param workitem
- */
- private void loadStats(ItemCollection workitem) {
-
- try {
- // Ausgangsrechnungen
- String dbtrNumber = workitem.getItemValueString("dbtr.number");
- if (!dbtrNumber.isEmpty()) {
- invoicesOut = businessPartnerService.findOutgoingInvoices(dbtrNumber);
- // Mahnungen
- String query = "(type:workitem) AND ($modelversion:mahnlauf-*) "
- + " AND (dbtr.number:" + dbtrNumber + ")";
- dunnings = documentService.findStubs(query, 999, 0, "invoice.number", false);
- }
-
- // Eingangsrechnungen
- String cdtrNumber = workitem.getItemValueString("cdtr.number");
- if (!cdtrNumber.isEmpty()) {
- String query = "(type:workitem) AND ($modelversion:rechnungseingang-*) "
- + " AND (cdtr.number:" + cdtrNumber + ")";
- invoicesIn = documentService.findStubs(query, 999, 0, "invoice.number", false);
- }
-
- } catch (QueryException e) {
- logger.severe("failed to load stats: " + e.getMessage());
- }
-
- }
-
- public List getIbanList() {
- return ibanList;
- }
-
- public void addIBAN() {
- if (ibanList == null) {
- ibanList = new ArrayList();
- }
- ItemCollection source = new ItemCollection();
- ibanList.add(source);
- }
-
- /**
- * Removes an dbtr item from the list
- *
- * @param name - name of dbtr
- */
- public void removeIBAN(String id) {
- if (id != null && ibanList != null) {
- for (ItemCollection cdtr : ibanList) {
- if (id.equals(cdtr.getItemValueString("id"))) {
- ibanList.remove(cdtr);
- break;
- }
- }
- }
- }
-
- /**
- * This JSF backing method is called by businesspartner_serach.xhtml after the
- * user has selected a new businesspartner.
- *
- * The method lookups the given BusinessPartner and updates the metadata for
- * dbtr/cdtr depending on the workflow type.
- * A form will than rerender the opList section.
- */
- public void updateMetaData() {
- FacesContext fc = FacesContext.getCurrentInstance();
- String bpid = fc.getExternalContext().getRequestParameterMap().get("partnerID");
- logger.info("....update metadata.....bpid = " + bpid);
- ItemCollection businessPartner = businessPartnerService.getBusinessPartnerByID(bpid);
- if (businessPartner != null) {
-
- // Eingangsrechnung
- if (InvoiceUtil.isCreditorInvoice(workflowController.getWorkitem())) {
- workflowController.getWorkitem().setItemValue("cdtr.number",
- businessPartner.getItemValueString("cdtr.number"));
- workflowController.getWorkitem().setItemValue("cdtr.name",
- businessPartner.getItemValueString("partner.name"));
- workflowController.getWorkitem().setItemValue("cdtr.mail",
- businessPartner.getItemValue("cdtr.mail"));
- }
-
- // Ausgangsrechnung
- if (InvoiceUtil.isDebitorInvoice(workflowController.getWorkitem())) {
- workflowController.getWorkitem().setItemValue("dbtr.number",
- businessPartner.getItemValueString("dbtr.number"));
- workflowController.getWorkitem().setItemValue("dbtr.name",
- businessPartner.getItemValueString("partner.name"));
- workflowController.getWorkitem().setItemValue("dbtr.mail",
- businessPartner.getItemValue("dbtr.mail"));
- }
-
- // Zahlungseingang
- if (workflowController.getWorkitem().getModelVersion().startsWith("zahlungseingang")) {
- workflowController.getWorkitem().setItemValue("dbtr.number",
- businessPartner.getItemValueString("dbtr.number"));
- workflowController.getWorkitem().setItemValue("dbtr.name",
- businessPartner.getItemValueString("partner.name"));
- workflowController.getWorkitem().setItemValue("dbtr.mail",
- businessPartner.getItemValue("dbtr.mail"));
- }
-
- // Analyse Debitor
- if (workflowController.getWorkitem().getModelVersion().startsWith("analyse-debitor")) {
- workflowController.getWorkitem().setItemValue("dbtr.number",
- businessPartner.getItemValueString("dbtr.number"));
- workflowController.getWorkitem().setItemValue("dbtr.name",
- businessPartner.getItemValueString("partner.name"));
- workflowController.getWorkitem().setItemValue("dbtr.mail",
- businessPartner.getItemValue("dbtr.mail"));
- }
-
- }
- searchResult = null;
-
- }
-
- /**
- * Hilfsmethode die eine JSON Struktur mit allen relevanten Daten für einen
- * BusinessPartner erzeugt.
- *
- * @return
- */
- private String buildJsonData(ItemCollection businessPartner) {
- JsonObjectBuilder objectBuilder = Json.createObjectBuilder(). //
- add("name", jsonVal(businessPartner.getItemValueString("name"))). //
- add("cdtr.number", jsonVal(businessPartner.getItemValueString("cdtr.number"))). //
- add("dbtr.number", jsonVal(businessPartner.getItemValueString("dbtr.number"))). //
- add("partner.name", jsonVal(businessPartner.getItemValueString("partner.name")));
-
- // get iban list
- // {iban=[Dxxxxxx1], name=[Bank 1], id=[bank1], bic=[CITIDEFF]}
- ibanList = BusinessPartnerService.getBanks(businessPartner);
- int i = 1;
- for (ItemCollection iban : ibanList) {
- objectBuilder.add("iban" + 1, jsonVal(iban.getItemValueString("iban"))). //
- add("bic" + 1, jsonVal(iban.getItemValueString("bic")));//
- }
-
- JsonObject jsonObject = objectBuilder.build();
-
- String jsonString = "{}";
- try (Writer writer = new StringWriter()) {
- Json.createWriter(writer).write(jsonObject);
- jsonString = writer.toString();
- } catch (IOException e) {
- logger.warning("Unable to build json structure");
- }
- return jsonString;
- }
-
- /**
- * Helper method to remove " and ' characters - causing problems
- *
- * @param val
- * @return
- */
- public static String jsonVal(String val) {
- val = val.replace("\"", "");
- val = val.replace("'", "");
- return val;
- }
-
-}
+/*******************************************************************************
+ * Imixs Workflow Technology
+ * Copyright (C) 2003, 2008 Imixs Software Solutions GmbH,
+ * http://www.imixs.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You can receive a copy of the GNU General Public
+ * License at http://www.gnu.org/licenses/gpl.html
+ *
+ * Contributors:
+ * Imixs Software Solutions GmbH - initial API and implementation
+ * Ralph Soika
+ *
+ *******************************************************************************/
+package com.alexanderlogistics;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.imixs.workflow.ItemCollection;
+import org.imixs.workflow.engine.DocumentService;
+import org.imixs.workflow.exceptions.AccessDeniedException;
+import org.imixs.workflow.exceptions.QueryException;
+import org.imixs.workflow.faces.data.WorkflowController;
+import org.imixs.workflow.faces.data.WorkflowEvent;
+
+import jakarta.enterprise.context.ConversationScoped;
+import jakarta.enterprise.event.Observes;
+import jakarta.faces.context.FacesContext;
+import jakarta.inject.Inject;
+import jakarta.inject.Named;
+import jakarta.json.Json;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonObjectBuilder;
+
+/**
+ * Der BusinessPartnerController stellt Methoden für die BusinessPartner Forms
+ * sowie für die das Suche-Widget 'businesspartner_search' bereit.
+ *
+ *
+ * @author rsoika
+ * @version 1.0
+ */
+@Named
+@ConversationScoped
+public class BusinessPartnerController implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ protected List ibanList = null;
+ protected List invoicesOut = null;
+ protected List invoicesIn = null;
+ protected List dunnings = null;
+
+ @Inject
+ protected WorkflowController workflowController;
+
+ @Inject
+ DocumentService documentService;
+
+ @Inject
+ BusinessPartnerService businessPartnerService;
+
+ private List searchResult = null;
+
+ private static Logger logger = Logger.getLogger(BusinessPartnerController.class.getName());
+
+ public List getInvoicesOut() {
+ if (invoicesOut == null) {
+ invoicesOut = new ArrayList<>();
+ }
+ return invoicesOut;
+ }
+
+ public List getInvoicesIn() {
+ if (invoicesIn == null) {
+ invoicesIn = new ArrayList<>();
+ }
+ return invoicesIn;
+ }
+
+ public List getDunnings() {
+ if (dunnings == null) {
+ dunnings = new ArrayList<>();
+ }
+ return dunnings;
+ }
+
+ /**
+ * This method searches a text phrase within the list of DATEV kreditoren
+ *
+ * JSF Integration:
+ *
+ * {@code
+ }
+ */
+ public void search(String options) {
+ List resultList = null;
+ searchResult = new ArrayList();
+ // get the param from faces context....
+ FacesContext fc = FacesContext.getCurrentInstance();
+ String phrase = fc.getExternalContext().getRequestParameterMap().get("phrase");
+ if (phrase == null) {
+ return;
+ }
+
+ logger.fine("search prase '" + phrase + "'");
+ if (phrase == null || phrase.length() < 2) {
+ return;
+ }
+ logger.fine("search for=" + phrase);
+ Pattern pattern = null;
+ resultList = businessPartnerService.search(phrase);
+ // Compile the regex pattern if available
+ if (options.contains("regexPattern=")) {
+ String regexPattern = options.substring(options.indexOf("regexPattern=") + 13);
+ logger.fine("regex=" + regexPattern);
+ pattern = Pattern.compile(regexPattern);
+ }
+
+ // Filter by Regex and convert ItemCollection into a BusinessPartnerSearchEntry
+ for (ItemCollection businessPartner : resultList) {
+ String name = businessPartner.getItemValueString("name");
+ // Prüfen, ob der name der Regex entspricht
+ if (pattern != null) {
+ Matcher matcher = pattern.matcher(name);
+ if (!matcher.matches()) {
+ // Kein passendes Konto
+ continue;
+ }
+ }
+ String display = businessPartner.getItemValueString("$workflowsummary");
+
+ display = display.replace("\"", "");
+ display = display.replace("'", "");
+
+ searchResult.add(new BusinessPartnerSearchEntry(name, display, buildJsonData(businessPartner)));
+
+ }
+ }
+
+ /**
+ * Diese Helper Method liefert true wenn in den Options von Form Part 'reRender'
+ * angegeben wurde. Damit löst die Suchmaske businesspartner_search.xhtml eine
+ * komplette rerender Phase der Form aus. Dies ist z.b. für den workflow
+ * 'analyse-debitor.bpmn' nützlich
+ *
+ * @param options
+ * @return
+ */
+ public boolean isRerenderMode(String options) {
+ return options.toLowerCase().contains("rerender");
+ }
+
+ /**
+ * Die Resultliste wird als eine Liste einen Arrays zurückgegeben. Der Erste
+ * Eintrag
+ *
+ * @return
+ */
+ public List getSearchResult() {
+ return searchResult;
+ }
+
+ public ItemCollection getBusinessPartnerByID(String bpid) {
+ ItemCollection partner = businessPartnerService.getBusinessPartnerByID(bpid);
+ return partner;
+ }
+
+ /**
+ * WorkflowEvent listener resolved additional data.
+ *
+ * For businesspartner the method converts the IBAN child list embeded HashMaps
+ * into ItemCollections and reconvert them before processing
+ *
+ * for invoices the method resolve the partner.id and partner.name
+ *
+ * @param workflowEvent
+ * @throws AccessDeniedException
+ */
+ public void onWorkflowEvent(@Observes WorkflowEvent workflowEvent) throws AccessDeniedException {
+
+ int eventType = workflowEvent.getEventType();
+ ItemCollection workitem = workflowEvent.getWorkitem();
+ if (workitem == null) {
+ return;
+ }
+ if (workitem.getModelVersion().startsWith("businesspartner-")) {
+ // reset orderItems if workItem has changed
+ if (WorkflowEvent.WORKITEM_CHANGED == eventType || WorkflowEvent.WORKITEM_CREATED == eventType) {
+ // reset state
+ ibanList = BusinessPartnerService.explodeBanks(workitem);
+ loadStats(workitem);
+ }
+
+ // before the workitem is saved we update the field txtOrderItems
+ if (WorkflowEvent.WORKITEM_BEFORE_PROCESS == eventType) {
+ BusinessPartnerService.implodeBanks(workitem, ibanList);
+ }
+
+ if (WorkflowEvent.WORKITEM_AFTER_PROCESS == eventType) {
+ // reset state
+ ibanList = BusinessPartnerService.explodeBanks(workitem);
+ }
+ }
+
+ if (workitem.getModelVersion().startsWith("rechnungsausgang-")) {
+ // resolve partner.id and partner.name
+ if (workitem.getItemValueString("partner.id").isEmpty()) {
+ // try to resolve the data
+ ItemCollection bpWorkitem = getBusinessPartnerByID(InvoiceUtil.getBPID(workitem));
+ if (bpWorkitem != null) {
+ workitem.setItemValue("partner.id", bpWorkitem.getItemValueString("partner.id"));
+ workitem.setItemValue("partner.name", bpWorkitem.getItemValueString("partner.name"));
+ }
+ }
+ }
+
+ if (workitem.getModelVersion().startsWith("rechnungseingang-")) {
+ // resolve partner.id and partner.name
+ if (workitem.getItemValueString("partner.id").isEmpty()) {
+ // try to resolve the data
+ ItemCollection bpWorkitem = getBusinessPartnerByID(InvoiceUtil.getBPID(workitem));
+ if (bpWorkitem != null) {
+ workitem.setItemValue("partner.id", bpWorkitem.getItemValueString("partner.id"));
+ workitem.setItemValue("partner.name", bpWorkitem.getItemValueString("partner.name"));
+ }
+ }
+ }
+
+ if (workitem.getModelVersion().startsWith("zahlungseingang-")) {
+ // resolve partner.id and partner.name
+ if (workitem.getItemValueString("partner.id").isEmpty()) {
+ // try to resolve the data
+ ItemCollection bpWorkitem = getBusinessPartnerByID(
+ InvoiceUtil.buildBPID(workitem.getItemValueString("dbtr.number")));
+ if (bpWorkitem != null) {
+ workitem.setItemValue("partner.id", bpWorkitem.getItemValueString("partner.id"));
+ workitem.setItemValue("partner.name", bpWorkitem.getItemValueString("partner.name"));
+ }
+ }
+ }
+
+ }
+
+ /**
+ * Hilfsmethode die die offenen Rechnungen läd. Wird von WorktiemChanged Event
+ * aufgerufen.
+ *
+ * @param workitem
+ */
+ private void loadStats(ItemCollection workitem) {
+
+ try {
+ // Ausgangsrechnungen
+ String dbtrNumber = workitem.getItemValueString("dbtr.number");
+ if (!dbtrNumber.isEmpty()) {
+ invoicesOut = businessPartnerService.findOutgoingInvoices(dbtrNumber);
+ // Mahnungen
+ String query = "(type:workitem) AND ($modelversion:mahnlauf-*) " + " AND (dbtr.number:" + dbtrNumber
+ + ")";
+ dunnings = documentService.findStubs(query, 999, 0, "invoice.number", false);
+ }
+
+ // Eingangsrechnungen
+ String cdtrNumber = workitem.getItemValueString("cdtr.number");
+ if (!cdtrNumber.isEmpty()) {
+ String query = "(type:workitem) AND ($modelversion:rechnungseingang-*) " + " AND (cdtr.number:"
+ + cdtrNumber + ")";
+ invoicesIn = documentService.findStubs(query, 999, 0, "invoice.number", false);
+ }
+
+ } catch (QueryException e) {
+ logger.severe("failed to load stats: " + e.getMessage());
+ }
+
+ }
+
+ public List getIbanList() {
+ return ibanList;
+ }
+
+ public void addIBAN() {
+ if (ibanList == null) {
+ ibanList = new ArrayList();
+ }
+ ItemCollection source = new ItemCollection();
+ ibanList.add(source);
+ }
+
+ /**
+ * Removes an dbtr item from the list
+ *
+ * @param name - name of dbtr
+ */
+ public void removeIBAN(String id) {
+ if (id != null && ibanList != null) {
+ for (ItemCollection cdtr : ibanList) {
+ if (id.equals(cdtr.getItemValueString("id"))) {
+ ibanList.remove(cdtr);
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * This JSF backing method is called by businesspartner_serach.xhtml after the
+ * user has selected a new businesspartner.
+ *
+ * The method lookups the given BusinessPartner and updates the metadata for
+ * dbtr/cdtr depending on the workflow type. A form will than rerender the
+ * opList section.
+ */
+ public void updateMetaData() {
+ FacesContext fc = FacesContext.getCurrentInstance();
+ String bpid = fc.getExternalContext().getRequestParameterMap().get("partnerID");
+ logger.info("....update metadata.....bpid = " + bpid);
+ ItemCollection businessPartner = businessPartnerService.getBusinessPartnerByID(bpid);
+ if (businessPartner != null) {
+
+ // Eingangsrechnung
+ if (InvoiceUtil.isCreditorInvoice(workflowController.getWorkitem())) {
+ workflowController.getWorkitem().setItemValue("cdtr.number",
+ businessPartner.getItemValueString("cdtr.number"));
+ workflowController.getWorkitem().setItemValue("cdtr.name",
+ businessPartner.getItemValueString("partner.name"));
+ workflowController.getWorkitem().setItemValue("cdtr.mail", businessPartner.getItemValue("cdtr.mail"));
+ }
+
+ // Ausgangsrechnung
+ if (InvoiceUtil.isDebitorInvoice(workflowController.getWorkitem())) {
+ workflowController.getWorkitem().setItemValue("dbtr.number",
+ businessPartner.getItemValueString("dbtr.number"));
+ workflowController.getWorkitem().setItemValue("dbtr.name",
+ businessPartner.getItemValueString("partner.name"));
+ workflowController.getWorkitem().setItemValue("dbtr.mail", businessPartner.getItemValue("dbtr.mail"));
+ }
+
+ // Zahlungseingang
+ if (workflowController.getWorkitem().getModelVersion().startsWith("zahlungseingang")) {
+ workflowController.getWorkitem().setItemValue("dbtr.number",
+ businessPartner.getItemValueString("dbtr.number"));
+ workflowController.getWorkitem().setItemValue("dbtr.name",
+ businessPartner.getItemValueString("partner.name"));
+ workflowController.getWorkitem().setItemValue("dbtr.mail", businessPartner.getItemValue("dbtr.mail"));
+ }
+
+ // Analyse Debitor
+ if (workflowController.getWorkitem().getModelVersion().startsWith("analyse-debitor")) {
+ workflowController.getWorkitem().setItemValue("dbtr.number",
+ businessPartner.getItemValueString("dbtr.number"));
+ workflowController.getWorkitem().setItemValue("dbtr.name",
+ businessPartner.getItemValueString("partner.name"));
+ workflowController.getWorkitem().setItemValue("dbtr.mail", businessPartner.getItemValue("dbtr.mail"));
+ }
+
+ }
+ searchResult = null;
+
+ }
+
+ /**
+ * Hilfsmethode die eine JSON Struktur mit allen relevanten Daten für einen
+ * BusinessPartner erzeugt.
+ *
+ * @return
+ */
+ private String buildJsonData(ItemCollection businessPartner) {
+ JsonObjectBuilder objectBuilder = Json.createObjectBuilder(). //
+ add("name", jsonVal(businessPartner.getItemValueString("name"))). //
+ add("cdtr.number", jsonVal(businessPartner.getItemValueString("cdtr.number"))). //
+ add("dbtr.number", jsonVal(businessPartner.getItemValueString("dbtr.number"))). //
+ add("partner.name", jsonVal(businessPartner.getItemValueString("partner.name")));
+
+ // get iban list
+ // {iban=[Dxxxxxx1], name=[Bank 1], id=[bank1], bic=[CITIDEFF]}
+ ibanList = BusinessPartnerService.getBanks(businessPartner);
+ int i = 1;
+ for (ItemCollection iban : ibanList) {
+ objectBuilder.add("iban" + 1, jsonVal(iban.getItemValueString("iban"))). //
+ add("bic" + 1, jsonVal(iban.getItemValueString("bic")));//
+ }
+
+ JsonObject jsonObject = objectBuilder.build();
+
+ String jsonString = "{}";
+ try (Writer writer = new StringWriter()) {
+ Json.createWriter(writer).write(jsonObject);
+ jsonString = writer.toString();
+ } catch (IOException e) {
+ logger.warning("Unable to build json structure");
+ }
+ return jsonString;
+ }
+
+ /**
+ * Helper method to remove " and ' characters - causing problems
+ *
+ * @param val
+ * @return
+ */
+ public static String jsonVal(String val) {
+ val = val.replace("\"", "");
+ val = val.replace("'", "");
+ return val;
+ }
+
+}
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/BusinessPartnerSearchEntry.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/BusinessPartnerSearchEntry.java
index dcd7234..227c42b 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/BusinessPartnerSearchEntry.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/BusinessPartnerSearchEntry.java
@@ -5,44 +5,44 @@ package com.alexanderlogistics;
* Sucheregenisses nach kreditoren an das Frontend. Die Klasse besteht aus einem
* Key, einer DisplayZeile für die Darstellung und einen JSON String der
* beliebige Daten enthalten kann.
- *
+ *
* @author rsoika
*
*/
public class BusinessPartnerSearchEntry {
- private String key;
- private String display;
- private String data;
+ private String key;
+ private String display;
+ private String data;
- public BusinessPartnerSearchEntry(String key, String display, String data) {
- super();
- this.key = key;
- this.display = display;
- this.data = data;
- }
+ public BusinessPartnerSearchEntry(String key, String display, String data) {
+ super();
+ this.key = key;
+ this.display = display;
+ this.data = data;
+ }
- public String getKey() {
- return key;
- }
+ public String getKey() {
+ return key;
+ }
- public void setKey(String key) {
- this.key = key;
- }
+ public void setKey(String key) {
+ this.key = key;
+ }
- public String getDisplay() {
- return display;
- }
+ public String getDisplay() {
+ return display;
+ }
- public void setDisplay(String display) {
- this.display = display;
- }
+ public void setDisplay(String display) {
+ this.display = display;
+ }
- public String getData() {
- return data;
- }
+ public String getData() {
+ return data;
+ }
- public void setData(String data) {
- this.data = data;
- }
+ public void setData(String data) {
+ this.data = data;
+ }
}
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/BusinessPartnerService.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/BusinessPartnerService.java
index dc77c7d..b5bd30e 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/BusinessPartnerService.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/BusinessPartnerService.java
@@ -1,26 +1,26 @@
/*******************************************************************************
- * Imixs Workflow
- * Copyright (C) 2001, 2011 Imixs Software Solutions GmbH,
+ * Imixs Workflow
+ * Copyright (C) 2001, 2011 Imixs Software Solutions GmbH,
* http://www.imixs.com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
- *
+ *
* You can receive a copy of the GNU General Public
* License at http://www.gnu.org/licenses/gpl.html
- *
- * Project:
+ *
+ * Project:
* http://www.imixs.org
* http://java.net/projects/imixs-workflow
- *
- * Contributors:
+ *
+ * Contributors:
* Imixs Software Solutions GmbH - initial API and implementation
* Ralph Soika - Software Developer
*******************************************************************************/
@@ -51,15 +51,15 @@ import jakarta.annotation.PostConstruct;
import jakarta.annotation.security.DeclareRoles;
import jakarta.annotation.security.RolesAllowed;
import jakarta.annotation.security.RunAs;
-import jakarta.ejb.Singleton;
+import jakarta.ejb.Stateless;
import jakarta.inject.Inject;
/**
* Der BusinessPartnerService stellt Methoden für den Zugriff auf Business
* Partner bereit.
- *
+ *
* @author rsoika
- *
+ *
*/
@DeclareRoles({ "org.imixs.ACCESSLEVEL.NOACCESS", "org.imixs.ACCESSLEVEL.READERACCESS",
@@ -68,7 +68,7 @@ import jakarta.inject.Inject;
@RolesAllowed({ "org.imixs.ACCESSLEVEL.NOACCESS", "org.imixs.ACCESSLEVEL.READERACCESS",
"org.imixs.ACCESSLEVEL.AUTHORACCESS", "org.imixs.ACCESSLEVEL.EDITORACCESS",
"org.imixs.ACCESSLEVEL.MANAGERACCESS" })
-@Singleton
+@Stateless
@RunAs("org.imixs.ACCESSLEVEL.MANAGERACCESS")
public class BusinessPartnerService {
@@ -121,13 +121,12 @@ public class BusinessPartnerService {
/**
* Diese Methode aktualisiert das business Partner object. Sie wird von den
- * Invoice Plugins genutzt.
- * Die Methode wirft eine PluginException falls das BusinessPartner Objekt
- * gesperrt oder in verification ist!
- *
+ * Invoice Plugins genutzt. Die Methode wirft eine PluginException falls das
+ * BusinessPartner Objekt gesperrt oder in verification ist!
+ *
* Gleichzeitig wird bei Rechnungen in Abhängigkeit der Rechnungsart die
* dbtr./cdtr. items sowie mail und country aktualisiert.
- *
+ *
* @param partnerID
* @param workitem
* @throws PluginException
@@ -145,8 +144,18 @@ public class BusinessPartnerService {
workitem.setItemValue("partner.id", partnerID);
}
+ if (partnerID == null || partnerID.isEmpty()) {
+ return;
+ }
// load Business Partner
ItemCollection businessPartner = getBusinessPartnerByID(partnerID);
+ if (businessPartner == null) {
+ return;
+ }
+ // because the method can be called multiple times within one worklfow
+ // processing cycle
+ // we need to load the object within the current transaction context
+ businessPartner = documentService.load(businessPartner.getUniqueID());
if (businessPartner != null) {
workitem.setItemValue("partner.name", businessPartner.getItemValueString("partner.name"));
@@ -166,13 +175,11 @@ public class BusinessPartnerService {
// Validate Business Partner Status!
if (businessPartner.getTaskID() == TASK_VERIFICATION) {
- throw new PluginException(InvoicePlugin.class.getName(),
- ERROR_BUSINESSPARTNER_VERIFICATION,
+ throw new PluginException(InvoicePlugin.class.getName(), ERROR_BUSINESSPARTNER_VERIFICATION,
"Businesspartner is in verification. Invoice can't be processed!");
}
if (businessPartner.getTaskID() == TASK_LOCKED) {
- throw new PluginException(InvoicePlugin.class.getName(),
- ERROR_BUSINESSPARTNER_LOCKED,
+ throw new PluginException(InvoicePlugin.class.getName(), ERROR_BUSINESSPARTNER_LOCKED,
"Businesspartner is locked. Invoice can't be processed!");
}
// update business partner status...
@@ -195,7 +202,7 @@ public class BusinessPartnerService {
/**
* Returns the stubs of all outgoing invoices
- *
+ *
* @param _dbtrNumber
* @return
*/
@@ -224,9 +231,8 @@ public class BusinessPartnerService {
/**
* Diese Methode sucht einen Business Partner anhand seiner BPID
- *
- * @param bpid
- * - business partner id phrase
+ *
+ * @param bpid - business partner id phrase
* @return - matching business partner
*/
public ItemCollection getBusinessPartnerByID(String bpid) {
@@ -250,9 +256,8 @@ public class BusinessPartnerService {
/**
* Diese Methode sucht Business Partner anhand einer Suchphrase
- *
- * @param phrase
- * - search phrase
+ *
+ * @param phrase - search phrase
* @return - list of matching business partners
*/
public List search(String phrase) {
@@ -283,7 +288,7 @@ public class BusinessPartnerService {
/**
* Packt die Liste der Bank Details (ItemCollections) in ein Workitem
- *
+ *
* @param workitem
*/
public static void implodeBanks(ItemCollection workitem, List ibanList) {
@@ -304,7 +309,7 @@ public class BusinessPartnerService {
/**
* Enpackt die iban Map Liste von eiem Worktiem in eine Liste von ItemCollection
- *
+ *
* @param workitem
*/
public static List explodeBanks(ItemCollection workitem) {
@@ -325,7 +330,7 @@ public class BusinessPartnerService {
/**
* Liefert die ChildItems mit den IBAN daten
- *
+ *
* @param workitem
* @return
*/
@@ -345,7 +350,7 @@ public class BusinessPartnerService {
/**
* Diese Methode übertragt neue IBAN/BIC Pare in den Kreditor Banken Bereich
- *
+ *
* @param cdtrNumber
* @param iban
* @param bic
@@ -374,7 +379,7 @@ public class BusinessPartnerService {
/**
* Diese Methode gibt true zurück wenn die angegebene IBAN/BIC Kombination als
* bank bereits bekannt ist
- *
+ *
* @param cdtrNumber
* @param iban
* @param bic
@@ -386,8 +391,7 @@ public class BusinessPartnerService {
List bankenListe = explodeBanks(businessPartner);
for (ItemCollection bank : bankenListe) {
- if (iban.equals(bank.getItemValueString("iban"))
- && bic.equals(bank.getItemValueString("bic"))) {
+ if (iban.equals(bank.getItemValueString("iban")) && bic.equals(bank.getItemValueString("bic"))) {
// known!
return true;
}
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/CargosoftExportAdapter.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/CargosoftExportAdapter.java
index eca0fdc..2db1e2e 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/CargosoftExportAdapter.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/CargosoftExportAdapter.java
@@ -25,18 +25,18 @@ import jakarta.inject.Inject;
*
* report = report definition to transfers the workitem into the cargosoft xml
* structure
- *
+ *
*
* {@code
cargosoft
-
+
}
*
*
* Because we also export the attachment data to cargosoft, the adaper lookups
* the conente of the attachment in the snapshot of the origin workitem
- *
- *
+ *
+ *
* @version 1.0
* @author rsoika
*/
@@ -113,8 +113,8 @@ public class CargosoftExportAdapter implements SignalAdapter {
// finally append the success event id
document.event(EVENT_SUCCESS);
- } catch (PluginException | IOException
- | jakarta.xml.bind.JAXBException | javax.xml.transform.TransformerException e) {
+ } catch (PluginException | IOException | jakarta.xml.bind.JAXBException
+ | javax.xml.transform.TransformerException e) {
logger.severe("cargosoft export failed: " + e.getMessage());
document.setItemValue("cargosoft.error", e.getMessage());
document.event(EVENT_FAILURE);
@@ -130,8 +130,8 @@ public class CargosoftExportAdapter implements SignalAdapter {
* Change 14.10.2021 - Wir senden maximal 5MB and Daten, da die Cargosoft
* Schnittstelle größere Datensätze mit großen Dateianhängen einfach verschluckt
* ohne eine Fehlermeldugn zu liefern.
- *
- *
+ *
+ *
* @param document
* @return
*/
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/CargosoftSplitAdapter.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/CargosoftSplitAdapter.java
index 6ddc396..51eb38f 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/CargosoftSplitAdapter.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/CargosoftSplitAdapter.java
@@ -32,7 +32,7 @@ import jakarta.inject.Inject;
* ein neue Sequencenummer die im Hautpworkitem gespeichert wird.
*
* Der Adapter wird im Modell wie folgt konfiguriert
- *
+ *
*
* Because we also export the attachment data to cargosoft, the adaper lookups
* the conente of the attachment in the snapshot of the origin workitem
- *
- *
+ *
+ *
* @version 1.0
* @author rsoika
*/
@@ -65,7 +65,7 @@ public class CargosoftSplitAdapter implements SignalAdapter {
/**
* This method computes the cargosoft export data file
- *
+ *
* @throws PluginException
*/
@SuppressWarnings("rawtypes")
@@ -189,21 +189,21 @@ public class CargosoftSplitAdapter implements SignalAdapter {
*
+ *
+ * @return
+ */
+ public String buildChartData() {
+
+ getStats();
+
+ // build a list of all lables....
+ List statusLabels = new ArrayList();
+
+ Set keys = stats.keySet();
+ for (String _key : keys) {
+ statusLabels.add(_key);
+ }
+
+ String result = "{";
+
+ // Lables
+ result = result + "labels : [ ";
+ result = result + statusLabels.stream().collect(Collectors.joining("','", "'", "'"));
+ result = result + "],";
+ result = result + "datasets: [";
+
+ // Datasets 1
+ result = result + "{label: 'Zahlungsziel',borderWidth: 1,";
+ result = result + " borderColor: [\"#3B6B82\"],";
+ result = result + " \"backgroundColor\" : [\"#CFE9F5\"], fill: true,tension: 0.5,";
+
+ result = result + "data: [";
+ for (Map.Entry entry : stats.entrySet()) {
+ result = result + entry.getValue().getAverageDueDays() + ",";
+ }
+ // cut last comma
+ result = result.substring(0, result.length() - 1);
+ result = result + "]";
+ result = result + "}, ";
+
+ // Datasets 2
+ result = result + "{label: 'Zahldauer',borderWidth: 1,";
+ result = result + " borderColor: [\"#E73B65\"],\"backgroundColor\" : [\"#70B088\" ], tension: 0.5,fill: true,";
+
+ result = result
+ + " trendlineLinear: { colorMin: \"red\", colorMax: \"green\", lineStyle: \"dotted\", width: 2 , projection: true },";
+
+ result = result + "data: [";
+ for (Map.Entry entry : stats.entrySet()) {
+ result = result + entry.getValue().getAveragePaymentDays() + ",";
+ }
+ // cut last comma
+ result = result.substring(0, result.length() - 1);
+ result = result + "]";
+ result = result + "} ";
+
+ // ende
+ result = result + "] }";
+
+ return result;
+ }
}
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/DebitorStatistikData.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/DebitorStatistikData.java
index ea07475..f145afe 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/DebitorStatistikData.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/DebitorStatistikData.java
@@ -40,7 +40,7 @@ public class DebitorStatistikData {
/**
* Aktualisiert die statistischen werte
- *
+ *
* @param invoiceDate
* @param paymentDate
*/
@@ -90,7 +90,7 @@ public class DebitorStatistikData {
/**
* returns
- *
+ *
* 202304
*/
public String toString() {
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/FTPConnector.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/FTPConnector.java
index d728880..7438dad 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/FTPConnector.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/FTPConnector.java
@@ -1,22 +1,22 @@
/*******************************************************************************
* Imixs Workflow Technology
- * Copyright (C) 2001, 2008 Imixs Software Solutions GmbH,
+ * Copyright (C) 2001, 2008 Imixs Software Solutions GmbH,
* http://www.imixs.com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
- *
+ *
* You can receive a copy of the GNU General Public
* License at http://www.gnu.org/licenses/gpl.html
- *
- * Contributors:
+ *
+ * Contributors:
* Imixs Software Solutions GmbH - initial API and implementation
* Ralph Soika
*******************************************************************************/
@@ -42,7 +42,7 @@ import jakarta.inject.Inject;
/**
* The FTPConnector service provides methods to push invoices to cargosoft
- *
+ *
* @version 1.0
* @author rsoika
*/
@@ -83,7 +83,7 @@ public class FTPConnector {
/**
* This method transfers a snapshot to a ftp server.
- *
+ *
* @param fileData object
* @throws PluginException
*/
@@ -158,7 +158,7 @@ public class FTPConnector {
/**
* This method reads data form the current working directory
- *
+ *
* @param snapshot
* @throws ArchiveException
* @return data
@@ -198,7 +198,7 @@ public class FTPConnector {
/**
* This method changes the current working sub-directy. If no corresponding
* directory exits the method creats one.
- *
+ *
* @throws ArchiveException
*/
@SuppressWarnings("unused")
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/InvoiceAnalyseController.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/InvoiceAnalyseController.java
index 2c6e7f9..a9098d9 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/InvoiceAnalyseController.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/InvoiceAnalyseController.java
@@ -22,7 +22,7 @@ import jakarta.inject.Named;
/**
* Der InvoiceAnalyseController dient zur Auswertung der Sachprüfungs Workflow
* Schritte. Die Analyse Seite ist über das Admin Menü erreichbar.
- *
+ *
* @author rsoika
*
*/
@@ -30,138 +30,138 @@ import jakarta.inject.Named;
@ConversationScoped
public class InvoiceAnalyseController implements Serializable {
- private static final long serialVersionUID = 1L;
- private static Logger logger = Logger.getLogger(InvoiceAnalyseController.class.getName());
+ private static final long serialVersionUID = 1L;
+ private static Logger logger = Logger.getLogger(InvoiceAnalyseController.class.getName());
- @Inject
- protected DocumentService documentService;
+ @Inject
+ protected DocumentService documentService;
- @Inject
- SearchService searchService;
+ @Inject
+ SearchService searchService;
- Category sachpruefung;
- Category verteilung;
- Category buchhaltung;
+ Category sachpruefung;
+ Category verteilung;
+ Category buchhaltung;
- private ItemCollection filter;
+ private ItemCollection filter;
- public ItemCollection getFilter() {
- if (filter == null) {
- filter = new ItemCollection();
- // compute start stop based on current month
- YearMonth startYearMonth = YearMonth.now();
- java.time.LocalDate startOfMonthDate = startYearMonth.atDay(1);
- java.time.LocalDate endOfMonthDate = startYearMonth.atEndOfMonth();
- filter.setItemValue("start",
- java.util.Date.from(startOfMonthDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()));
- filter.setItemValue("stop",
- java.util.Date.from(endOfMonthDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()));
- }
- return filter;
- }
+ public ItemCollection getFilter() {
+ if (filter == null) {
+ filter = new ItemCollection();
+ // compute start stop based on current month
+ YearMonth startYearMonth = YearMonth.now();
+ java.time.LocalDate startOfMonthDate = startYearMonth.atDay(1);
+ java.time.LocalDate endOfMonthDate = startYearMonth.atEndOfMonth();
+ filter.setItemValue("start",
+ java.util.Date.from(startOfMonthDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()));
+ filter.setItemValue("stop",
+ java.util.Date.from(endOfMonthDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()));
+ }
+ return filter;
+ }
- public void setFilter(ItemCollection filter) {
- this.filter = filter;
- }
+ public void setFilter(ItemCollection filter) {
+ this.filter = filter;
+ }
- public Category getSachpruefung() {
- return sachpruefung;
- }
+ public Category getSachpruefung() {
+ return sachpruefung;
+ }
- public Category getVerteilung() {
- return verteilung;
- }
+ public Category getVerteilung() {
+ return verteilung;
+ }
- public Category getBuchhaltung() {
- return buchhaltung;
- }
+ public Category getBuchhaltung() {
+ return buchhaltung;
+ }
- public int totalCountByCategory(Category cat) {
- int result = 0;
+ public int totalCountByCategory(Category cat) {
+ int result = 0;
- Collection allCounts = cat.getLabels().values();
- result = allCounts.stream().reduce(0, Integer::sum);
+ Collection allCounts = cat.getLabels().values();
+ result = allCounts.stream().reduce(0, Integer::sum);
- return result;
- }
+ return result;
+ }
- /**
- * Fuert verschiedene Queries aus um eine Analyse der Sachprufung durchzuführen.
- */
- public void analyse() {
+ /**
+ * Fuert verschiedene Queries aus um eine Analyse der Sachprufung durchzuführen.
+ */
+ public void analyse() {
- logger.info("start analyse....");
- verteilung = null;
- sachpruefung = null;
- Date start = filter.getItemValueDate("start");
- Date stop = filter.getItemValueDate("stop");
+ logger.info("start analyse....");
+ verteilung = null;
+ sachpruefung = null;
+ Date start = filter.getItemValueDate("start");
+ Date stop = filter.getItemValueDate("stop");
- logger.info("...daterange=" + start + " - " + stop);
+ logger.info("...daterange=" + start + " - " + stop);
- // serach date range?
- String sDateFrom = "191401070000"; // because * did not work here
- String sDateTo = "211401070000";
- SimpleDateFormat dateformat = new SimpleDateFormat("yyyyMMddHHmm");
+ // serach date range?
+ String sDateFrom = "191401070000"; // because * did not work here
+ String sDateTo = "211401070000";
+ SimpleDateFormat dateformat = new SimpleDateFormat("yyyyMMddHHmm");
- if (start != null) {
- Calendar cal = Calendar.getInstance();
- cal.setTime(start);
- sDateFrom = dateformat.format(cal.getTime());
- }
- if (stop != null) {
- Calendar cal = Calendar.getInstance();
- cal.setTime(stop);
- cal.add(Calendar.DATE, 1);
- sDateTo = dateformat.format(cal.getTime());
- }
+ if (start != null) {
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(start);
+ sDateFrom = dateformat.format(cal.getTime());
+ }
+ if (stop != null) {
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(stop);
+ cal.add(Calendar.DATE, 1);
+ sDateTo = dateformat.format(cal.getTime());
+ }
- // query Verteilung
- String query = "(type:workitem OR type:workitemarchive) ";
- if (start != null || stop != null) {
- query += "AND (taxonomy.verteilung.stop:[" + sDateFrom + " TO " + sDateTo + "]) ";
- }
- logger.info(query);
- List taxResult = searchService.getTaxonomyByQuery(query, "taxonomy.verteilung.stop.by");
- if (taxResult.size() > 0) {
- verteilung = taxResult.get(0);
+ // query Verteilung
+ String query = "(type:workitem OR type:workitemarchive) ";
+ if (start != null || stop != null) {
+ query += "AND (taxonomy.verteilung.stop:[" + sDateFrom + " TO " + sDateTo + "]) ";
+ }
+ logger.info(query);
+ List taxResult = searchService.getTaxonomyByQuery(query, "taxonomy.verteilung.stop.by");
+ if (taxResult.size() > 0) {
+ verteilung = taxResult.get(0);
- }
+ }
- // query Sachprüfung
- query = "(type:workitem OR type:workitemarchive) ";
- if (start != null || stop != null) {
- query += "AND (taxonomy.sachpruefung.stop:[" + sDateFrom + " TO " + sDateTo + "]) ";
- }
- logger.info(query);
- taxResult = searchService.getTaxonomyByQuery(query, "taxonomy.sachpruefung.stop.by");
- if (taxResult.size() > 0) {
- sachpruefung = taxResult.get(0);
+ // query Sachprüfung
+ query = "(type:workitem OR type:workitemarchive) ";
+ if (start != null || stop != null) {
+ query += "AND (taxonomy.sachpruefung.stop:[" + sDateFrom + " TO " + sDateTo + "]) ";
+ }
+ logger.info(query);
+ taxResult = searchService.getTaxonomyByQuery(query, "taxonomy.sachpruefung.stop.by");
+ if (taxResult.size() > 0) {
+ sachpruefung = taxResult.get(0);
- }
+ }
- // query Buchhaltung
- query = "(type:workitem OR type:workitemarchive) ";
- if (start != null || stop != null) {
- query += "AND (taxonomy.buchhaltung.stop:[" + sDateFrom + " TO " + sDateTo + "]) ";
- }
- logger.info(query);
- taxResult = searchService.getTaxonomyByQuery(query, "taxonomy.buchhaltung.stop.by");
- if (taxResult.size() > 0) {
- buchhaltung = taxResult.get(0);
+ // query Buchhaltung
+ query = "(type:workitem OR type:workitemarchive) ";
+ if (start != null || stop != null) {
+ query += "AND (taxonomy.buchhaltung.stop:[" + sDateFrom + " TO " + sDateTo + "]) ";
+ }
+ logger.info(query);
+ taxResult = searchService.getTaxonomyByQuery(query, "taxonomy.buchhaltung.stop.by");
+ if (taxResult.size() > 0) {
+ buchhaltung = taxResult.get(0);
- }
+ }
- }
+ }
- /**
- * This method reset the search and input state.
- */
- public void reset() {
- filter = new ItemCollection();
- sachpruefung = null;
- verteilung = null;
- buchhaltung = null;
- logger.fine("reset");
- }
+ /**
+ * This method reset the search and input state.
+ */
+ public void reset() {
+ filter = new ItemCollection();
+ sachpruefung = null;
+ verteilung = null;
+ buchhaltung = null;
+ logger.fine("reset");
+ }
}
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/InvoiceDispatchAdapter.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/InvoiceDispatchAdapter.java
index f7216d2..1408601 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/InvoiceDispatchAdapter.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/InvoiceDispatchAdapter.java
@@ -16,7 +16,7 @@ import jakarta.inject.Inject;
/**
* Der InvoiceDispatchAdapter verteilt die vom Abteilungsleiter ausgewählten
* Rechnungen
- *
+ *
* @version 1.0
* @author rsoika
*/
@@ -29,7 +29,7 @@ public class InvoiceDispatchAdapter implements SignalAdapter {
/**
* This method computes the cargosoft export data file
- *
+ *
* @throws PluginException
*/
@Override
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/InvoiceDispatchController.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/InvoiceDispatchController.java
index 6c17746..860020f 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/InvoiceDispatchController.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/InvoiceDispatchController.java
@@ -16,7 +16,7 @@ import jakarta.inject.Named;
/**
* The InvoiceDispatchController loads open workitems for the current user
- *
+ *
* @author rsoika
*
*/
@@ -50,7 +50,7 @@ public class InvoiceDispatchController implements Serializable {
* ($modelversion:rechnungseingang-de*) AND ($taskid:5100) AND
* ($owner:#{user})">
- *
+ *
*/
public void searchInvoices() {
long l = System.currentTimeMillis();
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/InvoiceOutgoingPlugin.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/InvoiceOutgoingPlugin.java
index 4c2b576..10a452d 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/InvoiceOutgoingPlugin.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/InvoiceOutgoingPlugin.java
@@ -8,40 +8,40 @@ import jakarta.inject.Inject;
/**
* Das InvoiceOutgoingPlugin aktualisiert die Debitor E-Mail Adresse
- *
+ *
* Auch das feld _img wird in Abhängigkeit vom item 'invoice.protest' gesetzt
- *
+ *
* @author rsoika
* @version 1.0
- *
+ *
*/
public class InvoiceOutgoingPlugin extends AbstractPlugin {
- @Inject
- BusinessPartnerService businessPartnerService;
+ @Inject
+ BusinessPartnerService businessPartnerService;
- /**
- *
- * @throws PluginException - if data is missing
- *
- **/
- @Override
- public ItemCollection run(ItemCollection workitem, ItemCollection event) throws PluginException {
+ /**
+ *
+ * @throws PluginException - if data is missing
+ *
+ **/
+ @Override
+ public ItemCollection run(ItemCollection workitem, ItemCollection event) throws PluginException {
- // Update BUsiness Partner Data
- businessPartnerService.updateBusinessPartnerData(workitem);
+ // Update BUsiness Partner Data
+ businessPartnerService.updateBusinessPartnerData(workitem);
- // Update Invoice.positions
- InvoiceUtil.updateInvoicePositions(workitem);
+ // Update Invoice.positions
+ InvoiceUtil.updateInvoicePositions(workitem);
- String img = "";
- if (workitem.getItemValueBoolean("invoice.protest")) {
- img = img + "";
+ String img = "";
+ if (workitem.getItemValueBoolean("invoice.protest")) {
+ img = img + "";
- }
- workitem.setItemValue("_img", img);
+ }
+ workitem.setItemValue("_img", img);
- return workitem;
- }
+ return workitem;
+ }
}
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/InvoicePlugin.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/InvoicePlugin.java
index 2704e0e..30b267a 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/InvoicePlugin.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/InvoicePlugin.java
@@ -35,403 +35,402 @@ import jakarta.inject.Inject;
*
* 2.2.22 - Das Plugin erzeugt auch das Feld _img welches die Images von
* Sofortüberweisung, Mahnung und Ablehnung anzeigt.
- *
- * 26.4.25 - Das Plugin setzt nun auch partner.name und partner.id
- * zusätzlich processed es das BP Workitem
- *
+ *
+ * 26.4.25 - Das Plugin setzt nun auch partner.name und partner.id zusätzlich
+ * processed es das BP Workitem
+ *
* @author rsoika
* @version 1.0
- *
+ *
*/
public class InvoicePlugin extends AbstractPlugin {
- public static final int TASK_ERFASSUNG = 5001;
- public static final int TASK_SACHPRUEFUNG = 5200;
- public static final int TASK_SACHPRUEFUNG_DELEGATION = 5210;
- public static final int EVENT_FREIGEBEN = 20;
+ public static final int TASK_ERFASSUNG = 5001;
+ public static final int TASK_SACHPRUEFUNG = 5200;
+ public static final int TASK_SACHPRUEFUNG_DELEGATION = 5210;
+ public static final int EVENT_FREIGEBEN = 20;
- public static final String ERROR_MISSING_DATA = "MISSING_DATA";
- public static final String ERROR_DUPPLICATE_INVOICE_NUMBER = "DUPPLICATE_INVOICE_NUMBER";
- public static final String ERROR_NEW_IBANBIC = "NEW_IBANBIC";
+ public static final String ERROR_MISSING_DATA = "MISSING_DATA";
+ public static final String ERROR_DUPPLICATE_INVOICE_NUMBER = "DUPPLICATE_INVOICE_NUMBER";
+ public static final String ERROR_NEW_IBANBIC = "NEW_IBANBIC";
- private static Logger logger = Logger.getLogger(InvoicePlugin.class.getName());
+ private static Logger logger = Logger.getLogger(InvoicePlugin.class.getName());
- // Positions Pattern - kann überschrieben werden
- // XX-YYY-####-### oder XX-YYYZZZ-####-###
- // Default = ([A-Z]{2}-[A-Z]{3}-[0-9]{4}-[0-9]{3})
- // Optional = ([A-Z]{2}-(?:[A-Z]{3}|[A-Z]{6})-[0-9]{4}-[0-9]{3})
- // Nur 6- Stellig = ([A-Z]{2}-(?:[A-Z]{6})-[0-9]{4}-[0-9]{3})
- public final static String INVOICE_POSITIONS_PATTERN_DEFAULT = "([A-Z]{2}-(?:[A-Z]{3}|[A-Z]{6})-[0-9]{4}-[0-9]{3})";
+ // Positions Pattern - kann überschrieben werden
+ // XX-YYY-####-### oder XX-YYYZZZ-####-###
+ // Default = ([A-Z]{2}-[A-Z]{3}-[0-9]{4}-[0-9]{3})
+ // Optional = ([A-Z]{2}-(?:[A-Z]{3}|[A-Z]{6})-[0-9]{4}-[0-9]{3})
+ // Nur 6- Stellig = ([A-Z]{2}-(?:[A-Z]{6})-[0-9]{4}-[0-9]{3})
+ public final static String INVOICE_POSITIONS_PATTERN_DEFAULT = "([A-Z]{2}-(?:[A-Z]{3}|[A-Z]{6})-[0-9]{4}-[0-9]{3})";
- @Inject
- @ConfigProperty(name = "invoice.position.pattern", defaultValue = INVOICE_POSITIONS_PATTERN_DEFAULT)
- String invoicePositionsPattern;
+ @Inject
+ @ConfigProperty(name = "invoice.position.pattern", defaultValue = INVOICE_POSITIONS_PATTERN_DEFAULT)
+ String invoicePositionsPattern;
- @Inject
- BusinessPartnerService businessPartnerService;
+ @Inject
+ BusinessPartnerService businessPartnerService;
- @Inject
- ResourceBundleHandler resourceBundleHandler;
+ @Inject
+ ResourceBundleHandler resourceBundleHandler;
- /**
- * Test childworkitems for empty lines
- *
- * @throws PluginException - if data is missing
- *
- **/
- @Override
- public ItemCollection run(ItemCollection workitem, ItemCollection event) throws PluginException {
+ /**
+ * Test childworkitems for empty lines
+ *
+ * @throws PluginException - if data is missing
+ *
+ **/
+ @Override
+ public ItemCollection run(ItemCollection workitem, ItemCollection event) throws PluginException {
- // Update BUsiness Partner Data
- businessPartnerService.updateBusinessPartnerData(workitem);
+ // Update BUsiness Partner Data
+ businessPartnerService.updateBusinessPartnerData(workitem);
- updateImg(workitem);
+ updateImg(workitem);
- // Update Invoice.positions
- InvoiceUtil.updateInvoicePositions(workitem);
+ // Update Invoice.positions
+ InvoiceUtil.updateInvoicePositions(workitem);
- // skip if validaten tag is required=false
- ItemCollection evalItemCollection = this.getWorkflowService().evalWorkflowResult(event, "validation", workitem);
- if (evalItemCollection != null) {
- // evaluate the validation rules...
- if ("false".equalsIgnoreCase(evalItemCollection.getItemValueString("required"))) {
- return workitem;
- }
- }
+ // skip if validaten tag is required=false
+ ItemCollection evalItemCollection = this.getWorkflowService().evalWorkflowResult(event, "validation", workitem);
+ if (evalItemCollection != null) {
+ // evaluate the validation rules...
+ if ("false".equalsIgnoreCase(evalItemCollection.getItemValueString("required"))) {
+ return workitem;
+ }
+ }
- boolean isPublicEvent = !("0".equals(event.getItemValueString("keypublicresult")));
+ boolean isPublicEvent = !("0".equals(event.getItemValueString("keypublicresult")));
- // Payment.type muss immer eingetragne werden!
- if (isPublicEvent && workitem.getTaskID() >= TASK_ERFASSUNG && workitem.getEventID() < 900) {
- if (workitem.getItemValueString("payment.type").trim().isEmpty()) {
- // throw a plugin exception!
- String message = resourceBundleHandler.findMessage("ERROR_MISSING_PAYMENT");
- throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA, message);
- }
- // doppelte Rechnungsnummer prüfen
- if (workitem.getTaskID() == TASK_ERFASSUNG) {
- validateInvoiceNumber(workitem);
- checkIBANNumber(workitem);
- }
+ // Payment.type muss immer eingetragne werden!
+ if (isPublicEvent && workitem.getTaskID() >= TASK_ERFASSUNG && workitem.getEventID() < 900) {
+ if (workitem.getItemValueString("payment.type").trim().isEmpty()) {
+ // throw a plugin exception!
+ String message = resourceBundleHandler.findMessage("ERROR_MISSING_PAYMENT");
+ throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA, message);
+ }
+ // doppelte Rechnungsnummer prüfen
+ if (workitem.getTaskID() == TASK_ERFASSUNG) {
+ validateInvoiceNumber(workitem);
+ checkIBANNumber(workitem);
+ }
- if (workitem.getTaskID() == TASK_ERFASSUNG || ((workitem.getTaskID() == TASK_SACHPRUEFUNG
- || workitem.getTaskID() == TASK_SACHPRUEFUNG_DELEGATION)
- && workitem.getEventID() == EVENT_FREIGEBEN)) {
- // Buchungsperiode auf plausi prüfen
- if (isCargoRechnung(workitem) && "workitem".equals(workitem.getType())) {
- validateBuchungsperiode(workitem.getItemValueString(InvoiceUtil.ITEM_INVOICE_PERIOD));
- }
- // Cargosoft Kreditorennnummer prüfen
- if (isCargoRechnung(workitem)) {
- validateCargosoftCdtrNumber(workitem);
- }
- }
- }
+ if (workitem.getTaskID() == TASK_ERFASSUNG || ((workitem.getTaskID() == TASK_SACHPRUEFUNG
+ || workitem.getTaskID() == TASK_SACHPRUEFUNG_DELEGATION)
+ && workitem.getEventID() == EVENT_FREIGEBEN)) {
+ // Buchungsperiode auf plausi prüfen
+ if (isCargoRechnung(workitem) && "workitem".equals(workitem.getType())) {
+ validateBuchungsperiode(workitem.getItemValueString(InvoiceUtil.ITEM_INVOICE_PERIOD));
+ }
+ // Cargosoft Kreditorennnummer prüfen
+ if (isCargoRechnung(workitem)) {
+ validateCargosoftCdtrNumber(workitem);
+ }
+ }
+ }
- // die prüfung der positionsnummern und Category erfolgt nur im Status
- // Sachprüfung (5200) und nur beim Freigeben (20)!
- if (isCargoRechnung(workitem)
- && ((workitem.getTaskID() == TASK_SACHPRUEFUNG || workitem.getTaskID() == TASK_SACHPRUEFUNG_DELEGATION)
- && workitem.getEventID() == EVENT_FREIGEBEN)) {
- List childs = InvoiceUtil.explodeChildList(workitem);
- for (ItemCollection posItem : childs) {
- if (posItem.getItemValueString("name").trim().isEmpty()) {
- // throw a plugin exception - because name is missing!
- String message = resourceBundleHandler.findMessage("ERROR_MISSING_POSNO");
- message = message.replace("{1}", posItem.getItemValueString("numpos"));
- throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA, message);
- }
+ // die prüfung der positionsnummern und Category erfolgt nur im Status
+ // Sachprüfung (5200) und nur beim Freigeben (20)!
+ if (isCargoRechnung(workitem)
+ && ((workitem.getTaskID() == TASK_SACHPRUEFUNG || workitem.getTaskID() == TASK_SACHPRUEFUNG_DELEGATION)
+ && workitem.getEventID() == EVENT_FREIGEBEN)) {
+ List childs = InvoiceUtil.explodeChildList(workitem);
+ for (ItemCollection posItem : childs) {
+ if (posItem.getItemValueString("name").trim().isEmpty()) {
+ // throw a plugin exception - because name is missing!
+ String message = resourceBundleHandler.findMessage("ERROR_MISSING_POSNO");
+ message = message.replace("{1}", posItem.getItemValueString("numpos"));
+ throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA, message);
+ }
- // validate pos for regex pattern 'XX-YYY-####-###'
- if (!posItem.getItemValueString("name").matches(invoicePositionsPattern)) {
- // throw a plugin exception - because name is missing!
- String message = resourceBundleHandler.findMessage("ERROR_FORMAT_POSNO");
- message = message.replace("{1}", posItem.getItemValueString("numpos"));
- throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA, message);
- }
+ // validate pos for regex pattern 'XX-YYY-####-###'
+ if (!posItem.getItemValueString("name").matches(invoicePositionsPattern)) {
+ // throw a plugin exception - because name is missing!
+ String message = resourceBundleHandler.findMessage("ERROR_FORMAT_POSNO");
+ message = message.replace("{1}", posItem.getItemValueString("numpos"));
+ throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA, message);
+ }
- if (posItem.getItemValueString("category").trim().isEmpty()) {
- // throw a plugin exception - because name is missing!
- String message = resourceBundleHandler.findMessage("ERROR_MISSING_CATEGORY");
- message = message.replace("{1}", posItem.getItemValueString("numpos"));
- throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA,
- "Eingabefehler - Die Leistungsart in Zeile " + posItem.getItemValueString("numpos")
- + " muss ausgefüllt sein!");
- }
+ if (posItem.getItemValueString("category").trim().isEmpty()) {
+ // throw a plugin exception - because name is missing!
+ String message = resourceBundleHandler.findMessage("ERROR_MISSING_CATEGORY");
+ message = message.replace("{1}", posItem.getItemValueString("numpos"));
+ throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA,
+ "Eingabefehler - Die Leistungsart in Zeile " + posItem.getItemValueString("numpos")
+ + " muss ausgefüllt sein!");
+ }
- if (posItem.getItemValueString("tax").trim().isEmpty()) {
- // throw a plugin exception - because name is missing!
- String message = resourceBundleHandler.findMessage("ERROR_MISSING_TAX");
- message = message.replace("{1}", posItem.getItemValueString("numpos"));
- throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA, message);
- }
+ if (posItem.getItemValueString("tax").trim().isEmpty()) {
+ // throw a plugin exception - because name is missing!
+ String message = resourceBundleHandler.findMessage("ERROR_MISSING_TAX");
+ message = message.replace("{1}", posItem.getItemValueString("numpos"));
+ throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA, message);
+ }
- if (posItem.getItemValueFloat("amount") == 0) {
- // throw a plugin exception - because name is missing!
- String message = resourceBundleHandler.findMessage("ERROR_MISSING_NET");
- message = message.replace("{1}", posItem.getItemValueString("numpos"));
- throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA, message);
- }
+ if (posItem.getItemValueFloat("amount") == 0) {
+ // throw a plugin exception - because name is missing!
+ String message = resourceBundleHandler.findMessage("ERROR_MISSING_NET");
+ message = message.replace("{1}", posItem.getItemValueString("numpos"));
+ throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA, message);
+ }
- // Buchunsperiode
- if (!posItem.getItemValueString(InvoiceUtil.ITEM_INVOICE_PERIOD).trim().isEmpty()) {
- validateBuchungsperiode(posItem.getItemValueString(InvoiceUtil.ITEM_INVOICE_PERIOD));
+ // Buchunsperiode
+ if (!posItem.getItemValueString(InvoiceUtil.ITEM_INVOICE_PERIOD).trim().isEmpty()) {
+ validateBuchungsperiode(posItem.getItemValueString(InvoiceUtil.ITEM_INVOICE_PERIOD));
- }
- }
+ }
+ }
- // Ergaenzung 18.05.2021:
- // es kann vorkommen, das die Anwender abweichende Buchungsperioden eingeben so
- // das die Hauptbuchungsperiode gar ncht merh vorkommt. Das darf aber nicht der
- // fall sein.
- // Im folgenden überprüfen wir ob eine Buchungszeile vorkommt in der keine oder
- // die Hauptbuchunsperiode ausgewählt wurde. Ist das nicht der Fal gibt es eine
- // Fehlermeldung für den Anwendere
- if (isCargoRechnung(workitem) && childs.size() > 0) {
- String hauptBuchungsperiode = workitem.getItemValueString("invoice.period");
- boolean buchungsperiodenValid = false;
- for (ItemCollection posItem : childs) {
- String posBuchungsperiode = posItem.getItemValueString("invoice.period");
- if (posBuchungsperiode.isEmpty() || posBuchungsperiode.equals(hauptBuchungsperiode)) {
- // alles fein!
- buchungsperiodenValid = true;
- }
- }
- if (buchungsperiodenValid == false) {
- // fehlerhafte Buchungsperioden.
- String message = resourceBundleHandler.findMessage("ERROR_MAIN_BOOKING_PERIOD");
- throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA, message);
- }
- }
+ // Ergaenzung 18.05.2021:
+ // es kann vorkommen, das die Anwender abweichende Buchungsperioden eingeben so
+ // das die Hauptbuchungsperiode gar ncht merh vorkommt. Das darf aber nicht der
+ // fall sein.
+ // Im folgenden überprüfen wir ob eine Buchungszeile vorkommt in der keine oder
+ // die Hauptbuchunsperiode ausgewählt wurde. Ist das nicht der Fal gibt es eine
+ // Fehlermeldung für den Anwendere
+ if (isCargoRechnung(workitem) && childs.size() > 0) {
+ String hauptBuchungsperiode = workitem.getItemValueString("invoice.period");
+ boolean buchungsperiodenValid = false;
+ for (ItemCollection posItem : childs) {
+ String posBuchungsperiode = posItem.getItemValueString("invoice.period");
+ if (posBuchungsperiode.isEmpty() || posBuchungsperiode.equals(hauptBuchungsperiode)) {
+ // alles fein!
+ buchungsperiodenValid = true;
+ }
+ }
+ if (buchungsperiodenValid == false) {
+ // fehlerhafte Buchungsperioden.
+ String message = resourceBundleHandler.findMessage("ERROR_MAIN_BOOKING_PERIOD");
+ throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA, message);
+ }
+ }
- }
+ }
- return workitem;
- }
+ return workitem;
+ }
- /**
- * Hilfsroutine die das _img item aktualisiert.
- */
- private void updateImg(ItemCollection workitem) {
+ /**
+ * Hilfsroutine die das _img item aktualisiert.
+ */
+ private void updateImg(ItemCollection workitem) {
- // Update _img icon list
- String img = workitem.getItemValueString("_img");
- // 031=ablehnen
- // 100=sofortüberweichung
- // 074=mahnen
- // sofortüberweisung
- if (workitem.getEventID() == 96 && !img.contains("100.png")) {
- img = img + "";
- }
- // mahnen
- if (workitem.getEventID() == 95 && !img.contains("103.png")) {
- img = img + "";
+ // Update _img icon list
+ String img = workitem.getItemValueString("_img");
+ // 031=ablehnen
+ // 100=sofortüberweichung
+ // 074=mahnen
+ // sofortüberweisung
+ if (workitem.getEventID() == 96 && !img.contains("100.png")) {
+ img = img + "";
+ }
+ // mahnen
+ if (workitem.getEventID() == 95 && !img.contains("103.png")) {
+ img = img + "";
- }
- // ablehnen
- if (workitem.getTaskID() == 5100 && workitem.getEventID() == 90 && !img.contains("028.png")) {
- img = img + "";
- }
- if (workitem.getTaskID() == 5200 && workitem.getEventID() == 90 && !img.contains("028.png")) {
- img = img + "";
- }
- workitem.setItemValue("_img", img);
+ }
+ // ablehnen
+ if (workitem.getTaskID() == 5100 && workitem.getEventID() == 90 && !img.contains("028.png")) {
+ img = img + "";
+ }
+ if (workitem.getTaskID() == 5200 && workitem.getEventID() == 90 && !img.contains("028.png")) {
+ img = img + "";
+ }
+ workitem.setItemValue("_img", img);
- }
+ }
- /**
- * Diese Method prüft die Buchungsperiode auf Plausibilität
- *
- * YYYY(+1)01-12
- *
- * z.b. 202110 oder 202107 oder 202201
- *
- * @param workitem
- * @throws PluginException
- */
- private void validateBuchungsperiode(String period) throws PluginException {
+ /**
+ * Diese Method prüft die Buchungsperiode auf Plausibilität
+ *
+ * YYYY(+1)01-12
+ *
+ * z.b. 202110 oder 202107 oder 202201
+ *
+ * @param workitem
+ * @throws PluginException
+ */
+ private void validateBuchungsperiode(String period) throws PluginException {
- // buchungsperionde nur prüfen wenn noch nicht archiviert
- if (!period.isEmpty()) {
- LocalDate localDate = LocalDate.now();
- int year = localDate.getYear();
- // build regex....
- String regex = "(" + year + "|" + (year + 1) + "|" + (year - 1) + ")(1[0-2]|0[1-9])";
+ // buchungsperionde nur prüfen wenn noch nicht archiviert
+ if (!period.isEmpty()) {
+ LocalDate localDate = LocalDate.now();
+ int year = localDate.getYear();
+ // build regex....
+ String regex = "(" + year + "|" + (year + 1) + "|" + (year - 1) + ")(1[0-2]|0[1-9])";
- if (!period.matches(regex)) {
- // throw a plugin exception - because name is missing!
- String message = resourceBundleHandler.findMessage("ERROR_BOOKING_PERIOD");
- throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA, message);
- }
- }
- }
+ if (!period.matches(regex)) {
+ // throw a plugin exception - because name is missing!
+ String message = resourceBundleHandler.findMessage("ERROR_BOOKING_PERIOD");
+ throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA, message);
+ }
+ }
+ }
- /**
- * Diese Method prüft ob die "invoice.number" bereits einmal im
- * Rechnugnsworkflow vergeben wurde. Falls ja wird eine PluginExcpetion
- * ausgelöst.
- *
- * Query Example:
- *
- * NOT $uniqueid:"9f72fa50-4845-41ea-b6b9-ccd518c353be" AND
- txtcooperatespace:"9dba107e-f8ef-4150-a832-040d75a6eda7" AND invoice.number:"45"
- *
- *
- * in case a duplicate invoice was detected the item invoice.number.duplicate is
- * filled. This item is used for a conditional event. The case is displayed as a
- * warning in the form.
- *
- * @throws PluginException
- * @throws QueryException
- *
- */
- private void validateInvoiceNumber(ItemCollection workitem) throws PluginException {
+ /**
+ * Diese Method prüft ob die "invoice.number" bereits einmal im
+ * Rechnugnsworkflow vergeben wurde. Falls ja wird eine PluginExcpetion
+ * ausgelöst.
+ *
+ * Query Example:
+ *
+ * NOT $uniqueid:"9f72fa50-4845-41ea-b6b9-ccd518c353be" AND
+ txtcooperatespace:"9dba107e-f8ef-4150-a832-040d75a6eda7" AND invoice.number:"45"
+ *
+ *
+ * in case a duplicate invoice was detected the item invoice.number.duplicate is
+ * filled. This item is used for a conditional event. The case is displayed as a
+ * warning in the form.
+ *
+ * @throws PluginException
+ * @throws QueryException
+ *
+ */
+ private void validateInvoiceNumber(ItemCollection workitem) throws PluginException {
- String invoiceNumber = workitem.getItemValueString("invoice.number");
- // strip
- String invoiceNumberStripped = invoiceNumber.replace(" ", "");
- workitem.setItemValue("invoice.number.stripped", invoiceNumberStripped);
- String invoiceNumberDuplicate = workitem.getItemValueString("invoice.number.duplicate");
+ String invoiceNumber = workitem.getItemValueString("invoice.number");
+ // strip
+ String invoiceNumberStripped = invoiceNumber.replace(" ", "");
+ workitem.setItemValue("invoice.number.stripped", invoiceNumberStripped);
+ String invoiceNumberDuplicate = workitem.getItemValueString("invoice.number.duplicate");
- // wenn keine Rechnungsnummer eingegeben wurde gehts weiter!
- if (invoiceNumber.isEmpty()) {
- return;
- }
+ // wenn keine Rechnungsnummer eingegeben wurde gehts weiter!
+ if (invoiceNumber.isEmpty()) {
+ return;
+ }
- // rechnungseingang only workitems...
- // Change 11.4.22 - we have now an additional field: invoice.number.stripped
- String query = "(type:workitem OR type:workitemarchive) AND ($modelversion:rechnungseingang*) AND NOT ($uniqueid:\""
- + workitem.getUniqueID() + "\") AND ((invoice.number:\"" + invoiceNumberStripped
- + "\") OR (invoice.number.stripped:\"" + invoiceNumberStripped + "\"))";
- try {
- int result = this.getWorkflowService().getDocumentService().count(query, 1);
- if (result > 0) {
- // wenn _invoicenumber_duplicate bereits gesetzt ist - dann geht es ohne prüfung
- // weiter
- if (!invoiceNumberDuplicate.isEmpty()) {
- logger.warning("...validateion skipped by user with duplicate invoice number: " + invoiceNumber);
- } else {
+ // rechnungseingang only workitems...
+ // Change 11.4.22 - we have now an additional field: invoice.number.stripped
+ String query = "(type:workitem OR type:workitemarchive) AND ($modelversion:rechnungseingang*) AND NOT ($uniqueid:\""
+ + workitem.getUniqueID() + "\") AND ((invoice.number:\"" + invoiceNumberStripped
+ + "\") OR (invoice.number.stripped:\"" + invoiceNumberStripped + "\"))";
+ try {
+ int result = this.getWorkflowService().getDocumentService().count(query, 1);
+ if (result > 0) {
+ // wenn _invoicenumber_duplicate bereits gesetzt ist - dann geht es ohne prüfung
+ // weiter
+ if (!invoiceNumberDuplicate.isEmpty()) {
+ logger.warning("...validateion skipped by user with duplicate invoice number: " + invoiceNumber);
+ } else {
- // set _invoicenumber_duplicate - dadurch wird die warnmeldung ausgegeben und
- // der Vorgang nicht weitergeleitet
- workitem.replaceItemValue("invoice.number.duplicate", invoiceNumber);
- String message = resourceBundleHandler.findMessage("ERROR_INVOICENO");
- throw new PluginException(InvoicePlugin.class.getName(), ERROR_DUPPLICATE_INVOICE_NUMBER, message);
- }
- } else {
- // clear !
- workitem.appendItemValue("invoice.number.duplicate.history",
- workitem.getItemValueString("invoice.number.duplicate"));
- workitem.replaceItemValue("invoice.number.duplicate", "");
- }
- } catch (QueryException e) {
- throw new PluginException(PluginException.class.getName(), "QUERY ERROR", e.getMessage(), e);
- }
- }
+ // set _invoicenumber_duplicate - dadurch wird die warnmeldung ausgegeben und
+ // der Vorgang nicht weitergeleitet
+ workitem.replaceItemValue("invoice.number.duplicate", invoiceNumber);
+ String message = resourceBundleHandler.findMessage("ERROR_INVOICENO");
+ throw new PluginException(InvoicePlugin.class.getName(), ERROR_DUPPLICATE_INVOICE_NUMBER, message);
+ }
+ } else {
+ // clear !
+ workitem.appendItemValue("invoice.number.duplicate.history",
+ workitem.getItemValueString("invoice.number.duplicate"));
+ workitem.replaceItemValue("invoice.number.duplicate", "");
+ }
+ } catch (QueryException e) {
+ throw new PluginException(PluginException.class.getName(), "QUERY ERROR", e.getMessage(), e);
+ }
+ }
- /**
- * Diese Method prüft ob die eingegebene IBAN nummer bereits in dem ausgewälten
- * Kreditor bekannt ist. Fallst nicht wird diese schnell mal in den Kreditoren
- * Datensatz übertragen. Dadurch muss man nicht extra die Kreditoren Verwaltung
- * aufrufen. Es ist ein art selbst-lernendes System.
- *
- * Die Mehtode ruft eine Plugin Exception aus um den User zu fragen ob er das
- * möchte.
- *
- * @throws PluginException
- * @throws QueryException
- *
- */
- private void checkIBANNumber(ItemCollection workitem) throws PluginException {
+ /**
+ * Diese Method prüft ob die eingegebene IBAN nummer bereits in dem ausgewälten
+ * Kreditor bekannt ist. Fallst nicht wird diese schnell mal in den Kreditoren
+ * Datensatz übertragen. Dadurch muss man nicht extra die Kreditoren Verwaltung
+ * aufrufen. Es ist ein art selbst-lernendes System.
+ *
+ * Die Mehtode ruft eine Plugin Exception aus um den User zu fragen ob er das
+ * möchte.
+ *
+ * @throws PluginException
+ * @throws QueryException
+ *
+ */
+ private void checkIBANNumber(ItemCollection workitem) throws PluginException {
- String cdtrNumber = workitem.getItemValueString("cdtr.number");
- String iban = workitem.getItemValueString("cdtr.iban");
- String bic = workitem.getItemValueString("cdtr.bic");
- String overtakeIBAN = workitem.getItemValueString("ibanbic.overtake");
+ String cdtrNumber = workitem.getItemValueString("cdtr.number");
+ String iban = workitem.getItemValueString("cdtr.iban");
+ String bic = workitem.getItemValueString("cdtr.bic");
+ String overtakeIBAN = workitem.getItemValueString("ibanbic.overtake");
- if (cdtrNumber.isEmpty() || iban.isEmpty() || bic.isEmpty()) {
- // no op
- return;
- }
+ if (cdtrNumber.isEmpty() || iban.isEmpty() || bic.isEmpty()) {
+ // no op
+ return;
+ }
- ItemCollection businessPartner = businessPartnerService
- .getBusinessPartnerByID(InvoiceUtil.buildBPID(cdtrNumber));
- if (businessPartner != null) {
- // update country
- workitem.setItemValue("invoice.country", businessPartner.getItemValueString("partner.country"));
+ ItemCollection businessPartner = businessPartnerService
+ .getBusinessPartnerByID(InvoiceUtil.buildBPID(cdtrNumber));
+ if (businessPartner != null) {
+ // update country
+ workitem.setItemValue("invoice.country", businessPartner.getItemValueString("partner.country"));
- // wenn bereits eine Übernahme angedroht wurde, dann übernehmen wir die neue
- // IBAN/BIC!
- if (!overtakeIBAN.isEmpty()) {
- businessPartnerService.addNewIBANBIC(businessPartner, iban, bic);
- workitem.setItemValue("ibanbic.overtake", "");
- return;
- }
+ // wenn bereits eine Übernahme angedroht wurde, dann übernehmen wir die neue
+ // IBAN/BIC!
+ if (!overtakeIBAN.isEmpty()) {
+ businessPartnerService.addNewIBANBIC(businessPartner, iban, bic);
+ workitem.setItemValue("ibanbic.overtake", "");
+ return;
+ }
- // Prüfen ob wir die IBAN schon kennen
- if (!businessPartnerService.isIBANBICKnown(businessPartner, iban, bic)) {
- // OK - scheinbar ist diese IBAN/BIC nicht bekannt. Also fragen wir mal nach....
- workitem.setItemValue("ibanbic.overtake", iban + bic);
- String message = resourceBundleHandler.findMessage("ERROR_IBAN_UNKNOWN");
- throw new PluginException(InvoicePlugin.class.getName(), ERROR_NEW_IBANBIC, message);
- }
+ // Prüfen ob wir die IBAN schon kennen
+ if (!businessPartnerService.isIBANBICKnown(businessPartner, iban, bic)) {
+ // OK - scheinbar ist diese IBAN/BIC nicht bekannt. Also fragen wir mal nach....
+ workitem.setItemValue("ibanbic.overtake", iban + bic);
+ String message = resourceBundleHandler.findMessage("ERROR_IBAN_UNKNOWN");
+ throw new PluginException(InvoicePlugin.class.getName(), ERROR_NEW_IBANBIC, message);
+ }
- }
+ }
- }
+ }
- /**
- * Hilfsmethod prüft ob die cdtr.nummer mit einer nummer aus der Cargosoft
- * Import Datei übereinstimmt.
- *
- * @param workitem
- * @throws PluginException
- */
- private void validateCargosoftCdtrNumber(ItemCollection workitem) throws PluginException {
- String crdtrNumber = workitem.getItemValueString("cdtr.number");
+ /**
+ * Hilfsmethod prüft ob die cdtr.nummer mit einer nummer aus der Cargosoft
+ * Import Datei übereinstimmt.
+ *
+ * @param workitem
+ * @throws PluginException
+ */
+ private void validateCargosoftCdtrNumber(ItemCollection workitem) throws PluginException {
+ String crdtrNumber = workitem.getItemValueString("cdtr.number");
- // wenn keine Nummer eingegeben wurde gehts weiter!
- if (crdtrNumber.isEmpty()) {
- return;
- }
+ // wenn keine Nummer eingegeben wurde gehts weiter!
+ if (crdtrNumber.isEmpty()) {
+ return;
+ }
- // search creditor number in cargosoft...
- // die cargosoft Kreditornummer beginnt seltsamerweise mit einem K.....
- try {
- String query = "(type:cargosoftkreditor) AND (name:K" + crdtrNumber + " OR name:" + crdtrNumber + ")";
- List result = this.getWorkflowService().getDocumentService().find(query, 1, 0);
- if (result == null || result.size() == 0) {
+ // search creditor number in cargosoft...
+ // die cargosoft Kreditornummer beginnt seltsamerweise mit einem K.....
+ try {
+ String query = "(type:cargosoftkreditor) AND (name:K" + crdtrNumber + " OR name:" + crdtrNumber + ")";
+ List result = this.getWorkflowService().getDocumentService().find(query, 1, 0);
+ if (result == null || result.size() == 0) {
- String message = resourceBundleHandler.findMessage("ERROR_CDTR_INVALID");
- throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA,
- message);
+ String message = resourceBundleHandler.findMessage("ERROR_CDTR_INVALID");
+ throw new PluginException(InvoicePlugin.class.getName(), ERROR_MISSING_DATA, message);
- } else {
- // update cargosoft crediotr name
- ItemCollection cargo = result.get(0);
- workitem.setItemValue("cdtr.name.cargosoft", cargo.getItemValueString("_VENDOR_Name"));
- }
- } catch (QueryException e) {
- e.printStackTrace();
- }
+ } else {
+ // update cargosoft crediotr name
+ ItemCollection cargo = result.get(0);
+ workitem.setItemValue("cdtr.name.cargosoft", cargo.getItemValueString("_VENDOR_Name"));
+ }
+ } catch (QueryException e) {
+ e.printStackTrace();
+ }
- }
+ }
- /**
- * This method returns true if the current workitem is a Cargosoft Invoice.
- *
- * This can be based on different model versions e.g. rechnungseingang-de-1.2,
- * rechnungseingang-pl-1.0, rechnungseingang-dwc-1.0, ...
- *
- * @param workitem
- * @return
- */
- public static boolean isCargoRechnung(ItemCollection workitem) {
- String REGEX_PATTERN = "rechnungseingang-([a-z]{2}|[a-z]{3})-\\d.\\d";
- // Erstellen Sie ein Pattern-Objekt
- Pattern pattern = Pattern.compile(REGEX_PATTERN);
- Matcher matcher = pattern.matcher(workitem.getModelVersion());
- // Überprüfen, ob das Muster übereinstimmt
- return matcher.matches();
- }
+ /**
+ * This method returns true if the current workitem is a Cargosoft Invoice.
+ *
+ * This can be based on different model versions e.g. rechnungseingang-de-1.2,
+ * rechnungseingang-pl-1.0, rechnungseingang-dwc-1.0, ...
+ *
+ * @param workitem
+ * @return
+ */
+ public static boolean isCargoRechnung(ItemCollection workitem) {
+ String REGEX_PATTERN = "rechnungseingang-([a-z]{2}|[a-z]{3})-\\d.\\d";
+ // Erstellen Sie ein Pattern-Objekt
+ Pattern pattern = Pattern.compile(REGEX_PATTERN);
+ Matcher matcher = pattern.matcher(workitem.getModelVersion());
+ // Überprüfen, ob das Muster übereinstimmt
+ return matcher.matches();
+ }
}
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/InvoiceService.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/InvoiceService.java
index 873b42c..19770c2 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/InvoiceService.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/InvoiceService.java
@@ -1,26 +1,26 @@
/*******************************************************************************
- * Imixs Workflow
- * Copyright (C) 2001, 2011 Imixs Software Solutions GmbH,
+ * Imixs Workflow
+ * Copyright (C) 2001, 2011 Imixs Software Solutions GmbH,
* http://www.imixs.com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
- *
+ *
* You can receive a copy of the GNU General Public
* License at http://www.gnu.org/licenses/gpl.html
- *
- * Project:
+ *
+ * Project:
* http://www.imixs.org
* http://java.net/projects/imixs-workflow
- *
- * Contributors:
+ *
+ * Contributors:
* Imixs Software Solutions GmbH - initial API and implementation
* Ralph Soika - Software Developer
*******************************************************************************/
@@ -47,9 +47,9 @@ import jakarta.inject.Inject;
/**
* Der InvoiceService stellt einige Hilfsmethoden bereit.
- *
+ *
* @author rsoika
- *
+ *
*/
@Singleton
@RunAs("org.imixs.ACCESSLEVEL.MANAGERACCESS")
@@ -79,7 +79,7 @@ public class InvoiceService {
/**
* Liefert die Liste der Ausgehenden Währungen
- *
+ *
* @return
* @throws PluginException
*/
@@ -89,8 +89,7 @@ public class InvoiceService {
ItemCollection configItemCollection = configService.loadConfiguration("AGL_CONFIGURATION");
List currencyList = configItemCollection.getItemValue("currency.out");
if (currencyList == null || currencyList.size() < 1) {
- throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(),
- InvoiceService.ERROR_CONFIG,
+ throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
"missing Currency configuration - please check parameters");
}
return currencyList;
@@ -98,7 +97,7 @@ public class InvoiceService {
/**
* Gibt die Hauptwährung zurück (1. in der liste)
- *
+ *
* @return
* @throws PluginException
*/
@@ -108,8 +107,7 @@ public class InvoiceService {
ItemCollection configItemCollection = configService.loadConfiguration("AGL_CONFIGURATION");
List currencyList = configItemCollection.getItemValue("currency.out");
if (currencyList == null || currencyList.size() < 1) {
- throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(),
- InvoiceService.ERROR_CONFIG,
+ throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
"missing Currency configuration - please check parameters");
}
return currencyList.get(0);
@@ -117,7 +115,7 @@ public class InvoiceService {
/**
* Liefert die Liste der Eingehenden Währungen
- *
+ *
* @return
* @throws PluginException
*/
@@ -127,16 +125,14 @@ public class InvoiceService {
ItemCollection configItemCollection = configService.loadConfiguration("AGL_CONFIGURATION");
List currencyList = configItemCollection.getItemValue("currency.in");
if (currencyList == null || currencyList.size() < 1) {
- throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(),
- InvoiceService.ERROR_CONFIG,
+ throw new PluginException(AGLAnalyticExcelAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
"missing Currency configuration - please check parameters");
}
return currencyList;
}
/**
- * Prüft ob der Vorgang überflällig ist.
- * Default ist 21 tage.
+ * Prüft ob der Vorgang überflällig ist. Default ist 21 tage.
*/
public boolean isOverdue(Date date, int taskid) {
Date now = new Date();
@@ -149,9 +145,9 @@ public class InvoiceService {
/**
* This method returns a text-block ItemCollection for a specified name.
- *
+ *
* @param name in attribute txtname
- *
+ *
*
*/
public FileData loadTextBlockFileData(String name, String fileName) {
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/InvoiceUtil.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/InvoiceUtil.java
index cc7a582..c358d67 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/InvoiceUtil.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/InvoiceUtil.java
@@ -12,14 +12,12 @@ import org.imixs.workflow.ItemCollection;
/**
* Hilfsmethoden für die Berechnung und Validierung von Ein und
* Ausgangsrechnugnen
- *
- * - Rundungs Methode
- * - Berechnung der Positionsnummern
- * - Explode Childitems
- *
+ *
+ * - Rundungs Methode - Berechnung der Positionsnummern - Explode Childitems
+ *
* See:
* https://stackoverflow.com/questions/2808535/round-a-double-to-2-decimal-places
- *
+ *
* @author rsoika
*
*/
@@ -42,7 +40,7 @@ public class InvoiceUtil {
/**
* Rounds a Flat Value
- *
+ *
* @param value
* @return
*/
@@ -54,7 +52,7 @@ public class InvoiceUtil {
/**
* Hilfsmethode zum validieren der Mailadresse
- *
+ *
* @param emailAddress
* @return
*/
@@ -63,9 +61,7 @@ public class InvoiceUtil {
String regexPattern = "^(?=.{1,64}@)[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*@"
+ "[^-][A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)*(\\.[A-Za-z]{2,})$";
- return Pattern.compile(regexPattern)
- .matcher(emailAddress)
- .matches();
+ return Pattern.compile(regexPattern).matcher(emailAddress).matches();
}
// @Deprecated
@@ -102,7 +98,7 @@ public class InvoiceUtil {
/**
* Convert the List of ItemCollections back into a List of Map elements
- *
+ *
* @param workitem
*/
public static void implodeChildList(ItemCollection workitem, List childItems) {
@@ -111,7 +107,7 @@ public class InvoiceUtil {
/**
* Convert the List of ItemCollections back into a List of Map elements
- *
+ *
* @param workitem
*/
@SuppressWarnings({ "rawtypes" })
@@ -130,11 +126,10 @@ public class InvoiceUtil {
/**
* Diese Methode berechnet das feld 'invoice.positions' welches eine Valueliste
- * mit allen Positionsnummern aus dem Childliste enthält.
- * Es wird sowohl für Ausgangs wie Eingangsrechnungen genutzt.
- * Das feld wird indiziert, so dass eine gezielte Suche nach positiosnummern
- * möglich ist.
- *
+ * mit allen Positionsnummern aus dem Childliste enthält. Es wird sowohl für
+ * Ausgangs wie Eingangsrechnungen genutzt. Das feld wird indiziert, so dass
+ * eine gezielte Suche nach positiosnummern möglich ist.
+ *
* @param workitem
*/
public static void updateInvoicePositions(ItemCollection workitem) {
@@ -162,9 +157,9 @@ public class InvoiceUtil {
/**
* Diese Hilfsmethode harmonisiert die Debitoren/Kreditoren ID von Cargosoft und
* liefert eine Geschäftspartner ID zurück.
- *
+ *
* Aus Kreditor K70153 und Debitor D10153 wird die einheitliche ID: BP0153
- *
+ *
* @param key
* @return
*/
@@ -188,7 +183,7 @@ public class InvoiceUtil {
/**
* Diese Hilfmethode berechnet die BusinessPartner id aus einer Invoice
- *
+ *
* @param Invoice
* @return
*/
@@ -204,7 +199,7 @@ public class InvoiceUtil {
/**
* Diese Hilfmethode berechnet die BusinessPartner Namen aus einer Invoice
- *
+ *
* @param Invoice
* @return
*/
@@ -223,7 +218,7 @@ public class InvoiceUtil {
/**
* Gibt true zurück wenn es sich um eine Kreditoren Rechnung/Gutschrift handelt.
- *
+ *
* @param invoice
* @return
*/
@@ -238,7 +233,7 @@ public class InvoiceUtil {
/**
* Gibt true zurück wenn es sich um eine Kreditoren Sachrechnung handelt.
- *
+ *
* @param invoice
* @return
*/
@@ -252,7 +247,7 @@ public class InvoiceUtil {
/**
* Gibt true zurück wenn es sich um eine Debitoren Rechnung/Gutschrift handelt.
- *
+ *
* @param invoice
* @return
*/
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/OPListController.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/OPListController.java
index 078e00f..36d15e6 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/OPListController.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/OPListController.java
@@ -31,7 +31,7 @@ import jakarta.inject.Named;
* errechnet der Controller die selectieren Invoices und verknpüft diese final
* mit dem Zahlungseingang.
*
- *
+ *
* @author rsoika
*
*/
@@ -74,8 +74,7 @@ public class OPListController implements Serializable {
* Diese Methode wird für Zahlungseingänge und Mahnläufe verwendet.
*
* Die Methode liefert die Rechnungen zur gegebenen dbtrNumber. Die Methode
- * nutzt
- * einen lokalen cache um die Zugriffe zu beschleunigen.
+ * nutzt einen lokalen cache um die Zugriffe zu beschleunigen.
*
* Befindet sich ein Zahlungseingang in Erstellung (Task=1000) werden alle
* offenen Rechnungen geholt.
@@ -90,8 +89,8 @@ public class OPListController implements Serializable {
* will.
*
* Beim Mahnlauf werden Inkasso Rechnungen ausgenommen.
- *
- *
+ *
+ *
* @param _dbtrNumber
* @return
*/
@@ -150,7 +149,7 @@ public class OPListController implements Serializable {
/*
* Zahlugnseingang?
- *
+ *
* Wir berechnen den saldo.
*/
if (workflowController.getWorkitem().getModelVersion().startsWith("zahlungseingang")) {
@@ -172,10 +171,10 @@ public class OPListController implements Serializable {
* Bei einem Mahnlauf selektieren wir alle Rechnungne immer vor. Das ist eine
* Anforderung von AGL Der Benutzer kann dann einzelne Rechnungen wieder
* abwählen.
- *
+ *
* Eine Ausnahme ist hier nur wenn jemand auf Speichern oder mahnen drückt
* (Event = 10|20). Dann ändern wir die Liste nicht!
- *
+ *
* Hinweis: in der Liste befinden sich keine Inkasso Rechnungen, da man diese
* nicht anwählen kann.
*/
@@ -185,8 +184,7 @@ public class OPListController implements Serializable {
// einer Rechnung mit dem Event 100 (Mahnlauf erstellen) kommen, oder
// wenn der Mahnlauf von außen gerate eben neu erzeugt wurde
if (workflowController.getWorkitem().getItemValueInteger("$lastevent") == 100
- ||
- workflowController.getWorkitem().getItemValueInteger("$lastevent") == 0) {
+ || workflowController.getWorkitem().getItemValueInteger("$lastevent") == 0) {
List intialSelection = new ArrayList();
for (ItemCollection invoice : invoiceList) {
// ist die Rechnung fällig?
@@ -247,7 +245,7 @@ public class OPListController implements Serializable {
/**
* On Before Process we store the selected invoices in $worktiemRef
- *
+ *
* @param workflowEvent
*/
public void onWorkflowEvent(@Observes WorkflowEvent workflowEvent) {
@@ -299,7 +297,7 @@ public class OPListController implements Serializable {
/**
* Hilfsmethode delegates to ZahlungseingangServcie
- *
+ *
* @param payment
* @return
*/
@@ -309,7 +307,7 @@ public class OPListController implements Serializable {
/**
* Berechnet den gesammten OP Saldo
- *
+ *
* @return
*/
public double calculateInvoiceTotal() {
@@ -323,10 +321,10 @@ public class OPListController implements Serializable {
}
/**
- * Berechnet die Summer aller Rechnungen zu einer Währung.
- * Es werden nur Rechnungen berücksichtigt, deren Haupt Währung der übergebenen
- * Währung entspricht.
- *
+ * Berechnet die Summer aller Rechnungen zu einer Währung. Es werden nur
+ * Rechnungen berücksichtigt, deren Haupt Währung der übergebenen Währung
+ * entspricht.
+ *
* @param currency
* @return
*/
@@ -344,7 +342,7 @@ public class OPListController implements Serializable {
/**
* Berechnet den gesamten OP Saldo
- *
+ *
* @return
*/
public double calculateInvoiceSaldo() {
@@ -361,7 +359,7 @@ public class OPListController implements Serializable {
/**
* Berechnet den noch offenen Differenz vom Zahlbetrag
- *
+ *
* @return
*/
public double calculatePaymentDifference() {
@@ -379,7 +377,7 @@ public class OPListController implements Serializable {
/**
* Berechnet den Zahlbetrag in EUR bei Fremdwärungen
- *
+ *
* @return
*/
public double calculatePaymentSaldoEUR() {
@@ -401,7 +399,7 @@ public class OPListController implements Serializable {
/**
* Returns true if the reminder date is today or in the past
- *
+ *
* @param uniqueid
* @return
*/
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/OPListExportAdapter.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/OPListExportAdapter.java
index 1b4dff5..f123efb 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/OPListExportAdapter.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/OPListExportAdapter.java
@@ -35,7 +35,7 @@ import jakarta.inject.Inject;
* Der OPListExportAdapter exportiert eine Excel Datei mit allen offenen
* Rechnungen gruppiert nach Debitor. Es werden alle Ausgehenden Währungen
* berücksichtigt und ab Spalte H eingefügt.
- *
+ *
*
* Der Adapter erweitert den POIAdapter somit können Felder aktualisiert werden
* (siehe POIFineReplaceAdapter).
- *
+ *
*
* Der Adapter kopiert die Rechnungsdaten in neue Zeilen, welche ab Zeilennummer
* 12 eingefügt werden.
*
- *
+ *
* Abschliessend werden Summen Formeln in Zeile 14 für jede Währung eingefügt.
- *
+ *
* Der Fälligkeitszeitrum von 21 Tagen kann über den Parameter
- *
+ *
* @version 1.0
* @author rsoika
*/
@@ -78,7 +78,7 @@ public class OPListExportAdapter extends POIFindReplaceAdapter {
/**
* This method finds or create the Zahlungsavis and adds a reference
* ($workitemref) to the current invoice.
- *
+ *
* @throws PluginException
*/
@SuppressWarnings("unchecked")
@@ -95,9 +95,7 @@ public class OPListExportAdapter extends POIFindReplaceAdapter {
}
// read the template options
- ItemCollection evalItemCollection = workflowService.evalWorkflowResult(event, "opliste",
- document,
- false);
+ ItemCollection evalItemCollection = workflowService.evalWorkflowResult(event, "opliste", document, false);
if (evalItemCollection == null || !evalItemCollection.hasItem("excel-export")) {
throw new PluginException(OPListExportAdapter.class.getSimpleName(), CONFIG_ERROR,
"missing opliste configuration in model event - please check model configuration");
@@ -132,13 +130,11 @@ public class OPListExportAdapter extends POIFindReplaceAdapter {
doc.write(byteArrayOutputStream);
byte[] newContent = byteArrayOutputStream.toByteArray();
- FileData fileDataNew = new FileData(fileData.getName(), newContent, fileData.getContentType(),
- null);
+ 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(OPListExportAdapter.class.getSimpleName(),
- InvoiceService.ERROR_CONFIG,
+ throw new PluginException(OPListExportAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
"failed to update opliste: " + e.getMessage());
} finally {
if (doc != null) {
@@ -157,8 +153,7 @@ public class OPListExportAdapter extends POIFindReplaceAdapter {
} catch (
PluginException e) {
- throw new PluginException(OPListExportAdapter.class.getSimpleName(),
- InvoiceService.ERROR_CONFIG,
+ throw new PluginException(OPListExportAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
"failed to update op-liste: " + e.getMessage());
}
logger.fine("... completed!");
@@ -169,8 +164,8 @@ public class OPListExportAdapter extends POIFindReplaceAdapter {
/**
* EIne OP Liste kann für eine oder mehrere Währungen erstellt werden. Diese
* Hilfsmethode fügt die Spalten anhand der Währungen ein.
- *
- *
+ *
+ *
* @param sheet
* @param currencyList
*/
@@ -206,13 +201,12 @@ public class OPListExportAdapter extends POIFindReplaceAdapter {
*
* 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, ItemCollection document, String fileName, boolean filter,
- List currencyList)
- throws PluginException, QueryException {
+ List currencyList) throws PluginException, QueryException {
String spaceID = document.getItemValueString("space.ref");
logger.fine("... space.ref=" + spaceID + " ...grouping invoices by spaceid....");
@@ -344,17 +338,15 @@ public class OPListExportAdapter extends POIFindReplaceAdapter {
/**
* 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 {
+ String targetName) throws PluginException {
if ((template == null || template.isEmpty()) || (textblockRef == null || textblockRef.isEmpty())) {
- throw new PluginException(OPListExportAdapter.class.getSimpleName(),
- InvoiceService.ERROR_CONFIG,
+ throw new PluginException(OPListExportAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
"invalid POI configuration in model event - textblock/template reference not defined!");
}
@@ -363,10 +355,8 @@ public class OPListExportAdapter extends POIFindReplaceAdapter {
// do we found the document?
if (fileData == null) {
- throw new PluginException(OPListExportAdapter.class.getSimpleName(),
- InvoiceService.ERROR_CONFIG,
- "invalid POI configuration in model event - template=" + template
- + " not found!");
+ throw new PluginException(OPListExportAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
+ "invalid POI configuration in model event - template=" + template + " not found!");
}
fileData.setName(targetName);
// append document
@@ -377,10 +367,10 @@ public class OPListExportAdapter extends POIFindReplaceAdapter {
/**
* Diese Methode gruppiert eine Rechnungsliste nach Debitorennummern
- *
+ *
* Falls 'filter==true' werden nur Rechnungen ab der 2. Mahnung oder mit einer
* Fälligkeit >10 Tage ausgegeben. Dieses Flag wird im Workflowmodell gesetzt
- *
+ *
* @param spaceID
* @return
*/
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/OPListExportAdapterByWeek.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/OPListExportAdapterByWeek.java
index 49de735..b110389 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/OPListExportAdapterByWeek.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/OPListExportAdapterByWeek.java
@@ -46,9 +46,9 @@ import jakarta.inject.Inject;
* Der OPListExportAdapterByWeek ist ählnlich dem Der OPListExportAdapter. Er
* erzeugt eine Excel tabelle mit allen offenen Rechnungen und gruppiert diese
* nach Abteilungen und KW
- *
+ *
* Der OPListExportAdapterByWeek importiert eine Excel Datei aus einem Textblock
- *
+ *
*
* Der Adapter erweitert den POIAdapter somit können felder aktualisiert werden
* (siehe POIFineReplaceAdapter).
- *
+ *
*
* Der Adapter kopiert die Rechnungsdaten in neue Zeilen, welche ab Zeilnenummer
* 16 eingefügt werden.
*
- *
+ *
* Abschliessend wird die Zelle 'TOTAL' noch aktualisiert.
- *
+ *
* @version 1.0
* @author rsoika
*/
@@ -97,7 +97,7 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
/**
* This method finds or create the Zahlungsavis and adds a reference
* ($workitemref) to the current invoice.
- *
+ *
* @throws PluginException
*/
@SuppressWarnings("unchecked")
@@ -119,9 +119,7 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
Collections.sort(spaces, new ItemCollectionComparator("space.name", true));
// read the template options
- ItemCollection evalItemCollection = workflowService.evalWorkflowResult(event, "opliste",
- document,
- false);
+ ItemCollection evalItemCollection = workflowService.evalWorkflowResult(event, "opliste", document, false);
if (evalItemCollection == null || !evalItemCollection.hasItem("excel-export")) {
throw new PluginException(OPListExportAdapter.class.getSimpleName(), CONFIG_ERROR,
"missing opliste configuration in model event - please check model configuration");
@@ -155,14 +153,12 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
doc.write(byteArrayOutputStream);
byte[] newContent = byteArrayOutputStream.toByteArray();
- FileData fileDataNew = new FileData(fileData.getName(), newContent, fileData.getContentType(),
- null);
+ 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(OPListExportAdapter.class.getSimpleName(),
- InvoiceService.ERROR_CONFIG,
+ throw new PluginException(OPListExportAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
"failed to update opliste: " + e.getMessage());
} finally {
if (doc != null) {
@@ -180,8 +176,7 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
} catch (
PluginException e) {
- throw new PluginException(OPListExportAdapter.class.getSimpleName(),
- InvoiceService.ERROR_CONFIG,
+ throw new PluginException(OPListExportAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
"failed to update op-liste: " + e.getMessage());
}
logger.fine("... completed!");
@@ -193,7 +188,7 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
/**
* EIne OP Liste kann für eine oder mehrere Währungen erstellt werden. Diese
* Hilfsmethode fügt die Spalten anhand der Währungen für jede Abteilung ein.
- *
+ *
* @param sheet
* @param currencyList
*/
@@ -249,13 +244,12 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
*
* The named cell 'TOTAL' should contain the summary formula. It will be
* evaluated at the end.
- *
+ *
* @throws PluginException
* @throws QueryException
*/
private void insertInvoiceRows(XSSFWorkbook doc, XSSFSheet sheet, List currencyList,
- List spaces)
- throws PluginException, QueryException {
+ List spaces) throws PluginException, QueryException {
List spaceNames = new ArrayList();
@@ -285,8 +279,8 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
}
/*
- * --- Phase 1 -------------------------------------------------------
- * Im folgenden gruppieren wir die Rechnungen nach Woche
+ * --- Phase 1 ------------------------------------------------------- Im
+ * folgenden gruppieren wir die Rechnungen nach Woche
*/
// XSSFCell cellKWTotalReference = referenceRowTotal.getCell(14);
@@ -306,10 +300,10 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
totalDataMapUeberFaellig.put("TOTAL", new TotalInvoiceData("TOTAL"));
/*
- * --- Phase 3 -------------------------------------------------------
- * now build a new row for each week and print out the collected invoice data
- * first iterate over all objects and collect all known weeks and sort them into
- * a ordered list....
+ * --- Phase 3 ------------------------------------------------------- now build
+ * a new row for each week and print out the collected invoice data first
+ * iterate over all objects and collect all known weeks and sort them into a
+ * ordered list....
*/
List sortedWeekList = new ArrayList();
Iterator> iterator = weekDataMap.entrySet().iterator();
@@ -323,9 +317,9 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
Collections.sort(sortedWeekList);
/*
- * --- Phase 4 -------------------------------------------------------
- * Nun müssen wir so viele Zeilen nach unten schieben wie wir gleich einfügen.
- * Dazu müssen wir kurz einen Probelauf machen um die geplante Anzahl zu
+ * --- Phase 4 ------------------------------------------------------- Nun
+ * müssen wir so viele Zeilen nach unten schieben wie wir gleich einfügen. Dazu
+ * müssen wir kurz einen Probelauf machen um die geplante Anzahl zu
* errechnen....
*/
int rowPos = 11;
@@ -333,8 +327,8 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
sheet.shiftRows(rowPos + 1, 2999, insertCount, true, true);
/*
- * --- Phase 5 -------------------------------------------------------
- * Jetzt Zahlen Zeile für Zeile einfügen....
+ * --- Phase 5 ------------------------------------------------------- Jetzt
+ * Zahlen Zeile für Zeile einfügen....
*/
boolean ueberFaellig = true;
for (String week : sortedWeekList) {
@@ -399,9 +393,8 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
}
/*
- * --- Phase 6 -------------------------------------------------------
- * now lets update the totals...
- * Überfällig
+ * --- Phase 6 ------------------------------------------------------- now lets
+ * update the totals... Überfällig
*/
int _rowNo = sortedWeekList.size() + 14;
XSSFRow rowUeberFaellig = sheet.getRow(_rowNo);
@@ -460,16 +453,14 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
/**
* Diese Methode gruppiert eine Rechnungsliste nach Kalenderwoche
- *
+ *
* @param spaceID - Space Ref to select a list of invoices associated with
- * a
- * space
+ * a space
* @param weekDataCache - a local cache storing all invoices by week
- *
- *
+ *
+ *
*/
- private void groupInvoicesByWeek(String spaceID, String spaceName,
- Map weekDataCache) {
+ private void groupInvoicesByWeek(String spaceID, String spaceName, Map weekDataCache) {
logger.info("...group invoices for " + spaceName + "/" + spaceID);
try {
@@ -482,9 +473,7 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
// compute Week
Date dueDate = invoice.getItemValueDate("invoice.duedate");
- LocalDate localDate = dueDate.toInstant()
- .atZone(ZoneId.systemDefault())
- .toLocalDate();
+ LocalDate localDate = dueDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
int weekNumber = localDate.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR);
int weekBasedYear = localDate.get(IsoFields.WEEK_BASED_YEAR);
String weekCategory = weekBasedYear + "/" + String.format("%02d", weekNumber);
@@ -521,17 +510,15 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
/**
* 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 {
+ String targetName) throws PluginException {
if ((template == null || template.isEmpty()) || (textblockRef == null || textblockRef.isEmpty())) {
- throw new PluginException(OPListExportAdapter.class.getSimpleName(),
- InvoiceService.ERROR_CONFIG,
+ throw new PluginException(OPListExportAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
"invalid POI configuration in model event - textblock/template reference not defined!");
}
@@ -540,10 +527,8 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
// do we found the document?
if (fileData == null) {
- throw new PluginException(OPListExportAdapter.class.getSimpleName(),
- InvoiceService.ERROR_CONFIG,
- "invalid POI configuration in model event - template=" + template
- + " not found!");
+ throw new PluginException(OPListExportAdapter.class.getSimpleName(), InvoiceService.ERROR_CONFIG,
+ "invalid POI configuration in model event - template=" + template + " not found!");
}
fileData.setName(targetName);
// append document
@@ -555,8 +540,8 @@ public class OPListExportAdapterByWeek extends POIFindReplaceAdapter {
}
/**
- * Data Element for invoice totals per week and space.
- * The object holds multiple currencies.
+ * Data Element for invoice totals per week and space. The object holds multiple
+ * currencies.
*/
class WeekInvoiceData {
@@ -601,8 +586,8 @@ class WeekInvoiceData {
}
/**
- * Data Element for invoice totals per space.
- * The object holds multiple currencies.
+ * Data Element for invoice totals per space. The object holds multiple
+ * currencies.
*/
class TotalInvoiceData {
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/OPListExportController.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/OPListExportController.java
index 550b888..37fab8b 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/OPListExportController.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/OPListExportController.java
@@ -2,26 +2,26 @@ package com.alexanderlogistics;
/*******************************************************************************
* Imixs Workflow Technology
- * Copyright (C) 2003, 2008 Imixs Software Solutions GmbH,
+ * Copyright (C) 2003, 2008 Imixs Software Solutions GmbH,
* http://www.imixs.com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
- *
+ *
* You can receive a copy of the GNU General Public
* License at http://www.gnu.org/licenses/gpl.html
- *
- * Contributors:
+ *
+ * Contributors:
* Imixs Software Solutions GmbH - initial API and implementation
* Ralph Soika
- *
+ *
*******************************************************************************/
import java.util.logging.Logger;
@@ -34,44 +34,43 @@ import jakarta.inject.Named;
/**
* The OPListExportController is used to configure the OpListeExporterService.
- * This service is
- * used to export workitems.
+ * This service is used to export workitems.
*
* The Controller creates a configuration entity "type=configuration;
* txtname=OPLIST_EXPORT_CONFIGURATION".
- *
- *
+ *
+ *
* @author rsoika
- *
+ *
*/
@Named(value = "oplistExportController")
@RequestScoped
public class OPListExportController extends SchedulerController {
- public static final String OPLIST_EXPORT_CONFIGURATION = "OPLIST_EXPORT_CONFIGURATION";
+ public static final String OPLIST_EXPORT_CONFIGURATION = "OPLIST_EXPORT_CONFIGURATION";
- private static final long serialVersionUID = 1L;
- private static Logger logger = Logger.getLogger(OPListExportController.class.getName());
+ private static final long serialVersionUID = 1L;
+ private static Logger logger = Logger.getLogger(OPListExportController.class.getName());
- @Inject
- OPListExportScheduler opListExportScheduler;
+ @Inject
+ OPListExportScheduler opListExportScheduler;
- @Override
- public String getName() {
- return OPLIST_EXPORT_CONFIGURATION;
- }
+ @Override
+ public String getName() {
+ return OPLIST_EXPORT_CONFIGURATION;
+ }
- /**
- * Returns the sepa scheduler class name. This name depends on the _export_type.
- *
- * There are two export interfaces available - csv and XML
- *
- */
- @Override
- public String getSchedulerClass() {
- String schedulerClass = OPListExportScheduler.class.getName();
- logger.finest("...... scheduler: " + schedulerClass);
- return schedulerClass;
- }
+ /**
+ * Returns the sepa scheduler class name. This name depends on the _export_type.
+ *
+ * There are two export interfaces available - csv and XML
+ *
+ */
+ @Override
+ public String getSchedulerClass() {
+ String schedulerClass = OPListExportScheduler.class.getName();
+ logger.finest("...... scheduler: " + schedulerClass);
+ return schedulerClass;
+ }
}
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/OPListExportScheduler.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/OPListExportScheduler.java
index 154e8c1..542ba56 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/OPListExportScheduler.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/OPListExportScheduler.java
@@ -1,22 +1,22 @@
/*******************************************************************************
* Imixs Workflow Technology
- * Copyright (C) 2001, 2008 Imixs Software Solutions GmbH,
+ * Copyright (C) 2001, 2008 Imixs Software Solutions GmbH,
* http://www.imixs.com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
- *
+ *
* You can receive a copy of the GNU General Public
* License at http://www.gnu.org/licenses/gpl.html
- *
- * Contributors:
+ *
+ * Contributors:
* Imixs Software Solutions GmbH - initial API and implementation
* Ralph Soika
*******************************************************************************/
@@ -61,10 +61,10 @@ import jakarta.inject.Inject;
* The class implements the interface
* _org.imixs.workflow.engine.scheduler.Scheduler_ and can be used in
* combination with the Imxis-Workflow Scheduler Service.
- *
+ *
* @see SchedulerService
* @author rsoika
- *
+ *
*/
public class OPListExportScheduler implements Scheduler {
@@ -89,7 +89,7 @@ public class OPListExportScheduler implements Scheduler {
/**
* This is the method which processes the timeout event depending on the running
* timer settings.
- *
+ *
* @param timer
* @throws QueryException
*/
@@ -131,7 +131,7 @@ public class OPListExportScheduler implements Scheduler {
/**
* Prüfen ob es Rechnungen in diesem Space gibt die entweder die 2. Mahnstufe
* erreicht haben oder deren Fälligkeit um mehr als 21 Tage überschritten ist.
- *
+ *
* @param space
* @return
*/
@@ -139,8 +139,8 @@ public class OPListExportScheduler implements Scheduler {
List invoices = new ArrayList();
try {
invoices = documentService.find(
- "$modelversion:rechnungsausgang-* AND type:workitem AND $uniqueidref:" + space.getUniqueID(),
- 999, 0);
+ "$modelversion:rechnungsausgang-* AND type:workitem AND $uniqueidref:" + space.getUniqueID(), 999,
+ 0);
} catch (QueryException e) {
logger.warning("Failed to compute invoice list: " + e.getMessage());
e.printStackTrace();
@@ -168,7 +168,7 @@ public class OPListExportScheduler implements Scheduler {
/**
* Creates a new log entry stored in the item _scheduler_log. The log can be
* writen optional to the configuraiton and the workitem
- *
+ *
* @param message
* @param configuration
*/
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/RenameFilenamesAdapter.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/RenameFilenamesAdapter.java
index a4763dc..662d1c5 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/RenameFilenamesAdapter.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/RenameFilenamesAdapter.java
@@ -17,123 +17,122 @@ import jakarta.inject.Inject;
/**
* Der RenameFilenamesAdapter kann optional eingesetzt werden. Dieser Adapter
* verändert den Dateinamen von angehangenen Rechnungen
- *
+ *
* Der Adapter wir beispielweise in DWC eingesetzt bevor die Dateien in einen
* FTP Server hochgeladen werden.
- *
+ *
* Die Dateinamen werden vom System berechnet.
- *
+ *
* sequencenumber + "_" +invoice.positions+".pdf"
- *
- *
+ *
+ *
* Bei Sachrechnungen
- *
- * sequencenumber + "_" + invoice.number.stripped + ".pdf"
- * wird das Rechnungsdatum verwendet um die Buchungsperiode zu berechnen.
- *
- *
- *
+ *
+ * sequencenumber + "_" + invoice.number.stripped + ".pdf" wird das
+ * Rechnungsdatum verwendet um die Buchungsperiode zu berechnen.
+ *
+ *
+ *
* @author rsoika
* @version 1.0
- *
+ *
*/
public class RenameFilenamesAdapter implements SignalAdapter {
- private static Logger logger = Logger.getLogger(RenameFilenamesAdapter.class.getName());
+ private static Logger logger = Logger.getLogger(RenameFilenamesAdapter.class.getName());
- @Inject
- SnapshotService snapshotService;
+ @Inject
+ SnapshotService snapshotService;
- /**
- * Rename Filenames
- *
- * @throws PluginException
- *
- **/
- @Override
- public ItemCollection execute(ItemCollection workitem, ItemCollection event)
- throws AdapterException, PluginException {
+ /**
+ * Rename Filenames
+ *
+ * @throws PluginException
+ *
+ **/
+ @Override
+ public ItemCollection execute(ItemCollection workitem, ItemCollection event)
+ throws AdapterException, PluginException {
- int fileNameCounter = 0; // for multiple files
- List fileDataSet = workitem.getFileData();
- for (FileData fileData : fileDataSet) {
- String fileName = fileData.getName();
- // only PDF files and X-Rechnung
- if ((fileName.toLowerCase().endsWith(".pdf")
- || fileName.toLowerCase().endsWith(".xml"))) {
+ int fileNameCounter = 0; // for multiple files
+ List fileDataSet = workitem.getFileData();
+ for (FileData fileData : fileDataSet) {
+ String fileName = fileData.getName();
+ // only PDF files and X-Rechnung
+ if ((fileName.toLowerCase().endsWith(".pdf") || fileName.toLowerCase().endsWith(".xml"))) {
- // Build new Filename
- String newFileName = buildFileName(fileName, workitem, fileNameCounter);
- if (!newFileName.equals(fileName)) {
- logger.info("Rename file name " + fileName + " -> " + newFileName);
- // do we have content
- if (fileData.getContent().length < 10) {
- // fetch snaphot data
- FileData snapShotFileData = snapshotService.getWorkItemFile(workitem.getUniqueID(), fileName);
- // remove old data
- workitem.removeFile(fileName);
- snapShotFileData.setName(newFileName);
- workitem.addFileData(snapShotFileData);
- } else {
- fileData.setName(newFileName);
- }
- fileNameCounter++;
- }
+ // Build new Filename
+ String newFileName = buildFileName(fileName, workitem, fileNameCounter);
+ if (!newFileName.equals(fileName)) {
+ logger.info("Rename file name " + fileName + " -> " + newFileName);
+ // do we have content
+ if (fileData.getContent().length < 10) {
+ // fetch snaphot data
+ FileData snapShotFileData = snapshotService.getWorkItemFile(workitem.getUniqueID(), fileName);
+ // remove old data
+ workitem.removeFile(fileName);
+ snapShotFileData.setName(newFileName);
+ workitem.addFileData(snapShotFileData);
+ } else {
+ fileData.setName(newFileName);
+ }
+ fileNameCounter++;
+ }
- // Update FTP Target path information
- String targetPath = "";
- if (InvoiceUtil.isCreditorInvoice(workitem)) {
- targetPath = "invoice-in/";
- String bookingPath = workitem.getItemValueString("invoice.period");
- // Sachrechnung
- if (bookingPath.isEmpty()) {
- // build period from invoice.date
- DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMM");
- LocalDate invoiceDate = workitem.getItemValueLocalDate("invoice.date");
- bookingPath = invoiceDate.format(formatter);
- }
- if (bookingPath.length() > 4) {
- targetPath = targetPath + bookingPath.substring(0, 4) + "/" + bookingPath.substring(4);
- }
- } else {
- targetPath = "invoice-out/";
- String bookingPath = workitem.getItemValueString("invoice.bookingperiod");
- targetPath = targetPath + bookingPath.substring(0, 4) + "/" + bookingPath.substring(4);
- }
+ // Update FTP Target path information
+ String targetPath = "";
+ if (InvoiceUtil.isCreditorInvoice(workitem)) {
+ targetPath = "invoice-in/";
+ String bookingPath = workitem.getItemValueString("invoice.period");
+ // Sachrechnung
+ if (bookingPath.isEmpty()) {
+ // build period from invoice.date
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMM");
+ LocalDate invoiceDate = workitem.getItemValueLocalDate("invoice.date");
+ bookingPath = invoiceDate.format(formatter);
+ }
+ if (bookingPath.length() > 4) {
+ targetPath = targetPath + bookingPath.substring(0, 4) + "/" + bookingPath.substring(4);
+ }
+ } else {
+ targetPath = "invoice-out/";
+ String bookingPath = workitem.getItemValueString("invoice.bookingperiod");
+ targetPath = targetPath + bookingPath.substring(0, 4) + "/" + bookingPath.substring(4);
+ }
- workitem.setItemValue("ftp.target.path", targetPath + "/");
- }
+ workitem.setItemValue("ftp.target.path", targetPath + "/");
+ }
- }
+ }
- return workitem;
- }
+ return workitem;
+ }
- /**
- * Baut einen Filenamen aus verschiedenen Attributen zusammen.
- *
- *
- * @param workitem
- * @return
- */
- private String buildFileName(String fileName, ItemCollection workitem, int counter) {
- String result = workitem.getItemValueString("sequencenumber") + "_";
+ /**
+ * Baut einen Filenamen aus verschiedenen Attributen zusammen.
+ *
+ *
+ * @param workitem
+ * @return
+ */
+ private String buildFileName(String fileName, ItemCollection workitem, int counter) {
+ String result = workitem.getItemValueString("sequencenumber") + "_";
- if (InvoiceUtil.isSachrechnung(workitem)) {
- result = result + workitem.getItemValueString("invoice.number.stripped");
- } else {
- // für ausgangsrechnungen skippen wir die Cargosoft XML Datei
- if (fileName.toLowerCase().endsWith(".xml")) {
- return fileName;
- }
- // für die PDF Datei bauen wir einen neuen Namen
- result = result + workitem.getItemValueString("invoice.positions");
- }
- if (counter > 0) {
- result = result + "_" + counter;
- }
- result = result + fileName.substring(fileName.lastIndexOf("."));
+ if (InvoiceUtil.isSachrechnung(workitem)) {
+ result = result + workitem.getItemValueString("invoice.number.stripped");
+ } else {
+ // für ausgangsrechnungen skippen wir die Cargosoft XML Datei
+ if (fileName.toLowerCase().endsWith(".xml")) {
+ return fileName;
+ }
+ // für die PDF Datei bauen wir einen neuen Namen
+ result = result + workitem.getItemValueString("invoice.positions");
+ }
+ if (counter > 0) {
+ result = result + "_" + counter;
+ }
+ result = result + fileName.substring(fileName.lastIndexOf("."));
- return result;
- }
+ return result;
+ }
}
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/SEPAExportControllerAGL.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/SEPAExportControllerAGL.java
index 3de738c..d7d71e9 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/SEPAExportControllerAGL.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/SEPAExportControllerAGL.java
@@ -14,10 +14,10 @@ import jakarta.inject.Inject;
import jakarta.inject.Named;
/**
- * Der SEPAExportControllerAGL dient dazu die IBAN/BIC einstellungen in
- * einem SEPA Export zu aktualiseren. Er wird von der Form
- * sepa_export.xhtml aus per Ajax angesteuert.
- *
+ * Der SEPAExportControllerAGL dient dazu die IBAN/BIC einstellungen in einem
+ * SEPA Export zu aktualiseren. Er wird von der Form sepa_export.xhtml aus per
+ * Ajax angesteuert.
+ *
* @author rsoika
*
*/
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/SteuerListController.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/SteuerListController.java
index 5b1ce41..dd2334a 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/SteuerListController.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/SteuerListController.java
@@ -12,9 +12,9 @@ import jakarta.inject.Inject;
import jakarta.inject.Named;
/**
- * Der SteuerListController dient dazu in einem Stuerbescheid
- * die einzelnen Zeilen auszugeben.
- *
+ * Der SteuerListController dient dazu in einem Stuerbescheid die einzelnen
+ * Zeilen auszugeben.
+ *
* @author rsoika
*
*/
@@ -32,7 +32,7 @@ public class SteuerListController implements Serializable {
/**
* Gibt die Zeilen aus einem importierten Steuerbeleg (eAkte) zurück
- *
+ *
* @return
*/
public List getRows() {
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/SteuerbescheidPlugin.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/SteuerbescheidPlugin.java
index dc0aa00..7430eb9 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/SteuerbescheidPlugin.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/SteuerbescheidPlugin.java
@@ -15,165 +15,161 @@ import jakarta.inject.Inject;
/**
* Das SteuerbescheidPlugin prüft ob
- *
+ *
* - die ATC Nummer aus dem Steuerbescheid in einer Ausgangsrechnung gefunden
- * wird ($taskID<5990)
- * - invoice.atc.number
- * - der Betrag "invoice.total.net"
- * - die Währung???
- * - die Positionsnummer ???
- *
- *
+ * wird ($taskID<5990) - invoice.atc.number - der Betrag "invoice.total.net" -
+ * die Währung??? - die Positionsnummer ???
+ *
+ *
* @author rsoika
* @version 1.0
- *
+ *
*/
public class SteuerbescheidPlugin extends AbstractPlugin {
- private static Logger logger = Logger.getLogger(SteuerbescheidPlugin.class.getName());
+ private static Logger logger = Logger.getLogger(SteuerbescheidPlugin.class.getName());
- @Inject
- protected DocumentService documentService;
+ @Inject
+ protected DocumentService documentService;
- /**
- * Prüft ob der Steuerbetrag abgerechnet ist.
- *
- *
- **/
- @Override
- public ItemCollection run(ItemCollection workitem, ItemCollection event) throws PluginException {
+ /**
+ * Prüft ob der Steuerbetrag abgerechnet ist.
+ *
+ *
+ **/
+ @Override
+ public ItemCollection run(ItemCollection workitem, ItemCollection event) throws PluginException {
- // Update Fälligkeit
- updateFaelligkeit(workitem);
+ // Update Fälligkeit
+ updateFaelligkeit(workitem);
- // Update Salden
- updateTotalEustZoll(workitem);
- updateInvoiceSaldo(workitem);
+ // Update Salden
+ updateTotalEustZoll(workitem);
+ updateInvoiceSaldo(workitem);
- return workitem;
- }
+ return workitem;
+ }
- /**
- * Aktualisiert die EUST/ZOLL Summen
- *
- */
- protected void updateTotalEustZoll(ItemCollection workitem) {
+ /**
+ * Aktualisiert die EUST/ZOLL Summen
+ *
+ */
+ protected void updateTotalEustZoll(ItemCollection workitem) {
- double saldoEust = 0;
- double saldoZoll = 0;
- List positionsTabelle = InvoiceUtil.explodeChildList(workitem);
- for (ItemCollection pos : positionsTabelle) {
- if ("EUST".equalsIgnoreCase(pos.getItemValueString("activity.type"))) {
- saldoEust = saldoEust + pos.getItemValueDouble("amount");
- }
- if ("ZOLL".equalsIgnoreCase(pos.getItemValueString("activity.type"))) {
- saldoZoll = saldoZoll + pos.getItemValueDouble("amount");
- }
- }
+ double saldoEust = 0;
+ double saldoZoll = 0;
+ List positionsTabelle = InvoiceUtil.explodeChildList(workitem);
+ for (ItemCollection pos : positionsTabelle) {
+ if ("EUST".equalsIgnoreCase(pos.getItemValueString("activity.type"))) {
+ saldoEust = saldoEust + pos.getItemValueDouble("amount");
+ }
+ if ("ZOLL".equalsIgnoreCase(pos.getItemValueString("activity.type"))) {
+ saldoZoll = saldoZoll + pos.getItemValueDouble("amount");
+ }
+ }
- workitem.setItemValue("steuer.eust", saldoEust);
- workitem.setItemValue("steuer.zoll", saldoZoll);
+ workitem.setItemValue("steuer.eust", saldoEust);
+ workitem.setItemValue("steuer.zoll", saldoZoll);
- }
+ }
- /**
- * Aktualisiert die EUST/ZOLL Fälligkeiten in den Detailtabellen
- * Die Daten kommen von der KI und werden auf die Positionsnummern gemappt.
- *
- */
- protected void updateFaelligkeit(ItemCollection workitem) {
+ /**
+ * Aktualisiert die EUST/ZOLL Fälligkeiten in den Detailtabellen Die Daten
+ * kommen von der KI und werden auf die Positionsnummern gemappt.
+ *
+ */
+ protected void updateFaelligkeit(ItemCollection workitem) {
- boolean foundZoll = false;
- boolean foundEust = false;
- Date datEust = null;
- Date datZoll = null;
- // resolve datEust und datZoll from steuerbescheid.positionen ChildItems....
- List steuerPositionen = InvoiceUtil.explodeChildList(workitem, "steuerbescheid.position");
- for (ItemCollection steuerPos : steuerPositionen) {
- if (steuerPos.getItemValueString("key").startsWith("A")) {
- datZoll = steuerPos.getItemValueDate("duedate");
- }
- if (steuerPos.getItemValueString("key").startsWith("B")) {
- datEust = steuerPos.getItemValueDate("duedate");
- }
- }
+ boolean foundZoll = false;
+ boolean foundEust = false;
+ Date datEust = null;
+ Date datZoll = null;
+ // resolve datEust und datZoll from steuerbescheid.positionen ChildItems....
+ List steuerPositionen = InvoiceUtil.explodeChildList(workitem, "steuerbescheid.position");
+ for (ItemCollection steuerPos : steuerPositionen) {
+ if (steuerPos.getItemValueString("key").startsWith("A")) {
+ datZoll = steuerPos.getItemValueDate("duedate");
+ }
+ if (steuerPos.getItemValueString("key").startsWith("B")) {
+ datEust = steuerPos.getItemValueDate("duedate");
+ }
+ }
- // Map fälligkeit auf die Cargosoft Positionen
- List rows = InvoiceUtil.explodeChildList(workitem);
- for (ItemCollection pos : rows) {
- if (datZoll != null && "ZOLL".equalsIgnoreCase(pos.getItemValueString("activity.type"))) {
- pos.setItemValue("duedate", datZoll);
- foundZoll = true;
- }
- if (datEust != null && "EUST".equalsIgnoreCase(pos.getItemValueString("activity.type"))) {
- pos.setItemValue("duedate", datEust);
- foundEust = true;
- }
- }
+ // Map fälligkeit auf die Cargosoft Positionen
+ List rows = InvoiceUtil.explodeChildList(workitem);
+ for (ItemCollection pos : rows) {
+ if (datZoll != null && "ZOLL".equalsIgnoreCase(pos.getItemValueString("activity.type"))) {
+ pos.setItemValue("duedate", datZoll);
+ foundZoll = true;
+ }
+ if (datEust != null && "EUST".equalsIgnoreCase(pos.getItemValueString("activity.type"))) {
+ pos.setItemValue("duedate", datEust);
+ foundEust = true;
+ }
+ }
- if (foundEust) {
- workitem.setItemValue("steuer.eust.due", datEust);
- } else {
- workitem.removeItem("steuer.eust.due");
- }
- if (foundZoll) {
- workitem.setItemValue("steuer.zoll.due", datZoll);
- } else {
- workitem.removeItem("steuer.zoll.due");
- }
- InvoiceUtil.implodeChildList(workitem, rows);
- }
+ if (foundEust) {
+ workitem.setItemValue("steuer.eust.due", datEust);
+ } else {
+ workitem.removeItem("steuer.eust.due");
+ }
+ if (foundZoll) {
+ workitem.setItemValue("steuer.zoll.due", datZoll);
+ } else {
+ workitem.removeItem("steuer.zoll.due");
+ }
+ InvoiceUtil.implodeChildList(workitem, rows);
+ }
- /**
- * Aktualisiert den invoice.saldo anhand der ausgehenden Rechnungen zu einer ATC
- * Nummer
- *
- */
- protected void updateInvoiceSaldo(ItemCollection workitem) {
+ /**
+ * Aktualisiert den invoice.saldo anhand der ausgehenden Rechnungen zu einer ATC
+ * Nummer
+ *
+ */
+ protected void updateInvoiceSaldo(ItemCollection workitem) {
- String atcNummer = workitem.getItemValueString("invoice.atc.number");
- logger.fine("Verify ATC-Nr.: " + atcNummer);
- double amount = workitem.getItemValueDouble("invoice.total.net");
- List invoices = findInvoices(atcNummer);
+ String atcNummer = workitem.getItemValueString("invoice.atc.number");
+ logger.fine("Verify ATC-Nr.: " + atcNummer);
+ double amount = workitem.getItemValueDouble("invoice.total.net");
+ List invoices = findInvoices(atcNummer);
- // Beträge subtrahieren....
- double saldo = amount;
- logger.info("Found " + invoices.size() + " matching invoices...");
- for (ItemCollection invoice : invoices) {
- workitem.setItemValueUnique("$workitemRef", invoice.getUniqueID());
+ // Beträge subtrahieren....
+ double saldo = amount;
+ logger.info("Found " + invoices.size() + " matching invoices...");
+ for (ItemCollection invoice : invoices) {
+ workitem.setItemValueUnique("$workitemRef", invoice.getUniqueID());
- // suche die Zeile in der die ATC Nummer vorkommt.
- List positionen = InvoiceUtil.explodeChildList(invoice);
- for (ItemCollection pos : positionen) {
- if (atcNummer.equals(pos.getItemValueString("atc.number"))) {
- double umsatz = pos.getItemValueDouble("datev.umsatz");
- logger.info("...Umsatz=" + umsatz);
- saldo = InvoiceUtil.round(saldo - umsatz);
- }
- }
- }
+ // suche die Zeile in der die ATC Nummer vorkommt.
+ List positionen = InvoiceUtil.explodeChildList(invoice);
+ for (ItemCollection pos : positionen) {
+ if (atcNummer.equals(pos.getItemValueString("atc.number"))) {
+ double umsatz = pos.getItemValueDouble("datev.umsatz");
+ logger.info("...Umsatz=" + umsatz);
+ saldo = InvoiceUtil.round(saldo - umsatz);
+ }
+ }
+ }
- // Update Saldo
- workitem.setItemValue("invoice.saldo", InvoiceUtil.round(saldo));
+ // Update Saldo
+ workitem.setItemValue("invoice.saldo", InvoiceUtil.round(saldo));
- }
+ }
- /*
- * Sucht alle Ausgansrechnungen zu einer ATC Nummer
- */
- protected List findInvoices(String atcNumber) {
- List result = new ArrayList();
- String query = "(type:workitem OR type:workitemarchive) AND ($taskid:[5000 TO 5990])"
- + " AND invoice.atc.number:\"" + atcNumber + "\" "
- + " AND $workflowgroup:\"Rechnungsausgang\" ";
- try {
- result = documentService.find(query, 999, 0, "$created", false);
- return result;
- } catch (QueryException e) {
- logger.severe("Failed to get invoices: " + e.getMessage());
- }
+ /*
+ * Sucht alle Ausgansrechnungen zu einer ATC Nummer
+ */
+ protected List findInvoices(String atcNumber) {
+ List result = new ArrayList();
+ String query = "(type:workitem OR type:workitemarchive) AND ($taskid:[5000 TO 5990])"
+ + " AND invoice.atc.number:\"" + atcNumber + "\" " + " AND $workflowgroup:\"Rechnungsausgang\" ";
+ try {
+ result = documentService.find(query, 999, 0, "$created", false);
+ return result;
+ } catch (QueryException e) {
+ logger.severe("Failed to get invoices: " + e.getMessage());
+ }
- return result;
- }
+ return result;
+ }
}
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/ZahlungsavisAppendAdapter.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/ZahlungsavisAppendAdapter.java
index 9dda062..e2eba98 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/ZahlungsavisAppendAdapter.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/ZahlungsavisAppendAdapter.java
@@ -21,9 +21,9 @@ import jakarta.inject.Inject;
* Kredito erzeugt der Adapter automatisch eine neue Prozessinstanz.
*
* Wurde die Rechnugn bereits einem Zahlungsavis zugeordnet passiert nichts.
- *
- *
- *
+ *
+ *
+ *
* @version 1.0
* @author rsoika
*/
@@ -40,7 +40,7 @@ public class ZahlungsavisAppendAdapter implements SignalAdapter {
/**
* This method finds or create the Zahlungsavis and adds a reference
* ($workitemref) to the current invoice.
- *
+ *
* @throws PluginException
*/
@Override
@@ -54,7 +54,7 @@ public class ZahlungsavisAppendAdapter implements SignalAdapter {
/**
* Diese method hängt eine referenz der aktuellen Rechnung an den Zahlungsavis
- *
+ *
* @param document
* @throws PluginException
*/
@@ -100,7 +100,7 @@ public class ZahlungsavisAppendAdapter implements SignalAdapter {
/**
* Prüft alle offenen Zahlugnsaviss und gibt den neuesten zur angegebenen
* cdrNumber zurück, oder null falls es keinen Offenen Zahlungsavis gibt.
- *
+ *
* @param cdrNumber
* @return
* @throws QueryException
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/ZahlungsavisController.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/ZahlungsavisController.java
index 0e98a34..5ee511d 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/ZahlungsavisController.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/ZahlungsavisController.java
@@ -18,7 +18,7 @@ import jakarta.inject.Named;
*
* Zusätzlich bietet er die Summenberechnung an, bei der die Gutschriften
* abgezogen werden.
- *
+ *
* @author rsoika
*
*/
@@ -41,7 +41,7 @@ public class ZahlungsavisController implements Serializable {
* result is rounded to 2 digits.
*
* Gutschriften werden abgezogen
- *
+ *
* @param refids - list of workitem uniqueIds
* @param item - name of the item to summarize
* @return sum rounded to 2 digits
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/ZahlungsavisExportAdapter.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/ZahlungsavisExportAdapter.java
index 7904a7b..2eaeebb 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/ZahlungsavisExportAdapter.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/ZahlungsavisExportAdapter.java
@@ -27,7 +27,7 @@ import jakarta.inject.Inject;
/**
* Der ZahlungsavisAdapter importiert eine Excel Datei aus einem Textblock
- *
+ *
*
* Der Adapter erweitert den POIAdapter somit können felder aktualisiert werden
* (siehe POIFineReplaceAdapter).
- *
+ *
*
* Der Adapter kopiert die Rechnungsdaten in neue Zeilen, welche ab Zeilnenummer
* 16 eingefügt werden.
@@ -46,7 +46,7 @@ import jakarta.inject.Inject;
* Dabei werden Gutschriften in spalte E und Rechnungen in Spalte F eingetrgen.
*
* Abschliessend wird die Zelle 'TOTAL' noch aktualisiert.
- *
+ *
* @version 1.0
* @author rsoika
*/
@@ -69,7 +69,7 @@ public class ZahlungsavisExportAdapter extends POIFindReplaceAdapter {
/**
* This method finds or create the Zahlungsavis and adds a reference
* ($workitemref) to the current invoice.
- *
+ *
* @throws PluginException
*/
@SuppressWarnings("unchecked")
@@ -121,7 +121,7 @@ public class ZahlungsavisExportAdapter extends POIFindReplaceAdapter {
*
* The named cell 'TOTAL' should contain the summary formula. It will be
* evaluated at the end.
- *
+ *
* @throws PluginException
*/
@SuppressWarnings("unchecked")
@@ -193,7 +193,7 @@ public class ZahlungsavisExportAdapter extends POIFindReplaceAdapter {
/**
* This method loads a text-block for a specified ref and appends the named
* fileData object of this document.
- *
+ *
* @param document
* @throws PluginException
*/
@@ -223,9 +223,9 @@ public class ZahlungsavisExportAdapter extends POIFindReplaceAdapter {
/**
* This method returns a text-block ItemCollection for a specified name.
- *
+ *
* @param name in attribute txtname
- *
+ *
*
*/
public FileData loadTextBlockFileData(String name, String fileName) {
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/ZahlungseingangSaldoAdapter.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/ZahlungseingangSaldoAdapter.java
index cf049d3..27c9809 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/ZahlungseingangSaldoAdapter.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/ZahlungseingangSaldoAdapter.java
@@ -28,7 +28,7 @@ import jakarta.inject.Inject;
*
payment.amount
*
* com.alexanderlogistics.ZahlungseingangSaldoAdapter
- *
+ *
* @version 1.0
* @author rsoika
*/
@@ -51,7 +51,7 @@ public class ZahlungseingangSaldoAdapter implements SignalAdapter {
/**
* This method finds the outgoing invoices and updates the saldo
* (payment.total).
- *
+ *
* @throws PluginException
*/
@Override
@@ -72,7 +72,7 @@ public class ZahlungseingangSaldoAdapter implements SignalAdapter {
/**
* Diese methode aktuallisiert alle referenzen der aktuellen Rechnungen
- *
+ *
* @param workitem
* @throws PluginException
*/
@@ -127,13 +127,11 @@ public class ZahlungseingangSaldoAdapter implements SignalAdapter {
String mainCurrency = invoiceService.getCurrenciesOutMain();
if ((!invoiceCurrency.equals(paymentCurrency))
- && (!invoiceCurrency.equals(mainCurrency) &&
- !paymentCurrency.equals(mainCurrency))) {
+ && (!invoiceCurrency.equals(mainCurrency) && !paymentCurrency.equals(mainCurrency))) {
String message = resourceBundleHandler.findMessage("ERROR_PAYMENT4");
message = message.replace("{1}", mainCurrency);
throw new PluginException(PluginException.class.getName(),
- ZahlungseingangService.ERROR_PAYMENT_BOOKING_FAILED,
- message);
+ ZahlungseingangService.ERROR_PAYMENT_BOOKING_FAILED, message);
}
if (!invoiceCurrency.equals(paymentCurrency)) {
@@ -142,8 +140,7 @@ public class ZahlungseingangSaldoAdapter implements SignalAdapter {
message = message.replace("{1}", paymentCurrency);
message = message.replace("{2}", invoiceNumber);
throw new PluginException(PluginException.class.getName(),
- ZahlungseingangService.ERROR_PAYMENT_BOOKING_FAILED,
- message);
+ ZahlungseingangService.ERROR_PAYMENT_BOOKING_FAILED, message);
}
}
@@ -151,8 +148,7 @@ public class ZahlungseingangSaldoAdapter implements SignalAdapter {
* Falls die Währung der Rechnung von der Währung der Zahlung abweicht, dann
* rechnen wir den PaymentAmmout mit der Rate aus.
*/
- if ("EUR".equals(paymentCurrency) &&
- !invoiceCurrency.equals(paymentCurrency) && invoiceRate != 0) {
+ if ("EUR".equals(paymentCurrency) && !invoiceCurrency.equals(paymentCurrency) && invoiceRate != 0) {
invoicePaymentAmount = invoicePaymentAmount * invoiceRate;
// runde auf 2 Stellen
invoicePaymentAmount = (float) InvoiceUtil.round(invoicePaymentAmount);
@@ -213,7 +209,7 @@ public class ZahlungseingangSaldoAdapter implements SignalAdapter {
/**
* Returns true wenn der Zahlungseingang bereits gebucht ist
- *
+ *
* @param workitem
* @return
*/
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/ZahlungseingangService.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/ZahlungseingangService.java
index 542a180..365c85c 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/ZahlungseingangService.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/ZahlungseingangService.java
@@ -1,26 +1,26 @@
/*******************************************************************************
- * Imixs Workflow
- * Copyright (C) 2001, 2011 Imixs Software Solutions GmbH,
+ * Imixs Workflow
+ * Copyright (C) 2001, 2011 Imixs Software Solutions GmbH,
* http://www.imixs.com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
- *
+ *
* You can receive a copy of the GNU General Public
* License at http://www.gnu.org/licenses/gpl.html
- *
- * Project:
+ *
+ * Project:
* http://www.imixs.org
* http://java.net/projects/imixs-workflow
- *
- * Contributors:
+ *
+ * Contributors:
* Imixs Software Solutions GmbH - initial API and implementation
* Ralph Soika - Software Developer
*******************************************************************************/
@@ -49,9 +49,9 @@ import jakarta.inject.Inject;
/**
* Der ZahlungseingangService wird vom ZahlungseingangSaldoAdapter verwendet um
* Ausgangsrechnungen zu akutalisieren.
- *
+ *
* @author rsoika
- *
+ *
*/
@DeclareRoles({ "org.imixs.ACCESSLEVEL.NOACCESS", "org.imixs.ACCESSLEVEL.READERACCESS",
@@ -79,7 +79,7 @@ public class ZahlungseingangService {
/**
* Diese Method sucht eine Invoice mit Manager Rechnten
- *
+ *
* @throws PluginException
*/
public ItemCollection findInvoice(String id) throws PluginException {
@@ -89,7 +89,7 @@ public class ZahlungseingangService {
/**
* * Diese Method processed eine Invoice mit Manager Rechnten
- *
+ *
* @throws PluginException
* @throws ModelException
* @throws ProcessingErrorException
@@ -106,10 +106,10 @@ public class ZahlungseingangService {
/**
* The method returns a List of ItemCollection holding the payment details
- *
- *
+ *
+ *
* Convert the List of ItemCollections back into a List of Map elements
- *
+ *
* @param invoice
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/ai/PromptExampleAdapterXML.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/ai/PromptExampleAdapterXML.java
index 243bd2e..ff0f15f 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/ai/PromptExampleAdapterXML.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/ai/PromptExampleAdapterXML.java
@@ -15,23 +15,23 @@ import jakarta.enterprise.event.Observes;
import jakarta.inject.Inject;
/**
- * The PromptExampleAdapterXML is a CDI bean that creates XML examples based
- * on the last 3 invoices.
- *
+ * The PromptExampleAdapterXML is a CDI bean that creates XML examples based on
+ * the last 3 invoices.
+ *
* The adapter only runs if the prompt template contains
- *
+ *
* <>
- *
+ *
* Prompt example generated by this Adapter:
- *
+ *
* Example:
- *
+ *
*
* {@code
* 1. Company Data:
* - Name and address of the supplier
* - Supplier contact information (phone number, email, etc.)
- *
+ *
* 2. Invoice Data:
* - Invoice number
* - Invoice date
@@ -41,7 +41,7 @@ import jakarta.inject.Inject;
*
*
* ...
- * ...
+ * ...
* 2024-12-31
* 2024-12-31
* 1234.00
@@ -50,7 +50,7 @@ import jakarta.inject.Inject;
*
* }
*
- *
+ *
*/
public class PromptExampleAdapterXML {
private static Logger logger = Logger.getLogger(PromptExampleAdapterXML.class.getName());
@@ -79,8 +79,7 @@ public class PromptExampleAdapterXML {
if (invoices != null && invoices.size() > 0) {
// Build an example for each invoice
for (ItemCollection invoice : invoices) {
- promptExamples = promptExamples + buildExampleDE(invoice, exampleHeaderData,
- exampleHeaderXML);
+ promptExamples = promptExamples + buildExampleDE(invoice, exampleHeaderData, exampleHeaderXML);
}
}
prompt = prompt.replace("<>", "" + promptExamples);
@@ -91,13 +90,13 @@ public class PromptExampleAdapterXML {
/**
* Helper Method that builds a prompt example out of an existing invoice:
- *
+ *
*
- *
+ *
* @param invoice
* @return
*/
@@ -126,14 +125,12 @@ public class PromptExampleAdapterXML {
example.append(
" " + invoice.getItemValueString("invoice.number") + "\n");
if (invoice.getItemValueDate("invoice.date") != null) {
- example.append(
- " " + dateFormat.format(invoice.getItemValueDate("invoice.date"))
- + "\n");
+ example.append(" " + dateFormat.format(invoice.getItemValueDate("invoice.date"))
+ + "\n");
}
if (invoice.getItemValueDate("invoice.duedate") != null) {
- example.append(
- " " + dateFormat.format(invoice.getItemValueDate("invoice.duedate"))
- + "\n");
+ example.append(" " + dateFormat.format(invoice.getItemValueDate("invoice.duedate"))
+ + "\n");
}
example.append(" " + invoice.getItemValueDouble("invoice.total")
+ "\n");
@@ -146,7 +143,7 @@ public class PromptExampleAdapterXML {
/**
* Helper method to find the last 3 invoices by cdtr.name
- *
+ *
* @param cdtrName
* @return
*/
@@ -154,8 +151,7 @@ public class PromptExampleAdapterXML {
List result = new ArrayList<>();
String searchTerm = "(type:workitemarchive) AND ($modelversion:rechnungseingang*) AND ($taskid:5900) AND NOT ($uniqueid:"
- + currentID + ") AND (document.company:\""
- + companyName + "\")";
+ + currentID + ") AND (document.company:\"" + companyName + "\")";
try {
result = documentService.find(searchTerm, 3, 0, "$modified", true);
} catch (QueryException e) {
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/api/CargosoftMigrationRestService.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/api/CargosoftMigrationRestService.java
index 38c757c..333750d 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/api/CargosoftMigrationRestService.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/api/CargosoftMigrationRestService.java
@@ -1,26 +1,26 @@
/*******************************************************************************
- * Imixs Workflow
- * Copyright (C) 2001, 2011 Imixs Software Solutions GmbH,
+ * Imixs Workflow
+ * Copyright (C) 2001, 2011 Imixs Software Solutions GmbH,
* http://www.imixs.com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
- *
+ *
* You can receive a copy of the GNU General Public
* License at http://www.gnu.org/licenses/gpl.html
- *
- * Project:
+ *
+ * Project:
* http://www.imixs.org
* http://java.net/projects/imixs-workflow
- *
- * Contributors:
+ *
+ * Contributors:
* Imixs Software Solutions GmbH - initial API and implementation
* Ralph Soika - Software Developer
*******************************************************************************/
@@ -60,9 +60,9 @@ import jakarta.ws.rs.core.MediaType;
/**
** Dieser Service korrigiert falsch importierte Cargosoft daten.
* Ausgangsrechnungen die ein falsches Jahr haben.
- *
+ *
* Oder DAten die über die XML Schnittstelle falsch reinkamen...
- *
+ *
* @author rsoika
* @version 1.1
*/
@@ -109,12 +109,12 @@ public class CargosoftMigrationRestService implements Serializable {
* Dieser agent speichert einfach alle Cargosoft Krediotren/Debitoren Daten ,
* was dann zur automatischen Neuanlage bzw. aktualisierung des businesspartner
* workflows führt.
- *
- *
+ *
+ *
* curl -H "Cookie:
* JSESSIONID=ShAegfNiXmqLFLSFwcUZ7hrLLQDKZGKiu4oj_xeX.imixs-office-workflow-8586d7d58d-h6k4q"
* https://alexander-logistics-dwc.office-workflow.de/api/cargosoft/bp-sync?maxcount=1000
- *
+ *
* @return
* @throws QueryException
* @throws AccessDeniedException
@@ -145,8 +145,7 @@ public class CargosoftMigrationRestService implements Serializable {
isRunning = true;
int totalCount = documentService.count(query);
- log("│ ├── found " + totalCount + " cargosoft entries",
- messageBuffer);
+ log("│ ├── found " + totalCount + " cargosoft entries", messageBuffer);
// Berechne Anzahl der benötigten Pages
int totalPages = (int) Math.ceil((double) totalCount / batchSize);
@@ -169,8 +168,8 @@ public class CargosoftMigrationRestService implements Serializable {
}
// Fortschritt loggen
- log("│ ├── Processed page " + (pageIndex + 1) + " of " + totalPages +
- " (" + totalObjects + " objects read, " + syncs + " total syncs)", messageBuffer);
+ log("│ ├── Processed page " + (pageIndex + 1) + " of " + totalPages + " (" + totalObjects
+ + " objects read, " + syncs + " total syncs)", messageBuffer);
// Optional: Kurze Pause nach jedem 5. Batch
try {
Thread.sleep(100);
@@ -185,8 +184,8 @@ public class CargosoftMigrationRestService implements Serializable {
}
long duration = System.currentTimeMillis() - l;
double objectsPerSecond = totalObjects / (duration / 1000.0);
- log("├── Successfully " + syncs + " business partner objects synced in " +
- duration + "ms (" + String.format("%.1f", objectsPerSecond) + " objects/sec)", messageBuffer);
+ log("├── Successfully " + syncs + " business partner objects synced in " + duration + "ms ("
+ + String.format("%.1f", objectsPerSecond) + " objects/sec)", messageBuffer);
isRunning = false;
return messageBuffer.toString();
@@ -194,7 +193,7 @@ public class CargosoftMigrationRestService implements Serializable {
/**
* Hilfsmethode speichert eine cargoosft kreditor object...
- *
+ *
* @param bpID
* @param messageBuffer
* @return
@@ -213,11 +212,11 @@ public class CargosoftMigrationRestService implements Serializable {
/**
* Dieser agent löscht einfach alle Businesspartner objekte. Wird eigentlich
* nicht mehr benötigt.
- *
+ *
* curl -H "Cookie:
* JSESSIONID=ShAegfNiXmqLFLSFwcUZ7hrLLQDKZGKiu4oj_xeX.imixs-office-workflow-8586d7d58d-h6k4q"
* https://alexander-logistics-dwc.office-workflow.de/api/cargosoft/bp-delete?maxcount=10000
- *
+ *
* @return
* @throws QueryException
* @throws AccessDeniedException
@@ -273,8 +272,8 @@ public class CargosoftMigrationRestService implements Serializable {
// Fortschritt loggen
iterations++;
- log("│ ├── Processed page " + (iterations) + " of " + totalPages +
- " (" + deletions + " total deletions)", messageBuffer);
+ log("│ ├── Processed page " + (iterations) + " of " + totalPages + " (" + deletions + " total deletions)",
+ messageBuffer);
// Optional: Kurze Pause nach jedem 5. Batch
try {
@@ -290,8 +289,8 @@ public class CargosoftMigrationRestService implements Serializable {
}
long duration = System.currentTimeMillis() - l;
double objectsPerSecond = totalObjects / (duration / 1000.0);
- log("├── Successfully " + deletions + " business partner objects deleted in " +
- duration + "ms (" + String.format("%.1f", objectsPerSecond) + " objects/sec)", messageBuffer);
+ log("├── Successfully " + deletions + " business partner objects deleted in " + duration + "ms ("
+ + String.format("%.1f", objectsPerSecond) + " objects/sec)", messageBuffer);
isRunning = false;
return messageBuffer.toString();
@@ -299,7 +298,7 @@ public class CargosoftMigrationRestService implements Serializable {
/**
* Entfernt doppelte Eintrage - sind irgnedwie entstandnen :(((
- *
+ *
* @return
* @throws QueryException
* @throws AccessDeniedException
@@ -373,8 +372,8 @@ public class CargosoftMigrationRestService implements Serializable {
// Fortschritt loggen
// Fortschritt loggen
- log("│ ├── Processed page " + (pageIndex + 1) + " of " + totalPages +
- " (" + deletions + " total deletions)", messageBuffer);
+ log("│ ├── Processed page " + (pageIndex + 1) + " of " + totalPages + " (" + deletions
+ + " total deletions)", messageBuffer);
// Optional: Kurze Pause nach jedem 5. Batch
try {
Thread.sleep(100);
@@ -389,8 +388,8 @@ public class CargosoftMigrationRestService implements Serializable {
}
long duration = System.currentTimeMillis() - l;
double objectsPerSecond = totalObjects / (duration / 1000.0);
- log("├── Successfully " + deletions + " duplicated cargosoft objects deleted in " +
- duration + "ms (" + String.format("%.1f", objectsPerSecond) + " objects/sec)", messageBuffer);
+ log("├── Successfully " + deletions + " duplicated cargosoft objects deleted in " + duration + "ms ("
+ + String.format("%.1f", objectsPerSecond) + " objects/sec)", messageBuffer);
isRunning = false;
return messageBuffer.toString();
@@ -398,7 +397,7 @@ public class CargosoftMigrationRestService implements Serializable {
/**
* Hilfsmethode - löscht ein cargoosoft object...
- *
+ *
* @param bpID
* @param messageBuffer
* @return
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/api/DataRestService.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/api/DataRestService.java
index 5194d52..450b3f3 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/api/DataRestService.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/api/DataRestService.java
@@ -1,27 +1,27 @@
-/*
- * Imixs-Workflow
- *
- * Copyright (C) 2001-2020 Imixs Software Solutions GmbH,
+/*
+ * Imixs-Workflow
+ *
+ * Copyright (C) 2001-2020 Imixs Software Solutions GmbH,
* http://www.imixs.com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
- *
+ *
* You can receive a copy of the GNU General Public
* License at http://www.gnu.org/licenses/gpl.html
- *
- * Project:
+ *
+ * Project:
* https://www.imixs.org
* https://github.com/imixs/imixs-workflow
- *
- * Contributors:
+ *
+ * Contributors:
* Imixs Software Solutions GmbH - Project Management
* Ralph Soika - Software Developer
*/
@@ -58,7 +58,7 @@ import jakarta.ws.rs.core.Response;
/**
* The api endpoint '/data' provides methods to read and post data via a access
* token
- *
+ *
* @version 1.0
* @author rsoika
*
@@ -87,7 +87,7 @@ public class DataRestService {
/**
* Test method
- *
+ *
* @param workflowgroup
* @param task
* @return
@@ -132,16 +132,14 @@ public class DataRestService {
* this token to the service.
*
* The method tests the access. If it is not possible the method returns null.
- *
+ *
* @see DefaultAuthenicator
* @return
*/
protected Client createClient(String serviceAPI, String sessionID) {
// Create a Cookie object with a name and a value
- Cookie cookie = new Cookie.Builder("JSESSIONID")
- .value(sessionID)
- .path("/")
+ Cookie cookie = new Cookie.Builder("JSESSIONID").value(sessionID).path("/")
// .domain("domain.com")
.build();
@@ -173,7 +171,7 @@ public class DataRestService {
/**
* Searches a report by name
- *
+ *
* @param name
* @return
* @throws UnsupportedEncodingException
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/datev/CargosoftExportController.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/datev/CargosoftExportController.java
index b2efbf2..910abb5 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/datev/CargosoftExportController.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/datev/CargosoftExportController.java
@@ -2,26 +2,26 @@ package com.alexanderlogistics.datev;
/*******************************************************************************
* Imixs Workflow Technology
- * Copyright (C) 2003, 2008 Imixs Software Solutions GmbH,
+ * Copyright (C) 2003, 2008 Imixs Software Solutions GmbH,
* http://www.imixs.com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
- *
+ *
* You can receive a copy of the GNU General Public
* License at http://www.gnu.org/licenses/gpl.html
- *
- * Contributors:
+ *
+ * Contributors:
* Imixs Software Solutions GmbH - initial API and implementation
* Ralph Soika
- *
+ *
*******************************************************************************/
import java.util.logging.Logger;
@@ -39,43 +39,43 @@ import jakarta.inject.Named;
* txtname=datev".
*
* The following config items are defined:
- *
+ *
* The following config items are defined:
- *
+ *
*
* _model_version = model version for the SEPA export
* _initial_task = inital task ID
*
- *
- *
+ *
+ *
* @author rsoika
- *
+ *
*/
@Named
@RequestScoped
public class CargosoftExportController extends SchedulerController {
- public static final String CARGOSOFT_EXPORT_CONFIGURATION = "CARGOSOFT_EXPORT_CONFIGURATION";
+ public static final String CARGOSOFT_EXPORT_CONFIGURATION = "CARGOSOFT_EXPORT_CONFIGURATION";
- private static final long serialVersionUID = 1L;
- private static Logger logger = Logger.getLogger(CargosoftExportController.class.getName());
+ private static final long serialVersionUID = 1L;
+ private static Logger logger = Logger.getLogger(CargosoftExportController.class.getName());
- @Override
- public String getName() {
- return CARGOSOFT_EXPORT_CONFIGURATION;
- }
+ @Override
+ public String getName() {
+ return CARGOSOFT_EXPORT_CONFIGURATION;
+ }
- /**
- * Returns the sepa scheduler class name. This name depends on the _export_type.
- *
- * There are two export interfaces available - csv and XML
- *
- */
- @Override
- public String getSchedulerClass() {
- String schedulerClass = CargosoftExportScheduler.class.getName();
- logger.finest("...... scheduler: " + schedulerClass);
- return schedulerClass;
- }
+ /**
+ * Returns the sepa scheduler class name. This name depends on the _export_type.
+ *
+ * There are two export interfaces available - csv and XML
+ *
+ */
+ @Override
+ public String getSchedulerClass() {
+ String schedulerClass = CargosoftExportScheduler.class.getName();
+ logger.finest("...... scheduler: " + schedulerClass);
+ return schedulerClass;
+ }
}
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/datev/CargosoftExportScheduler.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/datev/CargosoftExportScheduler.java
index 7857bb3..b42b8da 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/datev/CargosoftExportScheduler.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/datev/CargosoftExportScheduler.java
@@ -1,22 +1,22 @@
/*******************************************************************************
* Imixs Workflow Technology
- * Copyright (C) 2001, 2008 Imixs Software Solutions GmbH,
+ * Copyright (C) 2001, 2008 Imixs Software Solutions GmbH,
* http://www.imixs.com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
- *
+ *
* You can receive a copy of the GNU General Public
* License at http://www.gnu.org/licenses/gpl.html
- *
- * Contributors:
+ *
+ * Contributors:
* Imixs Software Solutions GmbH - initial API and implementation
* Ralph Soika
*******************************************************************************/
@@ -61,10 +61,10 @@ import jakarta.ejb.EJB;
* The class implements the interface
* _org.imixs.workflow.engine.scheduler.Scheduler_ and can be used in
* combination with the Imxis-Workflow Scheduler Service.
- *
+ *
* @see SchedulerService
* @author rsoika
- *
+ *
*/
public class CargosoftExportScheduler implements Scheduler {
@@ -94,9 +94,9 @@ public class CargosoftExportScheduler implements Scheduler {
/**
* This is the method which processes the timeout event depending on the running
* timer settings.
- *
- *
- *
+ *
+ *
+ *
* @param timer
* @throws QueryException
*/
@@ -198,7 +198,7 @@ public class CargosoftExportScheduler implements Scheduler {
/**
* Diese Hilfsmehtode überträgt eine Datei an einen FTP Server. Die
* Verbindugnsdaten stehen im Configuraiton Workitem.
- *
+ *
* @param fileData object
* @throws PluginException
*/
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/mahnlauf/ExcelExportController.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/mahnlauf/ExcelExportController.java
index d046104..7d7c2d5 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/mahnlauf/ExcelExportController.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/mahnlauf/ExcelExportController.java
@@ -44,9 +44,9 @@ import jakarta.inject.Named;
/**
* Der ExcelExportController exportiert rechnungen anhand von Filterangaben
* (excel_export_rechnungsausgang.xhmlt) nach Excel.
- *
+ *
* Die Ausgabe ist auf maximal 3000 Zeilen eingeschränkt
- *
+ *
* @author rsoika
*
*/
@@ -54,291 +54,290 @@ import jakarta.inject.Named;
@ConversationScoped
public class ExcelExportController implements Serializable {
- private static final long serialVersionUID = 1L;
- private static Logger logger = Logger.getLogger(ExcelExportController.class.getName());
+ private static final long serialVersionUID = 1L;
+ private static Logger logger = Logger.getLogger(ExcelExportController.class.getName());
- public static final String ERROR_CONFIG = "CONFIG_ERROR";
- final String TYPE_TEXTBLOCK = "textblock";
+ public static final String ERROR_CONFIG = "CONFIG_ERROR";
+ final String TYPE_TEXTBLOCK = "textblock";
- public static final int MAX_ROWS = 3000;
- @Inject
- protected DocumentService documentService;
+ public static final int MAX_ROWS = 3000;
+ @Inject
+ protected DocumentService documentService;
- @Inject
- WorkflowController workflowController;
+ @Inject
+ WorkflowController workflowController;
- @Inject
- DocumentController documentController;
+ @Inject
+ DocumentController documentController;
- @Inject
- SnapshotService snapshotService;
+ @Inject
+ SnapshotService snapshotService;
- private ItemCollection filter;
- private CustomFormItem dbtrItem;
+ private ItemCollection filter;
+ private CustomFormItem dbtrItem;
- public ExcelExportController() {
- }
+ public ExcelExportController() {
+ }
- @PostConstruct
- public void init() {
- reset();
- }
+ @PostConstruct
+ public void init() {
+ reset();
+ }
- public ItemCollection getFilter() {
- return filter;
- }
+ public ItemCollection getFilter() {
+ return filter;
+ }
- public void setFilter(ItemCollection filter) {
- this.filter = filter;
- }
+ public void setFilter(ItemCollection filter) {
+ this.filter = filter;
+ }
- /**
- * Fuert verschiedene Queries aus um eine Analyse der Sachprufung durchzuführen.
- *
- * @throws PluginException
- */
- public String export() throws PluginException {
+ /**
+ * Fuert verschiedene Queries aus um eine Analyse der Sachprufung durchzuführen.
+ *
+ * @throws PluginException
+ */
+ public String export() throws PluginException {
- logger.info("start export....");
- Date start = filter.getItemValueDate("start");
- Date stop = filter.getItemValueDate("stop");
- logger.info("...daterange=" + start + " - " + stop);
+ logger.info("start export....");
+ Date start = filter.getItemValueDate("start");
+ Date stop = filter.getItemValueDate("stop");
+ logger.info("...daterange=" + start + " - " + stop);
- // serach date range?
- String sDateFrom = "191401070000"; // because * did not work here
- String sDateTo = "211401070000";
- SimpleDateFormat dateformat = new SimpleDateFormat("yyyyMMddHHmm");
+ // serach date range?
+ String sDateFrom = "191401070000"; // because * did not work here
+ String sDateTo = "211401070000";
+ SimpleDateFormat dateformat = new SimpleDateFormat("yyyyMMddHHmm");
- if (start != null) {
- Calendar cal = Calendar.getInstance();
- cal.setTime(start);
- sDateFrom = dateformat.format(cal.getTime());
- }
- if (stop != null) {
- Calendar cal = Calendar.getInstance();
- cal.setTime(stop);
- cal.add(Calendar.DATE, 1);
- sDateTo = dateformat.format(cal.getTime());
- }
+ if (start != null) {
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(start);
+ sDateFrom = dateformat.format(cal.getTime());
+ }
+ if (stop != null) {
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(stop);
+ cal.add(Calendar.DATE, 1);
+ sDateTo = dateformat.format(cal.getTime());
+ }
- // query zeit
- String query = "(type:workitem OR type:workitemarchive) AND ($workflowgroup:Rechnungsausgang) ";
- if (start != null && stop != null) {
- query += "AND (invoice.date:[" + sDateFrom + " TO " + sDateTo + "]) ";
- } else {
- throw new PluginException("ERROR", "Bitte geben Sie einen Zeitraum an", null);
- }
- logger.info(query);
+ // query zeit
+ String query = "(type:workitem OR type:workitemarchive) AND ($workflowgroup:Rechnungsausgang) ";
+ if (start != null && stop != null) {
+ query += "AND (invoice.date:[" + sDateFrom + " TO " + sDateTo + "]) ";
+ } else {
+ throw new PluginException("ERROR", "Bitte geben Sie einen Zeitraum an", null);
+ }
+ logger.info(query);
- // query Sachprüfung
+ // query Sachprüfung
- if (!filter.getItemValueString("space.ref").isEmpty()
- && !"-".equals(filter.getItemValueString("space.ref"))) {
- query += " AND ($uniqueidref:" + filter.getItemValueString("space.ref") + ")";
- }
- if (workflowController.getWorkitem() != null
- && !workflowController.getWorkitem().getItemValueString("dbtr.number").isEmpty()) {
- query += " AND (dbtr.number:" + workflowController.getWorkitem().getItemValueString("dbtr.number") + ")";
- }
- if (!filter.getItemValueString("invoice.text").isEmpty()) {
- query += " AND (invoice.positions:" + filter.getItemValueString("invoice.text") + ")";
- }
+ if (!filter.getItemValueString("space.ref").isEmpty() && !"-".equals(filter.getItemValueString("space.ref"))) {
+ query += " AND ($uniqueidref:" + filter.getItemValueString("space.ref") + ")";
+ }
+ if (workflowController.getWorkitem() != null
+ && !workflowController.getWorkitem().getItemValueString("dbtr.number").isEmpty()) {
+ query += " AND (dbtr.number:" + workflowController.getWorkitem().getItemValueString("dbtr.number") + ")";
+ }
+ if (!filter.getItemValueString("invoice.text").isEmpty()) {
+ query += " AND (invoice.positions:" + filter.getItemValueString("invoice.text") + ")";
+ }
- // load the text block
- String template = "ausgangsrechnungen-export_template.xlsx";
- FileData fileData = loadTextBlockFileData("Excel-Export Template", template);
+ // load the text block
+ String template = "ausgangsrechnungen-export_template.xlsx";
+ FileData fileData = loadTextBlockFileData("Excel-Export Template", template);
- // do we found the document?
- if (fileData == null) {
- throw new PluginException(InkassoExportAdapter.class.getSimpleName(), ERROR_CONFIG,
- "Missing Excel Export Template - template=" + template + " not found!");
- }
- String targetName = "ausgangsrechnungen-export_" + dateformat.format(new Date()) + ".xlsx";
- try {
- List invoices = documentService.find(query, MAX_ROWS, 0, "invoice.date", true);
- if (invoices.size() > 0) {
- insertInvoiceRows(invoices, fileData);
- }
- fileData.setName(targetName);
+ // do we found the document?
+ if (fileData == null) {
+ throw new PluginException(InkassoExportAdapter.class.getSimpleName(), ERROR_CONFIG,
+ "Missing Excel Export Template - template=" + template + " not found!");
+ }
+ String targetName = "ausgangsrechnungen-export_" + dateformat.format(new Date()) + ".xlsx";
+ try {
+ List invoices = documentService.find(query, MAX_ROWS, 0, "invoice.date", true);
+ if (invoices.size() > 0) {
+ insertInvoiceRows(invoices, fileData);
+ }
+ fileData.setName(targetName);
- // See:
- // https://stackoverflow.com/questions/9391838/how-to-provide-a-file-download-from-a-jsf-backing-bean
- download(fileData);
- } catch (IOException | QueryException e) {
- throw new PluginException(InkassoExportAdapter.class.getSimpleName(), ERROR_CONFIG,
- "Failed to generate Excel Export: " + e.getMessage());
- }
+ // See:
+ // https://stackoverflow.com/questions/9391838/how-to-provide-a-file-download-from-a-jsf-backing-bean
+ download(fileData);
+ } catch (IOException | QueryException e) {
+ throw new PluginException(InkassoExportAdapter.class.getSimpleName(), ERROR_CONFIG,
+ "Failed to generate Excel Export: " + e.getMessage());
+ }
- logger.info("Query=" + query);
- return "/pages/admin/excel_export_rechnungsausgang.jsf?faces-redirect=true";
- }
+ logger.info("Query=" + query);
+ return "/pages/admin/excel_export_rechnungsausgang.jsf?faces-redirect=true";
+ }
- /**
- * Helper method to initialize a download
- *
- * @throws IOException
- */
- public void download(FileData fileData) throws IOException {
+ /**
+ * Helper method to initialize a download
+ *
+ * @throws IOException
+ */
+ public void download(FileData fileData) throws IOException {
- FacesContext facesContext = FacesContext.getCurrentInstance();
- ExternalContext externalContext = facesContext.getExternalContext();
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+ ExternalContext externalContext = facesContext.getExternalContext();
- externalContext.responseReset();
- externalContext.setResponseContentType("application/vnd.ms-excel");
- externalContext.setResponseContentLength(fileData.getContent().length);
- externalContext.setResponseHeader("Content-Disposition", "attachment; filename=\"" + fileData.getName() + "\"");
+ externalContext.responseReset();
+ externalContext.setResponseContentType("application/vnd.ms-excel");
+ externalContext.setResponseContentLength(fileData.getContent().length);
+ externalContext.setResponseHeader("Content-Disposition", "attachment; filename=\"" + fileData.getName() + "\"");
- OutputStream output = externalContext.getResponseOutputStream();
+ OutputStream output = externalContext.getResponseOutputStream();
- // Now you can write the InputStream of the file to the above OutputStream the
- // usual way.
- output.write(fileData.getContent());
+ // Now you can write the InputStream of the file to the above OutputStream the
+ // usual way.
+ output.write(fileData.getContent());
- facesContext.responseComplete(); // Important! Otherwise Faces will attempt to render the response which
- // obviously will fail since it's already written with a file and closed.
- }
+ facesContext.responseComplete(); // Important! Otherwise Faces will attempt to render the response which
+ // obviously will fail since it's already written with a file and closed.
+ }
- /**
- * This method returns a text-block ItemCollection for a specified name.
- *
- * @param name in attribute txtname
- *
- *
- */
- private FileData loadTextBlockFileData(String name, String fileName) {
- ItemCollection textBlockItemCollection = null;
+ /**
+ * This method returns a text-block ItemCollection for a specified name.
+ *
+ * @param name in attribute txtname
+ *
+ *
+ */
+ private 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);
+ // 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());
- }
+ } else {
+ logger.warning("Missing text-block : '" + name + "'");
+ }
+ } catch (QueryException e) {
+ logger.warning("getTextBlock - invalid query: " + e.getMessage());
+ }
- return null;
- }
+ return null;
+ }
- /**
- * This method reset the search and input state.
- */
- public void reset() {
- filter = new ItemCollection();
+ /**
+ * This method reset the search and input state.
+ */
+ public void reset() {
+ filter = new ItemCollection();
- // compute start stop based on current month
- YearMonth startYearMonth = YearMonth.now();
- java.time.LocalDate startOfMonthDate = startYearMonth.atDay(1);
- java.time.LocalDate endOfMonthDate = startYearMonth.atEndOfMonth();
- filter.setItemValue("start",
- java.util.Date.from(startOfMonthDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()));
- filter.setItemValue("stop",
- java.util.Date.from(endOfMonthDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()));
- workflowController.setWorkitem(new ItemCollection());
+ // compute start stop based on current month
+ YearMonth startYearMonth = YearMonth.now();
+ java.time.LocalDate startOfMonthDate = startYearMonth.atDay(1);
+ java.time.LocalDate endOfMonthDate = startYearMonth.atEndOfMonth();
+ filter.setItemValue("start",
+ java.util.Date.from(startOfMonthDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()));
+ filter.setItemValue("stop",
+ java.util.Date.from(endOfMonthDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()));
+ workflowController.setWorkitem(new ItemCollection());
- // debtr item
- dbtrItem = new CustomFormItem("dbtr.number", "text", "", false, false, false, "", null, false, 0);
+ // debtr item
+ dbtrItem = new CustomFormItem("dbtr.number", "text", "", false, false, false, "", null, false, 0);
- }
+ }
- public CustomFormItem getItem() {
- // dbtrItem.setName("dbtr.number");
- return dbtrItem;
- }
+ public CustomFormItem getItem() {
+ // dbtrItem.setName("dbtr.number");
+ return dbtrItem;
+ }
- /**
- * This helper method inserts a row for each invoice
- *
- * @throws PluginException
- */
- private void insertInvoiceRows(List invoices, FileData fileData) throws PluginException {
- // 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);
+ /**
+ * This helper method inserts a row for each invoice
+ *
+ * @throws PluginException
+ */
+ private void insertInvoiceRows(List invoices, FileData fileData) throws PluginException {
+ // 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);
- XSSFCell standCell = getCellByRef(doc, sheet, "F6");
- standCell.setCellValue(new Date());
+ XSSFCell standCell = getCellByRef(doc, sheet, "F6");
+ standCell.setCellValue(new Date());
- CellReference cr = new CellReference("A11");
- 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, invoices.size(), true, true);
+ CellReference cr = new CellReference("A11");
+ 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, invoices.size(), true, true);
- for (ItemCollection invoice : invoices) {
- logger.finest("......copy row...");
+ 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("invoice.number"));
- row.getCell(1).setCellValue(invoice.getItemValueString("dbtr.number"));
- row.getCell(2).setCellValue(invoice.getItemValueString("space.name"));
- row.getCell(3).setCellValue(invoice.getItemValueString("invoice.text"));
- row.getCell(4).setCellValue(invoice.getItemValueDate("invoice.date"));
- row.getCell(5).setCellValue(invoice.getItemValueDate("invoice.duedate"));
- row.getCell(6).setCellValue(invoice.getItemValueDouble("invoice.total"));
+ // now create a new line..
+ XSSFRow row = sheet.createRow(rowPos);
+ row.copyRowFrom(referenceRow, new CellCopyPolicy());
+ // insert values
+ row.getCell(0).setCellValue(invoice.getItemValueString("invoice.number"));
+ row.getCell(1).setCellValue(invoice.getItemValueString("dbtr.number"));
+ row.getCell(2).setCellValue(invoice.getItemValueString("space.name"));
+ row.getCell(3).setCellValue(invoice.getItemValueString("invoice.text"));
+ row.getCell(4).setCellValue(invoice.getItemValueDate("invoice.date"));
+ row.getCell(5).setCellValue(invoice.getItemValueDate("invoice.duedate"));
+ row.getCell(6).setCellValue(invoice.getItemValueDouble("invoice.total"));
- rowPos++;
- }
- // delete reference row
- sheet.shiftRows(referenceRowPos, lastRow + invoices.size(), -1, true, true);
+ rowPos++;
+ }
+ // delete reference row
+ sheet.shiftRows(referenceRowPos, lastRow + invoices.size(), -1, true, true);
- ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
- // write back the file
- doc.write(byteArrayOutputStream);
- doc.close();
- byte[] newContent = byteArrayOutputStream.toByteArray();
- fileData.setContent(newContent);
+ 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(ZahlungsavisExportAdapter.class.getSimpleName(), ERROR_CONFIG,
- "failed to update excel export: " + e.getMessage());
- }
- }
+ } catch (IOException e) {
+ throw new PluginException(ZahlungsavisExportAdapter.class.getSimpleName(), ERROR_CONFIG,
+ "failed to update excel export: " + e.getMessage());
+ }
+ }
- /**
- * Returns a Cell by name or an optional absolute cell postion
- *
- * Examples for refs are 'A1', 'AB3', 'MyCell' where 'MyCell' is a named cell.
- *
- *
- */
- public static XSSFCell getCellByRef(XSSFWorkbook doc, XSSFSheet sheet, String cellReference) {
- XSSFCell cell = null;
+ /**
+ * Returns a Cell by name or an optional absolute cell postion
+ *
+ * Examples for refs are 'A1', 'AB3', 'MyCell' where 'MyCell' is a named cell.
+ *
+ *
+ */
+ public static XSSFCell getCellByRef(XSSFWorkbook doc, XSSFSheet sheet, String cellReference) {
+ XSSFCell cell = null;
- // first we test if the cellName is a named cell
- Name aNamedCell = doc.getName(cellReference);
- if (aNamedCell != null) {
- // yes its a named cell so we need to get the referrer Formula
- logger.finest("...resolving named cell = " + aNamedCell.getNameName());
- cellReference = aNamedCell.getRefersToFormula();
- // now we can find the cell by its ref
- }
+ // first we test if the cellName is a named cell
+ Name aNamedCell = doc.getName(cellReference);
+ if (aNamedCell != null) {
+ // yes its a named cell so we need to get the referrer Formula
+ logger.finest("...resolving named cell = " + aNamedCell.getNameName());
+ cellReference = aNamedCell.getRefersToFormula();
+ // now we can find the cell by its ref
+ }
- CellReference cr = new CellReference(cellReference);
- XSSFRow row = sheet.getRow(cr.getRow());
- if (row == null) {
- logger.severe("Unable to resolve cell ref '" + cellReference + "'!");
- return null;
- }
- cell = row.getCell(cr.getCol());
- return cell;
- }
+ CellReference cr = new CellReference(cellReference);
+ XSSFRow row = sheet.getRow(cr.getRow());
+ if (row == null) {
+ logger.severe("Unable to resolve cell ref '" + cellReference + "'!");
+ return null;
+ }
+ cell = row.getCell(cr.getCol());
+ return cell;
+ }
}
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/mahnlauf/InkassoAppendAdapter.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/mahnlauf/InkassoAppendAdapter.java
index 3031b06..d2e9300 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/mahnlauf/InkassoAppendAdapter.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/mahnlauf/InkassoAppendAdapter.java
@@ -17,13 +17,13 @@ import jakarta.inject.Inject;
/**
* Der InkassoAppendAdapter verknüpft eine Rechnung mit einem Inkasso Workflow
- * zum aktuellen Debitor. Existiert aktuell kein Inkasso für diesen
- * Debitor erzeugt der Adapter automatisch eine neue Prozessinstanz.
+ * zum aktuellen Debitor. Existiert aktuell kein Inkasso für diesen Debitor
+ * erzeugt der Adapter automatisch eine neue Prozessinstanz.
*
* Wurde die Rechnung bereits einem Inkasso zugeordnet passiert nichts.
- *
- *
- *
+ *
+ *
+ *
* @version 1.0
* @author rsoika
*/
@@ -41,9 +41,9 @@ public class InkassoAppendAdapter implements SignalAdapter {
WorkflowService workflowService;
/**
- * This method finds or create the Inkasso and adds a reference
- * ($workitemref) to the current invoice.
- *
+ * This method finds or create the Inkasso and adds a reference ($workitemref)
+ * to the current invoice.
+ *
* @throws PluginException
*/
@Override
@@ -59,9 +59,9 @@ public class InkassoAppendAdapter implements SignalAdapter {
/**
* Diese method hängt eine referenz der aktuellen Rechnung an den Inkasso
- * Workflow an. Gibt es noch keinen, wird einer erzeugt.
- * Die method liefert das Inkasso Workitem zurück.
- *
+ * Workflow an. Gibt es noch keinen, wird einer erzeugt. Die method liefert das
+ * Inkasso Workitem zurück.
+ *
* @param document
* @throws PluginException
*/
@@ -103,7 +103,7 @@ public class InkassoAppendAdapter implements SignalAdapter {
/**
* Prüft alle offenen Inkasso Workflows und gibt den neuesten zur angegebenen
* dbtrNumber zurück, oder null falls es keinen Offenen gibt.
- *
+ *
* @param dbtrNumber
* @return
* @throws QueryException
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/mahnlauf/InkassoController.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/mahnlauf/InkassoController.java
index 20a7533..a98aa84 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/mahnlauf/InkassoController.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/mahnlauf/InkassoController.java
@@ -15,12 +15,12 @@ import jakarta.inject.Inject;
import jakarta.inject.Named;
/**
- * Der InkassoController dient dazu eine bereits zugewiesene Rechnung
- * wieder aus dem Inkasso zu entfernen.
+ * Der InkassoController dient dazu eine bereits zugewiesene Rechnung wieder aus
+ * dem Inkasso zu entfernen.
*
* Zusätzlich bietet er die Summenberechnung an, bei der die Gutschriften
* abgezogen werden.
- *
+ *
* @author rsoika
*
*/
@@ -43,7 +43,7 @@ public class InkassoController implements Serializable {
* result is rounded to 2 digits.
*
* Gutschriften werden abgezogen
- *
+ *
* @param refids - list of workitem uniqueIds
* @param item - name of the item to summarize
* @return sum rounded to 2 digits
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/mahnlauf/InkassoExportAdapter.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/mahnlauf/InkassoExportAdapter.java
index cdc81a3..4016091 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/mahnlauf/InkassoExportAdapter.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/mahnlauf/InkassoExportAdapter.java
@@ -27,7 +27,7 @@ import jakarta.inject.Inject;
/**
* Der ZahlungsavisAdapter importiert eine Excel Datei aus einem Textblock
- *
+ *
*
* Der Adapter erweitert den POIAdapter somit können felder aktualisiert werden
* (siehe POIFineReplaceAdapter).
- *
+ *
*
* Der Adapter kopiert die Rechnungsdaten in neue Zeilen, welche ab Zeilnenummer
* 16 eingefügt werden.
@@ -46,7 +46,7 @@ import jakarta.inject.Inject;
* Dabei werden Gutschriften in spalte E und Rechnungen in Spalte F eingetrgen.
*
* Abschliessend wird die Zelle 'TOTAL' noch aktualisiert.
- *
+ *
* @version 1.0
* @author rsoika
*/
@@ -69,7 +69,7 @@ public class InkassoExportAdapter extends POIFindReplaceAdapter {
/**
* This method finds or create the Zahlungsavis and adds a reference
* ($workitemref) to the current invoice.
- *
+ *
* @throws PluginException
*/
@SuppressWarnings("unchecked")
@@ -121,7 +121,7 @@ public class InkassoExportAdapter extends POIFindReplaceAdapter {
*
* The named cell 'TOTAL' should contain the summary formula. It will be
* evaluated at the end.
- *
+ *
* @throws PluginException
*/
@SuppressWarnings("unchecked")
@@ -186,7 +186,7 @@ public class InkassoExportAdapter extends POIFindReplaceAdapter {
/**
* This method loads a text-block for a specified ref and appends the named
* fileData object of this document.
- *
+ *
* @param document
* @throws PluginException
*/
@@ -216,9 +216,9 @@ public class InkassoExportAdapter extends POIFindReplaceAdapter {
/**
* This method returns a text-block ItemCollection for a specified name.
- *
+ *
* @param name in attribute txtname
- *
+ *
*
*/
public FileData loadTextBlockFileData(String name, String fileName) {
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/mahnlauf/MahnlaufExecuteAdapter.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/mahnlauf/MahnlaufExecuteAdapter.java
index e5898ca..ed5a2c2 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/mahnlauf/MahnlaufExecuteAdapter.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/mahnlauf/MahnlaufExecuteAdapter.java
@@ -29,10 +29,10 @@ import jakarta.inject.Inject;
* processed invoices. This item is used in the Workflow Model to construct a
* HTML Table wen sending the mail.
*
- * The Adapter also splits the item 'dbtr.mail' into a multi value field if
- * the value contains email addresses separated with new lines.
- *
- *
+ * The Adapter also splits the item 'dbtr.mail' into a multi value field if the
+ * value contains email addresses separated with new lines.
+ *
+ *
* @version 1.0
* @author rsoika
*/
@@ -52,7 +52,7 @@ public class MahnlaufExecuteAdapter implements SignalAdapter {
/**
* This method finds all invices ($workitemref) and tirgges event 300
- *
+ *
* @throws PluginException
*/
@SuppressWarnings("unchecked")
@@ -125,24 +125,24 @@ public class MahnlaufExecuteAdapter implements SignalAdapter {
}
switch (invoice.getTaskID()) {
- case 5200:
- case 5201:
- if (dunningLevel < 1)
- dunningLevel = 1;
- break;
- case 5210:
- case 5211:
- if (dunningLevel < 2)
- dunningLevel = 2;
- break;
- case 5220:
- if (dunningLevel < 3)
- dunningLevel = 3;
- break;
- default:
- if (dunningLevel < 1)
- dunningLevel = 1;
- break;
+ case 5200:
+ case 5201:
+ if (dunningLevel < 1)
+ dunningLevel = 1;
+ break;
+ case 5210:
+ case 5211:
+ if (dunningLevel < 2)
+ dunningLevel = 2;
+ break;
+ case 5220:
+ if (dunningLevel < 3)
+ dunningLevel = 3;
+ break;
+ default:
+ if (dunningLevel < 1)
+ dunningLevel = 1;
+ break;
}
// create a workitem stub for the mail message
@@ -179,18 +179,18 @@ public class MahnlaufExecuteAdapter implements SignalAdapter {
// compute subject
switch (dunningLevel) {
- case 2:
- mahnLaufWorkitem.setItemValue("mail.subject_de", "2. MAHNUNG");
- mahnLaufWorkitem.setItemValue("mail.subject_en", "2. REMINDER");
- break;
- case 3:
- mahnLaufWorkitem.setItemValue("mail.subject_de", "LETZTE AUSSERGERICHTLICHE MAHNUNG");
- mahnLaufWorkitem.setItemValue("mail.subject_en", "LAST REMINDER");
- break;
- default:
- mahnLaufWorkitem.setItemValue("mail.subject_de", "1. MAHNUNG");
- mahnLaufWorkitem.setItemValue("mail.subject_en", "1. REMINDER");
- break;
+ case 2:
+ mahnLaufWorkitem.setItemValue("mail.subject_de", "2. MAHNUNG");
+ mahnLaufWorkitem.setItemValue("mail.subject_en", "2. REMINDER");
+ break;
+ case 3:
+ mahnLaufWorkitem.setItemValue("mail.subject_de", "LETZTE AUSSERGERICHTLICHE MAHNUNG");
+ mahnLaufWorkitem.setItemValue("mail.subject_en", "LAST REMINDER");
+ break;
+ default:
+ mahnLaufWorkitem.setItemValue("mail.subject_de", "1. MAHNUNG");
+ mahnLaufWorkitem.setItemValue("mail.subject_en", "1. REMINDER");
+ break;
}
// Verify the dbtr.mail item (split into multi value)
@@ -198,8 +198,7 @@ public class MahnlaufExecuteAdapter implements SignalAdapter {
for (String mail : mailListe) {
logger.fine(" test mail address:'" + mail + "'");
if (!InvoiceUtil.validateEmail(mail)) {
- throw new PluginException(MahnlaufExecuteAdapter.class.getName(),
- "INVALID_EMAIL",
+ throw new PluginException(MahnlaufExecuteAdapter.class.getName(), "INVALID_EMAIL",
"Die Daten konnten nicht aktualisiert werden! Bitte geben Sie eine gültige E-Mail Adresse ein!");
}
}
@@ -208,7 +207,7 @@ public class MahnlaufExecuteAdapter implements SignalAdapter {
/**
* Returns true if the reminder date is today or in the past
- *
+ *
* @param uniqueid
* @return
*/
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/mahnlauf/MahnlaufRefAddAdapter.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/mahnlauf/MahnlaufRefAddAdapter.java
index e26bba8..c95b3a4 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/mahnlauf/MahnlaufRefAddAdapter.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/mahnlauf/MahnlaufRefAddAdapter.java
@@ -30,152 +30,151 @@ import jakarta.inject.Inject;
*
* If the invoice has already been linked to a Mahnlauf nothing happens.
*
- *
+ *
* @version 1.0
* @author rsoika
*/
public class MahnlaufRefAddAdapter implements SignalAdapter {
- private static Logger logger = Logger.getLogger(MahnlaufRefAddAdapter.class.getName());
+ private static Logger logger = Logger.getLogger(MahnlaufRefAddAdapter.class.getName());
- @EJB
- ModelService modelService;
+ @EJB
+ ModelService modelService;
- @EJB
- WorkflowService workflowService = null;
+ @EJB
+ WorkflowService workflowService = null;
- @Inject
- SepaWorkflowService sepaWorkflowService;
+ @Inject
+ SepaWorkflowService sepaWorkflowService;
- @Inject
- BusinessPartnerService businessPartnerService;
+ @Inject
+ BusinessPartnerService businessPartnerService;
- /**
- * This method finds or create the Mahnlauf and adds a reference ($workitemref)
- * to the current invoice.
- *
- * @throws PluginException
- */
- @SuppressWarnings("unchecked")
- @Override
- public ItemCollection execute(ItemCollection invoice, ItemCollection event)
- throws AdapterException, PluginException {
+ /**
+ * This method finds or create the Mahnlauf and adds a reference ($workitemref)
+ * to the current invoice.
+ *
+ * @throws PluginException
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public ItemCollection execute(ItemCollection invoice, ItemCollection event)
+ throws AdapterException, PluginException {
- if (invoice.getTaskID() < MahnlaufService.TASK_MAHNLAUF_START
- || invoice.getTaskID() > MahnlaufService.TASK_MAHNLAUF_END) {
- throw new PluginException(MahnlaufRefAddAdapter.class.getName(),
- MahnlaufService.ERROR_CONFIG,
- "Der Mahnlauf kann nur für Rechnungen erstellt werden die bereits die Fälligkeit erreicht haben.");
- }
+ if (invoice.getTaskID() < MahnlaufService.TASK_MAHNLAUF_START
+ || invoice.getTaskID() > MahnlaufService.TASK_MAHNLAUF_END) {
+ throw new PluginException(MahnlaufRefAddAdapter.class.getName(), MahnlaufService.ERROR_CONFIG,
+ "Der Mahnlauf kann nur für Rechnungen erstellt werden die bereits die Fälligkeit erreicht haben.");
+ }
- String dbtrNumber = invoice.getItemValueString(MahnlaufService.ITEM_DBTR_NUMBER);
- ItemCollection mahnLaufWorkitem;
- try {
- mahnLaufWorkitem = findMahnlauf(dbtrNumber);
+ String dbtrNumber = invoice.getItemValueString(MahnlaufService.ITEM_DBTR_NUMBER);
+ ItemCollection mahnLaufWorkitem;
+ try {
+ mahnLaufWorkitem = findMahnlauf(dbtrNumber);
- if (mahnLaufWorkitem == null) {
- // create one...
- mahnLaufWorkitem = createNewMahnlauf(dbtrNumber, invoice, event);
- }
+ if (mahnLaufWorkitem == null) {
+ // create one...
+ mahnLaufWorkitem = createNewMahnlauf(dbtrNumber, invoice, event);
+ }
- // add Invoice to Mahnlauf
- List refList = mahnLaufWorkitem.getItemValue("$workitemref");
- if (!refList.contains(invoice.getUniqueID())) {
- mahnLaufWorkitem.appendItemValueUnique("$workitemref", invoice.getUniqueID());
- }
+ // add Invoice to Mahnlauf
+ List refList = mahnLaufWorkitem.getItemValue("$workitemref");
+ if (!refList.contains(invoice.getUniqueID())) {
+ mahnLaufWorkitem.appendItemValueUnique("$workitemref", invoice.getUniqueID());
+ }
- // set event 100 and process
- ItemCollection mahnlaufConfig = workflowService.evalWorkflowResult(event, "mahnlauf", invoice, true);
- int eventID = mahnlaufConfig.getItemValueInteger("event");
+ // set event 100 and process
+ ItemCollection mahnlaufConfig = workflowService.evalWorkflowResult(event, "mahnlauf", invoice, true);
+ int eventID = mahnlaufConfig.getItemValueInteger("event");
- mahnLaufWorkitem.event(eventID);
- workflowService.processWorkItem(mahnLaufWorkitem);
+ mahnLaufWorkitem.event(eventID);
+ workflowService.processWorkItem(mahnLaufWorkitem);
- } catch (QueryException | ModelException e) {
- throw new PluginException(MahnlaufRefAddAdapter.class.getName(),
- MahnlaufService.ERROR_CONFIG, "Unable to create Mahnlauf", e);
- }
+ } catch (QueryException | ModelException e) {
+ throw new PluginException(MahnlaufRefAddAdapter.class.getName(), MahnlaufService.ERROR_CONFIG,
+ "Unable to create Mahnlauf", e);
+ }
- // set mahnlauf ref
- invoice.setItemValue("dunning.ref", mahnLaufWorkitem.getUniqueID());
- return invoice;
- }
+ // set mahnlauf ref
+ invoice.setItemValue("dunning.ref", mahnLaufWorkitem.getUniqueID());
+ return invoice;
+ }
- /**
- * Helper method finds an open mahnlauf for a debtr.numbre (name)
- *
- * @param key
- * @return
- * @throws QueryException
- */
- public ItemCollection findMahnlauf(String key) throws QueryException {
- String query = "(type:workitem) AND ($modelversion:mahnlauf*) AND (name:\"" + key + "\")";
- List resultList = workflowService.getDocumentService().find(query, 1, 0, "$modified", true);
+ /**
+ * Helper method finds an open mahnlauf for a debtr.numbre (name)
+ *
+ * @param key
+ * @return
+ * @throws QueryException
+ */
+ public ItemCollection findMahnlauf(String key) throws QueryException {
+ String query = "(type:workitem) AND ($modelversion:mahnlauf*) AND (name:\"" + key + "\")";
+ List resultList = workflowService.getDocumentService().find(query, 1, 0, "$modified", true);
- if (resultList.size() > 0) {
- return resultList.get(0);
- }
- // no mahnaluffound
- return null;
- }
+ if (resultList.size() > 0) {
+ return resultList.get(0);
+ }
+ // no mahnaluffound
+ return null;
+ }
- /**
- * Helper method to create a new Mahnlauf workitem
- *
- * @param key
- * @param invoice
- * @return
- * @throws ModelException
- * @throws PluginException
- */
- @SuppressWarnings("unused")
- public ItemCollection createNewMahnlauf(String key, ItemCollection invoice, ItemCollection event)
- throws ModelException, PluginException {
- String modelVersion = null;
- int taskID = -1;
- int eventID = -1;
- // test if the event provides a sepa export configuration
- ItemCollection mahnlaufConfig = workflowService.evalWorkflowResult(event, "mahnlauf", invoice, true);
- if (mahnlaufConfig != null && mahnlaufConfig.hasItem("modelversion") && mahnlaufConfig.hasItem("task")) {
- logger.fine("read model information from event");
- modelVersion = mahnlaufConfig.getItemValueString("modelVersion");
- taskID = mahnlaufConfig.getItemValueInteger("task");
- eventID = mahnlaufConfig.getItemValueInteger("event");
- }
+ /**
+ * Helper method to create a new Mahnlauf workitem
+ *
+ * @param key
+ * @param invoice
+ * @return
+ * @throws ModelException
+ * @throws PluginException
+ */
+ @SuppressWarnings("unused")
+ public ItemCollection createNewMahnlauf(String key, ItemCollection invoice, ItemCollection event)
+ throws ModelException, PluginException {
+ String modelVersion = null;
+ int taskID = -1;
+ int eventID = -1;
+ // test if the event provides a sepa export configuration
+ ItemCollection mahnlaufConfig = workflowService.evalWorkflowResult(event, "mahnlauf", invoice, true);
+ if (mahnlaufConfig != null && mahnlaufConfig.hasItem("modelversion") && mahnlaufConfig.hasItem("task")) {
+ logger.fine("read model information from event");
+ modelVersion = mahnlaufConfig.getItemValueString("modelVersion");
+ taskID = mahnlaufConfig.getItemValueInteger("task");
+ eventID = mahnlaufConfig.getItemValueInteger("event");
+ }
- // build the sepa export workitem....
- ItemCollection mahnlaufWorkitem = new ItemCollection().model(modelVersion).task(taskID);
- mahnlaufWorkitem.replaceItemValue("name", key);
- mahnlaufWorkitem.replaceItemValue(WorkflowKernel.CREATED, new Date());
- mahnlaufWorkitem.replaceItemValue(WorkflowKernel.MODIFIED, new Date());
- // set unqiueid
- mahnlaufWorkitem.setItemValue(WorkflowKernel.UNIQUEID, WorkflowKernel.generateUniqueID());
+ // build the sepa export workitem....
+ ItemCollection mahnlaufWorkitem = new ItemCollection().model(modelVersion).task(taskID);
+ mahnlaufWorkitem.replaceItemValue("name", key);
+ mahnlaufWorkitem.replaceItemValue(WorkflowKernel.CREATED, new Date());
+ mahnlaufWorkitem.replaceItemValue(WorkflowKernel.MODIFIED, new Date());
+ // set unqiueid
+ mahnlaufWorkitem.setItemValue(WorkflowKernel.UNIQUEID, WorkflowKernel.generateUniqueID());
- // copy dbtr_iban
- mahnlaufWorkitem.setItemValue(MahnlaufService.ITEM_DBTR_NAME,
- invoice.getItemValue(MahnlaufService.ITEM_DBTR_NAME));
+ // copy dbtr_iban
+ mahnlaufWorkitem.setItemValue(MahnlaufService.ITEM_DBTR_NAME,
+ invoice.getItemValue(MahnlaufService.ITEM_DBTR_NAME));
- // lookup email....
- String dbtrNumber = invoice.getItemValueString("dbtr.number");
- ItemCollection businessPartner = businessPartnerService
- .getBusinessPartnerByID(InvoiceUtil.buildBPID(dbtrNumber));
- if (businessPartner != null) {
- mahnlaufWorkitem.setItemValue(MahnlaufService.ITEM_DBTR_EMAIL, businessPartner.getItemValue("dbtr.mail"));// dbtr.mail
- }
+ // lookup email....
+ String dbtrNumber = invoice.getItemValueString("dbtr.number");
+ ItemCollection businessPartner = businessPartnerService
+ .getBusinessPartnerByID(InvoiceUtil.buildBPID(dbtrNumber));
+ if (businessPartner != null) {
+ mahnlaufWorkitem.setItemValue(MahnlaufService.ITEM_DBTR_EMAIL, businessPartner.getItemValue("dbtr.mail"));// dbtr.mail
+ }
- mahnlaufWorkitem.setItemValue(MahnlaufService.ITEM_DBTR_NUMBER,
- invoice.getItemValue(MahnlaufService.ITEM_DBTR_NUMBER));
- mahnlaufWorkitem.setItemValue("invoice.language", invoice.getItemValue("invoice.language"));
+ mahnlaufWorkitem.setItemValue(MahnlaufService.ITEM_DBTR_NUMBER,
+ invoice.getItemValue(MahnlaufService.ITEM_DBTR_NUMBER));
+ mahnlaufWorkitem.setItemValue("invoice.language", invoice.getItemValue("invoice.language"));
- // set workflow group name from the Task Element to identify document in xslt
- Model model = modelService.getModel(modelVersion);
- ItemCollection task = model.getTask(taskID);
- String modelTaskGroupName = task.getItemValueString("txtworkflowgroup"); // DO NOT CHANGE!
- mahnlaufWorkitem.setItemValue(WorkflowKernel.WORKFLOWGROUP, modelTaskGroupName);
+ // set workflow group name from the Task Element to identify document in xslt
+ Model model = modelService.getModel(modelVersion);
+ ItemCollection task = model.getTask(taskID);
+ String modelTaskGroupName = task.getItemValueString("txtworkflowgroup"); // DO NOT CHANGE!
+ mahnlaufWorkitem.setItemValue(WorkflowKernel.WORKFLOWGROUP, modelTaskGroupName);
- logger.info("...created new mahnlauf " + key + "...");
+ logger.info("...created new mahnlauf " + key + "...");
- return mahnlaufWorkitem;
- }
+ return mahnlaufWorkitem;
+ }
}
\ No newline at end of file
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/mahnlauf/MahnlaufService.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/mahnlauf/MahnlaufService.java
index ea9828b..2516dda 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/mahnlauf/MahnlaufService.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/mahnlauf/MahnlaufService.java
@@ -1,26 +1,26 @@
/*******************************************************************************
- * Imixs Workflow
- * Copyright (C) 2001, 2011 Imixs Software Solutions GmbH,
+ * Imixs Workflow
+ * Copyright (C) 2001, 2011 Imixs Software Solutions GmbH,
* http://www.imixs.com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
- *
+ *
* You can receive a copy of the GNU General Public
* License at http://www.gnu.org/licenses/gpl.html
- *
- * Project:
+ *
+ * Project:
* http://www.imixs.org
* http://java.net/projects/imixs-workflow
- *
- * Contributors:
+ *
+ * Contributors:
* Imixs Software Solutions GmbH - initial API and implementation
* Ralph Soika - Software Developer
*******************************************************************************/
@@ -49,11 +49,11 @@ import jakarta.ejb.Singleton;
import jakarta.inject.Inject;
/**
- * Der MahnlaufService wird vom MahnlaufExecuteAdapter um
- * Ausgangsrechnungen zu akutalisieren.
- *
+ * Der MahnlaufService wird vom MahnlaufExecuteAdapter um Ausgangsrechnungen zu
+ * akutalisieren.
+ *
* @author rsoika
- *
+ *
*/
@DeclareRoles({ "org.imixs.ACCESSLEVEL.NOACCESS", "org.imixs.ACCESSLEVEL.READERACCESS",
@@ -87,7 +87,7 @@ public class MahnlaufService {
/**
* * Diese Method processed eine Invoice mit Manager Rechnten
- *
+ *
* @throws PluginException
* @throws ModelException
* @throws ProcessingErrorException
@@ -104,7 +104,7 @@ public class MahnlaufService {
/**
* Helper method that loads all expressions from the spaces
- *
+ *
* @return List of list of expressions
*/
public Map> loadSpacePosMappings() {
@@ -125,7 +125,7 @@ public class MahnlaufService {
/**
* Hilfsmethode zum errechnen des richtigen Spaces zu einer invoice.text Positon
- *
+ *
* @param workitem
* @param spacePosMappings
*/
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/xml/BusinessPartnerImportService.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/xml/BusinessPartnerImportService.java
index 8dbcced..2da25e6 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/xml/BusinessPartnerImportService.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/xml/BusinessPartnerImportService.java
@@ -1,27 +1,27 @@
-/*
- * Imixs-Workflow
- *
- * Copyright (C) 2001-2020 Imixs Software Solutions GmbH,
+/*
+ * Imixs-Workflow
+ *
+ * Copyright (C) 2001-2020 Imixs Software Solutions GmbH,
* http://www.imixs.com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
- *
+ *
* You can receive a copy of the GNU General Public
* License at http://www.gnu.org/licenses/gpl.html
- *
- * Project:
+ *
+ * Project:
* https://www.imixs.org
* https://github.com/imixs/imixs-workflow
- *
- * Contributors:
+ *
+ * Contributors:
* Imixs Software Solutions GmbH - Project Management
* Ralph Soika - Software Developer
*/
@@ -59,11 +59,10 @@ import jakarta.enterprise.event.Observes;
/**
* Der BusinessPartnerImportService hängt sich an den standard CSVImport Service
- * der die Cargosoft Stammdaten aktualisiert.
- * Es ist ein simples Observer Pattern das auf das Document Event
- * "ON_DOCUMENT_SAVE" reagiert. Hier hängt sich der BusinessPartnerImportService
- * ein und prüft ob der Workflow schon existiert oder ggf. aktualisiert werden
- * muss.
+ * der die Cargosoft Stammdaten aktualisiert. Es ist ein simples Observer
+ * Pattern das auf das Document Event "ON_DOCUMENT_SAVE" reagiert. Hier hängt
+ * sich der BusinessPartnerImportService ein und prüft ob der Workflow schon
+ * existiert oder ggf. aktualisiert werden muss.
*
* Der Service migriert auch die alten zusätzlichen IBAN/BIC felder wenn der
* Business partner erstmals neu angelegt wird.
@@ -73,7 +72,7 @@ import jakarta.enterprise.event.Observes;
*
* Im Cargosoft Entity wird zusätzlich das flag NOSNAPSHOT=true gesetzt. Dies
* ist nur eine Performance Optimierung.
- *
+ *
* @author rsoika
*
*/
@@ -107,8 +106,8 @@ public class BusinessPartnerImportService {
/**
* Die Methode reagiert auf das CDI DocumentEvent beim Import von cargosoft
* cargosoftkreditor documenten.
- *
- *
+ *
+ *
*/
public void onEvent(@Observes DocumentEvent event) {
@@ -138,9 +137,9 @@ public class BusinessPartnerImportService {
/**
* Syncnrhonisert ein drecks Cargosoft Objekt mit dem neuen Busienss partner
* objekt
- *
+ *
* Gibt true urück wenn sich was verädnert hat
- *
+ *
* @param creditor
*/
public boolean syncCargosoftCreditorBusinessPartner(ItemCollection importDoc) {
@@ -218,7 +217,7 @@ public class BusinessPartnerImportService {
/**
* Erstellt ein neues leeres Business Partner Object
- *
+ *
* @return
*/
private ItemCollection createBusinessPartner(String partnerID) {
@@ -340,7 +339,7 @@ public class BusinessPartnerImportService {
/**
* Sucht nach einem Business partner
- *
+ *
* @param id
* @return
*/
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/xml/CargosoftXMLEAkteImportService.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/xml/CargosoftXMLEAkteImportService.java
index 47b8194..198069f 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/xml/CargosoftXMLEAkteImportService.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/xml/CargosoftXMLEAkteImportService.java
@@ -1,27 +1,27 @@
-/*
- * Imixs-Workflow
- *
- * Copyright (C) 2001-2020 Imixs Software Solutions GmbH,
+/*
+ * Imixs-Workflow
+ *
+ * Copyright (C) 2001-2020 Imixs Software Solutions GmbH,
* http://www.imixs.com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
- *
+ *
* You can receive a copy of the GNU General Public
* License at http://www.gnu.org/licenses/gpl.html
- *
- * Project:
+ *
+ * Project:
* https://www.imixs.org
* https://github.com/imixs/imixs-workflow
- *
- * Contributors:
+ *
+ * Contributors:
* Imixs Software Solutions GmbH - Project Management
* Ralph Soika - Software Developer
*/
@@ -89,20 +89,19 @@ import jakarta.enterprise.event.Observes;
import jakarta.inject.Inject;
/**
- * Der CargosoftXMLEAkteImportService erweitert den FTPImportService und
- * kann XML EAkten (Steuerbescheide) von Cargosoft importieren.
- * Der Service reagiert auf DocumentImportEvents und kann über das Options Feld
- * konfiguriert werden.
+ * Der CargosoftXMLEAkteImportService erweitert den FTPImportService und kann
+ * XML EAkten (Steuerbescheide) von Cargosoft importieren. Der Service reagiert
+ * auf DocumentImportEvents und kann über das Options Feld konfiguriert werden.
*
* Im Gegensatz zum FTPImportService werden die XML Dateien nach einem
* speziellen Verfahren geparsed und dann als Steuerbescheid importiert.
*
- * In den Optionen muss die option "mandant.id" hinterlegt sein. Stimmt
- * diese beim Import nicht mit der Mandanten Nummer in der XML Datei überein,
- * wird das XML Dokument gelöscht und nicht importiert.
- *
- *
- *
+ * In den Optionen muss die option "mandant.id" hinterlegt sein. Stimmt diese
+ * beim Import nicht mit der Mandanten Nummer in der XML Datei überein, wird das
+ * XML Dokument gelöscht und nicht importiert.
+ *
+ *
+ *
* @author rsoika
*
*/
@@ -135,8 +134,8 @@ public class CargosoftXMLEAkteImportService {
/**
* This method reacts on a CDI ImportEvent and reads documents form a ftp
* server.
- *
- *
+ *
+ *
*/
public void onEvent(@Observes DocumentImportEvent event) {
@@ -162,8 +161,7 @@ public class CargosoftXMLEAkteImportService {
return;
}
- documentImportService.logMessage("...CARGOSOFT_EAKTE_XML Import started: mandant.id=" + mandantID,
- event);
+ documentImportService.logMessage("...CARGOSOFT_EAKTE_XML Import started: mandant.id=" + mandantID, event);
String ftpServer = event.getSource().getItemValueString(DocumentImportService.SOURCE_ITEM_SERVER);
String ftpPort = event.getSource().getItemValueString(DocumentImportService.SOURCE_ITEM_PORT);
String ftpUser = event.getSource().getItemValueString(DocumentImportService.SOURCE_ITEM_USER);
@@ -216,8 +214,8 @@ public class CargosoftXMLEAkteImportService {
ftpClient.connect(ftpServer, ftpPort);
if (ftpClient.login(ftpUser, ftpPassword) == false) {
- throw new PluginException(CargosoftXMLEAkteImportService.class.getName(),
- "FTP_ERROR", "FTP file transfer failed: login failed!");
+ throw new PluginException(CargosoftXMLEAkteImportService.class.getName(), "FTP_ERROR",
+ "FTP file transfer failed: login failed!");
}
ftpClient.enterLocalPassiveMode();
logger.finest("...... FileType=" + FTP.BINARY_FILE_TYPE);
@@ -225,8 +223,7 @@ public class CargosoftXMLEAkteImportService {
ftpClient.setControlEncoding("UTF-8");
} catch (IOException e) {
- throw new PluginException(CargosoftXMLEAkteImportService.class.getName(),
- "FTP_ERROR", e.getMessage());
+ throw new PluginException(CargosoftXMLEAkteImportService.class.getName(), "FTP_ERROR", e.getMessage());
}
return ftpClient;
@@ -234,7 +231,7 @@ public class CargosoftXMLEAkteImportService {
/**
* Helper method reads the working FTP directory and starts importing the files.
- *
+ *
* @param ftpClient
* @param ftpPath
* @throws PluginException
@@ -250,8 +247,8 @@ public class CargosoftXMLEAkteImportService {
// try to enter the working directory and read all files...
boolean bWorkingDir = ftpClient.changeWorkingDirectory(ftpPath);
if (bWorkingDir == false) {
- throw new PluginException(CargosoftXMLEAkteImportService.class.getName(),
- "FTP_ERROR", "...failed to change into working directory: ");
+ throw new PluginException(CargosoftXMLEAkteImportService.class.getName(), "FTP_ERROR",
+ "...failed to change into working directory: ");
}
FTPFile[] allFiles = ftpClient.listFiles(ftpPath);
@@ -299,10 +296,10 @@ public class CargosoftXMLEAkteImportService {
// "processed/");
// }
- } catch (AccessDeniedException | ProcessingErrorException | PluginException
- | ModelException | XPathExpressionException | TransformerException e) {
- throw new PluginException(CargosoftXMLEAkteImportService.class.getName(),
- "FTP_ERROR", e.getMessage());
+ } catch (AccessDeniedException | ProcessingErrorException | PluginException | ModelException
+ | XPathExpressionException | TransformerException e) {
+ throw new PluginException(CargosoftXMLEAkteImportService.class.getName(), "FTP_ERROR",
+ e.getMessage());
}
}
documentImportService.logMessage("..." + count + " new files imported.", event);
@@ -313,8 +310,7 @@ public class CargosoftXMLEAkteImportService {
int r = ftpClient.getReplyCode();
logger.severe("FTP ReplyCode=" + r);
- throw new PluginException(CargosoftXMLEAkteImportService.class.getName(),
- "FTP_ERROR", e.getMessage());
+ throw new PluginException(CargosoftXMLEAkteImportService.class.getName(), "FTP_ERROR", e.getMessage());
} finally {
// do logout....
@@ -324,8 +320,7 @@ public class CargosoftXMLEAkteImportService {
ftpClient.disconnect();
} catch (IOException e) {
documentImportService.logMessage("...FTP file transfer failed: " + e.getMessage(), event);
- throw new PluginException(CargosoftXMLEAkteImportService.class.getName(),
- "FTP_ERROR", e.getMessage());
+ throw new PluginException(CargosoftXMLEAkteImportService.class.getName(), "FTP_ERROR", e.getMessage());
}
}
}
@@ -333,8 +328,8 @@ public class CargosoftXMLEAkteImportService {
/**
* Creates and processes a new workitem with a given xml information from the
* filedata
- *
- *
+ *
+ *
* @return
* @throws ModelException
* @throws PluginException
@@ -344,9 +339,8 @@ public class CargosoftXMLEAkteImportService {
* @throws XPathExpressionException
*/
public ItemCollection createWorkitem(ItemCollection source, String fileName, byte[] rawData,
- Map> spacePosMappings)
- throws AccessDeniedException, ProcessingErrorException, PluginException, ModelException,
- XPathExpressionException, TransformerException {
+ Map> spacePosMappings) throws AccessDeniedException, ProcessingErrorException,
+ PluginException, ModelException, XPathExpressionException, TransformerException {
ItemCollection workitem = new ItemCollection();
workitem.model(source.getItemValueString(DocumentImportService.SOURCE_ITEM_MODELVERSION));
workitem.task(source.getItemValueInteger(DocumentImportService.SOURCE_ITEM_TASK));
@@ -375,37 +369,37 @@ public class CargosoftXMLEAkteImportService {
// invoice.rate
// invoice.base.amount
- readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='client']", workitem,
- "mandant.id", String.class);
+ readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='client']", workitem, "mandant.id",
+ String.class);
- readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='cs_voucher_number']",
- workitem, "invoice.number", String.class);
+ readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='cs_voucher_number']", workitem,
+ "invoice.number", String.class);
- readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='cs_address_number']",
- workitem, "cdtr.number", String.class);
+ readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='cs_address_number']", workitem,
+ "cdtr.number", String.class);
- readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='voucherdate']",
- workitem, "invoice.date", Date.class);
+ readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='voucherdate']", workitem,
+ "invoice.date", Date.class);
- readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='currency']",
- workitem, "invoice.currency", String.class);
+ readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='currency']", workitem,
+ "invoice.currency", String.class);
- readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='currency_rate']",
- workitem, "invoice.rate", Double.class);
+ readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='currency_rate']", workitem,
+ "invoice.rate", Double.class);
- readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='total_net_amount']",
- workitem, "invoice.total.net", Double.class);
- readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='total_tax_amount']",
- workitem, "invoice.total.tax", Double.class);
- readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='reference']",
- workitem, "invoice.atc.number", String.class);
- readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='booking_period']",
- workitem, "invoice.booking_period", String.class);
+ readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='total_net_amount']", workitem,
+ "invoice.total.net", Double.class);
+ readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='total_tax_amount']", workitem,
+ "invoice.total.tax", Double.class);
+ readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='reference']", workitem,
+ "invoice.atc.number", String.class);
+ readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='booking_period']", workitem,
+ "invoice.booking_period", String.class);
- readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='booking_date']",
- workitem, "invoice.booking_date", Date.class);
- readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='booking_text']",
- workitem, "invoice.booking_text", String.class);
+ readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='booking_date']", workitem,
+ "invoice.booking_date", Date.class);
+ readXMLValue(doc, "/CargoSoftEFile/EFile/References/Reference[@type='booking_text']", workitem,
+ "invoice.booking_text", String.class);
// verify if invoice is already imported.
if (alreadyImported(workitem.getItemValueString("invoice.number"))) {
@@ -440,8 +434,7 @@ public class CargosoftXMLEAkteImportService {
attacheFiles(doc, workitem);
}
} catch (ParserConfigurationException | SAXException | IOException e) {
- throw new PluginException(CargosoftXMLEAkteImportService.class.getName(),
- "XML_ERROR", e.getMessage());
+ throw new PluginException(CargosoftXMLEAkteImportService.class.getName(), "XML_ERROR", e.getMessage());
}
return workitem;
}
@@ -449,12 +442,11 @@ public class CargosoftXMLEAkteImportService {
/**
* Reads a tag value from the xml tree and set the value into the given
* workitem.
- *
+ *
* /Invoices/Invoice/InvoiceHeader/Client/Code
- *
- * Beispiel Datum:
- * 2024-05-13T00:00:00+02:00
- *
+ *
+ * Beispiel Datum: 2024-05-13T00:00:00+02:00
+ *
* @param doc - xml doc
* @param expression - xpath expression
* @param workitem
@@ -513,10 +505,10 @@ public class CargosoftXMLEAkteImportService {
}
/**
- * This method attache the pdf file and the XML file to the workitem.
- * The method removes the file content first form the xml tree and attache the
- * XML without the pdf data.
- *
+ * This method attache the pdf file and the XML file to the workitem. The method
+ * removes the file content first form the xml tree and attache the XML without
+ * the pdf data.
+ *
* @throws XPathExpressionException
* @throws TransformerException
*/
@@ -526,24 +518,23 @@ public class CargosoftXMLEAkteImportService {
XPathFactory xpathFactory = XPathFactory.newInstance();
XPath xpath = xpathFactory.newXPath();
// read filename and content....
- readXMLValue(doc, "/CargoSoftEFile/EFile/Attachments/Attachment/Filename",
- workitem, "import.filename", String.class);
- readXMLValue(doc, "/CargoSoftEFile/EFile/Attachments/Attachment/Content",
- workitem, "import.filedata", String.class);
+ readXMLValue(doc, "/CargoSoftEFile/EFile/Attachments/Attachment/Filename", workitem, "import.filename",
+ String.class);
+ readXMLValue(doc, "/CargoSoftEFile/EFile/Attachments/Attachment/Content", workitem, "import.filedata",
+ String.class);
// attache the PDF file content
String fileDataString = workitem.getItemValueString("import.filedata");
byte[] decodedPDFData = java.util.Base64.getDecoder().decode(fileDataString);
- FileData fileData = new FileData(workitem.getItemValueString("import.filename"),
- decodedPDFData, "application/pdf", null);
+ FileData fileData = new FileData(workitem.getItemValueString("import.filename"), decodedPDFData,
+ "application/pdf", null);
workitem.addFileData(fileData);
// remove the temp items..
workitem.removeItem("import.filename");
workitem.removeItem("import.filedata");
// next remove the Attachments/AttachmentContent from the dom tree
- XPathExpression attachmentsExpr = xpath
- .compile("/CargoSoftEFile/EFile/Attachments/Attachment/Content");
+ XPathExpression attachmentsExpr = xpath.compile("/CargoSoftEFile/EFile/Attachments/Attachment/Content");
NodeList contentNodes = (NodeList) attachmentsExpr.evaluate(doc, XPathConstants.NODESET);
// Remove the matching nodes
for (int i = 0; i < contentNodes.getLength(); i++) {
@@ -569,7 +560,7 @@ public class CargosoftXMLEAkteImportService {
/**
* Prüft ob die Belegnummer schon existiert (importiert wurde)
- *
+ *
* @param belegNummer
* @return
*/
@@ -592,24 +583,23 @@ public class CargosoftXMLEAkteImportService {
/**
* This helper method reads the references starting with 'Row_' and creates a
* child Workitem for each row.
- *
+ *
* The method assumes that the rows are starting with the type 'row_n_' where
- * 'n' is the row number.
- * We start with row 1 and read until we found more rows.
- *
+ * 'n' is the row number. We start with row 1 and read until we found more rows.
+ *
* Example:
- *
+ *
*
* The last filenumber text will be transferred into the item 'invoice.text'
- *
+ *
* @param xml
* @return
* @throws Exception
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/xml/CargosoftXMLInvoiceImportService.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/xml/CargosoftXMLInvoiceImportService.java
index 10ac3aa..3b02d3a 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/xml/CargosoftXMLInvoiceImportService.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/xml/CargosoftXMLInvoiceImportService.java
@@ -1,27 +1,27 @@
-/*
- * Imixs-Workflow
- *
- * Copyright (C) 2001-2020 Imixs Software Solutions GmbH,
+/*
+ * Imixs-Workflow
+ *
+ * Copyright (C) 2001-2020 Imixs Software Solutions GmbH,
* http://www.imixs.com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
- *
+ *
* You can receive a copy of the GNU General Public
* License at http://www.gnu.org/licenses/gpl.html
- *
- * Project:
+ *
+ * Project:
* https://www.imixs.org
* https://github.com/imixs/imixs-workflow
- *
- * Contributors:
+ *
+ * Contributors:
* Imixs Software Solutions GmbH - Project Management
* Ralph Soika - Software Developer
*/
@@ -89,22 +89,21 @@ import jakarta.inject.Inject;
/**
* Der CargosoftXMLInvoiceImportImportService erweitert den FTPImportService und
- * kann XML Invoice Dokumente von Cargosoft importieren.
- * Der Service reagiert auf DocumentImportEvents und kann über das Options Feld
- * konfiguriert werden.
+ * kann XML Invoice Dokumente von Cargosoft importieren. Der Service reagiert
+ * auf DocumentImportEvents und kann über das Options Feld konfiguriert werden.
*
* Im Gegensatz zum FTPImportService werden die XML Dateien nach einem
- * speziellen Verfahren geparsed und dann als Ausgangsrechnungen importiert.
- * Der Service ersetzt den alten DATEV Import. Falls eine Rechnung schon
- * existiert (Rechnungsnummer) wird der Datensatz vom FTP Laufwerk gelöscht und
- * nicht importiert.
+ * speziellen Verfahren geparsed und dann als Ausgangsrechnungen importiert. Der
+ * Service ersetzt den alten DATEV Import. Falls eine Rechnung schon existiert
+ * (Rechnungsnummer) wird der Datensatz vom FTP Laufwerk gelöscht und nicht
+ * importiert.
*
- * In den Optionen muss die option "mandant.id" hinterlegt sein. Stimmt
- * diese beim Import nicht mit der Mandanten Nummer in der XML Datei überein,
- * wird das XML Dokument gelöscht und nicht importiert.
- *
- *
- *
+ * In den Optionen muss die option "mandant.id" hinterlegt sein. Stimmt diese
+ * beim Import nicht mit der Mandanten Nummer in der XML Datei überein, wird das
+ * XML Dokument gelöscht und nicht importiert.
+ *
+ *
+ *
* @author rsoika
*
*/
@@ -137,8 +136,8 @@ public class CargosoftXMLInvoiceImportService {
/**
* This method reacts on a CDI ImportEvent and reads documents form a ftp
* server.
- *
- *
+ *
+ *
*/
public void onEvent(@Observes DocumentImportEvent event) {
@@ -164,8 +163,7 @@ public class CargosoftXMLInvoiceImportService {
return;
}
- documentImportService.logMessage("...CARGOSOFT_INVOICE_XML Import started: mandant.id=" + mandantID,
- event);
+ documentImportService.logMessage("...CARGOSOFT_INVOICE_XML Import started: mandant.id=" + mandantID, event);
String ftpServer = event.getSource().getItemValueString(DocumentImportService.SOURCE_ITEM_SERVER);
String ftpPort = event.getSource().getItemValueString(DocumentImportService.SOURCE_ITEM_PORT);
String ftpUser = event.getSource().getItemValueString(DocumentImportService.SOURCE_ITEM_USER);
@@ -218,8 +216,8 @@ public class CargosoftXMLInvoiceImportService {
ftpClient.connect(ftpServer, ftpPort);
if (ftpClient.login(ftpUser, ftpPassword) == false) {
- throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(),
- "FTP_ERROR", "FTP file transfer failed: login failed!");
+ throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(), "FTP_ERROR",
+ "FTP file transfer failed: login failed!");
}
ftpClient.enterLocalPassiveMode();
logger.finest("...... FileType=" + FTP.BINARY_FILE_TYPE);
@@ -227,8 +225,7 @@ public class CargosoftXMLInvoiceImportService {
ftpClient.setControlEncoding("UTF-8");
} catch (IOException e) {
- throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(),
- "FTP_ERROR", e.getMessage());
+ throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(), "FTP_ERROR", e.getMessage());
}
return ftpClient;
@@ -236,7 +233,7 @@ public class CargosoftXMLInvoiceImportService {
/**
* Helper method reads the working FTP directory and starts importing the files.
- *
+ *
* @param ftpClient
* @param ftpPath
* @throws PluginException
@@ -252,8 +249,8 @@ public class CargosoftXMLInvoiceImportService {
// try to enter the working directory and read all files...
boolean bWorkingDir = ftpClient.changeWorkingDirectory(ftpPath);
if (bWorkingDir == false) {
- throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(),
- "FTP_ERROR", "...failed to change into working directory: ");
+ throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(), "FTP_ERROR",
+ "...failed to change into working directory: ");
}
FTPFile[] allFiles = ftpClient.listFiles(ftpPath);
@@ -301,10 +298,10 @@ public class CargosoftXMLInvoiceImportService {
// "processed/");
// }
- } catch (AccessDeniedException | ProcessingErrorException | PluginException
- | ModelException | XPathExpressionException | TransformerException e) {
- throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(),
- "FTP_ERROR", e.getMessage());
+ } catch (AccessDeniedException | ProcessingErrorException | PluginException | ModelException
+ | XPathExpressionException | TransformerException e) {
+ throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(), "FTP_ERROR",
+ e.getMessage());
}
}
documentImportService.logMessage("..." + count + " new files imported.", event);
@@ -315,8 +312,7 @@ public class CargosoftXMLInvoiceImportService {
int r = ftpClient.getReplyCode();
logger.severe("FTP ReplyCode=" + r);
- throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(),
- "FTP_ERROR", e.getMessage());
+ throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(), "FTP_ERROR", e.getMessage());
} finally {
// do logout....
@@ -326,8 +322,8 @@ public class CargosoftXMLInvoiceImportService {
ftpClient.disconnect();
} catch (IOException e) {
documentImportService.logMessage("...FTP file transfer failed: " + e.getMessage(), event);
- throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(),
- "FTP_ERROR", e.getMessage());
+ throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(), "FTP_ERROR",
+ e.getMessage());
}
}
}
@@ -335,8 +331,8 @@ public class CargosoftXMLInvoiceImportService {
/**
* Creates and processes a new workitem with a given xml information from the
* fileData
- *
- *
+ *
+ *
* @return
* @throws ModelException
* @throws PluginException
@@ -346,9 +342,8 @@ public class CargosoftXMLInvoiceImportService {
* @throws XPathExpressionException
*/
public ItemCollection createWorkitem(ItemCollection source, String fileName, byte[] rawData,
- Map> spacePosMappings)
- throws AccessDeniedException, ProcessingErrorException, PluginException, ModelException,
- XPathExpressionException, TransformerException {
+ Map> spacePosMappings) throws AccessDeniedException, ProcessingErrorException,
+ PluginException, ModelException, XPathExpressionException, TransformerException {
ItemCollection workitem = new ItemCollection();
workitem.model(source.getItemValueString(DocumentImportService.SOURCE_ITEM_MODELVERSION));
workitem.task(source.getItemValueInteger(DocumentImportService.SOURCE_ITEM_TASK));
@@ -377,11 +372,11 @@ public class CargosoftXMLInvoiceImportService {
// invoice.rate
// invoice.base.amount
- readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/Client/Codes/Code", workitem,
- "mandant.id", String.class);
+ readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/Client/Codes/Code", workitem, "mandant.id",
+ String.class);
- readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceNumber",
- workitem, "invoice.number", String.class);
+ readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceNumber", workitem, "invoice.number",
+ String.class);
// verify if invoice is already imported.
if (alreadyImported(workitem.getItemValueString("invoice.number"))) {
@@ -389,14 +384,14 @@ public class CargosoftXMLInvoiceImportService {
return null;
}
- readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceType/Codes/Code",
- workitem, "invoice.type", String.class);
- readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceType/Description",
- workitem, "invoice.type.description", String.class);
+ readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceType/Codes/Code", workitem, "invoice.type",
+ String.class);
+ readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceType/Description", workitem,
+ "invoice.type.description", String.class);
// Rechnungssumme errechnen.....
- readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceAmount/NetAmount/Amount/Value",
- workitem, "invoice.total.net", Double.class);
+ readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceAmount/NetAmount/Amount/Value", workitem,
+ "invoice.total.net", Double.class);
readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceAmount/VATInformation/VATAmount/Amount/Value",
workitem, "invoice.total.tax", Double.class);
if (!workitem.hasItem("invoice.total.tax")) {
@@ -416,34 +411,33 @@ public class CargosoftXMLInvoiceImportService {
}
// Steuer
- readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceAmount/VATInformation/VAT/VATRate",
- workitem, "invoice.vatrate", Double.class);
+ readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceAmount/VATInformation/VAT/VATRate", workitem,
+ "invoice.vatrate", Double.class);
// Booking Period
- readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/BookingPeriod",
- workitem, "invoice.bookingperiod", String.class);
+ readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/BookingPeriod", workitem, "invoice.bookingperiod",
+ String.class);
- readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceCurrency/Codes/Code",
- workitem, "invoice.currency", String.class);
+ readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceCurrency/Codes/Code", workitem,
+ "invoice.currency", String.class);
- readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceDate",
- workitem, "invoice.date", Date.class);
+ readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceDate", workitem, "invoice.date", Date.class);
readXMLValue(doc,
"/Invoices/Invoice/InvoiceHeader/PaymentConditions/PaymentCondition/Codes/Code[@Type='cs']",
workitem, "payment.term", String.class);
// kostenstelle
- readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/CostUnit/Description",
- workitem, "invoice.CostUnit", String.class);
+ readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/CostUnit/Description", workitem, "invoice.CostUnit",
+ String.class);
- readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/PaymentConditions/DueDate",
- workitem, "invoice.duedate", Date.class);
- readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/PaymentConditions/DueDate",
- workitem, "invoice.reminder", Date.class);
+ readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/PaymentConditions/DueDate", workitem, "invoice.duedate",
+ Date.class);
+ readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/PaymentConditions/DueDate", workitem, "invoice.reminder",
+ Date.class);
- readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceAddress/Codes/Code",
- workitem, "dbtr.number", String.class);
+ readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/InvoiceAddress/Codes/Code", workitem, "dbtr.number",
+ String.class);
String dbtrNumber = workitem.getItemValueString("dbtr.number");
if (dbtrNumber.startsWith("K") || dbtrNumber.startsWith("D")) {
workitem.setItemValue("dbtr.number", dbtrNumber.substring(1));
@@ -487,17 +481,16 @@ public class CargosoftXMLInvoiceImportService {
attacheFiles(doc, workitem);
} catch (ParserConfigurationException | SAXException | IOException e) {
- throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(),
- "XML_ERROR", e.getMessage());
+ throw new PluginException(CargosoftXMLInvoiceImportService.class.getName(), "XML_ERROR", e.getMessage());
}
return workitem;
}
/**
* Prüft ob die Rechnung eine Rückstellung ist also mit R1 bis R8 beginnt
- *
+ *
* ^R[1-8] .
- *
+ *
* @param workitem
* @return
*/
@@ -509,12 +502,11 @@ public class CargosoftXMLInvoiceImportService {
/**
* Reads a tag value from the xml tree and set the value into the given
* workitem.
- *
+ *
* /Invoices/Invoice/InvoiceHeader/Client/Code
- *
- * Beispiel Datum:
- * 2024-05-13T00:00:00+02:00
- *
+ *
+ * Beispiel Datum: 2024-05-13T00:00:00+02:00
+ *
* @param doc - xml doc
* @param expression - xpath expression
* @param workitem
@@ -566,12 +558,10 @@ public class CargosoftXMLInvoiceImportService {
/**
* Hilfsmethode die die ATC Nummer sucht und in das workitem feld
- * invoice.atc.number einträgt.
- * Wir gehen davon aus, das wir über die ChildItems diese aus dem billingtexts
- * schon ermittel haben.
- * Es können mehrere ATC nummern existieren. Diese werden in einer Liste
- * gespeichert
- *
+ * invoice.atc.number einträgt. Wir gehen davon aus, das wir über die ChildItems
+ * diese aus dem billingtexts schon ermittel haben. Es können mehrere ATC
+ * nummern existieren. Diese werden in einer Liste gespeichert
+ *
* @param doc
* @param workitem
*/
@@ -592,19 +582,13 @@ public class CargosoftXMLInvoiceImportService {
/**
* Reads the positions rows
- *
+ *
* InvoiceRows/InvoiceRow
*
- * Each row has the following items:
- * _childitems {
- * datev.shzeichen=[H],
- * datev.kurs=[0.0],
- * datev.basisumsatz=[0.0],
- * datev.text=[R LA-PAP-2405-051],
- * datev.konto=[3851],
- * datev.umsatz=[3307.81],
- * datev.wkz=[EUR]}}
- *
+ * Each row has the following items: _childitems { datev.shzeichen=[H],
+ * datev.kurs=[0.0], datev.basisumsatz=[0.0], datev.text=[R LA-PAP-2405-051],
+ * datev.konto=[3851], datev.umsatz=[3307.81], datev.wkz=[EUR]}}
+ *
* @param doc - xml doc
* @param workitem
*/
@@ -622,8 +606,7 @@ public class CargosoftXMLInvoiceImportService {
XPathExpression netAmountExchangeRateExpr = xPath
.compile("InvoiceAmount/NetAmount/Amount/ExchangeRate/text()");
- XPathExpression netActivityTypeExpr = xPath
- .compile("ActivityType/Codes/Code[@Type='cs']/text()");
+ XPathExpression netActivityTypeExpr = xPath.compile("ActivityType/Codes/Code[@Type='cs']/text()");
NodeList rowList = doc.getElementsByTagName("InvoiceRow");
double _kurs = 0.0;
@@ -679,7 +662,7 @@ public class CargosoftXMLInvoiceImportService {
/**
* S/H Kennzeichen auflösen
- *
+ *
* Bei G = Gutschrift oder SR = Stornorechnung müssen wir das vorzeichen ändern
* Invoice Type S/H
*/
@@ -693,7 +676,7 @@ public class CargosoftXMLInvoiceImportService {
/**
* Liste der BillingText-Elemente lesen....
- *
+ *
* und ggf. die ATC Nummer finden....
**/
childItemCol.setItemValue("BillingCode", billingCode);
@@ -732,14 +715,11 @@ public class CargosoftXMLInvoiceImportService {
}
/**
- * G = Gutschrift
- * SR = Stornorechnung
- * GK = Sammelgutschrift
- * SS = Sammelrechnung Storno
- *
- * müssen wir das vorzeichen ändern
- * dies wird über den Invoice.Type geprüft
- *
+ * G = Gutschrift SR = Stornorechnung GK = Sammelgutschrift SS = Sammelrechnung
+ * Storno
+ *
+ * müssen wir das vorzeichen ändern dies wird über den Invoice.Type geprüft
+ *
* @return
*/
private boolean isGutschrift(ItemCollection workitem) {
@@ -748,10 +728,10 @@ public class CargosoftXMLInvoiceImportService {
}
/**
- * This method attache the pdf file and the XML file to the workitem.
- * The method removes the file content first form the xml tree and attache the
- * XML without the pdf data.
- *
+ * This method attache the pdf file and the XML file to the workitem. The method
+ * removes the file content first form the xml tree and attache the XML without
+ * the pdf data.
+ *
* @throws XPathExpressionException
* @throws TransformerException
*/
@@ -761,16 +741,16 @@ public class CargosoftXMLInvoiceImportService {
XPathFactory xpathFactory = XPathFactory.newInstance();
XPath xpath = xpathFactory.newXPath();
// read filename and content....
- readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/Attachments/Attachment/Filename",
- workitem, "import.filename", String.class);
- readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/Attachments/Attachment/Content",
- workitem, "import.filedata", String.class);
+ readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/Attachments/Attachment/Filename", workitem,
+ "import.filename", String.class);
+ readXMLValue(doc, "/Invoices/Invoice/InvoiceHeader/Attachments/Attachment/Content", workitem, "import.filedata",
+ String.class);
// attache the PDF file content
String fileDataString = workitem.getItemValueString("import.filedata");
byte[] decodedPDFData = java.util.Base64.getDecoder().decode(fileDataString);
- FileData fileData = new FileData(workitem.getItemValueString("import.filename"),
- decodedPDFData, "application/pdf", null);
+ FileData fileData = new FileData(workitem.getItemValueString("import.filename"), decodedPDFData,
+ "application/pdf", null);
workitem.addFileData(fileData);
// remove the temp items..
workitem.removeItem("import.filename");
@@ -804,7 +784,7 @@ public class CargosoftXMLInvoiceImportService {
/**
* Prüft ob die Belegnummer schon existiert (importiert wurde)
- *
+ *
* @param belegNummer
* @return
*/
@@ -828,7 +808,7 @@ public class CargosoftXMLInvoiceImportService {
* Diese Method sucht einen Debitor.
*
* Diese Methode erwartet das führende D
- *
+ *
* @throws PluginException
*/
public ItemCollection findDebitor(String dbtrNumber) throws PluginException {
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/TokenResponse.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/TokenResponse.java
index 66cb23e..433a866 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/TokenResponse.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/TokenResponse.java
@@ -2,9 +2,9 @@ package com.alexanderlogistics.zoho;
/**
* Helper class for JSON deserialization
- *
+ *
* If the request is successful, you would receive the following:
- *
+ *
*
{
"access_token": "{access_token}",
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoAPIService.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoAPIService.java
index 0486d5e..06ac9a1 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoAPIService.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoAPIService.java
@@ -42,336 +42,306 @@ import jakarta.json.bind.JsonbConfig;
* Der ZohoAPIService stellt methoden für den Zugriff auf die Zoho API bereit.
*/
@DeclareRoles({ "org.imixs.ACCESSLEVEL.NOACCESS", "org.imixs.ACCESSLEVEL.READERACCESS",
- "org.imixs.ACCESSLEVEL.AUTHORACCESS", "org.imixs.ACCESSLEVEL.EDITORACCESS",
- "org.imixs.ACCESSLEVEL.MANAGERACCESS" })
+ "org.imixs.ACCESSLEVEL.AUTHORACCESS", "org.imixs.ACCESSLEVEL.EDITORACCESS",
+ "org.imixs.ACCESSLEVEL.MANAGERACCESS" })
@RolesAllowed({ "org.imixs.ACCESSLEVEL.NOACCESS", "org.imixs.ACCESSLEVEL.READERACCESS",
- "org.imixs.ACCESSLEVEL.AUTHORACCESS", "org.imixs.ACCESSLEVEL.EDITORACCESS",
- "org.imixs.ACCESSLEVEL.MANAGERACCESS" })
+ "org.imixs.ACCESSLEVEL.AUTHORACCESS", "org.imixs.ACCESSLEVEL.EDITORACCESS",
+ "org.imixs.ACCESSLEVEL.MANAGERACCESS" })
@Singleton
@RunAs("org.imixs.ACCESSLEVEL.MANAGERACCESS")
public class ZohoAPIService {
- private static Logger logger = Logger.getLogger(ZohoAPIService.class.getName());
- private static final String ZOHO_API_BASE_URL = "https://www.zohoapis.eu/books/v3/";
+ private static Logger logger = Logger.getLogger(ZohoAPIService.class.getName());
- @Inject
- ZohoOAuthManager zohoOAuthManager;
+ @Inject
+ ZohoOAuthManager zohoOAuthManager;
- private HttpClient httpClient;
- private Jsonb jsonb;
+ private HttpClient httpClient;
+ private Jsonb jsonb;
- @PostConstruct
- void init() {
- this.httpClient = HttpClient.newBuilder()
- .connectTimeout(Duration.ofSeconds(10))
- .build();
+ @PostConstruct
+ void init() {
+ this.httpClient = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
- JsonbConfig config = new JsonbConfig()
- .withDateFormat("yyyy-MM-dd", Locale.getDefault())
- .setProperty("jsonb.fail-on-unknown-properties", false); // Ignoriert unbekannte Felder
- this.jsonb = JsonbBuilder.create(config);
+ JsonbConfig config = new JsonbConfig().withDateFormat("yyyy-MM-dd", Locale.getDefault())
+ .setProperty("jsonb.fail-on-unknown-properties", false); // Ignoriert unbekannte Felder
+ this.jsonb = JsonbBuilder.create(config);
+ }
+
+ public String findContactIDByCompanyName(String companyName, String accessToken) throws PluginException {
+
+ // Print JSON to console for verification
+ logger.info("├── Zoho lookup contact '" + companyName + "'...");
+ try {
+ // https://www.zohoapis.com/books/v3/contacts?organization_id=10234695&company_name=xxx'
+ String uri = zohoOAuthManager.getBaseURI() + "contacts?organization_id="
+ + zohoOAuthManager.getOrganization() + "&company_name="
+ + URLEncoder.encode(companyName, StandardCharsets.UTF_8);
+ logger.fine("│ ├── uri= " + uri);
+ logger.fine("│ ├── accessToken=" + accessToken);
+ HttpRequest request = HttpRequest.newBuilder().uri(URI.create(uri))
+ .header("Authorization", "Zoho-oauthtoken " + accessToken)
+ .header("Content-Type", "application/json").GET().build();
+
+ HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
+
+ // Print response details to console
+ logger.fine("├── Zoho Response:");
+ logger.fine("│ ├── Status Code: " + response.statusCode());
+ logger.fine("│ ├── Response Body: " + response.body());
+ if (response.statusCode() >= 300) {
+ throw new PluginException(this.getClass().getName(), "Zoho API error",
+ "Failed to find Contacts - Status code: " + response.statusCode() + ", Response: "
+ + response.body());
+ }
+
+ ZohoContactFindResponse contactsResponse = jsonb.fromJson(response.body(), ZohoContactFindResponse.class);
+
+ if (contactsResponse != null && contactsResponse.getContacts() != null) {
+ // Durchsuche die Ergebnisse nach exakter Übereinstimmung
+ for (ZohoContact contact : contactsResponse.getContacts()) {
+ if (companyName.equalsIgnoreCase(contact.getCompanyName())) {
+ logger.info("│ ├── contactID= " + contact.getContactId());
+ return contact.getContactId();
+ }
+ }
+ }
+ return null;
+ } catch (Exception e) {
+ throw new PluginException(this.getClass().getName(), "Zoho API error", "Failed to find contacts", e);
}
- public String findContactIDByCompanyName(String companyName, String accessToken) throws PluginException {
+ }
- // Print JSON to console for verification
- logger.info("├── Zoho lookup contact '" + companyName + "'...");
- try {
- // https://www.zohoapis.com/books/v3/contacts?organization_id=10234695&company_name=xxx'
- String uri = ZOHO_API_BASE_URL + "contacts?organization_id="
- + zohoOAuthManager.getOrganization() + "&company_name="
- + URLEncoder.encode(companyName, StandardCharsets.UTF_8);
- logger.fine("│ ├── uri= " + uri);
- logger.fine("│ ├── accessToken=" + accessToken);
- HttpRequest request = HttpRequest.newBuilder()
- .uri(URI.create(uri))
- .header("Authorization", "Zoho-oauthtoken " + accessToken)
- .header("Content-Type", "application/json")
- .GET()
- .build();
-
- HttpResponse response = httpClient.send(
- request, HttpResponse.BodyHandlers.ofString());
-
- // Print response details to console
- logger.fine("├── Zoho Response:");
- logger.fine("│ ├── Status Code: " + response.statusCode());
- logger.fine("│ ├── Response Body: " + response.body());
- if (response.statusCode() >= 300) {
- throw new PluginException(this.getClass().getName(), "Zoho API error",
- "Failed to find Contacts - Status code: " + response.statusCode() +
- ", Response: " + response.body());
- }
-
- ZohoContactFindResponse contactsResponse = jsonb.fromJson(response.body(),
- ZohoContactFindResponse.class);
-
- if (contactsResponse != null && contactsResponse.getContacts() != null) {
- // Durchsuche die Ergebnisse nach exakter Übereinstimmung
- for (ZohoContact contact : contactsResponse.getContacts()) {
- if (companyName.equalsIgnoreCase(contact.getCompanyName())) {
- logger.info("│ ├── contactID= " + contact.getContactId());
- return contact.getContactId();
- }
- }
- }
- return null;
- } catch (Exception e) {
- throw new PluginException(this.getClass().getName(), "Zoho API error",
- "Failed to find contacts", e);
- }
+ /**
+ * Exports an invocie document
+ *
+ * @see https://www.zoho.com/books/api/v3/invoices/#create-an-invoice
+ *
+ * @param invoice
+ * @throws PluginException
+ */
+ public ZohoInvoice exportInvoice(ItemCollection invoice, List files) throws PluginException {
+ String accessToken = zohoOAuthManager.getValidAccessToken();
+ logger.info("├── Zoho Export Invoice " + invoice.getItemValueString("invoice.number") + "...");
+ // first lookup contact!
+ String contactID = "";
+ contactID = findContactIDByCompanyName(invoice.getItemValueString("dbtr.name"), accessToken);
+ if (contactID == null) {
+ logger.info("│ ├── contact not found");
+ ZohoContact contact = createContact(invoice.getItemValueString("dbtr.name"), accessToken);
+ contactID = contact.getContactId();
}
- /**
- * Exports an invocie document
- *
- * @see https://www.zoho.com/books/api/v3/invoices/#create-an-invoice
- *
- * @param invoice
- * @throws PluginException
- */
- public ZohoInvoice exportInvoice(ItemCollection invoice, List files) throws PluginException {
- String accessToken = zohoOAuthManager.getValidAccessToken();
- logger.info("├── Zoho Export Invoice " + invoice.getItemValueString("invoice.number") + "...");
+ // Konvertiere ItemCollection zu ZohoInvoiceDTO
+ ZohoInvoice zohoInvoice = convertToZohoInvoice(invoice, contactID, accessToken);
- // first lookup contact!
- String contactID = "";
- contactID = findContactIDByCompanyName(invoice.getItemValueString("dbtr.name"), accessToken);
- if (contactID == null) {
- logger.info("│ ├── contact not found");
- ZohoContact contact = createContact(invoice.getItemValueString("dbtr.name"), accessToken);
- contactID = contact.getContactId();
+ try {
+ String requestBody = jsonb.toJson(zohoInvoice);
+
+ // Print JSON to console for verification
+ logger.fine("├── Zoho Invoice JSON Request...");
+ logger.fine("│ ├── " + requestBody);
+
+ // https://www.zohoapis.com/books/v3/invoices?organization_id=10234695'
+ String uri = zohoOAuthManager.getBaseURI() + "invoices?organization_id="
+ + zohoOAuthManager.getOrganization();
+ logger.fine("│ ├── uri= " + uri);
+ logger.fine("│ ├── accessToken=" + accessToken);
+ HttpRequest request = HttpRequest.newBuilder().uri(URI.create(uri))
+ .header("Authorization", "Zoho-oauthtoken " + accessToken)
+ .header("Content-Type", "application/json").POST(HttpRequest.BodyPublishers.ofString(requestBody))
+ .build();
+
+ HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
+
+ // Print response details to console
+ logger.fine("├── Zoho Response:");
+ logger.fine("│ ├── Status Code: " + response.statusCode());
+
+ if (response.statusCode() >= 300) {
+ throw new PluginException(this.getClass().getName(), "Zoho API error",
+ "Failed to create invoice. Status code: " + response.statusCode() + ", Response: "
+ + response.body());
+ }
+
+ // Erfolgreiche Erstellung
+ String bodyContent = response.body();
+ logger.fine("│ ├── Response Body: " + bodyContent);
+
+ System.out.print(bodyContent);
+ ZohoInvoiceCreateResponse createResponse = jsonb.fromJson(bodyContent, ZohoInvoiceCreateResponse.class);
+
+ logger.fine("│ ├── OK - customerID=" + createResponse.getInvoice().getCustomerId());
+ logger.info("│ ├── OK - invoiceID=" + createResponse.getInvoice().getInvoiceId());
+
+ if (createResponse != null) {
+ zohoInvoice = createResponse.getInvoice();
+
+ // now add attachments (optional)
+ if (files != null) {
+ for (FileData file : files) {
+ attacheFileData(zohoInvoice.getInvoiceId(), file, "invoices", accessToken);
+ }
}
- // Konvertiere ItemCollection zu ZohoInvoiceDTO
- ZohoInvoice zohoInvoice = convertToZohoInvoice(invoice, contactID, accessToken);
-
- try {
- String requestBody = jsonb.toJson(zohoInvoice);
-
- // Print JSON to console for verification
- logger.fine("├── Zoho Invoice JSON Request...");
- logger.fine("│ ├── " + requestBody);
-
- // https://www.zohoapis.com/books/v3/invoices?organization_id=10234695'
- String uri = ZOHO_API_BASE_URL + "invoices?organization_id="
- + zohoOAuthManager.getOrganization();
- logger.fine("│ ├── uri= " + uri);
- logger.fine("│ ├── accessToken=" + accessToken);
- HttpRequest request = HttpRequest.newBuilder()
- .uri(URI.create(uri))
- .header("Authorization", "Zoho-oauthtoken " + accessToken)
- .header("Content-Type", "application/json")
- .POST(HttpRequest.BodyPublishers.ofString(requestBody))
- .build();
-
- HttpResponse response = httpClient.send(
- request, HttpResponse.BodyHandlers.ofString());
-
- // Print response details to console
- logger.fine("├── Zoho Response:");
- logger.fine("│ ├── Status Code: " + response.statusCode());
-
- if (response.statusCode() >= 300) {
- throw new PluginException(this.getClass().getName(), "Zoho API error",
- "Failed to create invoice. Status code: " + response.statusCode() +
- ", Response: " + response.body());
- }
-
- // Erfolgreiche Erstellung
- String bodyContent = response.body();
- logger.fine("│ ├── Response Body: " + bodyContent);
-
- System.out.print(bodyContent);
- ZohoInvoiceCreateResponse createResponse = jsonb.fromJson(bodyContent,
- ZohoInvoiceCreateResponse.class);
-
- logger.fine("│ ├── OK - customerID=" + createResponse.getInvoice().getCustomerId());
- logger.info("│ ├── OK - invoiceID=" + createResponse.getInvoice().getInvoiceId());
-
- if (createResponse != null) {
- zohoInvoice = createResponse.getInvoice();
-
- // now add attachments (optional)
- if (files != null) {
- for (FileData file : files) {
- attacheFileData(zohoInvoice.getInvoiceId(), file, "invoices",
- accessToken);
- }
- }
-
- logger.info("│ ├── Invoice Export successful.");
- return zohoInvoice;
- } else {
- throw new PluginException(this.getClass().getName(), "Zoho API error",
- "Failed to export invoice to Zoho: unable to resolve response");
- }
-
- } catch (IOException | InterruptedException e) {
- throw new PluginException(this.getClass().getName(), "Zoho API error",
- "Failed to export invoice to Zoho: " + e.getMessage(), e);
- }
-
- }
-
- /**
- * Erstellt einen neuen Contact in Zoho Books
- *
- * @param companyName Der Firmenname für den neuen Contact
- * @return Der erstellte ZohoContact mit contact_id
- * @throws PluginException Wenn der API-Aufruf fehlschlägt
- */
- public ZohoContact createContact(String companyName, String accessToken) throws PluginException {
- logger.info("├── Zoho create contact '" + companyName + "'...");
- try {
- // Contact-DTO vorbereiten
- ZohoContact newContact = new ZohoContact();
- newContact.setContactName(companyName); // Wir verwenden den Firmennamen auch als Contact Name
- newContact.setCompanyName(companyName);
-
- // JSON serialisieren
- String requestBody = jsonb.toJson(newContact);
- logger.fine("│ ├── " + requestBody);
- String uri = ZOHO_API_BASE_URL + "contacts?organization_id="
- + zohoOAuthManager.getOrganization();
-
- HttpRequest request = HttpRequest.newBuilder()
- .uri(URI.create(uri))
- .header("Authorization", "Zoho-oauthtoken " + accessToken)
- .header("Content-Type", "application/json")
- .POST(HttpRequest.BodyPublishers.ofString(requestBody))
- .build();
-
- HttpResponse response = httpClient.send(
- request, HttpResponse.BodyHandlers.ofString());
- logger.fine("├── Zoho Response:");
- logger.fine("│ ├── Status Code: " + response.statusCode());
- logger.fine("│ ├── Response Body: " + response.body());
- if (response.statusCode() >= 300) {
- throw new PluginException(this.getClass().getName(), "Zoho API error",
- "Failed to create invoice. Status code: " + response.statusCode() +
- ", Response: " + response.body());
- }
-
- // Erfolgreiche Erstellung
- ZohoContactCreateResponse createResponse = jsonb.fromJson(response.body(),
- ZohoContactCreateResponse.class);
- if (createResponse != null) {
- logger.info("│ ├── OK - contactID=" + createResponse.getContact().getContactId());
- return createResponse.getContact();
- } else {
- throw new PluginException(this.getClass().getName(), "Zoho API error",
- "Response could not be resolved!");
- }
-
- } catch (IOException | InterruptedException e) {
- throw new PluginException(this.getClass().getName(), "Zoho API error",
- "Failed to create contact: " + e.getMessage(), e);
- }
-
- }
-
- private ZohoInvoice convertToZohoInvoice(ItemCollection invoice, String contactID, String accessToken)
- throws PluginException {
-
- ZohoInvoice zohoInvoice = new ZohoInvoice();
- // Basisinformationen
- logger.fine("invoice.date=" + invoice.getItemValueDate("invoice.date"));
- logger.fine("invoice.duedate=" + invoice.getItemValueDate("invoice.duedate"));
-
- // LocalDate.ofInstant(date.toInstant(), ZoneId.systemDefault())
- zohoInvoice.setDate(
- LocalDate.ofInstant(invoice.getItemValueDate("invoice.date").toInstant(),
- ZoneId.systemDefault()));
-
- zohoInvoice.setDueDate(
- LocalDate.ofInstant(invoice.getItemValueDate("invoice.duedate").toInstant(),
- ZoneId.systemDefault()));
-
- zohoInvoice.setTotal(invoice.getItemValueDouble("invoice.total"));
- // Kunden-ID (muss angepasst werden je nachdem wie du sie speicherst)
- zohoInvoice.setCustomerId(contactID);
- List positionen = InvoiceUtil.explodeChildList(invoice);
-
- List lineItems = positionen.stream()
- .map(item -> {
- ItemCollection itemCol = (ItemCollection) item;
- ZohoInvoiceItem lineItem = new ZohoInvoiceItem();
- lineItem.setName(itemCol.getItemValueString("datev.text"));
- lineItem.setDescription(itemCol.getItemValueString("billingtext"));
- lineItem.setRate(itemCol.getItemValueDouble("datev.umsatz"));
- lineItem.setQuantity(1);
- return lineItem;
- })
- .collect(Collectors.toList());
-
- zohoInvoice.setLineItems(lineItems);
+ logger.info("│ ├── Invoice Export successful.");
return zohoInvoice;
+ } else {
+ throw new PluginException(this.getClass().getName(), "Zoho API error",
+ "Failed to export invoice to Zoho: unable to resolve response");
+ }
+
+ } catch (IOException | InterruptedException e) {
+ throw new PluginException(this.getClass().getName(), "Zoho API error",
+ "Failed to export invoice to Zoho: " + e.getMessage(), e);
}
- /**
- * This method adds an attachment to an invoice
- *
- * @param invoiceId The Zoho invoice ID
- * @param file The FileData object containing the attachment
- * @param uriPattern The API endpoint pattern (e.g., "invoices")
- * @param accessToken The OAuth access token
- * @throws PluginException If the API call fails
- */
- public void attacheFileData(String invoiceId, FileData file, String uriPattern, String accessToken)
- throws PluginException {
- String uri = ZOHO_API_BASE_URL + uriPattern + "/" + invoiceId + "/attachment" +
- "?organization_id=" + zohoOAuthManager.getOrganization();
+ }
- logger.info("│ ├── add attachment '" + file.getName() + "'...");
- logger.fine("│ ├── ...uri: " + uri + "...");
+ /**
+ * Erstellt einen neuen Contact in Zoho Books
+ *
+ * @param companyName Der Firmenname für den neuen Contact
+ * @return Der erstellte ZohoContact mit contact_id
+ * @throws PluginException Wenn der API-Aufruf fehlschlägt
+ */
+ public ZohoContact createContact(String companyName, String accessToken) throws PluginException {
+ logger.info("├── Zoho create contact '" + companyName + "'...");
+ try {
+ // Contact-DTO vorbereiten
+ ZohoContact newContact = new ZohoContact();
+ newContact.setContactName(companyName); // Wir verwenden den Firmennamen auch als Contact Name
+ newContact.setCompanyName(companyName);
- try {
- // Generate a unique boundary
- String boundary = "----WebKitFormBoundary" + System.currentTimeMillis();
+ // JSON serialisieren
+ String requestBody = jsonb.toJson(newContact);
+ logger.fine("│ ├── " + requestBody);
+ String uri = zohoOAuthManager.getBaseURI() + "contacts?organization_id="
+ + zohoOAuthManager.getOrganization();
- // Build multipart request body
- byte[] header = ("--" + boundary + "\r\n" +
- "Content-Disposition: form-data; name=\"attachment\"; filename=\""
- + file.getName() + "\"\r\n" +
- "Content-Type: " + file.getContentType() + "\r\n\r\n")
- .getBytes(StandardCharsets.UTF_8);
+ HttpRequest request = HttpRequest.newBuilder().uri(URI.create(uri))
+ .header("Authorization", "Zoho-oauthtoken " + accessToken)
+ .header("Content-Type", "application/json").POST(HttpRequest.BodyPublishers.ofString(requestBody))
+ .build();
- byte[] footer = ("\r\n--" + boundary + "--\r\n").getBytes(StandardCharsets.UTF_8);
+ HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
+ logger.fine("├── Zoho Response:");
+ logger.fine("│ ├── Status Code: " + response.statusCode());
+ logger.fine("│ ├── Response Body: " + response.body());
+ if (response.statusCode() >= 300) {
+ throw new PluginException(this.getClass().getName(), "Zoho API error",
+ "Failed to create invoice. Status code: " + response.statusCode() + ", Response: "
+ + response.body());
+ }
- logger.fine("│ ├── content size=" + file.getContent().length);
- HttpRequest.BodyPublisher bodyPublisher = HttpRequest.BodyPublishers.ofByteArrays(
- Arrays.asList(header, file.getContent(), footer));
+ // Erfolgreiche Erstellung
+ ZohoContactCreateResponse createResponse = jsonb.fromJson(response.body(), ZohoContactCreateResponse.class);
+ if (createResponse != null) {
+ logger.info("│ ├── OK - contactID=" + createResponse.getContact().getContactId());
+ return createResponse.getContact();
+ } else {
+ throw new PluginException(this.getClass().getName(), "Zoho API error",
+ "Response could not be resolved!");
+ }
- // Create and send the request
- HttpRequest request = HttpRequest.newBuilder()
- .uri(URI.create(uri))
- .header("Authorization", "Zoho-oauthtoken " + accessToken)
- .header("Content-Type", "multipart/form-data; boundary=" + boundary)
- .POST(bodyPublisher)
- .build();
-
- HttpResponse response = httpClient.send(
- request,
- HttpResponse.BodyHandlers.ofString());
-
- logger.fine("├── Zoho Response:");
- logger.fine("│ ├── Status Code: " + response.statusCode());
- logger.fine("│ ├── Response Body: " + response.body());
-
- if (response.statusCode() >= 300) {
- throw new PluginException(this.getClass().getName(), "Zoho API error",
- "Failed to add attachment. Status code: " + response.statusCode() +
- ", Response: " + response.body());
- }
-
- logger.info("│ ├── OK - Attachment added successfully");
-
- } catch (IOException | InterruptedException e) {
- throw new PluginException(this.getClass().getName(), "Zoho API error",
- "Failed to add attachment: " + e.getMessage(), e);
- }
+ } catch (IOException | InterruptedException e) {
+ throw new PluginException(this.getClass().getName(), "Zoho API error",
+ "Failed to create contact: " + e.getMessage(), e);
}
+ }
+
+ private ZohoInvoice convertToZohoInvoice(ItemCollection invoice, String contactID, String accessToken)
+ throws PluginException {
+
+ ZohoInvoice zohoInvoice = new ZohoInvoice();
+ // Basisinformationen
+
+ zohoInvoice.setInvoiceNumber(invoice.getItemValueString("invoice.number"));
+ zohoInvoice.setDate(
+ LocalDate.ofInstant(invoice.getItemValueDate("invoice.date").toInstant(), ZoneId.systemDefault()));
+
+ zohoInvoice.setDueDate(
+ LocalDate.ofInstant(invoice.getItemValueDate("invoice.duedate").toInstant(), ZoneId.systemDefault()));
+
+ zohoInvoice.setTotal(invoice.getItemValueDouble("invoice.total"));
+ // Kunden-ID (muss angepasst werden je nachdem wie du sie speicherst)
+ zohoInvoice.setCustomerId(contactID);
+ List positionen = InvoiceUtil.explodeChildList(invoice);
+
+ List lineItems = positionen.stream().map(item -> {
+ ItemCollection itemCol = (ItemCollection) item;
+ ZohoInvoiceItem lineItem = new ZohoInvoiceItem();
+ lineItem.setName(itemCol.getItemValueString("datev.text"));
+ lineItem.setDescription(itemCol.getItemValueString("billingtext"));
+ lineItem.setRate(itemCol.getItemValueDouble("datev.umsatz"));
+ lineItem.setQuantity(1);
+ return lineItem;
+ }).collect(Collectors.toList());
+
+ zohoInvoice.setLineItems(lineItems);
+ return zohoInvoice;
+ }
+
+ /**
+ * This method adds an attachment to an invoice
+ *
+ * @param invoiceId The Zoho invoice ID
+ * @param file The FileData object containing the attachment
+ * @param uriPattern The API endpoint pattern (e.g., "invoices")
+ * @param accessToken The OAuth access token
+ * @throws PluginException If the API call fails
+ */
+ public void attacheFileData(String invoiceId, FileData file, String uriPattern, String accessToken)
+ throws PluginException {
+ String uri = zohoOAuthManager.getBaseURI() + uriPattern + "/" + //
+ invoiceId + //
+ "/attachment" + //
+ "?organization_id=" + zohoOAuthManager.getOrganization();
+
+ logger.info("│ ├── add attachment '" + file.getName() + "'...");
+ logger.fine("│ ├── ...uri: " + uri + "...");
+
+ try {
+ // Generate a unique boundary
+ String boundary = "----WebKitFormBoundary" + System.currentTimeMillis();
+
+ // Build multipart request body
+ byte[] header = ("--" + boundary + "\r\n"
+ + "Content-Disposition: form-data; name=\"attachment\"; filename=\"" + file.getName() + "\"\r\n"
+ + "Content-Type: " + file.getContentType() + "\r\n\r\n").getBytes(StandardCharsets.UTF_8);
+
+ byte[] footer = ("\r\n--" + boundary + "--\r\n").getBytes(StandardCharsets.UTF_8);
+
+ logger.fine("│ ├── content size=" + file.getContent().length);
+ HttpRequest.BodyPublisher bodyPublisher = HttpRequest.BodyPublishers
+ .ofByteArrays(Arrays.asList(header, file.getContent(), footer));
+
+ // Create and send the request
+ HttpRequest request = HttpRequest.newBuilder().uri(URI.create(uri))
+ .header("Authorization", "Zoho-oauthtoken " + accessToken)
+ .header("Content-Type", "multipart/form-data; boundary=" + boundary).POST(bodyPublisher).build();
+
+ HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
+
+ logger.fine("├── Zoho Response:");
+ logger.fine("│ ├── Status Code: " + response.statusCode());
+ logger.fine("│ ├── Response Body: " + response.body());
+
+ if (response.statusCode() >= 300) {
+ throw new PluginException(this.getClass().getName(), "Zoho API error",
+ "Failed to add attachment. Status code: " + response.statusCode() + ", Response: "
+ + response.body());
+ }
+
+ logger.info("│ ├── OK - Attachment added successfully");
+
+ } catch (IOException | InterruptedException e) {
+ throw new PluginException(this.getClass().getName(), "Zoho API error",
+ "Failed to add attachment: " + e.getMessage(), e);
+ }
+ }
+
}
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoController.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoController.java
index 6f7675d..292012a 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoController.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoController.java
@@ -2,26 +2,26 @@ package com.alexanderlogistics.zoho;
/*******************************************************************************
* Imixs Workflow Technology
- * Copyright (C) 2003, 2008 Imixs Software Solutions GmbH,
+ * Copyright (C) 2003, 2008 Imixs Software Solutions GmbH,
* http://www.imixs.com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
- *
+ *
* You can receive a copy of the GNU General Public
* License at http://www.gnu.org/licenses/gpl.html
- *
- * Contributors:
+ *
+ * Contributors:
* Imixs Software Solutions GmbH - initial API and implementation
* Ralph Soika
- *
+ *
*******************************************************************************/
import java.util.logging.Logger;
@@ -35,54 +35,54 @@ import jakarta.inject.Named;
/**
* Der ZohoController ist für das Admin Interface um Access Tokens zu erzeugen.
- *
+ *
* @see admin/zoho.xhml
- *
+ *
* @author rsoika
- *
+ *
*/
@Named("zohoController")
@ApplicationScoped
public class ZohoController extends ConfigController {
- public static final String ZOHO_CONFIGURATION = "ZOHO_CONFIGURATION";
+ public static final String ZOHO_CONFIGURATION = "ZOHO_CONFIGURATION";
- private static final long serialVersionUID = 1L;
- private static Logger logger = Logger.getLogger(ZohoController.class.getName());
+ private static final long serialVersionUID = 1L;
+ private static Logger logger = Logger.getLogger(ZohoController.class.getName());
- @Inject
- ZohoOAuthManager zohoOAuthManager;
+ @Inject
+ ZohoOAuthManager zohoOAuthManager;
- public ZohoController() {
- super();
- setName(ZOHO_CONFIGURATION);
- }
+ public ZohoController() {
+ super();
+ setName(ZOHO_CONFIGURATION);
+ }
- /**
- * Ruft zohoOAuhtManager.updateToken auf
- */
- public void updateAccessToken() {
- //
- try {
- zohoOAuthManager.updateTokens(this.getWorkitem().getItemValueString("zoho.code"));
- } catch (PluginException e) {
- String message = "Failed to generate token: " + e.getMessage();
- logger.warning(message);
- this.getWorkitem().setItemValue("message", message);
- }
- }
+ /**
+ * Ruft zohoOAuhtManager.updateToken auf
+ */
+ public void updateAccessToken() {
+ //
+ try {
+ zohoOAuthManager.updateTokens(this.getWorkitem().getItemValueString("zoho.code"));
+ } catch (PluginException e) {
+ String message = "Failed to generate token: " + e.getMessage();
+ logger.warning(message);
+ this.getWorkitem().setItemValue("message", message);
+ }
+ }
- /**
- * Ruft zohoOAuhtManager.refreshToken auf
- */
- public void refreshAccessToken() {
- //
- try {
- zohoOAuthManager.refreshAccessToken();
- } catch (PluginException e) {
- String message = "Failed to refresh token: " + e.getMessage();
- logger.warning(message);
- this.getWorkitem().setItemValue("message", message);
- }
- }
+ /**
+ * Ruft zohoOAuhtManager.refreshToken auf
+ */
+ public void refreshAccessToken() {
+ //
+ try {
+ zohoOAuthManager.refreshAccessToken();
+ } catch (PluginException e) {
+ String message = "Failed to refresh token: " + e.getMessage();
+ logger.warning(message);
+ this.getWorkitem().setItemValue("message", message);
+ }
+ }
}
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoExportAdapter.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoExportAdapter.java
index 0909a53..9394df1 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoExportAdapter.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoExportAdapter.java
@@ -18,7 +18,7 @@ import jakarta.inject.Inject;
/**
* This adapter exports the invoice data to zoho
- *
+ *
* @version 1.0
* @author rsoika
*/
@@ -44,7 +44,7 @@ public class ZohoExportAdapter implements SignalAdapter {
/**
* This method calls the zoho api
- *
+ *
* @throws PluginException
*/
@Override
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoOAuthCallbackService.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoOAuthCallbackService.java
index 6c2ffaa..8afb329 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoOAuthCallbackService.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoOAuthCallbackService.java
@@ -1,27 +1,27 @@
-/*
- * Imixs-Workflow
- *
- * Copyright (C) 2001-2020 Imixs Software Solutions GmbH,
+/*
+ * Imixs-Workflow
+ *
+ * Copyright (C) 2001-2020 Imixs Software Solutions GmbH,
* http://www.imixs.com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
- *
+ *
* You can receive a copy of the GNU General Public
* License at http://www.gnu.org/licenses/gpl.html
- *
- * Project:
+ *
+ * Project:
* https://www.imixs.org
* https://github.com/imixs/imixs-workflow
- *
- * Contributors:
+ *
+ * Contributors:
* Imixs Software Solutions GmbH - Project Management
* Ralph Soika - Software Developer
*/
@@ -45,20 +45,20 @@ import jakarta.ws.rs.core.MediaType;
/**
* Dieser API Endpoint dient dazu über zoho einen sogenannten Grant Token zu
* erhalten.
- *
+ *
* https://www.zoho.com/books/api/v3/oauth/
- *
+ *
* Der Service wird aktuell nicht benötigt, das wir sogenannte Zoho Self-Clients
* verwenden!
- *
+ *
* Der Service stellt im Grunde nur eine Callback URL für einen normalen Zoho
- * Client ein. Also wenn jemand einen solchen Token über den Browser
- * anfordert. Der URL muss dann odrt als CallBack URL angegeben sein!
- *
+ * Client ein. Also wenn jemand einen solchen Token über den Browser anfordert.
+ * Der URL muss dann odrt als CallBack URL angegeben sein!
+ *
* Beispiel:
- *
+ *
* https://accounts.zoho.com/oauth/v2/auth?scope=ZohoBooks.invoices.CREATE,ZohoBooks.invoices.READ,ZohoBooks.invoices.UPDATE,ZohoBooks.invoices.DELETE&client_id=1000.NLTM2KUEHI696MSLGEIANATVGGX7IN&state=testing&response_type=code&redirect_uri=https://alexander-logistics-dwc.office-workflow.de/api/zoho/grant
- *
+ *
* @version 1.0
* @author rsoika
*
@@ -85,15 +85,14 @@ public class ZohoOAuthCallbackService {
/**
* Receive Grant Code.
- *
+ *
* The expected query params look like this:
- *
+ *
* state=testing
* code=1000.c27802b99c007ad8db93a5a7291cb15a.8cb60b6a51df13ea627ef3ac7c2e4791
- * location=eu
- * accounts-server=https%3A%2F%2Faccounts.zoho.eu
- *
- *
+ * location=eu accounts-server=https%3A%2F%2Faccounts.zoho.eu
+ *
+ *
* @param workflowgroup
* @param task
* @return
@@ -102,11 +101,8 @@ public class ZohoOAuthCallbackService {
@GET
@Path("/grant")
@Produces({ MediaType.TEXT_HTML })
- public String getGrantToken(
- @QueryParam("state") String state,
- @QueryParam("code") String code,
- @QueryParam("location") String location,
- @QueryParam("accounts-server") String accountsServer)
+ public String getGrantToken(@QueryParam("state") String state, @QueryParam("code") String code,
+ @QueryParam("location") String location, @QueryParam("accounts-server") String accountsServer)
throws QueryException {
logger.info("├── Receive Grant Token from Zoho");
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoOAuthManager.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoOAuthManager.java
index f888173..666c5fe 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoOAuthManager.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoOAuthManager.java
@@ -27,8 +27,8 @@ import jakarta.json.bind.JsonbBuilder;
/**
* Der ZohoOAuthManager stellt Methoden bereit um einen Access Token zu
* erstellen.
- *
- *
+ *
+ *
*/
@Singleton
@RunAs("org.imixs.ACCESSLEVEL.MANAGERACCESS")
@@ -47,9 +47,7 @@ public class ZohoOAuthManager {
@PostConstruct
void init() {
- this.httpClient = HttpClient.newBuilder()
- .connectTimeout(Duration.ofSeconds(10))
- .build();
+ this.httpClient = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
this.jsonb = JsonbBuilder.create();
}
@@ -57,7 +55,7 @@ public class ZohoOAuthManager {
* Gibt den aktuellen Access Token zurück. Falls dieser expired ist wird
* automatisch ein refresh durchgeführt. Somit liefert die Methode immer einen
* gültigen token.
- *
+ *
* @return
* @throws PluginException
*/
@@ -87,14 +85,26 @@ public class ZohoOAuthManager {
return null;
}
+ public String getBaseURI() throws PluginException {
+ String uri = "";
+ ItemCollection zohoConfig = configService.loadConfiguration(ZohoController.ZOHO_CONFIGURATION, false);
+ if (zohoConfig != null) {
+ uri = zohoConfig.getItemValueString("zoho.uri");
+ if (!uri.endsWith("/")) {
+ uri = uri + "/";
+ }
+ }
+ return uri;
+ }
+
/**
* Step 3: Generate Access and Refresh Token
- *
+ *
* After getting code from the GrantService we make a POST request
- *
+ *
* See description: https://www.zoho.com/books/api/v3/oauth/
- *
- *
+ *
+ *
* @param code
* @throws PluginException
*/
@@ -107,24 +117,21 @@ public class ZohoOAuthManager {
String clientID = zohoConfig.getItemValueString("zoho.clientid");
String clientSecret = zohoConfig.getItemValueString("zoho.clientsecret");
- String requestUrl = "https://accounts.zoho.eu/oauth/v2/token" +
- "?code=" + URLEncoder.encode(code, StandardCharsets.UTF_8) +
- "&client_id=" + URLEncoder.encode(clientID, StandardCharsets.UTF_8) +
- "&client_secret=" + URLEncoder.encode(clientSecret, StandardCharsets.UTF_8) +
- "&redirect_uri=" + URLEncoder.encode(redirectURI, StandardCharsets.UTF_8) +
- "&grant_type=authorization_code";
+ String requestUrl = "https://accounts.zoho.eu/oauth/v2/token" + "?code="
+ + URLEncoder.encode(code, StandardCharsets.UTF_8) + "&client_id="
+ + URLEncoder.encode(clientID, StandardCharsets.UTF_8) + "&client_secret="
+ + URLEncoder.encode(clientSecret, StandardCharsets.UTF_8) + "&redirect_uri="
+ + URLEncoder.encode(redirectURI, StandardCharsets.UTF_8) + "&grant_type=authorization_code";
logger.fine("│ ├── Request URI=" + requestUrl);
- HttpRequest request = HttpRequest.newBuilder()
- .uri(URI.create(requestUrl))
+ HttpRequest request = HttpRequest.newBuilder().uri(URI.create(requestUrl))
.header("Content-Type", "application/x-www-form-urlencoded")
.POST(HttpRequest.BodyPublishers.noBody()) // Wichtig: Kein Body!
.build();
HttpResponse response;
- response = httpClient.send(request,
- HttpResponse.BodyHandlers.ofString());
+ response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
logger.fine("│ ├── Response statusCode=" + response.statusCode());
if (response.statusCode() == 200) {
@@ -132,29 +139,26 @@ public class ZohoOAuthManager {
logger.fine("│ ├── Response Body=" + response.body());
if (response.body().contains("error")) {
- throw new PluginException(ZohoOAuthManager.class.getSimpleName(),
- ZohoOAuthManager.ERROR_CONFIG,
+ throw new PluginException(ZohoOAuthManager.class.getSimpleName(), ZohoOAuthManager.ERROR_CONFIG,
"Ungültiger Access Code!");
}
- TokenResponse tokenResponse = jsonb.fromJson(response.body(),
- TokenResponse.class);
+ TokenResponse tokenResponse = jsonb.fromJson(response.body(), TokenResponse.class);
saveTokenData(zohoConfig, tokenResponse);
} else {
- throw new RuntimeException("Failed to get tokens: " +
- response.statusCode() + " - " + response.body());
+ throw new RuntimeException("Failed to get tokens: " + response.statusCode() + " - " + response.body());
}
} catch (IOException | InterruptedException e) {
- throw new PluginException(ZohoOAuthManager.class.getSimpleName(),
- ZohoOAuthManager.ERROR_CONFIG, "Unable to resolve access tokens: " + e.getMessage());
+ throw new PluginException(ZohoOAuthManager.class.getSimpleName(), ZohoOAuthManager.ERROR_CONFIG,
+ "Unable to resolve access tokens: " + e.getMessage());
}
}
/**
* This method updates the Access Token based on the current Refresh Token
- *
+ *
* @throws IOException
* @throws PluginException
*/
@@ -168,26 +172,21 @@ public class ZohoOAuthManager {
String refreshToken = zohoConfig.getItemValueString("zoho.refreshToken");
try {
- String requestUrl = "https://accounts.zoho.eu/oauth/v2/token" +
- "?refresh_token=" + URLEncoder.encode(refreshToken, StandardCharsets.UTF_8) +
- "&client_id=" + URLEncoder.encode(clientID, StandardCharsets.UTF_8) +
- "&client_secret=" + URLEncoder.encode(clientSecret,
- StandardCharsets.UTF_8)
- +
- "&grant_type=refresh_token";
+ String requestUrl = "https://accounts.zoho.eu/oauth/v2/token" + "?refresh_token="
+ + URLEncoder.encode(refreshToken, StandardCharsets.UTF_8) + "&client_id="
+ + URLEncoder.encode(clientID, StandardCharsets.UTF_8) + "&client_secret="
+ + URLEncoder.encode(clientSecret, StandardCharsets.UTF_8) + "&grant_type=refresh_token";
logger.fine("│ ├── Request URI=" + requestUrl);
- HttpRequest request = HttpRequest.newBuilder()
- .uri(URI.create(requestUrl))
+ HttpRequest request = HttpRequest.newBuilder().uri(URI.create(requestUrl))
.header("Content-Type", "application/x-www-form-urlencoded")
.POST(HttpRequest.BodyPublishers.noBody()) // Wichtig: Kein Body!
.build();
HttpResponse response;
- response = httpClient.send(request,
- HttpResponse.BodyHandlers.ofString());
+ response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
logger.fine("│ ├── Response statusCode=" + response.statusCode());
if (response.statusCode() == 200) {
@@ -195,25 +194,23 @@ public class ZohoOAuthManager {
// 1. Response-Logging für Debugging
logger.fine("│ ├── Response Body=" + response.body());
- TokenResponse tokenResponse = jsonb.fromJson(response.body(),
- TokenResponse.class);
+ TokenResponse tokenResponse = jsonb.fromJson(response.body(), TokenResponse.class);
saveTokenData(zohoConfig, tokenResponse);
return zohoConfig.getItemValueString("zoho.accessToken");
} else {
- throw new RuntimeException("Failed to get tokens: " +
- response.statusCode() + " - " + response.body());
+ throw new RuntimeException("Failed to get tokens: " + response.statusCode() + " - " + response.body());
}
} catch (IOException | InterruptedException e) {
- throw new PluginException(ZohoOAuthManager.class.getSimpleName(),
- ZohoOAuthManager.ERROR_CONFIG, "Unable to refresh access tokens: " + e.getMessage());
+ throw new PluginException(ZohoOAuthManager.class.getSimpleName(), ZohoOAuthManager.ERROR_CONFIG,
+ "Unable to refresh access tokens: " + e.getMessage());
}
}
/**
* Helper method to update the config itemcolleciton based on a tokenResponse
- *
+ *
* @param zohoConfig
* @param tokenResponse
*/
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/dto/ZohoInvoiceItem.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/dto/ZohoInvoiceItem.java
index 8971bd5..5fe608a 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/dto/ZohoInvoiceItem.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/dto/ZohoInvoiceItem.java
@@ -1,42 +1,42 @@
package com.alexanderlogistics.zoho.dto;
public class ZohoInvoiceItem {
- private String name;
- private String description;
- private double rate;
- private int quantity;
+ private String name;
+ private String description;
+ private double rate;
+ private int quantity;
- // Getter und Setter
+ // Getter und Setter
- public String getName() {
- return name;
- }
+ public String getName() {
+ return name;
+ }
- public void setName(String name) {
- this.name = name;
- }
+ public void setName(String name) {
+ this.name = name;
+ }
- public String getDescription() {
- return description;
- }
+ public String getDescription() {
+ return description;
+ }
- public void setDescription(String description) {
- this.description = description;
- }
+ public void setDescription(String description) {
+ this.description = description;
+ }
- public double getRate() {
- return rate;
- }
+ public double getRate() {
+ return rate;
+ }
- public void setRate(double rate) {
- this.rate = rate;
- }
+ public void setRate(double rate) {
+ this.rate = rate;
+ }
- public int getQuantity() {
- return quantity;
- }
+ public int getQuantity() {
+ return quantity;
+ }
- public void setQuantity(int quantity) {
- this.quantity = quantity;
- }
+ public void setQuantity(int quantity) {
+ this.quantity = quantity;
+ }
}
diff --git a/office-alexander-logistics-app/src/main/java/org/imixs/workflow/office/forms/AnalyticController.java b/office-alexander-logistics-app/src/main/java/org/imixs/workflow/office/forms/AnalyticController.java
index 923a98c..3952bd6 100644
--- a/office-alexander-logistics-app/src/main/java/org/imixs/workflow/office/forms/AnalyticController.java
+++ b/office-alexander-logistics-app/src/main/java/org/imixs/workflow/office/forms/AnalyticController.java
@@ -24,8 +24,8 @@ import jakarta.inject.Named;
* The controller implements a caching mechanism to avoid repeated calls for new
* analytic values. If the analytic value is already stored in the current
* workitem, no new value will be fired.
- *
- *
+ *
+ *
* @author rsoika
*
*/
@@ -33,150 +33,149 @@ import jakarta.inject.Named;
@ConversationScoped
public class AnalyticController implements Serializable {
- private static final long serialVersionUID = 1L;
- private static Logger logger = Logger.getLogger(AnalyticController.class.getName());
+ private static final long serialVersionUID = 1L;
+ private static Logger logger = Logger.getLogger(AnalyticController.class.getName());
- @Inject
- protected Event analyticEvents;
+ @Inject
+ protected Event analyticEvents;
- @Inject
- protected WorkflowController workflowController;
+ @Inject
+ protected WorkflowController workflowController;
- /**
- * Returns a analytic value as a String for a given key.
- *
- * @param key
- * @return
- */
- public String getAsString(String key) {
- ItemCollection analyticData = computeValue(key);
- return analyticData.getItemValueString("value");
- }
+ /**
+ * Returns a analytic value as a String for a given key.
+ *
+ * @param key
+ * @return
+ */
+ public String getAsString(String key) {
+ ItemCollection analyticData = computeValue(key);
+ return analyticData.getItemValueString("value");
+ }
- /**
- * Returns a analytic value as a Json String for a given key.
- *
- * @param key
- * @return
- */
- public String getAsJson(String key) {
- ItemCollection analyticData = computeValue(key);
- String jsonval = analyticData.getItemValueString("value");
- if (jsonval == null || jsonval.isEmpty()) {
- return "null";
- } else {
- return jsonval;
- }
- }
+ /**
+ * Returns a analytic value as a Json String for a given key.
+ *
+ * @param key
+ * @return
+ */
+ public String getAsJson(String key) {
+ ItemCollection analyticData = computeValue(key);
+ String jsonval = analyticData.getItemValueString("value");
+ if (jsonval == null || jsonval.isEmpty()) {
+ return "null";
+ } else {
+ return jsonval;
+ }
+ }
- /**
- * Returns a analytic value as a Double for a given key.
- *
- * @param key
- * @return
- */
- public double getAsDouble(String key) {
- ItemCollection analyticData = computeValue(key);
- return analyticData.getItemValueDouble("value");
- }
+ /**
+ * Returns a analytic value as a Double for a given key.
+ *
+ * @param key
+ * @return
+ */
+ public double getAsDouble(String key) {
+ ItemCollection analyticData = computeValue(key);
+ return analyticData.getItemValueDouble("value");
+ }
- /**
- * Returns the analytic label for a given key
- *
- * @param key
- * @return
- */
- public String getLabel(String key) {
- ItemCollection analyticData = computeValue(key);
- return analyticData.getItemValueString("label");
- }
+ /**
+ * Returns the analytic label for a given key
+ *
+ * @param key
+ * @return
+ */
+ public String getLabel(String key) {
+ ItemCollection analyticData = computeValue(key);
+ return analyticData.getItemValueString("label");
+ }
- /**
- * Returns the analytic optional link for a given key
- *
- * @param key
- * @return
- */
- public String getLink(String key) {
- ItemCollection analyticData = computeValue(key);
- return analyticData.getItemValueString("link");
- }
+ /**
+ * Returns the analytic optional link for a given key
+ *
+ * @param key
+ * @return
+ */
+ public String getLink(String key) {
+ ItemCollection analyticData = computeValue(key);
+ return analyticData.getItemValueString("link");
+ }
- /**
- * Returns the analytic description for a given key
- *
- * @param key
- * @return
- */
- public String getDescription(String key) {
- ItemCollection analyticData = computeValue(key);
- return analyticData.getItemValueString("description");
- }
+ /**
+ * Returns the analytic description for a given key
+ *
+ * @param key
+ * @return
+ */
+ public String getDescription(String key) {
+ ItemCollection analyticData = computeValue(key);
+ return analyticData.getItemValueString("description");
+ }
- /**
- * Computes an analytic value. The method cache the value in the
- * item key.
- *
- * An observer controller is responsible to cache or reset the cached values if
- * needed.
- *
- * @param key
- * @return
- */
- protected ItemCollection computeValue(String key) {
- if (workflowController.getWorkitem() != null) {
- logger.fine("fire analytic event for key '" + key + "'");
- // Fire the Analytics Event for this key
- AnalyticEvent event = new AnalyticEvent(key, workflowController.getWorkitem());
- if (analyticEvents != null) {
- analyticEvents.fire(event);
- if (event.getValue() != null) {
- ItemCollection details = new ItemCollection();
- details.setItemValue("value", event.getValue());
- details.setItemValue("label", event.getLabel());
- details.setItemValue("description", event.getDescription());
- details.setItemValue("link", event.getLink());
- // cache result
- implodeDetails(key, details);
- }
- }
- }
+ /**
+ * Computes an analytic value. The method cache the value in the item key.
+ *
+ * An observer controller is responsible to cache or reset the cached values if
+ * needed.
+ *
+ * @param key
+ * @return
+ */
+ protected ItemCollection computeValue(String key) {
+ if (workflowController.getWorkitem() != null) {
+ logger.fine("fire analytic event for key '" + key + "'");
+ // Fire the Analytics Event for this key
+ AnalyticEvent event = new AnalyticEvent(key, workflowController.getWorkitem());
+ if (analyticEvents != null) {
+ analyticEvents.fire(event);
+ if (event.getValue() != null) {
+ ItemCollection details = new ItemCollection();
+ details.setItemValue("value", event.getValue());
+ details.setItemValue("label", event.getLabel());
+ details.setItemValue("description", event.getDescription());
+ details.setItemValue("link", event.getLink());
+ // cache result
+ implodeDetails(key, details);
+ }
+ }
+ }
- // analytic value is now already cached!
- return explodeDetails(key);
- }
+ // analytic value is now already cached!
+ return explodeDetails(key);
+ }
- /**
- * Convert the List of ItemCollections back into a List of Map elements
- *
- * @param workitem
- */
- @SuppressWarnings({ "rawtypes" })
- private void implodeDetails(String key, ItemCollection details) {
- // convert the child ItemCollection elements into a List of Map
- List