# Student Absence Controller Documentation

**File**: `/controllers/studentAbsence.php`  
**Purpose**: Manages student attendance tracking, device integration, and absence notification system  
**Last Updated**: December 21, 2024  
**Total Functions**: 7  
**Lines of Code**: ~358

---

## 📋 Overview

The Student Absence Controller handles comprehensive attendance management for the student system. It provides functionality for:
- Device-based attendance recording (file import)
- Manual attendance marking
- Automated absence notifications
- Schedule-based attendance tracking
- Real-time attendance monitoring
- Device IP address integration
- Attendance report generation
- Student search and selection for manual entry
- Bulk attendance operations

### Primary Functions
- [x] Import attendance data from external devices
- [x] Manual attendance entry and correction
- [x] Automated absence notification to groups
- [x] Schedule-based attendance validation
- [x] Real-time attendance status tracking
- [x] Device integration and monitoring
- [x] Attendance data table with filtering
- [x] Student availability checking

### Related Controllers
- [studentSettings.php](studentSettings.md) - System configuration
- [studentSubjectsController.php](studentSubjectsController.md) - Subject scheduling
- [studentsAddSubject.php](studentsAddSubject.md) - Student assignments
- [studentsExamsController.php](studentsExamsController.md) - Exam attendance

---

## 🗄️ Database Tables

### Primary Tables (Direct Operations)
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **studentabsences** | Attendance records | id, uniqid, studentid, todaysend, timesend, type, deviceid, status, studentsubjectid, studentsubjectgroupid, studentaddsubjectid, studentaddsubjectdetailid, ipaddrees, arrivedtime, onlys, del |

### Referenced Tables
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **studentaddsubjects** | Student assignments | id, studentsubjectid, studentsubjectgroupid, del |
| **studentaddsubjectdetails** | Assignment details | id, studentid, studentsubjectid, studentsubjectgroupid, studentaddsubjectid, del |
| **studentsubjects** | Subject information | id, subjectname, deviceid, ipaddress, del |
| **studentsubjectgroups** | Subject groups | id, subjectgroupname, del |
| **studentsubjectgroupdays** | Class schedules | id, studentsubjectgroupid, day, dayen, timeform, timeto, del |
| **students** | Student master data | id, studentname, studentphone, del |
| **user** | System users | userid, employeename |

---

## 🔑 Key Functions

### 1. **Default Action** - Attendance Interface
**Location**: Lines 11-16  
**Purpose**: Display the main attendance tracking interface

**Process Flow**:
1. Get current day of week
2. Display header and attendance form
3. Set student navigation flag
4. Display footer template

---

### 2. **show** - Daily Schedule View
**Location**: Lines 17-34  
**Purpose**: Display today's scheduled classes and attendance status

**Process Flow**:
1. Load system settings
2. Get current date and time
3. Query scheduled classes for current day
4. Display schedule interface with current classes

**Schedule Query**:
```php
$studentaddsubjects = R::getAll("SELECT *,studentaddsubjects.id as studentaddsubjectid 
    FROM studentaddsubjects 
    left JOIN studentsubjectgroupdays ON studentaddsubjects.studentsubjectid = studentsubjectgroupdays.studentsubjectid 
    left JOIN studentsubjectgroups ON studentsubjectgroupdays.studentsubjectgroupid = studentsubjectgroups.id 
    left JOIN studentsubjects ON studentsubjectgroupdays.studentsubjectid = studentsubjects.id 
    WHERE studentaddsubjects.del < 2 and studentsubjectgroupdays.del < 2 and dayen = '$day' 
    group by studentsubjectgroupdays.studentsubjectgroupid");
```

---

### 3. **edit** - Device Data Import
**Location**: Lines 35-79  
**Purpose**: Import attendance data from external device files

**Process Flow**:
1. Read device data file by date
2. Parse attendance records from file
3. Validate and process each record
4. Create attendance records in database
5. Link to student assignments
6. Display processed attendance data

**File Processing Logic**:
```php
$handle = file_get_contents($deviceid.'/'.date('Y-m-d').".txt");
if ($handle) {
    $lists = explode("\n", $handle);
    foreach ($lists as $data) {
        $data = explode('?', $data);
        $studentabsencesadd = R::count('studentabsences',
            "uniqid = ? and deviceid = ? and todaysend = '$date' ", [$data[0], $data[5]]);
        
        if ($studentabsencesadd == 0 && $data[0]) {
            // Create new attendance record
        }
    }
}
```

