Employeeendday Documentation

Employee End Day Controller Documentation

File: /controllers/employeeendday.php

Purpose: Advanced employee shift closure system with attendance tracking, payroll integration, and hierarchical status management

Last Updated: December 20, 2024

Total Functions: 7+

Lines of Code: ~477

---

๐Ÿ“‹ Overview

The Employee End Day Controller is a sophisticated workforce management system that handles the closure of employee shifts with comprehensive attendance tracking, automatic payroll integration, and hierarchical approval workflows. It provides:

Primary Functions

Related Controllers

---

๐Ÿ—„๏ธ Database Tables

Core Employee Tables

Table NamePurposeKey Columns
**employee**Employee master dataemployeeId, employeeName, employeegroupid, employeesubgroupid, branchid, conditions
**employeegroup**Employee group hierarchyid, name, employeeattendancesystemid, userid, del
**employeesubgroup**Employee subgroup structureid, name, employeegroupid, employeeattendancesystemid, userid, del
### Attendance System Tables

Table NamePurposeKey Columns
**employeeattendancesystem**Attendance rules configurationid, attendanceTime, departureTime, userid, del
**employeeclosedayhistory**Individual employee day closureid, day, employeeid, attendanceTime, departureTime, latePeriod, lateDiscount, isAbsent, absentDiscount, status
### Status Tracking Tables

Table NamePurposeKey Columns
**employeeclosedaygroupstatus**Group-level closure statusid, day, employeegroupid, status, userid, sysdate, conditions
**employeeclosedaysubgroupstatus**Subgroup-level closure statusid, day, employeesubgroupid, status, userid, sysdate, conditions
**employeeclosedaystatus**System-wide day closure statusid, day, status, userid, sysdate, conditions
### Configuration Tables

Table NamePurposeKey Columns
**youtubelink**Tutorial referencesyoutubelinkid, title, url
---

๐Ÿ”‘ Key Functions

1. getdaytoclose - Load Employee Day Data (Ajax)

Location: Line 129-176

Purpose: Load employee data for a specific day with attendance system rules

Function Signature:

// Ajax Action: do=getdaytoclose
$day = filter_input(INPUT_POST, 'day');
$employeegroupid = (int) filter_input(INPUT_POST, 'employeegroupid');
$employeesubgroupid = (int) filter_input(INPUT_POST, 'employeesubgroupid');

Process Flow:

