method()) { case 'POST': { return $this->getPostRules(); } default: { return []; } } } private function getPostRules() { $atendimento = is_numeric($this->atendimento_id ?? null) ? Atendimento::find($this->atendimento_id) : null; $rules = [ 'plantao_id' => [ 'required', 'integer' ], 'atendimento_id' => [ 'required', 'integer', 'exists:\App\Models\ProntoAtendimento\Atendimento\Atendimento,id' ], ]; if (is_null($atendimento)) { return $rules; } $rules = array_merge($rules, [ 'classificacao_risco_id' => [ 'nullable', 'integer', 'exists:\App\Models\ProntoAtendimento\ClassificacaoRisco\ClassificacaoRisco,id' ], 'historico' => [ 'nullable', 'string', 'max:3000' ], 'diagnostico' => [ 'nullable', 'string', $this->getIsUsuarioCboEnfermeiroValidator(), 'max:3000' ], 'planejamento' => [ 'nullable', 'string', $this->getIsUsuarioCboEnfermeiroValidator(), 'max:3000' ], 'implementacao' => [ 'nullable', 'string', $this->getIsUsuarioCboEnfermeiroValidator(), 'max:3000' ], 'avaliacao' => [ 'nullable', 'string', $this->getIsUsuarioCboEnfermeiroValidator(), 'max:6000' ], 'medicamentos_uso' => [ 'nullable', 'string', 'max:3000', ], 'observacoes' => [ 'nullable', 'string', 'max:3000', ], 'centro_custo_id_para' => [ 'nullable', 'integer', 'exists:\App\Models\Cadastro\Estabelecimento\CentroCusto,id', ], 'escala_coma_glasgow' => [ 'nullable', 'array', ], 'escala_coma_glasgow.*.abertura_ocular_id' => [ 'required', 'integer', 'exists:\App\Models\Geral\GlasgowAberturaOcular,id' ], 'escala_coma_glasgow.*.resposta_verbal_id' => [ 'required', 'integer', 'exists:\App\Models\Geral\GlasgowRespostaVerbal,id' ], 'escala_coma_glasgow.*.resposta_motora_id' => [ 'required', 'integer', 'exists:\App\Models\Geral\GlasgowRespostaMotora,id' ], 'escala_coma_glasgow.*.reatividade_pupilar_id' => [ 'required', 'integer', 'exists:\App\Models\Geral\GlasgowReatividadePupilar,id' ], 'escala_coma_glasgow.*.observacao' => [ 'nullable', 'string', 'max:2500' ], ]); return array_merge( $rules, $this->getPostAlergiaRules(), $this->getPostSinaisVitaisRules(), $this->getPostAvaliacaoAntropometricaRules(), $this->getPostFatoresRicoRules(), $this->getPostGestacaoRules(), $this->getPostAnotacoesRules(), $this->getPostServicosEnfermagemRules($atendimento), $this->getPostProcedimentosRules($atendimento), $this->getPostPrescricoesInternaRules($atendimento), $this->getPostPedidoExamesRules($atendimento), $this->getPostFinalizacaoRules($atendimento), ); } private function getIsUsuarioCboEnfermeiroValidator() { return function ($value, $attribute, $fail) { if ($this->getOcupacaoProfissionalLogado()->codigo !== OcupacaoEnum::ENFERMEIRO) { $fail('Não permitido para a CBO logado'); } }; } private function getPostFatoresRicoRules() { return [ 'fatores_risco' => [ 'nullable', 'array', ], 'fatores_risco.*' => [ 'required', 'integer', ], 'fator_risco_outro' => [ 'nullable', Rule::requiredIf(fn () => in_array(FatorRisco::OUTRO, $this->fatores_risco ?? [])), 'string', 'max:100', ] ]; } private function getPostAlergiaRules() { return [ 'alergias' => [ 'nullable', 'array', ], 'alergias.*.alergia_id' => [ 'required', 'integer', 'exists:\App\Models\Cadastro\SujeitoAtencao\Alergia,id', ], 'alergias.*.criticidade_id' => [ 'required', 'integer', 'exists:\App\Models\Cadastro\SujeitoAtencao\AlergiaCriticidade,id', ], 'alergias.*.reacoes_observacoes' => [ 'nullable', 'string', 'between:3,100', ], ]; } private function getPostSinaisVitaisRules() { $rules = [ 'sinais_vitais' => [ 'nullable', 'array', ], 'sinais_vitais.*.pa_unidade_medida_id' => [ 'nullable', 'required_with:sinais_vitais.*.pa', 'integer', Rule::in([UnidadeMedida::MILIMETROS_DE_MERCURIO, UnidadeMedida::CENTIMETROS_DE_MERCURIO]), ], 'sinais_vitais.*.glicemia' => [ 'nullable', 'required_without_all:' . 'sinais_vitais.*.pa,' . 'sinais_vitais.*.temperatura,' . 'sinais_vitais.*.pulso,' . 'sinais_vitais.*.respiracao,' . 'sinais_vitais.*.saturacao,' . 'sinais_vitais.*.intensidade_dor,' . 'sinais_vitais.*.cintura', 'integer', 'max:999', ], 'sinais_vitais.*.temperatura' => [ 'nullable', 'required_without_all:' . 'sinais_vitais.*.pa,' . 'sinais_vitais.*.glicemia,' . 'sinais_vitais.*.pulso,' . 'sinais_vitais.*.respiracao,' . 'sinais_vitais.*.saturacao,' . 'sinais_vitais.*.intensidade_dor,' . 'sinais_vitais.*.cintura', 'numeric', 'max:99.9', ], 'sinais_vitais.*.pulso' => [ 'nullable', 'required_without_all:' . 'sinais_vitais.*.pa,' . 'sinais_vitais.*.glicemia,' . 'sinais_vitais.*.temperatura,' . 'sinais_vitais.*.respiracao,' . 'sinais_vitais.*.saturacao,' . 'sinais_vitais.*.intensidade_dor,' . 'sinais_vitais.*.cintura', 'integer', 'max:999', ], 'sinais_vitais.*.respiracao' => [ 'nullable', 'required_without_all:' . 'sinais_vitais.*.pa,' . 'sinais_vitais.*.glicemia,' . 'sinais_vitais.*.temperatura,' . 'sinais_vitais.*.pulso,' . 'sinais_vitais.*.saturacao,' . 'sinais_vitais.*.intensidade_dor,' . 'sinais_vitais.*.cintura', 'integer', 'max:99', ], 'sinais_vitais.*.saturacao' => [ 'nullable', 'required_without_all:' . 'sinais_vitais.*.pa,' . 'sinais_vitais.*.glicemia,' . 'sinais_vitais.*.temperatura,' . 'sinais_vitais.*.pulso,' . 'sinais_vitais.*.respiracao,' . 'sinais_vitais.*.intensidade_dor,' . 'sinais_vitais.*.cintura', 'integer', 'between:1,100', ], 'sinais_vitais.*.intensidade_dor' => [ 'nullable', 'required_without_all:' . 'sinais_vitais.*.pa,' . 'sinais_vitais.*.glicemia,' . 'sinais_vitais.*.temperatura,' . 'sinais_vitais.*.pulso,' . 'sinais_vitais.*.respiracao,' . 'sinais_vitais.*.saturacao,' . 'sinais_vitais.*.cintura', 'integer', 'between:1,10', ], 'sinais_vitais.*.cintura' => [ 'nullable', 'required_without_all:' . 'sinais_vitais.*.pa,' . 'sinais_vitais.*.glicemia,' . 'sinais_vitais.*.temperatura,' . 'sinais_vitais.*.pulso,' . 'sinais_vitais.*.respiracao,' . 'sinais_vitais.*.saturacao,' . 'sinais_vitais.*.intensidade_dor,', 'integer', 'max:999', ], ]; foreach (($this->sinais_vitais ?? []) as $i => $sinalVital) { $rules["sinais_vitais.{$i}.pa"] = [ 'nullable', 'required_without_all:' . "sinais_vitais.{$i}.glicemia," . "sinais_vitais.{$i}.temperatura," . "sinais_vitais.{$i}.pulso," . "sinais_vitais.{$i}.respiracao," . "sinais_vitais.{$i}.saturacao," . "sinais_vitais.{$i}.intensidade_dor," . "sinais_vitais.{$i}.cintura'", 'string', ]; if ($sinalVital['pa_unidade_medida_id'] === UnidadeMedida::MILIMETROS_DE_MERCURIO) { $rules["sinais_vitais.{$i}.pa"][] = 'regex:/^[0-9]{2,3}\/+[0-9]{2,3}$/'; } else if ($sinalVital['pa_unidade_medida_id'] === UnidadeMedida::CENTIMETROS_DE_MERCURIO) { $rules["sinais_vitais.{$i}.pa"][] = 'regex:/^[0-9]{1,2}\/+[0-9]{1,2}$/'; } } return $rules; } private function getPostAvaliacaoAntropometricaRules() { $rules = [ 'avaliacao_antropometrica' => [ 'nullable', 'array', ], ]; if (is_array($this->avaliacao_antropometrica ?? null)) { $rules = array_merge($rules, [ 'avaliacao_antropometrica.massa' => [ 'nullable', 'required_without:avaliacao_antropometrica.altura', 'numeric', 'max:999.999', ], 'avaliacao_antropometrica.massa_unidade_medida_id' => [ 'nullable', 'required_with:avaliacao_antropometrica.massa', 'integer', Rule::in([UnidadeMedida::GRAMAS, UnidadeMedida::QUILOGRAMAS]), ], 'avaliacao_antropometrica.altura' => [ 'nullable', 'required_without:avaliacao_antropometrica.massa', 'numeric', 'max:999.99', ], 'avaliacao_antropometrica.altura_unidade_medida_id' => [ 'nullable', 'required_with:avaliacao_antropometrica.altura', 'integer', Rule::in([UnidadeMedida::CENTIMETROS, UnidadeMedida::METROS]), ], 'avaliacao_antropometrica.altura_tipo_medida_id' => [ 'nullable', 'required_with:avaliacao_antropometrica.altura', 'integer', 'exists:\App\Models\Geral\TipoMedidaAltura,id', ], ]); } return $rules; } private function getPostGestacaoRules() { $rules = [ 'gestacao' => [ 'nullable', 'array', ], ]; if (is_array($this->gestacao ?? null)) { $rules = array_merge($rules, [ 'gestacao.gestante' => [ 'required', 'boolean', ], 'gestacao.dum' => [ 'nullable', 'date_format:Y-m-d', 'before_or_equal:now', ], ]); } return $rules; } private function getPostAnotacoesRules() { $rules = [ 'anotacoes' => [ 'nullable', 'array', ], 'anotacoes.*.anotado_em' => [ 'required', 'date_format:Y-m-d H:i', 'before_or_equal:now', ], 'anotacoes.*.descricao' => [ 'required', 'string', 'max:6000' ] ]; return $rules; } private function getPostServicosEnfermagemRules(Atendimento $atendimento) { $rules = [ 'servicos_enfermagem' => [ 'nullable', 'array', ] ]; foreach (($this->servicos_enfermagem ?? []) as $i => $param) { $rules["servicos_enfermagem.{$i}.id"] = [ 'nullable', 'integer', 'exists:\App\Models\ProntoAtendimento\Atendimento\ServicoEnfermagem,id', ]; $rules["servicos_enfermagem.{$i}.observacoes"] = [ 'nullable', 'string', 'max:100' ]; $rules["servicos_enfermagem.{$i}.status_id"] = [ 'nullable', "required_with:servicos_enfermagem.{$i}.id", 'integer', Rule::in(ExameStatus::SOLICITADO, ExameStatus::REALIZADO, ExameStatus::NAO_REALIZADO), 'exists:\App\Models\Parametrizacao\Exame\ExameStatus,id', ]; $procedimento = is_numeric($param['procedimento_id'] ?? null) ? Procedimento::find($param['procedimento_id']) : null; $rules["servicos_enfermagem.{$i}.procedimento_id"] = [ 'required', 'integer', new ValidCompetencia($procedimento), $atendimento->faa->paciente->cidadao->idade ? new Idade($procedimento, $atendimento->faa->paciente->cidadao->idade['anos']) : null, new Ocupacao($procedimento, $this->getOcupacaoProfissionalLogado()), new Quantidade($procedimento, 1), new SexoRule($procedimento, $atendimento->faa->paciente->cidadao->sexo), $this->getMatchProcedimentoIdAndServicoEnfermagemIdValidator($atendimento, $this->servicos_enfermagem[$i]), 'exists:\App\Models\Sigtap\Procedimento,id', ]; $rules["servicos_enfermagem.{$i}.cid_id"] = [ 'nullable', Rule::requiredIf(fn () => $procedimento->hasCidPrincipal && ($param['status_id'] == ExameStatus::REALIZADO)), 'integer', $procedimento->hasCidPrincipal ? Rule::in($procedimento->cidsPrincipais()->pluck('id')) : 'exists:\App\Models\Sigtap\Cid,id', ]; } return $rules; } private function getMatchProcedimentoIdAndServicoEnfermagemIdValidator($atendimento, $currentServicoEnfermagem) { return function ($attribute, $value, $fail) use ($atendimento, $currentServicoEnfermagem) { if (is_null($currentServicoEnfermagem['id'] ?? null)) return; $found = false; $atendimentos = []; foreach ($atendimento->atendimentosMedico as $atendimentoMedico) { if (!empty($atendimentoMedico->servicosEnfermagem()->get()->toArray())) { $atendimentos[] = $atendimentoMedico->servicosEnfermagem; } } foreach ($atendimento->atendimentosEnfermagem as $atendimentoEnfermagem) { if (!empty($atendimentoEnfermagem->servicosEnfermagem()->get()->toArray())) { $atendimentos[] = $atendimentoEnfermagem->servicosEnfermagem; } } foreach ($atendimentos as $servicosEnfermagem) { foreach ($servicosEnfermagem as $servicoEnfermagem) { $found = $currentServicoEnfermagem['id'] == $servicoEnfermagem->id && $currentServicoEnfermagem['procedimento_id'] == $servicoEnfermagem->procedimento_id; if ($found) { break 2; } } } if (!$found) { $fail('O ' . $attribute . ' não é válido para o serviço de enfermagem!'); } }; } private function getPostProcedimentosRules($atendimento) { $rules = [ 'procedimentos' => [ 'nullable', 'array', ], ]; if (is_array($this->procedimentos ?? null)) { foreach ($this->procedimentos as $i => $params) { $procedimento = is_numeric($params['procedimento_id'] ?? null) ? Procedimento::find($params['procedimento_id']) : null; $rules["procedimentos.{$i}.procedimento_id"] = [ 'required', 'integer', 'exists:\App\Models\Sigtap\Procedimento,id', ]; if (is_null($procedimento)) { continue; } $rules["procedimentos.{$i}.procedimento_id"] = [ $this->getDuplicatedValidator($this->procedimentos, $i), new ValidCompetencia($procedimento), new Ocupacao($procedimento, $this->getOcupacaoProfissionalLogado()), new SexoRule($procedimento, $atendimento->faa->paciente->cidadao->sexo), ($atendimento->faa->paciente->cidadao->idade ? new Idade($procedimento, $atendimento->faa->paciente->cidadao->idade['anos']) : null), ]; if (is_numeric($params['quantidade'] ?? null)) { $rules["procedimentos.{$i}.procedimento_id"][] = new Quantidade( $procedimento, $params['quantidade'] ); } $rules["procedimentos.{$i}.cid_principal_id"] = [ 'nullable', Rule::requiredIf(fn () => $procedimento->hasCidPrincipal), 'integer', $procedimento->hasCidPrincipal ? Rule::in($procedimento->cidsPrincipais()->pluck('id')) : 'exists:\App\Models\Sigtap\Cid,id', ]; $rules["procedimentos.{$i}.quantidade"] = [ 'required', 'integer', 'min:1', ]; } } return $rules; } private function getDuplicatedValidator($procedimentos, $index) { return function ($attribute, $value, $fail) use ($procedimentos, $index) { foreach ($procedimentos as $j => $params) { if ($index === $j || !isset($params['procedimento_id'])) { continue; } if ($value == $params['procedimento_id']) { $fail('O campo ' . $attribute . ' campo tem um valor duplicado.'); } } }; } private function getPostPrescricoesInternaRules() { $rule = [ 'prescricao_interna_aplicacoes' => [ 'nullable', 'array', ], 'prescricao_interna_aplicacoes.*.id' => [ 'required', 'integer', 'exists:\App\Models\ProntoAtendimento\Atendimento\PrescricaoInternaMedicamentoAplicacao,id' ], 'prescricao_interna_aplicacoes.*.status_id' => [ 'required', 'integer', Rule::in(ExameStatus::SOLICITADO, ExameStatus::REALIZADO, ExameStatus::NAO_REALIZADO), 'exists:\App\Models\Parametrizacao\Exame\ExameStatus,id', ] ]; return $rule; } private function getPostPedidoExamesRules($atendimento) { $rules = [ 'pedidos_exames' => [ 'nullable', 'array', ], 'pedidos_exames.*.data_solicitacao' => [ 'nullable', 'date_format:d/m/Y', ], 'pedidos_exames.*.unidade_encaminhamento_id' => [ 'nullable', 'integer', 'exists:\App\Models\Cadastro\Estabelecimento\Unidade,id', ], 'pedidos_exames.*.unidade_externa_encaminhamento_id' => [ 'nullable', 'integer', 'exists:\App\Models\Cadastro\UnidadeExterna,id' ], 'pedidos_exames.*.medico_solicitante_encaminhamento' => [ 'nullable', 'string', 'between:6,150', new NomeCompleto, ], ]; foreach (($this->pedidos_exames ?? []) as $i => $pedidoExames) { $rules = array_merge($rules, [ "pedidos_exames.{$i}.id" => [ 'nullable', 'integer', ], "pedidos_exames.{$i}.urgente" => [ 'nullable', "required_without:pedidos_exames.{$i}.id", 'boolean', ], "pedidos_exames.{$i}.justificativa" => [ 'nullable', 'string', 'max:100', ], "pedidos_exames.{$i}.exames" => [ 'required', 'array', ], ]); foreach ($pedidoExames['exames'] as $j => $item) { $rules = array_merge($rules, [ "pedidos_exames.{$i}.exames.{$j}.id" => [ 'nullable', "required_with:pedidos_exames.{$i}.id", 'integer', 'exists:\App\Models\ProntoAtendimento\PedidoExame\Item,id' ], "pedidos_exames.{$i}.exames.{$j}.status_id" => [ 'nullable', 'integer', 'exists:\App\Models\Parametrizacao\Exame\ExameStatus,id' ], "pedidos_exames.{$i}.exames.{$j}.horario_realizacao" => [ Rule::requiredIf(fn () => $this->isRealizado($item['status_id'])), 'nullable', 'date_format:H:i:s', ], "pedidos_exames.{$i}.exames.{$j}.observacao" => [ 'nullable', 'string', 'min:1', 'max:1000' ], "pedidos_exames.{$i}.exames.{$j}.exame_id" => [ 'required', $this->getDistinctExameValidator($pedidoExames, $item, $j), 'integer', 'exists:\App\Models\Parametrizacao\Exame\Exame,id', ], ]); if (!$this->isRealizado($item['status_id'] ?? null)) { continue; } if (!$atendimento->faa->paciente->is_desconhecido) { $rules["pedidos_exames.{$i}.exames.{$j}.exame_id"] = array_merge($rules["pedidos_exames.{$i}.exames.{$j}.exame_id"], [ $this->getHasDataNascimentoValidator($atendimento), ]); } } } return $rules; } private function getDistinctExameValidator($pedidoExames, $currentItem, $currentIndex) { return function ($value, $attribute, $fail) use ($pedidoExames, $currentIndex, $currentItem) { foreach ($pedidoExames['exames'] as $i => $item) { if ($currentIndex != $i && $currentItem['exame_id'] == $item['exame_id']) { return $fail(":attribute possui valor duplicado."); } } }; } private function getHasDataNascimentoValidator(Atendimento $atendimento) { return function ($value, $attribute, $fail) use ($atendimento) { if ($this->isNullIdade($atendimento)) { $fail("O :attribute exige que a data de nascimento do paciente seja preenchida!"); } }; } private function isRealizado(?int $statusId) { return $statusId === ExameStatus::REALIZADO; } private function getOcupacaoProfissionalLogado() { return Lotacao::find(auth()->payload()->get('lotacao_id'))->ocupacao; } private function isNullIdade(Atendimento $atendimento) { return is_null($atendimento->faa->paciente->cidadao->idade ?? null); } private function getPostFinalizacaoRules(Atendimento $atendimento) { $rules = [ 'finalizacao' => [ 'nullable', 'array', ], ]; return array_merge( $rules, [ 'finalizacao.desfecho_id' => [ Rule::requiredIf($this->hasFinalizacao()), 'integer', $this->getDesfechoValidator($atendimento), 'exists:\App\Models\ProntoAtendimento\Atendimento\Desfecho,id', ], 'finalizacao.evasao' => [ 'nullable', 'required_if:finalizacao.desfecho_id,' . Desfecho::EVASAO, 'array', ], 'finalizacao.evasao.motivo' => [ 'nullable', 'required_if:finalizacao.desfecho_id,' . Desfecho::EVASAO, 'string', 'max:200' ], ] ); } private function getDesfechoValidator($atendimento) { return function ($attribute, $value, $fail) use ($atendimento) { switch ($value) { case Desfecho::PACIENTE_ATENDIDO: { if (!$this->isDesfechoPacienteAtendidoValid($value, $atendimento)) { return $fail(":attribute selecionado é inválido."); } break; } case Desfecho::ALTA_MEDICA: { if (!$this->isDesfechoAltaMedicaValid($value, $atendimento)) { return $fail(":attribute selecionado é inválido."); } break; } } }; } private function isDesfechoPacienteAtendidoValid(int $desfecho, Atendimento $atendimento) { $atendimentosMedico = $atendimento->atendimentosMedico; return $desfecho === Desfecho::PACIENTE_ATENDIDO && $atendimentosMedico->count() === 0; } private function isDesfechoAltaMedicaValid(int $desfecho, Atendimento $atendimento) { $atendimentoMedico = $atendimento->atendimentosMedico->sortByDesc('created_at')->first(); return !is_null($atendimentoMedico) && $desfecho === Desfecho::ALTA_MEDICA && !$atendimentoMedico->solicitou_reavaliacao; } private function hasFinalizacao() { return isset($this->finalizacao); } public function messages() { $cboNotAllowd = 'Não permitido para a CBO logado'; return [ 'diagnostico.in' => $cboNotAllowd, 'planejamento.in' => $cboNotAllowd, 'implementacao.in' => $cboNotAllowd, 'avaliacao.in' => $cboNotAllowd, ]; } }