Commit Graph

80 Commits

Author SHA1 Message Date
beo3000 65c18f4f51 added christmasTree additional End Option:
ChristmasTreeGameSetup.cs
  - Neues Enum GameEndCondition mit AllFivesGone (Standard) und TreeCleared
  - Property EndCondition zum Setup hinzugefügt

  ChristmasTreeGameModel.cs
  - Property EndCondition hinzugefügt

  ChristmasTreeGameLogicService.cs
  - Neue Methode CheckGameEndCondition() prüft je nach Einstellung
  - Neue Methode CheckAnyTreeCleared() prüft ob ein Team alle Zahlen gestrichen hat
  - Alle 3 Stellen wo Spielende geprüft wird nutzen jetzt die flexible Methode

  ChristmasTreeSetup.razor
  - Neues Dropdown "Spielende" mit zwei Optionen:
    - "Alle 5er gestrichen" (Standard)
    - "Ein Baum komplett leer"
  - Hilfstexte erklären die jeweilige Bedingung
2026-01-08 18:58:28 +01:00
beo3000 56f3e63046 fix ChristmaTree: Select Number Action 2026-01-08 18:44:37 +01:00
beo3000 31bbaaf70a added game christmas tree 2026-01-08 16:23:00 +01:00
beo3000 7aa49f8271 fix change default club:
Der Fix teilt die Operation in zwei Schritte:
  1. Alle IsDefault auf false → SaveChanges
  2. Neuen Default auf true → SaveChanges

  Das verhindert, dass EF Core temporär zwei IsDefault = true Einträge hat, was den Filtered Unique Index verletzen würde.
2026-01-07 22:19:18 +01:00
beo3000 e2ee3e6afe added club-terminology
Angepasst:
  - Club.cs - Navigation Property Terminologies
  - AppDbContext.cs - DbSet ClubTerminologies
  - DependencyInjection.cs - Service-Registrierung
  - NavMenu.razor - Menüpunkt "Begriffe" unter Stammdaten

  Migration: AddClubTerminology erstellt und angewandt.

  Nutzung im Code:
  @inject IClubTerminologyService Terms

  // In Component:
  var term = await Terms.GetTermAsync(TermKey.Gutter);  // "Gosse" oder Default "Pudel"

  Neue Keys einfach in TermKey.cs hinzufügen + Default in ClubTerminologyService.Defaults.
2026-01-06 18:41:16 +01:00
beo3000 d1215d73cb add ChristmasTree.md 2026-01-05 21:52:18 +01:00
beo3000 ebc00d6773 fix FoxHunt -> 21 Points for fox to win 2026-01-05 21:41:08 +01:00
beo3000 caeb1a8e8b added Team-Support
Features:
  - Beliebig viele Teams
  - Editierbare Team-Namen
  - "Zufällig verteilen" Button
  - Warnung bei ungleichen Team-Größen
  - Validierung bei Required-Modus
2026-01-05 21:07:22 +01:00
beo3000 3f62b3c0e0 refactorings 2026-01-05 19:49:41 +01:00
beo3000 4d584e98af refactorings 2026-01-05 19:07:15 +01:00
beo3000 8987fc34b5 dev foxhunt 2026-01-05 15:27:51 +01:00
beo3000 187a7e14c8 dev foxhunt 2026-01-05 15:02:53 +01:00
beo3000 433b61618d dev foxhunt 2026-01-04 22:27:24 +01:00
beo3000 86ea4f8640 foxhunt part2 2026-01-04 21:42:54 +01:00
beo3000 29fa9c5e84 fox hunt part1 2026-01-04 21:24:30 +01:00
beo3000 0d94d4c5c0 K20 fertig. Änderungen:
1. ClubService.cs:134 - MonthlyMembershipFee in UpdateAsync hinzugefügt
  2. Settings.razor:358-364 - Laden der Kassenbuch-Einstellungen beim Init
  3. Settings.razor:665-689 - SaveCashBookSettings() Methode implementiert

  Der Kassenbuch-Tab in den Vereins-Einstellungen funktioniert jetzt:
  - Zeigt aktuellen Kontostand
  - Erlaubt Ändern des monatlichen Mitgliedsbeitrags
  - Speichert Änderungen via Fluxor-Action
  - Quick-Links zu Kassenbuch, Kategorien, Berichten
