# Credits System Enhancement - Session Handoff

**Date:** January 22, 2026  
**Status:** Planning Complete - Ready for Implementation  
**Priority:** Medium

---

## Overview

This document captures the requirements and proposed implementation for enhancing the Credits system in the CC Soccer Drupal module. The work involves three main areas:

1. **Season Credits Summary Page** - Replace per-player credits list with a high-level season summary
2. **Admin User Credits Management** - Add/view/edit credits for individual players
3. **Player Credits Page (Phase 6)** - Public-facing page for players to view their own credits

---

## Current State Analysis

### Existing Credits Infrastructure

**Entity:** `Credits` (`/src/Entity/Credits.php`)
- Stores credit transactions in cents (integer to avoid float issues)
- Fields: user, season, amount, type, source, reason, status, expires, etc.
- Types: earned, used, expired, adjusted, donated
- Sources: registration_cancelled, rain_out, admin_adjustment, refund
- Statuses: active, used, expired, revoked, donated

**Service:** `CreditManagerService` (`/src/Service/CreditManagerService.php`)
- `issueCredit()` - Create credit for user
- `issueRainoutCredit()` - Create rainout credit
- `issueCancellationCredit()` - Create cancellation credit
- `getUserBalanceCents()` / `getUserBalanceDollars()` - Get user balance
- `getUserActiveCredits()` - Get all active credits (FIFO sorted)
- `useCredits()` - Apply credits to order
- `donateCredits()` - Donate all active credits
- `getSeasonCredits()` - Get all credits for a season
- `calculateRainoutCreditCents()` - Calculate credit amount for season

**Current Season Credits Page:** `/admin/ccsoccer/season/{season}/credits`
- Shows ALL individual credits for every player in the season
- Includes: Date, Player, Amount, Source, Reason, Status, Expires

**Game Status Form:** (`/src/Form/GameStatusForm.php`)
- Issues rainout credits to all players in a season
- Preview system with confirmation
- Multi-season support with custom amounts per season
- Tracks credits_applied on games to prevent duplicates

---

## Requirements from User

### 1. Season Credits Summary Page (Replaces current `/admin/ccsoccer/season/{season}/credits`)

**Old Site Reference:** Image 2 showing simple season-level credit summary

The old site shows:
- "Add New Season Credit" link
- Table with columns: Date Created, Amount, Title, Apply Dates, Revoke Dates, Actions (apply/revoke/edit/delete)
- Example: `01/06/2026 - 13:43 | $6.00 | rainout | 1/6/26 | 01/05/2026 - 17:43 | apply/revoke/edit/delete`

**Required Changes:**
- Replace the per-player list with a high-level **Season Credit Events** view
- Each row represents a credit event (e.g., "Rainout Jan 22") not individual player credits
- Ability to add a new "Admin Season Credit" without a rainout
- Actions: Apply (if not applied), Revoke, Edit, Delete
- Should reuse Game Status form pattern for applying credits to all players

**Questions:**
1. Should "Season Credit" be a new entity or stored differently?
2. Do we need an "unapplied" state where admin creates the credit event but hasn't applied it yet?
3. Should revoking credits actually delete the individual credits or mark them as revoked?
4. What fields should a Season Credit Event have? (amount, reason/title, apply_date, created, status)

### 2. Admin User Credits Management 

**Old Site Reference:** 
- Image 4: Players list showing Credits column (5,785 for Andrew Meade)
- Image 5: User account page with Credits tab
- Image 6: User credits page showing transaction history
- Image 7: Same as Image 6 (different user with $6.00 credit)

**Current New Site:**
- Players list already shows Credits column (from `SeasonController::players`)
- No way to view/edit individual user credits

**Required Features:**
- **Admin view of user credits:** `/admin/ccsoccer/player/{user}/credits` or `/user/{user}/credits` (admin tab)
  - Shows same format as Phase 6 player credits page
  - Table: Credits, Category, Date, Reason, Status, Actions (view/edit)
  - Summary at bottom: Total credits, Approved credits, Pending credits
  - Pagination support
  
