storeFlyer($flyer); $event = Event::query()->create([ 'event_name' => $payload['event_name'], 'event_category' => $payload['event_category'], 'description' => $payload['description'] ?? null, 'amount' => $payload['amount'], 'flyer' => $flyerPath, 'expiration_date' => $payload['expiration_date'], 'semester' => $payload['semester'], 'school_year' => $payload['school_year'], 'created_by' => $actorId ?: null, 'created_at' => utc_now(), 'updated_at' => utc_now(), ]); $seed = $this->charges->seedChargesForEvent( $event, (string) $payload['school_year'], (string) $payload['semester'], (float) $payload['amount'], $actorId ); return [ 'ok' => true, 'event' => $event, 'charges_created' => $seed['created'] ?? 0, ]; }); } public function update(int $eventId, array $payload, ?UploadedFile $flyer): array { $event = Event::query()->find($eventId); if (! $event) { return ['ok' => false, 'message' => 'Event not found.']; } $flyerPath = $event->flyer; if ($flyer) { $flyerPath = $this->storeFlyer($flyer) ?: $flyerPath; } $event->update([ 'event_name' => $payload['event_name'] ?? $event->event_name, 'event_category' => $payload['event_category'] ?? $event->event_category, 'description' => $payload['description'] ?? $event->description, 'amount' => $payload['amount'] ?? $event->amount, 'flyer' => $flyerPath, 'expiration_date' => $payload['expiration_date'] ?? $event->expiration_date, 'semester' => $payload['semester'] ?? $event->semester, 'school_year' => $payload['school_year'] ?? $event->school_year, 'updated_at' => utc_now(), ]); return ['ok' => true, 'event' => $event]; } public function delete(int $eventId, int $actorId): array { $event = Event::query()->find($eventId); if (! $event) { return ['ok' => false, 'message' => 'Event not found.']; } return DB::transaction(function () use ($event) { $charges = $this->charges->deleteChargesForEvent((int) $event->id); $event->delete(); foreach ($charges['parent_ids'] ?? [] as $parentId) { $this->invoiceGeneration->generateInvoice((int) $parentId, (string) $event->school_year); } return ['ok' => true]; }); } private function storeFlyer(?UploadedFile $file): ?string { if (! $file || ! $file->isValid()) { return null; } $allowed = [ 'image/jpeg' => 'jpg', 'image/png' => 'png', 'image/webp' => 'webp', 'application/pdf' => 'pdf', ]; $mime = strtolower((string) $file->getMimeType()); if (! isset($allowed[$mime])) { throw new \InvalidArgumentException('Unsupported flyer file type.'); } if ((int) $file->getSize() > 5 * 1024 * 1024) { throw new \InvalidArgumentException('Flyer file too large. Max 5MB.'); } $dir = public_path('uploads/event_flyers'); if (! File::exists($dir)) { File::makeDirectory($dir, 0755, true); } $name = bin2hex(random_bytes(16)).'.'.$allowed[$mime]; $file->move($dir, $name); return 'event_flyers/'.$name; } }