Files
rkm-conectasus-ci-sandbox/api/app/Services/ExameImagem/AgendamentoRetroativoService.php
Antonio Lopes dos Santos afec302c3e
All checks were successful
build-api-image / build (push) Successful in 51s
init commit
2026-08-04 16:52:02 -03:00

999 lines
49 KiB
PHP

<?php
namespace App\Services\ExameImagem;
use App\Enums\Administracao\Modulo;
use App\Enums\ExameImagem\Fechamento\Status;
use App\Enums\ExameImagem\Parametrizacao\Agendamento\AgendamentoStatus;
use App\Enums\ExameImagem\Parametrizacao\ControleJornada\Tipo as ControleJornadaTipo;
use App\Enums\ExameImagem\Tipo;
use App\Enums\Regulacao\StatusTipo as RegulacaoStatusTipo;
use App\Exceptions\ExameImagem\ExceededVagaJornadaException;
use App\Models\Cadastro\Estabelecimento\CentroCusto;
use App\Models\Cadastro\Estabelecimento\Unidade;
use App\Models\Cadastro\Feriado\Feriado;
use App\Models\Cadastro\SujeitoAtencao\Cidadao;
use App\Models\Cadastro\SujeitoAtencao\Lotacao;
use App\Models\Cadastro\SujeitoAtencao\Paciente;
use App\Models\Cadastro\SujeitoAtencao\Usuario;
use App\Models\ExameImagem\Agendamento\Agendamento;
use App\Models\ExameImagem\Agendamento\AgendamentoExame;
use App\Models\ExameImagem\Agendamento\AgendamentoHistoricoExclusao;
use App\Models\ExameImagem\CotaPrestador;
use App\Models\ExameImagem\Jornada\Jornada;
use App\Models\ExameImagem\Parametrizacao\MensagemProtocolo;
use App\Models\ExameImagem\Parametrizacao\Supervisor;
use App\Models\Intranet\Cliente;
use App\Models\Parametrizacao\Exame\Exame;
use App\Services\Administracao\ModuloService;
use App\Services\Integracao\CnsService;
use App\Services\Regulacao\SolicitacaoService as RegulacaoSolicitacaoService;
use App\Services\Service;
use App\Utils\MaskUtil;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\DB;
class AgendamentoRetroativoService extends Service
{
public static function datatable()
{
$gerenciamentoJornadas = DB::table('cadastro_usuario')
->select(
'cadastro_usuario.id',
'cadastro_cidadao.nome',
'cadastro_cidadao.cpf',
'cadastro_usuario.bloqueado',
'cadastro_lotacao.usuario_id',
'exame_imagem_parametrizacao_ocupacao.ocupacao_id',
'ocupacao.nome AS ocupacao_nome',
DB::raw('DATE_FORMAT(cadastro_cidadao.data_nascimento, "%d/%m/%Y") as data_nascimento')
)
->join(
'cadastro_cidadao',
'cadastro_cidadao.id',
'cadastro_usuario.cidadao_id'
)
->join(
'cadastro_lotacao',
'cadastro_lotacao.usuario_id',
'cadastro_usuario.id'
)
->join(
'sigtap.ocupacao AS ocupacao',
'ocupacao.id',
'cadastro_lotacao.ocupacao_id'
)
->join(
'exame_imagem_parametrizacao_ocupacao',
'exame_imagem_parametrizacao_ocupacao.ocupacao_id',
'cadastro_lotacao.ocupacao_id'
)
->where('cadastro_usuario.bloqueado', '=', '0')
->whereNull('cadastro_lotacao.deleted_at')
->whereNull('exame_imagem_parametrizacao_ocupacao.deleted_at');
return $gerenciamentoJornadas;
}
private static function getUsuarios($ids)
{
return Usuario::whereIn('id', $ids)->without(['registroTipo', 'cidadao'])->get();
}
private static function getCidadao($cidadao_id)
{
return Cidadao::where('id', $cidadao_id)
->without([
'carteiraIdentidade',
'carteiraHabilitacao',
'carteiraTrabalho',
'estrangeiroEntradaBrasil',
'tituloEleitor',
'certidao',
'telefones',
'conveniosMedico',
'domicilio',
'fatoresRisco',
'alergias',
'obito',
'sexo',
])->first();
}
private static function getAgendamentos($field, $ids)
{
return Agendamento::whereIn($field, $ids)
->whereHas('agendamentoExame', function ($query) {
$query->where(function ($q) {
$q->whereNotIn('status_id', [Status::CANCELADO])
->orWhereNull('status_id');
});
})
->get();
}
public static function show($id)
{
$mensagemProtocolo = MensagemProtocolo::select('mensagem')->first();
$centroCustroLogado = self::getCentroCustoLogado();
$currentLotacao = self::getCurrentLotacao();
$cliente = Cliente::where('link', app('config')->get('database.default'))->firstOrFail();
$paciente = Paciente::where('id', $id)->first();
$unidades = DB::table('cadastro_unidade')->orderBy('nome_fantasia')->get();
$idsUnidades = $unidades->pluck('id')->all();
$infraestruturas = DB::table('cadastro_infraestrutura')->whereIn('unidade_id', $idsUnidades)->get();
$centroCustoLogado = self::getCurrentCentroCusto();
$centroCustoLogadoInfraestrutura = $infraestruturas->firstWhere('id', $centroCustoLogado->infraestrutura_id);
$currentLotacao = self::getCurrentLotacao();
$usuario = self::getUsuarios([$currentLotacao->usuario_id])->first();
$agendamentosPaciente = self::getAgendamentos('paciente_id', [$id]);
return [
'additionals' => [
'permissoes_atualizacao_cadastro_paciente' => self::getPermissoesAtualizacaoCadastroPaciente(),
],
'form' => [
'paciente' => [
'id' => $paciente->id,
'classificacao_id' => $paciente->classificacao_id,
'unidade_id' => $paciente->unidade_id,
'observacao' => $paciente->observacao,
'prontuario' => $paciente->prontuario,
'is_desconhecido' => $paciente->is_desconhecido,
'unidade' => $unidades->where('id', $paciente->unidade_id)->first(),
'cidadao' => $paciente->cidadao
],
'cliente' => [
'sistema' => [
'ramo_atividade' => [
'nome' => $cliente->sistema->ramoAtividade->nome ?? null,
],
'nome' => $cliente->sistema->nome ?? null,
'versao' => $cliente->sistema->versao ?? null,
],
'municipio' => [
'estado' => [
'uf' => $cliente->municipio->estado->uf ?? null,
],
'nome' => $cliente->municipio->nome ?? null,
],
'nome' => $cliente->nome ?? null,
'email' => $cliente->email ?? null,
'site' => $cliente->site ?? null,
'logotipo' => $cliente->logotipo ?? null,
],
'data_atual' => Carbon::now()->format('d/m/Y'),
'unidade_logada' => $centroCustroLogado->infraestrutura->unidade->id,
'local_atendimento_logado' => $centroCustroLogado->infraestrutura->id,
'unidade_logada_nome' => Unidade::where('id', $centroCustoLogadoInfraestrutura->unidade_id)
->pluck('nome_fantasia')
->first(),
'usuario' => $usuario->cidadao->nome,
'usuario_nome_social' => $usuario->cidadao->nome_social ?? null,
'usuario_sistema_id' => $currentLotacao->usuario_id,
'mensagem_protocolo' => $mensagemProtocolo->mensagem,
'unidade_executante' => self::getUnidadeExecutante(),
'unidades' => Unidade::whereHas('parametrizacaoExameImagem', function ($query) {
$query->where('executante', true);
})
->get(),
'unidades_prestadoras' => Unidade::whereHas('parametrizacaoExameImagem', function ($query) {
$query->where('prestador', true);
})
->get()
->map(fn ($unidade) => [
'id' => $unidade->id,
'nome' => $unidade->nome_fantasia,
'infraestrutura_id' => $unidade->parametrizacaoExameImagem->infraestrutura_id,
'infraestrutura_nome' => $unidade->nome_fantasia,
'endereco' => $unidade->parametrizacaoExameImagem->infraestrutura->endereco->logradouro->nome,
'numero_endereco' => $unidade->parametrizacaoExameImagem->infraestrutura->numero,
'bairro' => $unidade->parametrizacaoExameImagem->infraestrutura->endereco->logradouro->bairro->nome,
'telefone' => $unidade->parametrizacaoExameImagem->infraestrutura->telefone ?
MaskUtil::getPhoneMasked($unidade->parametrizacaoExameImagem->infraestrutura->telefone) : 'NÃO INFORMADO',
]),
'feriados' => Feriado::orderBy('id')
->whereHas('modulos', function ($query) {
$query->where('id', ModuloService::getId(Modulo::EXAME_IMAGEM));
})
->get()
->map(fn($feriado) => [
'id' => $feriado->id,
'data' => (new Carbon($feriado->data))->format('d/m/Y') ?? null,
'tipo_id' => $feriado->tipo_id,
'tipo_nome' => $feriado->tipo->descricao,
'observacao' => $feriado->observacao,
]),
'cotas_prestadores' => CotaPrestador::orderBy('id')
->get()
->map(fn ($cotas) => [
'id' => $cotas->id ?? null,
'cota_tipo_id' => $cotas->cota_tipo_id ?? null,
'cota_tipo_nome' => $cotas->cota_tipo_id == Tipo::VALOR
? 'Valor' : 'Quantidade',
"periodo" => [
'start' => (new Carbon($cotas->inicio))->format('d/m/Y') ?? null,
'end' => (new Carbon($cotas->fim))->format('d/m/Y') ?? null,
],
'cota' => $cotas->cota_tipo_id == Tipo::VALOR
? number_format($cotas->cota_valor, 2, ',', '.')
: $cotas->cota_unidade,
'saldo' => $cotas->cota_tipo_id == Tipo::VALOR
? number_format($cotas->cota_valor, 2, ',', '.')
: $cotas->cota_unidade,
'utilizada' => "0",
'cota_unidade' => $cotas->cota_unidade ?? null,
'cota_valor' => $cotas->cota_valor ?? null,
'observacao' => $cotas->observacao ?? null,
'unidade_id' => $cotas->unidade->id ?? null,
'nome_fantasia' => $cotas->unidade->nome_fantasia ?? null,
'prestador' => "true",
])->values(),
],
'model' => [
'data_atual' => Carbon::now()->format('d/m/Y'),
'agendamentos' => $agendamentosPaciente
->map(function ($agendamento) use ($currentLotacao) {
$medico_nome = self::getCidadao(self::getUsuarios([$agendamento->medico_id])->first()->cidadao_id)->nome;
return [
'from_regulacao' => !is_null($agendamento->regulacao_solicitacao_id),
'alterar' => false,
'impressao' => false,
'agendamento_id' => $agendamento->id,
'agendamento_numero' => $agendamento->agendamento_numero,
'cotas_prestadores' => CotaPrestador::where('unidade_id', $agendamento->unidade_id)
->get()
->map(fn ($cotas) => [
'id' => $cotas->id ?? null,
'cota_tipo_id' => $cotas->cota_tipo_id ?? null,
'cota_tipo_nome' => $cotas->cota_tipo_id == Tipo::VALOR
? 'Valor' : 'Quantidade',
"periodo" => [
'start' => (new Carbon($cotas->inicio))->format('d/m/Y') ?? null,
'end' => (new Carbon($cotas->fim))->format('d/m/Y') ?? null,
],
'cota' => $cotas->cota_tipo_id == Tipo::VALOR
? number_format($cotas->cota_valor, 2, ',', '.')
: $cotas->cota_unidade,
'saldo' => $cotas->cota_tipo_id == Tipo::VALOR
? number_format($cotas->cota_valor, 2, ',', '.')
: $cotas->cota_unidade,
'utilizada' => "0",
'cota_unidade' => $cotas->cota_unidade ?? null,
'cota_valor' => number_format($cotas->cota_valor, 2, ',', '.') ?? null,
'observacao' => $cotas->observacao ?? null,
'prestador' => "true",
])->values(),
'controle_jornada_id' => $agendamento->jornada->controle_jornada_id,
'data' => (new Carbon($agendamento->data))->format('Y-m-d') ?? null,
'data_menstruacao' => (new Carbon($agendamento->data_menstruacao))->format('Y-m-d') ?? null,
'dias_semana' => [$agendamento->exame_id],
'grupo_exame_id' => $agendamento->exame_id,
'grupo_exame_nome' => $agendamento->grupo->nome ?? null,
'gestante' => $agendamento->gestante ?? false,
'hora_exame' => (new Carbon($agendamento->hora_exame))->format('H:i') ?? null,
'incluido' => AgendamentoExame::where('agendamento_id', $agendamento->id)
->get()
->map(function ($query) use ($agendamento) {
return [
'id' => $query->id,
'exame_id' => $query->exame_id,
'nome' => $query->exame->nome,
'codigo' => $query->exame->codigo ?? null,
'hora_exame' => (new Carbon($agendamento->hora_exame))->format('H:i') ?? null,
'observacao' => $query->exame->observacao,
'status_id' => $query->status_id ?? null,
'valor' => $query->exame->valor_sigtap ? $query->exame->procedimento->valor_servico_ambilatorial : $query->exame->valor,
'faturamento' => DB::table('exame_imagem_fechamento_faturamento')
->where('agendamento_id', $query->agendamento_id)
->where('exame_id', $query->exame_id)
->first() ? true : false,
];
})
->values(),
'pedido' => AgendamentoExame::where('agendamento_id', $agendamento->id)
->where(function ($query) {
$query->whereNull('status_id')
->orWhere('status_id', Status::AGENDADO);
})
->exists() ? false : true,
'infraestrutura_id' => $agendamento->infraestrutura_id,
'infraestrutura_nome' => $agendamento->infraestrutura->nome,
'infraestrutura_endereco' => $agendamento->infraestrutura->endereco->logradouro->nome,
'infraestrutura_numero' => $agendamento->infraestrutura->endereco->numero,
'infraestrutura_bairro' => $agendamento->infraestrutura->endereco->logradouro->bairro->nome,
'infraestrutura_telefone' => $agendamento->infraestrutura->telefone ? MaskUtil::getPhoneMasked($agendamento->infraestrutura->telefone) : 'NÃO INFORMADO',
'jornada_id' => $agendamento->jornada_id,
'medico_id' => $agendamento->medico_id,
'medico_nome' => $medico_nome,
'medico_solicitante' => [
'id' => $agendamento->medico_id,
'nome' => $medico_nome,
],
'nome_responsavel' => $agendamento->nome_responsavel,
'observacao' => $agendamento->observacao,
'paciente_id' => $agendamento->paciente_id,
'paciente_nome' => $agendamento->paciente->cidadao->nome,
'periodo' => [
'start' => (new Carbon($agendamento->data))->format('d/m/Y') ?? null,
'end' => (new Carbon($agendamento->data))->format('d/m/Y') ?? null,
],
'profissional_id' => $agendamento->profissional_id,
'profissional_nome' => $agendamento->jornada->usuario->nome,
'selecionado' => false,
'supervisor_id' => $agendamento->supervisor_id ?? null,
'unidade_id' => $agendamento->unidade_id,
'unidade_nome' => $agendamento->unidade->nome_fantasia,
'unidade_solicitante_id' => $agendamento->unidade_solicitante_id,
'unidade_solicitante_nome' => $agendamento->unidadeSolicitante->nome_fantasia,
'infraestrutura_solicitante_id' => $agendamento->infraestrutura_solicitante_id,
'urgente' => $agendamento->urgente ?? false,
'retroativo' => $agendamento->retroativo,
'agendador_id' => $agendamento->agendador_id ?? null,
'agendador_nome' => $currentLotacao->usuario->cidadao->nome ?? null,
];
})
->sortBy('data')
->values(),
'agendamentosNotSave' => null,
'statusExames' => null,
'periodo' => [
'start' => Carbon::now()->format('d/m/Y'),
'end' => Carbon::now()->format('d/m/Y'),
],
'agendamentos_cancelados' => Agendamento::where('paciente_id', $id)
->whereHas('agendamentoExame', function ($query) {
$query->where('status_id', Status::CANCELADO);
})
->orderBy('data', 'asc')
->get()
->map(function ($cancelados) {
$medico_nome = self::getCidadao(self::getUsuarios([$cancelados->medico_id])->first()->cidadao_id)->nome;
return [
'data' => (new Carbon($cancelados->data))->format('d/m/Y') ?? null,
'agendamento_numero' => $cancelados->agendamento_numero,
'grupo_exame_id' => $cancelados->exame_id,
'grupo_exame_nome' => $cancelados->grupo->nome ?? null,
'unidade_id' => $cancelados->unidade_id,
'unidade_nome' => $cancelados->unidade->nome_fantasia,
'unidade_solicitante_id' => $cancelados->unidade_solicitante_id,
'unidade_solicitante_nome' => $cancelados->unidadeSolicitante->nome_fantasia,
'infraestrutura_solicitante_id' => $cancelados->infraestrutura_solicitante_id,
'infraestrutura_id' => $cancelados->infraestrutura_id,
'infraestrutura_nome' => $cancelados->infraestrutura->nome,
'hora_exame' => (new Carbon($cancelados->hora_exame))->format('H:i') ?? null,
'profissional_id' => $cancelados->profissional_id,
'profissional_nome' => $cancelados->jornada->usuario->nome ?? null,
'medico_id' => $cancelados->medico_id,
'medico_nome' => $medico_nome ?? null,
'exames' => AgendamentoExame::where('agendamento_id', $cancelados->id)
->get()
->map(function ($query) {
$lotacaoCancelado = Lotacao::where('usuario_id', $query->usuario_id_cancelado)->first();
$usuarioCancelado = null;
if ($lotacaoCancelado && $lotacaoCancelado->usuario && $lotacaoCancelado->usuario->cidadao) {
$usuarioCancelado = $lotacaoCancelado->usuario->cidadao->nome;
}
return [
'exame_id' => $query->exame_id,
'nome_exame' => $query->exame->nome,
'usuario_id_cancelado' => $query->usuario_id_cancelado ?? null,
'usuario_cancelado_nome' => $usuarioCancelado ?? null,
'data_hora_cancelado' => $query->data_hora_cancelado
? (new Carbon($query->data_hora_cancelado))->format('d/m/Y H:i') : null,
];
})
->values(),
];
}),
'agendamentos_excluidos' => AgendamentoHistoricoExclusao::where('paciente_id', $id)
->get()
->groupBy('agendamento_id')
->map(function ($groupedItems) {
$agendamento = $groupedItems->first();
$lotacao = Lotacao::where('usuario_id', $agendamento->agendamento_agendador_id)->first();
$usuarioAgendador = $lotacao->usuario->cidadao->nome;
$usuarioExclusao = Lotacao::find($agendamento->created_lotacao_id)->usuario->cidadao->nome;
return [
'id' => $agendamento->id,
'agendamento_id' => $agendamento->agendamento_id,
'agendamento_agendador_id' => $agendamento->agendamento_agendador_id,
'usuario_agendador' => $usuarioAgendador,
'agendamento_numero' => $agendamento->agendamento_numero,
'data_hora_criacao' => $agendamento->data_hora_criacao
? (new Carbon($agendamento->data_hora_criacao))->format('d/m/Y H:i') : null,
'paciente_id' => $agendamento->paciente_id,
'created_lotacao_id' => $agendamento->created_lotacao_id,
'usuario_exclusao' => $usuarioExclusao,
'data_hora_exclusao' => $agendamento->data_hora_exclusao
? (new Carbon($agendamento->data_hora_exclusao))->format('d/m/Y H:i') : null,
'exames' => $groupedItems->map(function ($query) {
return [
'exame_id' => $query->exame_id,
'nome_exame' => $query->exame->nome,
];
})->values(),
];
})
->values(),
],
];
}
public static function getUnidadeExecutante()
{
$unidade = DB::table('exame_imagem_jornada as unidade_executante')
->select([
'unidade_executante.id as unidade_executante_id',
'cadastro_unidade.id AS unidade_id',
'cadastro_unidade.nome_fantasia as unidade_nome',
'cadastro_infraestrutura.id AS infraestrutura_id',
DB::raw("
CASE WHEN cadastro_infraestrutura.nome IS NOT NULL THEN
cadastro_infraestrutura.nome
ELSE
cadastro_unidade.nome_fantasia
END AS nome_infraestrutura
"),
'cadastro_infraestrutura.principal as principal',
'cadastro_logradouro.nome as endereco',
'cadastro_endereco.numero as numeroEndereco',
'cadastro_bairro.nome as bairro',
'cadastro_infraestrutura.telefone AS telefone',
])
->join('cadastro_infraestrutura', 'cadastro_infraestrutura.id', 'unidade_executante.infraestrutura_id')
->join('cadastro_unidade', 'cadastro_unidade.id', 'cadastro_infraestrutura.unidade_id')
->leftJoin('cadastro_endereco', 'cadastro_endereco.id', 'cadastro_infraestrutura.endereco_id')
->leftJoin('cadastro_logradouro', 'cadastro_logradouro.id', 'cadastro_endereco.logradouro_id')
->leftJoin('cadastro_bairro', 'cadastro_bairro.id', 'cadastro_logradouro.bairro_id')
->whereNull('unidade_executante.deleted_at')
->whereNull('cadastro_infraestrutura.deleted_at')
->where('unidade_executante.data', '<', now())
->groupBy('cadastro_infraestrutura.id')
->orderBy('unidade_nome')
->get();
if ($unidade->isEmpty()) {
return [];
}
foreach ($unidade as $item) {
$unidadeId = $item->unidade_id;
$infraestruturaId = $item->infraestrutura_id;
$nomeInfraestrutura = $item->nome_infraestrutura;
if (!isset($resultadoAgrupado[$unidadeId])) {
$resultadoAgrupado[$unidadeId] = [
'unidadeId' => $unidadeId,
'unidade_nome' => $item->unidade_nome ?? null,
'infraestruturas' => []
];
}
$resultadoAgrupado[$unidadeId]['infraestruturas'][] = [
'infraestruturaId' => $infraestruturaId,
'nomeInfraestrutura' => $nomeInfraestrutura,
'principal' => $item->principal,
'endereco' => $item->endereco ?? null,
'numeroEndereco' => $item->numeroEndereco ?? null,
'bairro' => $item->bairro ?? null,
'telefone' => $item->telefone ?? null,
];
}
usort($resultadoAgrupado, function ($a, $b) {
return strcmp($a['unidade_nome'], $b['unidade_nome']);
});
return $resultadoAgrupado;
}
public static function getGrupo($request)
{
$grupo = DB::table('exame_imagem_jornada as jornada_grupo')
->select([
'jornada_grupo.exame_id AS exame_id',
'grupo.nome AS exame_nome',
])
->leftJoin('cadastro_grupo AS grupo', 'grupo.id', 'jornada_grupo.exame_id')
->where('jornada_grupo.unidade_id', $request->unidade_id)
->where('jornada_grupo.infraestrutura_id', $request->infraestrutura_id)
->groupBy([
'exame_id',
])
->whereNull('grupo.deleted_at');
$grupo = $grupo->get()->toArray();
return $grupo;
}
public static function getProfissional($request)
{
$profissional = DB::table('cadastro_usuario')
->select([
'cadastro_usuario.usuario AS usuario',
'cadastro_usuario.id AS profissional_id',
'cadastro_cidadao.nome AS profissional_nome'
])
->leftJoin('exame_imagem_jornada', 'exame_imagem_jornada.usuario_id', 'cadastro_usuario.id')
->leftJoin('cadastro_cidadao', 'cadastro_cidadao.id', 'cadastro_usuario.cidadao_id')
->where('exame_imagem_jornada.unidade_id', $request->unidade_id)
->where('exame_imagem_jornada.infraestrutura_id', $request->infraestrutura_id)
->where('exame_imagem_jornada.exame_id', $request->exame_id)
->groupBy([
'cadastro_usuario.id',
]);
$profissional = $profissional->get()->toArray();
return $profissional;
}
private static function getCentroCustoLogado()
{
return CentroCusto::findOrFail(auth()->payload()->get('centro_custo_id'));
}
public static function getValorUtilizadoPeriodo($request)
{
return [
'valor_utilizado_periodo' => DB::table('exame_imagem_agendamento_exame')
->join('exame_imagem_agendamento', 'exame_imagem_agendamento.id', '=', 'exame_imagem_agendamento_exame.agendamento_id')
->join('parametrizacao_exame', 'parametrizacao_exame.id', '=', 'exame_imagem_agendamento_exame.exame_id')
->whereYear('exame_imagem_agendamento.data', $request->ano)
->whereMonth('exame_imagem_agendamento.data', $request->mes)
->where('exame_imagem_agendamento.infraestrutura_id', $request->infraestrutura_id)
->whereIn('exame_imagem_agendamento_exame.status_id', [AgendamentoStatus::REALIZADO, AgendamentoStatus::AGENDADO])
->selectRaw('SUM(parametrizacao_exame.valor) AS valor')
->value('valor'),
];
}
public static function getJornadas($request)
{
$dataAtual = Carbon::today();
return [
'agendamentos' => DB::table('exame_imagem_agendamento as agendamento')
->leftJoin('exame_imagem_jornada as jornada', 'jornada.id', 'agendamento.jornada_id')
->leftJoin('parametrizacao_exame as exame', 'exame.id', 'agendamento.exame_id')
->leftJoin('cadastro_grupo as grupo', 'grupo.id', 'exame.grupo_tipo_id')
->leftJoin('cadastro_infraestrutura as infraestrutura', 'infraestrutura.id', 'agendamento.infraestrutura_id')
->leftJoin('cadastro_usuario as usuario_medico', 'usuario_medico.id', 'agendamento.medico_id')
->leftJoin('cadastro_cidadao as medico', 'medico.id', 'usuario_medico.cidadao_id')
->leftJoin('cadastro_cidadao as profissional', 'profissional.id', 'agendamento.profissional_id')
->leftJoin('cadastro_unidade as unidade', 'unidade.id', 'agendamento.unidade_id')
->select([
'agendamento.id',
'agendamento.agendamento_numero',
'jornada.controle_jornada_id as controle_jornada_id',
'grupo.nome as exame_nome',
'agendamento.data',
'agendamento.data_menstruacao',
'agendamento.exame_id',
'agendamento.hora_exame',
'agendamento.infraestrutura_id',
'infraestrutura.nome as infraestrutura_nome',
'agendamento.jornada_id',
'agendamento.medico_id',
'medico.nome as medico_nome',
'agendamento.nome_responsavel',
'agendamento.observacao',
'agendamento.paciente_id',
'agendamento.profissional_id',
'profissional.nome as profissional_nome',
'agendamento.unidade_id',
'unidade.nome_fantasia as unidade_nome_fantasia',
'grupo.id as grupo_id',
])
->where('agendamento.data', '<', $dataAtual->format('Y-m-d'))
->where('agendamento.profissional_id', $request->profissional_id)
->where('agendamento.unidade_id', $request->unidade_id)
->where('agendamento.exame_id', $request->exame_id)
->get()
->map(fn ($agendamento) => [
'alterar' => false,
'agendamento_id' => $agendamento->id,
'agendamento_numero' => $agendamento->agendamento_numero,
'controle_jornada_id' => $agendamento->controle_jornada_id,
'data' => (new Carbon($agendamento->data))->format('d/m/Y') ?? null,
'data_menstruacao' => (new Carbon($agendamento->data_menstruacao))->format('Y-m-d') ?? null,
'dias_semana' => [$agendamento->exame_id],
'exame' => DB::table('parametrizacao_exame as exame')
->select([
'exame.id',
'exame.nome',
])
->where('exame.grupo_tipo_id', $agendamento->grupo_id)
->get()
->map(function ($query) {
return [
'id' => $query->id,
'nome' => $query->nome,
];
})
->values(),
'exame_id' => $agendamento->exame_id,
'exame_nome' => $agendamento->exame_nome,
'gestante' => $agendamento->gestante ?? false,
'hora_exame' => (new Carbon($agendamento->hora_exame))->format('H:i') ?? null,
'incluido' => AgendamentoExame::where('agendamento_id', $agendamento->id)
->get()
->map(function ($query) use ($agendamento) {
return [
'id' => $query->id,
'exame_id' => $query->exame_id,
'nome' => $query->exame->nome,
'codigo' => $query->exame->codigo ?? null,
'hora_exame' => (new Carbon($agendamento->hora_exame))->format('H:i') ?? null,
'observacao' => $query->exame->observacao,
'valor' => $query->exame->valor_sigtap ? $query->exame->procedimento->valor_servico_ambilatorial : $query->exame->valor,
];
})
->values(),
'infraestrutura_id' => $agendamento->infraestrutura_id,
'infraestrutura_nome' => $agendamento->infraestrutura_nome,
'jornada_id' => $agendamento->jornada_id,
'medico_id' => $agendamento->medico_id,
'medico_nome' => $agendamento->medico_nome,
'medico_solicitante' => [
'id' => $agendamento->medico_id,
'nome' => $agendamento->medico_nome,
],
'nome_responsavel' => $agendamento->nome_responsavel,
'observacao' => $agendamento->observacao,
'paciente_id' => $agendamento->paciente_id,
'periodo' => [
'start' => (new Carbon($agendamento->data))->format('d/m/Y') ?? null,
'end' => (new Carbon($agendamento->data))->format('d/m/Y') ?? null,
],
'profissional_id' => $agendamento->profissional_id,
'profissional_nome' => $agendamento->profissional_nome,
'selecionado' => false,
'supervisor_id' => $agendamento->supervisor_id ?? null,
'unidade_id' => $agendamento->unidade_id,
'unidade_nome' => $agendamento->unidade_nome_fantasia,
'urgente' => $agendamento->urgente ?? false,
'retroativo' => $agendamento->retroativo ?? false,
])
->sortBy('data')
->values(),
'jornadas' => DB::table('exame_imagem_jornada as jornada')
->leftJoin('parametrizacao_exame as exame', 'exame.id', 'jornada.exame_id')
->leftJoin('cadastro_grupo as grupo', 'grupo.id', 'jornada.exame_id')
->leftJoin('cadastro_usuario as usuario_jornada', 'usuario_jornada.id', 'jornada.prestador_id')
->leftJoin('cadastro_cidadao as cidadao_jornada', 'cidadao_jornada.id', 'usuario_jornada.cidadao_id')
->leftJoin('cadastro_unidade as unidade', 'unidade.id', 'jornada.unidade_id')
->leftJoin('cadastro_infraestrutura as infraestrutura', 'infraestrutura.id', 'jornada.infraestrutura_id')
->select([
'jornada.id',
'jornada.unidade_id',
'jornada.controle_jornada_id',
'jornada.exame_id',
'grupo.nome as grupo_nome',
'jornada.usuario_id',
'jornada.prestador_id',
'jornada.infraestrutura_id',
'jornada.semana_id',
'jornada.vagas',
'jornada.vagas_app',
'jornada.tipo_id',
'jornada.tempo_atendimento',
'jornada.data',
'jornada.hora_inicial',
'jornada.hora_fim',
'cidadao_jornada.nome as usuario_nome',
'unidade.nome_fantasia',
'infraestrutura.nome as infraestrutura_nome',
'grupo.id as grupo_id',
])
->where('jornada.data', '<', $dataAtual->format('Y-m-d'))
->where('jornada.unidade_id', $request->unidade_id)
->where('jornada.usuario_id', $request->profissional_id)
->where('jornada.exame_id', $request->exame_id)
->get()
->map(fn ($jornada) => [
'jornada_id' => $jornada->id,
'unidade_id' => $jornada->unidade_id,
'controle_jornada_id' => $jornada->controle_jornada_id,
'jornada_id' => $jornada->id,
'exame_id' => $jornada->exame_id,
'exame_nome' => $jornada->grupo_nome,
'profissional_id' => $jornada->usuario_id,
'profissional_nome' => $jornada->usuario_nome,
'prestador_id' => $jornada->prestador_id,
'prestador_nome' => $jornada->nome_fantasia,
'unidade_id' => $jornada->unidade_id,
'unidade_nome' => $jornada->nome_fantasia,
'infraestrutura_id' => $jornada->infraestrutura_id,
'infraestrutura_nome' => $jornada->infraestrutura_nome,
'semana_id' => $jornada->semana_id,
'data' => (new Carbon($jornada->data))->format('d/m/Y') ?? null,
'vagas' => $jornada->vagas ?? null,
'vagas_app' => $jornada->vagas_app ?? null,
'tipo_id' => $jornada->tipo_id,
'tempo_atendimento' => $jornada->tempo_atendimento,
'selecionado' => false,
'hora_inicial' => (new Carbon($jornada->hora_inicial))->format('H:i') ?? null,
'hora_fim' => (new Carbon($jornada->hora_fim))->format('H:i') ?? null,
])
->sortBy('data')
->sortBy('hora_inicial')
->values(),
];
}
public static function getSupervisores($request)
{
return [
'supervisores' => Supervisor::where('usuario_id', $request->supervisor_id)
->get()
->map(fn ($supervisor) => [
'id' => $supervisor->id,
'usuario_id' => $supervisor->usuario_id,
'nome' => $supervisor->usuario->cidadao->nome,
'cpf' => $supervisor->usuario->cidadao->cpf,
]),
];
}
public static function store(Request $request)
{
self::validate($request);
return self::saveAgendamento($request);
}
private static function saveAgendamento($request)
{
$ids = [];
$idsSms = [];
foreach ($request->agendamentos as $params) {
if ($params['agendamento_id'] && is_numeric($params['agendamento_id'])) {
$tipo = Agendamento::where('id', $params['agendamento_id'])->first();
} else {
$tipo = new Agendamento();
}
$tipo->agendamento_numero = $params['agendamento_numero'];
$tipo->paciente_id = $params['paciente_id'];
$tipo->jornada_id = $params['jornada_id'];
$tipo->medico_id = $params['medico_id'];
$tipo->profissional_id = $params['profissional_id'];
$tipo->data = $params['data'];
$tipo->exame_id = $params['grupo_exame_id'];
$tipo->hora_exame = $params['hora_exame'];
$tipo->unidade_id = $params['unidade_id'];
$tipo->unidade_solicitante_id = $params['unidade_solicitante_id'];
$tipo->infraestrutura_solicitante_id = $params['infraestrutura_solicitante_id'];
$tipo->infraestrutura_id = $params['infraestrutura_id'];
$tipo->nome_responsavel = $params['nome_responsavel'];
$tipo->observacao = $params['observacao'];
$tipo->gestante = $params['gestante'];
$tipo->urgente = $params['urgente'];
$tipo->supervisor_id = $params['supervisor_id'];
$tipo->retroativo = $params['retroativo'];
$tipo->agendador_id = $params['agendador_id'];
if ($params['impressao'] == true && $params['supervisor_id'] == null) {
self::verifyJornada($params);
}
$tipo->save();
$ids[] = $tipo->id;
$paciente_id = $tipo->paciente_id;
$agendamento_id = $tipo->id;
if ($params['impressao'] == true) {
$idsSms[] = $tipo->id;
$impressao_agendamento_numero = $tipo->agendamento_numero;
}
foreach ($params['incluido'] as $param_exame) {
if ($param_exame['id'] && is_numeric($param_exame['id'])) {
$exame = AgendamentoExame::where('id', $param_exame['id'])->first();
} else {
$exame = new AgendamentoExame();
}
$exame->agendamento_id = $agendamento_id;
$exame->exame_id = $param_exame['exame_id'];
$exame->paciente_id = $paciente_id;
$exame->save();
$idsExame[] = $exame->id;
}
}
foreach ($idsSms as $idSms) {
if ($params['agendamento_id'] && is_numeric($params['agendamento_id'])) {
(new SmsService($idSms))->cancel();
}
(new SmsService($idSms))->send();
}
if (isset($impressao_agendamento_numero)){
return [
'impressao_agendamento_numero' => $impressao_agendamento_numero,
];
}
}
private static function verifyJornada($params)
{
if($params['controle_jornada_id'] == ControleJornadaTipo::EXAME){
$agendamentoExames = Agendamento::where('data', '=', $params['data'])
->where('profissional_id', $params['profissional_id'])
->where('unidade_id', $params['unidade_id'])
->where('infraestrutura_id', $params['infraestrutura_id'])
->where('exame_id', $params['grupo_exame_id'])
->get();
$agendamentoCadastrado = 0;
foreach ($agendamentoExames as $param_exames) {
$agendamentoCadastrado = $agendamentoCadastrado +
AgendamentoExame::where('agendamento_id', $param_exames['id'])
->count('id') ?? 0;
}
if(is_numeric($params['agendamento_id'])){
$agendamentoExamesIncluidos = AgendamentoExame::where('agendamento_id', $params['agendamento_id'])
->count('id') ?? 0;
$agendamentoCadastrado = ($agendamentoCadastrado-$agendamentoExamesIncluidos) + count($params['incluido']);
} else {
$agendamentoCadastrado = $agendamentoCadastrado + count($params['incluido']);
}
} else {
$agendamentoCadastrado = Agendamento::where('data', '=', $params['data'])
->where('profissional_id', $params['profissional_id'])
->where('unidade_id', $params['unidade_id'])
->where('infraestrutura_id', $params['infraestrutura_id'])
->where('exame_id', $params['grupo_exame_id'])
->count('id') ?? 0;
}
$jornada = Jornada::where('unidade_id', $params['unidade_id'])
->where('infraestrutura_id', $params['infraestrutura_id'])
->where('usuario_id', $params['profissional_id'])
->where('exame_id', $params['grupo_exame_id'])
->where('data', '=', $params['data'])
->selectRaw('SUM(vagas + COALESCE(vagas_app, 0)) as total_vagas')
->value('total_vagas') ?? 0;
if ($agendamentoCadastrado > $jornada) {
throw new ExceededVagaJornadaException;
}
}
private static function validate($request)
{
$validations = [
'unidade_id' => [
'integer',
],
'incluido' => [
'array',
]
];
$messages = [
'unidade_id' => 'Necessário informar unidade.',
];
return $request->validate($validations, $messages);
}
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;
}
public static function cancel($id)
{
$agendamento = Agendamento::findOrFail($id);
$usuarioCancelado = self::getCurrentLotacao();
AgendamentoExame::where('agendamento_id', $agendamento->id)
->update([
'status_id' => Status::CANCELADO,
'usuario_id_cancelado' => $usuarioCancelado->usuario_id,
'data_hora_cancelado' => now(),
]);
if (!is_null($agendamento->regulacao_solicitacao_id)) {
RegulacaoSolicitacaoService::updateStatus(
$agendamento->regulacao_solicitacao_id,
RegulacaoStatusTipo::CANCELADO,
['justificativa' => 'Cancelado automaticamente pela funcionalidade Agendamento'],
);
}
(new SmsService($id))->cancel();
return $agendamento->fresh();
}
public static function destroy($id)
{
$agendamento = Agendamento::findOrFail($id);
$exames = AgendamentoExame::where('agendamento_id', $id)->get();
foreach ($exames as $exame) {
AgendamentoHistoricoExclusao::create([
'agendamento_id' => $agendamento->id,
'agendamento_agendador_id' => $agendamento->agendador_id,
'data_hora_criacao' => $agendamento->created_at,
'paciente_id' => $agendamento->paciente_id,
'agendamento_numero' => $agendamento->agendamento_numero,
'exame_id' => $exame->exame_id,
'data_hora_exclusao' => Carbon::now()->format('Y-m-d H:i:s'),
]);
}
(new SmsService($id))->cancel();
AgendamentoExame::where('agendamento_id', $id)->delete();
$agendamento = Agendamento::findOrFail($id);
$agendamento->delete();
}
}