558 lines
22 KiB
PHP
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);
|
|
}
|
|
}
|
|
}
|