Commit Graph
780 Commits
Author SHA1 Message Date
svennickel e1a0637795 Spielpunkte-Regel an eine Stelle: spielpunkteFuerSpiel() in tools.php
Vorarbeit fuer die STFV-Satzwertung (#304/#306-Konzept, Abschnitt 6): die
Spielpunkte-Kaskade stand woertlich doppelt im PHP — einmal beim Speichern des
Spielberichts (admin.php, Rechenweg A), einmal in begegnungenAktualisieren()
(sportsmanager.php, Rechenweg B). Der Remis-Vorfall (35384a5, 5d1df85) ist genau
aus dieser Doppelung entstanden. Bevor eine vierte Wertung dazukommt, wird die
Regel EINE Funktion: spielpunkteFuerSpiel(wertung, heim, gast) in tools.php,
beide Wege rufen sie nur noch auf. Reine Umformung, keine Verhaltensaenderung;
die dritte Rechenstelle (das erzeugte Formular-JavaScript) bleibt in diesem
Schritt unangetastet.

Gemessen, nicht nur begruendet — vorab wurden vier weitere Prueflige angelegt,
damit ALLE Wertungen und Spielformen unter der Messlatte liegen (C = Sieg 3/
Remis 1, D = Sieg 1, E = Race mit 9:9-Abbruch, F = Mehrere mit Ergebnis je Satz
samt Satz-Remis; dazu die bestehenden A = Gewinnsaetze, B = Einer sowie
Damenbundesliga und Testliga). Ablauf identisch vor und nach der Umformung:
alle zehn Modi unveraendert durchs Formular gespeichert (Rechenweg B ueber alle
116 Begegnungen), dazu zehn Begegnungen quer durch alle Ligen unveraendert
durchs Spielbericht-Formular (Rechenweg A). Danach verglichen:

  - Datenbank-Dump (116 Begegnungen, 455 teamspiel-Zeilen, 32 Team-Zeilen,
    138 bestenliste_punkte-Zeilen, 756 Zeilen gesamt): VOLLSTAENDIG identisch.
  - Frontend-Dump (8 Ligen je 3 Spieltagsansichten + 7 Spielerstatistiken,
    30995 Zeilen HTML): VOLLSTAENDIG identisch.
2026-09-09 18:46:01 +02:00
svennickel 5d1df8579d Gleicher Satzstand bleibt ein Unentschieden — die Sonderregel kommt weg
Sven beim Testen von Begegnung 93 (2:2 im Doppel, Modus 3 Gewinnsaetze,
Wertung Sieg 2/Remis 1): das Formular rechnete 7:3 vor, gespeichert wurde 6:2.
„Und das ist meinem Verstaendnis nach doch auch das richtige Ergebnis?" — ja.

Zwei Fehler in einem:

1. Die Spielpunkte werden an DREI Stellen berechnet, nicht an zweien: zusaetzlich
   zu admin.php und begegnungenAktualisieren() rechnet das Formular selbst per
   JavaScript mit (view_admin.php, spielpunkte_bedingung()). 554ad25/35384a5
   hatten die Remis-Sonderregel in die ersten beiden eingebaut, die dritte lief
   nach der alten Regel weiter — daher 7:3 gegen 6:2.

2. Die Sonderregel selbst war falsch. „Unentschieden nur, wo der Satzmodus es
   zulaesst" war eine Ableitung aus 554ad25, keine Anforderung. Die Wertung
   sagt ausdruecklich „Sieg 2 Punkte, Unentschieden 1 Punkt" — das ist eine
   Anweisung fuer den gleichen Stand, und eine Zahl von Gewinnsaetzen sagt nur,
   WANN ein Spiel endet, nicht dass ein gleicher Stand wertlos ist. Spiele
   enden faktisch gleich (Abbruch, Zeitlimit, Absprache); ein 0:0 an der Stelle
   verliert dieselbe Information, die es schuetzen wollte.

Also: remisMoeglich() samt beiden Verwendungen entfernt, alle drei Wege rechnen
wieder die langjaehrige Regel. Gemessen auf zwei Pruefligen (je 6 Begegnungen,
30 Spiele, 4 Gleichstaende ungleich 0:0): die auf demselben Datenbestand neu
berechneten Tabellen sind zwischen dem Stand vor diesem PR und danach
VOLLSTAENDIG identisch — keine einzige Zahl weicht ab. Begegnung 93 zeigt im
Formular, auf der Seite und in der Datenbank uebereinstimmend 7:3.
2026-09-08 18:31:24 +02:00
svennickel 7f1bedc41e Kommentare aus dem Quelltext entfernen
Aus dem Review: „Der Quelltext ist absolut ueberkommentiert." Nach dem Kuerzen
in 554ad25 jetzt vollstaendig — 294 Kommentarzeilen aus fuenf Dateien.

Nachgewiesen unveraendert: der Diff ohne Kommentar- und Leerzeilen gegen
5aee028 ist vor und nach dieser Aenderung derselbe (gleiche Pruefsumme). Es ist
also ausschliesslich Kommentar entfernt worden, keine Zeile Programmtext.

Entfernt wurden nur die von diesem Zweig HINZUGEFUEGTEN Kommentare; jeder
Kommentar, der im alten Stand schon stand, bleibt unangetastet (auch dort, wo
Formularzeilen verschoben wurden).
2026-09-08 18:17:24 +02:00
svennickel 35384a5c43 Die Remis-Regel galt nur auf einem der beiden Rechenwege
Sven 2026-09-08: „Teste fuer alle Modus, ob Siege, Unentschieden und
Niederlagen weiter korrekt berechnet werden pro Spiel fuer saemtliche
Modusszenarien."

Beim Testen ueber die volle Matrix (4 Spielpunkte-Wertungen x 7 Satzmodi x 4
Spielstaende = 112 Szenarien) kam ein Fehler DIESES Zweigs heraus: die
Spielpunkte werden an ZWEI Stellen berechnet, und 09ae1c1/554ad25 hatte die
Remis-Pruefung nur in eine davon eingebaut.

  Weg A  admin.php, Spielbericht speichern        — MIT Pruefung
  Weg B  sportsmanager.php, begegnungenAktualisieren() bei Modus-/
         Wettbewerbsaenderung                     — OHNE Pruefung

Dasselbe Spiel bekam damit verschiedene Spielpunkte, je nachdem, welcher Weg es
zuletzt angefasst hatte: Speichern ergab 0:0, ein Moduswechsel schrieb 1:1
zurueck. Betroffen sind Gleichstaende ungleich 0:0 in Wettbewerben, deren
Satzmodus kein Remis zulaesst (ein fester Satz, ungerade Satzzahl,
Gewinnsaetze) bei Wertung „Sieg 2/Remis 1" oder „Sieg 3/Remis 1" — 8 der 112
Szenarien. Gemessen, nicht geschaetzt.

Die Regel steht jetzt als remisMoeglich() auf Dateiebene und wird von beiden
Wegen aufgerufen, statt als Closure in einem der beiden Loops zu leben.
Matrix danach: 0 Widersprueche.

NICHT betroffen und mitgeprueft:
- Siege/Unentschieden/Niederlagen je Spiel sind in ALLEN 112 Szenarien
  unveraendert. Sie kommen in der Spielerstatistik aus dem Vergleich der
  PUNKTE (sportsmanager.php:6338), nicht aus den Spielpunkten, und an den
  Punkten aendert dieser Zweig nichts.
- Race bleibt unberuehrt: die Race-Normalisierung setzt die Wertung auf 2
  („ohne Umrechnung"), und dort gibt es keinen Remis-Zweig.
- spielerstatistikAktualisieren() selbst ist unveraendert (nur die
  Einheiten-Beschriftung kam hinzu).
2026-09-08 17:46:38 +02:00
svennickel 2c4b3e0908 Spielpunkte-Wertung neben die Einheit, die sie uebernimmt
Sven 2026-09-08: „hier wuerde ich die Option direkt unter ‚Saetze pro Spiel'
ziehen und abhaengig von der Einstellung bei ‚Saetze pro Spiel' benennen".

Die vierte Wertung („ohne Umrechnung") uebernimmt das Spielergebnis als
Spielpunkte — welche Zahl das ist, sagt aber ein ANDERES Feld: Tore bei
„Einer", Saetze bei „Mehrere". Sie stand bisher zwei Gruppen weiter oben unter
„Begegnung", also getrennt von der Angabe, die ihre Bedeutung festlegt.

- „Spielpunkte pro Spiel" (Einzel + Doppel) sitzt jetzt direkt unter „Saetze
  pro Spiel" in der Gruppe „Spiel" — wo sie hingehoert: es ist eine Angabe zum
  einzelnen Spiel, nicht zur Begegnung. „Begegnung abgeschlossen bei" bleibt in
  der Gruppe „Begegnung".
- Der Eintrag heisst jetzt nach der gewaehlten Einheit: „Ohne Umrechnung –
  Saetze sind die Spielpunkte" bzw. „… Tore sind die Spielpunkte". Ueber
  dasselbe data-tore/data-saetze-Verfahren, das die Siegbedingungen schon
  benutzen; umgeschaltet in zeilen_anzeigen(), also auch beim Wechseln ohne
  Neuladen. Der alte Sammeltext bleibt als Rueckfall stehen.
- Am lokalen Testserver gerendert und geprueft: Reihenfolge stimmt, beide
  Texte kommen uebersetzt an.
- Nebenbei: der Kommentar nannte Datenbankversion 126, tatsaechlich ist es 122.
2026-09-08 16:08:44 +02:00
svennickel 84211e9f9e Ergebnisanzeige, Spielerstatistik, und die Spielfolge bleibt schmal
Drei weitere Punkte aus dem Review.

1. ERGEBNISANZEIGE BEI SAETZEN. Im Spielbericht stand je Spiel NUR ergebnis_detailliert. Bei
reinem „Mehrere" ist das derselbe Satzstand — bei Erfassung je Satz sind es die Saetze, und
dann fehlte, wer das Spiel gewonnen hat. Gemessen: die Zeilen lasen „6:3 | 3:6" ohne jede
Angabe des Standes. Jetzt steht der Stand davor und die Saetze in Klammern dahinter:
„1:1 (6:3 | 3:6)", „2:1 (6:3 | 3:6 | 6:4)". Wo beides dasselbe ist („Einer", oder „Mehrere"
ohne Satzerfassung), bleibt es einzeilig — gegengeprueft an einer Begegnung aus der
Einer-Zeit: unveraendert „6:3", nichts doppelt. Ein nicht gespieltes Spiel bleibt leer und
zeigt kein „0:0".

2. SPIELERSTATISTIK. Die Spalten „T +/-" summieren teamspiel_*_punkte, zaehlen also je
punktetyp Tore oder gewonnene Saetze — hiessen aber immer „Tore". Anders als in der Tabelle
gibt es hier nicht einen Modus: eine Bestenliste kann mehrere Wettbewerbe umfassen, sogar
Individualwettbewerbe. spielerstatistikEinheit() liest deshalb den punktetyp der speisenden
Wettbewerbe; sind sie einig, steht die richtige Einheit, sonst „Punkte" — statt eine zu
behaupten, die nicht fuer alle Zeilen gilt. Neuer Schluessel COM_SPORTSMANAGER_SETS_SHORTCUT
in beiden Sprachen. Alle drei Faelle gemessen: nur „Mehrere" -> „S +/-" mit „Saetze",
gemischt -> „P +/-" mit „Punkte", zurueck -> wieder „S".

Und der Tooltip der Tabellenspalte hiess COM_SPORTSMANAGER_DIFFERENCE = „Differenz Tore",
widersprach also der neuen Beschriftung „Saetze". Er nennt jetzt nur die Rechenart
(„Differenz"), wie sein Geschwister „Verhaeltnis" schon immer; die Einheit steht in der
Spalte. Einzige Verwendungsstelle.

3. SPIELFOLGE. Die sechs Auswahlfelder der Spielfolge und der Verknuepfungen stehen wieder
auf medium — sie tragen kurze Werte und sollten nicht mitwachsen. Breit bleiben nur die 33
Felder der Einstellungen, wo die langen Beschriftungen stehen.
2026-09-07 18:01:58 +02:00
svennickel 099174c0ef Tabellenspalte richtig benennen: bei „Mehrere" sind es Saetze, keine Tore
Aus dem Review: „Die Summe der Tore ist auch falsch." Sie ist es nicht — sie ist falsch
BESCHRIFTET. Unter punktetyp „Mehrere" ist begegnung.heim_punkte seit immer die Summe der
Satzstaende, und die Tabellenspalte heisst „Tore". Bisher fiel das nicht auf, weil die Tore
gar nicht bekannt waren; mit der Erfassung je Satz sind sie es, und die Spalte behauptet
etwas, was sie nicht zeigt.

Die Absicht war schon da: tabelleAnzeigen() fragt `punktetyp != 2 ? Tore : Saetze` — nur
kennt punktetyp ausschliesslich 0 und 1, die Bedingung war also nie wahr. Jetzt
`punktetyp == 0 ? Tore : Saetze`, an beiden Spaltenkoepfen (Absolut und Differenz/Verhaeltnis).

Gemessen an zwei Wettbewerben derselben Installation: bei punktetyp 1 stehen jetzt „Saetze
Absolut" und „Saetze", bei punktetyp 0 unveraendert dreimal „Tore". Keine Zahl aendert
sich, kein Sortierschluessel, keine Bestandsdaten.

Die Alternative — die echten Tore summieren, wo Satzergebnisse geführt werden — waere ein
Eingriff in Bestandsstaende und in die Tabellensortierung und gehoert in einen eigenen PR
mit Migration (Sven 2026-09-07).
2026-09-07 13:52:35 +02:00
svennickel 554ad25156 Review: Unentschieden nur, wo es moeglich ist; Kommentare gekuerzt; Felder breiter
Drei Punkte aus dem Review.

1. UNENTSCHIEDEN, WO ES KEINES GIBT. Gemeldet: „2 Punkte pro Spiel und 1 Punkt
unentschieden ausgewaehlt, es kommt aber nur 1 Punkt pro Spiel." Nachgestellt an einer
Begegnung mit vier Spielen (Modus: Mehrere, Ergebnis je Satz, 3 Gewinnsaetze, Wertung
„Sieg 2, Remis 1"): Spiel 1 mit 6:3 3:6 steht 1:1 nach Saetzen und bekam 1:1 Spielpunkte.

Bei einer Zahl von GEWINNSAETZEN ist ein gleicher Satzstand aber kein Unentschieden,
sondern ein unfertiges Spiel — dafuer gibt es keinen Punkt. Die Rechnung fragt jetzt, ob
der Modus ueberhaupt ein Remis zulaesst: bei Gewinnsaetzen nein, bei fester Satzzahl nur
bei gerader Zahl, ohne Angabe wie bisher. Gemessen an derselben Meldung: Spiel 1 jetzt
0:0, die Begegnung 6:0 statt 7:1; die Spiele 2 bis 4 unveraendert 2:0.

Die Rechnung selbst ist Altbestand und von diesem PR nicht angefasst — erst die neue
Satzzahl liefert die Information, mit der sie unterscheiden kann.

2. KOMMENTARE. Zu Recht beanstandet. Was Sprachmechanik erklaert oder den Code
nacherzaehlt, ist raus; was eine Entscheidung oder einen Messwert festhaelt, bleibt in
hoechstens drei Zeilen. Die Herleitung gehoert in den PR-Text, nicht in die Datei.
update.php von 87 auf 22 Kommentarzeilen (57 % auf 25 % der Aenderung), ueber alle Dateien
von 459 auf 267.

3. AUSWAHLFELDER. Die 39 Auswahlfelder des Modus-Formulars stehen von medium (200 px) auf
large (500 px). Bei 200 px brach eine Beschriftung wie „Ohne Umrechnung - Tore bzw. Saetze
sind die Spielpunkte" ab. Nur dieses Formular, keine andere Ansicht.

Danach geprueft: sechs Ansichten HTTP 200 ohne PHP-Meldung, php -l sauber, dieselbe Meldung
mit dem erwarteten Ergebnis.
2026-09-07 13:30:21 +02:00
svennickel 09ae1c1609 Siegbedingungen vollstaendig abbilden, samt Race-Modus (#304)
Vorsprung und Deckelung je Spiel, dieselbe Regel eine Ebene tiefer fuer den
einzelnen Satz, eine Auswahl der Satzzahl (feste Zahl oder Gewinnsaetze) samt
optional abweichender Regel fuer den Entscheidungssatz, eine Auswahl
"Mehrere - mit Ergebnis je Satz" mit Satzzeilen im Begegnungsformular — und
eine Zaehlweise "Race-Modus", in der der Stand ueber die ganze Begegnung
durchlaeuft.

Die Regel beschreibt den Wettbewerb, sie lehnt keine Eingabe ab: ein 8:6 dort,
wo ein Spiel bei 6 endet, hat oft einen Grund, den keine Regel kennt, und ueber
die Richtigkeit wachen beide Mannschaften. Ihr Nutzen liegt darin, dass eine
auswertende Anwendung endlich erkennen kann, ob ein Spiel entschieden ist.

RACE-MODUS. Das Spiel N endet, wenn der LAUFENDE Stand einer Seite N mal den
Schritt erreicht; eingetragen wird wie bisher die DIFFERENZ dieses Spiels, und
der Begegnungsstand bleibt ihre Summe. Gemessen an 91 Bundesliga-Begegnungen:
6:5 5:7 7:5 4:7 8:2 6:9 6:5 summiert sich auf 42:40, und laufend gelesen trifft
jedes Spiel seine Etappe (6, 12, 18, 24, 30, 36, 42). Die Ergaenzung im Formular
rechnet deshalb mit laufenden Staenden und zieht ab, was schon auf dem Konto
steht.

Im Formular steht statt des gespeicherten "Zwischenergebnis" jetzt der
GESAMTSTAND, gross und in Echtzeit: die Spielpunkte, gerechnet aus den
eingetragenen Spielen mit derselben Arithmetik, die der Server beim Speichern
anwendet. Es ist DIE Zahl, die die Begegnung nach aussen hat — Liste,
Mannschaftsseite und die Kopfzeile der Begegnungsdetails zeigen alle
heim_spielpunkte:gast_spielpunkte. Gemessen an einem 5er-Spielplan mit "Sieg: 1
Punkt": ein eingetragenes 6:4 ergibt "1:0", genau wie die Details. Die Torsumme
gehoert dagegen in die Tabellenspalte "Tore" und nicht in den Kopf einer
Begegnung. Die Zeile steht als letzte des Kopfes, unter dem Kommentar, mit
demselben senkrechten Abstand, den die Spiele untereinander haben — und ohne
erklaerenden Zusatz: "Gesamtstand" samt Zahl sagt es selbst.

Das Ziel wird nicht eingegeben, sondern folgt aus der Spielfolge. Dort steht
deshalb die Rechenvorschrift ("Anzahl der Spiele aus der Spielfolge x Schritt je
Spiel") und die konkrete Zahl erst ab zwei Spielen ("derzeit 7 Spiele x 6 = 42
Tore"): bei einem einzigen — dem Anfangszustand — waere "1 Spiele x 6 = 6 Tore"
nicht nur ungrammatisch, sondern eine Auskunft ueber einen Zustand, den niemand
gemeint hat. Mindestvorsprung, Grenze und ein moegliches
Unentschieden gelten nur fuer das letzte Spiel. Die Zaehlweise setzt
"Spielergebnis als Spielpunkte" und einen Satz je Spiel voraus und setzt beides
mit; das Ziel wird zusaetzlich nach punkte_sieg_* gespiegelt (mit Vorzeichen
fuer das Unentschieden), damit eine aeltere Programmfassung dieselbe wahre
Aussage liest. Vorrunde und Hauptrunde sind zwei Mannschaftsspielplaene. Die Zaehlweise steht als
erste Zeile ihrer Gruppe: was sie ausblendet, liegt darunter — Felder ueber einer
Auswahl verschwinden zu lassen, liest sich als Fehler.

Damit die Einstellungen ueberhaupt auseinanderzuhalten sind, steht dem Editor
eine kurze Begriffsleiter voran: Begegnung, Spiel, Satz, Tor. Sie stecken
ineinander, und die Gruppen darunter folgen genau dieser Reihenfolge. Drei
weitere Hinweiszeilen sagen, was "Ergebnis je Satz" bedeutet, wozu die Angaben
gut sind und wie der Race-Modus zaehlt.

Die vierte Spielpunkte-Wertung hiess "Keine" und sagte damit das Gegenteil
dessen, was sie tut: gewertet wird alles, nur ohne Umrechnung — das Ergebnis
des Spiels IST sein Spielpunktestand. Sie heisst jetzt "Ohne Umrechnung - Tore
bzw. Saetze sind die Spielpunkte"; die drei uebrigen beginnen mit "Sieg:", also
sagt schon der Satzanfang, dass es hier nicht um einen Sieg-Wert geht.

Die Hinweiszeilen brechen ausdruecklich um und haben ein Mass (max-width): die
Zellen dieses Formulars tragen alle `nowrap`, was fuer Beschriftungen und
Auswahlfelder richtig ist und fuer Prosa falsch — die Hinweise zogen die Tabelle
sonst beliebig breit. Wo ein Hinweis steht, ist die Beschriftung oben
ausgerichtet: sonst stand sie auf halber Hoehe des Absatzes statt neben dem
Auswahlfeld, zu dem sie gehoert.

Die Satzebene fuehrt dasselbe Vorzeichen wie die Spielebene: der Betrag ist der
Siegwert, ein negatives Vorzeichen erlaubt zusaetzlich ein Unentschieden ein Tor
darunter. Ohne diese Faelle waere ein Satz, der remis endet, gar nicht
hinterlegbar gewesen.

Bestehende "Mehrere"-Modi werden in die Satzzahl UEBERFUEHRT, und zwar restlos: 1 wird ein fester Satz, ein positiver Wert N werden N
Gewinnsaetze, ein negativer wird die feste Satzzahl 2(|N|-1) — denn ein Remis
setzt voraus, dass alle Saetze gespielt werden. Auch Werte jenseits der neuen
Auswahl werden ueberfuehrt statt als "Beliebig" liegen zu bleiben, denn sie sind
nicht unsinnig, nur ungewoehnlich: ein gespeichertes "Spiel gewonnen bei 42
Saetzen" bleibt nach der Ueberfuehrung dieselbe wahre Aussage, nur an der
richtigen Stelle. Das Formular zeigt einen solchen Wert als EIGENEN,
vorgewaehlten Eintrag der Auswahl ("42 Gewinnsaetze"), speichert ihn unveraendert
wieder und bietet ihn, einmal weggestellt, nicht mehr an. Sonst haette dort eine
Zeile ohne Auswahlfeld gestanden — die Beschriftung "Spiel abgeschlossen bei:"
und rechts daneben nichts — oder die Zahl waere beim ersten Speichern
verschwunden. Gemessen an drei Bestandswerten: 42 wird -42 und uebersteht Anzeige
und Speichern unveraendert, -9 wird die feste Satzzahl 16, und nach dem Wechsel
auf "3 Gewinnsaetze" hat die Auswahl 18 statt 19 Eintraege. Der Race-Modus wird
NICHT automatisch erkannt; er ist aus Bestandsdaten nicht sicher abzuleiten und
wird einmal von Hand gewaehlt.

Dass die Ueberfuehrung nichts verschiebt, ist gemessen und nicht bloss
begruendet: dieselbe Datenbank einmal unter der alten Fassung mit altem Schema
und einmal unter dieser, je sieben Begegnungen unveraendert neu gespeichert und
dann Tabellen, Uebersicht, Spielerstatistik und drei Begegnungsdetails
verglichen — 7942 Zeilen HTML und 436 Datenzeilen aus begegnung und teamspiel,
kein einziger Unterschied. Darunter der Bestandsmodus mit punkte_sieg 42, den
die Ueberfuehrung anfasst.

Umgekehrt spiegelt der Editor die Satzzahl VOLLSTAENDIG nach punkte_sieg_*
zurueck, nicht nur bei Gewinnsaetzen: eine feste Satzzahl sagt genau, welche
Endstaende es gibt, und damit auch, bei welchem Stand das Spiel entschieden ist —
4 feste Saetze heissen "gewonnen bei 3, Unentschieden bei 2:2" (-3), 3 feste
Saetze "gewonnen bei 2" (2). Das ist die Umkehrung der Ueberfuehrung und deshalb
verlustfrei. Zuvor blieb punkte_sieg_* bei fester Satzzahl leer, mit der
Begruendung, sie sei keine Siegbedingung — richtig gedacht, aber praktisch falsch:
ein Client, der nur die alten Felder kennt, haette nach einmaligem Oeffnen und
Speichern eines Bestandsmodus "Beliebig" gelesen, wo vorher eine Zahl stand. Und
es gibt einen solchen Client, den wir nicht mitziehen koennen (Kickern). Gemessen:
feste Satzzahl 4 -> -3, 3 -> 2, 6 -> -4, 1 -> 1, und Gewinnsaetze unveraendert
3 -> 3, 2 -> 2.

Die Einheit der Spielebene folgt punktetyp: Tore bei "Einer", Saetze bei
"Mehrere". Bisher stand dort in beiden Faellen "Punkte" — und genau daran war
eine Fehlkonfiguration nicht zu erkennen. Am echten TFVB-Spielplan 2026 sah man
es doppelt: "Spiel abgeschlossen bei 5 Punkte" direkt ueber "Mindestvorsprung 2
Tore", dieselbe Einheit in zwei Woertern. Innerhalb eines Satzes wird ohnehin
durchgaengig von Toren gesprochen.

Und "Spiele in Spielerstatistik" waehlt "Alle Spiele" jetzt ausdruecklich vor,
statt sich darauf zu verlassen, dass es die erste Option ist. Aus "Vorsprung" wird "Mindestvorsprung" (und
der Wert 1 heisst "Keiner"), aus "Deckelung" wird "Spaetestens gewonnen bei".

Die Einstellungen sind in fuenf Gruppen geordnet, vom Grossen ins Kleine:
Allgemein, Begegnung, Spiel, Satz, Spieler und Statistik. Dafuer wechseln drei
bestehende Zeilen den Platz — "Aktiv" nach oben zu "Bezeichnung",
"Spielernamen" hinunter zu "Spiele in Spielerstatistik", und die Gruppe
"Begegnung" vor die Gruppe "Spiel"; sonst ist nichts verschoben. Der Knopf
"Doppel getrennt einstellen" bekommt eine eigene Zeile, weil er auch die
Satzregel schaltet. Eine Gruppe ohne sichtbare Zeile zeigt keine Ueberschrift.

Die Spielfolge zeigt nur noch die Zeilen, die es gibt: Spiel 1 steht fest, weitere
kommen ueber "Spiel hinzufuegen", jede weitere traegt ein Kreuz zum Entfernen — ohne
Rueckfrage, denn gespeichert ist bis zum Speichern nichts. Verknuepfungen fangen bei
null an. Alle Zeilen bleiben im Dokument und werden beim Entfernen nach oben geschoben,
weil das Speichern spiel_1, spiel_2 … der Reihe nach liest und beim ersten leeren Paar
abbricht. Das Ziel des Race-Modus rechnet dabei mit: es haengt an der Zahl der Spiele,
und die aendert sich hier.

Bei "Mehrere" beantwortet die Satzzahl die Frage vollstaendig — "Spiel abgeschlossen
bei" wird dort deshalb gar nicht mehr angeboten. Es geht dabei nichts verloren, weil
jeder Bestandswert in die Satzzahl uebergeht (siehe oben) und ein Wert jenseits der
Auswahl dort als eigener Eintrag steht.

Ohne geforderten Mindestvorsprung endet ein Spiel exakt beim Siegwert — eine Grenze
kann dann nie greifen. "Spaetestens gewonnen bei" wird deshalb ueberall nur noch
angeboten, wo ein Vorsprung verlangt ist, und beim Speichern auf null gesetzt.

Die Spielfolge steht schon in derselben Spalte unter den Einstellungen und bekommt
deshalb nur ihre Ueberschrift — als sechste Gruppe. Und "Spiele in Spielerstatistik"
stellte nackte Zahlen neben "Alle Spiele"; sie sagen jetzt, was sie zaehlen ("nur die
ersten 3 Spiele").

Beim WECHSEL der Satzart wird nichts umgerechnet — aus sechs Toren wuerden sechs
Saetze, und umgekehrt; aus "drei gewonnene Saetze" folgt keine Torzahl, es ist also gar
nicht rekonstruierbar. Stattdessen zwei Massnahmen. Erstens fragt der Editor nach, wenn
"Saetze pro Spiel" geaendert wird und unter dem Spielplan schon Ergebnisse stehen.
Zweitens ueberleben echte Satzergebnisse den Weg zurueck von "mit Ergebnis je Satz" auf
"nur der Satzstand": bringt ein Aufruf keine Satzfelder mit, bleibt der Stand
unveraendert und stehen im Bestand mehr als ein Paar, bleibt ergebnis_detailliert, wie
es ist — sonst haette blosses Oeffnen und Speichern "6:3 3:6 6:3 3:6 8:6" durch "3:2"
ersetzt. Wird der Stand geaendert, wird der Detailtext wie bisher neu geschrieben.

RUECKWAERTSKOMPATIBEL, und zwar geprueft und nicht bloss behauptet.

EINE Datenbankversion, 122, nicht sechs (Sven 2026-09-03): alle Spalten in einem
ALTER, die Ueberfuehrung dahinter, ein Zaehler hoch. 121 gehoert dem
Hall-of-Fame-Zweig (PR #303 / Issue #300), auf dem dieser Stand aufsetzt; dieser
Block muss deshalb der LETZTE der Kette bleiben — $datenbank_version wird einmal
gelesen, beide Bloecke laufen also im selben Aufruf, aber die Nummer des zuletzt
gelaufenen bleibt stehen. Gemessen gegen eine Datenbank, die #303 schon hinter sich
hat: 121 -> 122, unsere 24 Spalten dazu, die drei Hall-of-Fame-Spalten unberuehrt,
der Bestandsmodus mit punkte_sieg 42 als saetze_modus -42 ueberfuehrt. Die Zwischenstufen waren nur
die Reihenfolge, in der ich gebaut habe — kein Bestand hat sie je gesehen, und
sechs Schritte, die immer zusammen laufen, sind sechs Gelegenheiten, auf halbem
Weg stehenzubleiben. Gemessen an einer Datenbank auf Stand 120: ein Aufruf, 120
-> 122, 13 Spalten -> 37, der Bestandsmodus mit punkte_sieg 42 als saetze_modus
-42 ueberfuehrt; ein zweiter Lauf tut nichts (die Spaltenpruefung und das WHERE
der Ueberfuehrung sehen beide, dass es schon geschehen ist).

Ein Client, der nur die ueberlieferten Felder liest, soll weiterarbeiten wie
bisher — es gibt mindestens einen, den wir von hier aus nicht mitziehen koennen
(Kickern). Dafuer zaehlt nicht, was hinzukommt, sondern was sich an dem aendert,
was er schon liest. Neue Spalten sind harmlos: die Modus-Zeile geht als ganzes
Objekt in die JSON-Ansicht, unbekannte Schluessel ignoriert jeder Client. Die
Ueberfuehrung selbst fasst kein altes Feld an. Bleiben zwei Stellen, und beide
sind versorgt.

Erstens der Wertebereich von punktetyp. "Mehrere - mit Ergebnis je Satz" war
zuerst ein dritter Wert 2 — und punktetyp ist genau das Feld, an dem eine fremde
Anwendung ablesen muss, ob die Punkte eines Spiels Tore oder gewonnene Saetze
sind. Wer "1 = Saetze, sonst Tore" schreibt statt "0 = Tore, sonst Saetze",
haette bei einem Satzstand 3:2 "3:2 Tore" gelesen; beide Fassungen stehen im
Sports Manager selbst. Die Angabe bekommt deshalb eine EIGENE Spalte
(satzergebnisse), punktetyp behaelt seine zwei Werte und seine Bedeutung. Ein
Altclient liest weiter "Mehrere" und rechnet richtig — die Punkte SIND die
gewonnenen Saetze, daran aendert die feinere Erfassung nichts; er verpasst nur
das Zusaetzliche. Die Auswahl im Editor hat weiter drei Eintraege, der dritte
schreibt punktetyp 1 samt satzergebnisse 1.

Zweitens: der Server verlangt die Satzergebnisse NICHT, auch wo sie eingestellt
sind. Er fragt beim Speichern ueberhaupt nicht nach dem Modus — kommt kein
Satzfeld mit, gilt der Summenwert, wie immer. Gemessen an einem Spielplan mit
"3 Gewinnsaetze" und Satzerfassung, gemeldet wie ein Altclient nach
SetsMode.setsOnly (nur spiel_N_*_punkte, keine Satzfelder): Spiel 1 als 3:1
gespeichert, Spielpunkte 1:0, ergebnis_detailliert "3:1" — genau die Zeile, die
das eigene Formular unter "Mehrere" auch schreibt. Dieselbe Begegnung nimmt
gemischt beides auf: Spiel 1 als Satzstand, Spiel 2 als "6:3 3:6 6:4". Meldet der
Altclient danach beide Spiele erneut als Satzstand, ueberleben die Satzergebnisse
von Spiel 2 unveraendert; dasselbe beim Oeffnen und Speichern im Verbandsformular,
das fuer diesen Modus nur Satzzeilen zeigt — es belegt sie fuer Spiel 1 bewusst
nicht vor (aus "3:1" folgt kein erster Satz) und schickt den gespeicherten Stand
im versteckten Summenfeld mit. Nur wenn der Altclient das Spiel AENDERT, weicht
der Detailtext dem neuen Stand ("2:0") — er beschrieb dann ein anderes Ergebnis.

Und wo Satzergebnisse gefuehrt werden, bleibt ergebnis_detailliert bei einer Meldung
ohne Satzfelder LEER, statt wie sonst den Stand zu spiegeln. Dieses eine Paar bedeutet
dort naemlich etwas anderes als sonst: das Feld fuehrt Saetze, also liest man „3:1" als
einen Satz mit drei Toren und rechnet daraus 1:0 statt 3:1 — in unserer eigenen App
steckte genau dieser Fehler. Leer ist die Wahrheit: der Satzstand steht in
teamspiel_*_punkte, die Tore darin sind nicht bekannt, und die Anzeige laesst die
Detailspalte dann weg statt denselben Wert zweimal zu zeigen. Erfundene Platzhalter
(„1:0" je gewonnenen Satz) waeren die Alternative und sind verworfen: gespeichert liesse
sie niemand mehr von einer echten Meldung unterscheiden (Sven 2026-09-03). Es ist die
einzige Stelle, an der das Speichern nach dem Modus fragt. Gemessen: dieselbe
Altclient-Meldung schreibt unter „Mehrere" weiter „4:2" und unter „Mehrere - mit
Ergebnis je Satz" nichts; echte Satzergebnisse daneben bleiben unberuehrt, auch nach
erneuter Summenmeldung und nach Oeffnen und Speichern im Formular.

Der Race-Modus braucht dafuer nichts: fuer einen Altclient sieht ein
Race-Spielplan aus wie punktetyp 0, "Ergebnis als Spielpunkte" und punkte_sieg =
Ziel — also genau so, wie ein solcher Spielplan heute schon eingestellt ist. Er
verliert nichts und gewinnt nichts.

Die Spielerauswahl erscheint nur noch fuer eine Mannschaft, die auch Spieler
hinterlegt hat — sonst stand dort ein Feld mit nichts als dem Leereintrag und
behauptete eine Wahl, die es nicht gibt. Gespeichert wird dann genau wie bei
einer leeren Auswahl: der Server liest die fehlenden Felder mit Vorgabe 0, also
"kein Spieler". Die Absende-Pruefung wird SEITENWEISE erzeugt und liest nur, was
es gibt; ohne Kader auf beiden Seiten bleibt von ihr "return true" uebrig. Sonst
haette eine Forderung nach Namen, die niemand erfuellen kann, das Melden
verhindert statt es zu ordnen. Gemessen an drei Faellen: beide Kader (12 Felder
je Seite), nur der Heimkader (12 zu 0, und die Pruefung liest nur heim), keiner
(0 Felder, Pruefung ohne Feldzugriff, ein 5:3 speichert mit vier Spieler-IDs 0
und Begegnungsstand 5:3 bei Spielpunkten 1:0) — der letzte Fall ausdruecklich
mit "Spielernamen: Pflicht".

Nebenbei behoben:
- Durchweg leere Satzfelder gewannen gegen ein vorhandenes Summenergebnis; das
  blosse Oeffnen und Speichern loeschte damit Altbestand (gemessen: von sieben
  gespeicherten Spielen blieb eines uebrig).
- "Doppel separat" wurde allein aus punkte_sieg_* abgeleitet; abweichende
  Doppelwerte in den neuen Feldern waeren verborgen und beim naechsten
  Speichern ueberschrieben worden.
- Zwei hartkodierte deutsche Zeichenketten im uebersetzten Formular nutzen
  jetzt ihre vorhandenen Sprachschluessel.
- COM_SPORTSMANAGER_SETS fuehrte den Umlaut als HTML-Entitaet und wurde in zwei
  Auswahlfeldern erneut maskiert ("Sätze"); jetzt literal.
2026-09-06 21:23:49 +02:00
svennickel 5aee02830d Merge pull request #305 from Deutscher-Tischfussballbund/sportsmanager2-issue289
Zusatzinfo-Feld für Spielorte
2026-09-06 21:16:49 +02:00
Jürgen MeyerandClaude Sonnet 5 cb2e614604 Zusatzinfo-Feld für Spielort im Admin-Formular ergänzt und Frontend-Anzeige der Heimspielstätte um Weitere Infos, Ruhetag und Training erweitert.
Adresse der Heimspielstätte verlinkt jetzt zusätzlich auf Google Maps.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-06 17:50:42 +02:00
svennickel 5d126b0d28 Merge pull request #303 from Deutscher-Tischfussballbund/sportsmanager2-issue300
Überarbeitung Hall of Fame
2026-09-04 23:24:10 +02:00
Jürgen Meyer 69cf0e46ab Datenbankvorbereitung für issue 289 2026-09-04 11:34:07 +02:00
Jürgen Meyer df794966df Hall of Fame: Jahres-/Id-Filter korrigiert, inaktive Vereine bei Namens-Links berücksichtigt
- halloffame_id: Bereichssuche (z.B. "1-5") ist nicht mehr möglich, nur noch einzelne Werte.
- jahr: Bereichs- und Einzelwerte werden auf 1900..aktuelles Jahr+5 begrenzt; liegt bei einem Bereich der 2. Wert unter dem 1., werden die Werte vertauscht statt den Bereich zu verwerfen.
- halloffameNameLink verlinkt bei Vereinen jetzt nur noch, wenn der Verein nicht ausgetreten ist (analog zur bestehenden Spieler-Aktiv-Prüfung).
2026-09-04 08:35:27 +02:00
Jürgen MeyerandClaude Sonnet 5 12da0a9c00 Überarbeitung Hall of Fame
## Neue Frontend-Darstellungen (gruppierung)
- gruppierung=jahr - Jahresrückblick: eine Tabelle je Jahr mit allen Disziplinen, inkl. mehrerer Plätze, Team-Mitspielern und Spalten-/Zeilen-Layout wie auf der Detailseite.
- gruppierung=summe - Ranking über alle Disziplinen hinweg: ein Eintrag je Spieler/Team mit mindestens einem 1. Platz, inkl. Titelanzahl und Auflistung aller Titel (Disziplin, Jahre).
- gruppierung=summedisziplin - wie summe, aber eine eigene Rangliste je Disziplin.

## Neue/erweiterte Steuerungsparameter
- platzierung (inspalten/inzeilen), plaetzezeigen, sortierung (kontextabhängig: Jahresreihenfolge oder anzahl/name in den Summen-Ansichten).
- anzahltitel - Mindestanzahl an Titeln für die Summen-Ansichten.
- halloffame_id und jahr als Filter für alle Hall-of-Fame-Seiten, mit Komma- und Bereichs-Syntax (2006-2010,2015).
- Titel fällt auf den Joomla-Menütitel zurück, wenn kein eigener Titel im Menüpunkt gesetzt ist.
- Überschrift semantisch als h1 statt div.

## Mannschaftsspieler-Feld
- Neues Datenbankfeld teamspieler (TEXT) an #__sportsmanager_mitglied_von_halloffame, Eingabe im Backend als Textarea (nur bei Mannschaftsdisziplinen).
- Anzeige im Frontend bei platzierung=inzeilen oder wenn nur ein Platz gezeigt wird, sofern mindestens ein Eintrag >= 3 Zeichen vorhanden ist.

## Verlinkung & Bilder
- Spieler-, Vereins- und Mannschaftsnamen sind jetzt überall anklickbar (Detailseite, Jahresübersicht, Summen-Ansichten) und führen zur jeweiligen Profilseite - inaktive Spieler (ohne aktuellen Verein) bleiben unverlinkt.
- Dummybilder: neues geschlechtsneutrales Bild (spieler-n.png) für Spieler ohne Datenbank-ID; deren Geschlecht wird zusätzlich anhand der übrigen Spieler mit ID derselben Disziplin geschätzt, bevor auf das neutrale Bild zurückgefallen wird.
- Fehlt der Name zu einer Platzierung, wird in der Spaltenansicht nur das Bild weggelassen, in der Zeilenansicht die komplette Zeile.

## Neues Feld "nicht_ausgespielt"
- Neue Spalte nicht_ausgespielt (BOOL) hinter jahr an #__sportsmanager_mitglied_von_halloffame (Teil von Datenbank-Version 121).
- Admin-Formular: Checkbox neben dem Jahr-Feld; bei Aktivierung werden alle anderen Felder deaktiviert, beim Speichern werden Platz 2/3 gelöscht und Platz 1 auf reines nicht_ausgespielt=1 ohne Team-/Spielerdaten gesetzt.
- Frontend-Detailseite und Backend-Jahresliste zeigen bei solchen Einträgen "Nicht ausgespielt" statt Team-/Spielername an.
- Jahresübersicht und beide Summen-Ansichten überspringen solche Einträge vollständig.

## Vereins-Dropdown im Backend gruppiert
- Die Vereinsliste im Auswahlfeld (Plätze 1-3) ist jetzt in zwei optgroup-Blöcke aufgeteilt: "Aktive Vereine" / "Inaktive Vereine" (neue Sprachkonstanten COM_SPORTSMANAGER_ACTIVE_CLUBS / COM_SPORTSMANAGER_INACTIVE_CLUBS). Innerhalb jeder Gruppe bleibt die alphabetische Sortierung erhalten.

## Routing-Fix
- task=team_details und task=verein_details funktionierten nur, wenn der aktuelle Menüpunkt bereits auf content=teams bzw. content=vereine stand (z. B. beim Verlinken von der Hall-of-Fame-Seite aus nicht). Beide Tasks laufen jetzt wie spieler_details über eine content-unabhängige Route.

## Performance
- Options-Liste für Vereins-/Spieler-Dropdowns im Backend-Formular wurde bis zu 6x komplett neu gerendert (3 Plätze x 2 Spieler bzw. 3x Vereinsliste). Jetzt wird sie nur noch 1x aufgebaut, in einem <template>-Element abgelegt und per JavaScript in die <select>-Felder befüllt.
- Team-ID-Auflösung für Mannschaften ohne Vereinszuordnung läuft jetzt über eine einmalig geladene Liste statt einer Datenbankabfrage pro Zeile.

## Bugfixes
- halloffameTeamIdFuerTeamname() erwartete einen nicht-nullbaren string und stürzte bei nicht_ausgespielt-Einträgen (teamname = NULL) mit einem TypeError ab. Parameter ist jetzt nullable, leerer/NULL-Teamname liefert direkt null zurück.
- Bei Einzel-Disziplinen wurden Jahre in den Summen-Ansichten doppelt gezählt, wenn in der Datenbank (z. B. aus Altdaten) noch ein spieler2_id hinterlegt war; wird jetzt nur noch bei echten Doppel-Disziplinen berücksichtigt.

## Migration
- Datenbank-Version 121: neues Feld teamspieler, neue Spalte nicht_ausgespielt, Bereitstellung des neutralen Dummybilds für Bestandsinstallationen.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-02 11:33:38 +02:00
svennickel ca827a049f Merge pull request #302 from Deutscher-Tischfussballbund/sportsmanager2-issue301
Export von kompletten Ligen im json-Format
2026-08-30 15:16:26 +02:00
svennickel 70fb4d97b7 Merge pull request #299 from Deutscher-Tischfussballbund/sportsmanager2-issue298
Zusätzliche Link-Parameter für Menüeinträge "Allgemeine Inhalte"
2026-08-30 13:43:04 +02:00
Jürgen Meyer d39dc45cec Änderungsvorschläge abgearbeitet. 2026-08-30 11:57:17 +02:00
Jürgen Meyer c290986bac Änderung wie Vorgeschlagen übernommen. 2026-08-30 10:15:48 +02:00
Jürgen Meyer 9541bc0652 Export von kompletten Ligen im json-Format 2026-08-28 15:52:39 +02:00
jmeyer26 50e6872214 Merge pull request #288 from Deutscher-Tischfussballbund/claude/season-selection-url-persist-6yz518
Persist season selection in URL instead of cookie-only
2026-08-28 12:33:47 +02:00
Jürgen Meyer a953ebf130 Zusätzliche Link-Parameter für Menüeinträge "Allgemeine Inhalte" 2026-08-27 15:03:45 +02:00
MarvinF e8051bbcf6 Merge pull request #297 from Deutscher-Tischfussballbund/sportsmanager2-issue296
Mail sending silently fails
2026-08-25 22:51:32 +02:00
Jürgen Meyer a01efae2e9 Exception Fehler bei E-Mail Versand 2026-08-25 20:05:50 +02:00
MarvinF 04e4ea6cdf Merge pull request #295 from Deutscher-Tischfussballbund/294-fix-string-comparison-spielpunkte-bedingung
Match report: goals compared as strings – winner swapped for two-digit results
2026-08-25 12:40:01 +02:00
svennickel f787681fec fix: compare goals numerically in spielpunkte_bedingung()
Refs #294
2026-08-24 23:10:16 +02:00
MarvinF 541af8fb7f Merge branch 'sportsmanager2-stage' into sportsmanager2-dev 2026-07-16 23:16:50 +02:00
MarvinF cc92b938be Merge pull request #291 from Deutscher-Tischfussballbund/sportsmanager2-issue290
Bei Teilnehmerzahl 1 oder weniger eines Ranglistenturnieres werden oh…
2026-07-16 23:14:36 +02:00
Jürgen Meyer 4c21d66fbe Bei Teilnehmerzahl 1 oder weniger eines Ranglistenturnieres werden ohne weitere Berechnung 0 Punkte vergeben. 2026-07-16 14:27:34 +02:00
MarvinF afb89dba6e Rename dev_preview to dev_preview.yml dev-preview 2026-06-16 21:07:55 +02:00
MarvinF c4d599834a Create dev_preview 2026-06-16 21:06:47 +02:00
Claude dcea759ab2 Persist season selection in URL instead of cookie-only
Season filter dropdowns in all frontend views (Mannschaftswettbewerbe,
Turniere, Teams, Spielerstatistiken, Individualwettbewerbe, Ranglisten)
now navigate via JS URL update (window.location with searchParams) instead
of submitting a POST form. This puts filter_saison_id in the URL, making
season-filtered views bookmarkable and shareable.

The PHP backend already reads filter_saison_id from $_REQUEST (covers GET),
and the cookie is still set as fallback for links that don't carry the param.

For veranstaltungHeaderAlone (single competition detail view), the JS also
resets task=veranstaltungen and removes veranstaltungid on season change,
matching the previous form-based behaviour of navigating back to the list.

https://claude.ai/code/session_01VyKCAgyEfixxR6RhAkBSEL
2026-06-13 08:31:37 +00:00
MarvinF 19037d0729 Merge branch 'sportsmanager2-prod' into sportsmanager2-stage 2026-05-13 00:06:44 +02:00
MarvinF bfc65d6030 Merge pull request #284 from Deutscher-Tischfussballbund/sportsmanager2-dev
dev to stage
2026-05-13 00:05:08 +02:00
MarvinF 2a307b0987 Merge branch 'sportsmanager2-stage' into sportsmanager2-dev 2026-05-13 00:03:28 +02:00
MarvinF e8e6f7046d Merge pull request #283 from Deutscher-Tischfussballbund/sportsmanager2-issue282
add club mailing functionality to admin area
2026-05-13 00:02:35 +02:00
Marvin Flock 20ab5a44a9 fix: add table headers 2026-05-13 00:00:34 +02:00
Jürgen Meyer a5357e4a51 mailto Funktion bei Mannschaften in admin-Bereich Veranstaltung 2026-04-28 11:46:22 +02:00
Jürgen Meyer 68e16a3adb mailto Funktion bei Vereine in admin-Bereich 2026-04-28 09:45:29 +02:00
MarvinF 7d47b3ed24 Merge pull request #281 from Deutscher-Tischfussballbund/sportsmanager2-stage
stage to prod
v2.6.0
2026-04-14 19:10:16 +02:00
MarvinF cfc821f8ff Merge branch 'sportsmanager2-prod' into sportsmanager2-stage 2026-04-14 19:09:46 +02:00
MarvinF 582829331c Merge pull request #280 from Deutscher-Tischfussballbund/sportsmanager2-dev
dev to stage
2026-04-14 19:08:39 +02:00
MarvinF d8ccd08843 Merge branch 'sportsmanager2-stage' into sportsmanager2-dev 2026-04-14 19:08:15 +02:00
MarvinF 57e92da771 Merge pull request #279 from Deutscher-Tischfussballbund/sportsmanager2-issue274-neu
Enhancing Playerstatistics (Performance Index, Club Membership and more)
2026-04-14 19:06:45 +02:00
Marvin Flock 7f85888a26 fix: add table fix 2026-04-14 19:02:38 +02:00
Marvin Flock 13ad52f221 fix: add small fixes 2026-04-14 18:50:05 +02:00
Jürgen Meyer a44564a40e Anzeige naegative Satzpunkte in Ligatabelle 2026-04-09 11:11:37 +02:00
Jürgen Meyer ee4e817ad4 Aktualisierung Spielerstatistiken 2026-04-06 08:10:55 +02:00
jmeyer26 8a7ff6c234 Merge branch 'sportsmanager2-dev' into sportsmanager2-issue274-neu 2026-04-06 07:41:01 +02:00
Jürgen Meyer 8fb4ed1cdd Filter Mannschaften in Spielerstatistik 2026-04-06 07:33:33 +02:00