# PlayStation Card Controller Documentation

**File**: `/controllers/playStationCardController.php`  
**Purpose**: Gaming card package management system for PlayStation services  
**Last Updated**: December 20, 2024  
**Total Functions**: 12  
**Lines of Code**: ~875

---

## 📋 Overview

The PlayStation Card Controller manages prepaid gaming card packages for PlayStation services. It provides:
- Gaming package creation and management
- Client card purchasing and charging
- Card balance tracking and consumption
- Automatic expiration handling
- Payment processing integration
- Client debt management
- Cash register and save account updates
- Complete transaction history tracking

### Primary Functions
- [x] Gaming package management (creation, editing, deletion)
- [x] Client card purchasing with payment processing
- [x] Card balance tracking and consumption
- [x] Automatic card expiration handling
- [x] Payment method support (cash/debt)
- [x] Client debt integration
- [x] Save account management
- [x] Complete audit trail
- [x] AJAX payment processing
- [x] Card deletion and refund processing

### Related Controllers
- [restaurantplaystationpaly.php](#) - PlayStation gaming sessions
- [clientController.php](clientController.md) - Customer management
- [saveController.php](saveController.md) - Cash management
- [clientPayedDeptController.php](clientPayedDeptController.md) - Client payments

---

## 🗄️ Database Tables

### Primary Tables (Direct Operations)
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **playstationcard** | Gaming package definitions | id, name, packageVal, packagePrice, packageDays, file, del, userid, sysdate |
| **playstationclientcard** | Client purchased cards | id, cardid, clientid, buyDate, packVal, packPrice, packDays, packValConsumed, cardEndDate, cardStatus, del |
| **playstationclientcardpayhistory** | Card transaction history | id, clientid, cardid, cardValBefore, payAmount, changeType, cardValAfter, processname, modelid, tablename |

### Financial Integration Tables
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **client** | Customer master data | clientid, clientname, clientdebt |
| **clientdebtchange** | Client debt tracking | clientdebtchangeid, clientid, clientdebtchangeamount, clientdebtchangetype, clientdebtchangedate |
| **save** | Cash registers | saveid, savename, savecurrentvalue |
| **savedaily** | Cash flow tracking | savedailyid, saveid, savedailysavebefore, savedailychangeamount, savedailychangetype |

### System Tables
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **user** | System users | userid, username |
| **youtubelink** | Tutorial videos | youtubelinkid, title, url |

---

## 🔑 Key Functions

### 1. **add() / Package Creation** - Gaming Package Definition
**Location**: Line 341  
**Purpose**: Create new gaming card package with pricing and duration

**Function Signature**:
```php
function add()
// Triggered when: do=add
$name = filter_input(INPUT_POST, 'name');
$packageVal = (float) filter_input(INPUT_POST, 'packageVal');
$packagePrice = (float) filter_input(INPUT_POST, 'packagePrice');
$packageDays = (int) filter_input(INPUT_POST, 'packageDays');
```

**Process Flow**:
1. Handle image upload for package
2. Create package record with specifications
3. Set deletion flag and audit fields

**Package Structure**:
```php
$playstationCard->name = $name;              // Package name
$playstationCard->packageVal = $packageVal;  // Card value/credits
$playstationCard->packagePrice = $packagePrice; // Sale price
$playstationCard->packageDays = $packageDays;   // Validity period
$playstationCard->file = $file;              // Package image
```

---

### 2. **chargeCard() / Client Card Purchase** - Core Purchase Logic
**Location**: Line 406  
**Purpose**: Process client purchase of gaming card with complete financial integration

**Function Signature**:
```php
function chargeCard()
// Triggered when: do=dochargeCard
$cardid = (int) filter_input(INPUT_POST, 'cardid');
$client = (int) filter_input(INPUT_POST, 'client');
```

**Process Flow**:
1. **Transaction Initialization**: Start database transaction
2. **Package Loading**: Load selected gaming package
3. **Card Creation**: Create client card with validity dates
4. **Payment History**: Record purchase transaction
5. **Client Debt Update**: Reduce client debt by package value
6. **Client Debt Change**: Track debt change history  
7. **Save Account Update**: Increase cash register balance
8. **Save Daily Entry**: Record cash flow transaction
9. **Transaction Commit**: Finalize all changes

**Key Financial Logic**:
```php
// Calculate card end date
$startDate = strtotime($playstationClientCard->buyDate);
$playstationClientCard->cardEndDate = date('Y-m-d H:i:s', 
    strtotime('+' . $playstationClientCard->packDays . ' day', $startDate));

// Client debt reduction (package has value)
$debtAfter = $clientdata->clientdebt - $playstationCard->packageVal;
updateClientDebt($playstationClientCard->clientid, $debtAfter);

// Cash register increase (money received)
$saveData = getSaveValueAndPlus($_SESSION['saveid'], $playstationCard->packagePrice);
updateSave($saveId, $saveValueafter);
```

---

### 3. **payfromcard() / AJAX Payment Processing** - Real-time Card Payment
**Location**: Line 593  
**Purpose**: Process payment using card balance for gaming sessions (AJAX endpoint)

**Function Signature**:
```php
function payfromcard()
// AJAX call for real-time payment processing
$cardPayed = filter_input(INPUT_POST, 'cardPayed');
$client = (int) filter_input(INPUT_POST, 'client');
$restaurantPlaystationPlayId = filter_input(INPUT_POST, 'restaurantPlaystationPlayId');
```

**Process Flow**:
1. **Multi-Card Selection**: Find available client cards
2. **Smart Payment Distribution**: Distribute payment across multiple cards
3. **Card Balance Updates**: Update consumed amounts and status
4. **Client Debt Tracking**: Record debt change for paid amount
5. **Payment History**: Record detailed payment transactions

**Smart Payment Algorithm**:
```php
function selectCardsAndPay($cardPayed, $client, $restaurantPlaystationPlayId) {
    $allPlaystationClientCard = $playstationClientCardEX->getClientPSCards($client, " order by cardEndDate asc");
    $payedWtihinForeach = 0;
    
    foreach ($allPlaystationClientCard as $playstationClientCard) {
        if ($payedWtihinForeach == $cardPayed) break;
        
        $cardValBefore = $playstationClientCard->packVal - $playstationClientCard->packValConsumed;
        $cardValRequired = $cardPayed - $payedWtihinForeach;
        
        $onePay = ($cardValRequired <= $cardValBefore) ? $cardValRequired : $cardValBefore;
        $payedWtihinForeach += $onePay;
        
        $playstationClientCard->packValConsumed += $onePay;
        if ($playstationClientCard->packValConsumed >= $playstationClientCard->packVal) {
            $playstationClientCard->cardStatus = 1; // Fully consumed
        }
    }
}
```

---

### 4. **deleteClientCard() / Card Cancellation** - Refund Processing
**Location**: Line 479  
**Purpose**: Cancel card purchase and process refund (only if unused)

**Function Signature**:
```php
function deleteClientCard()
// Conditions: del=0 AND packValConsumed=0 (unused card only)
```

**Process Flow**:
1. **Validation**: Ensure card is unused (packValConsumed=0)
2. **Card Deletion**: Mark card as deleted
3. **Refund History**: Record cancellation transaction
4. **Client Debt Restoration**: Increase client debt by card value
5. **Save Account Adjustment**: Decrease cash register balance
6. **Financial Reconciliation**: Record all financial movements

**Refund Logic**:
```php
// Only allow refund if card is completely unused
if ($playstationClientCard->del == 0 && $playstationClientCard->packValConsumed == 0) {
    // Restore client debt
    $debtAfter = $clientdata->clientdebt + $playstationClientCard->packVal;
    
    // Reduce cash register balance  
    $saveData = getSaveValueAndMins($_SESSION['saveid'], $playstationClientCard->packPrice);
}
```

---

### 5. **handleExpiredCards() / Automatic Expiration Processing** - System Maintenance
**Location**: Line 531  
**Purpose**: Automatically process expired cards and handle remaining balances

**Function Signature**:
```php
function handleExpiredCards($clientId = 0)
// $clientId = 0 means process all clients, >0 means specific client
```

**Process Flow**:
1. **Query Expired Cards**: Find cards past their end date
2. **Status Update**: Change card status to expired (2)
3. **Balance Recovery**: Calculate remaining unused balance
4. **Client Credit**: Add remaining balance to client debt (as credit)
5. **History Recording**: Document expiration transaction

**Expiration Logic**:
```php
$expiredPlaystationCards = $playstationClientCardEX->getExpiredPSCards($queryString);
foreach ($expiredPlaystationCards as $playstationClientCard) {
    $playstationClientCard->cardStatus = 2; // Expired
    
    // Calculate remaining value
    $cardValBefore = $playstationClientCard->packVal - $playstationClientCard->packValConsumed;
    
    // Credit client for unused balance
    $debtAfter = $clientdata->clientdebt + $cardValBefore;
}
```

---

### 6. **show() / Package Management** - Package Display and Management
**Location**: Line 147  
**Purpose**: Display all gaming packages for management

**Function Signature**:
```php
// Triggered when: do=show
// Displays: All active packages (del=0)
```

---

### 7. **showClientsCards() / Card History and Filtering** - Client Card Management
**Location**: Line 228  
**Purpose**: Display and filter client card purchases with advanced filtering

**Function Signature**:
```php
// Supports filtering by: cardid, client, cardStatus, date ranges
$cardid = (int) filter_input(INPUT_POST, 'PSCardNoClient');
$client = (int) filter_input(INPUT_POST, 'client');  
$cardStatus = (int) filter_input(INPUT_POST, 'cardStatus');
```

**Advanced Filtering**:
- Card ID specific lookup
- Client-specific history
- Status filtering (active/consumed/expired)
- Purchase date range filtering
- Card expiration date filtering
- Default to current day if no filters

---

### 8. **update() / Package Modification** - Package Updates
**Location**: Line 368  
**Purpose**: Update existing gaming package details

**Process Flow**:
1. Handle image update (preserve existing if no new upload)
2. Update package specifications
3. Maintain package pricing and duration

---

## 🔄 Workflows

### Workflow 1: Client Card Purchase Process
```
┌─────────────────────────────────────────────────────────────┐
│             START: Client Selects Gaming Package           │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Package Selection                                       │
│     - Browse available packages                             │
│     - View package details (value, price, duration)        │
│     - Select desired package                               │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Client Selection and Validation                        │
│     - Select client account                                │
│     - Verify client exists and is active                  │
│     - Load current client debt status                     │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Card Creation and Initialization                       │
│     - Create client card record                            │
│     - Set package specifications                           │
│     - Calculate expiration date                           │
│     - Initialize consumption tracking                     │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Financial Processing                                    │
│     ┌─────────────────────────────────────────────────────┐ │
│     │  4a. Record Purchase Transaction                    │ │
│     │      - Log payment history entry                   │ │
│     │      - Track card value assignment                 │ │
│     └─────────────────────────────────────────────────────┘ │
│     ┌─────────────────────────────────────────────────────┐ │
│     │  4b. Update Client Debt                             │ │
│     │      - Decrease debt by package value               │ │
│     │      - Record debt change history                  │ │
│     └─────────────────────────────────────────────────────┘ │
│     ┌─────────────────────────────────────────────────────┐ │
│     │  4c. Update Cash Register                           │ │
│     │      - Increase save balance by package price      │ │
│     │      - Record cash flow transaction                │ │
│     └─────────────────────────────────────────────────────┘ │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  5. Transaction Completion                                  │
│     - Commit database transaction                          │
│     - Release client from processing state                │
│     - Generate success confirmation                        │
│     - Display card details and expiration                 │
└─────────────────────────────────────────────────────────────┘
```

---

### Workflow 2: Real-time Card Payment Processing
```
┌─────────────────────────────────────────────────────────────┐
│          START: Gaming Session Payment Request             │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Load Available Client Cards                            │
│     - Query active cards for client                       │
│     - Filter by card status (0=active, 1=consumed)        │
│     - Order by expiration date (use oldest first)         │
│     - Calculate available balance per card                │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Smart Payment Distribution                              │
│     FOR EACH available card:                               │
│     ┌─────────────────────────────────────────────────────┐ │
│     │  - Calculate card remaining balance                 │ │
│     │  - Determine payment amount for this card          │ │
│     │  - Apply payment (up to card limit)               │ │
│     │  - Update card consumption tracking               │ │
│     │  - Mark card as consumed if fully used            │ │
│     └─────────────────────────────────────────────────────┘ │
│     CONTINUE until full payment covered                    │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Update Client Financial Status                         │
│     - Increase client debt by paid amount                 │
│     - Record debt change for payment                      │
│     - Link to gaming session for tracking                 │
│     - Release client processing lock                      │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Record Payment History                                  │
│     - Create payment history entries for each card used   │
│     - Track before/after balances                         │
│     - Link to gaming session record                       │
│     - Return success status to gaming system              │
└─────────────────────────────────────────────────────────────┘
```

---

## 🌐 URL Routes & Actions

| URL Parameter | Function Called | Description |
|---------------|----------------|-------------|
| `do=` (empty) | Default display | Package creation form |
| `do=add` | `add()` | Create new gaming package |
| `do=show` | Package list | Display all packages |
| `do=edit` | Edit form | Package modification form |
| `do=update` | `update()` | Update package details |
| `do=delete` | `delete()` | Soft delete package |
| `do=choosePack` | Package selection | Client package selection |
| `do=chargeCard` | Charge form | Client card purchase form |
| `do=dochargeCard` | `chargeCard()` | Process card purchase |
| `do=showClientsCards` | Card history | Client card management |
| `do=deleteClientCard` | `deleteClientCard()` | Cancel/refund card |
| `do=handleExpiredCards` | `handleExpiredCards()` | Process card expiration |
| `do=payCard` | Payment form | Gaming session payment |
| `do=payfromcard` | `payfromcard()` | AJAX payment processing |

### Required Parameters by Action

**Package Creation** (`do=add`):
- `name` - Package name
- `packageVal` - Card value/credits  
- `packagePrice` - Sale price
- `packageDays` - Validity period in days
- `file` - Package image upload

**Card Purchase** (`do=dochargeCard`):
- `cardid` - Package ID to purchase
- `client` - Client ID making purchase

**Card Payment** (`do=payfromcard`):
- `cardPayed` - Amount to pay from card
- `client` - Client making payment
- `restaurantPlaystationPlayId` - Gaming session ID

**Card Management** (`do=showClientsCards`):
- `PSCardNoClient` - Specific card ID (optional)
- `client` - Client filter (optional)
- `cardStatus` - Status filter (optional)
- `buyfrom`, `buyto` - Purchase date range (optional)
- `endfrom`, `endto` - Expiration date range (optional)

---

## 🧮 Calculation Methods

### Card Expiration Date
```php
$startDate = strtotime($playstationClientCard->buyDate);
$endDate = strtotime('+' . $playstationClientCard->packDays . ' day', $startDate);
$playstationClientCard->cardEndDate = date('Y-m-d H:i:s', $endDate);
```

### Card Balance Tracking
```php
// Available balance calculation
$availableBalance = $playstationClientCard->packVal - $playstationClientCard->packValConsumed;

// Card status determination
if ($playstationClientCard->packValConsumed >= $playstationClientCard->packVal) {
    $playstationClientCard->cardStatus = 1; // Fully consumed
}
```

### Client Debt Impact
```php
// Purchase impact (debt reduction)
$debtAfter = $clientdata->clientdebt - $playstationCard->packageVal;

// Payment impact (debt increase)
$debtAfter = $clientdata->clientdebt + $cardPayed;

// Refund impact (debt restoration)  
$debtAfter = $clientdata->clientdebt + $playstationClientCard->packVal;
```

### Cash Register Management
```php
// Purchase income
$saveData = getSaveValueAndPlus($_SESSION['saveid'], $playstationCard->packagePrice);

// Refund outflow
$saveData = getSaveValueAndMins($_SESSION['saveid'], $playstationClientCard->packPrice);
```

---

## 🔒 Security & Permissions

### Authentication Requirements
```php
include_once("../public/authentication.php");
// Required for all operations except AJAX endpoints
```

### Input Validation
```php
$cardid = (int) filter_input(INPUT_POST, 'cardid');           // Integer casting
$packageVal = (float) filter_input(INPUT_POST, 'packageVal'); // Float validation
$client = (int) filter_input(INPUT_POST, 'client');           // Client ID validation
```

### Client Concurrency Protection
```php
// Prevent concurrent client modifications
$client_data = $clientEX->callClientInUseSP($clientid);
while ($client_data->clientdebt == 'in_use') {
    sleep(1);
    if ($noOfTries > 15) {
        // Force release after 15 seconds
        R::exec('UPDATE client SET inUse = 0 where clientid = ' . $clientid);
    }
}
```

### Transaction Integrity
```php
$mytransactions = new Transaction();
try {
    // Multiple financial operations
    $mytransactions->commit();
} catch (Exception $e) {
    $mytransactions->rollback();
    markClientAsNOTInUse($client);
}
```

---

## 📊 Performance Considerations

### Database Optimization
1. **Required Indexes**:
   - `playstationcard(del, sysdate)` - Active packages
   - `playstationclientcard(clientid, cardStatus, cardEndDate)` - Client cards
   - `playstationclientcard(cardEndDate)` - Expiration processing
   - `playstationclientcardpayhistory(clientid, sysDate)` - Payment history

2. **Query Optimization**:
   - Efficient card selection with ordering by expiration
   - Batch expiration processing
   - Client card filtering with compound conditions

3. **AJAX Performance**:
   - Real-time payment processing
   - Minimal database queries for card balance checks
   - Client locking for concurrency control

### Cache Considerations
```php
// Client balance caching during payment
$clientdata = getClientDataFromClientInUseSP($client);
// Implements retry logic with timeout for locked clients
```

---

## 🐛 Common Issues & Troubleshooting

### 1. **Card Expiration Not Processing**
**Issue**: Expired cards remain active  
**Cause**: Automatic expiration job not running

**Debug**:
```sql
-- Find expired cards still active
SELECT * FROM playstationclientcard 
WHERE cardEndDate < NOW() AND cardStatus = 0;
```

**Fix**:
```php
// Manual expiration processing
handleExpiredCards(0); // Process all clients
```

### 2. **Client Balance Mismatches**
**Issue**: Client debt doesn't match card transactions  
**Cause**: Failed transaction or concurrent modifications

**Debug**:
```sql
-- Compare client debt with card transactions
SELECT c.clientid, c.clientdebt,
       SUM(pcph.payAmount * CASE pcph.changeType WHEN 0 THEN -1 ELSE 1 END) as card_impact
FROM client c
LEFT JOIN playstationclientcardpayhistory pcph ON c.clientid = pcph.clientid
GROUP BY c.clientid
HAVING ABS(c.clientdebt - COALESCE(card_impact, 0)) > 0.01;
```

### 3. **Card Balance Calculation Errors**
**Issue**: Available balance shows negative or incorrect values  
**Cause**: Consumption tracking errors

**Debug**:
```sql
-- Verify card balance calculations
SELECT id, packVal, packValConsumed, 
       (packVal - packValConsumed) as calculated_balance,
       CASE WHEN packValConsumed >= packVal THEN 1 ELSE 0 END as should_be_consumed
FROM playstationclientcard 
WHERE del = 0 AND cardStatus = 0;
```

### 4. **Payment Processing Failures**
**Issue**: AJAX payment requests fail or timeout  
**Cause**: Client locking or insufficient card balance

**Debug**:
```php
// Enable payment debugging
error_log("Payment request: Client={$client}, Amount={$cardPayed}");
error_log("Available cards: " . json_encode($allPlaystationClientCard));
```

---

## 🧪 Testing Scenarios

### Test Case 1: Complete Card Purchase Flow
```
1. Create gaming package (do=add)
2. Access card purchase form (do=chargeCard)
3. Select client and package
4. Process purchase (do=dochargeCard)
5. Verify card created with correct expiration
6. Check client debt reduced by package value
7. Confirm cash register increased by package price
8. Validate all transaction history recorded
```

### Test Case 2: Card Payment Processing
```
1. Purchase card for client
2. Access payment form (do=payCard)
3. Submit AJAX payment request (do=payfromcard)
4. Verify card balance reduced correctly
5. Check client debt increased by payment amount
6. Confirm payment history recorded
7. Test multi-card payment scenarios
```

### Test Case 3: Card Expiration Handling
```
1. Create card with short expiration (for testing)
2. Wait for or manually trigger expiration
3. Run handleExpiredCards()
4. Verify card status changed to expired (2)
5. Check remaining balance credited to client
6. Confirm expiration transaction recorded
```

### Test Case 4: Card Cancellation and Refund
```
1. Purchase card for client
2. Attempt cancellation before any usage
3. Verify refund processed correctly
4. Check client debt restored
5. Confirm cash register balance reduced
6. Test prevention of partial-use card cancellation
```

---

## 📚 Related Documentation

- [CLAUDE.md](/Applications/AMPPS/www/erp19/CLAUDE.md) - PHP 8.2 migration guide
- [clientController.md](clientController.md) - Customer management system
- [saveController.md](saveController.md) - Cash register management
- [clientPayedDeptController.md](clientPayedDeptController.md) - Client payment processing
- [restaurantplaystationpaly.php](#) - Gaming session management

---

**Documented By**: AI Assistant  
**Review Status**: ✅ Complete  
**Next Review**: When gaming business rules change