1036 lines
41 KiB
PHP
1036 lines
41 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Ambulatorio;
|
|
|
|
use App\Enums\Administracao\Modulo;
|
|
use App\Enums\Ambulatorio\AgendamentoStatus;
|
|
use App\Enums\Ambulatorio\AgendamentoTipo;
|
|
use App\Enums\Ambulatorio\DemandaTipo;
|
|
use App\Enums\AtencaoBasica\AtendimentoIndividual\TipoAtendimento as TipoAtendimentoEnum;
|
|
use App\Enums\Cadastro\Estabelecimento\SetorTipo;
|
|
use App\Enums\Cadastro\SujeitoAtencao\Classificacao;
|
|
use App\Enums\Cadastro\SujeitoAtencao\Subclassificacao;
|
|
use App\Enums\PainelSenha\Status;
|
|
use App\Models\Ambulatorio\Agendamento;
|
|
use App\Models\Ambulatorio\Atendimento;
|
|
use App\Models\Ambulatorio\DemandaEspontanea;
|
|
use App\Models\Ambulatorio\Jornada;
|
|
use App\Models\Ambulatorio\ParametrizacaoAgendamento;
|
|
use App\Models\Ambulatorio\ParametrizacaoInfraestruturaEspecialidade;
|
|
use App\Models\Ambulatorio\Servico;
|
|
use App\Models\AtencaoBasica\AtendimentoIndividual\TipoAtendimento;
|
|
use App\Models\Cadastro\Especialidade;
|
|
use App\Models\Cadastro\Estabelecimento\CentroCusto;
|
|
use App\Models\Cadastro\Estabelecimento\Infraestrutura;
|
|
use App\Models\Cadastro\Estabelecimento\Unidade;
|
|
use App\Models\Cadastro\Parametrizacao\Parametrizacao;
|
|
use App\Models\Cadastro\SujeitoAtencao\CidadaoTelefone;
|
|
use App\Models\Cadastro\SujeitoAtencao\Paciente;
|
|
use App\Models\Cadastro\SujeitoAtencao\Usuario;
|
|
use App\Models\PainelSenha\Encaminhamento;
|
|
use App\Models\PainelSenha\Fila;
|
|
use App\Models\PainelSenha\OpcaoEntrada;
|
|
use App\Models\PainelSenha\Prioridade;
|
|
use App\Models\Sigtap\Ocupacao;
|
|
use App\Rules\Cns;
|
|
use App\Services\Administracao\ModuloService;
|
|
use App\Services\Geral\AgeService;
|
|
use App\Services\Integracao\CnsService;
|
|
use App\Services\Service;
|
|
use App\Utils\MaskUtil;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Validation\Rule;
|
|
|
|
class RecepcaoService extends Service
|
|
{
|
|
public static function autocompletePaciente()
|
|
{
|
|
$parametrizacao = ParametrizacaoAgendamento::first();
|
|
$cadastroParametrizacao = Parametrizacao::first();
|
|
|
|
$provisorioBloqueado = $parametrizacao->bloqueia_paciente_temporario ?? false;
|
|
$provisorioQuantidadeDias = $cadastroParametrizacao->cadastro_paciente_provisorio_quantidade_dias ?? 0;
|
|
|
|
$pacientes = DB::table('cadastro_paciente as paciente')
|
|
->join('cadastro_cidadao as cidadao', 'cidadao.id', 'paciente.cidadao_id')
|
|
->leftJoin('cadastro_cidadao_telefone as telefone', function ($join) {
|
|
$join->on('telefone.cidadao_id', '=', 'cidadao.id')
|
|
->where('telefone.principal', true)
|
|
->whereRaw('telefone.id = (
|
|
SELECT MAX(id)
|
|
FROM cadastro_cidadao_telefone
|
|
WHERE cidadao_id = cidadao.id
|
|
AND principal = true
|
|
AND deleted_at is null
|
|
)');
|
|
})
|
|
->leftJoin('cadastro_domicilio as domicilio', 'domicilio.id', 'cidadao.domicilio_id')
|
|
->leftJoin('cadastro_endereco as endereco', 'endereco.id', 'domicilio.endereco_id')
|
|
->leftJoin('cadastro_logradouro as logradouro', 'logradouro.id', 'endereco.logradouro_id')
|
|
->leftJoin('cadastro_logradouro_tipo as logradouro_tipo', 'logradouro_tipo.id', 'logradouro.tipo_id')
|
|
->leftJoin('cadastro_bairro as bairro', 'bairro.id', 'logradouro.bairro_id')
|
|
->leftJoin('intranet.cadastro_municipio as municipio', 'municipio.id', 'logradouro.municipio_id')
|
|
->leftJoin('intranet.cadastro_estado as estado', 'estado.id', 'municipio.estado_id')
|
|
->leftJoin('cadastro_unidade as unidade_referencia', 'unidade_referencia.id', 'paciente.unidade_id')
|
|
->leftJoin('cadastro_paciente_classificacao as classificacao', 'classificacao.id', 'paciente.classificacao_id')
|
|
->leftJoin('cadastro_obito', function ($join) {
|
|
|
|
$join->on('cidadao.id', '=', 'cadastro_obito.cidadao_id')
|
|
->whereNull('cadastro_obito.deleted_at');
|
|
})
|
|
->whereNull('paciente.deleted_at')
|
|
->whereNull('cadastro_obito.id')
|
|
->select(DB::raw("
|
|
paciente.id,
|
|
cidadao.nome,
|
|
cidadao.nome_social,
|
|
DATE_FORMAT(cidadao.data_nascimento, '%d/%m/%Y') as data_nascimento,
|
|
paciente.prontuario,
|
|
paciente.subclassificacao_id,
|
|
cidadao.cpf,
|
|
cidadao.cns,
|
|
cidadao.nome_mae,
|
|
unidade_referencia.nome_fantasia as unidade_referencia,
|
|
classificacao.descricao as classificacao,
|
|
DATE_FORMAT(paciente.validade_fim, '%d/%m/%Y') as validade_cadastro,
|
|
CONCAT(
|
|
logradouro_tipo.descricao,
|
|
' ',
|
|
logradouro.nome,
|
|
', ',
|
|
COALESCE(endereco.numero, 'S/N'),
|
|
' - ',
|
|
bairro.nome,
|
|
', ',
|
|
municipio.nome,
|
|
' - ',
|
|
estado.uf
|
|
) as endereco,
|
|
telefone.id as telefone_id,
|
|
telefone.numero as telefone_numero,
|
|
telefone.autoriza_sms as telefone_autoriza_sms,
|
|
cidadao.id as cidadao_id,
|
|
classificacao.id as classificacao_id
|
|
"));
|
|
|
|
$pacientes->where(function ($query) {
|
|
$query->where('paciente.bloqueado', false)
|
|
->orWhereNull('paciente.bloqueado');
|
|
});
|
|
|
|
if ($provisorioBloqueado) {
|
|
|
|
$pacientes->where(function ($query) use ($provisorioQuantidadeDias) {
|
|
$query->where('paciente.subclassificacao_id', '!=', Subclassificacao::TEMPORARIO)
|
|
->orWhere(function ($query) use ($provisorioQuantidadeDias) {
|
|
$query->where('paciente.subclassificacao_id', Subclassificacao::TEMPORARIO)
|
|
->where(function ($query) use ($provisorioQuantidadeDias) {
|
|
|
|
$query->where(function ($query) {
|
|
$query->whereNull('paciente.validade_inicio')
|
|
->orWhereDate('paciente.validade_inicio', '<=', Carbon::now()->format('Y-m-d'));
|
|
});
|
|
|
|
$query->where(function ($query) use ($provisorioQuantidadeDias) {
|
|
$query->whereNull('paciente.validade_fim')
|
|
->orWhere(function ($query) use ($provisorioQuantidadeDias) {
|
|
if (!is_null($provisorioQuantidadeDias) && $provisorioQuantidadeDias > 0) {
|
|
$query->whereDate('paciente.validade_fim', '>=', Carbon::now()->format('Y-m-d'))
|
|
->orWhereDate('paciente.validade_fim', '>=', Carbon::now()->subDays($provisorioQuantidadeDias)->format('Y-m-d'));
|
|
} else {
|
|
$query->whereDate('paciente.validade_fim', '>=', Carbon::now()->format('Y-m-d'));
|
|
}
|
|
});
|
|
});
|
|
});
|
|
})
|
|
->orWhereNull('paciente.subclassificacao_id');
|
|
});
|
|
}
|
|
|
|
return datatables()
|
|
->of($pacientes)
|
|
->filterColumn('cidadao.data_nascimento', function ($query, $keyword) {
|
|
|
|
$query->whereRaw("DATE_FORMAT(cidadao.data_nascimento, '%d/%m/%Y') like ?", ["%{$keyword}%"]);
|
|
})
|
|
->filterColumn('paciente.prontuario', function ($query, $keyword) {
|
|
|
|
$query->whereRaw("LPAD(paciente.prontuario, 6, 0) like ?", ["%{$keyword}%"]);
|
|
})
|
|
->filterColumn('cidadao.nome', function ($query, $keyword) {
|
|
$query->where(function ($query) use ($keyword) {
|
|
$query->where('cidadao.nome', 'like', "%{$keyword}%")
|
|
->orWhere('cidadao.nome_social', 'like', "%{$keyword}%");
|
|
});
|
|
})
|
|
->addColumn('idade', function ($paciente) {
|
|
|
|
return is_null($paciente->data_nascimento)
|
|
? null
|
|
: AgeService::getFormattedAge(
|
|
Carbon::createFromFormat('d/m/Y', $paciente->data_nascimento)->toDateTime()
|
|
);
|
|
})
|
|
->addColumn('idade_anos', function ($paciente) {
|
|
|
|
if ($paciente->data_nascimento === null) {
|
|
return null;
|
|
}
|
|
|
|
$idade = AgeService::getAge(Carbon::createFromFormat('d/m/Y', $paciente->data_nascimento)->toDateTime());
|
|
|
|
return $idade->years;
|
|
})
|
|
->editColumn('cpf', fn ($paciente) => MaskUtil::getCpfMasked($paciente->cpf))
|
|
->editColumn('cns', fn ($paciente) => MaskUtil::getCnsMasked($paciente->cns))
|
|
->editColumn('telefone_numero', fn ($paciente) => MaskUtil::getPhoneMasked($paciente->telefone_numero))
|
|
->editColumn('telefone_autoriza_sms', fn ($paciente) => !!$paciente->telefone_autoriza_sms)
|
|
->toJson();
|
|
}
|
|
|
|
public static function list()
|
|
{
|
|
$params = (object) request()->all();
|
|
|
|
$params->infraestrutura_id = self::getCurrentCentroCusto()->infraestrutura_id;
|
|
$params->data = Carbon::today();
|
|
|
|
if (collect(['ocupacoes', 'especialidades', 'usuarios'])->contains(request()->listar)) {
|
|
|
|
$paciente = Paciente::setEagerLoads([])->where('id', $params->paciente_id)->first();
|
|
|
|
$params->paciente_nao_municipe = $paciente->classificacao_id !== Classificacao::MUNICIPE;
|
|
}
|
|
|
|
switch (request()->listar) {
|
|
|
|
case 'totalizadores': {
|
|
|
|
return self::getTotalizadores();
|
|
}
|
|
case 'agendamentos': {
|
|
|
|
return [
|
|
'agendamentos' => self::getAgendamentos($params),
|
|
];
|
|
}
|
|
case 'usuarios': {
|
|
|
|
return [
|
|
'usuarios' => self::getUsuariosWithJornada($params),
|
|
'ocupacoes' => [],
|
|
'especialidades' => [],
|
|
'jornadas' => [],
|
|
];
|
|
}
|
|
case 'ocupacoes': {
|
|
|
|
return [
|
|
'ocupacoes' => self::getOcupacoesWithJornada($params),
|
|
'especialidades' => [],
|
|
'jornadas' => [],
|
|
];
|
|
}
|
|
case 'especialidades': {
|
|
|
|
return [
|
|
'especialidades' => self::getEspecialidadesWithJornada($params),
|
|
'jornadas' => [],
|
|
];
|
|
}
|
|
case 'jornadas': {
|
|
|
|
return [
|
|
'jornadas' => self::getJornadas($params),
|
|
];
|
|
}
|
|
}
|
|
}
|
|
|
|
public static function create($filaId = null)
|
|
{
|
|
$fila = null;
|
|
|
|
if (!is_null($filaId)) {
|
|
|
|
$fila = Fila::findOrFail($filaId);
|
|
|
|
FilaService::answer($fila->id);
|
|
}
|
|
|
|
return [
|
|
'additionals' => self::getAdditionalsData($fila),
|
|
'form' => self::getFormData($fila),
|
|
'model' => self::getModelData($fila),
|
|
];
|
|
}
|
|
|
|
public static function edit($atendimentoId)
|
|
{
|
|
$atendimento = Atendimento::findOrFail($atendimentoId);
|
|
|
|
return [
|
|
'additionals' => self::getAdditionalsData($atendimento->fila),
|
|
'form' => self::getFormData($atendimento->fila, $atendimento),
|
|
'model' => self::getModelData($atendimento->fila, $atendimento),
|
|
];
|
|
}
|
|
|
|
private static function getAdditionalsData($fila = null)
|
|
{
|
|
return [
|
|
'has_atendimento' => is_null($fila)
|
|
? false
|
|
: $fila->ambulatorioAtendimento()->exists(),
|
|
'permissoes_atualizacao_cadastro_paciente' => self::getPermissoesAtualizacaoCadastroPaciente(),
|
|
];
|
|
}
|
|
|
|
private static function getFormData($fila = null, $atendimento = null)
|
|
{
|
|
$demandaEspontaneaObservaVagaAtendimento = self::demandaEspontaneaObservaVagaAtendimento();
|
|
|
|
$agendamentos = [];
|
|
$usuarios = [];
|
|
$ocupacoes = [];
|
|
$especialidades = [];
|
|
$jornadas = [];
|
|
|
|
if (!is_null($atendimento)) {
|
|
|
|
$params = [
|
|
'paciente_id' => $atendimento->paciente->id,
|
|
'paciente_nao_municipe' => $atendimento->paciente->classificacao_id !== Classificacao::MUNICIPE,
|
|
'infraestrutura_id' => self::getCurrentCentroCusto()->infraestrutura_id,
|
|
'data' => Carbon::today(),
|
|
];
|
|
|
|
if ($atendimento->is_demanda_espontanea) {
|
|
|
|
$usuarios = self::getUsuariosWithJornada((object) $params);
|
|
|
|
if (!is_null($atendimento->usuario)) {
|
|
|
|
$ocupacoes = self::getOcupacoesWithJornada((object) array_merge($params, [
|
|
'usuario_id' => $atendimento->usuario->id,
|
|
]));
|
|
}
|
|
|
|
if (!is_null($atendimento->ocupacao)) {
|
|
|
|
$especialidades = self::getEspecialidadesWithJornada((object) array_merge($params, [
|
|
'usuario_id' => $atendimento->usuario->id,
|
|
'ocupacao_id' => $atendimento->ocupacao->id,
|
|
]));
|
|
}
|
|
|
|
if ($demandaEspontaneaObservaVagaAtendimento) {
|
|
if (!is_null($atendimento->usuario) && !is_null($atendimento->ocupacao)) {
|
|
$jornadas = self::getJornadas((object) [
|
|
'data' => $atendimento->created_at->format('Y-m-d'),
|
|
'usuario_id' => $atendimento->usuario->id,
|
|
'ocupacao_id' => $atendimento->ocupacao->id,
|
|
'infraestrutura_id' => $params['infraestrutura_id'],
|
|
]);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
|
|
$agendamentos = self::getAgendamentos((object) $params, $atendimento->agendamento_id);
|
|
}
|
|
}
|
|
|
|
$atendimentoTipos = TipoAtendimento::whereIn('id', [
|
|
TipoAtendimentoEnum::CONSULTA_AGENDADA_PROGRAMADA,
|
|
TipoAtendimentoEnum::CONSULTA_AGENDADA,
|
|
TipoAtendimentoEnum::ESCUTA_INICIAL_ORIENTACAO,
|
|
TipoAtendimentoEnum::CONSULTA_NO_DIA,
|
|
TipoAtendimentoEnum::ATENDIMENTO_DE_URGENCIA,
|
|
])->orderBy('descricao')->get(['id', 'descricao'])->map(fn ($tipo) => [
|
|
'id' => $tipo->id,
|
|
'nome' => $tipo->descricao,
|
|
'is_demanda_espontanea' => collect([
|
|
TipoAtendimentoEnum::ESCUTA_INICIAL_ORIENTACAO,
|
|
TipoAtendimentoEnum::CONSULTA_NO_DIA,
|
|
TipoAtendimentoEnum::ATENDIMENTO_DE_URGENCIA,
|
|
])->contains($tipo->id)
|
|
]);
|
|
|
|
return [
|
|
'opcoes_entrada' => self::getOpcoesEntrada($fila),
|
|
'prioridades' => self::getPrioridades(),
|
|
'demanda_tipos' => self::getDemandaTipos(),
|
|
'atendimento_tipos' => $atendimentoTipos,
|
|
'agendamentos' => $agendamentos,
|
|
'usuarios' => $usuarios,
|
|
'ocupacoes' => $ocupacoes,
|
|
'especialidades' => $especialidades,
|
|
'jornadas' => $jornadas,
|
|
'servicos' => self::getServicos(),
|
|
'centros_custo_encaminhamento' => self::getCentrosCustoEncaminhamento(
|
|
$atendimento->fila->centro_custo_id ?? null
|
|
),
|
|
];
|
|
}
|
|
|
|
public static function unidadePaciente($pacienteId)
|
|
{
|
|
$possuiJornadaUnidadePaciente = false;
|
|
$parametrizacao = ParametrizacaoAgendamento::first();
|
|
$cadastroParametrizacao = Parametrizacao::first();
|
|
$infraestruturaId = self::getCurrentCentroCusto()->infraestrutura_id;
|
|
|
|
$paciente = Paciente::findOrFail($pacienteId);
|
|
$unidadeId = Infraestrutura::findOrFail($infraestruturaId)->unidade_id;
|
|
|
|
if ($parametrizacao->avisa_paciente_outra_unidade) {
|
|
|
|
if ($unidadeId !== $paciente->unidade_id) {
|
|
|
|
$possuiJornadaUnidadePaciente = Unidade::where('id', $paciente->unidade_id)->exists();
|
|
}
|
|
}
|
|
|
|
return [
|
|
'unidade_com_jornada' => $possuiJornadaUnidadePaciente,
|
|
'unidade' => $paciente->unidade->nome_fantasia ?? null,
|
|
'cns_valido' => Cns::isValid($paciente->cidadao->cns),
|
|
'avisa_cns_temporario_invalido' => $cadastroParametrizacao->exibe_alerta_paciente_cns_temporario_invalido ?? false,
|
|
];
|
|
}
|
|
|
|
private static function getOpcoesEntrada($fila = null)
|
|
{
|
|
if (is_null($fila)) {
|
|
|
|
return OpcaoEntrada::where('centro_custo_id', self::getCurrentCentroCusto()->id)
|
|
->where('modulo_id', ModuloService::getId(Modulo::AMBULATORIO))
|
|
->orderBy('nome')
|
|
->get(['id', 'nome', 'prioridade_obrigatoria']);
|
|
}
|
|
|
|
return OpcaoEntrada::where('id', $fila->opcao_entrada_id)
|
|
->get(['id', 'nome', 'prioridade_obrigatoria']);
|
|
}
|
|
|
|
private static function getPrioridades()
|
|
{
|
|
return Prioridade::orderBy('nome')->get(['id', 'tipo_id', 'nome']);
|
|
}
|
|
|
|
private static function getDemandaTipos()
|
|
{
|
|
return [
|
|
['value' => DemandaTipo::AGENDADA, 'text' => 'Demanda agendada'],
|
|
['value' => DemandaTipo::ESPONTANEA, 'text' => 'Demanda espontânea'],
|
|
];
|
|
}
|
|
|
|
private static function getTotalizadores()
|
|
{
|
|
$agendamentos = GerenciamentoDiarioService::getAgendamentos(['data' => Carbon::today()->format('d/m/Y')]);
|
|
$atendimentos = GerenciamentoDiarioService::getAtendimentos();
|
|
$atendidosEvadidos = GerenciamentoDiarioService::getAtendidosEvadidos();
|
|
|
|
return [
|
|
'total_pacientes_agendados' => $agendamentos->count(),
|
|
'total_faltas_no_dia' => $agendamentos->where('status_id', AgendamentoStatus::FALTA_DO_PACIENTE)->count(),
|
|
'total_pacientes_atendidos_no_dia' => $atendidosEvadidos->where('evadido', false)->count(),
|
|
'total_pacientes_em_atendimento' => $atendimentos->where('fila_status_id', Status::EM_ATENDIMENTO)->count(),
|
|
'total_pacientes_aguardando_atendimento' => $atendimentos->where('fila_status_id', Status::EM_ESPERA)->count(),
|
|
'total_evasoes' => $atendidosEvadidos->where('evadido', true)->count(),
|
|
];
|
|
}
|
|
|
|
private static function getAgendamentos($params, $agendamentoId = null)
|
|
{
|
|
return DB::table('ambulatorio_agendamento as agendamento')
|
|
->join('ambulatorio_jornada as jornada', 'jornada.id', 'agendamento.jornada_id')
|
|
->join('cadastro_lotacao as lotacao', 'lotacao.id', 'jornada.lotacao_id')
|
|
->join('sigtap.ocupacao as ocupacao', 'ocupacao.id', 'lotacao.ocupacao_id')
|
|
->join('cadastro_usuario as usuario', 'usuario.id', 'lotacao.usuario_id')
|
|
->join('cadastro_cidadao as cidadao', 'cidadao.id', 'usuario.cidadao_id')
|
|
->join('cadastro_especialidade as especialidade', 'especialidade.id', 'jornada.especialidade_id')
|
|
->where('agendamento.paciente_id', $params->paciente_id)
|
|
->where('agendamento.status_id', AgendamentoStatus::AGENDADO)
|
|
->where(fn ($q) => $q
|
|
->whereNotExists(fn ($q) => $q
|
|
->select(DB::raw(1))
|
|
->from('ambulatorio_atendimento as atendimento')
|
|
->whereColumn('atendimento.agendamento_id', 'agendamento.id')
|
|
)
|
|
->when($agendamentoId, fn ($q) => $q
|
|
->orWhere('agendamento.id', $agendamentoId)
|
|
)
|
|
)
|
|
->where('jornada.data', $params->data)
|
|
->where('lotacao.infraestrutura_id', $params->infraestrutura_id)
|
|
->select(DB::raw("
|
|
agendamento.id,
|
|
DATE_FORMAT(agendamento.horario, '%H:%i') as horario,
|
|
CONCAT(ocupacao.codigo, ' - ', ocupacao.nome) as ocupacao_descricao,
|
|
especialidade.nome as especialidade_nome,
|
|
cidadao.nome as usuario_nome
|
|
"))
|
|
->unionAll(DB::table('ambulatorio_agendamento as agendamento')
|
|
->join('ambulatorio_jornada as jornada', 'jornada.id', 'agendamento.jornada_id')
|
|
->join('cadastro_lotacao as lotacao', 'lotacao.id', 'jornada.lotacao_id')
|
|
->join('cadastro_infraestrutura as infraestrutura', 'infraestrutura.id', 'lotacao.infraestrutura_id')
|
|
->join('sigtap.ocupacao as ocupacao', 'ocupacao.id', 'lotacao.ocupacao_id')
|
|
->join('cadastro_usuario as usuario', 'usuario.id', 'lotacao.usuario_id')
|
|
->join('cadastro_cidadao as cidadao', 'cidadao.id', 'usuario.cidadao_id')
|
|
->join('cadastro_especialidade as especialidade', 'especialidade.id', 'jornada.especialidade_id')
|
|
->where('agendamento.paciente_id', $params->paciente_id)
|
|
->where('agendamento.status_id', AgendamentoStatus::AGENDADO)
|
|
->where(fn ($q) => $q
|
|
->whereNotExists(fn ($q) => $q
|
|
->select(DB::raw(1))
|
|
->from('ambulatorio_atendimento as atendimento')
|
|
->whereColumn('atendimento.agendamento_id', 'agendamento.id')
|
|
)
|
|
->when($agendamentoId, fn ($q) => $q
|
|
->orWhere('agendamento.id', $agendamentoId)
|
|
)
|
|
)
|
|
->where('jornada.data', $params->data)
|
|
->where('infraestrutura.infraestrutura_id', $params->infraestrutura_id)
|
|
->select(DB::raw("
|
|
agendamento.id,
|
|
DATE_FORMAT(agendamento.horario, '%H:%i') as horario,
|
|
CONCAT(ocupacao.codigo, ' - ', ocupacao.nome) as ocupacao_descricao,
|
|
especialidade.nome as especialidade_nome,
|
|
cidadao.nome as usuario_nome
|
|
"))
|
|
)
|
|
->get();
|
|
}
|
|
|
|
private static function getUsuariosWithJornada($params)
|
|
{
|
|
return Usuario::setEagerLoads([])
|
|
->whereHas('lotacoes', fn ($q) => $q
|
|
->where('infraestrutura_id', $params->infraestrutura_id)
|
|
->whereHas('ambulatorioJornadas', fn ($q) => $q
|
|
->whereNotNull('quantidade_consulta')
|
|
->whereNull('situacao_id')
|
|
->whereDate('data', $params->data)
|
|
)
|
|
)
|
|
->get(['id', 'cidadao_id'])
|
|
->map(fn ($usuario) => [
|
|
'id' => $usuario->id,
|
|
'nome' => $usuario->cidadao()->setEagerLoads([])->first(['nome'])->nome,
|
|
])
|
|
->sortBy('nome')
|
|
->values();
|
|
}
|
|
|
|
private static function getOcupacoesWithJornada($params)
|
|
{
|
|
return DB::table('sigtap.ocupacao as ocupacao')
|
|
->whereExists(fn ($q) => $q
|
|
->select(DB::raw(1))
|
|
->from('cadastro_lotacao as lotacao')
|
|
->whereColumn('lotacao.ocupacao_id', 'ocupacao.id')
|
|
->where('lotacao.usuario_id', $params->usuario_id)
|
|
->where('lotacao.infraestrutura_id', $params->infraestrutura_id)
|
|
->whereExists(fn ($q) => $q
|
|
->select(DB::raw(1))
|
|
->from('ambulatorio_jornada as jornada')
|
|
->join(
|
|
'cadastro_especialidade as especialidade',
|
|
'especialidade.id',
|
|
'jornada.especialidade_id'
|
|
)
|
|
->whereColumn('jornada.lotacao_id', 'lotacao.id')
|
|
->whereNotNull('jornada.quantidade_consulta')
|
|
->whereNull('jornada.situacao_id')
|
|
->whereDate('jornada.data', $params->data)
|
|
->where(fn ($query) => self::setCadastroWhereEspecialidadePaciente(
|
|
$query,
|
|
$params->paciente_id,
|
|
'especialidade'
|
|
))
|
|
->when($params->paciente_nao_municipe, fn ($q) => $q
|
|
->where('especialidade.permite_agendamento_nao_municipe', true)
|
|
)
|
|
)
|
|
)
|
|
->orderByRaw("CONCAT(ocupacao.codigo, ' - ', ocupacao.nome)")
|
|
->select(DB::raw("
|
|
ocupacao.id,
|
|
CONCAT(ocupacao.codigo, ' - ', ocupacao.nome) as descricao
|
|
"))
|
|
->get();
|
|
}
|
|
|
|
private static function getEspecialidadesWithJornada($params)
|
|
{
|
|
return Especialidade::where(fn ($q) => self::setCadastroWhereEspecialidadePaciente($q, $params->paciente_id))
|
|
->whereHas('ambulatorioJornadas', fn ($q) => $q
|
|
->whereNotNull('quantidade_consulta')
|
|
->whereNull('situacao_id')
|
|
->whereDate('data', $params->data)
|
|
->whereHas('lotacao', fn ($q) => $q
|
|
->where('infraestrutura_id', $params->infraestrutura_id)
|
|
->where('usuario_id', $params->usuario_id)
|
|
->where('ocupacao_id', $params->ocupacao_id)
|
|
)
|
|
)
|
|
->when($params->paciente_nao_municipe, fn ($q) => $q
|
|
->where('permite_agendamento_nao_municipe', true)
|
|
)
|
|
->orderBy('nome')
|
|
->get()
|
|
->map(fn ($q) => [
|
|
'id' => $q->id,
|
|
'nome' => $q->nome,
|
|
'demanda_espontanea_observa_vaga_atendimento' => $q->ambulatorioParametrizacoesInfraestruturaEspecialidade()
|
|
->whereHas('parametrizacaoInfraestrutura', fn ($q) => $q->where('infraestrutura_id', $params->infraestrutura_id))
|
|
->first()->demanda_espontanea_observa_vaga_atendimento ?? false,
|
|
]);
|
|
}
|
|
|
|
private static function getJornadas($params)
|
|
{
|
|
$jornadas = Jornada::setEagerLoads([])
|
|
->whereHas('lotacao', fn ($q) => $q
|
|
->where('usuario_id', $params->usuario_id)
|
|
->where('ocupacao_id', $params->ocupacao_id)
|
|
->where('infraestrutura_id', $params->infraestrutura_id)
|
|
)
|
|
->whereNotNull('quantidade_consulta')
|
|
->whereNull('situacao_id')
|
|
->whereDate('data', $params->data)
|
|
->orderBy('inicio')
|
|
->get()
|
|
->map(function ($jornada) {
|
|
$quantidadeAgendamentos = $jornada->agendamentos()
|
|
->whereNotIn('status_id', self::getStatusLiberamHorario())
|
|
->where('tipo_id', AgendamentoTipo::CONSULTA)
|
|
->count();
|
|
|
|
$quantidadeDemandasEspontaneas = $jornada->demandasEspontaneas()->count();
|
|
|
|
$quantidadeUtilizada = $quantidadeAgendamentos + $quantidadeDemandasEspontaneas;
|
|
|
|
$quantidadeConsulta = $jornada->quantidade_consulta;
|
|
|
|
return [
|
|
'id' => $jornada->id,
|
|
'quantidade_utilizada' => $quantidadeUtilizada,
|
|
'quantidade_consulta' => $quantidadeConsulta,
|
|
'inicio' => $jornada->inicio->format('H:i'),
|
|
'fim' => $jornada->fim->format('H:i'),
|
|
'descricao' => $jornada->inicio->format('d/m/Y H:i') . ' - ' . $quantidadeUtilizada . '/' . $quantidadeConsulta,
|
|
];
|
|
});
|
|
|
|
$horarioAtual = Carbon::now()->format('H:i');
|
|
|
|
$jornada = $jornadas
|
|
->filter(fn ($jornada) => $jornada['inicio'] <= $horarioAtual && $jornada['fim'] >= $horarioAtual)
|
|
->first();
|
|
|
|
return [
|
|
'jornada_id' => $jornada['id'] ?? null,
|
|
'jornadas' => $jornadas,
|
|
];
|
|
}
|
|
|
|
private static function setCadastroWhereEspecialidadePaciente($query, $pacienteId, $tableAlias = '')
|
|
{
|
|
if (!empty($tableAlias)) {
|
|
|
|
$tableAlias .= '.';
|
|
}
|
|
|
|
$paciente = Paciente::find($pacienteId);
|
|
$idade = $paciente->cidadao->idade;
|
|
|
|
return $query->where(fn ($q) => $q
|
|
->when($idade, fn ($q) => $q
|
|
->where(fn ($q) => $q
|
|
->whereNull("{$tableAlias}idade_minima")
|
|
->orWhere("{$tableAlias}idade_minima", '<=', $idade['anos'])
|
|
)
|
|
->where(fn ($q) => $q
|
|
->whereNull("{$tableAlias}idade_maxima")
|
|
->orWhere("{$tableAlias}idade_maxima", '>=', $idade['anos'])
|
|
)
|
|
)
|
|
->where(fn ($q) => $q
|
|
->whereNull("{$tableAlias}sexo_id")
|
|
->orWhere("{$tableAlias}sexo_id", $paciente->cidadao->sexo_id)
|
|
)
|
|
);
|
|
}
|
|
|
|
private static function getServicos()
|
|
{
|
|
return Servico::orderBy('nome')
|
|
->whereHas('parametrizacoesInfraestrutura', fn ($q) => $q
|
|
->where('infraestrutura_id', self::getCurrentCentroCusto()->infraestrutura_id)
|
|
)
|
|
->get(['id', 'nome', 'tipo_id']);
|
|
}
|
|
|
|
private static function getCentrosCustoEncaminhamento($centroCustoId = null)
|
|
{
|
|
if (is_null($centroCustoId)) {
|
|
|
|
return Encaminhamento::where('centro_custo_id_de', self::getCurrentCentroCusto()->id)
|
|
->whereHas('centroCustoPara', fn ($q) => $q
|
|
->whereHas('setor', fn ($q) => $q
|
|
->whereIn('tipo_id', [
|
|
SetorTIpo::ENFERMAGEM,
|
|
SetorTipo::CONSULTORIO
|
|
])
|
|
)
|
|
)
|
|
->get()
|
|
->map(fn ($encaminhamento) => [
|
|
'id' => $encaminhamento->centroCustoPara->id,
|
|
'setor_nome' => $encaminhamento->centroCustoPara->setor->nome,
|
|
]);
|
|
}
|
|
|
|
return CentroCusto::where('id', $centroCustoId)
|
|
->get()
|
|
->map(fn ($centroCusto) => [
|
|
'id' => $centroCusto->id,
|
|
'setor_nome' => $centroCusto->setor->nome,
|
|
]);
|
|
}
|
|
|
|
private static function getModelData($fila = null, $atendimento = null)
|
|
{
|
|
$isDemandaEspontanea = $atendimento->is_demanda_espontanea ?? false;
|
|
|
|
return [
|
|
'paciente' => is_null($atendimento)
|
|
? null
|
|
: Paciente::with([
|
|
'cidadao',
|
|
'cidadao.etniaIndigena',
|
|
'cidadao.nacionalidade',
|
|
'cidadao.racaCor',
|
|
'cidadao.sexo',
|
|
'classificacao',
|
|
'unidade',
|
|
])->where('id', $atendimento->paciente->id)->first(),
|
|
'opcao_entrada_id' => $fila->opcao_entrada_id ?? null,
|
|
'prioridade_id' => $fila->prioridade_id ?? null,
|
|
'demanda_tipo' => $atendimento->demanda_tipo ?? null,
|
|
'agendamento_id' => $atendimento->agendamento_id ?? null,
|
|
'usuario_id' => $isDemandaEspontanea
|
|
? ($atendimento->usuario->id ?? null)
|
|
: null,
|
|
'ocupacao_id' => $isDemandaEspontanea
|
|
? ($atendimento->ocupacao->id ?? null)
|
|
: null,
|
|
'especialidade_id' => $isDemandaEspontanea
|
|
? ($atendimento->especialidade->id ?? null)
|
|
: null,
|
|
'jornada_id' => $isDemandaEspontanea
|
|
? ($atendimento->jornada->id ?? null)
|
|
: null,
|
|
'servicos' => ($atendimento->servicos ?? collect())->pluck('id'),
|
|
'centro_custo_encaminhamento_id' => $atendimento->fila->centro_custo_id ?? null,
|
|
];
|
|
}
|
|
|
|
public static function store()
|
|
{
|
|
self::validateStore();
|
|
|
|
$atendimento = new Atendimento();
|
|
|
|
DB::transaction(function () use ($atendimento) {
|
|
|
|
if (!is_null(request()->paciente['telefone_principal']['id'])) {
|
|
|
|
CidadaoTelefone::find(request()->paciente['telefone_principal']['id'])
|
|
->update(request()->paciente['telefone_principal']);
|
|
}
|
|
|
|
$fila = Fila::find(request()->fila_id);
|
|
$demandaEspontaneaId = null;
|
|
|
|
if (is_null($fila)) {
|
|
|
|
$fila = FilaService::store((object) array_merge(
|
|
request()->only(['paciente_id', 'opcao_entrada_id', 'prioridade_id']),
|
|
['centro_custo_id' => self::getCurrentCentroCusto()->id]
|
|
));
|
|
}
|
|
else {
|
|
|
|
$fila->update(request()->only('paciente_id'));
|
|
}
|
|
|
|
if (is_null(request()->agendamento_id)) {
|
|
|
|
$demandaEspontaneaId = DemandaEspontanea::create(array_merge(
|
|
request()->only(['paciente_id', 'ocupacao_id', 'especialidade_id', 'usuario_id', 'jornada_id']),
|
|
['data' => Carbon::today()]
|
|
))->id;
|
|
}
|
|
|
|
$atendimento->fill([
|
|
'atendimento_tipo_id' => request()->atendimento_tipo_id,
|
|
'fila_id' => $fila->id,
|
|
'paciente_id' => request()->paciente_id,
|
|
'agendamento_id' => request()->agendamento_id,
|
|
'demanda_espontanea_id' => $demandaEspontaneaId,
|
|
]);
|
|
|
|
$atendimento->save();
|
|
$atendimento->servicos()->sync(request()->servicos);
|
|
|
|
FilaService::forward($fila->id, request()->centro_custo_encaminhamento_id);
|
|
});
|
|
|
|
return $atendimento->fresh();
|
|
}
|
|
|
|
private static function validateStore()
|
|
{
|
|
$demandaEspontaneaObservaVagaAtendimento = self::demandaEspontaneaObservaVagaAtendimento();
|
|
|
|
$validations = [
|
|
'paciente.telefone_principal.id' => [
|
|
'nullable',
|
|
'integer',
|
|
Rule::exists(CidadaoTelefone::class, 'id'),
|
|
],
|
|
'paciente.telefone_principal.numero' => [
|
|
'nullable',
|
|
'required_with:paciente.telefone_principal.id',
|
|
'digits_between:10,11',
|
|
],
|
|
'paciente.telefone_principal.autoriza_sms' => [
|
|
'nullable',
|
|
'required_with:paciente.telefone_principal.id',
|
|
'boolean',
|
|
],
|
|
'atendimento_tipo_id' => [
|
|
'required',
|
|
'integer',
|
|
Rule::exists(TipoAtendimento::class, 'id'),
|
|
],
|
|
'fila_id' => [
|
|
'nullable',
|
|
'integer',
|
|
Rule::exists(Fila::class, 'id'),
|
|
],
|
|
'paciente_id' => [
|
|
'required',
|
|
'integer',
|
|
Rule::exists(Paciente::class, 'id'),
|
|
],
|
|
'opcao_entrada_id' => [
|
|
'required',
|
|
'integer',
|
|
Rule::exists(OpcaoEntrada::class, 'id'),
|
|
],
|
|
'prioridade_id' => [
|
|
'nullable',
|
|
Rule::requiredIf(fn () => OpcaoEntrada::find(request()->opcao_entrada_id)
|
|
->prioridade_obrigatoria ?? false
|
|
),
|
|
Rule::exists(Prioridade::class, 'id'),
|
|
],
|
|
'agendamento_id' => [
|
|
'nullable',
|
|
'integer',
|
|
Rule::exists(Agendamento::class, 'id'),
|
|
],
|
|
'usuario_id' => [
|
|
'nullable',
|
|
'required_with:ocupacao_id',
|
|
'integer',
|
|
Rule::exists(Usuario::class, 'id'),
|
|
],
|
|
'ocupacao_id' => [
|
|
'nullable',
|
|
'required_with:especialidade_id',
|
|
'integer',
|
|
Rule::exists(Ocupacao::class, 'id'),
|
|
],
|
|
'especialidade_id' => [
|
|
'nullable',
|
|
'integer',
|
|
Rule::exists(Especialidade::class, 'id'),
|
|
],
|
|
'servicos' => [
|
|
'present',
|
|
'array'
|
|
],
|
|
'servicos.*' => [
|
|
'required',
|
|
'integer',
|
|
Rule::exists(Servico::class, 'id'),
|
|
],
|
|
'centro_custo_encaminhamento_id' => [
|
|
'required',
|
|
'integer',
|
|
Rule::in(self::getCentrosCustoEncaminhamento()->pluck('id')),
|
|
],
|
|
];
|
|
|
|
if ($demandaEspontaneaObservaVagaAtendimento) {
|
|
$validations['jornada_id'] = [
|
|
'required',
|
|
'integer',
|
|
Rule::exists(Jornada::class, 'id'),
|
|
];
|
|
}
|
|
|
|
request()->validate($validations);
|
|
}
|
|
|
|
public static function update($atendimentoId)
|
|
{
|
|
$atendimento = Atendimento::findOrFail($atendimentoId);
|
|
|
|
self::validateUpdate($atendimento);
|
|
|
|
DB::transaction(function () use ($atendimento) {
|
|
|
|
$atendimento->fila()->update(request()->only(['prioridade_id']));
|
|
|
|
if ($atendimento->is_demanda_espontanea) {
|
|
|
|
$atendimento->demandaEspontanea()->update(
|
|
request()->only(['ocupacao_id', 'especialidade_id', 'usuario_id'])
|
|
);
|
|
}
|
|
|
|
$atendimento->servicos()->sync(request()->servicos);
|
|
|
|
FilaService::dispatch($atendimento->fila->centro_custo_id);
|
|
});
|
|
|
|
return $atendimento->fresh();
|
|
}
|
|
|
|
private static function validateUpdate($atendimento)
|
|
{
|
|
request()->validate([
|
|
'prioridade_id' => [
|
|
'nullable',
|
|
Rule::requiredIf(fn () => $atendimento->fila->opcaoEntrada->prioridade_obrigatoria),
|
|
Rule::exists(Prioridade::class, 'id'),
|
|
],
|
|
'usuario_id' => [
|
|
'nullable',
|
|
'required_with:ocupacao_id',
|
|
'integer',
|
|
Rule::exists(Usuario::class, 'id'),
|
|
],
|
|
'ocupacao_id' => [
|
|
'nullable',
|
|
'required_with:especialidade_id',
|
|
'integer',
|
|
Rule::exists(Ocupacao::class, 'id'),
|
|
],
|
|
'especialidade_id' => [
|
|
'nullable',
|
|
'integer',
|
|
Rule::exists(Especialidade::class, 'id'),
|
|
],
|
|
'servicos' => [
|
|
'present',
|
|
'array'
|
|
],
|
|
'servicos.*' => [
|
|
'required',
|
|
'integer',
|
|
Rule::exists(Servico::class, 'id'),
|
|
],
|
|
]);
|
|
}
|
|
|
|
public static function destroy($atendimentoId)
|
|
{
|
|
$atendimento = Atendimento::findOrFail($atendimentoId);
|
|
|
|
DB::transaction(function () use ($atendimento) {
|
|
|
|
$demandaEspontaneaId = $atendimento->demanda_espontanea_id;
|
|
$centroCustoAtualId = $atendimento->fila->centro_custo_id;
|
|
|
|
$firstItemHistorico = $atendimento->fila->historico()
|
|
->orderBy('id')
|
|
->first(['centro_custo_id', 'status_id']);
|
|
|
|
$atendimento->fila()->update([
|
|
'centro_custo_id' => $firstItemHistorico->centro_custo_id,
|
|
'status_id' => $firstItemHistorico->status_id,
|
|
'paciente_id' => null,
|
|
]);
|
|
|
|
$atendimento->delete();
|
|
|
|
if (!is_null($demandaEspontaneaId)) {
|
|
|
|
DemandaEspontanea::destroy($demandaEspontaneaId);
|
|
}
|
|
|
|
FilaService::dispatch($centroCustoAtualId);
|
|
FilaService::dispatch($firstItemHistorico->centro_custo_id);
|
|
});
|
|
}
|
|
|
|
private static function getPermissoesAtualizacaoCadastroPaciente()
|
|
{
|
|
$parametrizacao = CnsService::getParametrizacao();
|
|
|
|
if (!is_null($parametrizacao)) {
|
|
$lotacao = self::getCurrentLotacao();
|
|
|
|
return DB::table('cadastro_parametrizacao_permissao_usuario')
|
|
->select([
|
|
'municipe',
|
|
'provisorio',
|
|
'outro_municipio',
|
|
])
|
|
->where('infraestrutura_id', $lotacao->infraestrutura_id)
|
|
->where('usuario_id', $lotacao->usuario_id)
|
|
->get()
|
|
->first();
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private static function getStatusLiberamHorario()
|
|
{
|
|
return [
|
|
AgendamentoStatus::REAGENDADO_PELO_PACIENTE,
|
|
AgendamentoStatus::REAGENDADO_PELO_MEDICO,
|
|
AgendamentoStatus::CANCELADO_PELO_PACIENTE,
|
|
AgendamentoStatus::CANCELADO_PELO_MEDICO,
|
|
];
|
|
}
|
|
|
|
private static function demandaEspontaneaObservaVagaAtendimento()
|
|
{
|
|
$response = false;
|
|
|
|
if (isset(request()->especialidade_id)) {
|
|
$currentCentroCusto = self::getCurrentCentroCusto();
|
|
|
|
$response = ParametrizacaoInfraestruturaEspecialidade::where('especialidade_id', request()->especialidade_id)
|
|
->whereHas('parametrizacaoInfraestrutura', fn ($q) => $q->where('infraestrutura_id', $currentCentroCusto->infraestrutura_id))
|
|
->first()->demanda_espontanea_observa_vaga_atendimento ?? false;
|
|
}
|
|
|
|
return $response;
|
|
}
|
|
}
|