1512 lines
61 KiB
PHP
1512 lines
61 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Ambulatorio;
|
|
|
|
use App\Enums\Administracao\Modulo;
|
|
use App\Enums\Ambulatorio\AgendamentoStatus;
|
|
use App\Exceptions\Ambulatorio\FimExcedeuDataJornadaException;
|
|
use App\Exceptions\Ambulatorio\JornadaConflitanteException;
|
|
use App\Exceptions\Ambulatorio\PossuiAgendamentoException;
|
|
use App\Models\Ambulatorio\Jornada;
|
|
use App\Models\Ambulatorio\JornadaSituacao;
|
|
use App\Models\Ambulatorio\JornadaTipo;
|
|
use App\Models\Cadastro\Especialidade;
|
|
use App\Models\Cadastro\Estabelecimento\Infraestrutura;
|
|
use App\Models\Cadastro\Estabelecimento\Unidade;
|
|
use App\Models\Cadastro\Feriado\Feriado;
|
|
use App\Models\Cadastro\SujeitoAtencao\Lotacao;
|
|
use App\Models\Cadastro\SujeitoAtencao\Usuario;
|
|
use App\Models\Geral\DiaSemana;
|
|
use App\Rules\Cns;
|
|
use App\Services\Service;
|
|
use App\Utils\DataUtil;
|
|
use App\Utils\MaskUtil;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Validation\Rule;
|
|
|
|
class JornadaService extends Service
|
|
{
|
|
public static function datatable()
|
|
{
|
|
$usuarios = DB::table('cadastro_usuario')
|
|
->join(
|
|
'cadastro_cidadao',
|
|
'cadastro_cidadao.id',
|
|
'cadastro_usuario.cidadao_id'
|
|
)
|
|
->whereNull('cadastro_usuario.deleted_at')
|
|
->select(DB::raw("
|
|
cadastro_usuario.id,
|
|
cadastro_cidadao.nome,
|
|
DATE_FORMAT(cadastro_cidadao.data_nascimento, '%d/%m/%Y') as data_nascimento,
|
|
CONCAT(
|
|
SUBSTR(cadastro_cidadao.cpf,1,3),
|
|
'.',
|
|
SUBSTR(cadastro_cidadao.cpf,4,3),
|
|
'.',
|
|
SUBSTR(cadastro_cidadao.cpf,7,3),
|
|
'-',
|
|
SUBSTR(cadastro_cidadao.cpf,10,2)
|
|
) AS cpf,
|
|
cadastro_cidadao.cns
|
|
"));
|
|
|
|
return datatables()
|
|
->of($usuarios)
|
|
->filterColumn('cadastro_cidadao.data_nascimento', function ($query, $keyword) {
|
|
|
|
$query->whereRaw("DATE_FORMAT(cadastro_cidadao.data_nascimento, '%d/%m/%Y') LIKE ?", ["%{$keyword}%"])
|
|
->orWhereRaw(
|
|
"CONCAT(
|
|
SUBSTR(cadastro_cidadao.data_nascimento,9,2),
|
|
SUBSTR(cadastro_cidadao.data_nascimento,6,2),
|
|
SUBSTR(cadastro_cidadao.data_nascimento,1,4)
|
|
) like ?",
|
|
["%{$keyword}%"]
|
|
);
|
|
})
|
|
->filterColumn('cadastro_cidadao.cpf', function ($query, $keyword) {
|
|
|
|
$query->whereRaw("cadastro_cidadao.cpf LIKE ?", ["%{$keyword}%"])
|
|
->orWhereRaw(
|
|
"CONCAT(
|
|
SUBSTR(cadastro_cidadao.cpf,1,3),
|
|
'.',
|
|
SUBSTR(cadastro_cidadao.cpf,4,3),
|
|
'.',
|
|
SUBSTR(cadastro_cidadao.cpf,7,3),
|
|
'-',
|
|
SUBSTR(cadastro_cidadao.cpf,10,2)
|
|
) LIKE ?",
|
|
["%{$keyword}%"]
|
|
);
|
|
})
|
|
->addColumn('cns_valido', fn ($usuario) => Cns::isValid($usuario->cns))
|
|
->skipTotalRecords()
|
|
->toJson();
|
|
}
|
|
|
|
public static function index()
|
|
{
|
|
$statusAgendado = AgendamentoStatus::AGENDADO;
|
|
|
|
$jornadas = DB::table('ambulatorio_jornada as jornada')
|
|
->join(
|
|
'ambulatorio_jornada_tipo as tipo',
|
|
'tipo.id',
|
|
'jornada.tipo_id'
|
|
)
|
|
->join(
|
|
'cadastro_lotacao as lotacao',
|
|
'lotacao.id',
|
|
'jornada.lotacao_id'
|
|
)
|
|
->join(
|
|
'sigtap.ocupacao as ocupacao',
|
|
'ocupacao.id',
|
|
'lotacao.ocupacao_id'
|
|
)
|
|
->join(
|
|
'cadastro_especialidade as especialidade',
|
|
'especialidade.id',
|
|
'jornada.especialidade_id'
|
|
)
|
|
->join(
|
|
'cadastro_infraestrutura as infraestrutura',
|
|
'infraestrutura.id',
|
|
'lotacao.infraestrutura_id'
|
|
)
|
|
->join(
|
|
'cadastro_unidade as unidade',
|
|
'unidade.id',
|
|
'infraestrutura.unidade_id'
|
|
)
|
|
->join(
|
|
'geral_dia_semana as dia_semana',
|
|
'dia_semana.id',
|
|
DB::raw("DAYOFWEEK(jornada.data)")
|
|
)
|
|
->leftJoin(
|
|
'ambulatorio_jornada_situacao as situacao',
|
|
'situacao.id',
|
|
'jornada.situacao_id'
|
|
)
|
|
->leftJoin(
|
|
'ambulatorio_agendamento as agendamento',
|
|
'agendamento.jornada_id',
|
|
'jornada.id'
|
|
)
|
|
->where('lotacao.usuario_id', request()->usuario_id)
|
|
->whereBetween('jornada.data', [
|
|
Carbon::createFromFormat('d/m/Y', request()->periodo['start'])->format('Y-m-d'),
|
|
Carbon::createFromFormat('d/m/Y', request()->periodo['end'])->format('Y-m-d')
|
|
])
|
|
->when(!is_null(request()->inicio) && !is_null(request()->fim), fn ($q) => $q
|
|
->where(fn ($q) => $q
|
|
->where(fn ($q) => $q
|
|
->where('jornada.inicio', '<=', request()->inicio)
|
|
->where('jornada.fim', '>=', request()->inicio)
|
|
)
|
|
->orWhere(fn ($q) => $q
|
|
->where('jornada.inicio', '<=', request()->fim)
|
|
->where('jornada.fim', '>=', request()->fim)
|
|
)
|
|
->orWhere(fn ($q) => $q
|
|
->where('jornada.inicio', '>=', request()->inicio)
|
|
->where('jornada.inicio', '<=', request()->fim)
|
|
)
|
|
->orWhere(fn ($q) => $q
|
|
->where('jornada.fim', '>=', request()->inicio)
|
|
->where('jornada.fim', '<=', request()->fim)
|
|
)
|
|
)
|
|
)
|
|
->when(!empty(request()->dias_semana), fn ($q) => $q
|
|
->whereRaw("DAYOFWEEK(jornada.data) IN (" . collect(request()->dias_semana)->join(',') . ")")
|
|
)
|
|
->when(request()->unidade_id, fn ($q, $id) => $q->where('unidade.id', $id))
|
|
->when(request()->infraestrutura_id, fn ($q, $id) => $q->where('infraestrutura.id', $id))
|
|
->when(request()->ocupacao_id, fn ($q, $id) => $q->where('ocupacao.id', $id))
|
|
->when(request()->especialidade_id, fn ($q, $id) => $q->where('especialidade.id', $id))
|
|
->when(request()->tipo_id, fn ($q, $id) => $q->where('tipo.id', $id))
|
|
->when(DataUtil::isStringBoolean(request()->ativa), fn ($q) => $q
|
|
->when(DataUtil::isStringTrue(request()->ativa),
|
|
fn ($q) => $q->whereNull('jornada.situacao_id'),
|
|
fn ($q) => $q->whereNotNull('jornada.situacao_id')
|
|
->when(request()->situacao_id, fn ($q, $id) => $q->where('situacao.id', $id))
|
|
)
|
|
)
|
|
->when(request()->quantidade_consulta, fn ($q, $quantidade) => $q
|
|
->where('jornada.quantidade_consulta', $quantidade))
|
|
->when(request()->quantidade_retorno, fn ($q, $quantidade) => $q
|
|
->where('jornada.quantidade_retorno', $quantidade))
|
|
->when(request()->conectasus_cidadao === 'sim', fn ($q) => $q
|
|
->where(fn ($q) => $q
|
|
->where('especialidade.permite_integracao_conectasus_cidadao', 1)
|
|
))
|
|
->when(request()->conectasus_cidadao === 'nao', fn ($q) => $q
|
|
->where(fn ($q) => $q
|
|
->where(fn ($q) => $q
|
|
->where('especialidade.permite_integracao_conectasus_cidadao', 0)
|
|
)
|
|
))
|
|
->select(DB::raw("
|
|
jornada.id,
|
|
unidade.nome_fantasia as unidade_nome_fantasia,
|
|
COALESCE(infraestrutura.nome, unidade.nome_fantasia) as infraestrutura_nome,
|
|
jornada.lotacao_id,
|
|
CONCAT(ocupacao.codigo, ' - ', ocupacao.nome) as ocupacao_descricao,
|
|
especialidade.id as especialidade_id,
|
|
especialidade.nome as especialidade_nome,
|
|
jornada.tipo_id,
|
|
tipo.nome as tipo_nome,
|
|
jornada.data,
|
|
dia_semana.descricao as dia_semana,
|
|
DATE_FORMAT(jornada.inicio, '%H:%i') as inicio,
|
|
DATE_FORMAT(jornada.fim, '%H:%i') as fim,
|
|
jornada.situacao_id,
|
|
situacao.nome as situacao_nome,
|
|
COALESCE(jornada.quantidade_consulta, 0) as quantidade_consulta,
|
|
COALESCE(jornada.tempo_consulta, 0) as tempo_consulta,
|
|
COALESCE(jornada.quantidade_retorno, 0) as quantidade_retorno,
|
|
COALESCE(jornada.tempo_retorno, 0) as tempo_retorno,
|
|
COALESCE(jornada.quantidade_consulta_conectasus_cidadao, 0) as quantidade_consulta_conectasus_cidadao,
|
|
COALESCE(jornada.tempo_consulta_conectasus_cidadao, 0) as tempo_consulta_conectasus_cidadao,
|
|
COALESCE(jornada.quantidade_retorno_conectasus_cidadao, 0) as quantidade_retorno_conectasus_cidadao,
|
|
COALESCE(jornada.tempo_retorno_conectasus_cidadao, 0) as tempo_retorno_conectasus_cidadao,
|
|
jornada.permite_agendamento_somente_supervisor,
|
|
COUNT(CASE WHEN agendamento.status_id = $statusAgendado THEN agendamento.id END) as total_agendamentos
|
|
"))
|
|
->addSelect([
|
|
'tem_agendamentos' => function ($query) use($statusAgendado) {
|
|
|
|
$query->select(DB::raw(1))
|
|
->from('ambulatorio_agendamento as agendamento')
|
|
->whereColumn('agendamento.jornada_id', 'jornada.id')
|
|
->limit(1);
|
|
}
|
|
])
|
|
->groupBy('jornada.id')
|
|
->get();
|
|
|
|
$jornadas->each(function ($jornada) {
|
|
|
|
$jornada->tem_agendamentos = !is_null($jornada->tem_agendamentos);
|
|
});
|
|
|
|
return $jornadas;
|
|
}
|
|
|
|
public static function create()
|
|
{
|
|
switch (request()->origem) {
|
|
|
|
case 'busca': {
|
|
|
|
$usuario = Usuario::findOrFail(request()->usuario_id);
|
|
|
|
return [
|
|
'form' => [
|
|
'usuario' => [
|
|
'nome' => $usuario->cidadao->nome,
|
|
'data_nascimento' => is_null($usuario->cidadao->data_nascimento)
|
|
? null : (new Carbon($usuario->cidadao->data_nascimento))->format('d/m/Y'),
|
|
'cns' => MaskUtil::getCnsMasked($usuario->cidadao->cns),
|
|
'cpf' => MaskUtil::getCpfMasked($usuario->cidadao->cpf),
|
|
],
|
|
'busca' => [
|
|
'dias_semana' => self::getDiasSemana(),
|
|
'unidades' => [],
|
|
'infraestruturas' => [],
|
|
'ocupacoes' => [],
|
|
'especialidades' => [],
|
|
'tipos' => [],
|
|
'situacoes' => [],
|
|
],
|
|
'atribuicao' => [
|
|
'unidades' => self::getCadastroUnidades(['usuario_id' => request()->usuario_id]),
|
|
'infraestruturas' => [],
|
|
'lotacoes' => [],
|
|
'especialidades' => [],
|
|
'tipos' => self::getCadastroJornadaTipos(),
|
|
'situacoes' => self::getCadastroJornadaSituacoes(),
|
|
],
|
|
],
|
|
'model' => [
|
|
'busca' => [
|
|
'periodo' => [
|
|
'start' => null,
|
|
'end' => null,
|
|
],
|
|
'inicio' => null,
|
|
'fim' => null,
|
|
'dias_semana' => [],
|
|
'unidade_id' => null,
|
|
'infraestrutura_id' => null,
|
|
'ocupacao_id' => null,
|
|
'especialidade_id' => null,
|
|
'tipo_id' => null,
|
|
'ativa' => null,
|
|
'situacao_id' => null,
|
|
'quantidade_consulta' => null,
|
|
'quantidade_retorno' => null,
|
|
'conectasus_cidadao' => null,
|
|
],
|
|
'atribuicao' => [
|
|
'unidade_id' => null,
|
|
'infraestrutura_id' => null,
|
|
'lotacao_id' => null,
|
|
'especialidade_id' => null,
|
|
'tipo_id' => null,
|
|
'inicio' => null,
|
|
'fim' => null,
|
|
'situacao_id' => null,
|
|
'quantidade_consulta' => null,
|
|
'tempo_consulta' => null,
|
|
'quantidade_retorno' => null,
|
|
'tempo_retorno' => null,
|
|
'quantidade_consulta_conectasus_cidadao' => 0,
|
|
'tempo_consulta_conectasus_cidadao' => null,
|
|
'quantidade_retorno_conectasus_cidadao' => 0,
|
|
'tempo_retorno_conectasus_cidadao' => null,
|
|
'permite_agendamento_somente_supervisor' => null,
|
|
],
|
|
],
|
|
];
|
|
}
|
|
case 'cadastro': {
|
|
|
|
return [
|
|
'additionals' => [
|
|
'tem_agendamentos' => false,
|
|
],
|
|
'form' => [
|
|
'unidades' => self::getCadastroUnidades(['usuario_id' => request()->usuario_id]),
|
|
'infraestruturas' => [],
|
|
'lotacoes' => [],
|
|
'especialidades' => [],
|
|
'tipos' => self::getCadastroJornadaTipos(),
|
|
'dias_semana' => self::getDiasSemana(),
|
|
'situacoes' => self::getCadastroJornadaSituacoes(),
|
|
'equipes' => self::getAtencaoBasicaEquipes(['usuario_id' => request()->usuario_id]),
|
|
],
|
|
'model' => [
|
|
'unidade_id' => null,
|
|
'infraestrutura_id' => null,
|
|
'lotacao_id' => null,
|
|
'especialidade_id' => null,
|
|
'tipo_id' => null,
|
|
'periodo' => [
|
|
'start' => null,
|
|
'end' => null,
|
|
],
|
|
'inicio' => null,
|
|
'fim' => null,
|
|
'dias_semana' => [],
|
|
'situacao_id' => null,
|
|
'quantidade_consulta' => null,
|
|
'tempo_consulta' => null,
|
|
'quantidade_retorno' => null,
|
|
'tempo_retorno' => null,
|
|
'quantidade_consulta_conectasus_cidadao' => 0,
|
|
'tempo_consulta_conectasus_cidadao' => null,
|
|
'quantidade_retorno_conectasus_cidadao' => 0,
|
|
'tempo_retorno_conectasus_cidadao' => null,
|
|
'permite_agendamento_somente_supervisor' => false,
|
|
],
|
|
];
|
|
}
|
|
}
|
|
}
|
|
|
|
public static function edit($id)
|
|
{
|
|
$jornada = Jornada::findOrFail($id);
|
|
|
|
return [
|
|
'additionals' => [
|
|
'tem_agendamentos' => $jornada->agendamentos()->whereIn('ambulatorio_agendamento.status_id', [1, 6, 7, 8])->exists(),
|
|
'quantidade_agendamentos' => $jornada->agendamentos()->whereIn('ambulatorio_agendamento.status_id', [1, 6, 7, 8])->count(),
|
|
],
|
|
'form' => [
|
|
'unidades' => self::getCadastroUnidades(['usuario_id' => $jornada->lotacao->usuario_id]),
|
|
'infraestruturas' => self::getCadastroInfraestruturas([
|
|
'usuario_id' => $jornada->lotacao->usuario_id,
|
|
'unidade_id' => $jornada->lotacao->infraestrutura->unidade_id,
|
|
]),
|
|
'lotacoes' => self::getCadastroLotacoes([
|
|
'usuario_id' => $jornada->lotacao->usuario_id,
|
|
'infraestrutura_id' => $jornada->lotacao->infraestrutura_id,
|
|
]),
|
|
'especialidades' => self::getCadastroEspecialidades([
|
|
'lotacao_id' => $jornada->lotacao_id,
|
|
]),
|
|
'tipos' => self::getCadastroJornadaTipos(),
|
|
'dias_semana' => self::getDiasSemana(),
|
|
'situacoes' => self::getCadastroJornadaSituacoes(),
|
|
'equipes' => self::getAtencaoBasicaEquipes(['usuario_id' => $jornada->lotacao->usuario_id]),
|
|
],
|
|
'model' => [
|
|
'unidade_id' => $jornada->lotacao->infraestrutura->unidade_id,
|
|
'infraestrutura_id' => $jornada->lotacao->infraestrutura_id,
|
|
'lotacao_id' => $jornada->lotacao_id,
|
|
'especialidade_id' => $jornada->especialidade_id,
|
|
'tipo_id' => $jornada->tipo_id,
|
|
'periodo' => [
|
|
'start' => $jornada->data->format('d/m/Y'),
|
|
'end' => $jornada->data->format('d/m/Y'),
|
|
],
|
|
'inicio' => $jornada->inicio->format('H:i'),
|
|
'fim' => $jornada->fim->format('H:i'),
|
|
'dia_semana' => $jornada->dia_semana,
|
|
'situacao_id' => $jornada->situacao_id,
|
|
'quantidade_consulta' => $jornada->quantidade_consulta,
|
|
'tempo_consulta' => $jornada->tempo_consulta,
|
|
'quantidade_retorno' => $jornada->quantidade_retorno,
|
|
'tempo_retorno' => $jornada->tempo_retorno,
|
|
'quantidade_consulta_conectasus_cidadao' => $jornada->quantidade_consulta_conectasus_cidadao ?? 0,
|
|
'tempo_consulta_conectasus_cidadao' => $jornada->tempo_consulta_conectasus_cidadao,
|
|
'quantidade_retorno_conectasus_cidadao' => $jornada->quantidade_retorno_conectasus_cidadao ?? 0,
|
|
'tempo_retorno_conectasus_cidadao' => $jornada->tempo_retorno_conectasus_cidadao,
|
|
'permite_agendamento_somente_supervisor' => $jornada->permite_agendamento_somente_supervisor,
|
|
],
|
|
];
|
|
}
|
|
|
|
public static function list()
|
|
{
|
|
$params = request()->all();
|
|
|
|
switch (request()->origem) {
|
|
|
|
case 'busca': {
|
|
|
|
switch (request()->listar) {
|
|
|
|
case 'unidades': {
|
|
|
|
return [
|
|
'unidades' => self::getBuscaUnidades($params),
|
|
'infraestruturas' => [],
|
|
'ocupacoes' => self::getBuscaOcupacoes($params),
|
|
'especialidades' => [],
|
|
'tipos' => self::getBuscaJornadaTipos($params),
|
|
'situacoes' => self::getBuscaJornadaSituacoes($params),
|
|
];
|
|
}
|
|
case 'infraestruturas': {
|
|
|
|
return [
|
|
'infraestruturas' => self::getBuscaInfraestruturas($params),
|
|
'ocupacoes' => self::getBuscaOcupacoes($params),
|
|
'especialidades' => [],
|
|
'tipos' => self::getBuscaJornadaTipos($params),
|
|
'situacoes' => self::getBuscaJornadaSituacoes($params),
|
|
];
|
|
}
|
|
case 'ocupacoes': {
|
|
|
|
return [
|
|
'ocupacoes' => self::getBuscaOcupacoes($params),
|
|
'especialidades' => [],
|
|
'tipos' => self::getBuscaJornadaTipos($params),
|
|
'situacoes' => self::getBuscaJornadaSituacoes($params),
|
|
];
|
|
}
|
|
case 'especialidades': {
|
|
|
|
return [
|
|
'especialidades' => self::getBuscaEspecialidades($params),
|
|
'tipos' => self::getBuscaJornadaTipos($params),
|
|
'situacoes' => self::getBuscaJornadaSituacoes($params),
|
|
];
|
|
}
|
|
case 'tipos': {
|
|
|
|
return [
|
|
'tipos' => self::getBuscaJornadaTipos($params),
|
|
'situacoes' => self::getBuscaJornadaSituacoes($params),
|
|
];
|
|
}
|
|
case 'situacoes': {
|
|
|
|
return [
|
|
'situacoes' => self::getBuscaJornadaSituacoes($params),
|
|
];
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
case 'cadastro': {
|
|
|
|
switch (request()->listar) {
|
|
|
|
case 'infraestruturas': {
|
|
|
|
return self::getCadastroInfraestruturas($params);
|
|
}
|
|
case 'lotacoes': {
|
|
|
|
return self::getCadastroLotacoes($params);
|
|
}
|
|
case 'especialidades': {
|
|
|
|
return self::getCadastroEspecialidades($params);
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
private static function getAtencaoBasicaEquipes($params)
|
|
{
|
|
return DB::table('atencao_basica_parametrizacao_equipe_usuario as equipe_usuario')
|
|
->where('equipe_usuario.usuario_id', $params['usuario_id'])
|
|
->where('equipe_usuario.ativo', true)
|
|
->join('atencao_basica_parametrizacao_equipe as parametrizacao_equipe', 'parametrizacao_equipe.id', 'equipe_usuario.equipe_id')
|
|
->join('atencao_basica_parametrizacao_area as parametrizacao_area', 'parametrizacao_area.id', 'parametrizacao_equipe.area_id')
|
|
->leftJoin('atencao_basica_parametrizacao_area_tipo as parametrizacao_area_tipo', 'parametrizacao_area_tipo.id', 'parametrizacao_area.tipo_id')
|
|
->leftJoin('atencao_basica_parametrizacao_microarea as parametrizacao_microarea', 'parametrizacao_microarea.id', 'parametrizacao_equipe.microarea_id')
|
|
->join('cadastro_unidade as unidade', 'unidade.id', 'parametrizacao_equipe.unidade_id')
|
|
->join('cadastro_infraestrutura as infraestrutura', 'infraestrutura.id', 'parametrizacao_equipe.infraestrutura_id')
|
|
->get([
|
|
'equipe_usuario.equipe_id',
|
|
'parametrizacao_area.numero_ine as area_numero_ine',
|
|
'parametrizacao_area.descricao as area_descricao',
|
|
'parametrizacao_area_tipo.sigla as area_tipo_sigla',
|
|
'parametrizacao_area_tipo.descricao as area_tipo_descricao',
|
|
'parametrizacao_microarea.descricao as microarea_descricao',
|
|
'unidade.nome_fantasia as unidade_nome',
|
|
'infraestrutura.nome as infraestrutura_nome',
|
|
'parametrizacao_equipe.microarea_id as microarea_id',
|
|
])
|
|
->map(fn ($equipe) => [
|
|
'id' => $equipe->equipe_id,
|
|
'ine' => $equipe->area_numero_ine,
|
|
'tipo' => $equipe->area_tipo_sigla . ' - ' . $equipe->area_tipo_descricao,
|
|
'area' => $equipe->area_descricao,
|
|
'microarea' => $equipe->microarea_id ? $equipe->microarea_descricao : 'Não informada',
|
|
'unidade' => $equipe->unidade_nome,
|
|
'infraestrutura' => $equipe->infraestrutura_nome ?? $equipe->unidade_nome,
|
|
]);
|
|
}
|
|
|
|
private static function getBuscaUnidades($params)
|
|
{
|
|
return Unidade::whereHas('infraestruturas', fn ($q) => $q
|
|
->whereHas('lotacoes', fn ($q) => $q
|
|
->where('usuario_id', $params['usuario_id'])
|
|
->whereHas('ambulatorioJornadas', fn ($q) =>
|
|
self::setBuscaWhereJornadas($q, $params)
|
|
)
|
|
)
|
|
)
|
|
->orderBy('nome_fantasia')
|
|
->get(['id', 'nome_fantasia']);
|
|
}
|
|
|
|
private static function getBuscaInfraestruturas($params)
|
|
{
|
|
if (is_null($params['unidade_id'])) {
|
|
|
|
return [];
|
|
}
|
|
|
|
return Infraestrutura::setEagerLoads([])
|
|
->where('unidade_id', $params['unidade_id'])
|
|
->whereHas('lotacoes', fn ($q) => $q
|
|
->where('usuario_id', $params['usuario_id'])
|
|
->whereHas('ambulatorioJornadas', fn ($q) =>
|
|
self::setBuscaWhereJornadas($q, $params)
|
|
)
|
|
)
|
|
->get(['id', 'nome', 'principal', 'unidade_id'])
|
|
->map(fn ($infraestrutura) => [
|
|
'id' => $infraestrutura->id,
|
|
'nome' => $infraestrutura->nome,
|
|
])
|
|
->sortBy('nome')
|
|
->values();
|
|
}
|
|
|
|
private static function getBuscaOcupacoes($params)
|
|
{
|
|
return DB::table('sigtap.ocupacao as ocupacao')
|
|
->whereExists(function ($query) use ($params) {
|
|
|
|
$query->select(DB::raw(1))
|
|
->from('cadastro_lotacao as lotacao')
|
|
->join('cadastro_infraestrutura as infraestrutura', 'infraestrutura.id', 'lotacao.infraestrutura_id')
|
|
->whereColumn('lotacao.ocupacao_id', 'ocupacao.id')
|
|
->where('lotacao.usuario_id', $params['usuario_id'])
|
|
->when($params['infraestrutura_id'], fn ($q, $id) => $q->where('lotacao.infraestrutura_id', $id))
|
|
->when($params['unidade_id'], fn ($q, $id) => $q->where('infraestrutura.unidade_id', $id))
|
|
->whereExists(function ($query) use ($params) {
|
|
|
|
$query->select(DB::raw(1))
|
|
->from('ambulatorio_jornada as jornada')
|
|
->whereColumn('jornada.lotacao_id', 'lotacao.id')
|
|
->whereBetween('jornada.data', [
|
|
Carbon::createFromFormat('d/m/Y', $params['periodo']['start'])->format('Y-m-d'),
|
|
Carbon::createFromFormat('d/m/Y', $params['periodo']['end'])->format('Y-m-d')
|
|
])
|
|
->when(!is_null($params['inicio']) && !is_null($params['fim']), fn ($q) => $q
|
|
->where(fn ($q) => $q
|
|
->where('jornada.inicio', '<=', $params['inicio'])
|
|
->where('jornada.fim', '>=', $params['inicio'])
|
|
)
|
|
->orWhere(fn ($q) => $q
|
|
->where('jornada.inicio', '<=', $params['fim'])
|
|
->where('jornada.fim', '>=', $params['fim'])
|
|
)
|
|
->orWhere(fn ($q) => $q
|
|
->where('jornada.inicio', '>=', $params['inicio'])
|
|
->where('jornada.inicio', '<=', $params['fim'])
|
|
)
|
|
->orWhere(fn ($q) => $q
|
|
->where('jornada.fim', '>=', $params['inicio'])
|
|
->where('jornada.fim', '<=', $params['fim'])
|
|
)
|
|
)
|
|
->when(!empty($params['dias_semana']), fn ($q) => $q
|
|
->whereRaw("DAYOFWEEK(jornada.data) IN (" . collect($params['dias_semana'])->join(',') . ")")
|
|
);
|
|
});
|
|
})
|
|
->select(DB::raw("
|
|
ocupacao.id,
|
|
CONCAT(ocupacao.codigo, ' - ', ocupacao.nome) as descricao
|
|
"))
|
|
->orderByRaw("CONCAT(ocupacao.codigo, ' - ', ocupacao.nome)")
|
|
->get();
|
|
}
|
|
|
|
private static function getBuscaEspecialidades($params)
|
|
{
|
|
return Especialidade::whereHas('ambulatorioJornadas', fn ($q) =>
|
|
self::setBuscaWhereJornadas($q, $params)
|
|
->whereHas('lotacao', fn ($q) => $q
|
|
->where('usuario_id', $params['usuario_id'])
|
|
->where('ocupacao_id', $params['ocupacao_id'])
|
|
->when($params['infraestrutura_id'],
|
|
fn ($q, $id) => $q->where('infraestrutura_id', $id),
|
|
fn ($q) => $q
|
|
->when($params['unidade_id'], fn ($q, $id) => $q
|
|
->whereHas('infraestrutura', fn ($q) => $q
|
|
->where('unidade_id', $id)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
->when($params['conectasus_cidadao'] === 'sim', fn ($q) => $q
|
|
->where('permite_integracao_conectasus_cidadao', true))
|
|
->when($params['conectasus_cidadao'] === 'nao', fn ($q) => $q
|
|
->where(fn ($q) => $q
|
|
->where('permite_integracao_conectasus_cidadao', false)
|
|
->orWhereNull('permite_integracao_conectasus_cidadao')
|
|
))
|
|
->orderBy('nome')
|
|
->get(['id', 'nome', 'permite_integracao_conectasus_cidadao']);
|
|
}
|
|
|
|
private static function getBuscaJornadaTipos($params)
|
|
{
|
|
return JornadaTipo::whereHas('jornadas', fn ($q) =>
|
|
self::setBuscaWhereJornadas($q, $params)
|
|
->when($params['especialidade_id'], fn ($q, $id) => $q->where('especialidade_id', $id))
|
|
->whereHas('lotacao', fn ($q) => $q
|
|
->where('usuario_id', $params['usuario_id'])
|
|
->when($params['infraestrutura_id'],
|
|
fn ($q, $id) => $q->where('infraestrutura_id', $id),
|
|
fn ($q) => $q
|
|
->when($params['unidade_id'], fn ($q, $id) => $q
|
|
->whereHas('infraestrutura', fn ($q) => $q
|
|
->where('unidade_id', $id)
|
|
)
|
|
)
|
|
)
|
|
->when($params['ocupacao_id'], fn ($q, $id) => $q->where('ocupacao_id', $id))
|
|
)
|
|
)
|
|
->orderBy('nome')
|
|
->get(['id', 'nome']);
|
|
}
|
|
|
|
private static function getBuscaJornadaSituacoes($params)
|
|
{
|
|
return JornadaSituacao::whereHas('jornadas', fn ($q) =>
|
|
self::setBuscaWhereJornadas($q, $params)
|
|
->when($params['especialidade_id'], fn ($q, $id) => $q->where('especialidade_id', $id))
|
|
->whereHas('lotacao', fn ($q) => $q
|
|
->where('usuario_id', $params['usuario_id'])
|
|
->when($params['infraestrutura_id'],
|
|
fn ($q, $id) => $q->where('infraestrutura_id', $id),
|
|
fn ($q) => $q
|
|
->when($params['unidade_id'], fn ($q, $id) => $q
|
|
->whereHas('infraestrutura', fn ($q) => $q
|
|
->where('unidade_id', $id)
|
|
)
|
|
)
|
|
)
|
|
->when($params['ocupacao_id'], fn ($q, $id) => $q->where('ocupacao_id', $id))
|
|
->when($params['tipo_id'], fn ($q, $id) => $q->where('tipo_id', $id))
|
|
)
|
|
)
|
|
->orderBy('nome')
|
|
->get(['id', 'nome']);
|
|
}
|
|
|
|
private static function setBuscaWhereJornadas($query, $params)
|
|
{
|
|
return $query->whereBetween('data', [
|
|
Carbon::createFromFormat('d/m/Y', $params['periodo']['start'])->format('Y-m-d'),
|
|
Carbon::createFromFormat('d/m/Y', $params['periodo']['end'])->format('Y-m-d')
|
|
])
|
|
->when(!is_null($params['inicio']) && !is_null($params['fim']), fn ($q) => $q
|
|
->where(fn ($q) => $q
|
|
->where('inicio', '<=', $params['inicio'])
|
|
->where('fim', '>=', $params['inicio'])
|
|
)
|
|
->orWhere(fn ($q) => $q
|
|
->where('inicio', '<=', $params['fim'])
|
|
->where('fim', '>=', $params['fim'])
|
|
)
|
|
->orWhere(fn ($q) => $q
|
|
->where('inicio', '>=', $params['inicio'])
|
|
->where('inicio', '<=', $params['fim'])
|
|
)
|
|
->orWhere(fn ($q) => $q
|
|
->where('fim', '>=', $params['inicio'])
|
|
->where('fim', '<=', $params['fim'])
|
|
)
|
|
)
|
|
->when(!empty($params['dias_semana']), fn ($q) => $q
|
|
->whereRaw("DAYOFWEEK(ambulatorio_jornada.data) IN (" . collect($params['dias_semana'])->join(',') . ")")
|
|
);
|
|
}
|
|
|
|
private static function getCadastroUnidades($params)
|
|
{
|
|
return DB::table('cadastro_unidade as unidade')
|
|
->whereNull('unidade.deleted_at')
|
|
->whereExists(fn ($q) => $q
|
|
->select(DB::raw(1))
|
|
->from('cadastro_infraestrutura as infraestrutura')
|
|
->whereColumn('infraestrutura.unidade_id', 'unidade.id')
|
|
->where(fn ($q) => self::setCadastroWhereInfraestrutura($q, $params['usuario_id']))
|
|
)
|
|
->select(
|
|
'unidade.id',
|
|
'unidade.nome_fantasia'
|
|
)
|
|
->orderBy('unidade.nome_fantasia')
|
|
->get();
|
|
}
|
|
|
|
private static function getCadastroInfraestruturas($params)
|
|
{
|
|
return DB::table('cadastro_infraestrutura as infraestrutura')
|
|
->join(
|
|
'cadastro_unidade as unidade',
|
|
'unidade.id',
|
|
'infraestrutura.unidade_id'
|
|
)
|
|
->whereNull('infraestrutura.deleted_at')
|
|
->where('infraestrutura.unidade_id', $params['unidade_id'])
|
|
->where(fn ($q) => self::setCadastroWhereInfraestrutura($q, $params['usuario_id']))
|
|
->select(
|
|
'infraestrutura.id',
|
|
DB::raw("COALESCE(infraestrutura.nome, unidade.nome_fantasia) as nome")
|
|
)
|
|
->orderByRaw("COALESCE(infraestrutura.nome, unidade.nome_fantasia)")
|
|
->get();
|
|
}
|
|
|
|
private static function setCadastroWhereInfraestrutura($query, $usuarioId)
|
|
{
|
|
return $query->whereExists(fn ($q) => $q
|
|
->select(DB::raw(1))
|
|
->from('ambulatorio_parametrizacao_infraestrutura as parametrizacao_infraestrutura')
|
|
->whereColumn('parametrizacao_infraestrutura.infraestrutura_id', 'infraestrutura.id')
|
|
->whereExists(fn ($q) => $q
|
|
->select(DB::raw(1))
|
|
->from('ambulatorio_parametrizacao_infraestrutura_ocupacao as parametrizacao_ocupacao')
|
|
->join(
|
|
'cadastro_lotacao as lotacao',
|
|
'lotacao.ocupacao_id',
|
|
'parametrizacao_ocupacao.ocupacao_id'
|
|
)
|
|
->whereColumn(
|
|
'parametrizacao_ocupacao.parametrizacao_infraestrutura_id',
|
|
'parametrizacao_infraestrutura.id'
|
|
)
|
|
->whereColumn('lotacao.infraestrutura_id', 'infraestrutura.id')
|
|
->where('lotacao.usuario_id', $usuarioId)
|
|
->where('lotacao.realiza_atendimento', true)
|
|
->whereNull('lotacao.deleted_at')
|
|
)
|
|
->whereExists(fn ($q) => $q
|
|
->select(DB::raw(1))
|
|
->from('ambulatorio_parametrizacao_infraestrutura_especialidade as parametrizacao_especialidade')
|
|
->whereColumn(
|
|
'parametrizacao_especialidade.parametrizacao_infraestrutura_id',
|
|
'parametrizacao_infraestrutura.id'
|
|
)
|
|
)
|
|
);
|
|
}
|
|
|
|
private static function getCadastroLotacoes($params)
|
|
{
|
|
return DB::table('cadastro_lotacao as lotacao')
|
|
->join(
|
|
'sigtap.ocupacao as ocupacao',
|
|
'ocupacao.id',
|
|
'lotacao.ocupacao_id'
|
|
)
|
|
->whereNull('lotacao.deleted_at')
|
|
->where('lotacao.usuario_id', $params['usuario_id'])
|
|
->where('lotacao.infraestrutura_id', $params['infraestrutura_id'])
|
|
->where('lotacao.realiza_atendimento', true)
|
|
->whereExists(fn ($q) => $q
|
|
->select(DB::raw(1))
|
|
->from('ambulatorio_parametrizacao_infraestrutura as parametrizacao_infraestrutura')
|
|
->join(
|
|
'ambulatorio_parametrizacao_infraestrutura_ocupacao as parametrizacao_ocupacao',
|
|
'parametrizacao_ocupacao.parametrizacao_infraestrutura_id',
|
|
'parametrizacao_infraestrutura.id'
|
|
)
|
|
->join(
|
|
'ambulatorio_parametrizacao_infraestrutura_especialidade as parametrizacao_especialidade',
|
|
'parametrizacao_especialidade.parametrizacao_infraestrutura_id',
|
|
'parametrizacao_infraestrutura.id'
|
|
)
|
|
->join(
|
|
'cadastro_especialidade as especialidade',
|
|
'especialidade.id',
|
|
'parametrizacao_especialidade.especialidade_id'
|
|
)
|
|
->whereColumn('parametrizacao_infraestrutura.infraestrutura_id', 'lotacao.infraestrutura_id')
|
|
->whereColumn('parametrizacao_ocupacao.ocupacao_id', 'lotacao.ocupacao_id')
|
|
->whereColumn('especialidade.ocupacao_id', 'lotacao.ocupacao_id')
|
|
)
|
|
->select(
|
|
'lotacao.id',
|
|
DB::raw("CONCAT(ocupacao.codigo, ' - ', ocupacao.nome) as ocupacao_descricao")
|
|
)
|
|
->orderByRaw("CONCAT(ocupacao.codigo, ' - ', ocupacao.nome)")
|
|
->get();
|
|
}
|
|
|
|
private static function getCadastroEspecialidades($params)
|
|
{
|
|
$lotacao = Lotacao::where('id', $params['lotacao_id'])->first(['ocupacao_id', 'infraestrutura_id']);
|
|
|
|
return Especialidade::where('ativo', true)
|
|
->where('ocupacao_id', $lotacao->ocupacao_id)
|
|
->whereHas('ambulatorioParametrizacoesInfraestruturaEspecialidade', fn ($q) => $q
|
|
->whereHas('parametrizacaoInfraestrutura', fn ($q) => $q
|
|
->where('infraestrutura_id', $lotacao->infraestrutura_id)
|
|
)
|
|
)
|
|
->orderBy('nome')
|
|
->get(['id', 'nome', 'permite_integracao_conectasus_cidadao']);
|
|
}
|
|
|
|
private static function getCadastroJornadaTipos()
|
|
{
|
|
return JornadaTipo::orderBy('nome')->get(['id', 'nome']);
|
|
}
|
|
|
|
private static function getCadastroJornadaSituacoes()
|
|
{
|
|
return JornadaSituacao::orderBy('nome')->get(['id', 'nome']);
|
|
}
|
|
|
|
private static function getDiasSemana()
|
|
{
|
|
return DiaSemana::orderBy('id')
|
|
->get(['id', 'descricao'])
|
|
->map(fn ($diaSemana) => [
|
|
'id' => $diaSemana->id,
|
|
'descricao' => $diaSemana->descricao,
|
|
'disabled' => true,
|
|
]);
|
|
}
|
|
|
|
public static function store()
|
|
{
|
|
self::validateStore();
|
|
|
|
$jornadasCriadas = collect();
|
|
$jornadasConflitantes = collect();
|
|
$feriados = collect();
|
|
|
|
DB::transaction(function() use ($jornadasCriadas, $jornadasConflitantes, $feriados) {
|
|
|
|
$params = self::getStoreParams();
|
|
|
|
$date = Carbon::createFromFormat('d/m/Y', request()->periodo['start']);
|
|
$endDate = Carbon::createFromFormat('d/m/Y', request()->periodo['end']);
|
|
|
|
while ($date <= $endDate) {
|
|
|
|
$diaSemana = $date->dayOfWeek + 1;
|
|
|
|
if (collect(request()->dias_semana)->contains($diaSemana)) {
|
|
|
|
$params['fim'] = self::getFim(
|
|
$params['inicio'],
|
|
$params['quantidade_consulta'],
|
|
$params['tempo_consulta'],
|
|
$params['quantidade_retorno'],
|
|
$params['tempo_retorno'],
|
|
$params['quantidade_consulta_conectasus_cidadao'] ?? null,
|
|
$params['tempo_consulta_conectasus_cidadao'] ?? null,
|
|
$params['quantidade_retorno_conectasus_cidadao'] ?? null,
|
|
$params['tempo_retorno_conectasus_cidadao'] ?? null
|
|
);
|
|
|
|
$isConflitante = self::isJornadaConflitante([
|
|
'id' => null,
|
|
'data' => $date,
|
|
'inicio' => $params['inicio'],
|
|
'fim' => $params['fim'],
|
|
'lotacao_id' => $params['lotacao_id'],
|
|
]);
|
|
|
|
if ($isConflitante) {
|
|
|
|
$params['data'] = $date->format('d/m/Y');
|
|
$params['dia_semana'] = $diaSemana;
|
|
|
|
$jornadasConflitantes->push($params);
|
|
}
|
|
else if (self::isFeriado($date)) {
|
|
|
|
$feriados->push([
|
|
'data' => $date->format('d/m/Y'),
|
|
'dia_semana' => $diaSemana
|
|
]);
|
|
}
|
|
else {
|
|
|
|
$params['data'] = $date->format('Y-m-d');
|
|
|
|
$jornadasCriadas->push(Jornada::create($params));
|
|
}
|
|
}
|
|
|
|
$date->addDay();
|
|
}
|
|
});
|
|
|
|
return [
|
|
'jornadas_criadas' => $jornadasCriadas,
|
|
'jornadas_conflitantes' => $jornadasConflitantes,
|
|
'feriados' => $feriados,
|
|
];
|
|
}
|
|
|
|
private static function validateStore()
|
|
{
|
|
request()->validate([
|
|
'lotacao_id' => [
|
|
'required',
|
|
'integer',
|
|
Rule::exists(Lotacao::class, 'id'),
|
|
],
|
|
'especialidade_id' => [
|
|
'required',
|
|
'integer',
|
|
Rule::exists(Especialidade::class, 'id'),
|
|
],
|
|
'tipo_id' => [
|
|
'required',
|
|
'integer',
|
|
Rule::exists(JornadaTipo::class, 'id'),
|
|
],
|
|
'periodo.start' => [
|
|
'required',
|
|
'date_format:d/m/Y',
|
|
'before_or_equal:periodo.end'
|
|
],
|
|
'periodo.end' => [
|
|
'required',
|
|
'date_format:d/m/Y',
|
|
'after_or_equal:periodo.start'
|
|
],
|
|
'inicio' => [
|
|
'required',
|
|
'date_format:H:i',
|
|
],
|
|
'dias_semana' => [
|
|
'required',
|
|
'array'
|
|
],
|
|
'dias_semana.*' => [
|
|
'integer',
|
|
Rule::exists(DiaSemana::class, 'id'),
|
|
],
|
|
'situacao_id' => [
|
|
'nullable',
|
|
'integer',
|
|
Rule::exists(JornadaSituacao::class, 'id'),
|
|
],
|
|
'quantidade_consulta' => [
|
|
Rule::requiredIf(fn () => is_null(request()->quantidade_retorno)),
|
|
'nullable',
|
|
'integer',
|
|
'max:999'
|
|
],
|
|
'tempo_consulta' => [
|
|
Rule::requiredIf(fn () => !is_null(request()->quantidade_consulta)),
|
|
'nullable',
|
|
'integer',
|
|
'max:999'
|
|
],
|
|
'quantidade_retorno' => [
|
|
Rule::requiredIf(fn () => is_null(request()->quantidade_consulta)),
|
|
'nullable',
|
|
'integer',
|
|
'max:999'
|
|
],
|
|
'tempo_retorno' => [
|
|
Rule::requiredIf(fn () => !is_null(request()->quantidade_retorno)),
|
|
'nullable',
|
|
'integer',
|
|
'max:999'
|
|
],
|
|
'quantidade_consulta_conectasus_cidadao' => [
|
|
'nullable',
|
|
'integer',
|
|
'min:0',
|
|
'max:999'
|
|
],
|
|
'tempo_consulta_conectasus_cidadao' => [
|
|
Rule::requiredIf(fn () => request()->quantidade_consulta_conectasus_cidadao > 0),
|
|
'nullable',
|
|
'integer',
|
|
'min:1',
|
|
'max:999'
|
|
],
|
|
'quantidade_retorno_conectasus_cidadao' => [
|
|
'nullable',
|
|
'integer',
|
|
'min:0',
|
|
'max:999'
|
|
],
|
|
'tempo_retorno_conectasus_cidadao' => [
|
|
Rule::requiredIf(fn () => request()->quantidade_retorno_conectasus_cidadao > 0),
|
|
'nullable',
|
|
'integer',
|
|
'min:1',
|
|
'max:999'
|
|
],
|
|
'permite_agendamento_somente_supervisor' => [
|
|
'required',
|
|
'boolean'
|
|
],
|
|
]);
|
|
}
|
|
|
|
private static function getStoreParams()
|
|
{
|
|
return request()->except(['periodo', 'dias_semana']);
|
|
}
|
|
|
|
private static function isFeriado($date)
|
|
{
|
|
return Feriado::where('data', $date->format('Y-m-d'))
|
|
->whereHas('modulos', function ($query) {
|
|
|
|
$query->where('identificador', Modulo::AMBULATORIO);
|
|
})
|
|
->exists();
|
|
}
|
|
|
|
public static function update($id)
|
|
{
|
|
$jornada = Jornada::findOrFail($id);
|
|
|
|
self::validateUpdate($jornada);
|
|
|
|
$params = self::getUpdateParams($jornada, request()->all());
|
|
|
|
$params['fim'] = self::getFim(
|
|
$params['inicio'],
|
|
$params['quantidade_consulta'],
|
|
$params['tempo_consulta'],
|
|
$params['quantidade_retorno'],
|
|
$params['tempo_retorno'],
|
|
$params['quantidade_consulta_conectasus_cidadao'] ?? null,
|
|
$params['tempo_consulta_conectasus_cidadao'] ?? null,
|
|
$params['quantidade_retorno_conectasus_cidadao'] ?? null,
|
|
$params['tempo_retorno_conectasus_cidadao'] ?? null
|
|
);
|
|
|
|
$isConflitante = self::isJornadaConflitante([
|
|
'id' => $jornada->id,
|
|
'data' => $jornada->data,
|
|
'inicio' => $params['inicio'],
|
|
'fim' => $params['fim'],
|
|
'lotacao_id' => $params['lotacao_id'],
|
|
]);
|
|
|
|
if ($isConflitante) {
|
|
|
|
throw new JornadaConflitanteException();
|
|
}
|
|
|
|
$jornada->update($params);
|
|
|
|
return $jornada->fresh();
|
|
}
|
|
|
|
private static function validateUpdate($jornada)
|
|
{
|
|
$hasAgendamentos = $jornada->agendamentos()->exists();
|
|
$hasAgendamentoAndConsulta = $hasAgendamentos && !is_null($jornada->quantidade_consulta);
|
|
$hasAgendamentoAndRetorno = $hasAgendamentos && !is_null($jornada->quantidade_retorno);
|
|
|
|
if ($hasAgendamentoAndConsulta) {
|
|
$count = $jornada->agendamentos()->whereIn('status_id', [1, 6, 7, 8])->count();
|
|
$quantidade_agendamentos = $count !== 0 ? $count : 1;
|
|
}
|
|
|
|
$rules = [
|
|
'lotacao_id' => [
|
|
'required',
|
|
'integer',
|
|
Rule::exists(Lotacao::class, 'id'),
|
|
],
|
|
'especialidade_id' => [
|
|
'required',
|
|
'integer',
|
|
Rule::exists(Especialidade::class, 'id'),
|
|
],
|
|
'tipo_id' => [
|
|
'required',
|
|
'integer',
|
|
Rule::exists(JornadaTipo::class, 'id'),
|
|
],
|
|
'inicio' => [
|
|
'required',
|
|
'date_format:H:i',
|
|
],
|
|
'situacao_id' => [
|
|
'nullable',
|
|
'integer',
|
|
Rule::exists(JornadaSituacao::class, 'id'),
|
|
],
|
|
'quantidade_consulta' => [
|
|
Rule::requiredIf(fn () => $hasAgendamentoAndConsulta || is_null(request()->quantidade_retorno)),
|
|
'nullable',
|
|
'integer',
|
|
'min:' . ($hasAgendamentoAndConsulta ? $quantidade_agendamentos : 1),
|
|
'max:999'
|
|
],
|
|
'tempo_consulta' => [
|
|
Rule::requiredIf(fn () => !is_null(request()->quantidade_consulta)),
|
|
'nullable',
|
|
'integer',
|
|
'max:999'
|
|
],
|
|
'quantidade_retorno' => [
|
|
Rule::requiredIf(fn () => $hasAgendamentoAndRetorno || is_null(request()->quantidade_consulta)
|
|
),
|
|
'nullable',
|
|
'integer',
|
|
'min:' . ($hasAgendamentoAndRetorno ? $jornada->quantidade_retorno : 0),
|
|
'max:999'
|
|
],
|
|
'tempo_retorno' => [
|
|
Rule::requiredIf(fn () => !is_null(request()->quantidade_retorno)),
|
|
'nullable',
|
|
'integer',
|
|
'max:999'
|
|
],
|
|
'quantidade_consulta_conectasus_cidadao' => [
|
|
'nullable',
|
|
'integer',
|
|
'min:0',
|
|
'max:999'
|
|
],
|
|
'tempo_consulta_conectasus_cidadao' => [
|
|
Rule::requiredIf(fn () => request()->quantidade_consulta_conectasus_cidadao > 0),
|
|
'nullable',
|
|
'integer',
|
|
'min:1',
|
|
'max:999'
|
|
],
|
|
'quantidade_retorno_conectasus_cidadao' => [
|
|
'nullable',
|
|
'integer',
|
|
'min:0',
|
|
'max:999'
|
|
],
|
|
'tempo_retorno_conectasus_cidadao' => [
|
|
Rule::requiredIf(fn () => request()->quantidade_retorno_conectasus_cidadao > 0),
|
|
'nullable',
|
|
'integer',
|
|
'min:1',
|
|
'max:999'
|
|
],
|
|
'permite_agendamento_somente_supervisor' => [
|
|
'required',
|
|
'boolean'
|
|
],
|
|
];
|
|
|
|
request()->validate($rules);
|
|
}
|
|
|
|
public static function updateAll()
|
|
{
|
|
self::validateUpdateAll();
|
|
|
|
$jornadasAtualizadas = collect();
|
|
$jornadasConflitantes = collect();
|
|
$jornadasComAgendamento = collect();
|
|
|
|
DB::transaction(function() use ($jornadasAtualizadas, $jornadasConflitantes, $jornadasComAgendamento) {
|
|
|
|
collect(request()->all())
|
|
->each(function ($params) use ($jornadasAtualizadas, $jornadasConflitantes, $jornadasComAgendamento) {
|
|
|
|
$jornada = Jornada::findOrFail($params['id']);
|
|
$params = self::getUpdateAllParams($jornada, $params);
|
|
|
|
if ($jornada->agendamentos()->exists()) {
|
|
|
|
$jornadasComAgendamento->push($params);
|
|
}
|
|
else {
|
|
|
|
$params['fim'] = self::getFim(
|
|
$params['inicio'],
|
|
$params['quantidade_consulta'],
|
|
$params['tempo_consulta'],
|
|
$params['quantidade_retorno'],
|
|
$params['tempo_retorno'],
|
|
$params['quantidade_consulta_conectasus_cidadao'] ?? null,
|
|
$params['tempo_consulta_conectasus_cidadao'] ?? null,
|
|
$params['quantidade_retorno_conectasus_cidadao'] ?? null,
|
|
$params['tempo_retorno_conectasus_cidadao'] ?? null
|
|
);
|
|
|
|
$isConflitante = self::isJornadaConflitante([
|
|
'id' => $jornada->id,
|
|
'data' => $jornada->data,
|
|
'inicio' => $params['inicio'],
|
|
'fim' => $params['fim'],
|
|
'lotacao_id' => $params['lotacao_id'],
|
|
]);
|
|
|
|
if ($isConflitante) {
|
|
|
|
$jornadasConflitantes->push($params);
|
|
}
|
|
else {
|
|
|
|
$jornada->update($params);
|
|
|
|
$jornadasAtualizadas->push($jornada->fresh());
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
return [
|
|
'jornadas_atualizadas' => $jornadasAtualizadas,
|
|
'jornadas_conflitantes' => $jornadasConflitantes,
|
|
'jornadas_com_agendamento' => $jornadasComAgendamento,
|
|
];
|
|
}
|
|
|
|
private static function validateUpdateAll()
|
|
{
|
|
$rules = [];
|
|
|
|
collect(request()->all())->each(function ($jornada, $i) use (&$rules) {
|
|
$rules["{$i}.id"] = [
|
|
'required',
|
|
'integer',
|
|
Rule::exists(Jornada::class, 'id'),
|
|
];
|
|
|
|
$rules["{$i}.lotacao_id"] = [
|
|
'required',
|
|
'integer',
|
|
Rule::exists(Lotacao::class, 'id'),
|
|
];
|
|
|
|
$rules["{$i}.especialidade_id"] = [
|
|
'required',
|
|
'integer',
|
|
Rule::exists(Especialidade::class, 'id'),
|
|
];
|
|
|
|
$rules["{$i}.tipo_id"] = [
|
|
'required',
|
|
'integer',
|
|
Rule::exists(JornadaTipo::class, 'id'),
|
|
];
|
|
|
|
$rules["{$i}.inicio"] = [
|
|
'required',
|
|
'date_format:H:i',
|
|
];
|
|
|
|
$rules["{$i}.situacao_id"] = [
|
|
'nullable',
|
|
'integer',
|
|
Rule::exists(JornadaSituacao::class, 'id'),
|
|
];
|
|
|
|
$rules["{$i}.quantidade_consulta"] = [
|
|
Rule::requiredIf(fn() => !array_key_exists('total_agendamentos', $jornada) || is_null($jornada['total_agendamentos'])),
|
|
'nullable',
|
|
'integer',
|
|
'max:999'
|
|
];
|
|
|
|
$rules["{$i}.tempo_consulta"] = [
|
|
Rule::requiredIf(fn () => !is_null($jornada['quantidade_consulta'])),
|
|
'nullable',
|
|
'integer',
|
|
'max:999'
|
|
];
|
|
|
|
$rules["{$i}.quantidade_retorno"] = [
|
|
Rule::requiredIf(fn () => is_null($jornada['quantidade_consulta'])),
|
|
'nullable',
|
|
'integer',
|
|
'max:999'
|
|
];
|
|
|
|
$rules["{$i}.tempo_retorno"] = [
|
|
Rule::requiredIf(fn () => !is_null($jornada['quantidade_retorno'])),
|
|
'nullable',
|
|
'integer',
|
|
'max:999'
|
|
];
|
|
|
|
$rules["{$i}.quantidade_consulta_conectasus_cidadao"] = [
|
|
'nullable',
|
|
'integer',
|
|
'min:0',
|
|
'max:999'
|
|
];
|
|
|
|
$rules["{$i}.tempo_consulta_conectasus_cidadao"] = [
|
|
Rule::requiredIf(fn () => ($jornada['quantidade_consulta_conectasus_cidadao'] ?? 0) > 0),
|
|
'nullable',
|
|
'integer',
|
|
'min:1',
|
|
'max:999'
|
|
];
|
|
|
|
$rules["{$i}.quantidade_retorno_conectasus_cidadao"] = [
|
|
'nullable',
|
|
'integer',
|
|
'min:0',
|
|
'max:999'
|
|
];
|
|
|
|
$rules["{$i}.tempo_retorno_conectasus_cidadao"] = [
|
|
Rule::requiredIf(fn () => ($jornada['quantidade_retorno_conectasus_cidadao'] ?? 0) > 0),
|
|
'nullable',
|
|
'integer',
|
|
'min:1',
|
|
'max:999'
|
|
];
|
|
|
|
$rules["{$i}.permite_agendamento_somente_supervisor"] = [
|
|
'required',
|
|
'boolean'
|
|
];
|
|
|
|
});
|
|
|
|
request()->validate($rules);
|
|
}
|
|
|
|
private static function getUpdateParams($jornada, $params)
|
|
{
|
|
if ($jornada->agendamentos()->exists()) {
|
|
|
|
$params['lotacao_id'] = $jornada->lotacao_id == $params['lotacao_id'] ? $jornada->lotacao_id : $params['lotacao_id'];
|
|
$params['especialidade_id'] = $jornada->especialidade_id == $params['especialidade_id'] ? $jornada->especialidade_id : $params['especialidade_id'];
|
|
$params['tipo_id'] = $jornada->tipo_id == $params['tipo_id'] ? $jornada->tipo_id : $params['tipo_id'];
|
|
$params['inicio'] = $jornada->inicio->format('H:i') == $params['inicio'] ? $jornada->inicio->format('H:i') : $params['inicio'];
|
|
$params['situacao_id'] = $jornada->situacao_id == $params['situacao_id'] ? $jornada->situacao_id : $params['situacao_id'];
|
|
$params['tempo_consulta'] = $jornada->tempo_consulta == $params['tempo_consulta'] ? $jornada->tempo_consulta : $params['tempo_consulta'];
|
|
$params['tempo_retorno'] = $jornada->tempo_retorno == $params['tempo_retorno'] ? $jornada->tempo_retorno : $params['tempo_retorno'];
|
|
$params['permite_agendamento_somente_supervisor'] = $jornada->permite_agendamento_somente_supervisor == $params['permite_agendamento_somente_supervisor'] ? $jornada->permite_agendamento_somente_supervisor : $params['permite_agendamento_somente_supervisor'];
|
|
|
|
return $params;
|
|
}
|
|
|
|
return $params;
|
|
}
|
|
|
|
private static function getUpdateAllParams($jornada, $params)
|
|
{
|
|
if ($jornada->agendamentos()->exists()) {
|
|
|
|
$params['lotacao_id'] = $jornada->lotacao_id;
|
|
$params['especialidade_id'] = $jornada->especialidade_id;
|
|
$params['tipo_id'] = $jornada->tipo_id;
|
|
$params['inicio'] = $jornada->inicio->format('H:i');
|
|
$params['tempo_consulta'] = $jornada->tempo_consulta;
|
|
$params['tempo_retorno'] = $jornada->tempo_retorno;
|
|
$params['permite_agendamento_somente_supervisor'] = $jornada->permite_agendamento_somente_supervisor;
|
|
|
|
return $params;
|
|
}
|
|
|
|
return $params;
|
|
}
|
|
|
|
private static function isJornadaConflitante($jornada)
|
|
{
|
|
return Jornada::when($jornada['id'], fn ($q, $id) => $q->where('id', '<>', $id))
|
|
->whereNull('situacao_id')
|
|
->where('data', $jornada['data']->format('Y-m-d'))
|
|
->whereHas('lotacao', fn ($q) => $q
|
|
->where('usuario_id', Lotacao::findOrFail($jornada['lotacao_id'])->usuario_id)
|
|
)
|
|
->where(fn ($q) => $q
|
|
->where(fn ($q) => $q
|
|
->where('inicio', '<=', $jornada['inicio'])
|
|
->where('fim', '>=', $jornada['inicio'])
|
|
)
|
|
->orWhere(fn ($q) => $q
|
|
->where('inicio', '<=', $jornada['fim'])
|
|
->where('fim', '>=', $jornada['fim'])
|
|
)
|
|
->orWhere(fn ($q) => $q
|
|
->where('inicio', '>=', $jornada['inicio'])
|
|
->where('inicio', '<=', $jornada['fim'])
|
|
)
|
|
->orWhere(fn ($q) => $q
|
|
->where('fim', '>=', $jornada['inicio'])
|
|
->where('fim', '<=', $jornada['fim'])
|
|
)
|
|
)
|
|
->exists();
|
|
}
|
|
|
|
private static function getFim($inicio, $quantidadeConsulta, $tempoConsulta, $quantidadeRetorno, $tempoRetorno, $quantidadeConsultaCidadao = null, $tempoConsultaCidadao = null, $quantidadeRetornoCidadao = null, $tempoRetornoCidadao = null)
|
|
{
|
|
$quantidadeConsulta = $quantidadeConsulta ?? 0;
|
|
$tempoConsulta = $tempoConsulta ?? 0;
|
|
$quantidadeRetorno = $quantidadeRetorno ?? 0;
|
|
$tempoRetorno = $tempoRetorno ?? 0;
|
|
$quantidadeConsultaCidadao = $quantidadeConsultaCidadao ?? 0;
|
|
$tempoConsultaCidadao = $tempoConsultaCidadao ?? 0;
|
|
$quantidadeRetornoCidadao = $quantidadeRetornoCidadao ?? 0;
|
|
$tempoRetornoCidadao = $tempoRetornoCidadao ?? 0;
|
|
|
|
$tempoTotalConsulta = $quantidadeConsulta * $tempoConsulta;
|
|
$tempoTotalRetorno = $quantidadeRetorno * $tempoRetorno;
|
|
$tempoTotalConsultaCidadao = $quantidadeConsultaCidadao * $tempoConsultaCidadao;
|
|
$tempoTotalRetornoCidadao = $quantidadeRetornoCidadao * $tempoRetornoCidadao;
|
|
|
|
$inicio = Carbon::now()->setTimeFromTimeString("{$inicio}:00");
|
|
$fim = $inicio->copy()->addMinutes($tempoTotalConsulta + $tempoTotalRetorno + $tempoTotalConsultaCidadao + $tempoTotalRetornoCidadao);
|
|
|
|
if (!$inicio->isSameDay($fim)) {
|
|
|
|
throw new FimExcedeuDataJornadaException();
|
|
}
|
|
|
|
return $fim->format('H:i');
|
|
}
|
|
|
|
public static function destroy($id)
|
|
{
|
|
$jornada = Jornada::findOrFail($id);
|
|
|
|
if ($jornada->agendamentos()->exists()) {
|
|
|
|
throw new PossuiAgendamentoException();
|
|
}
|
|
|
|
$jornada->delete();
|
|
}
|
|
|
|
public static function destroyAll()
|
|
{
|
|
$idsExcluidos = collect();
|
|
$idsComAgendamento = collect();
|
|
|
|
collect(request()->ids)->each(function ($id) use ($idsExcluidos, $idsComAgendamento) {
|
|
|
|
$jornada = Jornada::findOrFail($id);
|
|
|
|
if ($jornada->agendamentos()->exists()) {
|
|
|
|
$idsComAgendamento->push($jornada->id);
|
|
}
|
|
else {
|
|
|
|
$jornada->delete();
|
|
|
|
$idsExcluidos->push($jornada->id);
|
|
}
|
|
});
|
|
|
|
return [
|
|
'jornadas_ids_excluidos' => $idsExcluidos,
|
|
'jornadas_ids_com_agendamento' => $idsComAgendamento,
|
|
];
|
|
}
|
|
}
|