%PDF- %PDF-
| Direktori : /home/vacivi36/core/app/Http/Controllers/ |
| Current File : /home/vacivi36/core/app/Http/Controllers/ScheduleController.php |
<?php
namespace App\Http\Controllers;
use App\Models\Schedule;
use App\Models\VaccineApplication;
use App\Models\Vaccine;
use App\Models\Patient;
use Illuminate\Http\Request;
use Maatwebsite\Excel\Facades\Excel;
use PhpOffice\PhpSpreadsheet\IOFactory;
use Carbon\Carbon;
class ScheduleController extends Controller
{
/**
* Exibir a lista de agendamentos com aplicações associadas.
*/
public function index(Request $request)
{
// Adicionar filtro por `patient_id` se for enviado no request
$query = Schedule::query();
if ($request->has('patient_id') && $request->patient_id) {
$query->where('patient_id', $request->patient_id);
}
// Verificar se `from`, `to`, `type` e `campaign_id` foram enviados no request
if ($request->has('from') && $request->has('to') && $request->has('type')) {
$from = $request->from;
$to = $request->to;
$type = $request->type;
if ($type === 'vaccine') {
// Filtrar `applications` pelo campo `application_date` e também por `campaign_id`
$query->with(['applications' => function ($q) use ($from, $to, $request) {
$q->whereBetween('application_date', [$from, $to]);
// Filtrar por `campaign_id` se fornecido
if ($request->has('campaign_id') && $request->campaign_id) {
$q->whereHas('vaccine', function ($q) use ($request) {
$q->where('campaign_id', $request->campaign_id);
});
}
$q->orderBy('application_date', 'desc');
}, 'applications.vaccine.campaign', 'applications.user', 'patient'])
->whereHas('applications', function ($q) use ($from, $to, $request) {
$q->whereBetween('application_date', [$from, $to]);
// Filtrar por `campaign_id` dentro de `whereHas` também
if ($request->has('campaign_id') && $request->campaign_id) {
$q->whereHas('vaccine', function ($q) use ($request) {
$q->where('campaign_id', $request->campaign_id);
});
}
});
} elseif ($type === 'schedule') {
// Filtrar diretamente pelo campo `schedule_date` na tabela `schedules`
$query->whereBetween('schedule_date', [$from, $to])
->with(['applications.vaccine.campaign', 'applications.user', 'patient'])
// Ordenar pelo campo `schedule_date` da tabela `schedules`
->orderBy('schedule_date');
// Adicionar o filtro de `campaign_id` para o tipo `schedule`
if ($request->has('campaign_id') && $request->campaign_id) {
$query->whereHas('applications.vaccine', function ($q) use ($request) {
$q->where('campaign_id', $request->campaign_id);
});
}
}
} else {
// Caso `from`, `to` e `type` não estejam presentes, carregar `applications` normalmente
$query->with(['applications.vaccine.campaign', 'applications.user', 'patient']);
// Adicionar o filtro de `campaign_id` se for fornecido
if ($request->has('campaign_id') && $request->campaign_id) {
$query->whereHas('applications.vaccine', function ($q) use ($request) {
$q->where('campaign_id', $request->campaign_id);
});
}
}
// Obter os resultados filtrados
$schedules = $query->get();
return response()->json($schedules);
}
/**
* Criar um novo agendamento com múltiplas aplicações.
*/
public function store(Request $request)
{
// Cria o agendamento
$schedule = new Schedule();
$schedule->patient_id = $request->patient_id;
$schedule->schedule_date = $request->schedule_date;
$schedule->notes = $request->notes;
$schedule->save();
// Adiciona as aplicações de vacina associadas
if ($request->has('applications')) {
foreach ($request->applications as $applicationData) {
$application = new VaccineApplication();
$application->schedule_id = $schedule->id;
$application->vaccine_id = $applicationData['vaccine_id'];
$application->application_date = $applicationData['application_date'];
$application->dose_number = $applicationData['dose_number'];
$application->notes = $applicationData['notes'] ?? null;
if (isset($applicationData['reason'])) {
$application->reason = $applicationData['reason'];
}
if (isset($applicationData['is_applied'])) {
$application->is_applied = $applicationData['is_applied'];
}
$application->save();
}
}
return response()->json(['status' => 'success', 'message' => 'Agendamento e aplicações criados com sucesso!'], 201);
}
/**
* Exibir um agendamento específico com detalhes das aplicações.
*/
public function show($id)
{
$schedule = Schedule::with(['applications.vaccine', 'patient'])->findOrFail($id);
return response()->json($schedule);
}
/**
* Atualizar um agendamento existente e suas aplicações.
*/
// public function update(Request $request, $id)
// {
// $schedule = Schedule::findOrFail($id);
// $schedule->patient_id = $request->patient_id;
// $schedule->schedule_date = $request->schedule_date;
// $schedule->notes = $request->notes;
// $schedule->save();
// // Atualiza as aplicações de vacina associadas
// if ($request->has('applications')) {
// foreach ($request->applications as $applicationData) {
// // Verifica se existe um ID para a aplicação de vacina
// if (isset($applicationData['id'])) {
// // Busca o VaccineApplication existente pelo ID
// $application = VaccineApplication::find($applicationData['id']);
// if ($application) {
// // Atualiza os dados da aplicação, mantendo is_applied intacto
// $application->application_date = $applicationData['application_date'];
// $application->dose_number = $applicationData['dose_number'];
// $application->notes = $applicationData['notes'] ?? $application->notes;
// $application->save();
// }
// }
// }
// }
// return response()->json(['status' => 'success', 'message' => 'Agendamento e aplicações atualizados com sucesso!'], 200);
// }
/**
* Remover um agendamento e suas aplicações associadas.
*/
public function destroy($id)
{
$schedule = Schedule::findOrFail($id);
// Verifica se existe alguma aplicação com is_applied igual a 1 ou 0
$hasAppliedOrCanceled = $schedule->applications()->whereNotNull('is_applied')->exists();
if ($hasAppliedOrCanceled) {
return response()->json(['message' => 'Não é possível excluir o agendamento, pois o paciente já possui registro de vacinas.'], 403);
}
// Permite a exclusão apenas se todas as aplicações tiverem is_applied como null
$schedule->applications()->delete(); // Remove as aplicações associadas
$schedule->delete(); // Remove o agendamento
return response()->json(['message' => 'Agendamento e aplicações excluídos com sucesso!']);
}
public function importFromSpreadsheet(Request $request)
{
// Verifica se o arquivo foi enviado
if (!$request->hasFile('file') || !$request->file('file')->isValid()) {
return response()->json(['status' => 'error', 'message' => 'Arquivo inválido ou não enviado.'], 400);
}
// Caminho do arquivo enviado
$filePath = $request->file('file')->getPathname();
// Lê a planilha
$spreadsheet = IOFactory::load($filePath);
$sheet = $spreadsheet->getActiveSheet();
$rows = $sheet->toArray();
// Define os campos obrigatórios com mapeamento para os campos do banco de dados
$requiredFields = [
'CPF do Paciente' => 'cpf',
'Código da Vacina' => 'vaccine_code',
'Data de Agendamento' => 'schedule_date',
'Data de Aplicação' => 'application_date',
'Dose' => 'dose_number'
];
// Validação dos cabeçalhos da planilha
$headers = $rows[0];
foreach (array_keys($requiredFields) as $field) {
if (!in_array($field, $headers)) {
return response()->json(['status' => 'error', 'message' => "Campo obrigatório '{$field}' está ausente na planilha."], 400);
}
}
// Índices dos campos obrigatórios na planilha
$indexes = array_flip($headers);
// Inicializa uma coleção de dados a serem enviados
$schedulesData = [];
// Processa cada linha da planilha
foreach (array_slice($rows, 1) as $row) {
$data = [];
foreach ($requiredFields as $field => $dbField) {
$value = $row[$indexes[$field]] ?? null;
if (is_null($value)) {
return response()->json(['status' => 'error', 'message' => "O campo obrigatório '{$field}' está vazio em alguma linha, utilize a planilha padrão do sistema para importar os agendamentos corretamente."], 400);
}
// Verifica e converte as datas para o formato 'yyyy-mm-dd'
if (in_array($field, ['Data de Aplicação', 'Data de Agendamento'])) {
try {
// Agora definimos o formato correto para dd/MM/yyyy
$value = Carbon::createFromFormat('d/m/Y', $value)->format('Y-m-d');
} catch (\Exception $e) {
return response()->json(['status' => 'error', 'message' => "Data inválida no campo '{$field}': {$value}. Use o formato dd/MM/aaaa Ex: 20/11/2024"], 400);
}
}
// Adiciona o valor ao array com o nome correto do campo no banco de dados
$data[$dbField] = $value;
}
// Busca o ID do paciente pelo CPF
$patient = Patient::where('cpf', $data['cpf'])->first();
if (!$patient) {
return response()->json(['status' => 'error', 'message' => "Paciente com CPF '{$data['cpf']}' não encontrado no sistema, verifique se esse CPF existe no cadastro de pacientes e tente novamente."], 400);
}
// Busca o ID da vacina pelo código da vacina
$vaccine = Vaccine::where('code', $data['vaccine_code'])->first();
if (!$vaccine) {
return response()->json(['status' => 'error', 'message' => "Vacina com código '{$data['vaccine_code']}' não encontrada no sistema, verifique se esse código existe no cadastro de vacinas e tente novamente."], 400);
}
// Monta o JSON conforme esperado pelo backend
$schedulesData[] = [
'patient_id' => $patient->id,
'schedule_date' => $data['schedule_date'],
'applications' => [
[
'vaccine_id' => $vaccine->id,
'application_date' => $data['application_date'],
'dose_number' => $data['dose_number']
]
]
];
}
// Salva cada agendamento e aplicação no banco de dados
foreach ($schedulesData as $scheduleData) {
// Cria um novo agendamento
$schedule = Schedule::create([
'patient_id' => $scheduleData['patient_id'],
'schedule_date' => $scheduleData['schedule_date'],
'notes' => null, // Pode ser ajustado conforme a necessidade
]);
// Cria cada aplicação associada ao agendamento
foreach ($scheduleData['applications'] as $applicationData) {
$schedule->applications()->create([
'vaccine_id' => $applicationData['vaccine_id'],
'application_date' => $applicationData['application_date'],
'dose_number' => $applicationData['dose_number']
]);
}
}
return response()->json(['status' => 'success', 'message' => 'Dados importados e salvos com sucesso!']);
}
}