1. Build Employee Query:

   $queryString = ' WHERE employee.conditions=0 ';
   if ($employeesubgroupid > 0) {
       $queryString .= " and employeesubgroupid = $employeesubgroupid ";
   } elseif ($employeegroupid > 0) {
       $queryString .= " and employeegroupid = $employeegroupid ";
   }
   ```

2. **Apply Branch Filtering**:
   ```php
   if ($_SESSION['branchId'] > 0)
       $queryString .= ' AND  branchid = ' . $_SESSION['branchId'];
   ```

3. **Load Attendance System Rules**:
   ```php
   foreach ($employeeArr as $emp) {
       $attendanceSysData = $employeeAttendanceSystemEX->getAttendanceSystemByEmployeeSubGroup($emp->employeesubgroupid);
       $sys->attendanceTime = $attendanceSysData->attendanceTime;
       $sys->departureTime = $attendanceSysData->departureTime;
       
       // Load employee-specific discount rates
       $sys->halfHourLateWithPermissionDisount = $emp->halfHourLateWithPermissionDisount;
       // ... (all other discount configurations)
   }
   ```

**Features**:
- Dynamic group/subgroup filtering
- Real-time attendance system rule loading
- Employee-specific discount configuration
- JSON-encoded rule data for frontend processing

---

### 2. **closeday** - Execute Day Closure (Ajax)
**Location**: Line 177-315  
**Purpose**: Process and close employee shifts with payroll integration

**Function Signature**:
php

// Ajax Action: do=closeday

// Transaction-protected operation

$mytransactions = new Transaction();

**Process Flow**:
1. **Validate Input Data**:
   ```php
   $day = filter_input(INPUT_POST, 'day');
   $empitr = (int) filter_input(INPUT_POST, 'empitr');
   
   if (isRealDate($day) && $empitr > 1) {
       // Process closure
   }
   ```

2. **Process Each Employee**:
   ```php
   for ($i = 1; $i < $empitr; $i++) {
       $empid = (int) filter_input(INPUT_POST, 'empid' . $i);
       
       $attendanceTime = filter_input(INPUT_POST, 'attendanceTime' . $empid);
       $departureTime = filter_input(INPUT_POST, 'departureTime' . $empid);
       $latePeriod = (float) filter_input(INPUT_POST, 'latePeriod' . $empid);
       $lateDiscount = (float) filter_input(INPUT_POST, 'lateDiscount' . $empid);
       $isAbsent = (int) filter_input(INPUT_POST, 'isAbsent' . $empid);
       $absentDiscount = (float) filter_input(INPUT_POST, 'absentDiscount' . $empid);
   }
   ```

3. **Update Employee History**:
   ```php
   if ($isAbsent == 0) { // Not absent
       $employeeCloseDayHistory->attendanceTime = $attendanceTime . ":00";
       $employeeCloseDayHistory->departureTime = $departureTime . ":00";
       $employeeCloseDayHistory->latePeriod = $latePeriod;
       $employeeCloseDayHistory->lateDiscount = $lateDiscount;
   } elseif ($isAbsent == 1) { // Absent
       $employeeCloseDayHistory->attendanceTime = "00:00:00";
       $employeeCloseDayHistory->departureTime = "00:00:00";
       $employeeCloseDayHistory->isAbsent = $isAbsent;
       $employeeCloseDayHistory->absentDiscount = $absentDiscount;
   }
   ```

4. **Payroll Integration**:
   ```php
   affectOnSalary($employeeCloseDayHistory, $oldEmployeeCloseDayHistory);
   ```

**Hierarchical Status Updates**:
- Updates subgroup status when all employees closed
- Updates group status when all subgroups closed  
- Updates day status when all groups closed

---

### 3. **affectOnSalary()** - Payroll System Integration
**Location**: Line 373-404  
**Purpose**: Integrate attendance data with payroll system via cURL

**Function Signature**:
php

function affectOnSalary($newEmployeeCloseDayHistory, $oldEmployeeCloseDayHistory)

**Process Flow**:
1. **Change Detection**:
   ```php
   if($oldEmployeeCloseDayHistory->status == 1 && 
      $newEmployeeCloseDayHistory->isAbsent == $oldEmployeeCloseDayHistory->isAbsent && 
      $newEmployeeCloseDayHistory->absentDiscount == $oldEmployeeCloseDayHistory->absentDiscount && 
      $newEmployeeCloseDayHistory->lateDiscount == $oldEmployeeCloseDayHistory->lateDiscount) {
       // No changes, do nothing
   }
   ```

2. **Remove Old Salary Effects**:
   ```php
   if ($oldEmployeeCloseDayHistory->status != -1) {
       if ($oldEmployeeCloseDayHistory->isAbsent == 0) {
           curlDeleteEmployeePersonal($oldEmployeeCloseDayHistory->employeeid, 
                                     $oldEmployeeCloseDayHistory->day, 
                                     $oldEmployeeCloseDayHistory->lateDiscount, 5);
       } elseif ($oldEmployeeCloseDayHistory->isAbsent == 1) {
           curlDeleteEmployeePersonal($oldEmployeeCloseDayHistory->employeeid, 
                                     $oldEmployeeCloseDayHistory->day, 
                                     $oldEmployeeCloseDayHistory->absentDiscount, 9);
       }
   }
   ```

3. **Apply New Salary Effects**:
   ```php
   if ($newEmployeeCloseDayHistory->isAbsent == 0) {
       curlAddEmployeePersonal($newEmployeeCloseDayHistory->employeeid, 
                              $newEmployeeCloseDayHistory->day, 
                              $newEmployeeCloseDayHistory->lateDiscount, 5);
   } elseif ($newEmployeeCloseDayHistory->isAbsent == 1) {
       curlAddEmployeePersonal($newEmployeeCloseDayHistory->employeeid, 
                              $newEmployeeCloseDayHistory->day, 
                              $newEmployeeCloseDayHistory->absentDiscount, 9);
   }
   ```

---

### 4. **curlAddEmployeePersonal()** - Add Payroll Entry
**Location**: Line 406-443  
**Purpose**: Add late/absence deductions to employee payroll via cURL

**Function Signature**:
php

function curlAddEmployeePersonal($empid, $day, $discountVal, $type)

// $type: 5=late, 9=absent

**cURL Implementation**:
php

$post = [

'fromCtrl' => 'employeeendday',

'empName' => $empid,

'empValue' => $discountVal,

'employeepersonneldate' => $dayAsDateTime,

'type' => $type, // 5=late, 9=absent

'Costcenterid' => '-1',

'paymethod' => '0',

'userid' => $_SESSION['userid'],

'saveid' => $_SESSION["saveid"],

'dbname' => $_SESSION["dbname"],

];

$ch = curl_init('http://localhost/ERP/controllers/employeePersonalController.php?do=add');

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

curl_setopt($ch, CURLOPT_POSTFIELDS, $post);

$response = curl_exec($ch);

---

### 5. **curlDeleteEmployeePersonal()** - Remove Payroll Entry
**Location**: Line 445-476  
**Purpose**: Remove previously applied payroll deductions via cURL

**Features**:
- Removes late/absence deductions
- Maintains payroll consistency
- Supports editing/reversal operations

---

### 6. **closedayshow** - Historical View
**Location**: Line 316-343  
**Purpose**: Display historical employee day closure data

**Features**:
- Monthly attendance history
- Employee-specific filtering
- Branch-based access control
- Historical trend analysis

---

### 7. **isRealDate()** - Date Validation
**Location**: Line 366-372  
**Purpose**: Validate date format for closure operations

php

function isRealDate($date) {

if (false === strtotime($date)) {

return false;

}

list($year, $month, $day) = explode('-', $date);

return checkdate($month, $day, $year);

}

---

## ๐Ÿ”„ Workflows

### Workflow 1: Hierarchical Day Closure Process

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”

โ”‚ START: Select Day to Close โ”‚

โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โ”‚

โ–ผ

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”

โ”‚ 1. Load Employee Data for Day โ”‚

โ”‚ - Apply group/subgroup filters โ”‚

โ”‚ - Load attendance system rules โ”‚

โ”‚ - Apply branch restrictions โ”‚

โ”‚ - Generate attendance forms โ”‚

โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โ”‚

โ–ผ

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”

โ”‚ 2. Process Individual Employee Closures โ”‚

โ”‚ FOR EACH Employee: โ”‚

โ”‚ โ”‚ โ”‚

โ”‚ โ”œโ”€โ†’ Record attendance/departure times โ”‚

โ”‚ โ”œโ”€โ†’ Calculate late period discounts โ”‚

โ”‚ โ”œโ”€โ†’ Process absence status and discounts โ”‚

โ”‚ โ”œโ”€โ†’ Update employeeclosedayhistory โ”‚

โ”‚ โ””โ”€โ†’ Integrate with payroll system โ”‚

โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โ”‚

โ–ผ

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”

โ”‚ 3. Update Subgroup Status โ”‚

โ”‚ - Mark subgroup as closed โ”‚

โ”‚ - Check if all employees in subgroup are closed โ”‚

โ”‚ - Update employeeclosedaysubgroupstatus โ”‚

โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โ”‚

โ–ผ

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”

โ”‚ 4. Check Group Closure Criteria โ”‚

โ”‚ - Count total subgroups in group โ”‚

โ”‚ - Count closed subgroups for day โ”‚

โ”‚ - IF all subgroups closed: Mark group as closed โ”‚

โ”‚ - Update employeeclosedaygroupstatus โ”‚

โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โ”‚

โ–ผ

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”

โ”‚ 5. Check System-Wide Day Closure โ”‚

โ”‚ - Count total employee groups โ”‚

โ”‚ - Count closed groups for day โ”‚

โ”‚ - IF all groups closed: Mark day as system closed โ”‚

โ”‚ - Update employeeclosedaystatus โ”‚

โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

---

### Workflow 2: Payroll Integration Process

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”

โ”‚ START: Employee Attendance Data Changed โ”‚

โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โ”‚

โ–ผ

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”

โ”‚ 1. Detect Changes in Attendance Data โ”‚

โ”‚ - Compare old vs new attendance status โ”‚

โ”‚ - Compare old vs new discount amounts โ”‚

โ”‚ - Determine if payroll update needed โ”‚

โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โ”‚

โ–ผ (if changes detected)

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”

โ”‚ 2. Remove Old Payroll Effects โ”‚

โ”‚ IF Previously Late: โ”‚

โ”‚ โ”‚ - cURL DELETE late deduction (type=5) โ”‚

โ”‚ IF Previously Absent: โ”‚

โ”‚ โ”‚ - cURL DELETE absence deduction (type=9) โ”‚

โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โ”‚

โ–ผ

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”

โ”‚ 3. Apply New Payroll Effects โ”‚

โ”‚ IF Currently Late: โ”‚

โ”‚ โ”‚ - cURL ADD late deduction (type=5) โ”‚

โ”‚ IF Currently Absent: โ”‚

โ”‚ โ”‚ - cURL ADD absence deduction (type=9) โ”‚

โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โ”‚

โ–ผ

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”

โ”‚ 4. Update Employee Personal Records โ”‚

โ”‚ - POST to employeePersonalController.php โ”‚

โ”‚ - Include employee ID, date, amount, type โ”‚

โ”‚ - Maintain audit trail in payroll system โ”‚

โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

---

## ๐ŸŒ URL Routes & Actions

| URL Parameter | Function Called | Description | Ajax |
|---------------|----------------|-------------|------|
| (empty) or `do=show` | Default display | Show day closure form | No |
| `do=getdaytoclose` | Load day data | Load employees for specific day | Yes |
| `do=closeday` | `closeday()` | Execute day closure process | Yes |
| `do=closedayshow` | Historical view | Show historical closure data | No |
| `do=sucess` | Success page | Display success message | No |
| `do=error` | Error page | Display error message | No |

### Ajax Operations Parameters

**getdaytoclose** (POST):
- `day` - Date to close (YYYY-MM-DD format)
- `employeegroupid` - Group filter (optional)
- `employeesubgroupid` - Subgroup filter (optional)

**closeday** (POST):
- `day` - Date being closed
- `empitr` - Number of employees being processed
- `employeegroupid_day` - Group ID for closure
- `employeesubgroupid_day` - Subgroup ID for closure
- `empid{N}` - Employee ID for each employee
- `attendanceTime{empid}` - Attendance time
- `departureTime{empid}` - Departure time  
- `latePeriod{empid}` - Late period in hours
- `lateDiscount{empid}` - Late discount amount
- `isAbsent{empid}` - Absence status (0/1)
- `absentDiscount{empid}` - Absence discount amount

---

## ๐Ÿงฎ Calculation Methods

### Late Period Discount Calculation
Based on employee-specific rates loaded from attendance system:
php

// Example discount structure:

$sys->halfHourLateWithPermissionDisount = $emp->halfHourLateWithPermissionDisount;

$sys->hourLateWithPermissionDisount = $emp->hourLateWithPermissionDisount;

$sys->hourAndHalfLateWithPermissionDisount = $emp->hourAndHalfLateWithPermissionDisount;

$sys->twoHoursLateWithPermissionDisount = $emp->twoHoursLateWithPermissionDisount;

$sys->moreThanTwoHoursLateWithPermissionDisount = $emp->moreThanTwoHoursLateWithPermissionDisount;

// Without permission discounts are typically higher

$sys->halfHourLateWithoutPermissionDisount = $emp->halfHourLateWithoutPermissionDisount;

// ... etc

### Absence Discount Calculation
php

// Day absence discounts

$sys->dayAbsenceWithPermissionDisount = $emp->dayAbsenceWithPermissionDisount;

$sys->dayAbsenceWithoutPermissionDisount = $emp->dayAbsenceWithoutPermissionDisount;

### Hierarchical Status Logic
php

// Subgroup closure check

$noOfSubGroupsInaGroup = count($employeeSubGroupEX->queryByEmployeegroupidEX($subGroupData->employeegroupid));

$noOfSubGroupsClosedInaGroupForADay = count($EmployeeclosedaysubgroupstatusEX->queryByEmployeegroupidAndDayGetDistinctSubGroupsClosed($subGroupData->employeegroupid, $day));

if ($noOfSubGroupsInaGroup == $noOfSubGroupsClosedInaGroupForADay) {

// Mark group as closed

}

// System-wide closure check

$noOfGroups = $employeeGroupEX->queryAllEXCount();

$noOfGroupsClosedInADay = $employeeCloseDayGroupStatusEX->getNoOfGroupsClosedInADay($day);

if ($noOfGroups == $noOfGroupsClosedInADay) {

// Mark entire day as closed

}

---

## ๐Ÿ”’ Security & Permissions

### Authentication & Session Management
php

include_once("../public/authentication.php");

### Branch-Level Access Control
php

if ($_SESSION['branchId'] > 0)

$queryString .= ' AND branchid = ' . $_SESSION['branchId'];

### Transaction Security
php

$mytransactions = new Transaction();

try {

// All closure operations

$mytransactions->commit();

} catch (Exception $e) {

echo -1;

$mytransactions->rollback();

}

### cURL Security
- Session-based user identification
- Database name validation
- Save ID verification
- Input parameter validation

---

## ๐Ÿ› Common Issues & Troubleshooting

### 1. **Payroll Integration Failures**
**Issue**: cURL calls to employeePersonalController.php fail  
**Causes**:
- Incorrect URL (hardcoded localhost)
- Missing session parameters
- Target controller unavailable

**Fix**:
php

// Use dynamic host configuration

$host = $_SERVER['HTTP_HOST'];

$ch = curl_init("http://$host/ERP/controllers/employeePersonalController.php?do=add");

### 2. **Hierarchical Status Issues**
**Issue**: Groups/subgroups not marked as closed properly  
**Debug Steps**:
1. Check employee count queries
2. Verify status update logic
3. Examine closure criteria calculations

### 3. **Date Validation Problems**
**Issue**: Invalid date formats cause closure failures  
**Fix**: Enhance date validation:
php

function isRealDate($date) {

if (false === strtotime($date)) {

return false;

}

if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) {

return false;

}

list($year, $month, $day) = explode('-', $date);

return checkdate($month, $day, $year);

}

### 4. **Ajax Response Handling**
**Issue**: Frontend doesn't receive proper Ajax responses  
**Ensure**:
- Return 1 for success, -1 for error
- No HTML output before Ajax responses
- Proper JSON encoding where needed

---

## ๐Ÿ“Š Performance Considerations

### Database Optimization
1. **Critical Indexes**:
   - `employee(employeegroupid, employeesubgroupid, conditions, branchid)`
   - `employeeclosedayhistory(day, employeeid, status)`
   - `employeeclosedaygroupstatus(day, employeegroupid, status)`
   - `employeeclosedaysubgroupstatus(day, employeesubgroupid, status)`

2. **Query Optimization**:
   - Use EXISTS queries for status checks
   - Limit date ranges appropriately
   - Cache attendance system rules

### cURL Performance
- Implement connection pooling
- Use asynchronous calls where possible
- Add timeout configurations
- Cache payroll responses

### Memory Management
- Process employees in batches for large organizations
- Clear variables in loops
- Optimize JSON data structures

---

## ๐Ÿงช Testing Scenarios

### Test Case 1: Complete Day Closure Workflow

1. Select a day with employees in multiple groups/subgroups

2. Close individual employees with various attendance statuses

3. Verify subgroup closure when all employees closed

4. Check group closure when all subgroups closed

5. Confirm system-wide closure when all groups closed

6. Validate payroll integration for each step

### Test Case 2: Payroll Integration

1. Close employee with late arrival

2. Verify late deduction appears in payroll system

3. Edit the same employee's data

4. Confirm old deduction removed and new one applied

5. Test absence scenarios similarly

### Test Case 3: Branch Access Control

1. Login as branch-restricted user

2. Verify only branch employees appear for closure

3. Test closure operations respect branch boundaries

4. Check status updates don't affect other branches

### Test Case 4: Error Handling

1. Test with invalid date formats

2. Simulate cURL failures to payroll system

3. Test transaction rollback scenarios

4. Verify data consistency after failures

```

---

๐Ÿ“š Related Documentation

---

Documented By: AI Assistant

Review Status: โœ… Complete

Next Review: When major changes occur