Bugfix und Monatsreport
All checks were successful
release-tag / release-image (push) Successful in 2m5s
All checks were successful
release-tag / release-image (push) Successful in 2m5s
This commit is contained in:
88
main.go
88
main.go
@@ -7,6 +7,7 @@ import (
|
||||
"math"
|
||||
"net/http"
|
||||
"os"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -55,6 +56,12 @@ type Abteilung struct {
|
||||
WertItem float64
|
||||
}
|
||||
|
||||
type Monatsstatistik struct {
|
||||
Monat string // z. B. "07.2025"
|
||||
Summe float64 // bezahlte
|
||||
SummeOffen float64 // noch nicht bezahlt
|
||||
}
|
||||
|
||||
var tmpl = template.Must(template.New("form").Funcs(template.FuncMap{
|
||||
"formatNumber": formatNumber,
|
||||
"div": func(a, b float64) float64 {
|
||||
@@ -236,7 +243,6 @@ func main() {
|
||||
}
|
||||
e.Gesamtwert = e.Endbestand - e.Anfangsbestand
|
||||
e.Bezahlt = bezahlt == 1
|
||||
eintraege = append(eintraege, e)
|
||||
|
||||
if !e.Bezahlt {
|
||||
offeneSumme += e.Abgabe
|
||||
@@ -250,8 +256,40 @@ func main() {
|
||||
e.CreatedAt = "unbekannt"
|
||||
}
|
||||
|
||||
eintraege = append(eintraege, e)
|
||||
|
||||
}
|
||||
|
||||
monatsMap := map[string]*Monatsstatistik{}
|
||||
for _, e := range eintraege {
|
||||
parsed, err := time.Parse("2006-01-02 15:04:05", e.CreatedAt)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
monatKey := parsed.Format("01.2006") // z. B. "07.2025"
|
||||
|
||||
if _, ok := monatsMap[monatKey]; !ok {
|
||||
monatsMap[monatKey] = &Monatsstatistik{Monat: monatKey}
|
||||
}
|
||||
if e.Bezahlt {
|
||||
monatsMap[monatKey].Summe += e.Abgabe
|
||||
} else {
|
||||
monatsMap[monatKey].SummeOffen += e.Abgabe
|
||||
}
|
||||
}
|
||||
|
||||
var monatsStat []Monatsstatistik
|
||||
for _, stat := range monatsMap {
|
||||
monatsStat = append(monatsStat, *stat)
|
||||
}
|
||||
|
||||
sort.Slice(monatsStat, func(i, j int) bool {
|
||||
// Nach Datum aufsteigend sortieren
|
||||
ti, _ := time.Parse("01.2006", monatsStat[i].Monat)
|
||||
tj, _ := time.Parse("01.2006", monatsStat[j].Monat)
|
||||
return ti.Before(tj)
|
||||
})
|
||||
|
||||
// Dynamische Abteilungen – frei anpassbar
|
||||
abteilungen := []Abteilung{
|
||||
{Name: "Raumkampf", Anteil: 15, Beispiel: "CF-337 Panther", WertItem: 36308},
|
||||
@@ -278,19 +316,21 @@ func main() {
|
||||
}
|
||||
|
||||
tmpl.Execute(w, struct {
|
||||
Entries []Entry
|
||||
Summe float64
|
||||
OffeneSumme float64
|
||||
Abteilungen []Abteilung
|
||||
LoggedIn bool
|
||||
Member string
|
||||
Entries []Entry
|
||||
Summe float64
|
||||
OffeneSumme float64
|
||||
Abteilungen []Abteilung
|
||||
Monatsstatistik []Monatsstatistik
|
||||
LoggedIn bool
|
||||
Member string
|
||||
}{
|
||||
Entries: eintraege,
|
||||
Summe: summe,
|
||||
OffeneSumme: offeneSumme,
|
||||
Abteilungen: abteilungen,
|
||||
LoggedIn: isAuthenticated(r),
|
||||
Member: membername,
|
||||
Entries: eintraege,
|
||||
Summe: summe,
|
||||
OffeneSumme: offeneSumme,
|
||||
Abteilungen: abteilungen,
|
||||
Monatsstatistik: monatsStat,
|
||||
LoggedIn: isAuthenticated(r),
|
||||
Member: membername,
|
||||
})
|
||||
})
|
||||
|
||||
@@ -467,6 +507,28 @@ const htmlTemplate = `
|
||||
|
||||
<hr />
|
||||
|
||||
<h4 class="mt-4">Monatliche Übersicht</h4>
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Monat</th>
|
||||
<th>Abgaben verteilt</th>
|
||||
<th>Abgaben offen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{range .Monatsstatistik}}
|
||||
<tr>
|
||||
<td>{{.Monat}}</td>
|
||||
<td>{{formatNumber .Summe}} UEC</td>
|
||||
<td>{{formatNumber .SummeOffen}} UEC</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="alert alert-info">
|
||||
<strong>Die tatsächlichen Werte können abweichen.</strong> Die dargestellten Werte sind meine Vorstellung einer sinnvollen Verteilung.<br>
|
||||
Die Summe wird an die Orga-Leitung entrichtet. Die entgültige Entscheidung über die Verteilung obliegt der Orga-Leitung.
|
||||
|
Reference in New Issue
Block a user