**Record Creation**:
```php
$studentabsences = R::dispense('studentabsences');
$studentabsences->uniqid = $data[0];
$studentabsences->studentid = $data[1];
$studentabsences->todaysend = $data[2];
$studentabsences->timesend = $data[3];
$studentabsences->type = $data[4];
$studentabsences->deviceid = $data[5];
$studentabsences->status = $data[6];
```

---

### 4. **sendmassage** - Automated Absence Notification
**Location**: Lines 80-112  
**Purpose**: Generate absence records for students not present in scheduled classes

**Function Signature**:
```php
// Triggered when: do=sendmassage
$studentsubjectgroupid = filter_input(INPUT_POST, 'studentsubjectgroupid');
```

**Process Flow**:
1. Get subject group and current time
2. Find all assigned students in group
3. Check for existing attendance records
4. Create absence records for missing students
5. Mark as automated (onlys = 1)

**Absence Logic**:
```php
foreach($studentaddsubjectdetails as $studentaddsubjectdetail) {
    $studentsubjects = R::load('studentsubjects', $studentaddsubjectdetail->studentsubjectid);
    $studentabsencesc = R::count('studentabsences', 
        " studentid = ? and deviceid = ? and todaysend = '$date' and del < 2",
        [$studentaddsubjectdetail->studentid, $studentsubjects->deviceid]);        
    
    if ($studentabsencesc == 0) {
        // Create absence record
        $studentabsences = R::dispense('studentabsences');
        $studentabsences->onlys = 1; // Automated
        $studentabsences->arrivedtime = '0';
        // Set all required fields
    }
}
```

---

### 5. **savedata()** - Manual Attendance Entry
**Location**: Lines 128-167  
**Purpose**: Manually record student attendance

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

**Process Flow**:
1. Extract attendance parameters
2. Parse selected student IDs
3. Validate against existing records
4. Create attendance records for selected students
5. Link to assignments and subjects

**Manual Entry Logic**:
```php
for ($i = 0; $i < count($Explode); $i++) { 
    $studentabsencesc = R::count('studentabsences', 
        " studentid = ? and deviceid = ? and todaysend = '$date' and del < 2",
        [$Explode[$i], $studentsubjects->deviceid]);
    
    if ($studentabsencesc == 0) {
        $studentabsences = R::dispense('studentabsences');
        $studentabsences->onlys = 0; // Manual entry
        $studentabsences->arrivedtime = '0';
        // Process student attendance
    }
}
```

---

### 6. **showajax()** - Attendance Data Table
**Location**: Lines 204-305  
**Purpose**: Provide attendance data for DataTables interface

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

**Process Flow**:
1. Define column mappings for sorting
2. Build search query with multiple filters
3. Apply date range and assignment filters
4. Execute complex JOIN query
5. Format results with device and student info
6. Return JSON response for DataTables

**Search Query Building**:
```php
if($data1 != '') {
    $searchQuery .= " and studentabsences.studentaddsubjectid = ".$data1. " ";
}
if($data2 != '') {
    $searchQuery .= " and studentabsences.studentaddsubjectdetailid = ".$data2. " "; 
}
if($data3 != '') {
    $searchQuery .= " and studentabsences.onlys = ".$data3. " "; 
}
```

**Grouping Logic**:
```php
if($data1 == '') {
    $searchQuery .= " group by studentsubjects.deviceid ";
}
```

---

### 7. **getstudentabsence()** - Available Student Search
**Location**: Lines 325-355  
**Purpose**: Find students available for manual attendance entry

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

**Process Flow**:
1. Get assignment and search parameters
2. Find students in assignment
3. Filter out students with existing attendance
4. Build search query with name filtering
5. Return formatted student list

**Availability Check**:
```php
foreach($studentaddsubjectdetails as $studentaddsubjectdetail) {
    $studentsubjects = R::load('studentsubjects', $studentaddsubjectdetail->studentsubjectid);
    $date = date("Y-m-d");
    $studentabsences = R::count('studentabsences', 
        "studentid = ? and deviceid = ? and todaysend = '$date' and del < 2",
        [$studentaddsubjectdetail->studentid, $studentsubjects->deviceid]);
    
    if ($studentabsences == 0) {
        $studentid .= ',' . $studentaddsubjectdetail->studentid;
    }
}
```

---

## 🔄 Workflows