- **Admin add/deduct credits:** `/admin/ccsoccer/player/{user}/credits/add`
  - Amount field (positive to add, negative to deduct)
  - Reason field
  - Season dropdown (optional - for associating with season)
  - Source auto-set to "admin_adjustment"

**Questions:**
1. Should this be a separate route or a local task tab on the user profile?
2. Should we allow editing existing credits or only adding new ones?
3. For deductions, should we create a negative credit or use credits from balance?

### 3. Player Credits Page (Phase 6 from Document)

**Route:** `/player/credits` or `/my-credits`  
**Access:** Authenticated users only (viewing their own credits)  
**Menu:** Add to "Player Links" dropdown menu

**Features:**
- Credit Balance Summary (prominent display)
  - Current available balance
  - Total earned (all time)
  - Total used (all time)
  - Total donated (all time)
  
- Credit History Table
  - Date, Amount, Source, Reason, Season, Status
  - Filters (nice to have): status, season, date range
  
**Files to Create:**
1. Route in `ccsoccer.routing.yml`
2. `PlayerCreditsController.php`
3. Template: `ccsoccer-player-credits.html.twig`
4. Theme hook in `ccsoccer.module`
5. CSS: `player-credits.css`
6. Library in `ccsoccer.libraries.yml`
7. Menu link in `ccsoccer.links.menu.yml`

---

## Proposed Implementation Plan

### Phase A: Season Credit Events (New Entity Approach)

Create a new "Season Credit Event" concept to track high-level credit applications:

**Option 1: New Entity `SeasonCreditEvent`**
```php
Fields:
- season (entity_reference to season)
- amount_cents (integer)
- title (string) - e.g., "Rainout Jan 22", "Admin bonus"
- source (list) - rain_out, admin_credit, other
- status (list) - pending, applied, revoked
- applied_date (datetime)
- revoked_date (datetime)
- credits_issued_count (integer) - number of credits created
- total_amount_issued (integer) - total cents issued
```

**Option 2: Use Config/State (Simpler)**
Store season credit events in config or database table without full entity:
- Pros: Simpler, faster to implement
- Cons: No entity features, harder to extend

**Recommendation:** Option 2 for MVP, can upgrade to entity later if needed.

### Phase B: Admin User Credits Page

Create admin interface to view/manage individual user credits:

**Routes:**
```yaml
ccsoccer.admin_user_credits:
  path: '/admin/ccsoccer/player/{user}/credits'
  defaults:
    _controller: '\Drupal\ccsoccer\Controller\AdminCreditsController::userCredits'
    _title_callback: '\Drupal\ccsoccer\Controller\AdminCreditsController::userCreditsTitle'
  requirements:
    _permission: 'view reports'

ccsoccer.admin_user_credits_add:
  path: '/admin/ccsoccer/player/{user}/credits/add'
  defaults:
    _form: '\Drupal\ccsoccer\Form\AdminCreditForm'
    _title: 'Add/Deduct Credits'
  requirements:
    _permission: 'issue credits'
```

**Controller:** `AdminCreditsController.php`
- Reuse Phase 6 template format
- Add admin-specific actions (edit, revoke)
- Link from Players list

**Form:** `AdminCreditForm.php`
- Amount (number, can be negative)
- Reason (text)
- Season (optional entity_reference)

### Phase C: Player Credits Page (Phase 6)

Implement exactly as specified in the Phase 6 document.

---

## Questions for User Before Implementing

### Season Credits Summary:

1. **Season Credit Events Storage:**
   - Do you want a new entity for "Season Credit Events"?
   - Or simpler tracking via database table?
   
2. **Apply/Revoke Flow:**
   - When "applying" a season credit, should it use the same preview/confirm flow as Game Status?
   - When "revoking", should it delete credits or mark them revoked?
   
3. **Relationship to Game Status:**
   - Game Status already issues rainout credits. Should that create a "Season Credit Event" record?
   - Or are Season Credit Events only for non-rainout admin credits?

