add controllers, servoices
This commit is contained in:
@@ -0,0 +1,233 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Incidents;
|
||||
|
||||
use App\Models\Configuration;
|
||||
use App\Models\CurrentIncident;
|
||||
use App\Models\Incident;
|
||||
use App\Models\Student;
|
||||
use App\Models\StudentClass;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class CurrentIncidentService
|
||||
{
|
||||
public function __construct(private IncidentLookupService $lookup)
|
||||
{
|
||||
}
|
||||
|
||||
public function listCurrent(): array
|
||||
{
|
||||
$incidents = CurrentIncident::query()->get()->map(fn ($row) => $row->toArray())->all();
|
||||
$schoolYear = Configuration::getConfig('school_year');
|
||||
|
||||
$updaterIds = [];
|
||||
foreach ($incidents as $incident) {
|
||||
foreach (['updated_by_open', 'updated_by_closed', 'updated_by_canceled'] as $key) {
|
||||
if (!empty($incident[$key])) {
|
||||
$updaterIds[] = (int) $incident[$key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$updaterMap = $this->lookup->updaterNameMap($updaterIds);
|
||||
foreach ($incidents as &$incident) {
|
||||
foreach (['updated_by_open', 'updated_by_closed', 'updated_by_canceled'] as $key) {
|
||||
$id = (int) ($incident[$key] ?? 0);
|
||||
$incident[$key . '_name'] = $id > 0 ? ($updaterMap[$id] ?? null) : null;
|
||||
}
|
||||
}
|
||||
unset($incident);
|
||||
|
||||
return [
|
||||
'incidents' => $incidents,
|
||||
'grades' => $this->lookup->gradeOptionsWithActiveStudents($schoolYear),
|
||||
];
|
||||
}
|
||||
|
||||
public function studentsByGrade(int $gradeId): array
|
||||
{
|
||||
$studentIds = StudentClass::query()
|
||||
->active()
|
||||
->where('student_class.class_section_id', $gradeId)
|
||||
->pluck('student_id')
|
||||
->all();
|
||||
|
||||
if (empty($studentIds)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return Student::query()
|
||||
->whereIn('id', $studentIds)
|
||||
->where('is_active', 1)
|
||||
->get()
|
||||
->map(fn ($student) => [
|
||||
'id' => (int) $student->id,
|
||||
'name' => trim((string) $student->firstname . ' ' . (string) $student->lastname),
|
||||
])
|
||||
->all();
|
||||
}
|
||||
|
||||
public function addIncident(array $payload, int $userId): array
|
||||
{
|
||||
$studentId = (int) $payload['student_id'];
|
||||
$incidentType = (string) $payload['incident'];
|
||||
$description = (string) ($payload['description'] ?? '');
|
||||
$incidentState = (string) ($payload['incident_state'] ?? 'Open');
|
||||
$stateDescription = (string) ($payload['state_description'] ?? '');
|
||||
$grade = (string) $payload['grade'];
|
||||
|
||||
$student = Student::query()->find($studentId);
|
||||
if (!$student) {
|
||||
return [
|
||||
'ok' => false,
|
||||
'message' => 'Student not found.',
|
||||
];
|
||||
}
|
||||
|
||||
$semester = Configuration::getConfig('semester');
|
||||
$schoolYear = Configuration::getConfig('school_year');
|
||||
$currentDateTime = function_exists('utc_now') ? utc_now() : now('UTC')->toDateTimeString();
|
||||
|
||||
$existingIncident = CurrentIncident::query()
|
||||
->where('student_id', $studentId)
|
||||
->where('incident', $incidentType)
|
||||
->first();
|
||||
|
||||
if ($existingIncident) {
|
||||
$data = [
|
||||
'incident_datetime' => $currentDateTime,
|
||||
'updated_by_open' => $userId,
|
||||
];
|
||||
|
||||
if ($incidentState === 'Closed') {
|
||||
$data['incident_state'] = 'Closed';
|
||||
$data['close_description'] = $this->appendLine($existingIncident->close_description ?? '', $stateDescription);
|
||||
} elseif ($incidentState === 'Canceled') {
|
||||
$data['incident_state'] = 'Canceled';
|
||||
$data['cancel_description'] = $this->appendLine($existingIncident->cancel_description ?? '', $stateDescription);
|
||||
} else {
|
||||
$data['open_description'] = $this->appendLine($existingIncident->open_description ?? '', $description);
|
||||
}
|
||||
|
||||
$existingIncident->fill($data);
|
||||
$existingIncident->save();
|
||||
|
||||
return [
|
||||
'ok' => true,
|
||||
'created' => false,
|
||||
'incident_id' => (int) $existingIncident->id,
|
||||
];
|
||||
}
|
||||
|
||||
$incident = CurrentIncident::query()->create([
|
||||
'student_id' => $student->id,
|
||||
'student_name' => trim((string) $student->firstname . ' ' . (string) $student->lastname),
|
||||
'grade' => $grade,
|
||||
'incident' => $incidentType,
|
||||
'incident_datetime' => $currentDateTime,
|
||||
'incident_state' => 'Open',
|
||||
'updated_by_open' => $userId,
|
||||
'open_description' => $description,
|
||||
'semester' => $semester,
|
||||
'school_year' => $schoolYear,
|
||||
]);
|
||||
|
||||
return [
|
||||
'ok' => true,
|
||||
'created' => true,
|
||||
'incident_id' => (int) $incident->id,
|
||||
];
|
||||
}
|
||||
|
||||
public function updateState(int $incidentId, string $newState): bool
|
||||
{
|
||||
return CurrentIncident::query()->whereKey($incidentId)->update([
|
||||
'incident_state' => $newState,
|
||||
]) > 0;
|
||||
}
|
||||
|
||||
public function closeIncident(int $incidentId, string $closeDescription, ?string $actionTaken, int $userId): array
|
||||
{
|
||||
$incident = CurrentIncident::query()->find($incidentId);
|
||||
if (!$incident) {
|
||||
return ['ok' => false, 'message' => 'Incident not found.'];
|
||||
}
|
||||
|
||||
if ($incident->incident_state === 'Closed') {
|
||||
return ['ok' => false, 'message' => 'Incident is already closed.'];
|
||||
}
|
||||
|
||||
$incident->fill([
|
||||
'incident_state' => 'Closed',
|
||||
'updated_by_closed' => $userId,
|
||||
'close_description' => $closeDescription,
|
||||
'action_taken' => $actionTaken,
|
||||
]);
|
||||
$incident->save();
|
||||
|
||||
return $this->moveToHistory($incident);
|
||||
}
|
||||
|
||||
public function cancelIncident(int $incidentId, ?string $cancelDescription, ?string $actionTaken, int $userId): array
|
||||
{
|
||||
$incident = CurrentIncident::query()->find($incidentId);
|
||||
if (!$incident) {
|
||||
return ['ok' => false, 'message' => 'Incident not found.'];
|
||||
}
|
||||
|
||||
if ($incident->incident_state === 'Canceled') {
|
||||
return ['ok' => false, 'message' => 'Incident is already canceled.'];
|
||||
}
|
||||
|
||||
$incident->fill([
|
||||
'incident_state' => 'Canceled',
|
||||
'updated_by_canceled' => $userId,
|
||||
'cancel_description' => $cancelDescription,
|
||||
'action_taken' => $actionTaken,
|
||||
]);
|
||||
$incident->save();
|
||||
|
||||
return $this->moveToHistory($incident);
|
||||
}
|
||||
|
||||
private function moveToHistory(CurrentIncident $incident): array
|
||||
{
|
||||
return DB::transaction(function () use ($incident) {
|
||||
$history = Incident::query()->create([
|
||||
'student_id' => $incident->student_id,
|
||||
'student_name' => $incident->student_name,
|
||||
'grade' => $incident->grade,
|
||||
'incident' => $incident->incident,
|
||||
'incident_datetime' => $incident->incident_datetime,
|
||||
'incident_state' => $incident->incident_state,
|
||||
'updated_by_open' => $incident->updated_by_open,
|
||||
'open_description' => $incident->open_description,
|
||||
'updated_by_closed' => $incident->updated_by_closed,
|
||||
'close_description' => $incident->close_description,
|
||||
'action_taken' => $incident->action_taken,
|
||||
'updated_by_canceled' => $incident->updated_by_canceled,
|
||||
'cancel_description' => $incident->cancel_description,
|
||||
'semester' => $incident->semester,
|
||||
'school_year' => $incident->school_year,
|
||||
'created_at' => $incident->created_at,
|
||||
'updated_at' => $incident->updated_at,
|
||||
]);
|
||||
|
||||
$incident->delete();
|
||||
|
||||
return [
|
||||
'ok' => true,
|
||||
'incident_id' => (int) $history->id,
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
private function appendLine(string $existing, string $append): string
|
||||
{
|
||||
if ($existing === '') {
|
||||
return $append;
|
||||
}
|
||||
|
||||
return $existing . PHP_EOL . $append;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user