feat: notifikasi + push Informasi Sekolah ke semua wali (broadcast, dedupe per hari)
This commit is contained in:
@@ -3,9 +3,14 @@
|
|||||||
namespace App\Http\Controllers\Admin;
|
namespace App\Http\Controllers\Admin;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\ParentDevice;
|
||||||
|
use App\Models\ParentStudent;
|
||||||
use App\Models\SchoolInformation;
|
use App\Models\SchoolInformation;
|
||||||
|
use App\Models\ViolationNotification;
|
||||||
|
use App\Services\FcmService;
|
||||||
use Illuminate\Http\RedirectResponse;
|
use Illuminate\Http\RedirectResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
use Illuminate\View\View;
|
use Illuminate\View\View;
|
||||||
|
|
||||||
class SchoolInformationController extends Controller
|
class SchoolInformationController extends Controller
|
||||||
@@ -27,6 +32,10 @@ class SchoolInformationController extends Controller
|
|||||||
|
|
||||||
SchoolInformation::create($validated + ['created_by' => $request->user()->id]);
|
SchoolInformation::create($validated + ['created_by' => $request->user()->id]);
|
||||||
|
|
||||||
|
if ($validated['is_published'] ?? false) {
|
||||||
|
$this->notifyParents($validated['title']);
|
||||||
|
}
|
||||||
|
|
||||||
return back()->with('success', 'Informasi "'.$validated['title'].'" berhasil dipublikasikan.');
|
return back()->with('success', 'Informasi "'.$validated['title'].'" berhasil dipublikasikan.');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,6 +46,10 @@ class SchoolInformationController extends Controller
|
|||||||
|
|
||||||
$info->update($validated);
|
$info->update($validated);
|
||||||
|
|
||||||
|
if ($validated['is_published'] ?? false) {
|
||||||
|
$this->notifyParents($validated['title']);
|
||||||
|
}
|
||||||
|
|
||||||
return back()->with('success', 'Informasi berhasil diperbarui.');
|
return back()->with('success', 'Informasi berhasil diperbarui.');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,4 +71,49 @@ class SchoolInformationController extends Controller
|
|||||||
'is_published' => ['nullable', 'boolean'],
|
'is_published' => ['nullable', 'boolean'],
|
||||||
]) + ['is_published' => $request->boolean('is_published')];
|
]) + ['is_published' => $request->boolean('is_published')];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kirim notifikasi + push informasi sekolah ke semua wali (broadcast).
|
||||||
|
* Dedupe: satu notifikasi per judul per hari.
|
||||||
|
*/
|
||||||
|
protected function notifyParents(string $title): void
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$message = 'Informasi Sekolah: '.$title;
|
||||||
|
|
||||||
|
$already = ViolationNotification::where('channel', 'info')
|
||||||
|
->where('message', $message)
|
||||||
|
->whereDate('created_at', today())
|
||||||
|
->exists();
|
||||||
|
if ($already) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$parentIds = ParentStudent::where('status', 'active')
|
||||||
|
->distinct()
|
||||||
|
->pluck('user_id');
|
||||||
|
|
||||||
|
foreach ($parentIds as $userId) {
|
||||||
|
ViolationNotification::create([
|
||||||
|
'student_id' => null,
|
||||||
|
'channel' => 'info',
|
||||||
|
'recipient' => 'Semua Wali',
|
||||||
|
'message' => $message,
|
||||||
|
'status' => 'sent',
|
||||||
|
'user_id' => $userId,
|
||||||
|
'created_at' => now(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$tokens = ParentDevice::where('user_id', $userId)->pluck('fcm_token');
|
||||||
|
foreach ($tokens as $token) {
|
||||||
|
app(FcmService::class)->sendToToken($token, [
|
||||||
|
'title' => '📢 Informasi Sekolah',
|
||||||
|
'body' => $title,
|
||||||
|
], ['type' => 'school_info', 'title' => $title]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
Log::error('Notif info sekolah gagal: '.$e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,13 @@ class ParentNotificationController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
$notifications = ViolationNotification::query()
|
$notifications = ViolationNotification::query()
|
||||||
->whereIn('student_id', $studentIds)
|
->where(function ($q) use ($studentIds) {
|
||||||
|
$q->whereIn('student_id', $studentIds)
|
||||||
|
->orWhere(function ($q2) use ($studentIds) {
|
||||||
|
// Info sekolah (broadcast): student_id null, per user
|
||||||
|
$q2->whereNull('student_id')->where('user_id', auth()->id());
|
||||||
|
});
|
||||||
|
})
|
||||||
->with('student:id,full_name,class_name')
|
->with('student:id,full_name,class_name')
|
||||||
->orderByDesc('created_at')
|
->orderByDesc('created_at')
|
||||||
->limit(50)
|
->limit(50)
|
||||||
@@ -69,8 +75,13 @@ class ParentNotificationController extends Controller
|
|||||||
return response()->json(['count' => 0]);
|
return response()->json(['count' => 0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$count = ViolationNotification::whereIn('student_id', $studentIds)
|
$count = ViolationNotification::where(function ($q) use ($studentIds) {
|
||||||
->where('channel', 'push') // pelanggaran & SP (bukan kehadiran)
|
$q->whereIn('student_id', $studentIds)
|
||||||
|
->orWhere(function ($q2) {
|
||||||
|
$q2->whereNull('student_id')->where('user_id', auth()->id());
|
||||||
|
});
|
||||||
|
})
|
||||||
|
->whereIn('channel', ['push', 'info']) // pelanggaran, SP, info sekolah
|
||||||
->where('is_read', false)
|
->where('is_read', false)
|
||||||
->count();
|
->count();
|
||||||
|
|
||||||
@@ -89,7 +100,12 @@ class ParentNotificationController extends Controller
|
|||||||
|
|
||||||
$updated = 0;
|
$updated = 0;
|
||||||
if (! empty($studentIds)) {
|
if (! empty($studentIds)) {
|
||||||
$updated = ViolationNotification::whereIn('student_id', $studentIds)
|
$updated = ViolationNotification::where(function ($q) use ($studentIds) {
|
||||||
|
$q->whereIn('student_id', $studentIds)
|
||||||
|
->orWhere(function ($q2) {
|
||||||
|
$q2->whereNull('student_id')->where('user_id', auth()->id());
|
||||||
|
});
|
||||||
|
})
|
||||||
->where('is_read', false)
|
->where('is_read', false)
|
||||||
->update(['is_read' => true, 'read_at' => now()]);
|
->update(['is_read' => true, 'read_at' => now()]);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user