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' => [ 'required', 'integer', 'exists:\App\Models\ProntoAtendimento\ClassificacaoRisco\ClassificacaoRisco,id' ], 'quarto' => [ 'nullable', 'string', 'max:5' ], 'leito' => [ 'nullable', 'string', 'max:5' ], 'medicamentos_uso' => [ 'nullable', 'string', 'max:3000', ], 'fator_risco_outro' => [ 'nullable', Rule::requiredIf(fn () => in_array(FatorRisco::OUTRO, $this->fatores_risco ?? [])), 'string', 'max:100', ], 'aguardando_vaga_hospitalar' => [ 'required', 'boolean' ], 'hemorragia_externa_grave_trauma_status_id' => [ 'nullable', 'integer', Rule::in([PacienteTraumaStatusEnum::AUSENTE, PacienteTraumaStatusEnum::PRESENTE]), 'exists:\App\Models\ProntoAtendimento\Atendimento\PacienteTraumaStatus,id' ], 'hemorragia_externa_grave_local' => [ 'nullable', "required_if:hemorragia_externa_grave_trauma_status_id," . PacienteTraumaStatusEnum::PRESENTE, 'string', 'max:100', ], 'vias_aerias_trauma_status_id' => [ 'nullable', 'integer', Rule::in([PacienteTraumaStatusEnum::PERVEAS, PacienteTraumaStatusEnum::OBSTRUCAO]), 'exists:\App\Models\ProntoAtendimento\Atendimento\PacienteTraumaStatus,id' ], 'vias_aerias_obstrucao_por' => [ 'nullable', "required_if:vias_aerias_trauma_status_id," . PacienteTraumaStatusEnum::OBSTRUCAO, 'string', 'max:100', ], 'oxigenacao_respiracao_ventilacao_trauma_status_id' => [ 'nullable', 'integer', Rule::in([ PacienteTraumaStatusEnum::AUSENTE, PacienteTraumaStatusEnum::PRESENTE, PacienteTraumaStatusEnum::SIMETRICA, PacienteTraumaStatusEnum::ASSIMETRICA, ]), 'exists:\App\Models\ProntoAtendimento\Atendimento\PacienteTraumaStatus,id' ], 'pulso_trauma_status_id' => [ 'nullable', 'integer', Rule::in([PacienteTraumaStatusEnum::AUSENTE, PacienteTraumaStatusEnum::PRESENTE]), 'exists:\App\Models\ProntoAtendimento\Atendimento\PacienteTraumaStatus,id' ], 'pele_trauma_status_id' => [ 'nullable', 'integer', Rule::in([PacienteTraumaStatusEnum::NORMAL, PacienteTraumaStatusEnum::ALTERACOES]), 'exists:\App\Models\ProntoAtendimento\Atendimento\PacienteTraumaStatus,id' ], 'pele_alteracao' => [ 'nullable', "required_if:pele_trauma_status_id," . PacienteTraumaStatusEnum::ALTERACOES, 'string', 'max:100', ], 'perfuracao_trauma_status_id' => [ 'nullable', 'integer', Rule::in([PacienteTraumaStatusEnum::NORMAL, PacienteTraumaStatusEnum::LENTIFICADA]), 'exists:\App\Models\ProntoAtendimento\Atendimento\PacienteTraumaStatus,id' ], 'perfuracao_lentificada' => [ 'nullable', "required_if:perfuracao_trauma_status_id," . PacienteTraumaStatusEnum::LENTIFICADA, 'numeric', 'digits_between:1,3', ], 'sangramento_trauma_status_id' => [ 'nullable', 'integer', Rule::in([PacienteTraumaStatusEnum::AUSENTE, PacienteTraumaStatusEnum::PRESENTE]), 'exists:\App\Models\ProntoAtendimento\Atendimento\PacienteTraumaStatus,id' ], 'sangramento_local' => [ 'nullable', "required_if:sangramento_trauma_status_id," . PacienteTraumaStatusEnum::PRESENTE, 'string', 'max:100', ], 'pupilas_trauma_status_id' => [ 'nullable', 'integer', Rule::in([ PacienteTraumaStatusEnum::ISOCORICAS, PacienteTraumaStatusEnum::MIDRIASE, PacienteTraumaStatusEnum::ANISOCORIA, ]), 'exists:\App\Models\ProntoAtendimento\Atendimento\PacienteTraumaStatus,id' ], 'paresias_trauma_status_id' => [ 'nullable', 'integer', Rule::in([PacienteTraumaStatusEnum::AUSENTE, PacienteTraumaStatusEnum::PRESENTE]), 'exists:\App\Models\ProntoAtendimento\Atendimento\PacienteTraumaStatus,id' ], 'plegia_trauma_status_id' => [ 'nullable', 'integer', Rule::in([PacienteTraumaStatusEnum::AUSENTE, PacienteTraumaStatusEnum::PRESENTE]), 'exists:\App\Models\ProntoAtendimento\Atendimento\PacienteTraumaStatus,id' ], 'exposicao_hipotermia_trauma_status_id' => [ 'nullable', 'integer', Rule::in([PacienteTraumaStatusEnum::SEM_LESOES, PacienteTraumaStatusEnum::COM_LESOES]), 'exists:\App\Models\ProntoAtendimento\Atendimento\PacienteTraumaStatus,id' ], 'exposicao_hipotermia_observacao' => [ 'nullable', "required_if:exposicao_hipotermia_trauma_status_id," . PacienteTraumaStatusEnum::COM_LESOES, 'string', 'max:100', ], 'avaliacao_cabeca_pescoco' => [ 'nullable', 'string', 'max:3000', ], 'avaliacao_torax' => [ 'nullable', 'string', 'max:3000', ], 'avaliacao_abdome' => [ 'nullable', 'string', 'max:3000', ], 'avaliacao_mmss_mmii' => [ 'nullable', 'string', 'max:3000', ], 'observacao' => [ 'nullable', 'string', 'max:3000', ], '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' ], ]); return array_merge( $rules, $this->getPostAlergiaRules(), $this->getPostFatorRiscoRules(), $this->getPostSinaisVitaisRules(), $this->getPostAvaliacaoAntropometricaRules(), $this->getPostGestacaoRules(), $this->getPostAnotacaoRules(), $this->getPostServicosEnfermagemRules($atendimento), $this->getPostProcedimentosRules($atendimento), $this->getPostPrescricoesInternaRules($atendimento), $this->getPostEscalasComaGlasgowRules($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 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 getPostFatorRiscoRules() { return [ 'fatores_risco' => [ 'nullable', 'array', ], 'fatores_risco.*' => [ 'required', 'integer', 'exists:\App\Models\Cadastro\SujeitoAtencao\FatorRisco,id', ], ]; } 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:d/m/Y', 'before_or_equal:now', ], ]); } return $rules; } private function getPostAnotacaoRules() { $rules = [ 'anotacao' => [ 'nullable', 'array', ], ]; if (is_array($this->anotacao ?? null)) { $rules = array_merge($rules, [ 'anotacao.*.anotado_em' => [ 'required', 'date_format:d/m/Y H:i', 'before_or_equal:now', ], 'anotacao.*.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}.status_id"] = [ 'nullable', 'integer', Rule::in(ExameStatus::REALIZADO, ExameStatus::SOLICITADO, ExameStatus::NAO_REALIZADO), 'exists:\App\Models\Parametrizacao\Exame\ExameStatus,id', ]; $procedimento = is_numeric($param['procedimento_id'] ?? null) ? Procedimento::findOrFail($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->getDuplicatedValidator($this->servicos_enfermagem, $i), $this->getDuplicatedServicoEnfermagemOnAtendimentoValidator($atendimento, $this->servicos_enfermagem[$i]), $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 getDuplicatedServicoEnfermagemOnAtendimentoValidator($atendimento, $currentServicoEnfermagem) { return function ($attribute, $value, $fail) use ($atendimento, $currentServicoEnfermagem) { $found = false; $atendimentos = []; $servicosEnfermagem = $this->getServicosEnfermagem($atendimento); foreach ($servicosEnfermagem as $servicoEnfermagem) { $found = is_null($currentServicoEnfermagem['id'] ?? null) && $servicoEnfermagem->procedimento_id === (int)$value; if ($found) { break; } } if ($found) { $fail('O ' . $attribute . ' já foi cadastrado!'); } }; } private function getMatchProcedimentoIdAndServicoEnfermagemIdValidator($atendimento, $currentServicoEnfermagem) { return function ($attribute, $value, $fail) use ($atendimento, $currentServicoEnfermagem) { if (is_null($currentServicoEnfermagem['id'] ?? null)) return; $found = false; $atendimentos = []; $servicosEnfermagem = $this->getServicosEnfermagem($atendimento); foreach ($servicosEnfermagem as $servicoEnfermagem) { $found = $currentServicoEnfermagem['id'] == $servicoEnfermagem->id && $currentServicoEnfermagem['procedimento_id'] == $servicoEnfermagem->procedimento_id; if ($found) { break; } } if (!$found) { $fail('O ' . $attribute . ' não é válido para o serviço de enfermagem!'); } }; } private function getServicosEnfermagem($atendimento) { return ServicoEnfermagem::whereHas('atendimentoMedico', function ($query) use ($atendimento) { $query->where('atendimento_id', $atendimento->id); }) ->orWhereHas('atendimentoEnfermagem', function ($query) use ($atendimento) { $query->where('atendimento_id', $atendimento->id); }) ->orWhereHas('pacienteObservacao', function ($query) use ($atendimento) { $query->where('atendimento_id', $atendimento->id); }) ->get(); } private function getPostProcedimentosRules($atendimento) { $rules = [ 'procedimentos' => [ 'nullable', 'array', ], ]; 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)) { $quantidade = $atendimento->procedimentos ->where('procedimento_id', $procedimento->id) ->sum('quantidade') + $params['quantidade']; foreach (($this->servicos_enfermagem ?? []) as $servico) { if ($servico['procedimento_id'] == $params['procedimento_id']) { $quantidade++; } } $rules["procedimentos.{$i}.procedimento_id"][] = new Quantidade($procedimento, $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($servicosEnfermagem, $index) { return function ($attribute, $value, $fail) use ($servicosEnfermagem, $index) { foreach ($servicosEnfermagem 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 getPostEscalasComaGlasgowRules() { $rules = [ 'escala_coma_glasgow' => [ 'nullable', 'array', ], ]; if (is_array($this->escala_coma_glasgow ?? null)) { $rules = array_merge($rules, [ '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 $rules; } private function getPostPedidoExamesRules($atendimento) { $rules = [ 'pedidos_exames' => [ 'nullable', 'array', ], 'pedidos_exames.*.exames.*.data_solicitacao' => [ 'nullable', 'date_format:d/m/Y', ], 'pedidos_exames.*.exames.*.unidade_solicitante' => [ 'nullable', 'string', 'max:255' ], 'pedidos_exames.*.exames.*.medico_solicitante' => [ 'nullable', 'string', 'max:255' ], ]; 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', "required_without:pedidos_exames.{$i}.id", '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), ]); } $item = is_numeric($item['exame_id']) ? Exame::find($item['exame_id']) : null; if (is_null($item) || $this->isNullIdade($atendimento)) { continue; } $procedimento = Procedimento::where('codigo', $item->codigo) ->orderByDesc('competencia_id') ->first(); $rules["pedidos_exames.{$i}.exames.{$j}.exame_id"] = array_merge($rules["pedidos_exames.{$i}.exames.{$j}.exame_id"], [ new ValidCompetencia($procedimento), ($atendimento->faa->paciente->cidadao->idade ? new Idade($procedimento, $atendimento->faa->paciente->cidadao->idade['anos']) : null), new Quantidade($procedimento, 1), new SexoRule($procedimento, $atendimento->faa->paciente->cidadao->sexo), ]); } } 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 isNullIdade(Atendimento $atendimento) { return is_null($atendimento->faa->paciente->cidadao->idade ?? null); } private function getPostFinalizacaoRules($atendimento) { $rules = [ 'finalizacao' => [ 'nullable', 'array', ], 'finalizacao.data_hora' => [ Rule::requiredIf(fn () => $this->hasFinalizacao()), 'date_format:d/m/Y H:i', ], ]; return array_merge( $rules, $this->getPostFinalizacaoDesfechoRules($atendimento) ); } private function getFinalizacaoValidator() { return function ($attribute, $value, $fail) { if (empty($this->servicos_enfermagem)) { return; } $fail('Não é permitido finalizar se existir serviços de enfermagem solicitados'); }; } private function getPostFinalizacaoDesfechoRules($atendimento) { $rules = [ 'finalizacao.desfecho_id' => [ Rule::requiredIf(fn () => $this->hasFinalizacao()), 'integer', Rule::in( Desfecho::ALTA_MEDICA, Desfecho::EVASAO, Desfecho::ENCAMINHAMENTO_HOSPITALAR, Desfecho::OBITO, ), $this->getDesfechoIdValidator($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' ], 'finalizacao.encaminhamento_hospitalar' => [ 'nullable', 'required_if:finalizacao.desfecho_id,' . Desfecho::ENCAMINHAMENTO_HOSPITALAR, 'array', ], 'desfecho.obito' => [ 'required_if:desfecho.id,' . Desfecho::OBITO, 'array', ], ]; if (!is_null($this->finalizacao['encaminhamento_hospitalar'] ?? null)) { $rules = array_merge($rules, [ 'finalizacao.encaminhamento_hospitalar.unidade_id' => [ 'nullable', Rule::requiredIf(fn () => $this->finalizacao && $this->finalizacao['desfecho_id'] === Desfecho::ENCAMINHAMENTO_HOSPITALAR && ($this->finalizacao['encaminhamento_hospitalar']['unidade_nome'] ?? null) === null ), 'integer', 'exists:\App\Models\Cadastro\Estabelecimento\Unidade,id', ], 'finalizacao.encaminhamento_hospitalar.unidade_nome' => [ 'nullable', Rule::requiredIf(fn () => $this->finalizacao && $this->finalizacao['desfecho_id'] === Desfecho::ENCAMINHAMENTO_HOSPITALAR && ($this->finalizacao['encaminhamento_hospitalar']['unidade_id'] ?? null) === null ), 'string', 'max:100', ], 'finalizacao.encaminhamento_hospitalar.lotacao_id' => [ 'required', 'integer', 'exists:\App\Models\Cadastro\SujeitoAtencao\Lotacao,id', ], 'finalizacao.encaminhamento_hospitalar.quarto' => [ 'nullable', 'string', 'max:3', ], 'finalizacao.encaminhamento_hospitalar.leito' => [ 'nullable', 'string', 'max:3', ], 'finalizacao.encaminhamento_hospitalar.cid_id' => [ 'nullable', 'integer', 'exists:\App\Models\Sigtap\Cid,id', ], 'finalizacao.encaminhamento_hospitalar.medico_hospitalar' => [ 'nullable', 'string', 'max:150', new NomeCompleto, ], 'finalizacao.encaminhamento_hospitalar.observacoes' => [ 'nullable', 'string', 'max:3000', ], ] ); } if (is_array($this->desfecho['obito'] ?? null)) { $rules = array_merge($rules, [ 'desfecho.obito.obito_em' => [ 'required', 'date_format:d/m/Y H:i', $this->getObitoEmValidator($atendimento), ], 'desfecho.obito.declaracao' => [ 'required', 'string', 'min:8', 'max:13' ], 'desfecho.obito.causa' => [ 'required', 'string', 'max:255' ], 'desfecho.obito.cid_id' => [ 'required', 'integer', 'exists:\App\Models\Sigtap\Cid,id' ] ]); } return $rules; } private function getObitoEmValidator($atendimento) { return function ($attribute, $value, $fail) use ($atendimento) { if (!$atendimento->faa->paciente->cidadao->data_nascimento) { return; } $dataAtual = Carbon::today(); $dataNascimento = $atendimento->faa->paciente->cidadao->data_nascimento; $dataObito = Carbon::createFromFormat('d/m/Y H:i', $value); $diffObitoDataNascimento = $dataNascimento->diffInDays($dataObito, false); $diffObitoDataAtual = $dataAtual->diffInDays($dataObito, false); if ($diffObitoDataNascimento < 0 || $diffObitoDataAtual > 0) { $fail("A data inserida deve ser entre a data de nascimento {$dataNascimento->format('d/m/Y')} e a data atual."); } }; } private function hasFinalizacao() { return isset($this->finalizacao); } private function getDesfechoIdValidator($atendimento) { return function ($attribute, $value, $fail) use ($atendimento) { $desfechoIdRequest = $this->finalizacao['desfecho_id']; if ($desfechoIdRequest !== Desfecho::OBITO && $desfechoIdRequest !== Desfecho::ALTA_MEDICA) { return; } $atendimentoMedico = $atendimento->atendimentosMedico->last(); $desfechoIdAtendimentoMedico = $atendimentoMedico->desfecho_id ?? null; if ($desfechoIdRequest === Desfecho::ALTA_MEDICA && $desfechoIdAtendimentoMedico === Desfecho::ALTA_MEDICA) { return; } if ($desfechoIdRequest === Desfecho::OBITO && $desfechoIdAtendimentoMedico === Desfecho::OBITO) { return; } $fail("O campo finalizacao.desfecho id é inválido!"); }; } private function getOcupacaoProfissionalLogado() { return Lotacao::find(auth()->payload()->get('lotacao_id'))->ocupacao; } }