New-Thanasoft/thanasoft-back/app/Http/Controllers/Api/InterventionController.php
2025-11-26 17:53:17 +03:00

558 lines
22 KiB
PHP

<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Http\Requests\StoreInterventionRequest;
use App\HttpRequests\StoreInterventionWithAllDataRequest;
use App\Http\Requests\UpdateInterventionRequest;
use App\Http\Resources\Intervention\InterventionResource;
use App\Http\Resources\Intervention\InterventionCollection;
use App\Repositories\InterventionRepositoryInterface;
use App\Repositories\InterventionPractitionerRepositoryInterface;
use App\Repositories\ClientRepositoryInterface;
use App\Repositories\ContactRepositoryInterface;
use App\Repositories\DeceasedRepositoryInterface;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpFoundation\Response;
class InterventionController extends Controller
{
/**
* @var InterventionRepositoryInterface
*/
protected $interventionRepository;
/**
* @var InterventionPractitionerRepositoryInterface
*/
protected $interventionPractitionerRepository;
/**
* @var ClientRepositoryInterface
*/
protected $clientRepository;
/**
* @var ContactRepositoryInterface
*/
protected $contactRepository;
/**
* @var DeceasedRepositoryInterface
*/
protected $deceasedRepository;
/**
* InterventionController constructor.
*
* @param InterventionRepositoryInterface $interventionRepository
* @param InterventionPractitionerRepositoryInterface $interventionPractitionerRepository
* @param ClientRepositoryInterface $clientRepository
* @param ContactRepositoryInterface $contactRepository
* @param DeceasedRepositoryInterface $deceasedRepository
*/
public function __construct(
InterventionRepositoryInterface $interventionRepository,
InterventionPractitionerRepositoryInterface $interventionPractitionerRepository,
ClientRepositoryInterface $clientRepository,
ContactRepositoryInterface $contactRepository,
DeceasedRepositoryInterface $deceasedRepository
) {
$this->interventionRepository = $interventionRepository;
$this->interventionPractitionerRepository = $interventionPractitionerRepository;
$this->clientRepository = $clientRepository;
$this->contactRepository = $contactRepository;
$this->deceasedRepository = $deceasedRepository;
}
/**
* Display a listing of the resource.
*/
public function index(Request $request): JsonResponse
{
try {
$filters = $request->only([
'client_id',
'deceased_id',
'status',
'type',
'start_date',
'end_date',
'sort_by',
'sort_order'
]);
$perPage = $request->input('per_page', 15);
$interventions = $this->interventionRepository->getAllPaginated($filters, $perPage);
return response()->json(new InterventionCollection($interventions));
} catch (\Exception $e) {
Log::error('Error fetching interventions list: ' . $e->getMessage());
return response()->json([
'message' => 'Une erreur est survenue lors de la récupération des interventions.',
'error' => $e->getMessage()
], Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Store a newly created resource in storage.
*/
public function store(StoreInterventionRequest $request): JsonResponse
{
try {
$validated = $request->validated();
$intervention = $this->interventionRepository->create($validated);
return response()->json(new InterventionResource($intervention), Response::HTTP_CREATED);
} catch (\Exception $e) {
Log::error('Error creating intervention: ' . $e->getMessage());
return response()->json([
'message' => 'Une erreur est survenue lors de la création de l\'intervention.',
'error' => $e->getMessage()
], Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Create an intervention with all related data (deceased, client, contact, location, documents).
*/
public function createInterventionalldata(StoreInterventionWithAllDataRequest $request): JsonResponse
{
try {
$validated = $request->validated();
// Wrap everything in a database transaction
$result = DB::transaction(function () use ($validated) {
// Step 1: Create the deceased
$deceasedData = $validated['deceased'];
$deceased = $this->deceasedRepository->create($deceasedData);
// Step 2: Create the client
$clientData = $validated['client'];
$client = $this->clientRepository->create($clientData);
// Step 3: Create the contact (if provided)
$contactId = null;
if (!empty($validated['contact'])) {
$contactData = array_merge($validated['contact'], [
'client_id' => $client->id
]);
$contact = $this->contactRepository->create($contactData);
$contactId = $contact->id;
}
// Step 4: Prepare location data (for now, we'll include it in intervention notes)
// In the future, you might want to create a ClientLocation entry
$locationData = $validated['location'] ?? [];
$locationNotes = '';
if (!empty($locationData)) {
$locationParts = [];
if (!empty($locationData['name'])) {
$locationParts[] = 'Lieu: ' . $locationData['name'];
}
if (!empty($locationData['address'])) {
$locationParts[] = 'Adresse: ' . $locationData['address'];
}
if (!empty($locationData['city'])) {
$locationParts[] = 'Ville: ' . $locationData['city'];
}
if (!empty($locationData['access_instructions'])) {
$locationParts[] = 'Instructions: ' . $locationData['access_instructions'];
}
if (!empty($locationData['notes'])) {
$locationParts[] = 'Notes: ' . $locationData['notes'];
}
$locationNotes = !empty($locationParts) ? "\n\n" . implode("\n", $locationParts) : '';
}
// Step 5: Create the intervention
$interventionData = array_merge($validated['intervention'], [
'deceased_id' => $deceased->id,
'client_id' => $client->id,
'notes' => ($validated['intervention']['notes'] ?? '') . $locationNotes
]);
$intervention = $this->interventionRepository->create($interventionData);
// Step 6: Handle document uploads (if any)
$documents = $validated['documents'] ?? [];
if (!empty($documents)) {
foreach ($documents as $documentData) {
if (isset($documentData['file']) && $documentData['file']->isValid()) {
// Store the file and create intervention attachment
// This is a placeholder - implement actual file upload logic
// $path = $documentData['file']->store('intervention_documents');
// Create intervention attachment record
}
}
}
// Return all created data
return [
'intervention' => $intervention,
'deceased' => $deceased,
'client' => $client,
'contact_id' => $contactId,
'documents_count' => count($documents)
];
});
Log::info('Intervention with all data created successfully', [
'intervention_id' => $result['intervention']->id,
'deceased_id' => $result['deceased']->id,
'client_id' => $result['client']->id,
'documents_count' => $result['documents_count']
]);
return response()->json([
'message' => 'Intervention créée avec succès',
'data' => [
'intervention' => new InterventionResource($result['intervention']),
'deceased' => $result['deceased'],
'client' => $result['client'],
'contact_id' => $result['contact_id'],
'documents_count' => $result['documents_count']
]
], Response::HTTP_CREATED);
} catch (\Illuminate\Validation\ValidationException $e) {
// Validation errors are handled by the FormRequest
return response()->json([
'message' => 'Données invalides',
'errors' => $e->errors()
], Response::HTTP_UNPROCESSABLE_ENTITY);
} catch (\Exception $e) {
Log::error('Error creating intervention with all data: ' . $e->getMessage(), [
'trace' => $e->getTraceAsString(),
'input' => $request->except(['documents']) // Don't log file data
]);
return response()->json([
'message' => 'Une erreur est survenue lors de la création de l\'intervention.',
'error' => $e->getMessage()
], Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Display the specified resource.
*/
public function show(int $id): JsonResponse
{
try {
$intervention = $this->interventionRepository->findById($id);
return response()->json(new InterventionResource($intervention));
} catch (\Exception $e) {
Log::error('Error fetching intervention details: ' . $e->getMessage());
return response()->json([
'message' => 'Intervention non trouvée ou une erreur est survenue.',
'error' => $e->getMessage()
], Response::HTTP_NOT_FOUND);
}
}
/**
* Update the specified resource in storage.
*/
public function update(UpdateInterventionRequest $request, int $id): JsonResponse
{
try {
$intervention = $this->interventionRepository->findById($id);
$validated = $request->validated();
$updatedIntervention = $this->interventionRepository->update($intervention, $validated);
return response()->json(new InterventionResource($updatedIntervention));
} catch (\Exception $e) {
Log::error('Error updating intervention: ' . $e->getMessage());
return response()->json([
'message' => 'Une erreur est survenue lors de la mise à jour de l\'intervention.',
'error' => $e->getMessage()
], Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Remove the specified resource from storage.
*/
public function destroy(int $id): JsonResponse
{
try {
$intervention = $this->interventionRepository->findById($id);
$this->interventionRepository->delete($intervention);
return response()->json(null, Response::HTTP_NO_CONTENT);
} catch (\Exception $e) {
Log::error('Error deleting intervention: ' . $e->getMessage());
return response()->json([
'message' => 'Une erreur est survenue lors de la suppression de l\'intervention.',
'error' => $e->getMessage()
], Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Change the status of an intervention.
*/
public function changeStatus(Request $request, int $id): JsonResponse
{
try {
$validated = $request->validate([
'status' => 'required|in:demande,planifie,en_cours,termine,annule'
]);
$intervention = $this->interventionRepository->findById($id);
$updatedIntervention = $this->interventionRepository->changeStatus(
$intervention,
$validated['status']
);
return response()->json(new InterventionResource($updatedIntervention));
} catch (\Exception $e) {
Log::error('Error changing intervention status: ' . $e->getMessage());
return response()->json([
'message' => 'Une erreur est survenue lors de la modification du statut de l\'intervention.',
'error' => $e->getMessage()
], Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Get interventions for a specific month.
*/
public function byMonth(Request $request): JsonResponse
{
try {
$validated = $request->validate([
'year' => 'required|integer|min:2000|max:2100',
'month' => 'required|integer|min:1|max:12'
]);
$interventions = $this->interventionRepository->getByMonth(
$validated['year'],
$validated['month']
);
return response()->json([
'data' => $interventions->map(function ($intervention) {
return new InterventionResource($intervention);
}),
'meta' => [
'total' => $interventions->count(),
'year' => $validated['year'],
'month' => $validated['month'],
]
]);
} catch (\Exception $e) {
Log::error('Error fetching interventions by month: ' . $e->getMessage());
return response()->json([
'message' => 'Une erreur est survenue lors de la récupération des interventions du mois.',
'error' => $e->getMessage()
], Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Create assignment of practitioners to an intervention
*
* @param Request $request
* @param int $id
* @return JsonResponse
*/
public function createAssignment(Request $request, int $id): JsonResponse
{
try {
$validated = $request->validate([
'principal_practitioner_id' => 'nullable|integer|exists:thanatopractitioners,id',
'assistant_practitioner_ids' => 'nullable|array',
'assistant_practitioner_ids.*' => 'integer|exists:thanatopractitioners,id',
]);
$intervention = $this->interventionRepository->findById($id);
if (!$intervention) {
return response()->json([
'message' => 'Intervention non trouvée.'
], Response::HTTP_NOT_FOUND);
}
// Remove existing principal practitioner first
if (isset($validated['principal_practitioner_id'])) {
$principalId = $validated['principal_practitioner_id'];
$this->interventionPractitionerRepository->createAssignment($id, $principalId, 'principal');
}
// Handle assistant practitioners
if (isset($validated['assistant_practitioner_ids']) && is_array($validated['assistant_practitioner_ids'])) {
foreach ($validated['assistant_practitioner_ids'] as $assistantId) {
$this->interventionPractitionerRepository->createAssignment($id, $assistantId, 'assistant');
}
}
// Load the intervention with practitioners to return updated data
$intervention->load('practitioners');
$practitioners = $intervention->practitioners;
return response()->json([
'data' => new InterventionResource($intervention),
'message' => 'Assignment(s) créé(s) avec succès.',
'practitioners_count' => $practitioners->count(),
'practitioners' => $practitioners->map(function($p) {
return [
'id' => $p->id,
'full_name' => $p->full_name ?? ($p->first_name . ' ' . $p->last_name),
'role' => $p->pivot->role ?? 'unknown'
];
})->toArray()
], Response::HTTP_OK);
} catch (\Exception $e) {
return response()->json([
'message' => 'Une erreur est survenue lors de la création de l\'assignment.',
'error' => $e->getMessage()
], Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Unassign a practitioner from an intervention
*
* @param Request $request
* @param int $interventionId
* @param int $practitionerId
* @return JsonResponse
*/
public function unassignPractitioner(Request $request, int $interventionId, int $practitionerId): JsonResponse
{
try {
Log::info('Unassigning practitioner from intervention', [
'intervention_id' => $interventionId,
'practitioner_id' => $practitionerId
]);
// Validate that the intervention exists
$intervention = $this->interventionRepository->findById($interventionId);
if (!$intervention) {
return response()->json([
'message' => 'Intervention non trouvée.'
], Response::HTTP_NOT_FOUND);
}
// Check if the practitioner is actually assigned to this intervention
$isAssigned = $this->interventionPractitionerRepository->isPractitionerAssigned($interventionId, $practitionerId);
if (!$isAssigned) {
return response()->json([
'message' => 'Le praticien n\'est pas assigné à cette intervention.'
], Response::HTTP_NOT_FOUND);
}
// Remove the practitioner assignment
$deleted = $this->interventionPractitionerRepository->removeAssignment($interventionId, $practitionerId);
if ($deleted > 0) {
Log::info('Practitioner unassigned successfully', [
'intervention_id' => $interventionId,
'practitioner_id' => $practitionerId,
'deleted_records' => $deleted
]);
// Reload intervention with remaining practitioners
$intervention->load('practitioners');
$remainingPractitioners = $intervention->practitioners;
return response()->json([
'data' => new InterventionResource($intervention),
'message' => 'Praticien désassigné avec succès.',
'remaining_practitioners_count' => $remainingPractitioners->count(),
'remaining_practitioners' => $remainingPractitioners->map(function($p) {
return [
'id' => $p->id,
'employee_name' => $p->employee->full_name ?? ($p->employee->first_name . ' ' . $p->employee->last_name),
'role' => $p->pivot->role ?? 'unknown'
];
})->toArray()
], Response::HTTP_OK);
} else {
Log::warning('No practitioner assignment found to delete', [
'intervention_id' => $interventionId,
'practitioner_id' => $practitionerId
]);
return response()->json([
'message' => 'Aucun assignment de praticien trouvé à supprimer.'
], Response::HTTP_NOT_FOUND);
}
} catch (\Exception $e) {
Log::error('Error unassigning practitioner from intervention: ' . $e->getMessage(), [
'intervention_id' => $interventionId,
'practitioner_id' => $practitionerId,
'request_data' => $request->all(),
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
]);
return response()->json([
'message' => 'Une erreur est survenue lors de la désassignation du praticien.',
'error' => $e->getMessage()
], Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Debug endpoint to check practitioners in database
*/
public function debugPractitioners(int $id): JsonResponse
{
try {
$intervention = $this->interventionRepository->findById($id);
// Direct database query
$dbPractitioners = DB::table('intervention_practitioner')
->where('intervention_id', $id)
->get();
// Eager loaded practitioners
$eagerPractitioners = $intervention->practitioners()->get();
return response()->json([
'intervention_id' => $id,
'database_records' => $dbPractitioners,
'eager_loaded_count' => $eagerPractitioners->count(),
'eager_loaded_data' => $eagerPractitioners->map(function($p) {
return [
'id' => $p->id,
'full_name' => $p->full_name ?? ($p->first_name . ' ' . $p->last_name),
'role' => $p->pivot->role ?? 'unknown'
];
})->toArray()
]);
} catch (\Exception $e) {
Log::error('Error in debug practitioners: ' . $e->getMessage());
return response()->json(['error' => $e->getMessage()], 500);
}
}
}