2026-01-04 09:56:15 +01:00
beo3000 ea237183f9 K17 fertig.
Erweitert: src/Koogle.Application/Services/CashBookExportService.cs

  PDF-Struktur (QuestPDF 2025.12.1):
  - Header: Titel, Vereinsname, Berichtszeitraum
  - Zusammenfassung: Salden-Tabelle (Anfang/Einnahmen/Ausgaben/End)
  - Kategorien: Einnahmen + Ausgaben mit farbigen Tabellen
  - Footer: Erstelldatum + Seitenzahlen
2026-01-03 22:03:17 +01:00
beo3000 5bd0e19f06 K16 fertig.
Erstellte Dateien:
  - src/Koogle.Application/Interfaces/ICashBookExportService.cs - Interface mit ExportToExcelAsync + ExportToPdfAsync
  - src/Koogle.Application/Services/CashBookExportService.cs - Excel-Export via ClosedXML

  Excel-Struktur (3 Sheets):
  1. Zusammenfassung - Salden, Summen, Statistik
  2. Kategorien - Einnahmen/Ausgaben nach Kategorie
  3. Buchungen - Alle Einträge mit Summenzeile

  NuGet: ClosedXML 0.105.0 hinzugefügt.
2026-01-03 21:59:13 +01:00
beo3000 595c92df76 K10: create penalty entries on day close
- ICashBookService.CreatePenaltyEntriesForDayAsync
- Groups PersonExpenses by person, sums amounts
- Marks PersonExpenses as Done
- DayService calls after SaveChanges
2026-01-03 15:00:42 +01:00
beo3000 21c3d03c61 K9: seed system categories on club creation
- EnsureSystemCategoriesAsync accepts optional clubId
- ClubService calls seeder after GIF seeding
2026-01-03 14:56:50 +01:00
beo3000 2c09cfa991 K8: add cashbook service implementations
- BookingCategoryService: CRUD + EnsureSystemCategoriesAsync
- CashBookService: entries, balance, reports, membership fees
- CashBookMappingProfile: entity to DTO mappings
- DI registration for both services
2026-01-03 14:53:48 +01:00
beo3000 1a7ba8837d K7: add cashbook service interfaces
- IBookingCategoryService: CRUD + EnsureSystemCategories
- ICashBookService: entries, balance, report, membership fees
2026-01-03 14:45:07 +01:00
beo3000 96c5b4d196 K6: add cashbook DTOs
- BookingCategoryDto, CreateBookingCategoryDto, UpdateBookingCategoryDto
- CashBookEntryDto, CreateCashBookEntryDto, UpdateCashBookEntryDto
- CashBookReportDto, CategorySummaryDto, CreateMembershipFeesDto
2026-01-03 14:39:40 +01:00
beo3000 3b65f9f1cd fix switch club and RefreshSign 2026-01-02 22:48:00 +01:00
beo3000 51b8c2dbd4 edit users in club-settings 2026-01-02 20:58:49 +01:00
beo3000 f0b0d617a5 handling club memberships and creation of clubs:
Neue Dateien erstellt:

  - Domain/Enums/ClubRequestStatus.cs - Enum
  - Domain/Entities/ClubRequest.cs - Entity
  - Infrastructure/Data/Configurations/ClubRequestConfiguration.cs - EF Config
  - Application/DTOs/ClubRequestDto.cs - DTOs
  - Application/Interfaces/IClubRequestService.cs - Interface
  - Application/Services/ClubRequestService.cs - Service
  - Web/Controllers/ClubSwitchController.cs - API
  - Web/Components/Pages/Account/ClubSetup.razor - Club-Setup Seite
  - Web/Components/Shared/ClubSwitcher.razor - NavMenu Dropdown
  - Web/Components/Pages/Admin/ClubRequests.razor - SuperAdmin Freigaben

  Geänderte Dateien:

  - Login/Register: ClubName-Feld entfernt
  - UserService: Auto-Select Logic, SwitchClubAsync
  - AuthController: Routing basierend auf Club-Anzahl
  - MainLayout: ClubSwitcher statt statischer Anzeige
  - AuthState/Effects: AvailableClubs laden

  Flow:

  Login → Clubs vorhanden?
    ├─ Nein → /account/club-setup
    ├─ 1 Club → Auto-Select → /dashboard
    └─ Mehrere → IsDefault wählen → /dashboard
