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 bedde9b..ebdff55 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
@@ -38,6 +38,18 @@ public class InvoiceUtil {
return bd.doubleValue();
}
+ /**
+ * Rounds a Flat Value
+ *
+ * @param value
+ * @return
+ */
+ public static float roundToFloat(double value) {
+ BigDecimal bd = BigDecimal.valueOf(value);
+ bd = bd.setScale(2, RoundingMode.HALF_UP);
+ return bd.floatValue();
+ }
+
/**
* Hilfsmethode zum validieren der Mailadresse
*
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 12e3fda..e71d395 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
@@ -173,7 +173,7 @@ public class OPListController implements Serializable {
float rate = invoice.getItemValueFloat("invoice.rate");
float maxSaldo = invoice.getItemValueFloat("invoice.saldo");
if (rate != 0) {
- maxSaldo = maxSaldo / rate;
+ maxSaldo = InvoiceUtil.roundToFloat(maxSaldo / rate);
invoice.setItemValue("invoice.saldo.byrate", maxSaldo);
}
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 7e60d1d..7ab9887 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
@@ -160,7 +160,7 @@ public class ZahlungseingangSaldoAdapter implements SignalAdapter {
invoiceSaldo = invoiceSaldo - invoicePaymentAmount;
}
invoiceSaldo = (float) InvoiceUtil.round(invoiceSaldo);
- invoice.setItemValue("invoice.saldo", invoiceSaldo);
+ invoice.setItemValue("invoice.saldo", InvoiceUtil.roundToFloat(invoiceSaldo));
invoice.event(ZahlungseingangService.EVENT_UPDATE_INVOICE);
zahlungseingangService.processInvoice(invoice);
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 bdaf303..4a20ba9 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
@@ -621,8 +621,8 @@ public class CargosoftMigrationRestService implements Serializable {
total = total + tax;
saldo = saldo + tax;
}
- workitem.setItemValue("invoice.total", total);
- workitem.setItemValue("invoice.saldo", saldo);
+ workitem.setItemValue("invoice.total", InvoiceUtil.round(total));
+ workitem.setItemValue("invoice.saldo", InvoiceUtil.round(saldo));
workitem.setItemValue("cargosoft.fix.xmlerror", tax);
log = log + "....... total neu=" + total + " saldo neu=" + saldo + "\n";
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/MetricDebitorRestService.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/metrics/MetricDebitorRestService.java
similarity index 74%
rename from office-alexander-logistics-app/src/main/java/com/alexanderlogistics/MetricDebitorRestService.java
rename to office-alexander-logistics-app/src/main/java/com/alexanderlogistics/metrics/MetricDebitorRestService.java
index 55638c3..a7a8f3e 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/MetricDebitorRestService.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/metrics/MetricDebitorRestService.java
@@ -1,7 +1,5 @@
-package com.alexanderlogistics;
+package com.alexanderlogistics.metrics;
-import java.util.ArrayList;
-import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -9,11 +7,12 @@ import java.util.logging.Logger;
import org.imixs.marty.team.TeamService;
import org.imixs.workflow.ItemCollection;
-import org.imixs.workflow.ItemCollectionComparator;
import org.imixs.workflow.engine.DocumentService;
import org.imixs.workflow.exceptions.PluginException;
import org.imixs.workflow.exceptions.QueryException;
+import com.alexanderlogistics.InvoiceUtil;
+
import jakarta.ejb.Stateless;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
@@ -88,22 +87,15 @@ public class MetricDebitorRestService {
long l = System.currentTimeMillis();
logger.info("├── init metrics...");
try {
- // compute all departments
- List spaceNames = new ArrayList();
- List spaces = teamService.getSpaces();
- // sort by space.name
- Collections.sort(spaces, new ItemCollectionComparator("space.name", true));
- for (ItemCollection space : spaces) {
- String spaceName = space.getItemValueString("space.name");
- spaceNames.add(spaceName);
- logger.info("│ ├── grouping invoices by debitor...");
- groupInvoicesByWeek(space.getUniqueID(), spaceName, metricCache);
- }
+ groupInvoicesByDebitor(metricCache);
logger.info("│ ├── grouping invoices finished in " + (System.currentTimeMillis() - l) + "ms");
rebuildMetrics(metricCache);
- logger.info("├── init metrics completed in " + (System.currentTimeMillis() - l) + "ms");
- return Response.ok().entity("init metrics completed in " + (System.currentTimeMillis() - l) + "ms").build();
+ String message = "├── init " + metricCache.size() + " metrics completed in "
+ + (System.currentTimeMillis() - l)
+ + "ms";
+ logger.info(message);
+ return Response.ok().entity(message).build();
} catch (Exception e) {
e.printStackTrace();
@@ -118,13 +110,8 @@ public class MetricDebitorRestService {
for (String dbtrNumber : metricCache.keySet()) {
ItemCollection metricData = metricCache.get(dbtrNumber);
- // String dbtrName = metricData.getItemValueString("dbtr.name");
-
- // ItemCollection metric = metricService.loadMetric(dbtrNumber, dbtrName);
- // metric.setItemValue(MetricDebitorService.ITEM_TOTALS, metricData.totals);
documentService.save(metricData);
metricService.initMetric(metricData);
-
}
}
@@ -138,18 +125,17 @@ public class MetricDebitorRestService {
*
*
*/
- private void groupInvoicesByWeek(String spaceID, String spaceName,
+ private void groupInvoicesByDebitor(
Map metricCache) {
- logger.info("│ │ ├── group invoices for " + spaceName + "/" + spaceID);
+ logger.info("│ │ ├── group invoices by debitor...");
try {
List invoices = documentService.find(
- "$modelversion:rechnungsausgang-* AND type:workitem AND $uniqueidref:" +
- spaceID,
+ "$modelversion:rechnungsausgang-* AND type:workitem",
9999, 0,
"invoice.number", false);
- logger.fine(" found " + invoices.size() + " for space " + spaceName);
+ logger.fine(" found " + invoices.size() + " open invoices");
for (ItemCollection invoice : invoices) {
String debitorName = invoice.getItemValueString("dbtr.name");
@@ -157,15 +143,26 @@ public class MetricDebitorRestService {
ItemCollection metricData = metricCache.get(debitorNumber);
if (metricData == null) {
- metricData = metricService.createMetaData(debitorNumber, debitorName);
+ try {
+ metricData = metricService.loadMetric(debitorNumber, debitorName);
+ // reset old metrics now!
+ for (String itemName : metricData.getItemNames()) {
+ if (itemName.startsWith(MetricDebitorService.ITEM_SALDO + ".")) {
+ metricData.setItemValue(itemName, 0.0);
+ }
+ }
+ } catch (PluginException e) {
+ logger.severe(
+ "Unable to load metric for invoice " + invoice.getUniqueID() + " : " + e.getMessage());
+ continue;
+ }
}
-
// Jetzt Rechnung addieren
addInvoice(metricData, invoice);
// invoiceData.add(invoice);
metricCache.put(debitorNumber, metricData);
}
-
+ logger.info("│ │ ├── grouped " + invoices.size() + " invoices.");
} catch (QueryException e) {
e.printStackTrace();
}
@@ -180,7 +177,7 @@ public class MetricDebitorRestService {
*/
public void addInvoice(ItemCollection metricData, ItemCollection invoice) {
String currency = invoice.getItemValueString("invoice.currency");
- double saldo = invoice.getItemValueDouble("invoice.saldo");
+ double saldo = invoice.getItemValueDouble(MetricDebitorService.ITEM_SALDO);
double saldoOld = metricData.getItemValueDouble(MetricDebitorService.ITEM_SALDO + "." + currency);
double saldoNew = InvoiceUtil.round(saldoOld + saldo);
diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/MetricDebitorService.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/metrics/MetricDebitorService.java
similarity index 80%
rename from office-alexander-logistics-app/src/main/java/com/alexanderlogistics/MetricDebitorService.java
rename to office-alexander-logistics-app/src/main/java/com/alexanderlogistics/metrics/MetricDebitorService.java
index 03e3b7e..009daa2 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/MetricDebitorService.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/metrics/MetricDebitorService.java
@@ -1,7 +1,8 @@
-package com.alexanderlogistics;
+package com.alexanderlogistics.metrics;
import java.util.ArrayList;
import java.util.List;
+import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Logger;
@@ -16,6 +17,8 @@ import org.imixs.workflow.engine.ProcessingEvent;
import org.imixs.workflow.exceptions.PluginException;
import org.imixs.workflow.exceptions.QueryException;
+import com.alexanderlogistics.InvoiceUtil;
+
import jakarta.annotation.security.DeclareRoles;
import jakarta.annotation.security.RolesAllowed;
import jakarta.annotation.security.RunAs;
@@ -49,6 +52,7 @@ public class MetricDebitorService {
private static Logger logger = Logger.getLogger(MetricDebitorService.class.getName());
private final ConcurrentHashMap metricCache = new ConcurrentHashMap<>();
+ private final Set registeredGauges = ConcurrentHashMap.newKeySet();
public static final String TYPE_METRIC_DEBITOR = "metric.debitor";
public static final String ITEM_SALDO = "invoice.saldo";
@@ -84,6 +88,10 @@ public class MetricDebitorService {
// verify if saldo has changed.....
double invoiceSaldo = invoice.getItemValueDouble(ITEM_SALDO);
+ if (!"workitem".equals(invoice.getType())) {
+ // vorgang ist archiviert oder gelöscht worden => saldo = 0!
+ invoiceSaldo = 0.0;
+ }
String dbtrNumber = invoice.getItemValueString("dbtr.number");
String dbtrName = invoice.getItemValueString("dbtr.name");
String currency = invoice.getItemValueString("invoice.currency");
@@ -115,7 +123,7 @@ public class MetricDebitorService {
documentService.save(metricData);
// Gauge registrieren
- registerGauge(metricData, currency);
+ updateGauge(metricData, currency);
}
}
@@ -181,7 +189,7 @@ public class MetricDebitorService {
* @param dbtrName
* @return
*/
- public ItemCollection createMetaData(String dbtrNumber, String dbtrName) {
+ private ItemCollection createMetaData(String dbtrNumber, String dbtrName) {
ItemCollection metricData = new ItemCollection();
metricData = new ItemCollection();
@@ -192,6 +200,38 @@ public class MetricDebitorService {
return metricData;
}
+ /**
+ * Helper method to register a gauge for a debitor
+ *
+ * @param dbtrNumber - the debitor number
+ * @param dbtrName - the debitor name
+ */
+ private void updateGauge(ItemCollection metricData, String currency) {
+ String dbtrNumber = metricData.getItemValueString("dbtr.number");
+ String dbtrName = metricData.getItemValueString("dbtr.name");
+ String metricKey = "dbtr_" + dbtrNumber + "_" + dbtrName + "_" + currency;
+ // Prüfen ob Gauge bereits registriert ist
+ if (registeredGauges.add(metricKey)) { // returns true newly added
+ List tags = new ArrayList<>();
+ tags.add(new Tag("type", "dbtr"));
+ tags.add(new Tag("number", dbtrNumber));
+ tags.add(new Tag("name", dbtrName));
+ tags.add(new Tag("currency", currency));
+ logger.info("register new metric for debitor: " + dbtrNumber + " -> " + currency);
+ Metadata metadata = Metadata.builder()
+ .withName("dbtr.invoice.saldo")
+ .withDescription("Debitor Balance by Currency")
+ .build();
+ metricRegistry.gauge(metadata,
+ () -> metricCache.getOrDefault(dbtrNumber, createMetaData(dbtrNumber, dbtrName))
+ .getItemValueDouble(ITEM_SALDO + "." + currency),
+ tags.toArray(new Tag[0]));
+ } else {
+ logger.fine("Gauge already registered for debitor: " + dbtrNumber + " -> " + currency);
+ }
+
+ }
+
/**
* Hilfsmethode um Metriken initial aufzubauen. Wird vom Metric Rest Service
* verwendet.
@@ -206,38 +246,11 @@ public class MetricDebitorService {
if (itemName.startsWith(ITEM_SALDO + ".")) {
// currency value found
int pos = (ITEM_SALDO + ".").length();
- String currency = itemName.substring(pos + 1);
- logger.info("Init metric for debitor " + dbtrNumber + " -> " + currency);
- registerGauge(metric, currency);
+ String currency = itemName.substring(pos).toUpperCase();
+ logger.info("│ │ ├──init metric for debitor " + dbtrNumber + " -> " + currency);
+ updateGauge(metric, currency);
}
}
}
- /**
- * Helper method to register a gauge for a debitor
- *
- * @param dbtrNumber - the debitor number
- * @param dbtrName - the debitor name
- */
- private void registerGauge(ItemCollection metricData, String currency) {
- String dbtrNumber = metricData.getItemValueString("dbtr.number");
- String dbtrName = metricData.getItemValueString("dbtr.name");
- List tags = new ArrayList<>();
- tags.add(new Tag("type", "dbtr"));
- tags.add(new Tag("number", dbtrNumber));
- tags.add(new Tag("name", dbtrName));
- tags.add(new Tag("currency", currency));
-
- logger.info("Register metric for debitor: " + dbtrNumber + " -> " + currency);
- Metadata metadata = Metadata.builder()
- .withName("dbtr.invoice.saldo")
- .withDescription("Debitor Balance by Currency")
- .build();
-
- metricRegistry.gauge(metadata,
- () -> metricCache.getOrDefault(dbtrNumber, createMetaData(dbtrNumber, dbtrName))
- .getItemValueDouble(ITEM_SALDO + "." + currency),
- tags.toArray(new Tag[0]));
- }
-
}
\ No newline at end of file
diff --git a/workflow/dwc/rechnungsausgang-dwc-1.0.1.bpmn b/workflow/dwc/rechnungsausgang-dwc-1.0.1.bpmn
new file mode 100644
index 0000000..7d6a20e
--- /dev/null
+++ b/workflow/dwc/rechnungsausgang-dwc-1.0.1.bpmn
@@ -0,0 +1,1721 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+$workflowstatus
+
+]]>
+
+
+ In case you have already made the payment, please disregard this notice. If you require any information regarding your account, please do not hesitate to contact us.
+Thank you for your cooperation.
+
+Kind regards
Alexander Global Logistics GmbH
+
+