add projet
This commit is contained in:
@@ -0,0 +1,330 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Admin;
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Throwable;
|
||||
|
||||
class AdminNotificationService
|
||||
{
|
||||
public function alertsPayload(): array
|
||||
{
|
||||
$admins = $this->fetchAdminNotificationUsers();
|
||||
$subjects = $this->notificationSubjectOptions();
|
||||
$assignedSubjects = [];
|
||||
$tableReady = $this->hasTable('admin_notification_subjects');
|
||||
|
||||
if ($tableReady && !empty($admins)) {
|
||||
$adminIds = array_map('intval', array_column($admins, 'id'));
|
||||
|
||||
$rows = DB::table('admin_notification_subjects')
|
||||
->select('id', 'admin_id', 'subject')
|
||||
->whereIn('admin_id', $adminIds)
|
||||
->get();
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$adminId = (int) ($row->admin_id ?? 0);
|
||||
$subject = (string) ($row->subject ?? '');
|
||||
|
||||
if ($adminId <= 0 || $subject === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$assignedSubjects[$adminId] ??= [];
|
||||
$assignedSubjects[$adminId][$subject] = true;
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'admins' => $admins,
|
||||
'subjects' => $subjects,
|
||||
'assigned_subjects' => $assignedSubjects,
|
||||
'table_ready' => $tableReady,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Input shape (API):
|
||||
* [
|
||||
* 'subjects' => [
|
||||
* 12 => ['finance' => true, 'attendance' => true],
|
||||
* 15 => ['general', 'events']
|
||||
* ]
|
||||
* ]
|
||||
*/
|
||||
public function saveSubjects(array $posted): array
|
||||
{
|
||||
if (!$this->hasTable('admin_notification_subjects')) {
|
||||
return [
|
||||
'ok' => false,
|
||||
'message' => 'Notification subject storage is missing. Run migrations first.',
|
||||
'updated' => 0,
|
||||
];
|
||||
}
|
||||
|
||||
$subjectsMap = $this->notificationSubjectOptions();
|
||||
$allowed = array_keys($subjectsMap);
|
||||
|
||||
$admins = $this->fetchAdminNotificationUsers();
|
||||
$adminIds = array_map('intval', array_column($admins, 'id'));
|
||||
|
||||
if (empty($adminIds)) {
|
||||
return [
|
||||
'ok' => true,
|
||||
'message' => 'No admins found to update.',
|
||||
'updated' => 0,
|
||||
];
|
||||
}
|
||||
|
||||
$existing = DB::table('admin_notification_subjects')
|
||||
->select('id', 'admin_id', 'subject')
|
||||
->whereIn('admin_id', $adminIds)
|
||||
->get();
|
||||
|
||||
$existingMap = [];
|
||||
foreach ($existing as $row) {
|
||||
$adminId = (int) ($row->admin_id ?? 0);
|
||||
$subject = (string) ($row->subject ?? '');
|
||||
if ($adminId <= 0 || $subject === '') {
|
||||
continue;
|
||||
}
|
||||
$existingMap[$adminId] ??= [];
|
||||
$existingMap[$adminId][$subject] = (int) ($row->id ?? 0);
|
||||
}
|
||||
|
||||
$updates = 0;
|
||||
|
||||
DB::transaction(function () use ($posted, $adminIds, $allowed, $existingMap, &$updates) {
|
||||
foreach ($adminIds as $adminId) {
|
||||
$subjectRaw = $posted[$adminId] ?? [];
|
||||
|
||||
$selected = [];
|
||||
if (is_array($subjectRaw)) {
|
||||
foreach ($subjectRaw as $key => $value) {
|
||||
$candidate = is_string($key) ? $key : $value;
|
||||
if (!is_string($candidate)) {
|
||||
continue;
|
||||
}
|
||||
$candidate = trim($candidate);
|
||||
if ($candidate !== '') {
|
||||
$selected[] = $candidate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$selected = array_values(array_unique(array_filter(
|
||||
$selected,
|
||||
fn ($value) => in_array($value, $allowed, true)
|
||||
)));
|
||||
|
||||
$current = array_keys($existingMap[$adminId] ?? []);
|
||||
$toDelete = array_values(array_diff($current, $selected));
|
||||
$toInsert = array_values(array_diff($selected, $current));
|
||||
|
||||
if (!empty($toDelete)) {
|
||||
DB::table('admin_notification_subjects')
|
||||
->where('admin_id', $adminId)
|
||||
->whereIn('subject', $toDelete)
|
||||
->delete();
|
||||
|
||||
$updates += count($toDelete);
|
||||
}
|
||||
|
||||
if (!empty($toInsert)) {
|
||||
$batch = [];
|
||||
foreach ($toInsert as $subject) {
|
||||
$batch[] = [
|
||||
'admin_id' => $adminId,
|
||||
'subject' => $subject,
|
||||
];
|
||||
}
|
||||
|
||||
DB::table('admin_notification_subjects')->insert($batch);
|
||||
$updates += count($toInsert);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return [
|
||||
'ok' => true,
|
||||
'message' => $updates > 0 ? 'Notification subjects updated.' : 'No changes were made.',
|
||||
'updated' => $updates,
|
||||
];
|
||||
}
|
||||
|
||||
public function printRecipientsPayload(): array
|
||||
{
|
||||
$admins = $this->fetchAdminNotificationUsers();
|
||||
$tableReady = $this->hasTable('admin_notification_subjects');
|
||||
$assigned = [];
|
||||
|
||||
if ($tableReady && !empty($admins)) {
|
||||
$adminIds = array_map('intval', array_column($admins, 'id'));
|
||||
|
||||
$rows = DB::table('admin_notification_subjects')
|
||||
->select('admin_id')
|
||||
->where('subject', 'print_requests')
|
||||
->whereIn('admin_id', $adminIds)
|
||||
->get();
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$adminId = (int) ($row->admin_id ?? 0);
|
||||
if ($adminId > 0) {
|
||||
$assigned[$adminId] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'admins' => $admins,
|
||||
'assigned' => $assigned,
|
||||
'table_ready' => $tableReady,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Input shape (API):
|
||||
* ['notify' => [12 => true, 15 => true]]
|
||||
*/
|
||||
public function savePrintRecipients(array $postedNotify): array
|
||||
{
|
||||
if (!$this->hasTable('admin_notification_subjects')) {
|
||||
return [
|
||||
'ok' => false,
|
||||
'message' => 'Notification subject storage is missing. Run migrations first.',
|
||||
'updated' => 0,
|
||||
];
|
||||
}
|
||||
|
||||
$admins = $this->fetchAdminNotificationUsers();
|
||||
$adminIds = array_map('intval', array_column($admins, 'id'));
|
||||
|
||||
if (empty($adminIds)) {
|
||||
return [
|
||||
'ok' => true,
|
||||
'message' => 'No admins found to update.',
|
||||
'updated' => 0,
|
||||
];
|
||||
}
|
||||
|
||||
$selected = [];
|
||||
foreach ((array) $postedNotify as $key => $value) {
|
||||
$adminId = (int) $key;
|
||||
if ($adminId <= 0) continue;
|
||||
if (!in_array($adminId, $adminIds, true)) continue;
|
||||
$selected[] = $adminId;
|
||||
}
|
||||
$selected = array_values(array_unique($selected));
|
||||
|
||||
$existingRows = DB::table('admin_notification_subjects')
|
||||
->select('admin_id')
|
||||
->where('subject', 'print_requests')
|
||||
->whereIn('admin_id', $adminIds)
|
||||
->get();
|
||||
|
||||
$current = array_values(array_unique(array_map(
|
||||
fn ($row) => (int) ($row->admin_id ?? 0),
|
||||
$existingRows->all()
|
||||
)));
|
||||
|
||||
$toDelete = array_values(array_diff($current, $selected));
|
||||
$toInsert = array_values(array_diff($selected, $current));
|
||||
|
||||
DB::transaction(function () use ($toDelete, $toInsert) {
|
||||
if (!empty($toDelete)) {
|
||||
DB::table('admin_notification_subjects')
|
||||
->where('subject', 'print_requests')
|
||||
->whereIn('admin_id', $toDelete)
|
||||
->delete();
|
||||
}
|
||||
|
||||
if (!empty($toInsert)) {
|
||||
$batch = [];
|
||||
foreach ($toInsert as $adminId) {
|
||||
$batch[] = [
|
||||
'admin_id' => $adminId,
|
||||
'subject' => 'print_requests',
|
||||
];
|
||||
}
|
||||
DB::table('admin_notification_subjects')->insert($batch);
|
||||
}
|
||||
});
|
||||
|
||||
$changes = count($toDelete) + count($toInsert);
|
||||
|
||||
return [
|
||||
'ok' => true,
|
||||
'message' => $changes > 0 ? 'Print notification recipients updated.' : 'No changes were made.',
|
||||
'updated' => $changes,
|
||||
'selected_admin_ids' => $selected,
|
||||
];
|
||||
}
|
||||
|
||||
public function notificationSubjectOptions(): array
|
||||
{
|
||||
return [
|
||||
'academics' => 'Academics',
|
||||
'attendance' => 'Attendance',
|
||||
'events' => 'Events',
|
||||
'finance' => 'Finance',
|
||||
'general' => 'General',
|
||||
'print_requests' => 'Print Requests',
|
||||
];
|
||||
}
|
||||
|
||||
private function getAdminNotificationExcludedRoles(): array
|
||||
{
|
||||
return [
|
||||
'parent',
|
||||
'student',
|
||||
'guest',
|
||||
'teacher',
|
||||
'assistant teacher',
|
||||
'teacher assistant',
|
||||
'teacher_assistant',
|
||||
'assistant_teacher',
|
||||
'ta',
|
||||
'authorized_user',
|
||||
];
|
||||
}
|
||||
|
||||
public function fetchAdminNotificationUsers(): array
|
||||
{
|
||||
$excluded = array_map(
|
||||
fn ($value) => strtolower(trim((string) $value)),
|
||||
$this->getAdminNotificationExcludedRoles()
|
||||
);
|
||||
|
||||
// Safer than raw NOT IN string: use bindings + lower(name)
|
||||
$rows = DB::table('users as u')
|
||||
->select('u.id', 'u.firstname', 'u.lastname', 'u.email')
|
||||
->join('user_roles as ur', 'ur.user_id', '=', 'u.id')
|
||||
->join('roles as r', 'r.id', '=', 'ur.role_id')
|
||||
->whereNull('ur.deleted_at')
|
||||
->whereNotNull('r.name')
|
||||
->whereNotIn(DB::raw('LOWER(r.name)'), $excluded)
|
||||
->groupBy('u.id', 'u.firstname', 'u.lastname', 'u.email')
|
||||
->orderBy('u.lastname')
|
||||
->orderBy('u.firstname')
|
||||
->get();
|
||||
|
||||
return $rows->map(function ($row) {
|
||||
return [
|
||||
'id' => (int) $row->id,
|
||||
'firstname' => (string) ($row->firstname ?? ''),
|
||||
'lastname' => (string) ($row->lastname ?? ''),
|
||||
'email' => (string) ($row->email ?? ''),
|
||||
'full_name' => trim((string)($row->firstname ?? '') . ' ' . (string)($row->lastname ?? '')),
|
||||
];
|
||||
})->all();
|
||||
}
|
||||
|
||||
private function hasTable(string $table): bool
|
||||
{
|
||||
try {
|
||||
return DB::getSchemaBuilder()->hasTable($table);
|
||||
} catch (Throwable) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user