diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/AGLAnalyticControllerDebitor.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/AGLAnalyticControllerDebitor.java
index 83dbae0..631e973 100644
--- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/AGLAnalyticControllerDebitor.java
+++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/AGLAnalyticControllerDebitor.java
@@ -96,10 +96,11 @@ public class AGLAnalyticControllerDebitor implements Serializable {
// load all invoices?
if (invoices == null || (!dbtrNumber.isEmpty() && !dbtrNumber.equals(dbtrNumberLast))) {
+ resetStats();
+ event.getWorkitem().setItemValue("dbtr.number.last", dbtrNumber);
logger.info("Analyse new debitor data for : " + dbtrNumber);
loadRechnungen();
- event.getWorkitem().setItemValue("dbtr.number.last", dbtrNumber);
-
+ chartData = buildChartData();
}
String link = "/pages/workitems/worklist.xhtml" + "?phrase=" + getDbtNr();
@@ -187,13 +188,15 @@ public class AGLAnalyticControllerDebitor implements Serializable {
private void loadRechnungen() {
if (getDbtNr().isEmpty()) {
invoices = new ArrayList();
+ stats = null;
} else {
+ logger.info(" ├──load invoices for " + getDbtNr() + "....");
String query = "(type:workitem) AND dbtr.number:" + getDbtNr()
+ " AND $modelversion:rechnungsausgang-*";
try {
- logger.info("...debitor analysis for " + getDbtNr() + "....");
+ logger.info(" ├──refresh invoice stats for " + getDbtNr() + "....");
invoices = documentService.find(query, 999, 0, "$created", false);
- refreshStats();
+ calculateStats();
} catch (QueryException e) {
logger.warning("Failed to query invoices: " + query + " - Error: " + e.getMessage());
invoices = new ArrayList();
@@ -202,12 +205,17 @@ public class AGLAnalyticControllerDebitor implements Serializable {
}
- private void refreshStats() {
+ /**
+ * Läd die statistik daten zu einem debitor aus den aktuellen Rechnungen
+ */
+ private void calculateStats() {
countAll = 0;
countOpen = 0;
countDue = 0;
countDunning = 0;
- if (invoices != null) {
+ logger.info(" ├──calculate stats for " + getDbtNr() + "....");
+ // do we have data?
+ if (invoices != null && invoices.size() > 0) {
countAll = invoices.size();
for (ItemCollection invoice : invoices) {
@@ -264,15 +272,37 @@ public class AGLAnalyticControllerDebitor implements Serializable {
totalDunningCurrency1 = InvoiceUtil.round(totalDunningCurrency1);
totalDunningCurrency2 = InvoiceUtil.round(totalDunningCurrency2);
- chartData = buildChartData();
- // System.out.println(chartData);
+ } else {
+ // reset data because no invoices are available ...
+ resetStats();
- getDurchschnittZahlungsziel();
- getDurchschnittZahlungsdauer();
}
}
+ /**
+ * Setzt alle Statistikwerte zurück
+ */
+ private void resetStats() {
+ logger.info(" ├──reset stats for " + getDbtNr() + "....");
+ stats = null;
+
+ totalAllCurrency1 = 0;
+ totalAllCurrency2 = 0;
+ totalOpenCurrency1 = 0;
+ totalOpenCurrency2 = 0;
+ totalDueCurrency1 = 0;
+ totalDueCurrency2 = 0;
+ totalDunningCurrency1 = 0;
+ totalDunningCurrency2 = 0;
+
+ // chartData = null;
+ chartData = "{}";
+
+ averagePaymentDue = 0;
+ averagePaymentDays = 0;
+ }
+
private void getDurchschnittZahlungsziel() {
if (stats == null) {
averagePaymentDue = 0;
@@ -335,19 +365,20 @@ public class AGLAnalyticControllerDebitor implements Serializable {
* Zahlungszeitspanne gruppiert nach monaten
*
*/
- public Map getStats() {
+ public Map loadStats() {
if (stats != null) {
return stats;
}
+ logger.info(" ├──load stats for " + getDbtNr() + "....");
// recompute
stats = new TreeMap();
if (getDbtNr().isEmpty()) {
return stats;
}
- // Letzen 6 Monate
+ // Letzen 12 Monate
LocalDate endDate = LocalDate.now();
LocalDate startDate = endDate.minusMonths(12);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
@@ -372,7 +403,7 @@ public class AGLAnalyticControllerDebitor implements Serializable {
Date invoiceDueDate = invoice.getItemValueDate("invoice.duedate");
Date paymentDate = findPaymentDateByWorkitem(invoice);
if (paymentDate == null) {
- logger.warning("Es wurde kein Zahlungseingang gefunden");
+ logger.fine("Es wurde kein Zahlungseingang gefunden");
continue;
}
@@ -402,6 +433,10 @@ public class AGLAnalyticControllerDebitor implements Serializable {
}
// Step 2: Sort the list based on the alphanumeric order of the keys
completeMissingMonths();
+
+ // berechne zahluntsziel durchscnitt
+ getDurchschnittZahlungsziel();
+ getDurchschnittZahlungsdauer();
return stats;
}
@@ -475,8 +510,8 @@ public class AGLAnalyticControllerDebitor implements Serializable {
*/
public String buildChartData() {
- getStats();
-
+ loadStats();
+ logger.info(" ├──build chart for " + getDbtNr() + "....");
// build a list of all lables....
List statusLabels = new ArrayList();
@@ -488,38 +523,43 @@ public class AGLAnalyticControllerDebitor implements Serializable {
String result = "{\n \"type\": \"bar\",\n \"data\": { ";
// Lables
- result = result + "labels : [ ";
- result = result + statusLabels.stream().collect(Collectors.joining("','", "'", "'"));
+ result = result + "\"labels\" : [ ";
+ result = result + statusLabels.stream().collect(Collectors.joining("\",\"", "\"", "\""));
result = result + "],";
- result = result + "datasets: [";
+ result = result + "\"datasets\": [";
// Datasets 1
- result = result + "{label: 'Days for payment',borderWidth: 1,";
- result = result + " borderColor: [\"#3B6B82\"],";
- result = result + " \"backgroundColor\" : [\"#CFE9F5\"], fill: true,tension: 0.5,";
+ result = result + "{\"label\": \"Days for payment\",\"borderWidth\": 1,";
+ result = result + " \"borderColor\": [\"#3B6B82\"],";
+ result = result + " \"backgroundColor\" : [\"#CFE9F5\"], \"fill\": true,\"tension\": 0.5,";
- result = result + "data: [";
+ result = result + "\"data\": [";
for (Map.Entry entry : stats.entrySet()) {
result = result + entry.getValue().getAverageDueDays() + ",";
}
// cut last comma
- result = result.substring(0, result.length() - 1);
+ if (result.endsWith(",")) {
+ result = result.substring(0, result.length() - 1);
+ }
result = result + "]";
result = result + "}, ";
// Datasets 2
- result = result + "{label: 'Payment duration',borderWidth: 1,";
- result = result + " borderColor: [\"#E73B65\"],\"backgroundColor\" : [\"#70B088\" ], tension: 0.5,fill: true,";
+ result = result + "{\"label\": \"Payment duration\",\"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 },";
+ + " \"trendlineLinear\": { \"colorMin\": \"red\", \"colorMax\": \"green\", \"lineStyle\": \"dotted\", \"width\": 2 , \"projection\": true },";
- result = result + "data: [";
+ result = result + "\"data\": [";
for (Map.Entry entry : stats.entrySet()) {
result = result + entry.getValue().getAveragePaymentDays() + ",";
}
// cut last comma
- result = result.substring(0, result.length() - 1);
+ if (result.endsWith(",")) {
+ result = result.substring(0, result.length() - 1);
+ }
result = result + "]";
result = result + "} ";
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 ba049cc..7c435cf 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
@@ -53,6 +53,22 @@ public class AnalyticController implements Serializable {
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 Double for a given key.
*
diff --git a/office-alexander-logistics-app/src/main/webapp/pages/workitems/parts/alexander/analyze_chart.xhtml b/office-alexander-logistics-app/src/main/webapp/pages/workitems/parts/alexander/analyze_chart.xhtml
index 071091f..c0857b6 100644
--- a/office-alexander-logistics-app/src/main/webapp/pages/workitems/parts/alexander/analyze_chart.xhtml
+++ b/office-alexander-logistics-app/src/main/webapp/pages/workitems/parts/alexander/analyze_chart.xhtml
@@ -34,27 +34,14 @@
-
-
-
-
-
diff --git a/office-alexander-logistics-app/src/main/webapp/pages/workitems/parts/alexander/debitor_search.xhtml b/office-alexander-logistics-app/src/main/webapp/pages/workitems/parts/alexander/debitor_search.xhtml
index 3bffc75..0d7c309 100644
--- a/office-alexander-logistics-app/src/main/webapp/pages/workitems/parts/alexander/debitor_search.xhtml
+++ b/office-alexander-logistics-app/src/main/webapp/pages/workitems/parts/alexander/debitor_search.xhtml
@@ -44,6 +44,12 @@
* Hilfsmethode die nur fur Ajax Events in JSF render verwendet wird
*/
function ajaxUpdateDbtrSearchPart(data) {
+ var $body = $("body");
+ if (data.status === 'begin') {
+ // show ajax loader...
+ //imixsOfficeMain.layoutAjaxEvent(data, '#{customFormComponents.clientId}');
+ $body.addClass("loading");
+ }
if (data.status === 'success') {
// add autocomplete feature to dbtr_number_part...
var creditorField = $("input[data-item='dbtr_number_part']");
@@ -51,7 +57,9 @@
var dbtrName = "#{workflowController.workitem.item['dbtr.name']}";
// append span with dbtr.name....
creditorField.after("" + dbtrName + "
");
- //$("[id$=autocomplete-resultlist-cargosoft_part]").hide();
+
+ // remove ajax loader
+ $body.removeClass("loading");
}
}
@@ -81,6 +89,7 @@
+
diff --git a/workflow/analyse-debitor-de-1.0.0.bpmn b/workflow/analyse-debitor-de-1.0.0.bpmn
index 3cf8659..4554a23 100644
--- a/workflow/analyse-debitor-de-1.0.0.bpmn
+++ b/workflow/analyse-debitor-de-1.0.0.bpmn
@@ -174,22 +174,20 @@ th { font-weight: bold;}
+
-
-
-
+
-
]]>