Files
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

368 lines
20 KiB
PHP

<?php
namespace App\Services\ExameImagem;
use App\Enums\ExameImagem\Fechamento\Status;
use App\Enums\Regulacao\StatusTipo as RegulacaoStatusTipoEnum;
use App\Exceptions\ExameImagem\ProtocoloFechamentoException;
use App\Models\Cadastro\SujeitoAtencao\Lotacao;
use App\Models\ExameImagem\Agendamento\AgendamentoExame;
use App\Models\ExameImagem\Fechamento\Faturamento;
use App\Models\ExameImagem\Fechamento\StatusFechamento;
use App\Models\Parametrizacao\Exame\Exame;
use App\Services\Regulacao\SolicitacaoService as RegulacaoSolicitacaoService;
use App\Services\Service;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class FechamentoService extends Service
{
public static function list()
{
$now = Carbon::now();
$currentLotacao = self::getCurrentLotacao();
$isSupervisor = DB::table('exame_imagem_parametrizacao_supervisor')
->where('usuario_id', $currentLotacao->usuario_id)
->exists();
return [
'form' => [
'data_atual' => Carbon::now()->format('d/m/Y'),
'infraestrutura' => $currentLotacao->infraestrutura->nome,
'status' => DB::table('exame_imagem_fechamento_status')
->select(
'exame_imagem_fechamento_status.id as id',
'exame_imagem_fechamento_status.nome as nome'
)
->leftjoin('exame_imagem_agendamento_exame', 'exame_imagem_agendamento_exame.status_id', '=', 'exame_imagem_fechamento_status.id')
->leftjoin('exame_imagem_agendamento', 'exame_imagem_agendamento.id', '=', 'exame_imagem_agendamento_exame.agendamento_id')
->leftjoin('regulacao_solicitacao', 'regulacao_solicitacao.id', '=', 'exame_imagem_agendamento.regulacao_solicitacao_id')
->whereNotIn('exame_imagem_fechamento_status.id', [Status::RESULTADO,Status::CANCELADO, Status::REAGENDADO, Status::FALTA_MEDICA])
->orderBy('exame_imagem_fechamento_status.nome')
->distinct()
->get()
->map(fn($status) => [
'id' => $status->id,
'nome' => $status->nome,
]),
],
'model' => [
'periodo' => [
'start' => Carbon::now()->format('d/m/Y'),
'end' => Carbon::now()->format('d/m/Y'),
],
'agendamentos' => self::getAgendamentos(),
'agendamentosNotSave' => null,
'unidade_id' => null,
'profissional_id' => null,
'medico_id' => null,
'grupo_exame_id' => null,
'exame_id' => null,
],
'additionals' => [
'periodo_min_date' => $now->copy()->subYears(130)->format('d/m/Y'),
'current_date' => $now->format('d/m/Y'),
'is_supervisor' => $isSupervisor,
],
];
}
private static function getAgendamentos()
{
$agendamentos = DB::table('exame_imagem_agendamento_exame')
->select(
'exame_imagem_agendamento_exame.id AS id_paciente',
'exame_imagem_agendamento_exame.id AS agendamento_exame_id',
'cadastro_grupo.id AS grupo_exame_id',
'exame_imagem_agendamento.agendamento_numero AS agendamento_numero',
'cadastro_grupo.nome as grupo_nome',
'exame_imagem_fechamento_status.id AS status_id',
'exame_imagem_fechamento_status.nome AS status_nome',
'exame_imagem_agendamento_exame.agendamento_id AS agendamento_id',
'exame_imagem_agendamento.medico_id',
'exame_imagem_agendamento.unidade_id',
'exame_imagem_agendamento.profissional_id',
'exame_imagem_agendamento.urgente',
'exame_imagem_agendamento.nome_responsavel',
'exame_imagem_agendamento.regulacao_solicitacao_id AS regulacao_solicitacao_id',
'cadastro_unidade.nome_fantasia as unidade_nome',
'medico_cidadao.nome AS medico',
'profissional.nome AS profissional_nome',
'cadastro_unidade_solicitante.nome_fantasia AS unidade_solicitante_nome',
'cadastro_paciente.id AS paciente_id',
'cidadao.nome AS paciente_nome',
'cidadao.cns AS paciente_cns',
'cidadao.cpf as paciente_cpf',
'cidadao.nome_social AS nome_social',
'sexo.descricao AS paciente_sexo',
'unidade_referencia_paciente.nome_fantasia AS paciente_unidade_referencia',
'parametrizacao_exame.id AS exame_id',
'parametrizacao_exame.nome AS exame_nome',
DB::raw("DATE_FORMAT(exame_imagem_agendamento.data, '%d/%m/%Y') AS data"),
DB::raw("DATE_FORMAT(exame_imagem_agendamento.created_at, '%d/%m/%Y') AS data_pedido"),
DB::raw('LPAD(cadastro_paciente.prontuario,7,0) AS prontuario'),
DB::raw('IF (cidadao.data_nascimento IS NULL, "Não informada", DATE_FORMAT(cidadao.data_nascimento, "%d/%m/%Y")) as data_nascimento'),
DB::raw('IF(cidadao.data_nascimento IS NULL, "Não informada",
TIMESTAMPDIFF(YEAR, cidadao.data_nascimento, CURDATE())) as idade'),
DB::raw('
(CASE WHEN cidadao.nome_mae IS NULL THEN
"Não informado"
ELSE
cidadao.nome_mae
END) as nome_mae'
),
DB::raw("
(
SELECT numero
FROM cadastro_cidadao_telefone
WHERE cadastro_cidadao_telefone.cidadao_id = cidadao.id
AND cadastro_cidadao_telefone.principal = TRUE
LIMIT 1
) AS paciente_telefone
"),
'regulacao_solicitacao.numero',
'regulacao_parametrizacao_prestador_interno.controla_protocolo_fechamento',
)
->where(function ($query) {
$query->where('exame_imagem_agendamento_exame.status_id', Status::AGENDADO)
->orWhere('exame_imagem_agendamento_exame.status_id', NULL);
})
->join('exame_imagem_agendamento', 'exame_imagem_agendamento.id', 'exame_imagem_agendamento_exame.agendamento_id')
->join('cadastro_infraestrutura', 'cadastro_infraestrutura.id', 'exame_imagem_agendamento.infraestrutura_id')
->join('cadastro_unidade', 'cadastro_unidade.id', 'cadastro_infraestrutura.unidade_id')
->join('cadastro_infraestrutura AS cadastro_infraestrutura_solicitante', 'cadastro_infraestrutura_solicitante.id', 'exame_imagem_agendamento.infraestrutura_solicitante_id')
->join('cadastro_unidade AS cadastro_unidade_solicitante', 'cadastro_unidade_solicitante.id', 'cadastro_infraestrutura_solicitante.unidade_id')
->join('cadastro_usuario', 'cadastro_usuario.id', 'exame_imagem_agendamento.medico_id')
->join('cadastro_cidadao AS medico_cidadao', 'medico_cidadao.id', 'cadastro_usuario.cidadao_id')
->join('cadastro_usuario AS profissional_cidadao', 'profissional_cidadao.id', 'exame_imagem_agendamento.profissional_id')
->join('cadastro_cidadao AS profissional', 'profissional.id', 'profissional_cidadao.cidadao_id')
->leftJoin('exame_imagem_fechamento_status', 'exame_imagem_fechamento_status.id', 'exame_imagem_agendamento_exame.status_id')
->join('parametrizacao_exame', 'parametrizacao_exame.id', 'exame_imagem_agendamento_exame.exame_id')
->leftJoin('cadastro_paciente', 'cadastro_paciente.id', 'exame_imagem_agendamento_exame.paciente_id')
->leftJoin('cadastro_cidadao AS cidadao', 'cidadao.id', 'cadastro_paciente.cidadao_id')
->leftJoin('cadastro_usuario_registro_tipo', 'cadastro_usuario_registro_tipo.id', 'profissional_cidadao.registro_tipo_id')
->leftJoin('cadastro_grupo', 'cadastro_grupo.id', 'parametrizacao_exame.grupo_tipo_id')
->leftJoin('cadastro_sexo AS sexo', 'sexo.id', 'cidadao.sexo_id')
->leftJoin('cadastro_unidade AS unidade_referencia_paciente', 'unidade_referencia_paciente.id', 'cadastro_paciente.unidade_id')
->leftJoin('regulacao_solicitacao', 'regulacao_solicitacao.id', 'exame_imagem_agendamento.regulacao_solicitacao_id')
->leftJoin('regulacao_parametrizacao_prestador_interno', 'regulacao_parametrizacao_prestador_interno.id', 'regulacao_solicitacao.prestador_interno_id')
->get()
->map(function ($item) {
return [
'id_paciente' => $item->id_paciente,
'agendamento_numero' => $item->agendamento_numero,
'agendamento_exame_id' => $item->agendamento_exame_id,
'grupo_exame_id' => $item->grupo_exame_id,
'grupo_nome' => $item->grupo_nome,
'status_id' => $item->status_id,
'status_nome' => $item->status_nome,
'agendamento_id' => $item->agendamento_id,
'medico_id' => $item->medico_id,
'unidade_id' => $item->unidade_id,
'profissional_id' => $item->profissional_id,
'urgente' => $item->urgente,
'unidade_nome' => $item->unidade_nome,
'medico' => $item->medico,
'profissional_nome' => $item->profissional_nome,
'unidade_solicitante_nome' => $item->unidade_solicitante_nome,
'paciente_id' => $item->paciente_id,
'paciente_nome' => $item->paciente_nome,
'paciente_cns' => $item->paciente_cns,
'paciente_cpf' => $item->paciente_cpf,
'paciente_telefone' => $item->paciente_telefone,
'paciente_idade' => $item->idade,
'paciente_sexo' => $item->paciente_sexo,
'nome_responsavel' => $item->nome_responsavel ?? null,
'paciente_unidade_referencia' => $item->paciente_unidade_referencia ?? null,
'nome_social' => $item->nome_social,
'exame_id' => $item->exame_id,
'exame_nome' => $item->exame_nome,
'data' => $item->data,
'data_pedido' => $item->data_pedido,
'prontuario' => $item->prontuario,
'data_nascimento' => $item->data_nascimento,
'nome_mae' => $item->nome_mae,
'regulacao_solicitacao_id' => $item->regulacao_solicitacao_id ?? null,
'faturamento' => DB::table('exame_imagem_agendamento_exame')
->select('id', 'exame_id')
->where('agendamento_id', $item->agendamento_id)
->get()
->map(function ($faturamento) use ($item) {
$exame = DB::table('parametrizacao_exame')
->select('nome', 'codigo', 'exige_procedimento', 'valor', 'valor_sigtap')
->where('id', $faturamento->exame_id)
->first();
$procedimento = DB::table('sigtap.procedimento')
->where('codigo',
$exame->codigo
)
->where('competencia_id', function ($query) {
$query->select('id')
->from('sigtap.competencia')
->orderByDesc('valor')
->limit(1);
})
->first();
return [
'id' => $faturamento->id,
'agendamento_id' => $item->agendamento_id,
'agendamento_exame_id' => $item->agendamento_exame_id,
'exame_id' => $item->exame_id,
'data' => $item->data,
'grupo_id' => $item->grupo_exame_id,
'paciente_id' => $item->paciente_id,
'unidade_id' => $item->unidade_id,
'valor_normal' => $exame->valor ?? null,
'exige_procedimento' => $exame->exige_procedimento,
'profissional_id' => $item->profissional_id,
'profissional_nome' => $item->profissional_nome ?? null,
'procedimento_id' => $procedimento->id ?? null,
'procedimento_codigo' => $procedimento->codigo ?? null,
'procedimento_nome' => $procedimento->nome ?? null,
'valor' => $procedimento->valor_servico_ambilatorial ?? null,
'lotacao' => DB::table('cadastro_lotacao')
->select('id', 'ocupacao_id', 'usuario_id')
->whereNull('deleted_at')
->where('usuario_id', $item->profissional_id)
->get()
->map(function ($lotacaoProfissional) use ($item) {
return [
'ocupacao_id' => $lotacaoProfissional->ocupacao_id,
'usuario_id' => $lotacaoProfissional->usuario_id,
'lotacao_id' => $lotacaoProfissional->id,
];
})
->toArray(),
];
}),
'numero' => $item->numero,
'controla_protocolo_fechamento' => $item->controla_protocolo_fechamento,
'protocolo_fechamento' => null,
];
});
return $agendamentos->isNotEmpty() ? $agendamentos->toArray() : [];
}
public static function store(Request $request)
{
return self::saveStatusExame($request);
}
private static function saveStatusExame($request)
{
$ids = [];
foreach ($request->agendamentos as $params) {
if ($params['status_id'] == Status::REALIZADO && $params['controla_protocolo_fechamento']
&& $params['numero'] && $params['numero'] !== $params['protocolo_fechamento']) {
throw new ProtocoloFechamentoException();
}
$tipo = AgendamentoExame::where('agendamento_id', $params['agendamento_id'])
->where('id', $params['agendamento_exame_id'])
->where('exame_id', $params['exame_id'])
->first();
$tipo->status_id = $params['status_id'];
if($params['status_id'] != null){
$tipo->save();
}
$regulacaoSolicitacaoId = $params['regulacao_solicitacao_id'] ?? null;
if ($regulacaoSolicitacaoId) {
$statusTipoId = null;
if ($params['status_id'] === Status::REALIZADO) {
$statusTipoId = RegulacaoStatusTipoEnum::REALIZADO;
} else if ($params['status_id'] === Status::FALTOU) {
$statusTipoId = RegulacaoStatusTipoEnum::FALTA;
}
if (!is_null($statusTipoId)) {
RegulacaoSolicitacaoService::updateStatus($regulacaoSolicitacaoId, $statusTipoId);
}
}
$ids[] = $tipo->id;
if ($params['status_id'] == Status::REALIZADO) {
foreach ($params['faturamento'] as $param_faturamento) {
if($param_faturamento['exige_procedimento']){
$faturamento = Faturamento::where('exame_id', $param_faturamento['exame_id'])
->where('agendamento_exame_id', $param_faturamento['agendamento_exame_id'])
->where('grupo_id', $param_faturamento['grupo_id'])
->first() ?? new Faturamento();
foreach ($param_faturamento['lotacao'] as $lotacao_faturar) {
$lotacoes = Lotacao::join(
'cadastro_infraestrutura',
'cadastro_infraestrutura.id',
'cadastro_lotacao.infraestrutura_id'
)
->select([
'cadastro_lotacao.id',
'cadastro_lotacao.ocupacao_id',
'cadastro_lotacao.usuario_id',
])
->where('cadastro_lotacao.id', $lotacao_faturar['lotacao_id'])
->where('cadastro_lotacao.usuario_id', $lotacao_faturar['usuario_id'])
->where('cadastro_infraestrutura.unidade_id', $param_faturamento['unidade_id'])
->where('cadastro_lotacao.ativo', true)
->whereNull('cadastro_lotacao.deleted_at')
->first();
if (!empty($lotacoes)) {
$faturamento->lotacao_id = $lotacoes->id;
$faturamento->ocupacao_id = $lotacoes->ocupacao_id;
$faturamento->usuario_id = $lotacoes->usuario_id;
break;
} else {
$faturamento->lotacao_id = $lotacao_faturar['lotacao_id'];
$faturamento->ocupacao_id = $lotacao_faturar['ocupacao_id'];
$faturamento->usuario_id = $lotacao_faturar['usuario_id'];
}
}
$faturamento->agendamento_exame_id = $param_faturamento['agendamento_exame_id'];
$faturamento->grupo_id = $param_faturamento['grupo_id'];
$faturamento->unidade_id = $param_faturamento['unidade_id'];
$faturamento->valor = $param_faturamento['valor'];
$faturamento->valor_normal = $param_faturamento['valor_normal'];
$faturamento->data = Carbon::createFromFormat('d/m/Y', $param_faturamento['data']);
$faturamento->procedimento_id = $param_faturamento['procedimento_id'];
$faturamento->quantidade = 1;
$faturamento->fill($params);
$faturamento->save();
$idsFaturamento[] = $faturamento->id;
}
}
}
}
}
}