### Workflow 1: Device-Based Attendance Processing
```
┌─────────────────────────────────────────────────────────────┐
│              START: Process Device Attendance Data         │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Read Device File                                        │
│     - Access device IP address endpoint                     │
│     - Read daily attendance file (YYYY-MM-DD.txt)           │
│     - Parse file content line by line                       │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Process Each Attendance Record                          │
│     FOR EACH line in file:                                  │
│       │                                                     │
│       ├─→ Parse record (uniqid?studentid?date?time?type)   │
│       │                                                     │
│       ├─→ Check for duplicate records                      │
│       │                                                     │
│       ├─→ Validate student assignment                      │
│       │   └─ Find student in subject assignments           │
│       │                                                     │
│       └─→ Create attendance record                         │
│           ├─ Set all attendance fields                     │
│           ├─ Link to student and assignments               │
│           └─ Set audit information                         │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Display Processed Results                               │
│     - Show imported attendance records                      │
│     - Display any processing errors                         │
│     - Provide summary statistics                            │
└─────────────────────────────────────────────────────────────┘
```

---

### Workflow 2: Automated Absence Detection
```
┌─────────────────────────────────────────────────────────────┐
│              START: Generate Absence Notifications         │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Select Subject Group                                    │
│     - Choose from scheduled classes for today               │
│     - Get current time and date                             │
│     - Load group assignment details                         │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Check Student Attendance                                │
│     FOR EACH student in group:                              │
│       │                                                     │
│       ├─→ Check for existing attendance record today       │
│       │   └─ Query by student, device, date                │
│       │                                                     │
│       ├─→ If no record exists:                             │
│       │   ├─ Create absence record                         │
│       │   ├─ Mark as automated (onlys = 1)                 │
│       │   ├─ Set arrival time as '0'                       │
│       │   └─ Link to all assignment details                │
│       │                                                     │
│       └─→ Continue to next student                         │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Generate Notifications                                  │
│     - Create absence records for all missing students       │
│     - Mark notifications as automated                       │
│     - Return success status                                 │
└─────────────────────────────────────────────────────────────┘
```

---

## 🌐 URL Routes & Actions

| URL Parameter | Function Called | Description |
|---------------|----------------|-------------|
| `do=` (empty) | Default action | Display attendance interface |
| `do=show` | Show view | Display daily schedule view |
| `do=edit` | Edit/Import | Import attendance from device file |
| `do=sendmassage` | Absence notification | Generate automated absence records |
| `do=savedata` | `savedata()` | Manual attendance entry |
| `do=receivedata` | Data receiver | Receive attendance data (undefined) |
| `do=showajax` | `showajax()` | AJAX data for attendance table |
| `do=removecontroller` | `removecontroller()` | Delete attendance record |
| `do=getstudentabsence` | `getstudentabsence()` | Get available students |
| `do=sendmassagemanual` | `sendmassagemanual()` | Manual group absence |

### Required Parameters by Action

**Device Import** (`do=edit`):
- `id` - Device IP address or identifier

**Absence Notification** (`do=sendmassage`):
- `studentsubjectgroupid` - Subject group ID

**Manual Entry** (`do=savedata`):
- `studentaddsubjectid` - Assignment ID
- `studentid` - Comma-separated student IDs

**Student Search** (`do=getstudentabsence`):
- `searchTerms` - Search string
- `tablesearch` - Search fields
- `studentaddsubjectid` - Assignment context

**AJAX Data**:
- `start_date` / `end_date` - Date range filters
- `data1` - Assignment filter
- `data2` - Detail filter
- `data3` - Record type filter (automated vs manual)

---

## 🧮 Calculation Methods

### Time-Based Validation
```php
$times = date("H:i:s");
$time1hour = date('H:i:s', strtotime('+1 hour'));
$day = date('l'); // Current day name
```

### Attendance Status Determination
```php
// Check if student already recorded today
$studentabsencesc = R::count('studentabsences', 
    " studentid = ? and deviceid = ? and todaysend = '$date' and del < 2",
    [$studentid, $deviceid]);
```

### Record Type Classification
```php
// onlys field indicates record type
// 0 = Manual entry
// 1 = Automated/system generated
$studentabsences->onlys = 0; // Manual
$studentabsences->onlys = 1; // Automated
```

---

## 🔒 Security & Permissions

### Authentication Check
```php
include_once("../public/authentication.php");
```

### Device Security
- Device file access restricted by IP address
- File path validation for device endpoints
- Duplicate record prevention

### Input Validation
```php
// File content validation
if ($handle) {
    $lists = explode("\n", $handle);
    foreach ($lists as $data) {
        if ($data && count(explode('?', $data)) >= 6) {
            // Process valid record
        }
    }
}
```

