940afe9319
API CI/CD / Validate (composer + pint) (push) Successful in 2m7s
API CI/CD / Test (PHPUnit) (push) Failing after 2m23s
API CI/CD / Build frontend assets (push) Successful in 2m18s
API CI/CD / Security audit (push) Successful in 31s
API CI/CD / Deploy to shared hosting (PHP) (push) Has been skipped
238 lines
7.9 KiB
PHP
238 lines
7.9 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Badges;
|
|
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Schema;
|
|
|
|
class BadgeUserLookupService
|
|
{
|
|
public function __construct(
|
|
protected BadgeTextFormatter $formatter
|
|
) {}
|
|
|
|
public function fetchStaffList(?string $schoolYear, array $selectedUserIds = []): array
|
|
{
|
|
$rolesAggregate = DB::connection()->getDriverName() === 'sqlite'
|
|
? "GROUP_CONCAT(DISTINCT CASE WHEN LOWER(roles.name) != 'parent' THEN roles.name END) as roles"
|
|
: "GROUP_CONCAT(DISTINCT CASE WHEN LOWER(roles.name) != 'parent' THEN roles.name END ORDER BY roles.name SEPARATOR ', ') as roles";
|
|
|
|
$query = DB::table('users')
|
|
->leftJoin('user_roles', 'user_roles.user_id', '=', 'users.id')
|
|
->leftJoin('roles', 'roles.id', '=', 'user_roles.role_id')
|
|
->select([
|
|
'users.id',
|
|
'users.firstname',
|
|
'users.lastname',
|
|
DB::raw($rolesAggregate),
|
|
])
|
|
->groupBy('users.id', 'users.firstname', 'users.lastname');
|
|
|
|
if (! empty($selectedUserIds)) {
|
|
$query->whereIn('users.id', $selectedUserIds);
|
|
}
|
|
|
|
if (Schema::hasColumn('user_roles', 'deleted_at')) {
|
|
$query->whereNull('user_roles.deleted_at');
|
|
}
|
|
|
|
$rows = array_map(static fn ($row) => (array) $row, $query->get()->all());
|
|
|
|
return array_values(array_filter($rows, static function (array $row): bool {
|
|
$roles = strtolower(trim((string) ($row['roles'] ?? '')));
|
|
|
|
if ($roles === '') {
|
|
return false;
|
|
}
|
|
|
|
$parts = array_values(array_filter(array_map('trim', explode(',', $roles))));
|
|
foreach ($parts as $part) {
|
|
if (in_array($part, ['parent', 'student'], true)) {
|
|
continue;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}));
|
|
}
|
|
|
|
public function getLatestClassForUser(int $userId, ?string $schoolYear = null): ?array
|
|
{
|
|
$query = DB::table('teacher_class as tc')
|
|
->leftJoin('classSection as cs', 'cs.class_section_id', '=', 'tc.class_section_id')
|
|
->select([
|
|
'tc.class_section_id',
|
|
'cs.class_section_name',
|
|
])
|
|
->where('tc.teacher_id', $userId);
|
|
|
|
if (! empty($schoolYear)) {
|
|
$query->where('tc.school_year', $schoolYear);
|
|
}
|
|
|
|
$row = $query
|
|
->orderByRaw("CASE tc.position WHEN 'main' THEN 0 WHEN 'ta' THEN 1 ELSE 2 END")
|
|
->orderByRaw('IFNULL(tc.updated_at,"0000-00-00 00:00:00") DESC')
|
|
->orderByDesc('tc.id')
|
|
->first();
|
|
|
|
if (! $row || empty($row->class_section_id)) {
|
|
return null;
|
|
}
|
|
|
|
return [
|
|
'class_section_id' => (int) $row->class_section_id,
|
|
'class_section_name' => $row->class_section_name ?? null,
|
|
];
|
|
}
|
|
|
|
public function getUserInfoById(int $id, ?string $schoolYear = null): ?array
|
|
{
|
|
$u = DB::table('users')
|
|
->select(['id as user_id', 'firstname', 'lastname', 'school_id', 'account_id'])
|
|
->where('id', $id)
|
|
->first();
|
|
|
|
if (! $u) {
|
|
return null;
|
|
}
|
|
|
|
$userId = (int) $u->user_id;
|
|
$fullname = trim(($u->firstname ?? '').' '.($u->lastname ?? ''));
|
|
$schoolId = trim((string) ($u->school_id ?? ''));
|
|
if ($schoolId === '') {
|
|
$schoolId = trim((string) ($u->account_id ?? ''));
|
|
}
|
|
|
|
$rolesRows = DB::table('user_roles as ur')
|
|
->join('roles as r', 'r.id', '=', 'ur.role_id')
|
|
->select(['r.id as role_id', 'r.name as role_name'])
|
|
->where('ur.user_id', $userId)
|
|
->get();
|
|
|
|
$allRoles = [];
|
|
foreach ($rolesRows as $rr) {
|
|
$name = trim((string) ($rr->role_name ?? ''));
|
|
if ($name !== '' && strtolower($name) !== 'parent') {
|
|
$allRoles[] = ucwords(strtolower($name));
|
|
}
|
|
}
|
|
|
|
$allRoles = array_values(array_unique($allRoles));
|
|
$rolesCsv = $allRoles ? implode(', ', $allRoles) : '';
|
|
|
|
$tcQuery = DB::table('teacher_class')
|
|
->select(['class_section_id', 'updated_at', 'id', 'position', 'school_year'])
|
|
->where('teacher_id', $userId);
|
|
|
|
if (! empty($schoolYear)) {
|
|
$tcQuery->where('school_year', $schoolYear);
|
|
}
|
|
|
|
$assignment = $tcQuery
|
|
->orderByRaw('IFNULL(updated_at, "1970-01-01 00:00:00") DESC, id DESC')
|
|
->first();
|
|
|
|
$classId = $assignment->class_section_id ?? null;
|
|
$position = strtolower(trim((string) ($assignment->position ?? '')));
|
|
$className = null;
|
|
|
|
if (! empty($classId)) {
|
|
$className = $this->resolveClassName((int) $classId);
|
|
}
|
|
|
|
if (in_array($position, ['ta', 'teacher_assistant', 'assistant'], true)) {
|
|
$roleLabel = 'Teacher Assistant';
|
|
} elseif ($position === 'teacher' || $position === 'main') {
|
|
$roleLabel = 'Teacher';
|
|
} elseif (! empty($allRoles)) {
|
|
$roleLabel = $allRoles[0];
|
|
} else {
|
|
$roleLabel = 'Staff';
|
|
}
|
|
|
|
$schoolLogo = $this->formatter->firstExisting([
|
|
public_path('assets/images/school_logo.png'),
|
|
public_path('assets/images/logo.png'),
|
|
]);
|
|
|
|
$isglLogo = $this->formatter->firstExisting([
|
|
public_path('assets/images/isgl_logo.png'),
|
|
public_path('assets/images/isgl.png'),
|
|
]);
|
|
|
|
$jobTitle = '';
|
|
if (! empty($roleLabel) && ! empty($className)) {
|
|
$jobTitle = "{$roleLabel} - {$className}";
|
|
} elseif (! empty($roleLabel)) {
|
|
$jobTitle = $roleLabel;
|
|
} elseif (! empty($className)) {
|
|
$jobTitle = $className;
|
|
}
|
|
|
|
return [
|
|
'user_id' => $userId,
|
|
'name' => $fullname !== '' ? $fullname : 'STAFF',
|
|
'role' => $roleLabel,
|
|
'roles' => $rolesCsv,
|
|
'class_section_id' => $classId ? (int) $classId : null,
|
|
'class_section_name' => $className,
|
|
'job_title' => $jobTitle,
|
|
'school_name' => 'Al Rahma Sunday School',
|
|
'school_id' => $schoolId,
|
|
'school_logo' => $schoolLogo,
|
|
'isgl_logo' => $isglLogo,
|
|
'school_year' => $assignment->school_year ?? $schoolYear,
|
|
];
|
|
}
|
|
|
|
public function getAvailableSchoolYears(): array
|
|
{
|
|
$schoolYears = [];
|
|
|
|
try {
|
|
if (Schema::hasTable('teacher_class')) {
|
|
$schoolYears = DB::table('teacher_class')
|
|
->selectRaw('DISTINCT school_year')
|
|
->whereNotNull('school_year')
|
|
->orderByDesc('school_year')
|
|
->pluck('school_year')
|
|
->filter()
|
|
->values()
|
|
->all();
|
|
}
|
|
} catch (\Throwable) {
|
|
}
|
|
|
|
if (empty($schoolYears)) {
|
|
try {
|
|
if (Schema::hasTable('user_roles') && Schema::hasColumn('user_roles', 'school_year')) {
|
|
$schoolYears = DB::table('user_roles')
|
|
->selectRaw('DISTINCT school_year')
|
|
->whereNotNull('school_year')
|
|
->orderByDesc('school_year')
|
|
->pluck('school_year')
|
|
->filter()
|
|
->values()
|
|
->all();
|
|
}
|
|
} catch (\Throwable) {
|
|
}
|
|
}
|
|
|
|
return $schoolYears;
|
|
}
|
|
|
|
protected function resolveClassName(int $classSectionId): ?string
|
|
{
|
|
$row = DB::table('classSection')
|
|
->select('class_section_name')
|
|
->where('class_section_id', $classSectionId)
|
|
->first();
|
|
|
|
return $row->class_section_name ?? null;
|
|
}
|
|
}
|