# Charity Center Controller Documentation

**File**: `/controllers/charityCenterController.php`  
**Purpose**: Manages charity centers with CRUD operations and comprehensive reporting  
**Last Updated**: December 20, 2024  
**Total Functions**: 4  
**Lines of Code**: ~187

---

## 📋 Overview

The Charity Center Controller is a management module for charity organizations that handles the administration of charity centers with associated charities and beneficiaries. It provides:
- Charity center creation and management
- CRUD operations with soft delete functionality
- DataTables integration for dynamic listing
- Comprehensive reporting with statistics
- Hierarchical relationship tracking (centers → charities → beneficiaries)
- AJAX-based operations for responsive user interface

### Primary Functions
- [x] Create and edit charity centers
- [x] Display charity center listings with DataTables
- [x] Soft delete/restore functionality
- [x] AJAX-powered search and filtering
- [x] Generate statistical reports
- [x] Track relationships between centers, charities, and beneficiaries
- [x] Count beneficiaries across different categories

### Charity System Hierarchy
```
Charity Centers
    ↓
Charities (linked to centers via center_id)
    ↓  
Beneficiaries (linked to charities via charity_id)
    ↓
Special Category: "Takafol" beneficiaries (charity_id = 0)
```

### Related Controllers
- [charitiesController.php](#) - Individual charity management
- [beneficiariesController.php](#) - Beneficiary management
- [userController.php](#) - User management system

---

## 🗄️ Database Tables

### Primary Table (Direct Operations)
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **charitiescenter** | Charity center master data | id, name, del, sysdate, user_id, del_date, deluserid, update_date, updateuserid |

### Related Tables (Read-Only References)
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **charities** | Individual charities | id, center_id, name, del |
| **beneficiaries** | Charity beneficiaries | id, charity_id, idnumber, del |
| **user** | System users | userid, username |

### Soft Delete States
| Del Value | Status | Description |
|-----------|--------|-------------|
| 0 | Active | Normal active record |
| 1 | Updated | Record has been updated |
| 2 | Deleted | Soft deleted record |
| 5 | Special | Special status (appears in edit scenarios) |

---

## 🔑 Key Functions

### 1. **Default Action** - Add Center Form
**Location**: Lines 8-12  
**Purpose**: Display form to create new charity center

**Process Flow**:
1. Display header template
2. Show add form template
3. Set charity-specific CSS flag
4. Display footer template

**Template Variables**:
- `$charity = 1` - Enables charity-specific styling and JavaScript

---

### 2. **show** - Display Centers List
**Location**: Lines 13-24  
**Purpose**: Display charity centers list with optional filtering

**Function Signature**:
```php
// Triggered when: do=show
elseif ($do == "show") {
```

**Process Flow**:
1. **Authentication Check**: Include authentication validation
2. **View Mode Detection**: Check for special view mode (`show=2`)
3. **Template Preparation**: Assign current date and view flags
4. **Display**: Render show template with DataTables integration

**URL Parameters**:
- `show` - View mode (2 for special view)

**Template Variables**:
- `$show` - View mode indicator
- `$date` - Current date for filtering
- `$charity = 1` - CSS/JavaScript flag

---

### 3. **edit** - Edit Center Form
**Location**: Lines 25-34  
**Purpose**: Load and display charity center for editing

**Function Signature**:
```php
// Triggered when: do=edit
elseif ($do == "edit") {
```

**Process Flow**:
1. **Authentication Check**: Validate user permissions
2. **Data Loading**: Load charity center by ID using RedBeanPHP
3. **Template Assignment**: Pass center data to template
4. **Display**: Render edit form with populated data

**URL Parameters**:
- `id` - Charity center ID to edit

**Data Loading**:
```php
$id = filter_input(INPUT_GET, 'id');
$centerdata = R::load('charitiescenter', $id);
$smarty->assign('centerdata', $centerdata);
```

---

### 4. **savedata** - Save Center Data
**Location**: Lines 72-102  
**Purpose**: Create new charity center or update existing one

**Function Signature**:
```php
function savedata()
```

**Process Flow**:

#### **Input Processing**:
```php
$name = filter_input(INPUT_POST, 'name');
$charityid = filter_input(INPUT_POST, 'charityid');
```

#### **Create vs Update Logic**:
```php
if (!$charityid) {
    // Create new center
    $charitiescenter = R::dispense('charitiescenter');
    $charitiescenter->del = 0;
    $charitiescenter->sysdate = $today;
    $charitiescenter->user_id = $userid;
    $charitiescenter->del_date = '';
    $charitiescenter->deluserid = '';
} else {
    // Update existing center
    $charitiescenter = R::load('charitiescenter', $charityid);
    $charitiescenter->del = 1;
    $charitiescenter->update_date = $today;
    $charitiescenter->updateuserid = $userid;
}
```

#### **Data Assignment and Save**:
```php
$charitiescenter->name = $name;

try {
    $charityid = R::store($charitiescenter);
    echo 1; // Success
} catch (Exception $e) {
    echo 0; // Failure
}
```

**Input Parameters**:
- `name` - Charity center name
- `charityid` - ID for updates (empty for new records)

**Response**:
- `1` - Success
- `0` - Error/Exception

---

### 5. **showajax** - DataTables AJAX Endpoint
**Location**: Lines 103-167  
**Purpose**: Provide JSON data for DataTables with search, pagination, and sorting

**Function Signature**:
```php
function showajax()
```

**Process Flow**:

#### **Column Definition**:
```php
$columns = array('id', 'id', 'name', 'id', 'id');
// Columns: [0=ID, 1=ID, 2=Name, 3=Edit, 4=Delete]
```

#### **Search Query Building**:
```php
$searchQuery = " ";

// Filter by specific ID
if ($data1 != '') {
    $searchQuery .= " and charitiescenter.id = " . $data1 . " ";
}

// Filter by delete status
if ($del == '') {
    $searchQuery .= " and charitiescenter.del < 2 "; // Show active records
}

// Global search across columns
if (isset($_POST['search']['value']) && $_POST['search']['value'] != "") {
    $searchQuery .= 'and ( charitiescenter.id LIKE " % ' . $_POST["search"]["value"] . ' %" 
                    OR charitiescenter.sysdate LIKE "%' . $_POST["search"]["value"] . ' % "
                    OR charitiescenter.name LIKE "%' . $_POST["search"]["value"] . '%"
                    )';
}
```

#### **Sorting and Pagination**:
```php
// Sorting
if (isset($_POST["order"])) {
    $searchQuery .= 'ORDER BY ' . $columns[$_POST['order']['0']['column']] . ' ' . $_POST['order']['0']['dir'] . '  ';
} else {
    $searchQuery .= "ORDER BY charitiescenter.id DESC ";
}

// Pagination
if (isset($_POST['start']) && $_POST['length'] != '-1') {
    $searchQuery .= "LIMIT " . intval($_POST['start']) . ", " . intval($_POST['length']);
}
```

#### **Action Buttons Generation**:
```php
foreach ($rResult as $row) {
    if ($row["del"] < 2) {
        // Active record: Show edit and delete buttons
        $sub_array[] = '<a href="charityCenterController.php?do=edit&id=' . $row["id"] . '" type="button" class="btn btn-default btn-lg editicon"></a>';
        $sub_array[] = '<a href="javascript:;" data-id="' . $row["id"] . '" data-controll="charityCenterController" type="button" class="btn btn-default btn-lg deleteicon removecontroller"  ></a>';
    } else if ($row["del"] == 5) {
        // Special status: Show only edit button
        $sub_array[] = '<a href="charityCenterController.php?do=edit&id=' . $row["id"] . '" type="button" class="btn btn-default btn-lg editicon"></a>';
    } else {
        // Deleted record: Show details button and "deleted" status
        $sub_array[] = '<a href="charityCenterController.php?do=edit&id=' . $row["id"] . '" type="button" class="btn btn-default btn-lm ">تفاصيل</a>';
        $sub_array[] = 'محذوف ';
    }
}
```

**AJAX Parameters**:
- `del` - Delete status filter
- `data1` - Specific ID filter
- `search[value]` - Global search term
- `order` - Sorting configuration
- `start` - Pagination start
- `length` - Page size

**Response Format**:
```json
{
    "draw": 1,
    "recordsTotal": 50,
    "recordsFiltered": 25,
    "data": [
        ["1", "Center Name", "<edit button>", "<delete button>"],
        // ... more rows
    ]
}
```

---

### 6. **removecontroller** - Soft Delete Center
**Location**: Lines 170-186  
**Purpose**: Soft delete charity center by setting delete flag

**Function Signature**:
```php
function removecontroller()
```

**Process Flow**:
1. **Input Processing**: Get center ID from POST
2. **Data Loading**: Load charity center record
3. **Soft Delete**: Set del=2, del_date, and deluserid
4. **Save**: Store updated record

**Implementation**:
```php
$id = filter_input(INPUT_POST, 'id');
$tables = R::load('charitiescenter', $id);
$tables->del = 2;              // Mark as deleted
$tables->del_date = $today;    // Record deletion timestamp
$tables->deluserid = $userid;  // Record who deleted it

try {
    R::store($tables);
    echo 1; // Success
} catch (Exception $e) {
    echo 0; // Failure
}
```

**Response**:
- `1` - Successfully deleted
- `0` - Error occurred

---

### 7. **report** - Statistical Reporting
**Location**: Lines 41-68  
**Purpose**: Generate comprehensive statistics report for charity centers

**Function Signature**:
```php
// Triggered when: do=report
elseif ($do == "report") {
```

**Process Flow**:

#### **Main Statistics Query**:
```sql
SELECT cs.id, cs.name, 
    (SELECT COUNT(charities.id) FROM charities 
     WHERE charities.del < 2 AND charities.id != 0 AND charities.center_id = cs.id) AS chCount, 
    (SELECT COUNT(beneficiaries.id) FROM beneficiaries 
     JOIN charities ON beneficiaries.charity_id = charities.id
     WHERE beneficiaries.del < 2 AND charities.del < 2 AND cs.del < 2 
     AND charities.id != 0 AND charities.center_id = cs.id) AS benCount
FROM charitiescenter cs
WHERE cs.del < 2
```

#### **Takafol Beneficiaries Calculation**:
```php
foreach ($allCenters as $center) {
    $tkafolCounter = R::getCell('SELECT COUNT(b.id) FROM beneficiaries b 
                               WHERE b.charity_id = 0 
                               AND b.idnumber IN (
                                   SELECT beneficiaries.idnumber FROM beneficiaries 
                                   JOIN charities ON beneficiaries.charity_id = charities.id
                                   WHERE beneficiaries.del < 2 AND charities.del < 2 
                                   AND beneficiaries.charity_id != 0 AND charities.center_id = ' . $center["id"] . '
                               )');
    $dataArr[$center['id']]['tkafolCount'] = $tkafolCounter;
}
```

#### **Global Takafol Count**:
```php
$tkafolCount = R::getCell('SELECT COUNT(id) FROM beneficiaries WHERE charity_id = 0');
```

**Report Metrics**:
- **chCount** - Number of active charities per center
- **benCount** - Number of beneficiaries linked to charities in each center
- **tkafolCount** - Number of "takafol" beneficiaries (special category with charity_id=0)
- **Global takafol** - Total takafol beneficiaries across all centers

**Template Variables**:
- `$allData` - Main statistics for each center
- `$dataArr` - Takafol counts by center
- `$tkafolCount` - Global takafol count

---

## 🔄 Workflows

### Workflow 1: Charity Center Creation
```
┌─────────────────────────────────────────────────────────────┐
│                START: User Creates New Center               │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Display Add Form                                        │
│     - Load add.html template                                │
│     - Set charity flag for CSS/JS                          │
│     - Show empty form for input                             │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Form Submission (savedata)                              │
│     - Validate input data                                   │
│     - Create new charitiescenter record                     │
│     - Set del = 0 (active)                                 │
│     - Record creation timestamp and user                    │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Save to Database                                        │
│     - Store record using RedBeanPHP                        │
│     - Return success (1) or failure (0)                    │
│     - Record becomes available in listings                 │
└─────────────────────────────────────────────────────────────┘
```

---

### Workflow 2: Center Listing with DataTables
```
┌─────────────────────────────────────────────────────────────┐
│                START: User Views Center List                │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Load Show Page                                          │
│     - Display show.html template                           │
│     - Initialize DataTables configuration                   │
│     - Set current date for filtering                       │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. AJAX Data Request (showajax)                            │
│     - Receive DataTables parameters                        │
│     - Apply search and filter criteria                     │
│     - Apply sorting and pagination                         │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Generate Response                                       │
│     - Query database with built criteria                   │
│     - Format data for DataTables                           │
│     - Generate action buttons based on record status       │
│     - Return JSON response                                  │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Display Results                                         │
│     - DataTables renders the table                         │
│     - Show edit/delete buttons for active records          │
│     - Show "details" for deleted records                   │
└─────────────────────────────────────────────────────────────┘
```

---

### Workflow 3: Statistical Report Generation
```
┌─────────────────────────────────────────────────────────────┐
│              START: Generate Statistics Report              │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Load Center Statistics                                  │
│     - Count charities per center                           │
│     - Count beneficiaries per center                       │
│     - Query all active centers                             │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Calculate Takafol Beneficiaries                         │
│     FOR EACH center:                                        │
│       │                                                     │
│       ├─→ Find beneficiaries linked to center's charities  │
│       ├─→ Count those also registered as takafol (ID=0)    │
│       └─→ Store takafol count for center                   │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Global Calculations                                     │
│     - Count total takafol beneficiaries                    │
│     - Prepare summary statistics                            │
│     - Format data for report display                       │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Display Report                                          │
│     - Show center-by-center breakdown                      │
│     - Display charity and beneficiary counts               │
│     - Show takafol statistics                              │
│     - Present totals and summaries                         │
└─────────────────────────────────────────────────────────────┘
```

---

## 🌐 URL Routes & Actions

| URL Parameter | Function Called | Description |
|---------------|----------------|-------------|
| (no parameters) | Default action | Display add center form |
| `do=show` | Show listing | Display centers with DataTables |
| `do=edit` | Edit form | Load center for editing |
| `do=savedata` | `savedata()` | Create/update center |
| `do=showajax` | `showajax()` | AJAX endpoint for DataTables |
| `do=removecontroller` | `removecontroller()` | Soft delete center |
| `do=report` | Report view | Generate statistical report |

### Required Parameters by Action

**Show Centers** (`do=show`):
- `show` - View mode (optional, 2 for special view)

**Edit Center** (`do=edit`):
- `id` - Charity center ID

**Save Data** (`do=savedata`):
- `name` - Center name
- `charityid` - ID for updates (empty for new)

**AJAX Data** (`do=showajax`):
- DataTables parameters (draw, start, length, search, order)
- `del` - Delete status filter (optional)
- `data1` - Specific ID filter (optional)

**Delete Center** (`do=removecontroller`):
- `id` - Center ID to delete

---

## 🧮 Statistical Calculations

### Charity Count per Center
```sql
SELECT COUNT(charities.id) FROM charities 
WHERE charities.del < 2 
AND charities.id != 0 
AND charities.center_id = [CENTER_ID]
```

### Beneficiary Count per Center
```sql
SELECT COUNT(beneficiaries.id) FROM beneficiaries 
JOIN charities ON beneficiaries.charity_id = charities.id
WHERE beneficiaries.del < 2 
AND charities.del < 2 
AND charities.id != 0 
AND charities.center_id = [CENTER_ID]
```

### Takafol Beneficiaries per Center
```sql
SELECT COUNT(b.id) FROM beneficiaries b 
WHERE b.charity_id = 0 
AND b.idnumber IN (
    SELECT beneficiaries.idnumber FROM beneficiaries 
    JOIN charities ON beneficiaries.charity_id = charities.id
    WHERE beneficiaries.del < 2 
    AND charities.del < 2 
    AND beneficiaries.charity_id != 0 
    AND charities.center_id = [CENTER_ID]
)
```

**Explanation**: Takafol beneficiaries are those with `charity_id = 0` but whose ID numbers also appear in the regular beneficiary system linked to actual charities.

---

## 🔒 Security & Permissions

### Access Control
```php
// Authentication required for most operations
include_once("../public/authentication.php");

// Session-based user tracking
$userid = $_SESSION['userid'];
```

### Input Validation
```php
// All input filtered through filter_input
$name = filter_input(INPUT_POST, 'name');
$id = filter_input(INPUT_GET, 'id');
$charityid = filter_input(INPUT_POST, 'charityid');
```

### Soft Delete Implementation
```php
// Records never physically deleted, only marked
$tables->del = 2;              // Mark as deleted
$tables->del_date = $today;    // Timestamp deletion
$tables->deluserid = $userid;  // Track who deleted
```

### AJAX Security
- POST requests for data modification
- Input validation on all AJAX endpoints
- No direct SQL in AJAX functions

---

## 📊 Performance Considerations

### Database Optimization Tips
1. **Indexes Needed**:
   - `charitiescenter(del)` - For active record filtering
   - `charities(center_id, del)` - For center-charity relationships
   - `beneficiaries(charity_id, del)` - For charity-beneficiary relationships

2. **Query Optimization**:
   - Report queries use subqueries which could be optimized with JOINs
   - Takafol calculation is complex and could benefit from caching
   - DataTables pagination helps with large datasets

3. **Potential Issues**:
   - N+1 query problem in report generation (one query per center for takafol count)
   - Complex subqueries in main statistics might be slow with large datasets

### Performance Improvements
```sql
-- Current approach (N+1 queries)
SELECT id, name FROM charitiescenter;
-- Then for each center:
SELECT COUNT(*) FROM beneficiaries WHERE charity_id = 0 AND idnumber IN (...);

-- Better approach (single query with JOINs)
SELECT cs.id, cs.name,
       COUNT(DISTINCT c.id) as charity_count,
       COUNT(DISTINCT b.id) as beneficiary_count,
       COUNT(DISTINCT bt.id) as takafol_count
FROM charitiescenter cs
LEFT JOIN charities c ON c.center_id = cs.id AND c.del < 2
LEFT JOIN beneficiaries b ON b.charity_id = c.id AND b.del < 2
LEFT JOIN beneficiaries bt ON bt.charity_id = 0 AND bt.idnumber = b.idnumber
WHERE cs.del < 2
GROUP BY cs.id;
```

---

## 🐛 Common Issues & Troubleshooting

### 1. **DataTables Not Loading**
**Issue**: Table shows "Loading..." indefinitely  
**Cause**: AJAX endpoint returning malformed JSON

**Debug**:
```javascript
// Check browser console for AJAX errors
// Verify JSON response format
// Check PHP error logs
```

### 2. **Incorrect Statistics**
**Issue**: Report shows wrong counts  
**Cause**: Complex JOIN queries or deleted records included

**Debug**:
```sql
-- Check data integrity
SELECT del, COUNT(*) FROM charitiescenter GROUP BY del;
SELECT del, COUNT(*) FROM charities GROUP BY del;
SELECT charity_id, COUNT(*) FROM beneficiaries GROUP BY charity_id;
```

### 3. **Soft Delete Issues**
**Issue**: Deleted records still appearing  
**Cause**: del field not properly filtered

**Fix**:
```sql
-- Always include del filter in queries
WHERE del < 2  -- Show active only
WHERE del = 2  -- Show deleted only
WHERE del IN (0,1,5)  -- Show specific statuses
```

---

## 🧪 Testing Scenarios

### Test Case 1: Basic CRUD Operations
```
1. Create new charity center with unique name
2. Verify it appears in listing
3. Edit center name
4. Verify update appears
5. Soft delete center
6. Verify it's marked as deleted but still in database
```

### Test Case 2: DataTables Functionality
```
1. Create multiple charity centers
2. Test search functionality
3. Test sorting by different columns
4. Test pagination with different page sizes
5. Verify action buttons work correctly
```

### Test Case 3: Statistical Report Accuracy
```
1. Create test data:
   - Multiple centers
   - Charities linked to centers
   - Beneficiaries linked to charities
   - Some takafol beneficiaries
2. Generate report
3. Verify counts match manual calculations
```

---

## 📚 Related Documentation

- [CLAUDE.md](/Applications/AMPPS/www/erp19/CLAUDE.md) - PHP 8.2 migration guide
- [DataTables Integration](#) - AJAX table functionality
- [RedBeanPHP ORM](#) - Database operations
- [Charity Management System](#) - Overall system architecture

---

**Documented By**: AI Assistant  
**Review Status**: ✅ Complete  
**Next Review**: When major changes occur