Analytic controller - improved caching
This commit is contained in:
parent
6c538355d7
commit
c34ed64445
4 changed files with 73 additions and 36 deletions
|
|
@ -84,8 +84,8 @@ public class AGLAnalyticControllerDebitor implements Serializable {
|
||||||
String chartData = "";
|
String chartData = "";
|
||||||
|
|
||||||
public void onEvent(@Observes AnalyticEvent event) {
|
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
|
// no op
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -96,13 +96,20 @@ public class AGLAnalyticControllerDebitor implements Serializable {
|
||||||
|
|
||||||
// load all invoices?
|
// load all invoices?
|
||||||
if (invoices == null || (!dbtrNumber.isEmpty() && !dbtrNumber.equals(dbtrNumberLast))) {
|
if (invoices == null || (!dbtrNumber.isEmpty() && !dbtrNumber.equals(dbtrNumberLast))) {
|
||||||
resetStats();
|
resetStats(event);
|
||||||
event.getWorkitem().setItemValue("dbtr.number.last", dbtrNumber);
|
event.getWorkitem().setItemValue("dbtr.number.last", dbtrNumber);
|
||||||
logger.info("Analyse new debitor data for : " + dbtrNumber);
|
logger.info("Analyse new debitor data for : " + dbtrNumber);
|
||||||
loadRechnungen();
|
loadRechnungen(event);
|
||||||
chartData = buildChartData();
|
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();
|
String link = "/pages/workitems/worklist.xhtml" + "?phrase=" + getDbtNr();
|
||||||
logger.fine("process ref=" + workflowController.getWorkitem().getItemValueString("process.ref"));
|
logger.fine("process ref=" + workflowController.getWorkitem().getItemValueString("process.ref"));
|
||||||
ItemCollection process = documentService
|
ItemCollection process = documentService
|
||||||
|
|
@ -185,7 +192,7 @@ public class AGLAnalyticControllerDebitor implements Serializable {
|
||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadRechnungen() {
|
private void loadRechnungen(AnalyticEvent event) {
|
||||||
if (getDbtNr().isEmpty()) {
|
if (getDbtNr().isEmpty()) {
|
||||||
invoices = new ArrayList();
|
invoices = new ArrayList();
|
||||||
stats = null;
|
stats = null;
|
||||||
|
|
@ -196,7 +203,7 @@ public class AGLAnalyticControllerDebitor implements Serializable {
|
||||||
try {
|
try {
|
||||||
logger.info(" ├──refresh invoice stats for " + getDbtNr() + "....");
|
logger.info(" ├──refresh invoice stats for " + getDbtNr() + "....");
|
||||||
invoices = documentService.find(query, 999, 0, "$created", false);
|
invoices = documentService.find(query, 999, 0, "$created", false);
|
||||||
calculateStats();
|
calculateStats(event);
|
||||||
} catch (QueryException e) {
|
} catch (QueryException e) {
|
||||||
logger.warning("Failed to query invoices: " + query + " - Error: " + e.getMessage());
|
logger.warning("Failed to query invoices: " + query + " - Error: " + e.getMessage());
|
||||||
invoices = new ArrayList();
|
invoices = new ArrayList();
|
||||||
|
|
@ -208,7 +215,7 @@ public class AGLAnalyticControllerDebitor implements Serializable {
|
||||||
/**
|
/**
|
||||||
* Läd die statistik daten zu einem debitor aus den aktuellen Rechnungen
|
* Läd die statistik daten zu einem debitor aus den aktuellen Rechnungen
|
||||||
*/
|
*/
|
||||||
private void calculateStats() {
|
private void calculateStats(AnalyticEvent event) {
|
||||||
countAll = 0;
|
countAll = 0;
|
||||||
countOpen = 0;
|
countOpen = 0;
|
||||||
countDue = 0;
|
countDue = 0;
|
||||||
|
|
@ -274,7 +281,7 @@ public class AGLAnalyticControllerDebitor implements Serializable {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// reset data because no invoices are available ...
|
// reset data because no invoices are available ...
|
||||||
resetStats();
|
resetStats(event);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -283,7 +290,7 @@ public class AGLAnalyticControllerDebitor implements Serializable {
|
||||||
/**
|
/**
|
||||||
* Setzt alle Statistikwerte zurück
|
* Setzt alle Statistikwerte zurück
|
||||||
*/
|
*/
|
||||||
private void resetStats() {
|
private void resetStats(AnalyticEvent event) {
|
||||||
logger.info(" ├──reset stats for " + getDbtNr() + "....");
|
logger.info(" ├──reset stats for " + getDbtNr() + "....");
|
||||||
stats = null;
|
stats = null;
|
||||||
|
|
||||||
|
|
@ -301,6 +308,16 @@ public class AGLAnalyticControllerDebitor implements Serializable {
|
||||||
|
|
||||||
averagePaymentDue = 0;
|
averagePaymentDue = 0;
|
||||||
averagePaymentDays = 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() {
|
private void getDurchschnittZahlungsziel() {
|
||||||
|
|
|
||||||
|
|
@ -51,18 +51,18 @@ public class AGLAnalyticControllerOPListe implements Serializable {
|
||||||
|
|
||||||
String departmentID;
|
String departmentID;
|
||||||
String departmentIDLast = null;
|
String departmentIDLast = null;
|
||||||
String departmentName;
|
// String departmentName;
|
||||||
ItemCollection department;
|
ItemCollection department;
|
||||||
|
|
||||||
int countAll = 0;
|
int countAll = 0;
|
||||||
int countOpen = 0;
|
int countOpen = 0;
|
||||||
int countDue = 0;
|
int countDue = 0;
|
||||||
int countDunning = 0;
|
int countDunning = 0;
|
||||||
boolean refreshCalculation = true;
|
boolean refreshCalculation = false;
|
||||||
|
|
||||||
public void onEvent(@Observes AnalyticEvent event) {
|
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
|
// no op
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -70,25 +70,30 @@ public class AGLAnalyticControllerOPListe implements Serializable {
|
||||||
department = null;
|
department = null;
|
||||||
departmentID = event.getWorkitem().getItemValueString("space.ref");
|
departmentID = event.getWorkitem().getItemValueString("space.ref");
|
||||||
|
|
||||||
if ((!departmentID.isEmpty() && !departmentID.equals(departmentIDLast))) {
|
if (departmentIDLast == null || !departmentID.equals(departmentIDLast)) {
|
||||||
department = documentService.load(departmentID);
|
department = documentService.load(departmentID);
|
||||||
departmentName = department.getItemValueString("name");
|
if (department != null) {
|
||||||
|
event.getWorkitem().setItemValue("space.name", department.getItemValueString("name"));
|
||||||
|
}
|
||||||
departmentIDLast = departmentID;
|
departmentIDLast = departmentID;
|
||||||
|
resetStats(event);
|
||||||
|
calculateStats();
|
||||||
refreshCalculation = true;
|
refreshCalculation = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (refreshCalculation) {
|
// use cache?
|
||||||
calculateStats();
|
if (event.getWorkitem().hasItem(event.getKey())) {
|
||||||
refreshCalculation = false;
|
// logger.info(" use cache for " + event.getKey());
|
||||||
|
// no op
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String link = "/pages/workitems/worklist.xhtml";
|
String link = "/pages/workitems/worklist.xhtml";
|
||||||
logger.fine("process ref=" + workflowController.getWorkitem().getItemValueString("process.ref"));
|
logger.fine("process ref=" + workflowController.getWorkitem().getItemValueString("process.ref"));
|
||||||
ItemCollection process = documentService
|
ItemCollection process = documentService
|
||||||
.load(workflowController.getWorkitem().getItemValueString("process.ref"));
|
.load(workflowController.getWorkitem().getItemValueString("process.ref"));
|
||||||
if (process != null) {
|
if (process != null) {
|
||||||
link = link + "&processref=" + process.getUniqueID()
|
link = link + "&processref=" + process.getUniqueID()
|
||||||
+ "&phrase=" + departmentName;
|
+ "&spaceref=" + departmentID;
|
||||||
}
|
}
|
||||||
if ("analytic.invoices.count.all".equals(event.getKey())) {
|
if ("analytic.invoices.count.all".equals(event.getKey())) {
|
||||||
event.setValue("" + countAll);
|
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
|
* Läd die statistik daten zu einem department die Anzahl an aktuellen
|
||||||
* Rechnungen zu ermitteln
|
* Rechnungen zu ermitteln
|
||||||
|
|
@ -134,6 +150,7 @@ public class AGLAnalyticControllerOPListe implements Serializable {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private void calculateStats() {
|
private void calculateStats() {
|
||||||
|
long l = System.currentTimeMillis();
|
||||||
countAll = 0;
|
countAll = 0;
|
||||||
countOpen = 0;
|
countOpen = 0;
|
||||||
countDue = 0;
|
countDue = 0;
|
||||||
|
|
@ -161,6 +178,7 @@ public class AGLAnalyticControllerOPListe implements Serializable {
|
||||||
logger.warning("Failed to query invoices: " + e.getMessage());
|
logger.warning("Failed to query invoices: " + e.getMessage());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
logger.info(" ├──calculate stats took " + (System.currentTimeMillis() - l) + "ms");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,12 @@ public class AGLAnalyticControllerSteuer implements Serializable {
|
||||||
|
|
||||||
public void onEvent(@Observes AnalyticEvent event) {
|
public void onEvent(@Observes AnalyticEvent event) {
|
||||||
|
|
||||||
|
if (!"workitem".equals(event.getWorkitem().getType())
|
||||||
|
|| !event.getWorkitem().getModelVersion().startsWith("analyse-steuer")) {
|
||||||
|
// no op
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ItemCollection process = documentService
|
ItemCollection process = documentService
|
||||||
.load(workflowController.getWorkitem().getItemValueString("process.ref"));
|
.load(workflowController.getWorkitem().getItemValueString("process.ref"));
|
||||||
String link = "/pages/workitems/worklist.xhtml";
|
String link = "/pages/workitems/worklist.xhtml";
|
||||||
|
|
|
||||||
|
|
@ -114,15 +114,17 @@ public class AnalyticController implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes am analytic value. The method cache the value in the item
|
* Computes an analytic value. The method cache the value in the
|
||||||
* 'analytic.KEY' to avoid feierring repeated AnalyticEvents.
|
* item key.
|
||||||
|
*
|
||||||
|
* An observer controller is responsible to cache or reset the cached values if
|
||||||
|
* needed.
|
||||||
*
|
*
|
||||||
* @param key
|
* @param key
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected ItemCollection computeValue(String key) {
|
protected ItemCollection computeValue(String key) {
|
||||||
if (workflowController.getWorkitem() != null) {
|
if (workflowController.getWorkitem() != null) {
|
||||||
|
|
||||||
logger.fine("fire analytic event for key '" + key + "'");
|
logger.fine("fire analytic event for key '" + key + "'");
|
||||||
// Fire the Analytics Event for this key
|
// Fire the Analytics Event for this key
|
||||||
AnalyticEvent event = new AnalyticEvent(key, workflowController.getWorkitem());
|
AnalyticEvent event = new AnalyticEvent(key, workflowController.getWorkitem());
|
||||||
|
|
@ -134,21 +136,10 @@ public class AnalyticController implements Serializable {
|
||||||
details.setItemValue("label", event.getLabel());
|
details.setItemValue("label", event.getLabel());
|
||||||
details.setItemValue("description", event.getDescription());
|
details.setItemValue("description", event.getDescription());
|
||||||
details.setItemValue("link", event.getLink());
|
details.setItemValue("link", event.getLink());
|
||||||
|
// cache result
|
||||||
implodeDetails(key, details);
|
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!
|
// analytic value is now already cached!
|
||||||
|
|
@ -180,7 +171,12 @@ public class AnalyticController implements Serializable {
|
||||||
return itemCol;
|
return itemCol;
|
||||||
}
|
}
|
||||||
// return empty collection
|
// return empty collection
|
||||||
return new ItemCollection();
|
ItemCollection dummy = new ItemCollection();
|
||||||
|
dummy.setItemValue("value", "");
|
||||||
|
dummy.setItemValue("label", "");
|
||||||
|
dummy.setItemValue("description", "No data available");
|
||||||
|
|
||||||
|
return dummy;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue