add projet
This commit is contained in:
Executable
+244
@@ -0,0 +1,244 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Models\Configuration;
|
||||
use App\Models\Staff;
|
||||
use App\Models\TeacherClass;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class StaffController extends BaseApiController
|
||||
{
|
||||
protected Staff $staff;
|
||||
protected User $user;
|
||||
protected TeacherClass $teacherClass;
|
||||
protected Configuration $config;
|
||||
protected string $schoolYear;
|
||||
protected string $semester;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->staff = model(Staff::class);
|
||||
$this->user = model(User::class);
|
||||
$this->teacherClass = model(TeacherClass::class);
|
||||
$this->config = model(Configuration::class);
|
||||
$this->schoolYear = (string) ($this->config->getConfig('school_year') ?? '');
|
||||
$this->semester = (string) ($this->config->getConfig('semester') ?? '');
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$page = max(1, (int) ($this->request->getGet('page') ?? 1));
|
||||
$perPage = min(100, max(1, (int) ($this->request->getGet('per_page') ?? 20)));
|
||||
$role = $this->request->getGet('role');
|
||||
|
||||
// Roles we never show
|
||||
$excludedRoles = ['student', 'parent', 'guest', 'inactive'];
|
||||
$normalizedExcluded = array_map('strtolower', $excludedRoles);
|
||||
|
||||
$placeholders = implode(',', array_fill(0, count($normalizedExcluded), '?'));
|
||||
|
||||
$query = $this->staff->newQuery()
|
||||
->whereRaw('LOWER(active_role) NOT IN (' . $placeholders . ')', $normalizedExcluded);
|
||||
|
||||
if (!empty($role)) {
|
||||
$query->whereRaw('LOWER(active_role) = ?', [strtolower((string) $role)]);
|
||||
}
|
||||
|
||||
$query->orderByDesc('created_at');
|
||||
|
||||
// Preload assignments for the selected school year (across all semesters)
|
||||
$assignRows = DB::table('teacher_class as tc')
|
||||
->select('tc.teacher_id', 'tc.position', 'cs.class_section_name')
|
||||
->leftJoin('classSection as cs', 'cs.class_section_id', '=', 'tc.class_section_id')
|
||||
->where('tc.school_year', (string) $this->schoolYear)
|
||||
->get()
|
||||
->toArray();
|
||||
|
||||
$assignByTeacher = [];
|
||||
foreach ($assignRows as $row) {
|
||||
$teacherId = (int) ($row->teacher_id ?? 0);
|
||||
if ($teacherId <= 0) {
|
||||
continue;
|
||||
}
|
||||
$section = trim((string) ($row->class_section_name ?? ''));
|
||||
if ($section === '') {
|
||||
continue;
|
||||
}
|
||||
$position = strtolower((string) ($row->position ?? ''));
|
||||
if (!in_array($position, ['main', 'ta'], true)) {
|
||||
continue;
|
||||
}
|
||||
$assignByTeacher[$teacherId][] = $section . ' (' . $position . ')';
|
||||
}
|
||||
|
||||
// Get all staff (not paginated) for issues count calculation
|
||||
$allStaff = $query->get()->toArray();
|
||||
$issuesCount = 0;
|
||||
|
||||
foreach ($allStaff as $staff) {
|
||||
$roleName = strtolower((string) ($staff['active_role'] ?? ''));
|
||||
if (in_array($roleName, ['teacher', 'teacher_assistant'], true)) {
|
||||
$userId = (int) ($staff['user_id'] ?? 0);
|
||||
$labels = $assignByTeacher[$userId] ?? [];
|
||||
if (empty($labels)) {
|
||||
$issuesCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Paginate the results
|
||||
$result = $this->paginate($query, $page, $perPage);
|
||||
|
||||
// Apply transformations to paginated data
|
||||
foreach ($result['data'] as &$staff) {
|
||||
$userId = (int) ($staff['user_id'] ?? 0);
|
||||
$staff['school_id'] = $userId > 0 ? $this->user->getSchoolIdByUserId($userId) : null;
|
||||
|
||||
$roleName = strtolower((string) ($staff['active_role'] ?? ''));
|
||||
if (in_array($roleName, ['teacher', 'teacher_assistant'], true)) {
|
||||
$labels = $assignByTeacher[$userId] ?? [];
|
||||
if (!empty($labels)) {
|
||||
$staff['class_section'] = implode(', ', array_unique($labels));
|
||||
$staff['verification_issue'] = false;
|
||||
} else {
|
||||
$staff['class_section'] = 'No class assigned';
|
||||
$staff['verification_issue'] = true;
|
||||
}
|
||||
} else {
|
||||
$staff['class_section'] = '—';
|
||||
$staff['verification_issue'] = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->success([
|
||||
'data' => $result['data'],
|
||||
'pagination' => $result['pagination'],
|
||||
'issues_count' => $issuesCount,
|
||||
'semester' => $this->semester,
|
||||
'school_year' => $this->schoolYear,
|
||||
], 'Staff members retrieved successfully');
|
||||
}
|
||||
|
||||
public function show($id = null)
|
||||
{
|
||||
$staff = $this->staff->find($id);
|
||||
if (!$staff) {
|
||||
return $this->respondError('Staff member not found', Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
$staff['school_id'] = $this->user->getSchoolIdByUserId((int) ($staff['user_id'] ?? 0));
|
||||
|
||||
return $this->success($staff, 'Staff member retrieved successfully');
|
||||
}
|
||||
|
||||
public function store()
|
||||
{
|
||||
$data = $this->payloadData();
|
||||
if (empty($data)) {
|
||||
return $this->respondError('Invalid request data', Response::HTTP_BAD_REQUEST);
|
||||
}
|
||||
|
||||
$now = utc_now();
|
||||
$payload = [
|
||||
'firstname' => trim((string) ($data['firstname'] ?? '')),
|
||||
'lastname' => trim((string) ($data['lastname'] ?? '')),
|
||||
'email' => trim((string) ($data['email'] ?? '')),
|
||||
'phone' => trim((string) ($data['phone'] ?? '')),
|
||||
'role_name' => trim((string) ($data['role_name'] ?? '')),
|
||||
'school_year' => trim((string) ($data['school_year'] ?? $this->schoolYear)),
|
||||
'status' => trim((string) ($data['status'] ?? 'Active')),
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
];
|
||||
|
||||
// Set active_role from role_name if provided
|
||||
if (!empty($payload['role_name'])) {
|
||||
$payload['active_role'] = strtolower($payload['role_name']);
|
||||
}
|
||||
|
||||
try {
|
||||
$inserted = $this->staff->insert($payload);
|
||||
if (!$inserted) {
|
||||
return $this->respondError('Failed to create staff member', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
// Fetch the created record
|
||||
$staff = $this->staff->where('created_at', $now)->orderBy('id', 'DESC')->first();
|
||||
return $this->success($staff, 'Staff member added successfully', Response::HTTP_CREATED);
|
||||
} catch (\Throwable $e) {
|
||||
\Illuminate\Support\Facades\Log::error('Staff creation error: ' . $e->getMessage());
|
||||
return $this->respondError('Failed to create staff member', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
public function update($id = null)
|
||||
{
|
||||
$staff = $this->staff->find($id);
|
||||
if (!$staff) {
|
||||
return $this->respondError('Staff member not found', Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
$data = $this->payloadData();
|
||||
if (empty($data)) {
|
||||
return $this->respondError('Invalid request data', Response::HTTP_BAD_REQUEST);
|
||||
}
|
||||
|
||||
// Only update fields provided by the request to avoid wiping data
|
||||
$updateData = [];
|
||||
$allowedFields = ['firstname', 'lastname', 'email', 'phone', 'role_name', 'school_year', 'status'];
|
||||
|
||||
foreach ($allowedFields as $field) {
|
||||
if (array_key_exists($field, $data)) {
|
||||
$value = $data[$field];
|
||||
if ($value !== null && $value !== '') {
|
||||
$updateData[$field] = trim((string) $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set active_role from role_name if role_name is being updated
|
||||
if (isset($updateData['role_name']) && !empty($updateData['role_name'])) {
|
||||
$updateData['active_role'] = strtolower($updateData['role_name']);
|
||||
}
|
||||
|
||||
// Always bump updated_at
|
||||
$updateData['updated_at'] = utc_now();
|
||||
|
||||
if (empty($updateData)) {
|
||||
return $this->respondError('No changes detected', Response::HTTP_BAD_REQUEST);
|
||||
}
|
||||
|
||||
try {
|
||||
$updated = $this->staff->update($id, $updateData);
|
||||
if (!$updated) {
|
||||
return $this->respondError('Failed to update staff member', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
$updatedStaff = $this->staff->find($id);
|
||||
return $this->success($updatedStaff, 'Staff member updated successfully');
|
||||
} catch (\Throwable $e) {
|
||||
\Illuminate\Support\Facades\Log::error('Staff update error: ' . $e->getMessage());
|
||||
return $this->respondError('Failed to update staff member', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
public function destroy($id = null)
|
||||
{
|
||||
$staff = $this->staff->find($id);
|
||||
if (!$staff) {
|
||||
return $this->respondError('Staff member not found', Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
try {
|
||||
$this->staff->delete($id);
|
||||
return $this->respondDeleted(null, 'Staff member deleted successfully');
|
||||
} catch (\Throwable $e) {
|
||||
\Illuminate\Support\Facades\Log::error('Staff deletion error: ' . $e->getMessage());
|
||||
return $this->respondError('Failed to delete staff member', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user