CharityCenter Documentation

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:

Primary Functions

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

---

๐Ÿ—„๏ธ Database Tables

Primary Table (Direct Operations)

Table NamePurposeKey Columns
**charitiescenter**Charity center master dataid, name, del, sysdate, user_id, del_date, deluserid, update_date, updateuserid
### Related Tables (Read-Only References)

Table NamePurposeKey Columns
**charities**Individual charitiesid, center_id, name, del
**beneficiaries**Charity beneficiariesid, charity_id, idnumber, del
**user**System usersuserid, username
### Soft Delete States

Del ValueStatusDescription
0ActiveNormal active record
1UpdatedRecord has been updated
2DeletedSoft deleted record
5SpecialSpecial 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:

---

2. show - Display Centers List

Location: Lines 13-24

Purpose: Display charity centers list with optional filtering

Function Signature:

// 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:

Template Variables:

---

3. edit - Edit Center Form

Location: Lines 25-34

Purpose: Load and display charity center for editing

Function Signature:

// 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:

Data Loading:

$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:

function savedata()

Process Flow:

Input Processing:

$name = filter_input(INPUT_POST, 'name');
$charityid = filter_input(INPUT_POST, 'charityid');

Create vs Update Logic:

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:

$charitiescenter->name = $name;

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

Input Parameters:

Response:

---

5. showajax - DataTables AJAX Endpoint

Location: Lines 103-167

Purpose: Provide JSON data for DataTables with search, pagination, and sorting

Function Signature:

function showajax()

Process Flow:

Column Definition:

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

Search Query Building:

$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:

// 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:

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:

Response Format:

{
    "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:

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:

$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:

---

7. report - Statistical Reporting

Location: Lines 41-68

Purpose: Generate comprehensive statistics report for charity centers

Function Signature:

// Triggered when: do=report
elseif ($do == "report") {

Process Flow:

Main Statistics Query:

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:

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:

$tkafolCount = R::getCell('SELECT COUNT(id) FROM beneficiaries WHERE charity_id = 0');

Report Metrics:

Template Variables:

---

๐Ÿ”„ Workflows

Workflow 1: Charity Center Creation

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
START: User Creates New Center
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
1Display Add Form
- Load add.html template
- Set charity flag for CSS/JS
- Show empty form for input
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
2Form Submission (savedata)
- Validate input data
- Create new charitiescenter record
- Set del = 0 (active)
- Record creation timestamp and user
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
3Save 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
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
1Load Show Page
- Display show.html template
- Initialize DataTables configuration
- Set current date for filtering
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
2AJAX Data Request (showajax)
- Receive DataTables parameters
- Apply search and filter criteria
- Apply sorting and pagination
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
3Generate Response
- Query database with built criteria
- Format data for DataTables
- Generate action buttons based on record status
- Return JSON response
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
4Display 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
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
1Load Center Statistics
- Count charities per center
- Count beneficiaries per center
- Query all active centers
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
2Calculate 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 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
3Global Calculations
- Count total takafol beneficiaries
- Prepare summary statistics
- Format data for report display
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
4Display Report
- Show center-by-center breakdown
- Display charity and beneficiary counts
- Show takafol statistics
- Present totals and summaries
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

---

๐ŸŒ URL Routes & Actions

URL ParameterFunction CalledDescription
(no parameters)Default actionDisplay add center form
`do=show`Show listingDisplay centers with DataTables
`do=edit`Edit formLoad 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 viewGenerate statistical report
### Required Parameters by Action

Show Centers (do=show):

Edit Center (do=edit):

Save Data (do=savedata):

AJAX Data (do=showajax):

Delete Center (do=removecontroller):

---

๐Ÿงฎ Statistical Calculations

Charity Count per Center

SELECT COUNT(charities.id) FROM charities 
WHERE charities.del < 2 
AND charities.id != 0 
AND charities.center_id = [CENTER_ID]

Beneficiary Count per Center

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

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

// Authentication required for most operations
include_once("../public/authentication.php");

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

Input Validation

// 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

// 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

---

๐Ÿ“Š 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

-- 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:

// 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:

-- 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:

-- 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

---

Documented By: AI Assistant

Review Status: โœ… Complete

Next Review: When major changes occur