add projet
This commit is contained in:
Executable
+399
@@ -0,0 +1,399 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Models\ClassSection;
|
||||
use App\Models\Configuration;
|
||||
use App\Models\CurrentFlag;
|
||||
use App\Models\Flag;
|
||||
use App\Models\StudentClass;
|
||||
use App\Models\Student;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class FlagController extends BaseApiController
|
||||
{
|
||||
protected CurrentFlag $currentFlag;
|
||||
protected Flag $flag;
|
||||
protected Student $student;
|
||||
protected ClassSection $classSection;
|
||||
protected StudentClass $studentClass;
|
||||
protected Configuration $config;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->currentFlag = model(CurrentFlag::class);
|
||||
$this->flag = model(Flag::class);
|
||||
$this->student = model(Student::class);
|
||||
$this->classSection = model(ClassSection::class);
|
||||
$this->studentClass = model(StudentClass::class);
|
||||
$this->config = model(Configuration::class);
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$page = max(1, (int) ($this->request->getGet('page') ?? 1));
|
||||
$perPage = min(100, max(1, (int) ($this->request->getGet('per_page') ?? 20)));
|
||||
$studentId = $this->request->getGet('student_id');
|
||||
$flagType = $this->request->getGet('flag_type') ?? $this->request->getGet('flag');
|
||||
$state = $this->request->getGet('state') ?? $this->request->getGet('flag_state');
|
||||
|
||||
$query = $this->currentFlag->newQuery()->orderBy('created_at', 'DESC');
|
||||
if ($studentId) {
|
||||
$query->where('student_id', $studentId);
|
||||
}
|
||||
if ($flagType) {
|
||||
$query->where('flag', $flagType);
|
||||
}
|
||||
if ($state) {
|
||||
$query->where('flag_state', $state);
|
||||
}
|
||||
|
||||
$result = $this->paginate($query, $page, $perPage);
|
||||
|
||||
// Also return class sections (grades) for UI
|
||||
$classSections = $this->classSection->findAll();
|
||||
$grades = [];
|
||||
foreach ($classSections as $section) {
|
||||
$grades[] = [
|
||||
'id' => $section['class_section_id'] ?? $section['id'] ?? null,
|
||||
'name' => $section['class_section_name'] ?? $section['name'] ?? '',
|
||||
];
|
||||
}
|
||||
|
||||
$result['grades'] = $grades;
|
||||
|
||||
return $this->success($result, 'Flags retrieved successfully');
|
||||
}
|
||||
|
||||
public function show($id = null)
|
||||
{
|
||||
$flag = $this->currentFlag->find($id);
|
||||
if (!$flag) {
|
||||
return $this->respondError('Flag not found', Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
return $this->success($flag, 'Flag retrieved successfully');
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
return $this->addFlag();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add or update a flag for a student
|
||||
* If a flag of the same type exists, it updates it; otherwise creates a new one
|
||||
*/
|
||||
public function addFlag()
|
||||
{
|
||||
$user = $this->getCurrentUser();
|
||||
$data = $this->payloadData();
|
||||
if (empty($data)) {
|
||||
return $this->respondError('Invalid request data', Response::HTTP_BAD_REQUEST);
|
||||
}
|
||||
|
||||
$studentId = $data['student_id'] ?? $data['student'] ?? null;
|
||||
$flagType = $data['flag'] ?? $data['flag_type'] ?? null;
|
||||
$description = $data['description'] ?? $data['open_description'] ?? null;
|
||||
$flagState = $data['flag_state'] ?? 'Open';
|
||||
$stateDescription = $data['state_description'] ?? null;
|
||||
$grade = $data['grade'] ?? null;
|
||||
|
||||
if (!$studentId || !$flagType || !$description) {
|
||||
return $this->respondError('Missing required fields: student_id, flag, description', Response::HTTP_BAD_REQUEST);
|
||||
}
|
||||
|
||||
try {
|
||||
// Retrieve student information
|
||||
$student = $this->student->find($studentId);
|
||||
if (!$student) {
|
||||
return $this->respondError('Student not found', Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
$userId = $user->id ?? null;
|
||||
$semester = $this->config->getConfig('semester');
|
||||
$schoolYear = $this->config->getConfig('school_year');
|
||||
$currentDateTime = date('Y-m-d H:i:s');
|
||||
|
||||
// Check if a flag of the same type already exists for this student
|
||||
$existingFlag = $this->currentFlag
|
||||
->where('student_id', $studentId)
|
||||
->where('flag', $flagType)
|
||||
->first();
|
||||
|
||||
if ($existingFlag) {
|
||||
// Update existing flag
|
||||
$updateData = [
|
||||
'flag_datetime' => $currentDateTime,
|
||||
'updated_by_open' => $userId,
|
||||
];
|
||||
|
||||
// Append description based on flag state
|
||||
if ($flagState === 'Closed') {
|
||||
$updateData['flag_state'] = 'Closed';
|
||||
$existingCloseDesc = $existingFlag['close_description'] ?? '';
|
||||
$updateData['close_description'] = $existingCloseDesc
|
||||
? $existingCloseDesc . PHP_EOL . $stateDescription
|
||||
: $stateDescription;
|
||||
} elseif ($flagState === 'Canceled') {
|
||||
$updateData['flag_state'] = 'Canceled';
|
||||
$existingCancelDesc = $existingFlag['cancel_description'] ?? '';
|
||||
$updateData['cancel_description'] = $existingCancelDesc
|
||||
? $existingCancelDesc . PHP_EOL . $stateDescription
|
||||
: $stateDescription;
|
||||
} else {
|
||||
$existingOpenDesc = $existingFlag['open_description'] ?? '';
|
||||
$updateData['open_description'] = $existingOpenDesc
|
||||
? $existingOpenDesc . PHP_EOL . $description
|
||||
: $description;
|
||||
}
|
||||
|
||||
$this->currentFlag->update($existingFlag['id'], $updateData);
|
||||
$flag = $this->currentFlag->find($existingFlag['id']);
|
||||
|
||||
return $this->success($flag, 'Flag updated successfully');
|
||||
} else {
|
||||
// Create new flag
|
||||
$flagData = [
|
||||
'student_id' => $student['id'],
|
||||
'student_name' => trim(($student['firstname'] ?? '') . ' ' . ($student['lastname'] ?? '')),
|
||||
'grade' => $grade,
|
||||
'flag' => $flagType,
|
||||
'flag_datetime' => $currentDateTime,
|
||||
'flag_state' => 'Open',
|
||||
'updated_by_open' => $userId,
|
||||
'open_description' => $description,
|
||||
'semester' => $semester,
|
||||
'school_year' => $schoolYear,
|
||||
];
|
||||
|
||||
$flag = $this->currentFlag->create($flagData);
|
||||
return $this->success($flag, 'New flag added successfully', Response::HTTP_CREATED);
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
log_message('error', 'Add flag error: ' . $e->getMessage());
|
||||
return $this->respondError('Failed to add flag', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
public function updateState($id = null)
|
||||
{
|
||||
$flag = $this->currentFlag->find($id);
|
||||
if (!$flag) {
|
||||
return $this->respondError('Flag not found', Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
$data = $this->payloadData();
|
||||
if (empty($data)) {
|
||||
return $this->respondError('Invalid request data', Response::HTTP_BAD_REQUEST);
|
||||
}
|
||||
|
||||
$newState = $data['flag_state'] ?? null;
|
||||
if (!$newState) {
|
||||
return $this->respondError('Flag state is required', Response::HTTP_BAD_REQUEST);
|
||||
}
|
||||
|
||||
try {
|
||||
$updateData = ['flag_state' => $newState];
|
||||
|
||||
// Update appropriate description field based on state
|
||||
if (isset($data['state_description'])) {
|
||||
if ($newState === 'Closed') {
|
||||
$updateData['close_description'] = $data['state_description'];
|
||||
} elseif ($newState === 'Canceled') {
|
||||
$updateData['cancel_description'] = $data['state_description'];
|
||||
} else {
|
||||
$updateData['open_description'] = $data['state_description'];
|
||||
}
|
||||
}
|
||||
|
||||
$this->currentFlag->update($id, $updateData);
|
||||
$flag = $this->currentFlag->find($id);
|
||||
|
||||
return $this->success($flag, 'Flag state updated successfully');
|
||||
} catch (\Throwable $e) {
|
||||
log_message('error', 'Update flag state error: ' . $e->getMessage());
|
||||
return $this->respondError('Failed to update flag state', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
public function close($id = null)
|
||||
{
|
||||
return $this->closeFlag($id);
|
||||
}
|
||||
|
||||
public function cancel($id = null)
|
||||
{
|
||||
return $this->cancelFlag($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close a flag and move it to history
|
||||
*/
|
||||
public function closeFlag($flagId = null)
|
||||
{
|
||||
$flagId = $flagId ?? $this->request->getPost('id') ?? $this->request->getGet('id');
|
||||
if (!$flagId) {
|
||||
return $this->respondError('Flag ID is required', Response::HTTP_BAD_REQUEST);
|
||||
}
|
||||
|
||||
try {
|
||||
$user = $this->getCurrentUser();
|
||||
$userId = $user->id ?? null;
|
||||
|
||||
// Get the current flag data
|
||||
$flagData = $this->currentFlag->find($flagId);
|
||||
if (!$flagData) {
|
||||
return $this->respondError('Flag not found', Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
// Check if flag is already closed
|
||||
if ($flagData['flag_state'] === 'Closed') {
|
||||
return $this->respondError('Flag is already closed', Response::HTTP_BAD_REQUEST);
|
||||
}
|
||||
|
||||
// Get close description from request
|
||||
$data = $this->payloadData();
|
||||
$closeDescription = $data['state_description'] ?? $data['close_description'] ?? null;
|
||||
|
||||
if (empty($closeDescription)) {
|
||||
return $this->respondError('Close description is required', Response::HTTP_BAD_REQUEST);
|
||||
}
|
||||
|
||||
// Update the flag state to Closed
|
||||
$this->currentFlag->update($flagId, [
|
||||
'flag_state' => 'Closed',
|
||||
'updated_by_closed' => $userId,
|
||||
'close_description' => $closeDescription,
|
||||
]);
|
||||
|
||||
// Retrieve updated flag data
|
||||
$flagData = $this->currentFlag->find($flagId);
|
||||
|
||||
// Move to history
|
||||
return $this->moveToHistory($flagData);
|
||||
} catch (\Throwable $e) {
|
||||
log_message('error', 'Close flag error: ' . $e->getMessage());
|
||||
return $this->respondError('Failed to close flag', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel a flag and move it to history
|
||||
*/
|
||||
public function cancelFlag($flagId = null)
|
||||
{
|
||||
$flagId = $flagId ?? $this->request->getPost('id') ?? $this->request->getGet('id');
|
||||
if (!$flagId) {
|
||||
return $this->respondError('Flag ID is required', Response::HTTP_BAD_REQUEST);
|
||||
}
|
||||
|
||||
try {
|
||||
$user = $this->getCurrentUser();
|
||||
$userId = $user->id ?? null;
|
||||
|
||||
// Get the current flag data
|
||||
$flagData = $this->currentFlag->find($flagId);
|
||||
if (!$flagData) {
|
||||
return $this->respondError('Flag not found', Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
// Check if flag is already canceled
|
||||
if ($flagData['flag_state'] === 'Canceled') {
|
||||
return $this->respondError('Flag is already canceled', Response::HTTP_BAD_REQUEST);
|
||||
}
|
||||
|
||||
// Get cancel description from request
|
||||
$data = $this->payloadData();
|
||||
$cancelDescription = $data['state_description'] ?? $data['cancel_description'] ?? null;
|
||||
|
||||
if (empty($cancelDescription)) {
|
||||
return $this->respondError('Cancel description is required', Response::HTTP_BAD_REQUEST);
|
||||
}
|
||||
|
||||
// Update the flag state to Canceled
|
||||
$this->currentFlag->update($flagId, [
|
||||
'flag_state' => 'Canceled',
|
||||
'updated_by_canceled' => $userId,
|
||||
'cancel_description' => $cancelDescription,
|
||||
]);
|
||||
|
||||
// Retrieve updated flag data
|
||||
$flagData = $this->currentFlag->find($flagId);
|
||||
|
||||
// Move to history
|
||||
return $this->moveToHistory($flagData);
|
||||
} catch (\Throwable $e) {
|
||||
log_message('error', 'Cancel flag error: ' . $e->getMessage());
|
||||
return $this->respondError('Failed to cancel flag', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Move flag to history table and delete from current_flag table
|
||||
*/
|
||||
protected function moveToHistory($flagData)
|
||||
{
|
||||
try {
|
||||
// Prepare data for the flag table
|
||||
$dataToInsert = [
|
||||
'student_id' => $flagData['student_id'] ?? null,
|
||||
'student_name' => $flagData['student_name'] ?? null,
|
||||
'grade' => $flagData['grade'] ?? null,
|
||||
'flag' => $flagData['flag'] ?? null,
|
||||
'flag_datetime' => $flagData['flag_datetime'] ?? null,
|
||||
'flag_state' => $flagData['flag_state'] ?? null,
|
||||
'updated_by_open' => $flagData['updated_by_open'] ?? null,
|
||||
'open_description' => $flagData['open_description'] ?? null,
|
||||
'updated_by_closed' => $flagData['updated_by_closed'] ?? null,
|
||||
'close_description' => $flagData['close_description'] ?? null,
|
||||
'updated_by_canceled' => $flagData['updated_by_canceled'] ?? null,
|
||||
'cancel_description' => $flagData['cancel_description'] ?? null,
|
||||
'semester' => $flagData['semester'] ?? null,
|
||||
'school_year' => $flagData['school_year'] ?? null,
|
||||
'created_at' => $flagData['created_at'] ?? date('Y-m-d H:i:s'),
|
||||
'updated_at' => $flagData['updated_at'] ?? date('Y-m-d H:i:s'),
|
||||
];
|
||||
|
||||
// Insert data into the flag table
|
||||
$this->flag->insert($dataToInsert);
|
||||
|
||||
// Delete the entry from the current_flag table
|
||||
$this->currentFlag->delete($flagData['id']);
|
||||
|
||||
return $this->success(['moved_to_history' => true], 'Flag has been moved to history');
|
||||
} catch (\Throwable $e) {
|
||||
log_message('error', 'Move to history error: ' . $e->getMessage());
|
||||
return $this->respondError('Failed to move flag to history', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
public function getStudentsByGrade($gradeId = null)
|
||||
{
|
||||
try {
|
||||
$studentIds = $this->studentClass->newQuery()
|
||||
->where('class_section_id', $gradeId)
|
||||
->pluck('student_id')
|
||||
->toArray();
|
||||
|
||||
if (empty($studentIds)) {
|
||||
return $this->success([], 'No students found for this grade');
|
||||
}
|
||||
|
||||
$students = $this->student->newQuery()
|
||||
->whereIn('id', $studentIds)
|
||||
->get()
|
||||
->map(fn($student) => [
|
||||
'id' => $student->id,
|
||||
'name' => trim(($student->firstname ?? '') . ' ' . ($student->lastname ?? '')),
|
||||
])
|
||||
->values()
|
||||
->toArray();
|
||||
|
||||
return $this->success($students, 'Students retrieved successfully');
|
||||
} catch (\Throwable $e) {
|
||||
log_message('error', 'Get students by grade error: ' . $e->getMessage());
|
||||
return $this->respondError('Failed to retrieve students', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user