Analytic controller - improved caching

This commit is contained in:
Ralph Soika 2024-11-25 11:20:43 +01:00
parent 6c538355d7
commit c34ed64445
4 changed files with 73 additions and 36 deletions

View file

@ -84,8 +84,8 @@ public class AGLAnalyticControllerDebitor implements Serializable {
String chartData = "";
public void onEvent(@Observes AnalyticEvent event) {
if (!"workitem".equals(event.getWorkitem().getType())) {
if (!"workitem".equals(event.getWorkitem().getType())
|| !event.getWorkitem().getModelVersion().startsWith("analyse-debitor")) {
// no op
return;
}
@ -96,13 +96,20 @@ public class AGLAnalyticControllerDebitor implements Serializable {
// load all invoices?
if (invoices == null || (!dbtrNumber.isEmpty() && !dbtrNumber.equals(dbtrNumberLast))) {
resetStats();
resetStats(event);
event.getWorkitem().setItemValue("dbtr.number.last", dbtrNumber);
logger.info("Analyse new debitor data for : " + dbtrNumber);
loadRechnungen();
loadRechnungen(event);
chartData = buildChartData();
}
// use cache?
if (event.getWorkitem().hasItem(event.getKey())) {
// logger.info(" use cache for " + event.getKey());
// no op
return;
}
String link = "/pages/workitems/worklist.xhtml" + "?phrase=" + getDbtNr();
logger.fine("process ref=" + workflowController.getWorkitem().getItemValueString("process.ref"));
ItemCollection process = documentService
@ -185,7 +192,7 @@ public class AGLAnalyticControllerDebitor implements Serializable {
return label;
}
private void loadRechnungen() {
private void loadRechnungen(AnalyticEvent event) {
if (getDbtNr().isEmpty()) {
invoices = new ArrayList();
stats = null;
@ -196,7 +203,7 @@ public class AGLAnalyticControllerDebitor implements Serializable {
try {
logger.info(" ├──refresh invoice stats for " + getDbtNr() + "....");
invoices = documentService.find(query, 999, 0, "$created", false);
calculateStats();
calculateStats(event);
} catch (QueryException e) {
logger.warning("Failed to query invoices: " + query + " - Error: " + e.getMessage());
invoices = new ArrayList();
@ -208,7 +215,7 @@ public class AGLAnalyticControllerDebitor implements Serializable {
/**
* Läd die statistik daten zu einem debitor aus den aktuellen Rechnungen
*/
private void calculateStats() {
private void calculateStats(AnalyticEvent event) {
countAll = 0;
countOpen = 0;
countDue = 0;
@ -274,7 +281,7 @@ public class AGLAnalyticControllerDebitor implements Serializable {
} else {
// reset data because no invoices are available ...
resetStats();
resetStats(event);
}
@ -283,7 +290,7 @@ public class AGLAnalyticControllerDebitor implements Serializable {
/**
* Setzt alle Statistikwerte zurück
*/
private void resetStats() {
private void resetStats(AnalyticEvent event) {
logger.info(" ├──reset stats for " + getDbtNr() + "....");
stats = null;
@ -301,6 +308,16 @@ public class AGLAnalyticControllerDebitor implements Serializable {
averagePaymentDue = 0;
averagePaymentDays = 0;
event.getWorkitem().removeItem("analytic.invoices.count.all");
event.getWorkitem().removeItem("analytic.invoices.count.open");
event.getWorkitem().removeItem("analytic.invoices.count.due");
event.getWorkitem().removeItem("analytic.invoices.count.dunning");
event.getWorkitem().removeItem("analytic.payment.avg.due");
event.getWorkitem().removeItem("analytic.payment.avg.days");
event.getWorkitem().removeItem("analytic.invoices.trend");
}
private void getDurchschnittZahlungsziel() {

View file

@ -51,18 +51,18 @@ public class AGLAnalyticControllerOPListe implements Serializable {
String departmentID;
String departmentIDLast = null;
String departmentName;
// String departmentName;
ItemCollection department;
int countAll = 0;
int countOpen = 0;
int countDue = 0;
int countDunning = 0;
boolean refreshCalculation = true;
boolean refreshCalculation = false;
public void onEvent(@Observes AnalyticEvent event) {
if (!"workitem".equals(event.getWorkitem().getType())) {
if (!"workitem".equals(event.getWorkitem().getType())
|| !event.getWorkitem().getModelVersion().startsWith("analyse-opliste")) {
// no op
return;
}
@ -70,25 +70,30 @@ public class AGLAnalyticControllerOPListe implements Serializable {
department = null;
departmentID = event.getWorkitem().getItemValueString("space.ref");
if ((!departmentID.isEmpty() && !departmentID.equals(departmentIDLast))) {
if (departmentIDLast == null || !departmentID.equals(departmentIDLast)) {
department = documentService.load(departmentID);
departmentName = department.getItemValueString("name");
if (department != null) {
event.getWorkitem().setItemValue("space.name", department.getItemValueString("name"));
}
departmentIDLast = departmentID;
resetStats(event);
calculateStats();
refreshCalculation = true;
}
if (refreshCalculation) {
calculateStats();
refreshCalculation = false;
// use cache?
if (event.getWorkitem().hasItem(event.getKey())) {
// logger.info(" use cache for " + event.getKey());
// no op
return;
}
String link = "/pages/workitems/worklist.xhtml";
logger.fine("process ref=" + workflowController.getWorkitem().getItemValueString("process.ref"));
ItemCollection process = documentService
.load(workflowController.getWorkitem().getItemValueString("process.ref"));
if (process != null) {
link = link + "&processref=" + process.getUniqueID()
+ "&phrase=" + departmentName;
+ "&spaceref=" + departmentID;
}
if ("analytic.invoices.count.all".equals(event.getKey())) {
event.setValue("" + countAll);
@ -123,6 +128,17 @@ public class AGLAnalyticControllerOPListe implements Serializable {
}
/**
* Reset cached analytic keys
*/
private void resetStats(AnalyticEvent event) {
event.getWorkitem().removeItem("analytic.invoices.count.all");
event.getWorkitem().removeItem("analytic.invoices.count.open");
event.getWorkitem().removeItem("analytic.invoices.count.due");
event.getWorkitem().removeItem("analytic.invoices.count.dunning");
}
/**
* Läd die statistik daten zu einem department die Anzahl an aktuellen
* Rechnungen zu ermitteln
@ -134,6 +150,7 @@ public class AGLAnalyticControllerOPListe implements Serializable {
*
*/
private void calculateStats() {
long l = System.currentTimeMillis();
countAll = 0;
countOpen = 0;
countDue = 0;
@ -161,6 +178,7 @@ public class AGLAnalyticControllerOPListe implements Serializable {
logger.warning("Failed to query invoices: " + e.getMessage());
}
logger.info(" ├──calculate stats took " + (System.currentTimeMillis() - l) + "ms");
}

View file

@ -56,6 +56,12 @@ public class AGLAnalyticControllerSteuer implements Serializable {
public void onEvent(@Observes AnalyticEvent event) {
if (!"workitem".equals(event.getWorkitem().getType())
|| !event.getWorkitem().getModelVersion().startsWith("analyse-steuer")) {
// no op
return;
}
ItemCollection process = documentService
.load(workflowController.getWorkitem().getItemValueString("process.ref"));
String link = "/pages/workitems/worklist.xhtml";

View file

@ -114,15 +114,17 @@ public class AnalyticController implements Serializable {
}
/**
* Computes am analytic value. The method cache the value in the item
* 'analytic.KEY' to avoid feierring repeated AnalyticEvents.
* 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());
@ -134,21 +136,10 @@ public class AnalyticController implements Serializable {
details.setItemValue("label", event.getLabel());
details.setItemValue("description", event.getDescription());
details.setItemValue("link", event.getLink());
// cache result
implodeDetails(key, details);
}
}
// try loading from cache
ItemCollection details = explodeDetails(key);
if (details == null) {
// set dummy value
details = new ItemCollection();
details.setItemValue("value", "");
details.setItemValue("label", "");
details.setItemValue("description", "No data available");
implodeDetails(key, details);
}
}
// analytic value is now already cached!
@ -180,7 +171,12 @@ public class AnalyticController implements Serializable {
return itemCol;
}
// return empty collection
return new ItemCollection();
ItemCollection dummy = new ItemCollection();
dummy.setItemValue("value", "");
dummy.setItemValue("label", "");
dummy.setItemValue("description", "No data available");
return dummy;
}
}