4. **UI Placement:**
   - Keep the route `/admin/ccsoccer/season/{season}/credits`?
   - Or create a new "Season Credits Events" page separate from individual credits?

### Admin User Credits:

5. **Route Structure:**
   - `/admin/ccsoccer/player/{user}/credits` (new admin section)?
   - Or add as a local task tab on user profile page?
   
6. **Edit vs Add Only:**
   - Should admins be able to edit existing credits?
   - Or only add new credits/adjustments?

7. **Deduction Method:**
   - Create negative credit record?
   - Or use `useCredits()` to consume existing balance?

### Player Credits Page:

8. **Route Preference:**
   - `/player/credits`
   - `/my-credits`
   - `/user/{user}/credits` (with access control)?

9. **Filters:**
   - Implement status/season filters in initial version?
   - Or defer to future enhancement?

---

## Files That Will Be Created/Modified

### New Files:
- `/src/Controller/AdminCreditsController.php`
- `/src/Controller/PlayerCreditsController.php`
- `/src/Form/AdminCreditForm.php`
- `/src/Form/SeasonCreditEventForm.php` (if using entity approach)
- `/templates/ccsoccer-player-credits.html.twig`
- `/templates/ccsoccer-admin-user-credits.html.twig`
- `/css/player-credits.css`

### Modified Files:
- `ccsoccer.routing.yml` - Add new routes
- `ccsoccer.links.menu.yml` - Add player credits menu link
- `ccsoccer.module` - Add theme hooks
- `ccsoccer.libraries.yml` - Add CSS library
- `SeasonController.php` - Modify `credits()` method for summary view
- `GameStatusForm.php` - Optionally create Season Credit Event records

---

## Reference: Old Site URLs

From images analysis:
- Admin Season Credits: `/admin/manage/seasons/credit/manage/{season_id}` (Image 2)
- User Credits View: `/user/{uid}/points` (Image 6, 7)
- User Credits Add: `/admin/config/people/userpoints/add/{uid}` (referenced)
- Admin Players: `/players/{uid}` with Credits tab (Image 4, 5)

---

## Implementation Order Recommendation

1. **Start with Phase C (Player Credits Page)** - Standalone, doesn't modify existing
2. **Then Phase B (Admin User Credits)** - Reuses Phase C template
3. **Finally Phase A (Season Credits Summary)** - More complex, modifies existing

This order minimizes risk and allows incremental testing.

---

## Additional Context from Images

### Image 1: New Site - Season Credits List
- Current implementation at `/admin/ccsoccer/season/16/credits`
- Shows per-player credits: Date, Player, Amount, Source, Reason, Status, Expires
- Multiple rows per player possible (e.g., Test User113 has two credits)
- Status badges: Active (green), Used (gray)

### Image 2: Old Site - Season Credits Summary
- Simple list of credit events
- "Add New Season Credit" link at top
- Columns: Date Created, Amount, Title, Apply Dates, Revoke Dates, Actions
- This is the target UI for the Season Credits page

### Image 3: New Site - Game Status Preview
- Shows how rainout credits are previewed before applying
- "💰 Credits to be issued" with calculation
- Pattern to reuse for season credit application

### Image 4: Old Site - Players Admin List
- Shows Credits column (5,785 = $57.85)
- This already exists in new site

### Image 5: Old Site - User Account Page
- Tabs: My Account, Stored cards, Credits
- Sub-tabs: Account, Mobile, Twitter accounts
- Credits tab would link to user credits page

### Image 6 & 7: Old Site - User Credits Page
- Columns: Credits (amount), Category, Date, Reason, Status, Actions (view/edit)
- Summary: Total credits, Approved credits, Pending credits
- Pagination at bottom
- This is the target UI for both Admin User Credits and Player Credits pages

---

## Ready for Implementation

When you return to this, start by:
1. Answering the questions above
2. Implementing Phase C (Player Credits Page) first
3. Test with existing credit data
4. Move to Phase B and A

All the code patterns exist in the codebase - this is primarily about creating new routes and controllers using existing services.
