Update für Beispielwertberechnung
All checks were successful
release-tag / release-image (push) Successful in 2m12s
All checks were successful
release-tag / release-image (push) Successful in 2m12s
This commit is contained in:
103
main.go
103
main.go
@@ -41,6 +41,7 @@ type Entry struct {
|
||||
Abgabe float64
|
||||
Gesamtwert float64
|
||||
Bezahlt bool
|
||||
CreatedAt string
|
||||
}
|
||||
|
||||
type Abteilung struct {
|
||||
@@ -48,10 +49,18 @@ type Abteilung struct {
|
||||
Anteil float64 // in Prozent
|
||||
Wert float64 // berechnet: Anteil * Summe / 100
|
||||
WertOffen float64 // berechnet: Anteil * Summe / 100 (von offen)
|
||||
Beispiel string
|
||||
WertItem float64
|
||||
}
|
||||
|
||||
var tmpl = template.Must(template.New("form").Funcs(template.FuncMap{
|
||||
"formatNumber": formatNumber,
|
||||
"div": func(a, b float64) float64 {
|
||||
if b == 0 {
|
||||
return 0
|
||||
}
|
||||
return a / b
|
||||
},
|
||||
}).Parse(htmlTemplate))
|
||||
|
||||
// Tausendertrenner für deutsche Zahlendarstellung (z. B. 12345 → "12.345")
|
||||
@@ -162,6 +171,19 @@ func main() {
|
||||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||
})
|
||||
|
||||
http.HandleFunc("/unmarkaspaid", func(w http.ResponseWriter, r *http.Request) {
|
||||
if !isAuthenticated(r) {
|
||||
http.Error(w, "Nicht autorisiert", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
id := r.URL.Query().Get("id")
|
||||
if id != "" {
|
||||
db.Exec("UPDATE eintraege SET bezahlt = 0 WHERE id = ?", id)
|
||||
}
|
||||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||
})
|
||||
|
||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method == http.MethodPost {
|
||||
if !isAuthenticated(r) {
|
||||
@@ -175,8 +197,7 @@ func main() {
|
||||
diff := ende - anfang
|
||||
abgabe := (diff / 100) * prozent
|
||||
|
||||
_, err := db.Exec(`INSERT INTO eintraege (anfangsbestand, endbestand, prozentwert, abgabe) VALUES (?, ?, ?, ?)`,
|
||||
anfang, ende, prozent, abgabe)
|
||||
_, err := db.Exec(`INSERT INTO eintraege (anfangsbestand, endbestand, prozentwert, abgabe, created_at) VALUES (?, ?, ?, ?, datetime('now'))`, anfang, ende, prozent, abgabe)
|
||||
if err != nil {
|
||||
http.Error(w, "Fehler beim Einfügen", http.StatusInternalServerError)
|
||||
return
|
||||
@@ -185,7 +206,7 @@ func main() {
|
||||
return
|
||||
}
|
||||
|
||||
rows, err := db.Query(`SELECT id, anfangsbestand, endbestand, prozentwert, abgabe, bezahlt FROM eintraege`)
|
||||
rows, err := db.Query(`SELECT id, anfangsbestand, endbestand, prozentwert, abgabe, bezahlt, created_at FROM eintraege`)
|
||||
if err != nil {
|
||||
http.Error(w, "Fehler beim Abrufen", http.StatusInternalServerError)
|
||||
return
|
||||
@@ -198,7 +219,7 @@ func main() {
|
||||
for rows.Next() {
|
||||
var e Entry
|
||||
var bezahlt int
|
||||
err := rows.Scan(&e.ID, &e.Anfangsbestand, &e.Endbestand, &e.Prozentwert, &e.Abgabe, &bezahlt)
|
||||
err := rows.Scan(&e.ID, &e.Anfangsbestand, &e.Endbestand, &e.Prozentwert, &e.Abgabe, &bezahlt, &e.CreatedAt)
|
||||
if err != nil {
|
||||
log.Println("Fehler beim Scan:", err)
|
||||
continue
|
||||
@@ -217,22 +238,22 @@ func main() {
|
||||
|
||||
// Dynamische Abteilungen – frei anpassbar
|
||||
abteilungen := []Abteilung{
|
||||
{Name: "Raumkampf", Anteil: 15},
|
||||
{Name: "Bodenkampf", Anteil: 8},
|
||||
{Name: "Racing", Anteil: 3},
|
||||
{Name: "Medical", Anteil: 5},
|
||||
{Name: "Exploration", Anteil: 3},
|
||||
{Name: "Rettung", Anteil: 5},
|
||||
{Name: "Logistik", Anteil: 8},
|
||||
{Name: "Mining", Anteil: 3},
|
||||
{Name: "Salvaging", Anteil: 3},
|
||||
{Name: "Trading", Anteil: 3},
|
||||
{Name: "Basebuilding (+10)", Anteil: 0},
|
||||
{Name: "Crafting (+8)", Anteil: 0},
|
||||
{Name: "Forschung (+5)", Anteil: 0},
|
||||
{Name: "Events (-23)", Anteil: 38},
|
||||
{Name: "Roleplay", Anteil: 3},
|
||||
{Name: "Kunstflug", Anteil: 3},
|
||||
{Name: "Raumkampf", Anteil: 15, Beispiel: "CF-337 Panther", WertItem: 36308},
|
||||
{Name: "Bodenkampf", Anteil: 8, Beispiel: "P4-AR Rifle (10x)", WertItem: 59000},
|
||||
{Name: "Racing", Anteil: 3, Beispiel: "LumaCore - Power Plant", WertItem: 69300},
|
||||
{Name: "Medical", Anteil: 5, Beispiel: "Drake Cutlass Red", WertItem: 2857680},
|
||||
{Name: "Exploration", Anteil: 3, Beispiel: "Anvil Terrapin", WertItem: 5433120},
|
||||
{Name: "Rettung", Anteil: 5, Beispiel: "GSX-HP Fuel-Pod", WertItem: 115200},
|
||||
{Name: "Logistik", Anteil: 8, Beispiel: "MaxLift Tractor Beam", WertItem: 19175},
|
||||
{Name: "Mining", Anteil: 3, Beispiel: "Helix II", WertItem: 108000},
|
||||
{Name: "Salvaging", Anteil: 3, Beispiel: "Abrade Scraper Module", WertItem: 21250},
|
||||
{Name: "Trading", Anteil: 3, Beispiel: "MaxLift Tractor Beam", WertItem: 19175},
|
||||
{Name: "Basebuilding (+10)", Anteil: 0, Beispiel: "CF-337 Panther", WertItem: 36308},
|
||||
{Name: "Crafting (+8)", Anteil: 0, Beispiel: "CF-337 Panther", WertItem: 36308},
|
||||
{Name: "Forschung (+5)", Anteil: 0, Beispiel: "CF-337 Panther", WertItem: 36308},
|
||||
{Name: "Events (-23)", Anteil: 38, Beispiel: "CF-337 Panther", WertItem: 36308},
|
||||
{Name: "Roleplay", Anteil: 3, Beispiel: "Clothing (10x)", WertItem: 84000},
|
||||
{Name: "Kunstflug", Anteil: 3, Beispiel: "Esperia Talon", WertItem: 3260250},
|
||||
}
|
||||
|
||||
for i := range abteilungen {
|
||||
@@ -281,6 +302,10 @@ func createTable(db *sql.DB) {
|
||||
if err != nil && !strings.Contains(err.Error(), "duplicate column") {
|
||||
log.Fatal(err)
|
||||
}
|
||||
_, err = db.Exec(`ALTER TABLE eintraege ADD COLUMN created_at TEXT DEFAULT CURRENT_TIMESTAMP`)
|
||||
if err != nil && !strings.Contains(err.Error(), "duplicate column") {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
const loginForm = `
|
||||
@@ -346,11 +371,11 @@ const htmlTemplate = `
|
||||
<div class="row mb-3">
|
||||
<div class="col">
|
||||
<label class="form-label">Anfangsbestand</label>
|
||||
<input type="number" step="0.01" name="anfangsbestand" class="form-control" required>
|
||||
<input type="number" step="1" name="anfangsbestand" class="form-control" required>
|
||||
</div>
|
||||
<div class="col">
|
||||
<label class="form-label">Endbestand</label>
|
||||
<input type="number" step="0.01" name="endbestand" class="form-control" required>
|
||||
<input type="number" step="1" name="endbestand" class="form-control" required>
|
||||
</div>
|
||||
<div class="col">
|
||||
<label class="form-label">Prozentwert</label>
|
||||
@@ -399,7 +424,11 @@ const htmlTemplate = `
|
||||
</td>
|
||||
<td>
|
||||
{{if .Bezahlt}}
|
||||
{{if $.LoggedIn}}
|
||||
<a href="/unmarkaspaid?id={{.ID}}" class="btn btn-sm btn-outline-success">Als unverteilt markieren</a>
|
||||
{{else}}
|
||||
<span class="badge bg-success">✓ verteilt</span>
|
||||
{{end}}
|
||||
{{else}}
|
||||
{{if $.LoggedIn}}
|
||||
<a href="/markaspaid?id={{.ID}}" class="btn btn-sm btn-outline-success">Als verteilt markieren</a>
|
||||
@@ -446,6 +475,36 @@ const htmlTemplate = `
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h4 class="mt-4">Gegenwert in Items:</h4>
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Abteilung</th>
|
||||
<th>Beispiel</th>
|
||||
<th>Wert pro Item</th>
|
||||
<th>Summe verteilt</th>
|
||||
<th>Menge</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{range .Abteilungen}}
|
||||
<tr>
|
||||
<td>{{.Name}}</td>
|
||||
<td>{{.Beispiel}}</td>
|
||||
<td>{{formatNumber .WertItem}} UEC</td>
|
||||
<td>{{formatNumber .Wert}} UEC</td>
|
||||
<td>
|
||||
{{if gt .WertItem 0.0}}
|
||||
{{formatNumber (div .Wert .WertItem)}}
|
||||
{{else}}
|
||||
-
|
||||
{{end}}
|
||||
</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{{if .LoggedIn}}
|
||||
<form action="/reset" method="POST" onsubmit="return confirm('Alle Einträge wirklich löschen?')">
|
||||
|
Reference in New Issue
Block a user