Skip to content

Commit

Permalink
Merge branch 'master' of [email protected]:willuhn/hibiscus.git
Browse files Browse the repository at this point in the history
  • Loading branch information
willuhn committed Jan 4, 2022
2 parents 3f24a57 + 44eea0f commit 07e4b69
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ public Input getEnd()
}

/**
* Liefert ein Auswahl-Feld für die zeitliche Gruppierung.
* Liefert ein Auswahl-Feld für die zeitliche Gruppierung.
* @return Auswahl-Feld
* */
public SelectInput getInterval()
Expand All @@ -249,7 +249,7 @@ public void handleEvent(Event event)
}

/**
* Liefert ein Balkendiagramm bei dem Ausgaben und Einnahmen gegenübergestellt werden
* Liefert ein Balkendiagramm bei dem Ausgaben und Einnahmen gegenübergestellt werden
* @return Balkendiagramm
* @throws RemoteException
*/
Expand Down Expand Up @@ -322,27 +322,8 @@ public void format(TreeItem item)
return tree;
}

private Date getStartOfFirstInterval(Date start, Interval interval)
{
if (start == null)
{
return null;
}
if (interval == Interval.ALL)
{
return start;
}

Calendar calendar = Calendar.getInstance();
calendar.setTime(DateUtil.startOfDay(start));
// Tag auf den ersten im Intervall setzen
calendar.set(interval.type, 1);

return calendar.getTime();
}

