862 lines
34 KiB
PHP
862 lines
34 KiB
PHP
<?php
|
|
|
|
namespace App\Services\ExameImagem;
|
|
|
|
use App\Enums\Administracao\Modulo;
|
|
use App\Enums\ExameImagem\Fechamento\Status;
|
|
use App\Enums\ExameImagem\Jornada\Tipo as JornadaTipo;
|
|
use App\Enums\ExameImagem\Parametrizacao\ControleJornada\Tipo as ControleJornadaTipo;
|
|
use App\Enums\ExameImagem\Tipo as ExameImagemTipo;
|
|
use App\Exceptions\ExameImagem\ExceededCotaAgendamentoException;
|
|
use App\Exceptions\ExameImagem\ExceededJornadaException;
|
|
use App\Models\Cadastro\Estabelecimento\Unidade;
|
|
use App\Models\Cadastro\Feriado\Feriado;
|
|
use App\Models\Cadastro\Grupo\Grupo;
|
|
use App\Models\Cadastro\SujeitoAtencao\Usuario;
|
|
use App\Models\ExameImagem\Agendamento\Agendamento;
|
|
use App\Models\ExameImagem\Agendamento\AgendamentoExame;
|
|
use App\Models\ExameImagem\CotaPrestador;
|
|
use App\Models\ExameImagem\Jornada\Jornada;
|
|
use App\Models\ExameImagem\Jornada\SemanaJornada;
|
|
use App\Models\ExameImagem\Parametrizacao;
|
|
use App\Services\Service;
|
|
use App\Utils\MaskUtil;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Validation\Rule;
|
|
|
|
class ReagendamentoCancelamentoExameService extends Service
|
|
{
|
|
|
|
public static function datatable()
|
|
{
|
|
$gerenciamentoJornadas = DB::table('cadastro_usuario')
|
|
->select(
|
|
'cadastro_usuario.id',
|
|
'cadastro_usuario.cidadao_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'),
|
|
'cadastro_unidade.nome_fantasia'
|
|
)
|
|
->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'
|
|
)
|
|
->join(
|
|
'cadastro_infraestrutura',
|
|
'cadastro_infraestrutura.id',
|
|
'cadastro_lotacao.infraestrutura_id'
|
|
)
|
|
->join(
|
|
'cadastro_unidade',
|
|
'cadastro_unidade.id',
|
|
'cadastro_infraestrutura.unidade_id'
|
|
)
|
|
->where('cadastro_usuario.bloqueado', '=', '0')
|
|
->whereNull('cadastro_lotacao.deleted_at')
|
|
->whereNull('exame_imagem_parametrizacao_ocupacao.deleted_at')
|
|
->groupBy('cadastro_usuario.id');
|
|
|
|
return $gerenciamentoJornadas;
|
|
}
|
|
|
|
public static function edit($usuarioId)
|
|
{
|
|
$usuario = Usuario::findOrFail($usuarioId);
|
|
|
|
return [
|
|
'form' => self::getFormData($usuario),
|
|
'model' => self::getModelData(),
|
|
];
|
|
}
|
|
|
|
private static function getFormData($usuario)
|
|
{
|
|
return [
|
|
'data_atual' => Carbon::now()->format('Y-m-d'),
|
|
'usuario' => self::getUsuarioData($usuario),
|
|
'origem' => [
|
|
'feriados' => self::getFeriados(),
|
|
'unidades' => [],
|
|
'infraestruturas' => [],
|
|
'prestadores' => [],
|
|
'agendamentos' => [],
|
|
'grupos' => [],
|
|
],
|
|
'destino' => [
|
|
'unidades' => [],
|
|
'infraestruturas' => [],
|
|
'prestadores' => [],
|
|
'grupos' => [],
|
|
'usuarios' => [],
|
|
'jornadas' => [],
|
|
],
|
|
'unidadesParametrizadas' => Parametrizacao::where('executante', true)
|
|
->orderBy('unidade_id')
|
|
->whereExists(function ($query) use ($usuario) {
|
|
$query->select(DB::raw(1))
|
|
->from('exame_imagem_jornada')
|
|
->where('usuario_id', $usuario->id)
|
|
->whereColumn('exame_imagem_jornada.unidade_id', 'exame_imagem_parametrizacao_unidade.unidade_id')
|
|
->whereExists(function ($query) {
|
|
$query->select(DB::raw(1))
|
|
->from('exame_imagem_agendamento')
|
|
->whereColumn('exame_imagem_agendamento.jornada_id', 'exame_imagem_jornada.id');
|
|
});
|
|
})
|
|
->get()
|
|
->map(fn ($query) => [
|
|
'id' => $query->id,
|
|
'unidade_id' => $query->unidade_id,
|
|
'nome_fantasia' => $query->unidade->nome_fantasia,
|
|
'infraestruturas' => $query->unidade->infraestruturas->sortBy('nome')->map(fn ($infraestrutura) => [
|
|
'id' => $infraestrutura->id,
|
|
'nome' => $infraestrutura->nome,
|
|
'principal' => $infraestrutura->principal,
|
|
])->values()
|
|
]),
|
|
'exames' => [],
|
|
'dias_semana' => SemanaJornada::orderBy('id')
|
|
->get()
|
|
->map(fn ($semanaJornadas) => [
|
|
'id' => $semanaJornadas->id,
|
|
'nome' => $semanaJornadas->nome,
|
|
'disabled' => true,
|
|
]),
|
|
'prestadores' => [],
|
|
];
|
|
}
|
|
|
|
public static function getGrupos($request) {
|
|
|
|
return Grupo::whereExists(function ($query) use ($request) {
|
|
$query->select(DB::raw(1))
|
|
->from('exame_imagem_jornada')
|
|
->where('usuario_id', $request->profissional_id)
|
|
->where('infraestrutura_id', $request->infraestrutura_id)
|
|
->where('prestador_id', $request->prestador_id)
|
|
->whereColumn('exame_imagem_jornada.exame_id', 'cadastro_grupo.id')
|
|
->whereExists(function ($query) {
|
|
$query->select(DB::raw(1))
|
|
->from('exame_imagem_agendamento')
|
|
->whereColumn('exame_imagem_agendamento.jornada_id', 'exame_imagem_jornada.id');
|
|
});
|
|
})
|
|
->get()
|
|
->map(function ($query) {
|
|
return [
|
|
'id' => $query->id,
|
|
'nome' => $query->nome,
|
|
];
|
|
})
|
|
->values();
|
|
}
|
|
|
|
public static function getPrestadores($request) {
|
|
|
|
return Unidade::whereHas('parametrizacaoExameImagem', function ($query) use ($request) {
|
|
$query->where('prestador', true)
|
|
->whereExists(function ($query) use ($request) {
|
|
$query->select(DB::raw(1))
|
|
->from('exame_imagem_jornada')
|
|
->where('usuario_id', $request->profissional_id)
|
|
->where('infraestrutura_id', $request->infraestrutura_id)
|
|
->whereColumn('exame_imagem_jornada.prestador_id', 'exame_imagem_parametrizacao_unidade.id')
|
|
->whereExists(function ($query) {
|
|
$query->select(DB::raw(1))
|
|
->from('exame_imagem_agendamento')
|
|
->whereColumn('exame_imagem_agendamento.jornada_id', 'exame_imagem_jornada.id');
|
|
});
|
|
});
|
|
})
|
|
->orderBy('nome_fantasia')
|
|
->get()
|
|
->map(fn ($unidade) => [
|
|
'unidade_id' => $unidade->id,
|
|
'nome_fantasia' => $unidade->nome_fantasia,
|
|
'prestador' => $unidade->parametrizacaoExameImagem->prestador,
|
|
'prestador_id' => $unidade->parametrizacaoExameImagem->id,
|
|
])
|
|
->unique('unidade_id')
|
|
->values();
|
|
}
|
|
|
|
private static function getFeriados()
|
|
{
|
|
return Feriado::whereHas('modulos', fn ($q) => $q
|
|
->where('identificador', Modulo::EXAME_IMAGEM)
|
|
)
|
|
->orderBy('data')
|
|
->get()
|
|
->map(fn ($feriado) => (object) [
|
|
'data' => (new Carbon($feriado->data))->format('d/m/Y'),
|
|
'tipo_descricao' => $feriado->tipo->descricao,
|
|
'observacao' => $feriado->observacao,
|
|
]);
|
|
}
|
|
|
|
private static function getUsuarioData($usuario)
|
|
{
|
|
$cidadao = $usuario->cidadao()->setEagerLoads([])->first(['nome', 'data_nascimento', 'cns', 'cpf']);
|
|
$ocupacao = DB::table('cadastro_usuario')
|
|
->select(
|
|
'exame_imagem_parametrizacao_ocupacao.ocupacao_id',
|
|
'ocupacao.nome AS ocupacao_nome',
|
|
)
|
|
->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.id', $usuario->id)
|
|
->whereNull('cadastro_lotacao.deleted_at')
|
|
->whereNull('exame_imagem_parametrizacao_ocupacao.deleted_at')
|
|
->first();
|
|
|
|
return [
|
|
'id' => $usuario->id,
|
|
'nome' => $cidadao->nome,
|
|
'data_nascimento' => is_null($cidadao->data_nascimento)
|
|
? null : (new Carbon($cidadao->data_nascimento))->format('d/m/Y'),
|
|
'cns' => MaskUtil::getCnsMasked($cidadao->cns),
|
|
'cpf' => MaskUtil::getCpfMasked($cidadao->cpf),
|
|
'ocupacao' => $ocupacao->ocupacao_nome,
|
|
];
|
|
}
|
|
|
|
public static function getJornadas($request)
|
|
{
|
|
|
|
$dataAtual = Carbon::today();
|
|
$proximoMes = $dataAtual->copy()->addMonths(1);
|
|
$ultimoDiaProximoMes = $proximoMes->copy()->endOfMonth();
|
|
|
|
$agendamentos = Agendamento::with([
|
|
'jornada',
|
|
'paciente.cidadao.telefones',
|
|
'createdLotacao.usuario.cidadao',
|
|
'agendamentoExame.exame.procedimento'
|
|
])
|
|
->where('profissional_id', $request->profissional_id)
|
|
->whereHas('agendamentoExame', function($query) {
|
|
$query->where('status_id', Status::AGENDADO)
|
|
->orWhereNull('status_id');
|
|
})
|
|
->whereNull('regulacao_solicitacao_id')
|
|
->where('unidade_id', $request->unidade_id)
|
|
->where('exame_id', $request->exame_id)
|
|
->when($request->filled('data'), function ($query) use ($request) {
|
|
$query->where('data', $request->data);
|
|
}, function ($query) use ($dataAtual) {
|
|
$query->where('data', '>=', $dataAtual->format('Y-m-d'));
|
|
})
|
|
->get()
|
|
->map(function ($agendamento) {
|
|
return [
|
|
'alterar' => false,
|
|
'id' => $agendamento->id,
|
|
'agendamento_numero' => $agendamento->agendamento_numero,
|
|
'controle_jornada_id' => optional($agendamento->jornada)->controle_jornada_id,
|
|
'data' => optional($agendamento->data)->format('d/m/Y'),
|
|
'data_menstruacao' => optional($agendamento->data_menstruacao)->format('Y-m-d'),
|
|
'hora_exame' => optional($agendamento->hora_exame)->format('H:i'),
|
|
'paciente_telefones' => $agendamento->paciente->cidadao->telefones->map(fn ($t) => MaskUtil::getPhoneMasked($t->numero))->all(),
|
|
'usuario' => optional($agendamento->createdLotacao->usuario->cidadao)->nome,
|
|
'paciente' => [
|
|
'nome' => optional($agendamento->paciente->cidadao)->nome,
|
|
'nome_social' => optional($agendamento->paciente->cidadao)->nome_social,
|
|
'data_nascimento' => optional($agendamento->paciente->cidadao->data_nascimento)->format('d/m/Y'),
|
|
'prontuario' => $agendamento->paciente->prontuario,
|
|
],
|
|
'incluido' => $agendamento->agendamentoExame->map(function ($exame) use ($agendamento) {
|
|
return [
|
|
'id' => $exame->id,
|
|
'exame_id' => $exame->exame_id,
|
|
'nome' => $exame->exame->nome,
|
|
'codigo' => $exame->exame->codigo,
|
|
'hora_exame' => optional($agendamento->hora_exame)->format('H:i'),
|
|
'observacao' => $exame->exame->observacao,
|
|
'valor' => $exame->exame->valor_sigtap
|
|
? optional($exame->exame->procedimento)->valor_servico_ambilatorial
|
|
: $exame->exame->valor,
|
|
];
|
|
})->values(),
|
|
];
|
|
})->sortBy('data')->values();
|
|
|
|
$jornadas = Jornada::where('unidade_id', $request->unidade_id)
|
|
->where('usuario_id', $request->profissional_id)
|
|
->where('exame_id', $request->exame_id)
|
|
->where('prestador_id', $request->prestador_id)
|
|
->where(function ($query) use ($dataAtual, $ultimoDiaProximoMes) {
|
|
$query->where('data', '>=', $dataAtual)
|
|
->orWhereBetween('data', [$dataAtual, $ultimoDiaProximoMes]);
|
|
})
|
|
->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->unidade->nome_fantasia,
|
|
'unidade_id' => $jornada->unidade_id,
|
|
'unidade_nome' => $jornada->unidade->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,
|
|
'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,
|
|
'status_id' => $jornada->status_id,
|
|
'status_nome' => $jornada->status->nome,
|
|
])
|
|
->sortBy('data')
|
|
->sortBy('hora_inicial')
|
|
->values();
|
|
|
|
return [
|
|
'agendamentos' => $agendamentos,
|
|
'jornadas' => $jornadas,
|
|
];
|
|
}
|
|
|
|
public static function getJornadasDestino($request)
|
|
{
|
|
|
|
$dataAtual = Carbon::today();
|
|
$proximoMes = $dataAtual->copy()->addMonths(1);
|
|
$ultimoDiaProximoMes = $proximoMes->copy()->endOfMonth();
|
|
|
|
if ($request->field === 'unidade') {
|
|
|
|
$resultado = Jornada::where(function ($query) use ($dataAtual, $ultimoDiaProximoMes) {
|
|
$query->where('data', '>=', $dataAtual)
|
|
->orWhereBetween('data', [$dataAtual, $ultimoDiaProximoMes]);
|
|
})
|
|
->whereExists(function ($query) {
|
|
$query->select(DB::raw(1))
|
|
->from('exame_imagem_agendamento')
|
|
->whereColumn('exame_imagem_agendamento.jornada_id', 'exame_imagem_jornada.id');
|
|
})
|
|
->groupBy('unidade_id')
|
|
->get()
|
|
->map(fn ($jornada) => [
|
|
'id' => $jornada->unidade_id,
|
|
'nome_fantasia' => $jornada->unidade->nome_fantasia,
|
|
]);
|
|
}
|
|
|
|
if ($request->field === 'infraestrutura') {
|
|
|
|
$resultado = Jornada::when($request->filled('unidade_id'), function ($query) use ($request) {
|
|
$query->where('unidade_id', $request->unidade_id);
|
|
})
|
|
->where(function ($query) use ($dataAtual, $ultimoDiaProximoMes) {
|
|
$query->where('data', '>=', $dataAtual)
|
|
->orWhereBetween('data', [$dataAtual, $ultimoDiaProximoMes]);
|
|
})
|
|
->whereExists(function ($query) {
|
|
$query->select(DB::raw(1))
|
|
->from('exame_imagem_agendamento')
|
|
->whereColumn('exame_imagem_agendamento.jornada_id', 'exame_imagem_jornada.id');
|
|
})
|
|
->groupBy('infraestrutura_id')
|
|
->get()
|
|
->map(fn ($jornada) => [
|
|
'id' => $jornada->infraestrutura_id,
|
|
'nome' => $jornada->infraestrutura->nome,
|
|
]);
|
|
}
|
|
|
|
if ($request->field === 'prestador') {
|
|
|
|
$resultado = Jornada::when($request->filled('unidade_id'), function ($query) use ($request) {
|
|
$query->where('unidade_id', $request->unidade_id);
|
|
})
|
|
->when($request->filled('infraestrutura_id'), function ($query) use ($request) {
|
|
$query->where('infraestrutura_id', $request->infraestrutura_id);
|
|
})
|
|
->where(function ($query) use ($dataAtual, $ultimoDiaProximoMes) {
|
|
$query->where('data', '>=', $dataAtual)
|
|
->orWhereBetween('data', [$dataAtual, $ultimoDiaProximoMes]);
|
|
})
|
|
->whereExists(function ($query) {
|
|
$query->select(DB::raw(1))
|
|
->from('exame_imagem_agendamento')
|
|
->whereColumn('exame_imagem_agendamento.jornada_id', 'exame_imagem_jornada.id');
|
|
})
|
|
->groupBy('prestador_id')
|
|
->get()
|
|
->map(fn ($jornada) => [
|
|
'id' => $jornada->prestador_id,
|
|
'nome' => $jornada->prestador->unidade->nome_fantasia,
|
|
]);
|
|
}
|
|
|
|
if ($request->field === 'grupo') {
|
|
|
|
$resultado = Jornada::when($request->filled('unidade_id'), function ($query) use ($request) {
|
|
$query->where('unidade_id', $request->unidade_id);
|
|
})
|
|
->when($request->filled('infraestrutura_id'), function ($query) use ($request) {
|
|
$query->where('infraestrutura_id', $request->infraestrutura_id);
|
|
})
|
|
->when($request->filled('prestador_id'), function ($query) use ($request) {
|
|
$query->where('prestador_id', $request->prestador_id);
|
|
})
|
|
->where(function ($query) use ($dataAtual, $ultimoDiaProximoMes) {
|
|
$query->where('data', '>=', $dataAtual)
|
|
->orWhereBetween('data', [$dataAtual, $ultimoDiaProximoMes]);
|
|
})
|
|
->whereExists(function ($query) {
|
|
$query->select(DB::raw(1))
|
|
->from('exame_imagem_agendamento')
|
|
->whereColumn('exame_imagem_agendamento.jornada_id', 'exame_imagem_jornada.id');
|
|
})
|
|
->groupBy('exame_id')
|
|
->get()
|
|
->map(fn ($jornada) => [
|
|
'id' => $jornada->exame_id,
|
|
'nome' => $jornada->grupo->nome,
|
|
]);
|
|
}
|
|
|
|
if ($request->field === 'usuario') {
|
|
|
|
$resultado = Jornada::when($request->filled('unidade_id'), function ($query) use ($request) {
|
|
$query->where('unidade_id', $request->unidade_id);
|
|
})
|
|
->when($request->filled('infraestrutura_id'), function ($query) use ($request) {
|
|
$query->where('infraestrutura_id', $request->infraestrutura_id);
|
|
})
|
|
->when($request->filled('prestador_id'), function ($query) use ($request) {
|
|
$query->where('prestador_id', $request->prestador_id);
|
|
})
|
|
->where(function ($query) use ($dataAtual, $ultimoDiaProximoMes) {
|
|
$query->where('data', '>=', $dataAtual)
|
|
->orWhereBetween('data', [$dataAtual, $ultimoDiaProximoMes]);
|
|
})
|
|
->whereExists(function ($query) {
|
|
$query->select(DB::raw(1))
|
|
->from('exame_imagem_agendamento')
|
|
->whereColumn('exame_imagem_agendamento.jornada_id', 'exame_imagem_jornada.id');
|
|
})
|
|
->groupBy('usuario_id')
|
|
->get()
|
|
->map(fn ($jornada) => [
|
|
'id' => $jornada->usuario_id,
|
|
'nome' => $jornada->usuario->nome,
|
|
]);
|
|
}
|
|
|
|
return $resultado;
|
|
}
|
|
|
|
public static function reschedule()
|
|
{
|
|
self::validateReschedule();
|
|
|
|
DB::transaction(function () {
|
|
|
|
collect(request()->agendamentos)->each(function ($agendamento) {
|
|
|
|
$id = $agendamento['id'];
|
|
|
|
$agendamentoAnterior = Agendamento::findOrFail($id);
|
|
$jornada = Jornada::findOrFail(request()->jornada_id);
|
|
|
|
if (!request()->supervisor_id) {
|
|
|
|
if ($jornada->tipo_id === ExameImagemTipo::QUANTIDADE) {
|
|
|
|
self::getSaldoUnidadeQuantidade($jornada, $agendamentoAnterior);
|
|
} else {
|
|
self::getSaldoUnidadeValor($jornada, $agendamentoAnterior);
|
|
}
|
|
|
|
self::handleJornada($jornada, $agendamentoAnterior);
|
|
}
|
|
|
|
$agendamentoAnterior->agendamentoExame()->update(['status_id' => Status::REAGENDADO]);
|
|
|
|
$nextHorario = self::getNextHorario($jornada);
|
|
|
|
$reagendamento = new Agendamento();
|
|
$reagendamento->agendamento_numero = now()->timestamp * 1000;;
|
|
$reagendamento->paciente_id = $agendamentoAnterior['paciente_id'];
|
|
$reagendamento->jornada_id = $jornada->id;
|
|
$reagendamento->medico_id = $agendamentoAnterior['medico_id'];
|
|
$reagendamento->profissional_id = $jornada->usuario_id;
|
|
$reagendamento->data = $jornada->data;
|
|
$reagendamento->exame_id = $jornada->exame_id;
|
|
$reagendamento->hora_exame = $nextHorario->horario;
|
|
$reagendamento->unidade_id = $jornada->unidade_id;
|
|
$reagendamento->unidade_solicitante_id = $agendamentoAnterior['unidade_solicitante_id'];
|
|
$reagendamento->infraestrutura_solicitante_id = $agendamentoAnterior['infraestrutura_solicitante_id'];
|
|
$reagendamento->infraestrutura_id = $jornada->infraestrutura_id;
|
|
$reagendamento->nome_responsavel = $agendamentoAnterior['nome_responsavel'];
|
|
$reagendamento->observacao = $agendamentoAnterior['observacao'];
|
|
$reagendamento->gestante = $agendamentoAnterior['gestante'];
|
|
$reagendamento->urgente = $agendamentoAnterior['urgente'];
|
|
$reagendamento->supervisor_id = request()->supervisor_id;
|
|
$reagendamento->retroativo = $agendamentoAnterior['retroativo'];
|
|
$reagendamento->agendador_id = $agendamentoAnterior['agendador_id'];
|
|
$reagendamento->save();
|
|
|
|
$paciente_id = $reagendamento->paciente_id;
|
|
$agendamento_id = $reagendamento->id;
|
|
|
|
foreach ($agendamentoAnterior->agendamentoExame as $param_exame) {
|
|
|
|
$exame = new AgendamentoExame();
|
|
$exame->agendamento_id = $agendamento_id;
|
|
$exame->exame_id = $param_exame['exame_id'];
|
|
$exame->paciente_id = $paciente_id;
|
|
$exame->status_id = Status::AGENDADO;
|
|
|
|
$exame->save();
|
|
}
|
|
});
|
|
});
|
|
|
|
return (object) ['agendamentos_nao_reagendados' => []];
|
|
}
|
|
|
|
private static function getSaldoUnidadeQuantidade($jornada, $agendamentoAnterior)
|
|
{
|
|
|
|
$cotaUnidade = CotaPrestador::where('infraestrutura_id', $jornada->prestador->infraestrutura->id)
|
|
->where('cota_tipo_id', ExameImagemTipo::QUANTIDADE)
|
|
->where('inicio', '<=', $jornada->data)
|
|
->where('fim', '>=', $jornada->data)
|
|
->first();
|
|
|
|
if ($cotaUnidade) {
|
|
|
|
$totalUnidade = $cotaUnidade->cota_unidade;
|
|
|
|
if ($jornada->controle_jornada_id == ControleJornadaTipo::EXAME) {
|
|
|
|
$cotaUtilizada = AgendamentoExame::whereHas('agendamento', function($query) use ($jornada, $cotaUnidade) {
|
|
$query->whereHas('jornada', function($query) use ($jornada) {
|
|
$query->where('prestador_id', $jornada->prestador_id);
|
|
})
|
|
->where('data', '>=', $cotaUnidade->inicio)
|
|
->where('data', '<=', $cotaUnidade->fim);
|
|
})
|
|
->count('id') ?? 0;
|
|
|
|
$cotaUtilizada = $cotaUtilizada + $agendamentoAnterior->agendamentoExame->count();
|
|
} else {
|
|
|
|
$cotaUtilizada = Agendamento::whereHas('jornada', function($query) use ($jornada) {
|
|
$query->where('prestador_id', $jornada->prestador_id);
|
|
})
|
|
->where('data', '>=', $cotaUnidade->inicio)
|
|
->where('data', '<=', $cotaUnidade->fim)
|
|
->count('id') ?? 0;
|
|
}
|
|
|
|
if (($totalUnidade - $cotaUtilizada) - 1 < 0) {
|
|
|
|
throw new ExceededCotaAgendamentoException;
|
|
}
|
|
}
|
|
}
|
|
|
|
private static function getSaldoUnidadeValor($jornada, $agendamentoAnterior)
|
|
{
|
|
|
|
$cotaUnidade = CotaPrestador::where('infraestrutura_id', $jornada->prestador->infraestrutura->id)
|
|
->where('cota_tipo_id', ExameImagemTipo::VALOR)
|
|
->where('inicio', '<=', $jornada->data)
|
|
->where('fim', '>=', $jornada->data)
|
|
->first();
|
|
|
|
if ($cotaUnidade) {
|
|
|
|
$totalUnidade = $cotaUnidade->cota_valor;
|
|
|
|
$cotaUtilizada = AgendamentoExame::whereHas('agendamento', function ($query) use ($jornada, $cotaUnidade) {
|
|
$query->whereHas('jornada', function ($query) use ($jornada) {
|
|
$query->where('prestador_id', $jornada->prestador_id);
|
|
})
|
|
->whereBetween('data', [$cotaUnidade->inicio, $cotaUnidade->fim]);
|
|
})
|
|
->whereHas('exame')
|
|
->with('exame')
|
|
->get()
|
|
->sum(fn($agendamentoExame) => $agendamentoExame->exame->valor);
|
|
|
|
$agendamentoCotaExames = 0;
|
|
|
|
foreach ($agendamentoAnterior->agendamentoExame as $agendamentoExame) {
|
|
|
|
$agendamentoCotaExames = $agendamentoCotaExames + $agendamentoExame->exame->valor;
|
|
}
|
|
|
|
if (($totalUnidade - $cotaUtilizada) - $agendamentoCotaExames < 0) {
|
|
|
|
throw new ExceededCotaAgendamentoException;
|
|
}
|
|
}
|
|
}
|
|
|
|
private static function handleJornada($jornada, $agendamentoAnterior)
|
|
{
|
|
if($jornada->controle_jornada_id == ControleJornadaTipo::EXAME){
|
|
|
|
$agendamentoCadastrado = AgendamentoExame::whereHas('agendamento', function($query) use ($jornada) {
|
|
$query->whereHas('jornada', function($query) use ($jornada) {
|
|
$query->where('id', $jornada->id);
|
|
});
|
|
})
|
|
->count('id') ?? 0;
|
|
|
|
$agendamentoCadastrado = $agendamentoCadastrado + $agendamentoAnterior->agendamentoExame->count();
|
|
} else {
|
|
|
|
$agendamentoCadastrado = Agendamento::whereHas('jornada', function($query) use ($jornada) {
|
|
$query->where('id', $jornada->id);
|
|
})
|
|
->count('id') ?? 0;
|
|
|
|
$agendamentoCadastrado = $agendamentoCadastrado + 1;
|
|
}
|
|
|
|
if ($agendamentoCadastrado > $jornada->vagas) {
|
|
|
|
throw new ExceededJornadaException;
|
|
}
|
|
}
|
|
|
|
private static function getNextHorario($jornada)
|
|
{
|
|
$nextHorario = (object) [
|
|
'horario' => null,
|
|
'is_excedente' => false,
|
|
];
|
|
|
|
if ($jornada->tipo_id === JornadaTipo::FIXA) {
|
|
|
|
$nextHorario->horario = Carbon::parse($jornada->hora_inicial)->format('H:i');
|
|
}
|
|
else if ($jornada->tipo_id === JornadaTipo::DINAMICA) {
|
|
|
|
$horarios = collect();
|
|
|
|
$agendamentos = self::getAgendamentos($jornada->id);
|
|
|
|
$agendamentos->each(fn ($a) => $a->hora_exame = $jornada->data->copy()->setTimeFromTimeString($a->hora_exame));
|
|
|
|
$agendamentos
|
|
->each(fn ($agendamento) => $horarios->push((object) [
|
|
'horario' => $agendamento->hora_exame->format('H:i'),
|
|
'quantidade_agendada' => $agendamento->quantidade_agendada,
|
|
'quantidade_total' => 1,
|
|
]));
|
|
|
|
$quantidade = $agendamentos->count();
|
|
|
|
if ($quantidade < $jornada->vagas) {
|
|
|
|
$data = $jornada->data->copy();
|
|
|
|
self::setHorarioJornadaDinamica(
|
|
$horarios,
|
|
$agendamentos,
|
|
$jornada,
|
|
$quantidade,
|
|
$data
|
|
);
|
|
}
|
|
|
|
$horarios = $horarios->sortBy('horario')->values();
|
|
$horario = $horarios->where('quantidade_agendada', 0)->first();
|
|
|
|
if (is_null($horario)) {
|
|
|
|
$horario = $horarios->last();
|
|
}
|
|
|
|
$nextHorario->horario = $horario->horario;
|
|
}
|
|
|
|
return $nextHorario;
|
|
}
|
|
|
|
private static function getStatusLiberamHorario()
|
|
{
|
|
return [
|
|
Status::REAGENDADO,
|
|
Status::CANCELADO,
|
|
];
|
|
}
|
|
|
|
private static function setHorarioJornadaDinamica($horarios, $agendamentos, $jornada, $quantidade, $data)
|
|
{
|
|
$agendamento = $agendamentos->where('horario', $data)->first();
|
|
|
|
if (is_null($agendamento)) {
|
|
|
|
$final = $data->copy()->addMinutes($jornada->tempo_atendimento);
|
|
|
|
$agendamento = $agendamentos
|
|
->where('horario', '>', $data)
|
|
->where('horario', '<', $final)
|
|
->first();
|
|
|
|
if ($agendamento) {
|
|
|
|
self::setHorarioJornadaDinamica(
|
|
$horarios,
|
|
$agendamentos,
|
|
$jornada,
|
|
$quantidade,
|
|
$agendamento->horario
|
|
);
|
|
}
|
|
else {
|
|
|
|
$horarios->push((object) [
|
|
'horario' => $data->format('H:i'),
|
|
'quantidade_agendada' => 0,
|
|
'quantidade_total' => 1,
|
|
]);
|
|
|
|
if (++$quantidade < $jornada->vagas) {
|
|
|
|
$data->addMinutes($jornada->tempo_atendimento);
|
|
|
|
self::setHorarioJornadaDinamica($horarios, $agendamentos, $jornada, $quantidade, $data);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
|
|
$data->addMinutes($jornada->tempo_atendimento);
|
|
|
|
self::setHorarioJornadaDinamica($horarios, $agendamentos, $jornada, $quantidade, $data);
|
|
}
|
|
}
|
|
|
|
public static function cancel()
|
|
{
|
|
|
|
DB::transaction(function () {
|
|
|
|
collect(request()->agendamentos)->each(function ($id) {
|
|
|
|
$agendamento = Agendamento::findOrFail($id);
|
|
$agendamento->agendamentoExame()->update(['status_id' => Status::CANCELADO]);
|
|
});
|
|
});
|
|
}
|
|
|
|
private static function validateReschedule()
|
|
{
|
|
request()->validate([
|
|
'agendamentos' => [
|
|
'required',
|
|
'array',
|
|
],
|
|
'agendamentos.*.id' => [
|
|
'required',
|
|
'integer',
|
|
Rule::exists(Agendamento::class, 'id'),
|
|
],
|
|
'jornada_id' => [
|
|
'required',
|
|
'integer',
|
|
Rule::exists(Jornada::class, 'id'),
|
|
],
|
|
'motivo_agendamento_excedente' => [
|
|
'nullable',
|
|
'string',
|
|
'max:500',
|
|
]
|
|
]);
|
|
}
|
|
|
|
private static function getAgendamentos($jornadaId)
|
|
{
|
|
return Agendamento::where('jornada_id', $jornadaId)
|
|
->whereHas('agendamentoExame', function ($query) {
|
|
$query->whereNotIn('status_id', self::getStatusLiberamHorario());
|
|
})
|
|
->groupBy('hora_exame')
|
|
->orderBy('hora_exame')
|
|
->select('hora_exame', DB::raw('COUNT(id) as quantidade_agendada'))
|
|
->get();
|
|
}
|
|
|
|
private static function getModelData()
|
|
{
|
|
return [
|
|
'origem' => [
|
|
'unidade_id' => null,
|
|
'infraestrutura_id' => null,
|
|
'ocupacao_id' => null,
|
|
'especialidade_id' => null,
|
|
'data' => null,
|
|
'grupo_id' => null,
|
|
'prestador_id' => null,
|
|
],
|
|
'destino' => [
|
|
'unidade_id' => null,
|
|
'infraestrutura_id' => null,
|
|
'prestador_id' => null,
|
|
'grupo_id' => null,
|
|
'usuario_id' => null,
|
|
'agendamentos' => [],
|
|
'jornada_id' => null,
|
|
'motivo_agendamento_excedente' => null,
|
|
],
|
|
'cancelamento' => [
|
|
'agendamentos' => [],
|
|
'motivo' => null,
|
|
]
|
|
];
|
|
}
|
|
}
|