add projet
This commit is contained in:
Executable
+382
@@ -0,0 +1,382 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Models\Configuration;
|
||||
use App\Models\Event;
|
||||
use App\Models\EventCharges;
|
||||
use App\Models\Student;
|
||||
use App\Models\User;
|
||||
use App\Http\Controllers\Api\InvoiceController;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class EventController extends BaseApiController
|
||||
{
|
||||
protected Event $event;
|
||||
protected Configuration $config;
|
||||
protected EventCharges $eventCharges;
|
||||
protected Student $student;
|
||||
protected User $user;
|
||||
protected InvoiceController $invoiceController;
|
||||
protected ?string $schoolYear;
|
||||
protected ?string $semester;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->event = model(Event::class);
|
||||
$this->config = model(Configuration::class);
|
||||
$this->eventCharges = model(EventCharges::class);
|
||||
$this->student = model(Student::class);
|
||||
$this->user = model(User::class);
|
||||
$this->invoiceController = app(InvoiceController::class);
|
||||
|
||||
$this->schoolYear = $this->config->getConfig('school_year');
|
||||
$this->semester = $this->config->getConfig('semester');
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$schoolYear = $this->request->getGet('school_year') ?? $this->schoolYear;
|
||||
$upcomingOnly = $this->request->getGet('upcoming') === 'true';
|
||||
|
||||
$query = $this->event->newQuery();
|
||||
if ($schoolYear) {
|
||||
$query->where('school_year', $schoolYear);
|
||||
}
|
||||
if ($upcomingOnly) {
|
||||
$today = Carbon::now()->toDateString();
|
||||
$query->where('expiration_date', '>=', $today);
|
||||
}
|
||||
|
||||
$events = $query->orderBy('created_at', 'DESC')->get()->toArray();
|
||||
|
||||
// Count active events
|
||||
$today = Carbon::now()->toDateString();
|
||||
$activeEventCount = $this->event->newQuery()
|
||||
->where('expiration_date', '>=', $today)
|
||||
->count();
|
||||
|
||||
return $this->success([
|
||||
'events' => $events,
|
||||
'active_event_count' => $activeEventCount,
|
||||
], 'Events retrieved successfully');
|
||||
}
|
||||
|
||||
public function show($id = null)
|
||||
{
|
||||
$event = $this->event->find($id);
|
||||
if (!$event) {
|
||||
return $this->respondError('Event not found', Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
return $this->success($event, 'Event retrieved successfully');
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
$data = $this->payloadData();
|
||||
if (empty($data)) {
|
||||
return $this->respondError('Invalid request data', Response::HTTP_BAD_REQUEST);
|
||||
}
|
||||
|
||||
$rules = [
|
||||
'event_name' => 'required|max_length[255]',
|
||||
'description' => 'nullable',
|
||||
'amount' => 'required|numeric',
|
||||
'expiration_date' => 'required|date',
|
||||
'semester' => 'nullable',
|
||||
'school_year' => 'nullable',
|
||||
];
|
||||
|
||||
$errors = $this->validateRequest($data, $rules);
|
||||
if (!empty($errors)) {
|
||||
return $this->respondValidationError($errors);
|
||||
}
|
||||
|
||||
$flyerPath = null;
|
||||
|
||||
// Handle file upload if present
|
||||
if ($this->laravelRequest->hasFile('flyer')) {
|
||||
$file = $this->laravelRequest->file('flyer');
|
||||
if ($file->isValid()) {
|
||||
$path = $file->store('event_flyers', 'public');
|
||||
$flyerPath = $path;
|
||||
}
|
||||
}
|
||||
|
||||
$payload = [
|
||||
'event_name' => $data['event_name'],
|
||||
'description' => $data['description'] ?? null,
|
||||
'amount' => $data['amount'],
|
||||
'flyer' => $flyerPath,
|
||||
'expiration_date' => $data['expiration_date'],
|
||||
'semester' => $data['semester'] ?? $this->semester,
|
||||
'school_year' => $data['school_year'] ?? $this->schoolYear,
|
||||
'created_by' => $this->getCurrentUserId(),
|
||||
];
|
||||
|
||||
try {
|
||||
$event = $this->event->create($payload);
|
||||
return $this->respondCreated($event->toArray(), 'Event created successfully');
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Event creation error: ' . $e->getMessage());
|
||||
return $this->respondError('Failed to create event', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
public function update($id = null)
|
||||
{
|
||||
$event = $this->event->find($id);
|
||||
if (!$event) {
|
||||
return $this->respondError('Event not found', Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
$data = $this->payloadData();
|
||||
if (empty($data)) {
|
||||
return $this->respondError('Invalid request data', Response::HTTP_BAD_REQUEST);
|
||||
}
|
||||
|
||||
$flyerPath = $event['flyer']; // Keep existing flyer by default
|
||||
|
||||
// Handle file upload if present
|
||||
if ($this->laravelRequest->hasFile('flyer')) {
|
||||
$file = $this->laravelRequest->file('flyer');
|
||||
if ($file->isValid()) {
|
||||
// Delete old flyer if exists
|
||||
if ($flyerPath && Storage::disk('public')->exists($flyerPath)) {
|
||||
Storage::disk('public')->delete($flyerPath);
|
||||
}
|
||||
$path = $file->store('event_flyers', 'public');
|
||||
$flyerPath = $path;
|
||||
}
|
||||
}
|
||||
|
||||
$updateData = [];
|
||||
$allowed = ['event_name', 'description', 'amount', 'expiration_date', 'semester', 'school_year'];
|
||||
foreach ($allowed as $field) {
|
||||
if (array_key_exists($field, $data)) {
|
||||
$updateData[$field] = $data[$field];
|
||||
}
|
||||
}
|
||||
$updateData['flyer'] = $flyerPath;
|
||||
|
||||
try {
|
||||
$this->event->update($id, $updateData);
|
||||
$updated = $this->event->find($id);
|
||||
return $this->success($updated->toArray(), 'Event updated successfully');
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Event update error: ' . $e->getMessage());
|
||||
return $this->respondError('Failed to update event', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
public function delete($id = null)
|
||||
{
|
||||
$event = $this->event->find($id);
|
||||
if (!$event) {
|
||||
return $this->respondError('Event not found', Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
try {
|
||||
// Delete related charges and collect parent IDs
|
||||
$charges = $this->eventCharges->newQuery()
|
||||
->where('event_id', $id)
|
||||
->get()
|
||||
->toArray();
|
||||
|
||||
$parentIds = [];
|
||||
foreach ($charges as $charge) {
|
||||
$this->eventCharges->delete($charge['id']);
|
||||
$parentIds[] = $charge['parent_id'];
|
||||
}
|
||||
|
||||
// Delete event
|
||||
$this->event->delete($id);
|
||||
|
||||
$parentIds = array_unique($parentIds);
|
||||
|
||||
// Regenerate invoices for affected parents
|
||||
// Note: generateInvoice method may need to be implemented in InvoiceController
|
||||
foreach ($parentIds as $parentId) {
|
||||
// This would need to be implemented or called differently
|
||||
// $this->invoiceController->generateInvoice($parentId);
|
||||
}
|
||||
|
||||
return $this->success(null, 'Event, charges, and invoices updated successfully');
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Event deletion error: ' . $e->getMessage());
|
||||
return $this->respondError('Failed to delete event', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /api/v1/events/charges
|
||||
* Returns event charges with parent and student information
|
||||
*/
|
||||
public function charges()
|
||||
{
|
||||
$schoolYear = $this->request->getGet('school_year') ?? $this->schoolYear;
|
||||
$semester = $this->request->getGet('semester') ?? $this->semester;
|
||||
|
||||
try {
|
||||
$parents = $this->user->getParents();
|
||||
$events = $this->event->getActiveEvents($this->schoolYear);
|
||||
|
||||
$charges = $this->eventCharges->newQuery()
|
||||
->select([
|
||||
'event_charges.*',
|
||||
'users.firstname AS parent_firstname',
|
||||
'users.lastname AS parent_lastname',
|
||||
'students.firstname AS student_firstname',
|
||||
'students.lastname AS student_lastname',
|
||||
'events.event_name'
|
||||
])
|
||||
->leftJoin('users', 'users.id', '=', 'event_charges.parent_id')
|
||||
->leftJoin('students', 'students.id', '=', 'event_charges.student_id')
|
||||
->leftJoin('events', 'events.id', '=', 'event_charges.event_id')
|
||||
->where('event_charges.school_year', $schoolYear)
|
||||
->where('event_charges.semester', $semester)
|
||||
->orderBy('event_charges.created_at', 'DESC')
|
||||
->get()
|
||||
->toArray();
|
||||
|
||||
return $this->success([
|
||||
'charges' => $charges,
|
||||
'parents' => $parents,
|
||||
'events' => $events,
|
||||
'school_year' => $schoolYear,
|
||||
'semester' => $semester,
|
||||
], 'Event charges retrieved successfully');
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Event charges retrieval error: ' . $e->getMessage());
|
||||
return $this->respondError('Failed to retrieve event charges', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* POST /api/v1/events/charges/update
|
||||
* Updates event charges for a parent and students
|
||||
*/
|
||||
public function updateCharges()
|
||||
{
|
||||
$data = $this->payloadData();
|
||||
if (empty($data)) {
|
||||
return $this->respondError('Invalid request data', Response::HTTP_BAD_REQUEST);
|
||||
}
|
||||
|
||||
$schoolYear = $data['school_year'] ?? $this->schoolYear;
|
||||
$semester = $data['semester'] ?? $this->semester;
|
||||
$parentId = $data['parent_id'] ?? null;
|
||||
$eventId = $data['event_id'] ?? null;
|
||||
$participations = $data['participation'] ?? [];
|
||||
|
||||
if (!$parentId || !$eventId || empty($participations)) {
|
||||
return $this->respondError('Missing required information: parent_id, event_id, and participation are required', Response::HTTP_BAD_REQUEST);
|
||||
}
|
||||
|
||||
try {
|
||||
$userId = $this->getCurrentUserId();
|
||||
$event = $this->event->getEvent($eventId, $schoolYear);
|
||||
|
||||
if (!$event) {
|
||||
return $this->respondError('Event not found', Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
foreach ($participations as $studentId => $value) {
|
||||
$existing = $this->eventCharges->newQuery()
|
||||
->where('parent_id', $parentId)
|
||||
->where('student_id', $studentId)
|
||||
->where('event_id', $eventId)
|
||||
->where('school_year', $schoolYear)
|
||||
->where('semester', $semester)
|
||||
->first();
|
||||
|
||||
if ($value === 'no') {
|
||||
if ($existing) {
|
||||
$this->eventCharges->delete($existing['id']);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// value is 'yes'
|
||||
$chargeData = [
|
||||
'parent_id' => $parentId,
|
||||
'student_id' => $studentId,
|
||||
'event_id' => $eventId,
|
||||
'participation' => 'yes',
|
||||
'charged' => $event['amount'],
|
||||
'school_year' => $schoolYear,
|
||||
'semester' => $semester,
|
||||
];
|
||||
|
||||
if ($existing) {
|
||||
$chargeData['updated_by'] = $userId;
|
||||
$this->eventCharges->update($existing['id'], $chargeData);
|
||||
} else {
|
||||
$chargeData['updated_by'] = $userId;
|
||||
$this->eventCharges->insert($chargeData);
|
||||
}
|
||||
}
|
||||
|
||||
// Regenerate invoice for parent
|
||||
// Note: generateInvoice method may need to be implemented
|
||||
// $this->invoiceController->generateInvoice($parentId);
|
||||
|
||||
return $this->success(null, 'Event charges updated successfully');
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Event charges update error: ' . $e->getMessage());
|
||||
return $this->respondError('Failed to update event charges', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /api/v1/events/students-with-charges
|
||||
* Returns students for a parent with their charge status
|
||||
*/
|
||||
public function getStudentsWithCharges()
|
||||
{
|
||||
$parentId = $this->request->getGet('parent_id');
|
||||
$semester = $this->request->getGet('semester') ?? $this->semester;
|
||||
$schoolYear = $this->request->getGet('school_year') ?? $this->schoolYear;
|
||||
|
||||
if (!$parentId) {
|
||||
return $this->respondError('parent_id is required', Response::HTTP_BAD_REQUEST);
|
||||
}
|
||||
|
||||
try {
|
||||
// Get students for parent
|
||||
$students = $this->student->newQuery()
|
||||
->where('parent_id', $parentId)
|
||||
->get()
|
||||
->toArray();
|
||||
|
||||
// Get student_ids that already have charges
|
||||
$chargedStudentIds = $this->eventCharges->newQuery()
|
||||
->where('parent_id', $parentId)
|
||||
->where('semester', $semester)
|
||||
->where('school_year', $schoolYear)
|
||||
->groupBy('student_id')
|
||||
->pluck('student_id')
|
||||
->toArray();
|
||||
|
||||
$data = [];
|
||||
foreach ($students as $student) {
|
||||
$data[] = [
|
||||
'id' => $student['id'],
|
||||
'name' => trim(($student['firstname'] ?? '') . ' ' . ($student['lastname'] ?? '')),
|
||||
'charged' => in_array($student['id'], $chargedStudentIds),
|
||||
];
|
||||
}
|
||||
|
||||
return $this->success($data, 'Students with charges retrieved successfully');
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Get students with charges error: ' . $e->getMessage());
|
||||
return $this->respondError('Failed to retrieve students with charges', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user