join( 'sigtap.ocupacao as ocupacao', 'ocupacao.id', 'especialidade.ocupacao_id' ) ->select(DB::raw(" especialidade.id, especialidade.nome, especialidade.ativo, CONCAT(ocupacao.codigo, ' - ', ocupacao.nome) as ocupacao_descricao, CASE WHEN especialidade.permite_integracao_conectasus_cidadao = 1 THEN 'Sim' ELSE 'Não' END as permite_integracao_conectasus_cidadao, CASE WHEN especialidade.permite_integracao_aplicativo_feridas = 1 THEN 'Sim' ELSE 'Não' END as permite_integracao_aplicativo_feridas ")); } public static function autocomplete() { return DB::table('cadastro_especialidade as especialidade') ->join( 'sigtap.ocupacao as ocupacao', 'ocupacao.id', 'especialidade.ocupacao_id' ) ->where('ativo', true) ->when(isset(request()->encaminhamento), fn ($q) => $q ->where('especialidade.encaminhamento', DataUtil::getBooleanValueFromStringBoolean(request()->encaminhamento))) ->where(function ($q) { $q->where('is_regulado', false) ->orWhere(function ($q2) { $q2->where('is_regulado', true) ->whereExists(function ($sub) { $sub->select(DB::raw(1)) ->from('regulacao_parametrizacao_solicitante as solicitante') ->join('regulacao_parametrizacao_solicitante_regulador as regulador', 'regulador.solicitante_id', 'solicitante.id') ->join('regulacao_parametrizacao_solicitante_regulador_especialidade as regulador_especialidade', 'regulador_especialidade.solicitante_regulador_id', 'regulador.id') ->whereColumn('regulador_especialidade.especialidade_id', 'especialidade.id') ->where('solicitante.infraestrutura_id', self::getCurrentCentroCusto()->infraestrutura_id); }); }); }) ->when(is_array(request()->ocupacoes), fn($q) => $q->whereIn('ocupacao_id', request()->ocupacoes)) ->select(DB::raw(" especialidade.id, especialidade.nome, especialidade.ocupacao_id, especialidade.sexo_id, especialidade.idade_minima, especialidade.idade_maxima, especialidade.tratamento, especialidade.encaminhamento, especialidade.exigir_peso_altura_circunferencia, especialidade.permite_agendamento_mesmo_dia, especialidade.permite_agendamento_gestante, especialidade.permite_fechamento_sem_procedimento, especialidade.permite_agendamento_nao_municipe, especialidade.precisa_informar_conclusao_tratamento, especialidade.permite_integracao_conectasus_cidadao, especialidade.permite_integracao_aplicativo_feridas, especialidade.limite_consulta, especialidade.limite_consulta_mes, especialidade.procedimento_grupo_codigo, ocupacao.codigo as ocupacao_codigo, especialidade.is_regulado ")); } public static function create() { return [ 'form' => self::getFormData(), 'model' => [ 'encaminhamento' => false, 'idade_maxima' => null, 'idade_minima' => null, 'is_regulado' => false, 'limite_consulta' => null, 'limite_consulta_mes' => null, 'mensagem_protocolo_agendamento' => null, 'nome' => null, 'ocupacao' => null, 'permite_agendamento_gestante' => false, 'permite_agendamento_mesmo_dia' => false, 'permite_agendamento_nao_municipe' => false, 'permite_fechamento_sem_procedimento' => false, 'precisa_informar_conclusao_tratamento' => false, 'permite_integracao_conectasus_cidadao' => false, 'permite_integracao_aplicativo_feridas' => false, 'exigir_peso_altura_circunferencia' => false, 'procedimento_grupo' => null, 'regulacao_tipo_id' => null, 'sexo_id' => null, 'tratamento' => false, 'atencao_basica' => [ 'procedimento_padrao' => null, 'motivo_saida_permanencia_id' => null, 'classificacao_codigo' => null, 'numero_autorizacao' => null, 'problema_condicao' => [ 'situacao_id' => null, 'cid' => null, 'ciap' => null, ], 'condutas' => [], 'odontologico' => [ 'consulta_tipo_id' => null, 'vigilancia_id' => null, 'conduta_id' => null, ], 'condicoes_avaliadas' => [] ], 'is_ppi' => false, 'valor_ppi' => null, 'limite_ocorrencias_paciente' => null, 'periodo_monitoramento' => null, 'tempo_liberacao' => null, 'tempo_medio_previsto_atendimento_dias' => null, ], ]; } public static function store() { self::validate(); $params = self::getParams(); $params['valor_ppi'] = str_replace(',', '.', str_replace('.', '', $params['valor_ppi'])); $especialidade = Especialidade::create($params); $especialidade->condutas()->sync($params['condutas']); $especialidade->condicoesAvaliadas()->sync($params['condicoes_avaliadas']); return $especialidade; } public static function edit($id) { $especialidade = Especialidade::findOrFail($id); return [ 'form' => self::getFormData(), 'model' => [ 'nome' => $especialidade->nome, 'ocupacao' => [ 'id' => $especialidade->ocupacao->id, 'codigo' => $especialidade->ocupacao->codigo, 'nome' => $especialidade->ocupacao->nome, ], 'sexo_id' => $especialidade->sexo_id ?? null, 'idade_minima' => $especialidade->idade_minima ?? null, 'idade_maxima' => $especialidade->idade_maxima ?? null, 'tratamento' => $especialidade->tratamento ?? false, 'encaminhamento' => $especialidade->encaminhamento ?? false, 'permite_agendamento_mesmo_dia' => $especialidade->permite_agendamento_mesmo_dia ?? false, 'permite_agendamento_gestante' => $especialidade->permite_agendamento_gestante ?? false, 'permite_fechamento_sem_procedimento' => $especialidade->permite_fechamento_sem_procedimento ?? false, 'permite_agendamento_nao_municipe' => $especialidade->permite_agendamento_nao_municipe ?? false, 'precisa_informar_conclusao_tratamento' => $especialidade->precisa_informar_conclusao_tratamento ?? false, 'permite_integracao_conectasus_cidadao' => $especialidade->permite_integracao_conectasus_cidadao ?? false, 'permite_integracao_aplicativo_feridas' => $especialidade->permite_integracao_aplicativo_feridas ?? false, 'exigir_peso_altura_circunferencia' => $especialidade->exigir_peso_altura_circunferencia ?? false, 'limite_consulta' => $especialidade->limite_consulta ?? null, 'limite_consulta_mes' => $especialidade->limite_consulta_mes ?? null, 'procedimento_grupo' => [ 'codigo' => $especialidade->procedimentoGrupo->codigo ?? null, 'nome' => $especialidade->procedimentoGrupo->nome ?? null, ], 'mensagem_protocolo_agendamento' => $especialidade->mensagem_protocolo_agendamento ?? null, 'is_regulado' => $especialidade->is_regulado ?? false, 'regulacao_tipo_id' => $especialidade->regulacao_tipo_id ?? null, 'atencao_basica' => [ 'procedimento_padrao' => is_null($especialidade->atencao_basica_procedimento_padrao_codigo) ? null : [ 'id' => $especialidade->atencaoBasicaProcedimentoPadrao->id, 'codigo' => $especialidade->atencaoBasicaProcedimentoPadrao->codigo, 'nome' => $especialidade->atencaoBasicaProcedimentoPadrao->nome, 'has_instrumento_registro_raas' => $especialidade->atencaoBasicaProcedimentoPadrao ->registros() ->whereIn('codigo', [Registro::RAAS_ATENCAO_DOMICILIAR, Registro::RAAS_ATENCAO_PSICOSSOCIAL]) ->exists() ], 'motivo_saida_permanencia_id' => $especialidade->atencao_basica_motivo_saida_permanencia_id, 'classificacao_codigo' => $especialidade->atencao_basica_classificacao_codigo, 'numero_autorizacao' => $especialidade->atencao_basica_numero_autorizacao, 'problema_condicao' => [ 'situacao_id' => $especialidade->atencao_basica_problema_condicao_situacao_id, 'ciap' => is_null($especialidade->atencao_basica_problema_condicao_ciap_id) ? null : [ 'id' => $especialidade->atencaoBasicaProblemaCondicaoCiap->id, 'codigo' => $especialidade->atencaoBasicaProblemaCondicaoCiap->codigo, 'descricao' => $especialidade->atencaoBasicaProblemaCondicaoCiap->descricao, ], 'cid' => is_null($especialidade->atencao_basica_problema_condicao_cid_id) ? null : [ 'id' => $especialidade->atencaoBasicaProblemaCondicaoCid->id, 'codigo' => $especialidade->atencaoBasicaProblemaCondicaoCid->codigo, 'nome' => $especialidade->atencaoBasicaProblemaCondicaoCid->nome, ], ], 'condutas' => $especialidade->condutas()->pluck('atencao_basica_cadastro_conduta.id'), 'odontologico' => [ 'consulta_tipo_id' => $especialidade->atencao_basica_odontologico_consulta_tipo_id, 'vigilancia_id' => $especialidade->atencao_basica_odontologico_vigilancia_id, 'conduta_id' => $especialidade->atencao_basica_odontologico_conduta_id, ], 'condicoes_avaliadas' => $especialidade->condicoesAvaliadas()->pluck('atencao_basica_cadastro_condicao_avaliada.id') ], 'is_ppi' => $especialidade->is_ppi ?? false, 'valor_ppi' => $especialidade->valor_ppi ?? null, 'limite_ocorrencias_paciente' => $especialidade->limite_ocorrencias_paciente ?? null, 'periodo_monitoramento' => $especialidade->periodo_monitoramento ?? null, 'tempo_liberacao' => $especialidade->tempo_liberacao ?? null, 'tempo_medio_previsto_atendimento_dias' => $especialidade->tempo_medio_previsto_atendimento_dias, ], ]; } private static function getFormData() { return [ 'sexos' => Sexo::orderBy('descricao')->get()->map(fn($sexo) => [ 'id' => $sexo->id, 'descricao' => $sexo->descricao, ]), 'regulacao_tipos' => RegulacaoTipo::orderBy('nome')->get()->map(fn($tipo) => [ 'id' => $tipo->id, 'nome' => $tipo->nome, ]), 'atencao_basica' => [ 'motivos_saida_permacencia' => MotivoSaidaPermanencia::orderBy('nome')->get(['id', 'nome']), 'classificacoes_servico' => self::getClassificacoesServico(), 'problema_condicao' => [ 'situacoes' => ProblemaCondicaoSituacao::orderBy('nome')->get(['id', 'nome']), ], 'condutas' => Conduta::whereIn('id', [ CondutaEnum::RETORNO_PARA_CONSULTA_AGENDADA, CondutaEnum::RETORNO_PARA_CUIDADO_CONTINUADO_PROGRAMADO, CondutaEnum::AGENDAMENTO_PARA_GRUPOS, CondutaEnum::AGENDAMENTO_PARA_E_MULTI, CondutaEnum::ALTA_DO_EPISODIO, ])->orderBy('descricao')->get(['id', 'descricao']), 'odontologico' => [ 'consulta_tipos' => TipoConsulta::orderBy('id')->get(['id', 'descricao']), 'vigilancias' => SaudeBucalVigilancia::orderBy('nome')->get(['id', 'nome']), 'condutas' => Conduta::whereIn('id', [ CondutaEnum::RETORNO_PARA_CONSULTA_AGENDADA, CondutaEnum::AGENDAMENTO_PARA_E_MULTI, CondutaEnum::AGENDAMENTO_PARA_GRUPOS, CondutaEnum::ALTA_DO_EPISODIO, ])->orderBy('descricao')->get(['id', 'descricao']), ], 'condicoes_avaliadas' => CondicaoAvaliada::whereNotIn('id', [ AtendimentoIndividualCondicaoAvaliada::PRE_NATAL, AtendimentoIndividualCondicaoAvaliada::PUERICULTURA, ])->orderBy('descricao')->get(), ], ]; } private static function getClassificacoesServico() { return DB::table('sigtap.classificacao as classificacao') ->join('sigtap.servico as servico', 'servico.id', 'classificacao.servico_id') ->where('classificacao.competencia_id', DB::table('sigtap.competencia')->max('id')) ->where('servico.codigo', Servico::SERVICO_DE_ATENCAO_PSICOSSOCIAL) ->whereIn('classificacao.codigo', [ ClassificacaoServicoAtencaoPsicossocial::RESIDENCIA_TERAPEUTICA_EM_SAUDE_MENTAL, ClassificacaoServicoAtencaoPsicossocial::SERVICO_RESIDENCIAL_TERAPEUTICO_TIPO_I_SRT_TIPO_I, ClassificacaoServicoAtencaoPsicossocial::SERVICO_RESIDENCIAL_TERAPEUTICO_TIPO_II_SRT_TIPO_II, ]) ->selectRaw(" classificacao.codigo, classificacao.nome ") ->orderBy('classificacao.nome') ->get(); } public static function update($id) { self::validate(); $especialidade = Especialidade::findOrFail($id); $params = self::getParams(); $params['valor_ppi'] = str_replace(',', '.', str_replace('.', '', $params['valor_ppi'])); $especialidade->update($params); $especialidade->condutas()->sync($params['condutas']); $especialidade->condicoesAvaliadas()->sync($params['condicoes_avaliadas']); return $especialidade->fresh(); } private static function getParams() { $params = request()->except(['ativo', 'atencao_basica']); if ($params['sexo_id'] === SexoEnum::MASCULINO) { $params['permite_agendamento_gestante'] = false; } $atencaoBasica = request()->only('atencao_basica')['atencao_basica']; $params['atencao_basica_procedimento_padrao_codigo'] = $atencaoBasica['procedimento_padrao_codigo']; $params['atencao_basica_motivo_saida_permanencia_id'] = $atencaoBasica['motivo_saida_permanencia_id']; $params['atencao_basica_classificacao_codigo'] = $atencaoBasica['classificacao_codigo']; $params['atencao_basica_numero_autorizacao'] = $atencaoBasica['numero_autorizacao']; $params['atencao_basica_problema_condicao_situacao_id'] = $atencaoBasica['problema_condicao']['situacao_id']; $params['atencao_basica_problema_condicao_ciap_id'] = $atencaoBasica['problema_condicao']['ciap_id']; $params['atencao_basica_problema_condicao_cid_id'] = $atencaoBasica['problema_condicao']['cid_id']; $params['atencao_basica_odontologico_consulta_tipo_id'] = $atencaoBasica['odontologico']['consulta_tipo_id']; $params['atencao_basica_odontologico_vigilancia_id'] = $atencaoBasica['odontologico']['vigilancia_id']; $params['atencao_basica_odontologico_conduta_id'] = $atencaoBasica['odontologico']['conduta_id']; $params['condutas'] = $atencaoBasica['condutas']; $params['condicoes_avaliadas'] = $atencaoBasica['condicoes_avaliadas']; return $params; } public static function activate($id) { $especialidade = Especialidade::findOrFail($id); $especialidade->update(['ativo' => true]); return $especialidade->fresh(); } public static function deactivate($id) { $especialidade = Especialidade::findOrFail($id); $especialidade->update(['ativo' => false]); return $especialidade->fresh(); } public static function destroy($id) { Especialidade::findOrFail($id)->delete(); } private static function validate() { return request()->validate([ 'nome' => [ 'required', 'string', 'between:3,100', Rule::unique(Especialidade::class, 'nome') ->ignore(request()->route('especialidade')) ], 'ocupacao_id' => [ 'required', Rule::exists(Ocupacao::class, 'id'), ], 'sexo_id' => [ 'nullable', 'integer', Rule::exists(Sexo::class, 'id'), ], 'idade_minima' => [ 'nullable', 'integer', 'max:130', ], 'idade_maxima' => [ 'nullable', 'integer', 'max:130', ], 'tratamento' => [ 'required', 'boolean', ], 'encaminhamento' => [ 'required', 'boolean', ], 'permite_agendamento_mesmo_dia' => [ 'required', 'boolean', ], 'permite_agendamento_gestante' => [ 'required', 'boolean', ], 'permite_fechamento_sem_procedimento' => [ 'required', 'boolean', ], 'permite_agendamento_nao_municipe' => [ 'required', 'boolean', ], 'precisa_informar_conclusao_tratamento' => [ 'required', 'boolean', ], 'permite_integracao_conectasus_cidadao' => [ 'required', 'boolean', ], 'permite_integracao_aplicativo_feridas' => [ 'required', 'boolean', ], 'exigir_peso_altura_circunferencia' => [ 'required', 'boolean', ], 'limite_consulta' => [ 'nullable', 'required_with:limite_consulta_mes', 'integer', 'between:1,9999' ], 'limite_consulta_mes' => [ 'nullable', 'required_with:limite_consulta', 'integer', 'between:1,12' ], 'regulacao_tipo_id' => [ 'nullable', 'integer', ], 'procedimento_grupo_codigo' => [ 'bail', 'nullable', 'numeric', 'digits:10', Rule::exists(Procedimento::class, 'codigo'), function ($_, $value, $fail) { $procedimento = Procedimento::where('codigo', $value) ->orderByDesc('competencia_id') ->first(['id', 'competencia_id']); $valid = $procedimento->registros() ->where('codigo', Registro::BPA_CONSOLIDADO) ->exists(); if (!$valid) { $fail("O procedimento deve ser do tipo BPA (consolidado)."); } }, ], 'mensagem_protocolo_agendamento' => [ 'nullable', 'string', 'max:500', ], 'atencao_basica.procedimento_padrao_codigo' => [ 'nullable', 'digits:10' ], 'atencao_basica.motivo_saida_permanencia_id' => [ 'nullable', 'integer', Rule::exists(MotivoSaidaPermanencia::class, 'id'), ], 'atencao_basica.classificacao_codigo' => [ 'nullable', 'digits:3' ], 'atencao_basica.numero_autorizacao' => [ 'nullable', 'string', 'max:13' ], 'atencao_basica.problema_condicao.situacao_id' => [ 'nullable', 'integer', Rule::exists(ProblemaCondicaoSituacao::class, 'id'), ], 'atencao_basica.problema_condicao.ciap_id' => [ 'nullable', 'integer', Rule::exists(Ciap::class, 'id'), ], 'atencao_basica.problema_condicao.cid_id' => [ 'nullable', 'integer', Rule::exists(Cid::class, 'id'), ], 'atencao_basica.odontologico.consulta_tipo_id' => [ 'nullable', 'integer', Rule::exists(TipoConsulta::class, 'id'), ], 'atencao_basica.odontologico.vigilancia_id' => [ 'nullable', 'integer', Rule::exists(SaudeBucalVigilancia::class, 'id'), ], 'atencao_basica.odontologico.conduta_id' => [ 'nullable', 'integer', Rule::exists(Conduta::class, 'id'), ], 'limite_ocorrencias_paciente' => [ 'nullable', 'integer', 'min:1', ], 'periodo_monitoramento' => [ 'nullable', 'integer', 'min:1', ], 'tempo_liberacao' => [ 'nullable', 'integer', 'min:0', ], 'tempo_medio_previsto_atendimento_dias' => [ 'nullable', 'integer', 'max:9999' ], ], [ 'nome.unique' => 'O nome da Especialidade já foi inserido anteriormente.', ]); } public static function getDadosParaAtribuicao() { return [ 'ocupacoes' => self::getOcupacoesParaAtribuicao(), 'especialidades' => self::getEspecialidadesParaAtribuicao(), ]; } private static function getOcupacoesParaAtribuicao() { return DB::table('sigtap.ocupacao AS ocupacao') ->whereExists(fn ($q) => $q ->selectRaw(1) ->from('cadastro_especialidade AS especialidade') ->whereColumn('especialidade.ocupacao_id', 'ocupacao.id') ) ->select( 'ocupacao.id', 'ocupacao.codigo', 'ocupacao.nome', ) ->get(); } private static function getEspecialidadesParaAtribuicao() { return DB::table('cadastro_especialidade AS especialidade') ->select( 'especialidade.id', 'especialidade.nome', 'especialidade.ocupacao_id', ) ->get(); } public static function saveAtribuicao() { self::validateSaveAtribuicao(); $params = []; if (isset(request()->tempo_medio_previsto_atendimento_dias)) { $params['tempo_medio_previsto_atendimento_dias'] = request()->tempo_medio_previsto_atendimento_dias; } Especialidade::where(fn ($q) => $q ->whereIn('id', request()->especialidades) ->orWhereIn('ocupacao_id', request()->ocupacoes) )->update($params); } private static function validateSaveAtribuicao() { request()->validate([ 'ocupacoes' => [ 'present', 'array', ], 'ocupacoes.*' => [ 'required', 'integer', ], 'especialidades' => [ 'present', 'array', ], 'especialidades.*' => [ 'required', 'integer', ], 'tempo_medio_previsto_atendimento_dias' => [ 'nullable', 'integer', 'max:9999' ], ]); } }