314 lines
9.3 KiB
Java
314 lines
9.3 KiB
Java
package com.alexanderlogistics;
|
|
|
|
import java.io.Serializable;
|
|
import java.util.Calendar;
|
|
import java.util.Date;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.logging.Logger;
|
|
|
|
import org.imixs.workflow.ItemCollection;
|
|
import org.imixs.workflow.engine.DocumentService;
|
|
import org.imixs.workflow.exceptions.QueryException;
|
|
|
|
import jakarta.enterprise.context.RequestScoped;
|
|
import jakarta.enterprise.event.Observes;
|
|
import jakarta.inject.Inject;
|
|
import jakarta.inject.Named;
|
|
import jakarta.json.Json;
|
|
import jakarta.json.JsonArrayBuilder;
|
|
import jakarta.json.JsonObject;
|
|
import jakarta.json.JsonObjectBuilder;
|
|
|
|
/**
|
|
* Der AGLAnalyticController berechnet verschiedene Analyse Daten
|
|
*
|
|
* @author rsoika
|
|
*
|
|
*/
|
|
@Named
|
|
@RequestScoped
|
|
public class AGLAnalyticController implements Serializable {
|
|
|
|
private static final long serialVersionUID = 1L;
|
|
private static Logger logger = Logger.getLogger(AnalyticController.class.getName());
|
|
|
|
@Inject
|
|
protected DocumentService documentService;
|
|
|
|
@Inject
|
|
protected DebitorStatistikController debitorStatistikController;
|
|
|
|
List<ItemCollection> steuerbescheide = null;
|
|
|
|
public void onEvent(@Observes AnalyticEvent event) {
|
|
if ("analytic.steuer.eust".equals(event.getKey())) {
|
|
event.setValue(computeSteuerbescheideEUST());
|
|
event.setLabel("EUR");
|
|
event.setDescription("Gesamt Einfuhrumsatzsteuer (EUSt)");
|
|
event.getWorkitem().setItemValue("eust.total", event.getValue());
|
|
|
|
}
|
|
if ("analytic.steuer.zoll".equals(event.getKey())) {
|
|
event.setValue(computeSteuerbescheideZoll());
|
|
event.setLabel("EUR");
|
|
event.setDescription("Gesamt Zölle (ZOLLEU)");
|
|
}
|
|
if ("analytic.steuer.due".equals(event.getKey())) {
|
|
event.setValue(computeSteuerbescheideUeberfaellig());
|
|
event.setLabel("EUR");
|
|
event.setDescription("Überfällige Steuerbescheide die noch nicht abgerechnet wurden.");
|
|
}
|
|
|
|
if ("analytic.steuer.trend".equals(event.getKey())) {
|
|
event.setValue(accumulateSteuerbescheideByWeek());
|
|
event.setLabel("Zoll & EUST");
|
|
event.setDescription("Fälligkeiten nach KW");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Berechnet die Summe aller offenen EUST Beträge
|
|
* // tax.code=[0], amount=[3885.16], activity.type=[EUST],
|
|
* // filenumber=[LA-PAP-2408-024]}
|
|
*
|
|
* @return
|
|
*/
|
|
private double computeSteuerbescheideEUST() {
|
|
logger.info("compute EUST...");
|
|
List<ItemCollection> list = getSteuerbescheide();
|
|
double result = 0;
|
|
|
|
for (ItemCollection steuerItemCol : list) {
|
|
result = result + getZollBySteuerBeleg(steuerItemCol, "EUST");
|
|
// List<ItemCollection> positionsTabelle =
|
|
// InvoiceUtil.explodeChildList(steuerItemCol);
|
|
// for (ItemCollection pos : positionsTabelle) {
|
|
// if ("EUST".equalsIgnoreCase(pos.getItemValueString("activity.type"))) {
|
|
// result = result + pos.getItemValueDouble("amount");
|
|
// }
|
|
// }
|
|
|
|
}
|
|
return InvoiceUtil.round(result);
|
|
}
|
|
|
|
/**
|
|
* Berechnet die Summe aller offenen Zoll Beträge
|
|
*
|
|
* @return
|
|
*/
|
|
private double computeSteuerbescheideZoll() {
|
|
logger.info("compute Zoll...");
|
|
List<ItemCollection> list = getSteuerbescheide();
|
|
double result = 0;
|
|
|
|
for (ItemCollection steuerItemCol : list) {
|
|
result = result + getZollBySteuerBeleg(steuerItemCol, "ZOLL");
|
|
// List<ItemCollection> positionsTabelle =
|
|
// InvoiceUtil.explodeChildList(steuerItemCol);
|
|
// for (ItemCollection pos : positionsTabelle) {
|
|
// if ("ZOLL".equalsIgnoreCase(pos.getItemValueString("activity.type"))) {
|
|
// result = result + pos.getItemValueDouble("amount");
|
|
// }
|
|
// }
|
|
|
|
}
|
|
return InvoiceUtil.round(result);
|
|
}
|
|
|
|
/**
|
|
* Berechnet die Summe aller überfälligen steuer Beträge $taskID=1200
|
|
*
|
|
* @return
|
|
*/
|
|
private double computeSteuerbescheideUeberfaellig() {
|
|
logger.info("compute EUST...");
|
|
List<ItemCollection> list = getSteuerbescheide();
|
|
double result = 0;
|
|
for (ItemCollection steuerItemCol : list) {
|
|
if (steuerItemCol.getTaskID() == 1200) {
|
|
result = result + steuerItemCol.getItemValueDouble("invoice.saldo");
|
|
}
|
|
}
|
|
return InvoiceUtil.round(result);
|
|
|
|
}
|
|
|
|
/**
|
|
* Berechnet die summ zoll/eust für einen Beleg
|
|
*
|
|
* @param steuerItemCol
|
|
* @return
|
|
*/
|
|
private double getZollBySteuerBeleg(ItemCollection steuerItemCol, String type) {
|
|
double result = 0;
|
|
List<ItemCollection> positionsTabelle = InvoiceUtil.explodeChildList(steuerItemCol);
|
|
for (ItemCollection pos : positionsTabelle) {
|
|
if (type.equalsIgnoreCase(pos.getItemValueString("activity.type"))) {
|
|
result = result + pos.getItemValueDouble("amount");
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private List<ItemCollection> getSteuerbescheide() {
|
|
if (steuerbescheide != null) {
|
|
return steuerbescheide;
|
|
}
|
|
// compute steuerbescheide....
|
|
logger.info("Load Steuerbescheide for analytics....");
|
|
String query = "(type:workitem ) AND ($workflowgroup:\"Steuerbescheid\")";
|
|
try {
|
|
steuerbescheide = documentService.find(query, 999, 0, "$created", false);
|
|
return steuerbescheide;
|
|
} catch (QueryException e) {
|
|
logger.severe("Failed to get invoices: " + e.getMessage());
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Berechnet Chart daten aller Steuerbescheide bei KW
|
|
*
|
|
* <pre>
|
|
*
|
|
chartCfg = {
|
|
type: 'bar',
|
|
data: {
|
|
datasets: [{
|
|
data: [20, 10],
|
|
}],
|
|
labels: ['1', '2']
|
|
}
|
|
}
|
|
*
|
|
* </pre>
|
|
*
|
|
* @return
|
|
*/
|
|
private String accumulateSteuerbescheideByWeek() {
|
|
logger.info("accumulate steuer by week...");
|
|
|
|
List<ItemCollection> list = getSteuerbescheide();
|
|
Map<Integer, SteuerData> saldoByWeek = new HashMap<>();
|
|
Calendar calendar = Calendar.getInstance();
|
|
int earliestWeek = Integer.MAX_VALUE;
|
|
int latestWeek = Integer.MIN_VALUE;
|
|
|
|
// Step 1: Group saldo by week
|
|
for (ItemCollection steuerItemCol : list) {
|
|
double saldo = steuerItemCol.getItemValueDouble("invoice.saldo");
|
|
Date date = steuerItemCol.getItemValueDate("invoice.date");
|
|
|
|
// 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; // Unique key for each year + week combination
|
|
|
|
// Accumulate the saldo per week
|
|
SteuerData steuerDataByWeek = saldoByWeek.getOrDefault(yearWeek, new SteuerData());
|
|
double eust = getZollBySteuerBeleg(steuerItemCol, "EUST");
|
|
double zoll = getZollBySteuerBeleg(steuerItemCol, "ZOLL");
|
|
steuerDataByWeek.add(eust, zoll, saldo);
|
|
|
|
saldoByWeek.put(yearWeek, 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 dataBuilderSaldo = Json.createArrayBuilder();
|
|
JsonArrayBuilder dataBuilderEust = Json.createArrayBuilder();
|
|
JsonArrayBuilder dataBuilderZoll = Json.createArrayBuilder();
|
|
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);
|
|
|
|
while (!startCal.after(endCal)) {
|
|
int weekNumber = startCal.get(Calendar.WEEK_OF_YEAR);
|
|
int year = startCal.get(Calendar.YEAR);
|
|
int yearWeek = year * 100 + weekNumber;
|
|
|
|
// Add the saldo for the week or 0.0 if no data
|
|
SteuerData steuerData = saldoByWeek.getOrDefault(yearWeek, new SteuerData());
|
|
dataBuilderSaldo.add(steuerData.saldo);
|
|
dataBuilderEust.add(steuerData.eust);
|
|
dataBuilderZoll.add(steuerData.zoll);
|
|
labelsBuilder.add(weekNumber + "/" + year); // Label as 'week/year'
|
|
|
|
// Move to the next week
|
|
startCal.add(Calendar.WEEK_OF_YEAR, 1);
|
|
}
|
|
|
|
// Step 3: Prepare the JSON structure
|
|
JsonObjectBuilder jsonBuilder = Json.createObjectBuilder()
|
|
.add("type", "bar")
|
|
.add("data", Json.createObjectBuilder()
|
|
.add("datasets", Json.createArrayBuilder()
|
|
|
|
.add(Json.createObjectBuilder() // First dataset for 'tax'
|
|
.add("label", "Zoll")
|
|
.add("backgroundColor", "#96f")
|
|
.add("borderWidth", 1)
|
|
.add("data", dataBuilderZoll))
|
|
.add(Json.createObjectBuilder() // Second dataset for 'eust'
|
|
.add("label", "EUSt")
|
|
.add("backgroundColor", "#36a2eb")
|
|
.add("borderWidth", 1)
|
|
.add("data", dataBuilderEust))
|
|
.add(Json.createObjectBuilder() // Third dataset for 'Saldo'
|
|
.add("label", "Saldo")
|
|
.add("backgroundColor", "#ff6384")
|
|
.add("borderWidth", 1)
|
|
.add("data", dataBuilderSaldo)))
|
|
|
|
.add("labels", labelsBuilder));
|
|
|
|
// Step 4: Return the JSON structure as a string
|
|
JsonObject chartCfg = jsonBuilder.build();
|
|
return chartCfg.toString();
|
|
}
|
|
|
|
/**
|
|
* Helper method to hold zoll and eust totls 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;
|
|
|
|
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 saldoNew) {
|
|
eust = eust + eustNew;
|
|
zoll = zoll + zollNew;
|
|
saldo = saldo + saldoNew;
|
|
// update total
|
|
total = eust + zoll;
|
|
}
|
|
|
|
}
|
|
}
|