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; } $centroCustoLogado = $this->getCentroCustoLogado(); $parametrizacao = ParametrizacaoAtendimentoMedicoService::get($centroCustoLogado->infraestrutura_id); $isAtendimentoSimples = $parametrizacao->tipo_id === TipoAtendimento::SIMPLES; $isReavaliacao = $atendimento->atendimentosMedico()->get()->isNotEmpty(); $isPrimeiroAtendimentoSimples = !$isReavaliacao && $isAtendimentoSimples; $isPrimeiroAtendimentoEstruturado = !$isReavaliacao && !$isAtendimentoSimples; $raatObrigatorio = !is_null($this->desfecho['id'] ?? null) && $atendimento->faa->isRaatAberta; $procedimentoPadrao = ParametrizacaoAtendimentoMedico::first()->procedimento_padrao ?? null; $rules = array_merge($rules, [ 'classificacao_risco_id' => [ 'required', 'integer', 'exists:\App\Models\ProntoAtendimento\ClassificacaoRisco\ClassificacaoRisco,id' ], 'evolucao' => [ 'nullable', Rule::requiredIf(fn () => $isReavaliacao), 'string', 'max:5000', ], 'atendimento_geral' => [ 'nullable', Rule::requiredIf(fn () => $isPrimeiroAtendimentoSimples), 'string', 'max:5000', ], 'queixa_principal_duracao' => [ 'nullable', ($isPrimeiroAtendimentoEstruturado ? 'required_without_all:' . 'historia,' . 'exame_fisico,' . 'diagnostico,' . 'conduta' : null), 'string', 'max:5000', ], 'historia' => [ 'nullable', ($isPrimeiroAtendimentoEstruturado ? 'required_without_all:' . 'queixa_principal_duracao,' . 'exame_fisico,' . 'diagnostico,' . 'conduta' : null), 'string', 'max:5000', ], 'exame_fisico' => [ 'nullable', ($isPrimeiroAtendimentoEstruturado ? 'required_without_all:' . 'queixa_principal_duracao,' . 'historia,' . 'diagnostico,' . 'conduta' : null), 'string', 'max:5000', ], 'diagnostico' => [ 'nullable', ($isPrimeiroAtendimentoEstruturado ? 'required_without_all:' . 'queixa_principal_duracao,' . 'historia,' . 'exame_fisico,' . 'conduta' : null), 'string', 'max:5000', ], 'conduta' => [ 'nullable', ($isPrimeiroAtendimentoEstruturado ? 'required_without_all:' . 'queixa_principal_duracao,' . 'historia,' . 'exame_fisico,' . 'diagnostico' : null), 'string', 'max:5000', ], 'observacoes' => [ 'nullable', 'string', 'max:5000', ], 'dor_toracica_resultado_eletrocardiograma' => [ 'nullable', 'string', 'max:5000', ], 'dor_toracica_protocolo_finalizado' => [ 'nullable', 'boolean', ], 'dor_toracica_protocolo_tem_prosseguimento' => [ 'nullable', 'boolean', ], 'dor_toracica_tem_contra_indicacao_trombolitico' => [ 'nullable', 'boolean', ], 'dor_toracica_contra_indicacao_trombolitico_motivo' => [ 'nullable', 'string', 'max:200', ], 'dor_toracica_sinais_instabilidade' => [ 'present', 'array', ], 'dor_toracica_sinais_instabilidade.*' => [ 'present', 'integer', ], 'doencas_cronicas' => [ 'nullable', 'string', 'max:3000', ], 'cid_id' => [ 'nullable', Rule::requiredIf(fn () => !$isReavaliacao), 'integer', ], 'orientacoes' => [ 'nullable', 'string', 'between:2,3000', ], 'centro_custo_id_para' => [ 'nullable', Rule::requiredIf(fn () => !$this->hasFinalizacao() && !$this->fromObservacao($atendimento)), 'integer', 'exists:\App\Models\Cadastro\Estabelecimento\CentroCusto,id', ], 'observacoes_enfermagem' => [ 'nullable', 'string', 'max:5000', ], 'data_hora_proxima_reavaliacao' => [ 'bail', 'nullable', Rule::requiredIf(fn () => $this->fromObservacao($atendimento) && is_null($this->desfecho['id'] ?? null) || ( $this->isCentroCustoParaObservacao($this->centro_custo_id_para) && !$this->fromObservacao($atendimento) && is_null($this->desfecho['id'] ?? null) ) ), 'date_format:d/m/Y H:i', function ($attribute, $value, $fail) { if (!$value) return; $dataAtual = Carbon::now(); $dataLimite = $dataAtual->copy()->modify('+24 hours'); $dataProximaReavaliacao = Carbon::createFromFormat('d/m/Y H:i', $value); if ($dataProximaReavaliacao <= $dataAtual) { $fail("Data/hora da próxima reavaliação deve ser maior " . "que {$dataAtual->format('d/m/Y H:i')}."); } else if ($dataProximaReavaliacao > $dataLimite) { $fail("Data/hora da próxima reavaliação deve ser menor ou " . "igual a {$dataLimite->format('d/m/Y H:i')}."); } }, ], 'fatores_risco' => [ 'nullable', 'array', ], 'fatores_risco.*' => [ 'integer', 'exists:\App\Models\Cadastro\SujeitoAtencao\FatorRisco,id', ], 'fator_risco_outro' => [ 'nullable', Rule::requiredIf(fn () => in_array(FatorRisco::OUTRO, $this->fatores_risco ?? [])), 'string', 'max:100', ], '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->getPostMedicamentosUsoRules(), $this->getPostSinaisVitaisRules(), $this->getPostAvaliacaoAntropometricaRules(), $this->getPostGestacaoRules(), $this->getPostAtestadoRules(), $this->getPostReceitaMedicaRules(), $this->getPostPrescricaoInternaRules(), $this->getPostEncaminhamentosRules(), $this->getPostDeclaracoesComparecimentoRules(), $this->getPostRaatRules($raatObrigatorio), $this->getPostProcedimentosRules($isReavaliacao, $atendimento, $procedimentoPadrao), $this->getPostPedidoExameRules($atendimento), $this->getPostServicosEnfermagemRules($atendimento), $this->getPostDesfechoRules($atendimento), $this->getPostFinalizacaoRules($atendimento, $raatObrigatorio), ); } private function fromObservacao($atendimento) { return $atendimento->fila->centroCusto->setor->tipo_id === SetorTipo::OBSERVACAO; } private function isCentroCustoParaObservacao($centroCustoIdPara) { if (is_null($centroCustoIdPara)) { return false; } $centroCustoPara = CentroCusto::findOrFail($centroCustoIdPara); return $centroCustoPara->setor->tipo_id === SetorTipo::OBSERVACAO; } 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 getPostMedicamentosUsoRules() { return [ 'medicamentos_uso' => [ 'nullable', 'string', 'max:3000', ], ]; } 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 getPostAtestadoRules() { $modeloId = (int) ($this->atestado['modelo_id'] ?? AtestadoModelo::PADRAO); $rules = [ 'atestado' => [ 'nullable', 'array' ], ]; if (is_array($this->atestado ?? null)) { $rules = array_merge($rules, [ 'atestado.modelo_id' => [ 'required', 'integer', Rule::in([ AtestadoModelo::PADRAO, AtestadoModelo::PERIODO_MANHA, AtestadoModelo::PERIODO_TARDE, AtestadoModelo::PERIODO_NOITE, AtestadoModelo::QUANTIDADE_HORAS, ]), ], 'atestado.dias' => [ 'nullable', Rule::requiredIf(fn () => $modeloId === AtestadoModelo::PADRAO), 'integer', 'max:999' ], 'atestado.quantidade_horas' => [ 'nullable', Rule::requiredIf(fn () => $modeloId === AtestadoModelo::QUANTIDADE_HORAS), 'integer', 'between:1,24', ], 'atestado.horario_inicial' => [ 'nullable', Rule::requiredIf(fn () => $modeloId === AtestadoModelo::QUANTIDADE_HORAS), 'date_format:H:i', ], 'atestado.documento_tipo_id' => [ 'required', 'integer', 'exists:\App\Models\Geral\DocumentoTipo,id' ], 'atestado.documento_numero' => [ 'required', ($this->atestado['paciente'] == 1 ? 'digits_between:2,20' : ''), ], ]); } return $rules; } private function getPostReceitaMedicaRules() { $rules = [ 'receitas_medicas_assinadas' => [ 'present', 'array', ], 'receitas_medicas_assinadas.*' => [ 'array', ], 'receitas_medicas_assinadas.*.*' => [ 'string', ], 'receita_medica' => [ 'nullable', 'array' ], ]; if (is_array($this->receita_medica ?? null)) { $rules["receita_medica.is_assinada"] = [ 'required', 'boolean', ]; $rules["receita_medica.medicamentos"] = [ 'present', 'array', ]; if (is_array($this->receita_medica['medicamentos'] ?? null)) { foreach ($this->receita_medica['medicamentos'] as $i => $params) { $rules["receita_medica.medicamentos.{$i}.medicamento_id"] = [ 'nullable', 'integer', ]; $rules["receita_medica.medicamentos.{$i}.tipo_aplicacao"] = [ 'required', 'string', Rule::in(['dose_unica', 'uso_continuo', 'livre', 'padrao']) ]; if (!is_numeric($params['medicamento_id'] ?? null) || !is_string($params['tipo_aplicacao'] ?? null) ) { continue; } $rules["receita_medica.medicamentos.{$i}.via_administracao_outras"] = [ 'nullable', Rule::requiredIf(fn () => (Medicamento::find($params['medicamento_id']) ->via_administracao_id ?? null) === ViaAdministracao::OUTRAS ), 'string', 'max:100' ]; $usoContinuo = $params['tipo_aplicacao'] === 'uso_continuo'; $livre = $params['tipo_aplicacao'] === 'livre'; $padrao = $params['tipo_aplicacao'] === 'padrao'; $rules["receita_medica.medicamentos.{$i}.tipo_posologia"] = [ 'nullable', Rule::requiredIf(fn () => $padrao || $usoContinuo), Rule::in([TipoPosologia::FREQUENCIA, TipoPosologia::TURNO]), 'string', ]; $rules["receita_medica.medicamentos.{$i}.quantidade"] = [ 'nullable', Rule::requiredIf(fn () => !$livre), 'numeric', 'between:0.1,999', ]; if (is_string($params['tipo_posologia'] ?? null)) { $posologiaPorFrequencia = $params['tipo_posologia'] === TipoPosologia::FREQUENCIA; $posologiaPorTurno = $params['tipo_posologia'] === TipoPosologia::TURNO; $rules["receita_medica.medicamentos.{$i}.intervalo_tempo"] = [ 'nullable', Rule::requiredIf(fn () => $posologiaPorFrequencia), 'integer', 'between:1,999', ]; $rules["receita_medica.medicamentos.{$i}.intervalo_medida_tempo_id"] = [ 'nullable', Rule::requiredIf(fn () => $posologiaPorFrequencia), 'integer', 'exists:\App\Models\Geral\MedidaTempo,id', ]; $rules["receita_medica.medicamentos.{$i}.turno_id"] = [ 'nullable', Rule::requiredIf(fn () => $posologiaPorTurno), 'integer', 'exists:\App\Models\Geral\Turno,id', ]; } $rules["receita_medica.medicamentos.{$i}.durante_tempo"] = [ 'nullable', Rule::requiredIf(fn () => $padrao), 'between:1,999', ]; $rules["receita_medica.medicamentos.{$i}.durante_medida_tempo_id"] = [ 'nullable', Rule::requiredIf(fn () => $padrao), 'integer', 'exists:\App\Models\Geral\MedidaTempo,id', ]; $rules["receita_medica.medicamentos.{$i}.recomendacoes"] = [ 'nullable', 'string', 'max:250', ]; $rules["receita_medica.medicamentos.{$i}.descricao"] = [ 'nullable', Rule::requiredIf(fn () => $livre), 'string', 'max:250', ]; $rules["receita_medica.medicamentos.{$i}.medicamento_manual"] = [ 'nullable', 'string', 'max:500', ]; $rules["receita_medica.medicamentos.{$i}.prescricao_manual"] = [ 'nullable', 'string', 'max:5000', ]; } } } return $rules; } private function getPostPrescricaoInternaRules() { $rules = [ 'prescricoes_internas' => [ 'nullable', 'array', ], ]; if (is_array($this->prescricoes_internas ?? null)) { foreach ($this->prescricoes_internas as $i => $prescricaoInterna) { $rules["prescricoes_internas.{$i}.dose_unica"] = [ 'required', 'boolean', ]; $rules["prescricoes_internas.{$i}"][] = function ($attribute, $value, $fail) use ($prescricaoInterna) { $faltando = false; if (!isset($prescricaoInterna['dose_unica'])) { $faltando = true; } if ( isset($prescricaoInterna['dose_unica']) && RequestUtil::isAcceptedBoolean($prescricaoInterna['dose_unica']) && !((bool) $prescricaoInterna['dose_unica']) ) { if ( empty($prescricaoInterna['frequencia_quantidade_vezes']) || empty($prescricaoInterna['frequencia_tempo']) || empty($prescricaoInterna['frequencia_medida_tempo_id']) ) { $faltando = true; } } if (empty($prescricaoInterna['medicamentos']) || !is_array($prescricaoInterna['medicamentos'])) { $faltando = true; } if ($faltando) { $fail('Acessar a Prescrição Interna e preencher os campos corretamente.'); } }; if (RequestUtil::isAcceptedBoolean($prescricaoInterna['dose_unica'] ?? null) && !((bool) $prescricaoInterna['dose_unica']) ) { $rules["prescricoes_internas.{$i}.frequencia_quantidade_vezes"] = [ 'required', 'integer', 'between:1,999', ]; $rules["prescricoes_internas.{$i}.frequencia_tempo"] = [ 'required', 'integer', 'between:1,999', ]; $rules["prescricoes_internas.{$i}.frequencia_medida_tempo_id"] = [ 'required', 'integer', 'exists:\App\Models\Geral\MedidaTempo,id', ]; } $rules["prescricoes_internas.{$i}.observacoes"] = [ 'nullable', 'string', 'max:250' ]; $rules["prescricoes_internas.{$i}.medicamentos"] = [ 'required', 'array', ]; if (!is_array($prescricaoInterna['medicamentos'] ?? null)) { continue; } foreach ($prescricaoInterna['medicamentos'] as $j => $params) { $medicamento = is_numeric($params['medicamento_id'] ?? null) ? Medicamento::find($params['medicamento_id']) : null; $rules["prescricoes_internas.{$i}.medicamentos.{$j}.medicamento_id"] = [ 'required', 'integer', ]; $rules["prescricoes_internas.{$i}.medicamentos.{$j}.unidade_medida_id"] = [ 'nullable', 'integer', ]; $rules["prescricoes_internas.{$i}.medicamentos.{$j}.quantidade"] = [ 'required', 'numeric', 'between:0.1,99', ]; $rules["prescricoes_internas.{$i}.medicamentos.{$j}.administracao"] = [ 'nullable', 'string', 'max:3000', ]; if (is_null($medicamento)) { continue; } $rules["prescricoes_internas.{$i}.medicamentos.{$j}.medicamento_id"][] = function ($attribute, $value, $fail) use ($j, $prescricaoInterna) { foreach ($prescricaoInterna['medicamentos'] as $k => $params) { if ($j === $k || !isset($params['medicamento_id'])) { continue; } if ($value == $params['medicamento_id']) { $fail('O campo ' . $attribute . ' campo tem um valor duplicado.'); } } }; } } } return $rules; } private function isPrescricaoDuplicada($medicamentos, $currentIndex) { $idsMedicamentosAtual = []; foreach ($medicamentos as $params) { if (!isset($params['medicamento_id'])) { return false; } $idsMedicamentosAtual[] = $params['medicamento_id']; } foreach ($this->prescricoes_internas as $j => $prescricaoInterna) { if ($currentIndex === $j) { continue; } $idsMedicamentos = []; foreach ($prescricaoInterna['medicamentos'] as $params) { if (!isset($params['medicamento_id'])) { continue 2; } $idsMedicamentos[] = $params['medicamento_id']; } if (count($idsMedicamentosAtual) === count($idsMedicamentos) && empty(array_diff($idsMedicamentosAtual, $idsMedicamentos)) ) { return true; } } return false; } private function getPostEncaminhamentosRules() { return [ 'encaminhamentos' => [ 'nullable', 'array', ], 'encaminhamentos.*.urgente' => [ 'required', 'boolean', ], 'encaminhamentos.*.ocupacao_id' => [ 'required', 'integer', 'distinct', 'exists:\App\Models\Sigtap\Ocupacao,id', ], 'encaminhamentos.*.motivo' => [ 'required', 'string', 'max:300', ], 'encaminhamentos.*.observacoes' => [ 'nullable', 'string', 'max:300', ], ]; } private function getPostDeclaracoesComparecimentoRules() { $rules = [ 'declaracoes_comparecimento' => [ 'nullable', 'array', ], ]; if (is_array($this->declaracoes_comparecimento ?? null)) { foreach ($this->declaracoes_comparecimento as $i => $declaracaoComparecimento) { $rules["declaracoes_comparecimento.{$i}.tipo_id"] = [ 'required', 'integer', 'exists:\App\Models\ProntoAtendimento\Atendimento\Medico\DeclaracaoComparecimentoTipo,id', ]; $rules["declaracoes_comparecimento.{$i}.nome"] = [ Rule::requiredIf(fn () => ($declaracaoComparecimento['tipo_id'] ?? null) == DeclaracaoComparecimentoTipo::ACOMPANHANTE), 'string', 'between:6,150', ($declaracaoComparecimento['tipo_id'] ?? null) == DeclaracaoComparecimentoTipo::ACOMPANHANTE ? new NomeCompleto : null, ($declaracaoComparecimento['tipo_id'] ?? null) == DeclaracaoComparecimentoTipo::ACOMPANHANTE ? new CnsTermoValido(['attribute' => 'Acompanhante']) : null, ]; $rules["declaracoes_comparecimento.{$i}.documento_tipo_id"] = [ 'required', 'integer', 'exists:\App\Models\Geral\DocumentoTipo,id', ]; $rules["declaracoes_comparecimento.{$i}.documento_numero"] = [ 'required', 'between:2,20', $this->getDocumentoNumeroValidation($declaracaoComparecimento['documento_tipo_id'] ?? null) ]; $rules["declaracoes_comparecimento.{$i}.de"] = [ 'required', 'date_format:Y-m-d H:i', ]; $rules["declaracoes_comparecimento.{$i}.ate"] = [ 'required', 'date_format:Y-m-d H:i', "after_or_equal:declaracoes_comparecimento.{$i}.de" ]; $rules["declaracoes_comparecimento.{$i}.motivo"] = [ 'required', 'string', 'between:2,50', ]; } } return $rules; } private function getPostRaatRules($required) { if ($this->finalizacao && ($this->finalizacao['desfecho_id'] == Desfecho::EVASAO || $this->finalizacao['desfecho_id'] == Desfecho::OBITO) ) { $required = false; } $rules = [ 'raat' => [ 'nullable', Rule::requiredIf(fn () => $required), 'array', ], ]; if (is_array($this->raat ?? null)) { $rules = array_merge($rules, [ 'raat.agente_id' => [ 'required', 'integer', 'exists:\App\Models\ProntoAtendimento\Raat\Agente,id', ], 'raat.partes_corpo_atingidas' => [ 'required', 'array', ], 'raat.partes_corpo_atingidas.*' => [ 'integer', 'exists:\App\Models\ProntoAtendimento\Raat\ParteCorpoAtingida,id', ], 'raat.parte_corpo_atingida_outras' => [ 'nullable', Rule::requiredIf(fn () => in_array( ParteCorpoAtingida::OUTROS, $this->raat['partes_corpo_atingidas'] ?? []) ), 'string', 'between:3,150', ], 'raat.causas_acidente' => [ 'required', 'array', ], 'raat.causas_acidente.*' => [ 'integer', 'exists:\App\Models\ProntoAtendimento\Raat\CausaAcidente,id', ], 'raat.causa_acidente_outras' => [ 'nullable', Rule::requiredIf(fn () => in_array( CausaAcidente::OUTROS, $this->raat['causas_acidente'] ?? []) ), 'string', 'between:3,150', ], 'raat.diagnosticos' => [ 'required', 'array', ], 'raat.diagnosticos.*' => [ 'integer', 'exists:\App\Models\ProntoAtendimento\Raat\Diagnostico,id', ], 'raat.diagnostico_outros' => [ 'nullable', Rule::requiredIf(fn () => in_array( Diagnostico::OUTROS, $this->raat['diagnosticos'] ?? []) ), 'string', 'between:3,150', ], 'raat.observacao' => [ 'nullable', 'string', 'between:3,150', ], 'raat.classificacao_inicial_id' => [ 'required', 'integer', 'exists:\App\Models\ProntoAtendimento\Raat\ClassificacaoInicial,id', ], 'raat.afastado' => [ 'required', 'boolean', ] ]); } return $rules; } private function getDocumentoNumeroValidation($documentoTipoId) { switch ($documentoTipoId) { case DocumentoTipo::CPF: { return new Cpf; } case DocumentoTipo::CNS: { return new Cns; } default: { return null; } } } private function getPostProcedimentosRules($isReavaliacao, $atendimento, $procedimentoPadrao) { $rules = [ 'procedimentos' => [ 'nullable', Rule::requiredIf(fn () => !$isReavaliacao && is_null($procedimentoPadrao)), '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', Rule::notIn([ ProcedimentoEnum::AFERICAO_PRESSAO_ARTERIAL, ProcedimentoEnum::GLICEMIA_CAPILAR, ]), 'exists:\App\Models\Sigtap\Procedimento,id', ]; if (is_null($procedimento)) { continue; } $validation = new ProcedimentoValidationService($procedimento); $rules["procedimentos.{$i}.procedimento_id"] = array_merge( $rules["procedimentos.{$i}.procedimento_id"], [ $this->getDuplicatedValidator($this->procedimentos, $i), $this->getOnValidCompetenciaValidator($validation), $this->getOcupacaoValidator($validation), $this->getSexoValidator($validation, $atendimento), $this->getIdadeValidator($validation, $atendimento), ] ); if (is_numeric($params['quantidade'] ?? null)) { $quantidade = $atendimento->procedimentos ->where('procedimento_id', $procedimento->id) ->sum('quantidade') + $params['quantidade']; $rules["procedimentos.{$i}.procedimento_id"][] = $this->getQuantidadeValidator($validation, $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}.cid_secundario_id"] = [ 'nullable', 'integer', Rule::in($procedimento->cidsSecundarios()->pluck('id')), ]; $rules["procedimentos.{$i}.quantidade"] = [ 'required', 'integer', 'min:1', ]; } } return $rules; } private function getPostPedidoExameRules($atendimento) { $rules = [ 'pedidos_exames' => [ 'nullable', 'array', ], ]; if ((is_array($this->pedidos_exames) ?? null)) { $rules = array_merge($rules, [ 'pedidos_exames.urgente' => [ 'required', 'boolean', ], 'pedidos_exames.justificativa' => [ 'nullable', 'string', 'max:100', ], 'pedidos_exames.exames' => [ 'required', 'array', ], 'pedidos_exames.exames.*.exame_id' => [ 'required', 'distinct', 'integer', 'exists:\App\Models\Parametrizacao\Exame\Exame,id' ], 'pedidos_exames.exames.*.observacao' => [ 'nullable', 'string', 'max:1000' ], ]); } return $rules; } private function getPostServicosEnfermagemRules($atendimento) { $rules = [ 'servicos_enfermagem' => [ 'nullable', 'array', ], ]; if (is_array($this->servicos_enfermagem ?? null)) { foreach ($this->servicos_enfermagem as $i => $params) { $rules["servicos_enfermagem.{$i}.observacoes"] = [ 'nullable', 'string', 'max:100' ]; $rules["servicos_enfermagem.{$i}.procedimento_id"] = [ 'required', 'integer', 'exists:\App\Models\Sigtap\Procedimento,id', ]; $procedimento = is_numeric($params['procedimento_id'] ?? null) ? Procedimento::find($params['procedimento_id']) : null; if (is_null($procedimento)) { continue; } $validation = new ProcedimentoValidationService($procedimento); $quantidade = $atendimento->procedimentos ->where('procedimento_id', $procedimento->id) ->sum('quantidade') + 1; $rules["servicos_enfermagem.{$i}.procedimento_id"] = [ $this->getOnValidCompetenciaValidator($validation), $this->getSexoValidator($validation, $atendimento), $this->getIdadeValidator($validation, $atendimento), $this->getQuantidadeValidator($validation, $quantidade), ]; } } 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 getOnValidCompetenciaValidator($validation) { return function ($attribute, $value, $fail) use ($validation) { if (!$validation->isOnValidCompetencia()) { $fail('Competência do ' . $attribute . ' inválida.'); } }; } private function getOcupacaoValidator($validation) { return function ($attribute, $value, $fail) use ($validation) { $ocupacao = Lotacao::find(auth()->payload()->get('lotacao_id'))->ocupacao; if (!$validation->isOcupacaoValid($ocupacao)) { $fail($attribute . ' não permitido para o CBO do médico.'); } }; } private function getSexoValidator($validation, $atendimento) { return function($attribute, $value, $fail) use ($validation, $atendimento) { if (!$validation->isSexoValid($atendimento->faa->paciente->cidadao->sexo)) { $fail($attribute . ' não permitido para o sexo do paciente.'); } }; } private function getIdadeValidator($validation, $atendimento) { return function ($attribute, $value, $fail) use ($validation, $atendimento) { if (!$atendimento->faa->paciente->is_desconhecido && !$validation->isIdadeValid($atendimento->faa->paciente->cidadao->idade['anos']) ) { $fail($attribute . ' não permitido para a idade do paciente.'); } }; } private function getQuantidadeValidator($validation, $quantidade) { return function ($attribute, $value, $fail) use ($validation, $quantidade) { if (!$validation->isQuantidadeValid($quantidade)) { $fail('Quantidade máxima atingida para o '. $attribute); } }; } private function getPostDesfechoRules($atendimento) { $rules = [ 'desfecho' => [ 'nullable', 'array' ], 'desfecho.id' => [ 'nullable', 'integer', Rule::in( Desfecho::ALTA_MEDICA, Desfecho::EVASAO, Desfecho::ENCAMINHAMENTO_HOSPITALAR, Desfecho::OBITO, ), 'exists:\App\Models\ProntoAtendimento\Atendimento\Desfecho,id', ], 'desfecho.evasao' => [ 'nullable', 'required_if:desfecho.id,' . Desfecho::EVASAO, 'array', ], 'desfecho.evasao.motivo' => [ 'nullable', 'required_if:desfecho.id,' . Desfecho::EVASAO, 'string', 'max:200' ], 'desfecho.encaminhamento_hospitalar' => [ 'nullable', 'array', ], 'desfecho.encaminhamento_hospitalar.unidade_id' => [ 'nullable', 'integer', 'exists:\App\Models\Cadastro\Estabelecimento\Unidade,id', ], 'desfecho.encaminhamento_hospitalar.unidade_nome' => [ 'nullable', 'string', 'max:100', ], 'desfecho.encaminhamento_hospitalar.quarto' => [ 'nullable', 'string', 'max:3', ], 'desfecho.encaminhamento_hospitalar.leito' => [ 'nullable', 'string', 'max:3', ], 'desfecho.encaminhamento_hospitalar.cid_id' => [ 'nullable', 'integer', 'exists:\App\Models\Sigtap\Cid,id', ], 'desfecho.encaminhamento_hospitalar.medico_hospitalar' => [ 'nullable', 'string', 'max:150', new NomeCompleto, ], 'desfecho.encaminhamento_hospitalar.observacoes' => [ 'nullable', 'string', 'max:3000', ], 'desfecho.obito' => [ 'required_if:desfecho.id,' . Desfecho::OBITO, 'array', ], ]; 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' => [ 'nullable', '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 getPostFinalizacaoRules($atendimento, $raatObrigatorio) { $rules = [ 'finalizacao' => [ 'nullable', 'array', ], ]; return array_merge( $rules, $this->getPostFinalizacaoDesfechoRules($atendimento) ); } private function getPostFinalizacaoDesfechoRules($atendimento) { $rules = [ 'finalizacao.desfecho_id' => [ Rule::requiredIf(fn () => $this->hasFinalizacao()), 'integer', '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', ], '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 ), '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 ), 'string', 'max:100', ], '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', ], 'finalizacao.encaminhamento_hospitalar.observacoes' => [ 'nullable', 'string', 'max:3000', ], 'finalizacao.obito' => [ 'required_if:finalizacao.desfecho_id,' . Desfecho::OBITO, 'array', ], ]; if (is_array($this->finalizacao['obito'] ?? null)) { $rules = array_merge($rules, [ 'finalizacao.obito.obito_em' => [ 'required', 'date_format:d/m/Y H:i', $this->getObitoEmValidator($atendimento), ], 'finalizacao.obito.declaracao' => [ 'nullable', 'string', 'min:8', 'max:13' ], 'finalizacao.obito.causa' => [ 'required', 'string', 'max:255' ], 'finalizacao.obito.cid_id' => [ 'required', 'integer', 'exists:\App\Models\Sigtap\Cid,id' ] ]); } return $rules; } private function hasFinalizacao() { return isset($this->finalizacao); } 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 getCentroCustoLogado() { return CentroCusto::findOrFail(auth()->payload()->get('centro_custo_id')); } }