2026-01-02 19:15:30 +01:00
beo3000 028909c24f manage invitations and requests by club-admin 2026-01-02 14:47:09 +01:00
beo3000 b163fb30c7 send day protocol by email 2026-01-01 20:04:55 +01:00
beo3000 0d8289563d add email service:
Neue Dateien

  - src/Koogle.Domain/Interfaces/IEmailService.cs - Interface
  - src/Koogle.Infrastructure/Configuration/SmtpSettings.cs - SMTP-Konfiguration
  - src/Koogle.Infrastructure/Services/SmtpEmailService.cs - MailKit-basierte Implementierung

  Geänderte Dateien

  | Datei                  | Änderung                                    |
  |------------------------|---------------------------------------------|
  | Club.cs                | + SenderEmail Property                      |
  | Person.cs              | + UserProfileId + Navigation zu UserProfile |
  | ClubConfiguration.cs   | + SenderEmail Config                        |
  | PersonConfiguration.cs | + UserProfileId FK + Index                  |
  | DayService.cs          | + E-Mail-Versand bei Day-Close              |
  | ClubDto.cs             | + SenderEmail in allen DTOs                 |
  | PersonDto.cs           | + UserProfileId                             |
  | DependencyInjection.cs | + SmtpSettings + SmtpEmailService           |
  | appsettings.json       | + SmtpSettings Section                      |

  Gelöschte Dateien

  - StubEmailService.cs
  - IEmailService.cs (Application → Domain verschoben)

  Migration

  - AddEmailFeatures - Neue Spalten SenderEmail (Clubs) und UserProfileId (Persons)

  Konfiguration (appsettings.json)

  "SmtpSettings": {
    "Host": "smtp.example.com",
    "Port": 587,
    "Enabled": false  // Auf true setzen um E-Mails zu aktivieren
  }

  Funktionen

  1. Club-spezifische Absender-Adresse - Club.SenderEmail (Fallback: DefaultSenderEmail)
  2. Spieltag-Protokoll - HTML-E-Mail mit Tabelle der Strafen pro Teilnehmer
  3. Empfänger - Nur Teilnehmer mit verknüpftem UserProfile
  4. Error Handling - Log & Continue (Day-Close schlägt nicht fehl)
2026-01-01 19:13:05 +01:00
beo3000 4666056e24 add expenses, on day closing
1. Neue Methode CreateAbsentMemberExpensesAsync() (Zeile 322-421)
    - Prüft Club.ExpenseCalculation (None → skip)
    - Berechnet Average/Maximum aller Tages-Expenses
    - Findet Absent-Expense via ExpenseTriggerType.Absent
    - Erstellt PersonExpense für alle abwesenden Members
  2. Aufruf in AdvanceStatusAsync() (Zeile 312-316)
    - Wird aufgerufen wenn Status → Closed wechselt
    - Vor SaveChangesAsync() → eine Transaktion
2026-01-01 14:18:34 +01:00
beo3000 504daec8d7 fix ro media folder on linux:
1. IMediaStorageService (src/Koogle.Domain/Interfaces/):
  - Neue Methoden GetMediaBasePath() und GetFilePath() hinzugefügt

  2. MediaStorageService (src/Koogle.Infrastructure/Services/):
  - Erkennt Production+Linux → verwendet /home/data/club-media
  - Development → verwendet wwwroot/club-media

  3. Program.cs (src/Koogle.Web/):
  - StaticFileOptions für /club-media aus /home/data/club-media in Production

  4. DemoSeeder (src/Koogle.Infrastructure/Data/):
  - Alle Methoden nutzen jetzt IMediaStorageService statt hardkodierte Pfade

  5. ClubGifService (src/Koogle.Application/Services/):
  - Alle Path.Combine("wwwroot", ...) durch _mediaStorage.GetFilePath() ersetzt

  Das Verhalten:
  - Windows/Development: weiterhin wwwroot/club-media
  - Linux/Production (Azure): /home/data/club-media (persistent und beschreibbar)