/**
* Ermittelt die Liste der Knoten für den Baum. Wenn keine Aufschlüsselung gewünscht ist,
* Ermittelt die Liste der Knoten für den Baum. Wenn keine Aufschlüsselung gewünscht ist,
* werden die Zeilen ohne Elternknoten angezeigt.
* @return Liste mit den Werten.
* @throws RemoteException
Expand All @@ -356,13 +337,11 @@ private List<EinnahmeAusgabeZeitraum> getWerte() throws RemoteException

Date start = (Date) this.getStart().getValue();
Date end = (Date) this.getEnd().getValue();
// Datum zu Beginn des Intervalls für Umsatzliste und Saldenauswahl, damit es mit Startdatum in nodes übereinstimmt
final Date startFirstInterval = getStartOfFirstInterval(start, (Interval) getInterval().getValue());

List<Konto> konten = getSelectedAccounts();
List<Umsatz> umsatzList = getUmsaetze(konten, startFirstInterval, end);
List<Umsatz> umsatzList = getUmsaetze(konten, start, end);
if (!umsatzList.isEmpty())
// bei offenen Zeiträumen können wir den ersten und letzten Umsatztag ermitteln
// bei offenen Zeiträumen können wir den ersten und letzten Umsatztag ermitteln
{
if (start == null)
{
Expand All @@ -373,20 +352,20 @@ private List<EinnahmeAusgabeZeitraum> getWerte() throws RemoteException
end = umsatzList.get(umsatzList.size() - 1).getDatum();
}
}
Map<String, List<Value>> saldenProKonto = getSaldenProKonto(konten, startFirstInterval, end);
Map<String, List<Value>> saldenProKonto = getSaldenProKonto(konten, start, end);

// wenn die Umsatzliste leer ist, erfolgt keine Gruppierung, es wird nur der Gesamtzeitraum
// ausgewertet und da keine Umsätze zugeordnet werden müssen, spielen fehlende Datumsangaben keine Rolle
// ausgewertet und da keine Umsätze zugeordnet werden müssen, spielen fehlende Datumsangaben keine Rolle
Interval interval = umsatzList.isEmpty() ? Interval.ALL : (Interval) getInterval().getValue();
List<EinnahmeAusgabeTreeNode> nodes = createEmptyNodes(startFirstInterval, end, konten, interval);
List<EinnahmeAusgabeTreeNode> nodes = createEmptyNodes(start, end, konten, interval);

this.werte = new ArrayList<EinnahmeAusgabeZeitraum>();
if (nodes.isEmpty())
{
Logger.warn("no nodes created between range starts on " + startFirstInterval + " and range ends on " + end);
Logger.warn("no nodes created between range starts on " + start + " and range ends on " + end);
return this.werte;
}
addData(nodes, umsatzList, saldenProKonto);
addData(nodes, umsatzList, saldenProKonto, start, end);

if (interval == Interval.ALL)
{
Expand Down Expand Up @@ -415,7 +394,7 @@ private List<Umsatz> getUmsaetze(List<Konto> konten, Date start, Date end) throw
{
umsaetze.addFilter("datum <= ?", new java.sql.Date(DateUtil.endOfDay(end).getTime()));
}
// TODO funktioniert das mit allen unterstützten Datenbankversionen?
// TODO funktioniert das mit allen unterstützten Datenbankversionen?
umsaetze.addFilter("konto_id in (" + Joiner.on(",").join(kontoIds) + ")");
List<Umsatz> umsatzList = new ArrayList<Umsatz>();
while (umsaetze.hasNext())
Expand All @@ -430,12 +409,12 @@ private List<Umsatz> getUmsaetze(List<Konto> konten, Date start, Date end) throw
}

/**
* Liefert die Salden pro Konto für den angegebenen Zeitraum.
* Liefert die Salden pro Konto für den angegebenen Zeitraum.
* Zu beachten ist, dass ein Tagessaldo immer am Ende eines Tages berechnet wird.
* Da für Auswertungen ein Anfangssaldo angezeigt werden soll, welcher der Endsaldo des vorhergehenden Tages ist,
* wird als erstes Element der Liste ein zusätzlicher Tag eingefügt.
* Da für Auswertungen ein Anfangssaldo angezeigt werden soll, welcher der Endsaldo des vorhergehenden Tages ist,
* wird als erstes Element der Liste ein zusätzlicher Tag eingefügt.
*
* Beispiel: start=7.11., end=8.11. -> Liste enthält 6.11., 7.11., 8.11.
* Beispiel: start=7.11., end=8.11. -> Liste enthält 6.11., 7.11., 8.11.
* @param konten
* @param start
* @param end
Expand All @@ -447,9 +426,14 @@ private Map<String, List<Value>> getSaldenProKonto(List<Konto> konten, Date star
final BeanService bs = Application.getBootLoader().getBootable(BeanService.class);
final AccountBalanceService balanceService = bs.get(AccountBalanceService.class);
Map<String, List<Value>> saldenProKonto = new HashMap<String, List<Value>>();
if ((start == null) || (end == null))
{
return saldenProKonto;
}

final Calendar cal = Calendar.getInstance();
cal.setTime(start);
cal.add(Calendar.DAY_OF_MONTH, -1); // Salden um einen Tag nach vorne verlängern, weil die Salden immer nur für das Ende eines Tages berechnet werden
cal.add(Calendar.DAY_OF_MONTH, -1); // Salden um einen Tag nach vorne verlängern, weil die Salden immer nur für das Ende eines Tages berechnet werden
Date saldoStart = cal.getTime();
for (Konto konto : konten)
{
Expand All @@ -460,25 +444,25 @@ private Map<String, List<Value>> getSaldenProKonto(List<Konto> konten, Date star
return saldenProKonto;
}

private void addData(List<EinnahmeAusgabeTreeNode> nodes, List<Umsatz> umsatzList, Map<String, List<Value>> saldoProKonto) throws RemoteException
private void addData(List<EinnahmeAusgabeTreeNode> nodes, List<Umsatz> umsatzList, Map<String, List<Value>> saldoProKonto, Date start, Date end) throws RemoteException
{
int index = 0;
EinnahmeAusgabeTreeNode currentNode = null;
// Map der Daten für eine Konto-ID für schnelles Zuweisen der Umsätze
// Map der Daten für eine Konto-ID für schnelles Zuweisen der Umsätze
Map<String, EinnahmeAusgabe> kontoData = null;
for (Umsatz umsatz : umsatzList)
{
// Daten für das nächste relevante Intervall vorbereiten; 'while' da es möglich wäre, dass es für einen Zeitraum in der Mitte gar keine Umsätze gab
// Daten für das nächste relevante Intervall vorbereiten; 'while' da es möglich wäre, dass es für einen Zeitraum in der Mitte gar keine Umsätze gab
while (currentNode == null || umsatz.getDatum().after(currentNode.getEnddatum()))
{
// Wenn der Filterzeitraum identisches Start- und Enddatum hat, es an diesem Tag
// aber einen Umsatz auf dem gewählten Konto gibt, so bekam man eine leere Liste nodes.
// Ggf. gibt es weitere Fälle, die eine IndexOutOfBoundsException auslösen können.
// Daher ist Prüfung des index erforderlich.
// aber einen Umsatz auf dem gewählten Konto gibt, so bekam man eine leere Liste nodes.
// Ggf. gibt es weitere Fälle, die eine IndexOutOfBoundsException auslösen können.
// Daher ist Prüfung des index erforderlich.
if (index >= nodes.size())
{
Date end = currentNode != null ? currentNode.getEnddatum() : null;
Logger.warn("found umsatz outside range, date: " + umsatz.getDatum() + ", range ends " + end);
Date endInterval = (currentNode != null ? currentNode.getEnddatum() : null);
Logger.warn("found umsatz at date " + umsatz.getDatum() + " outside last interval ending at " + endInterval);
return;
}

Expand All @@ -496,12 +480,14 @@ private void addData(List<EinnahmeAusgabeTreeNode> nodes, List<Umsatz> umsatzLis
{
Map<String, EinnahmeAusgabe> kontoMap = getKontoDataMap(node);

int tagEnde = tagStart + (int) getDifferenceDays(node.getStartdatum(), node.getEnddatum()) + 1;
final Date startDatum = (tagStart == 0 ? start : node.getStartdatum());
final Date endDatum = (end.before(node.getEnddatum()) ? end : node.getEnddatum());
int tagEnde = tagStart + (int) getDifferenceDays(startDatum, endDatum) + 1;
for (Entry<String, EinnahmeAusgabe> kontoEntry : kontoMap.entrySet())
{
EinnahmeAusgabe ea = kontoEntry.getValue();
List<Value> saldo = saldoProKonto.get(ea.getKonto().getID());
if (saldo.isEmpty())
if ((saldo == null) || saldo.isEmpty())
{
// sollte nicht passieren, aber sonst wird tagEnde im Folgenden negativ
continue;
Expand Down Expand Up @@ -608,7 +594,7 @@ private List<Konto> getSelectedAccounts() throws RemoteException
}

/**
* Erstelle die finale Struktur - nur ohne Beträge und Salden
* Erstelle die finale Struktur - nur ohne Beträge und Salden
*/
private List<EinnahmeAusgabeTreeNode> createEmptyNodes(Date start, Date end, List<Konto> konten, Interval interval) throws RemoteException
{
Expand All @@ -625,20 +611,21 @@ private List<EinnahmeAusgabeTreeNode> createEmptyNodes(Date start, Date end, Lis
{
Calendar calendar = Calendar.getInstance();
calendar.setTime(DateUtil.startOfDay(start));
// Prüfe auf time <= end mit !after(), damit bei start==end auch ein Intervallknoten bestimmt wird.
// Prüfe auf time <= end mit !after(), damit bei start==end auch ein Intervallknoten bestimmt wird.
while (!calendar.getTime().after(end))
{
// Tag auf den ersten im Intervall setzen
calendar.set(interval.type, 1);
Date nodeFrom = calendar.getTime();

// ermittle den Zeitpunkt unmittelbar vor dem nächsten Zeitraumstart
// ermittle den Zeitpunkt unmittelbar vor dem nächsten Zeitraumstart
calendar.add(interval.size, 1);
calendar.add(Calendar.MILLISECOND, -1);
Date nodeTo = DateUtil.startOfDay(calendar.getTime());

List<EinnahmeAusgabe> werte = getEmptyNodes(nodeFrom, nodeTo, konten);
result.add(new EinnahmeAusgabeTreeNode(nodeFrom, nodeTo, werte));
// ermittle den Start des nächsten Zeitraums
// ermittle den Start des nächsten Zeitraums
calendar.setTime(nodeFrom);
// eine Intervalldauer in die Zukunft springen
calendar.add(interval.size, 1);
Expand Down
8 changes: 4 additions & 4 deletions src/de/willuhn/jameica/hbci/server/KontoUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ else if (flag > 0)
}

/**
* Liefert den Anfangssaldo eines Tages bzw. des 1. Tages nach diesem Datum mit Umsätzen
* Liefert den Anfangssaldo eines Tages bzw. des 1. Tages nach diesem Datum mit Umsätzen
* oder <code>0.0</code> wenn er noch nie abgefragt wurde.
* @param konto das Konto.
* @param datum Datum.
Expand Down Expand Up @@ -318,8 +318,8 @@ public static double getAnfangsSaldo(Konto konto, Date datum) throws RemoteExcep
return u.getSaldo() - u.getBetrag(); // Wir ziehen den Betrag noch ab, um den Saldo VOR der Buchung zu kriegen
}

// Im angegebenen Zeitraum waren keine Umsätze zu finden. Deshalb suchen wir
// frühere Umsätze.
// Im angegebenen Zeitraum waren keine Umsätze zu finden. Deshalb suchen wir
// frühere Umsätze.
list = UmsatzUtil.getUmsaetzeBackwards();
list.addFilter("konto_id = " + konto.getID());

Expand All @@ -339,7 +339,7 @@ public static double getAnfangsSaldo(Konto konto, Date datum) throws RemoteExcep
}

/**
* Liefert den Endsaldo eines Tages bzw. des 1. Tages vor diesem Datum mit Umsätzen oder
* Liefert den Endsaldo eines Tages bzw. des 1. Tages vor diesem Datum mit Umsätzen oder
* <code>0.0</code> wenn er noch nie abgefragt wurde.
* @param konto das Konto.
* @param datum Datum.
Expand Down

0 comments on commit 07e4b69

Please sign in to comment.