### Data Integrity
- Unique constraints on attendance records
- Foreign key relationships maintained
- Soft deletion preserves attendance history

---

## 📊 Performance Considerations

### Database Optimization
1. **Efficient Queries**: Date-based indexing for attendance lookups
2. **Duplicate Prevention**: Count queries before insertion
3. **Batch Processing**: File import handles multiple records efficiently

### File I/O Optimization
- Daily file structure for device integration
- Efficient file parsing with minimal memory usage
- Error handling for corrupted or missing files

### Recommended Indexes
```sql
CREATE INDEX idx_studentabsences_student_device_date ON studentabsences(studentid, deviceid, todaysend, del);
CREATE INDEX idx_studentabsences_assignment_date ON studentabsences(studentaddsubjectid, todaysend, del);
CREATE INDEX idx_studentabsences_uniq_device_date ON studentabsences(uniqid, deviceid, todaysend);
```

### Performance Issues
- **Large Files**: Device files with many records may impact import time
- **Real-time Processing**: Multiple simultaneous device imports
- **Search Performance**: Student search across large datasets

---

## 🐛 Common Issues & Troubleshooting

### 1. **Device File Not Found**
**Issue**: Attendance import fails with file not found  
**Cause**: Incorrect device IP or missing date file

**Debug**:
```php
$deviceid = filter_input(INPUT_GET, 'id');
$filename = $deviceid.'/'.date('Y-m-d').".txt";
if (!file_exists($filename)) {
    echo "File not found: " . $filename;
}
```

### 2. **Duplicate Attendance Records**
**Issue**: Same student appears multiple times for same day  
**Cause**: Duplicate prevention logic failing

**Fix**:
```sql
-- Check for duplicates
SELECT studentid, deviceid, todaysend, COUNT(*) as count
FROM studentabsences 
WHERE del < 2
GROUP BY studentid, deviceid, todaysend
HAVING COUNT(*) > 1;
```

### 3. **Students Not Found in Assignment**
**Issue**: Device records can't be linked to student assignments  
**Cause**: Student not assigned to subject with matching device

**Debug**:
```sql
-- Check student assignment with device
SELECT s.studentname, sub.deviceid, ass.id
FROM students s
LEFT JOIN studentaddsubjectdetails det ON s.id = det.studentid
LEFT JOIN studentsubjects sub ON det.studentsubjectid = sub.id
LEFT JOIN studentaddsubjects ass ON det.studentaddsubjectid = ass.id
WHERE s.id = [STUDENT_ID] AND sub.deviceid = '[DEVICE_ID]';
```

### 4. **Absence Notifications Not Generating**
**Issue**: Automated absence records not created  
**Cause**: Group has no assigned students or existing records

**Debug**:
```php
$studentaddsubjectdetails = R::findAll('studentaddsubjectdetails',
    ' studentsubjectgroupid = ? and del < 2 ', [$studentsubjectgroupid]);
echo "Students in group: " . count($studentaddsubjectdetails);
```

---

## 🧪 Testing Scenarios

### Test Case 1: Device Integration
```
1. Create test attendance file with valid format
2. Place file in device directory with current date
3. Run device import process
4. Verify records created correctly
5. Check duplicate prevention works
```

### Test Case 2: Manual Attendance Entry
```
1. Select assignment and available students
2. Mark attendance manually
3. Verify records created with correct type
4. Check students removed from available list
5. Test with various student combinations
```

### Test Case 3: Automated Absence Detection
```
1. Set up scheduled class with assigned students
2. Mark some students present manually/device
3. Run automated absence detection
4. Verify absent students get absence records
5. Check automation flags set correctly
```

### Test Case 4: Attendance Reporting
```
1. Create various attendance records (present/absent)
2. Test data table filtering and search
3. Verify date range filtering works
4. Check action buttons and record deletion
5. Test export functionality if available
```

---

## 📚 Related Documentation

- [CLAUDE.md](/Applications/AMPPS/www/erp19/CLAUDE.md) - PHP 8.2 migration guide
- [studentSettings.md](studentSettings.md) - System configuration
- [studentSubjectsController.md](studentSubjectsController.md) - Subject scheduling
- [studentsAddSubject.md](studentsAddSubject.md) - Student assignments
- [studentsExamsController.md](studentsExamsController.md) - Exam attendance
- [Database Schema Documentation](#) - Table relationships

---

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