2026-01-01 12:21:17 +01:00
beo3000 3b12a82982 submit gifs by URL:
UI (Submit.razor)
  - Toggle zwischen "Datei" und "URL" Modus
  - URL-Eingabefeld mit Validierung (nur HTTP/HTTPS)
  - Beide Modi teilen Submit-Button und Erfolgsanzeige

  Service (IClubGifService, ClubGifService)
  - Neue Methode SubmitAnonymousFromUrlAsync(token, url, name)
  - Nutzt bestehende SaveGifFromUrlAsync von MediaStorageService

  Serverseitige Validierung (bereits in MediaStorageService vorhanden):
  - Content-Type Prüfung: nur image/gif, video/mp4, video/webm
  - Dateigröße max. 20MB
  - Datei wird nach Download nochmals auf Größe geprüft
  - Ungültige Content-Types werden mit Exception abgelehnt
2026-01-01 10:58:02 +01:00
beo3000 49a03a8fbb fix Bell-Handling 2025-12-30 20:37:21 +01:00
beo3000 9aee6b50c0 add gif-Seeder and gif-Templates:
Zusammenfassung der Änderungen

  Template-GIF Seeding implementiert:

  1. DemoSeeder.cs aktualisiert:
  - SeedTemplateGifsAsync() - Öffentliche Methode für externes Seeding
  - SeedTemplateGifsInternalAsync() - Kopiert GIFs vom Template-Ordner und erstellt DB-Einträge
  - DeleteClubGifsAsync() - Löscht GIF-Dateien und DB-Einträge beim Reset
  - ResetDemoClubAsync() - Löscht nun auch GIFs und seedet sie neu
  - SeedAsync() - Seedet Template-GIFs beim Demo-Club-Setup

  2. IClubGifService.cs erweitert:
  - SeedTemplateGifsAsync(Guid clubId) - Neue Interface-Methode

  3. ClubGifService.cs erweitert:
  - SeedTemplateGifsAsync() implementiert - Liest giftemplates.json, kopiert Dateien und erstellt ClubGif-Einträge

  4. ClubService.cs aktualisiert:
  - Injiziert IClubGifService
  - CreateAsync() seedet automatisch Template-GIFs für neue Clubs

  Ablauf:

  1. Neuer Club: Template-GIFs werden automatisch kopiert nach wwwroot/club-media/{LoginName}/gifs/
  2. Demo-Reset: Alte GIFs werden gelöscht, Templates neu kopiert
  3. Demo-Seed: Template-GIFs werden geseedet falls noch keine vorhanden

  Template-Struktur:

  wwwroot/club-template/gifs/
  ├── giftemplates.json        # Definition der GIFs
  ├── 44f5bc11-...-d1215.gif   # Strike GIF
  └── 297970f3-...-a2a93.gif   # NoWood GIF
2025-12-30 18:00:11 +01:00
beo3000 752523fe78 added gif-Feature:
Summary of Changes:

  Phase 1-3 (Domain/Infrastructure/Application):
  - ThrowEventType enum with Strike, Circle, Bell, Gutter flags
  - ClubGif, ClubGifRating, GifSubmissionToken entities
  - EF configurations with proper indexes
  - ClubGifRepository with weighted random selection
  - MediaStorageService for file storage (wwwroot/club-media/{LoginName}/gifs/)
  - ClubGifService with rating system and auto-disable at -5 threshold

  Phase 4-5 (Admin UI & Playback):
  - Admin page at /club/{ClubId}/admin/gifs with Upload, Import, Edit, Token management
  - QR code generation for submission tokens
  - GifPlayer component with overlay, rating buttons, and dismiss
  - Fluxor state management (GifState, actions, reducers, effects)

  Phase 6 (Anonymous Submission):
  - Public page at /gif/submit/{Token} with EmptyLayout
  - Token validation and file upload

  Phase 7 (Game Integration + Migration):
  - Database migration AddClubGifFeature applied
  - GameEffects.TriggerGifForEventsAsync triggers GIFs on special throws
  - SignalR broadcast via BroadcastGifTriggeredAsync to all clients
  - DayDetails.razor includes GifPlayer and handles SignalR GIF events

  Key Features:

  - GIFs play on Strike (alle 9), Circle (Kranz), Bell (Glocke), Gutter (Rinne)
  - Weighted random selection based on ratings
  - Real-time sync across all connected clients via SignalR
  - Thumbs up/down rating with auto-disable at -5
  - Max file size: 20MB, Video duration: 15s
  - Supports GIF, MP4, WebM formats
2025-12-30 14:57:06 +01:00
beo3000 0e4e1530ed added LoginName for Clubs 2025-12-30 11:57:01 +01:00
beo3000 1fbf4763d9 add dayStatisticChart 2025-12-29 16:11:22 +01:00
beo3000 21130895d4 add statistics:
Erfasste Metriken:
  - ThrowCount, PinCount, ClearedCount, GutterCount, CircleCount, StrikeCount, BellCount

  Widget zeigt:
  - Jahres-Übersicht (Spiele, Würfe, Kegel, Durchschnitt)
  - Top 5 Kegler Rangliste
  - Monatstrend-Tabelle
2025-12-29 15:27:25 +01:00
beo3000 f5d2ceb628 fix unit tests 2025-12-29 14:33:53 +01:00
beo3000 e2d1792cec fix deathbox, first player starts with a X 2025-12-29 09:59:20 +01:00
beo3000 7795c3064f fix deathbox handling 2025-12-28 22:43:21 +01:00
beo3000 cafd38519f add deathbox 2025-12-28 21:25:04 +01:00
beo3000 b8bd1b0939 fix ShitGameLogic 2025-12-28 17:23:10 +01:00
beo3000 fc97a266d4 create and assign expenses:
Datenfluss bei Gutter:
  Spieler wirft Gosse
    → RecordThrowAction (IsGutter=true)
    → HandleRecordThrow
    → FireThrowTriggersAsync
      → GameEventService.RegisterGutterAsync
        → TriggerService.FireTriggerAsync
          → PersonExpense in DB gespeichert ✓
          → PersonExpenseDto zurückgegeben
      → dispatcher.Dispatch(TriggerExpensesCreatedAction)
        → DayReducer fügt Expenses zu SelectedDayExpenses hinzu
          → UI aktualisiert sich automatisch ✓
2025-12-28 15:41:57 +01:00
beo3000 fcfbbae94e fix CurrentClub Id
Änderungen:

  1. UserProfile.cs:47-52 - Neues Feld CurrentClubId (nullable FK zu Club)
  2. CustomClaimsPrincipalFactory.cs:38-50 - Lädt jetzt CurrentClub und setzt current_club_id/current_club_name Claims bei jeder Cookie-Erneuerung
  3. UserService.cs:113-118 - Speichert CurrentClubId bei Login, nutzt jetzt einfaches SignInAsync (Claims kommen via Factory)
  4. Migration AddCurrentClubIdToUserProfile erstellt + angewandt

  Ablauf jetzt:
  - Login → CurrentClubId wird in DB gespeichert
  - Cookie-Erneuerung → CustomClaimsPrincipalFactory liest CurrentClubId aus DB → Claims bleiben erhalten
2025-12-28 11:25:30 +01:00
beo3000 44b04ec2de dev Trigger / Expense Masterdata, Seeder for triggers 2025-12-28 11:16:51 +01:00
beo3000 954c2589e6 added Trigger and Trigger/Expense Releations 2025-12-28 10:18:39 +01:00
beo3000 22fbb79801 added GameAction Framework 2025-12-28 08:34:23 +01:00
beo3000 37b8fc0e8d add: IsCleared 2025-12-27 22:46:54 +01:00
beo3000 03364291aa fix undo/redo handling 2025-12-27 21:46:20 +01:00