init commit
All checks were successful
build-api-image / build (push) Successful in 51s

This commit is contained in:
Antonio Lopes dos Santos
2026-08-04 16:52:02 -03:00
commit afec302c3e
11594 changed files with 1636728 additions and 0 deletions

View File

@@ -0,0 +1,627 @@
<?php
namespace App\Services\Integracao\Erpsaude;
use App\Models\Integracao\Erpsaude\Paciente as ErpsaudePaciente;
use App\Services\Service;
use App\Utils\DataUtil;
use Carbon\Carbon;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;
class RelatorioAtendimentoService extends Service
{
public static function autocompletePaciente()
{
$params = request()->all();
self::adjustPeriod($params);
$pacientes = DB::table('integracao_erpsaude_paciente')
->select(
'integracao_erpsaude_paciente.id',
'integracao_erpsaude_paciente.nome',
'integracao_erpsaude_paciente.cns',
)
->join('integracao_erpsaude_atendimento', 'integracao_erpsaude_atendimento.paciente_id', 'integracao_erpsaude_paciente.id')
->where(function ($query) use ($params) {
$idadeDe = $params['idade_de'] ?? null;
$idadeAte = $params['idade_ate'] ?? null;
$query->whereRaw("CONCAT(integracao_erpsaude_atendimento.data_atendimento, ' ', integracao_erpsaude_atendimento.horario_atendimento) BETWEEN ? AND ?", [
$params['periodo']['date']['start'],
$params['periodo']['date']['end']
]);
if (isset($params['dia_semana'])) {
self::addWhereRawDayOfWeek($params['dia_semana'], $query);
}
if (self::hasParamId($params, 'tipo_alta_id')) {
$query->where('integracao_erpsaude_atendimento.tipo_alta_id', $params['tipo_alta_id']);
}
if (isset($params['cid'])) {
$query->where('integracao_erpsaude_atendimento.cid10', $params['cid']);
}
if (isset($params['profissional'])) {
$query->where('integracao_erpsaude_atendimento.profissional', $params['profissional']);
}
if (!is_null($idadeDe)) {
$query->whereRaw("(TIMESTAMPDIFF(YEAR, integracao_erpsaude_paciente.data_nascimento, CURRENT_DATE)) >= $idadeDe");
}
if (!is_null($idadeAte)) {
$query->whereRaw("(TIMESTAMPDIFF(YEAR, integracao_erpsaude_paciente.data_nascimento, CURRENT_DATE)) <= $idadeAte");
}
})->distinct();
return $pacientes;
}
public static function index()
{
$params = request()->all();
$idadeDe = $params['idade_de'] ?? null;
$idadeAte = $params['idade_ate'] ?? null;
self::adjustPeriod($params);
$atendimentos = DB::table('integracao_erpsaude_atendimento')
->select(
'integracao_erpsaude_paciente.nome AS nome_paciente',
'integracao_erpsaude_paciente.cns AS cns',
'integracao_erpsaude_paciente.data_nascimento AS data_nascimento',
DB::raw("DATE_FORMAT(integracao_erpsaude_atendimento.data_atendimento, '%d/%m/%Y') AS data"),
'integracao_erpsaude_atendimento.data_atendimento AS data_atendimento',
DB::raw("DATE_FORMAT(integracao_erpsaude_atendimento.horario_atendimento, '%H:%i') AS horario"),
'integracao_erpsaude_atendimento.profissional AS profissional',
'integracao_erpsaude_tipo_alta.descricao AS tipo_alta',
DB::raw("IF(cadastro_cidadao.id IS NOT NULL, 'CADASTRADO', 'SEM CADASTRO') AS conectasus"),
DB::raw("IF(cid.id IS NULL, integracao_erpsaude_atendimento.cid10, CONCAT(cid.codigo, ' - ', cid.nome)) AS cid"),
DB::raw("
CONCAT(
TIMESTAMPDIFF(YEAR, integracao_erpsaude_paciente.data_nascimento, CURDATE()), ' anos, ',
TIMESTAMPDIFF(MONTH, integracao_erpsaude_paciente.data_nascimento, CURDATE()) % 12, ' meses e ',
DATEDIFF(
CURDATE(),
DATE_ADD(
DATE_ADD(
integracao_erpsaude_paciente.data_nascimento,
INTERVAL TIMESTAMPDIFF(YEAR, integracao_erpsaude_paciente.data_nascimento, CURDATE()) YEAR
),
INTERVAL (TIMESTAMPDIFF(MONTH, integracao_erpsaude_paciente.data_nascimento, CURDATE()) % 12) MONTH
)
), ' dias'
) AS idade
"),
DB::raw("
CASE integracao_erpsaude_paciente.sexo
WHEN 'M' THEN 'Masculino'
WHEN 'F' THEN 'Feminino'
ELSE 'Não informado'
END AS sexo
"),
)
->join('integracao_erpsaude_paciente', 'integracao_erpsaude_paciente.id', 'integracao_erpsaude_atendimento.paciente_id')
->leftJoin('integracao_erpsaude_tipo_alta', 'integracao_erpsaude_tipo_alta.id', 'integracao_erpsaude_atendimento.tipo_alta_id')
->leftJoin('sigtap.cid AS cid', 'cid.codigo', 'integracao_erpsaude_atendimento.cid10')
->leftJoin('cadastro_cidadao', function ($join) {
$join->on('cadastro_cidadao.cns', '=', 'integracao_erpsaude_paciente.cns')
->orOn(function ($query) {
$query->on(DB::raw('LOWER(cadastro_cidadao.nome)'), '=', DB::raw('LOWER(integracao_erpsaude_paciente.nome)'))
->whereRaw('DATE(cadastro_cidadao.data_nascimento) = DATE(integracao_erpsaude_paciente.data_nascimento)');
});
})
->whereRaw("CONCAT(integracao_erpsaude_atendimento.data_atendimento, ' ', integracao_erpsaude_atendimento.horario_atendimento) BETWEEN ? AND ?", [
$params['periodo']['date']['start'],
$params['periodo']['date']['end']
]);
if (isset($params['dia_semana'])) {
self::addWhereRawDayOfWeek($params['dia_semana'], $atendimentos);
}
if (self::hasParamId($params, 'tipo_alta_id')) {
$atendimentos->where('integracao_erpsaude_atendimento.tipo_alta_id', $params['tipo_alta_id']);
}
if (isset($params['profissional'])) {
$atendimentos->where('integracao_erpsaude_atendimento.profissional', $params['profissional']);
}
if (isset($params['cid'])) {
$atendimentos->where('integracao_erpsaude_atendimento.cid10', $params['cid']);
}
if (!is_null($idadeDe)) {
$atendimentos->whereRaw("(TIMESTAMPDIFF(YEAR, integracao_erpsaude_paciente.data_nascimento, CURRENT_DATE)) >= ?", [$idadeDe]);
}
if (!is_null($idadeAte)) {
$atendimentos->whereRaw("(TIMESTAMPDIFF(YEAR, integracao_erpsaude_paciente.data_nascimento, CURRENT_DATE)) <= ?", [$idadeAte]);
}
if (self::hasParamId($params, 'paciente_id')) {
$atendimentos->where('integracao_erpsaude_paciente.id', $params['paciente_id']);
} else {
if (isset($params['cns'])) {
$atendimentos->where('integracao_erpsaude_paciente.cns', $params['cns']);
}
}
if (isset($params['sexo_id'])) {
$atendimentos->where('integracao_erpsaude_paciente.sexo', $params['sexo_id']);
}
self::setOrderBy($atendimentos);
$atendimentos = $atendimentos->get()
->map(function ($atendimento) {
$dtAtend = Carbon::create($atendimento->data_atendimento);
return array_merge([
'nome_paciente' => $atendimento->nome_paciente,
'data_nascimento' => $atendimento->data_nascimento,
'cns' => $atendimento->cns,
'profissional' => $atendimento->profissional ?? '-',
'data' => $atendimento->data,
'horario' => $atendimento->horario,
'cid' => $atendimento->cid ?? '-',
'idade' => $atendimento->idade,
'sexo' => $atendimento->sexo,
'tipo_alta' => $atendimento->tipo_alta,
'conectasus' => $atendimento->conectasus,
'dia_semana' => Str::ucfirst($dtAtend->translatedFormat('l')),
]);
});
$contagens = $atendimentos->groupBy('cns')->map->count();
$atendimentos = $atendimentos->map(function ($item) use ($contagens) {
$item['quantidade'] = $contagens[$item['cns']];
return $item;
});
$minimo = request()->quantidade;
$atendimentos = $atendimentos->when($minimo, function ($query) use ($minimo) {
return $query->filter(fn ($item) => $item['quantidade'] >= $minimo);
});
$atendimentos = $atendimentos->values()->toArray();
return [
'atendimentos' => $atendimentos,
];
}
private static function setOrderBy($builder)
{
$columns = [
'data' => 'integracao_erpsaude_atendimento.data_atendimento',
'horario' => 'integracao_erpsaude_atendimento.horario_atendimento',
'cns' => 'integracao_erpsaude_paciente.cns',
'nome_paciente' => 'integracao_erpsaude_paciente.nome',
'sexo' => 'integracao_erpsaude_paciente.sexo',
'dia_semana' => DB::raw('DAYOFWEEK(integracao_erpsaude_atendimento.data_atendimento)'),
'idade' => DB::raw("
CONCAT(
TIMESTAMPDIFF(YEAR, integracao_erpsaude_paciente.data_nascimento, CURDATE()), ' anos, ',
TIMESTAMPDIFF(MONTH, integracao_erpsaude_paciente.data_nascimento, CURDATE()) % 12, ' meses e ',
DATEDIFF(
CURDATE(),
DATE_ADD(
DATE_ADD(
integracao_erpsaude_paciente.data_nascimento,
INTERVAL TIMESTAMPDIFF(YEAR, integracao_erpsaude_paciente.data_nascimento, CURDATE()) YEAR
),
INTERVAL (TIMESTAMPDIFF(MONTH, integracao_erpsaude_paciente.data_nascimento, CURDATE()) % 12) MONTH
)
), ' dias'
)
"),
'tipo_alta' => 'integracao_erpsaude_atendimento.tipo_alta_id',
'cid' => 'integracao_erpsaude_atendimento.cid10',
'profissional' => 'integracao_erpsaude_atendimento.profissional',
'conectasus' => DB::raw("IF(cadastro_cidadao.id IS NOT NULL, 'CADASTRADO', 'SEM CADASTRO')"),
'cns' => 'integracao_erpsaude_paciente.cns',
'data_nascimento' => 'integracao_erpsaude_paciente.data_nascimento',
];
if (is_null(request()->sort_by)) {
$builder->orderByRaw(join(', ', $columns));
return;
}
$column = $columns[request()->sort_by];
$direction = DataUtil::getBooleanValueFromStringBoolean(request()->sort_desc) ? 'DESC' : 'ASC';
unset($columns[request()->sort_by]);
$builder->orderByRaw(
"{$column} {$direction}, " . join(', ', $columns)
);
}
public static function list()
{
$params = collect(request()->all());
$camposParaCarregar = collect();
if($params->isNotEmpty()){
$camposParaCarregar->push(
'dias_semana',
'tipoAltas',
'profissionais',
'cids',
'sexos',
);
}
return [
'form' => self::camposFiltrados($camposParaCarregar),
'model' => self::getModel(),
'additionals' => [
'data_atual' => Carbon::today()->format('d/m/Y'),
]
];
}
public static function filtragemPorDiaSemana(){
return self::camposFiltrados(collect([
'tipoAltas',
'profissionais',
'cids',
'sexos',
]));
}
public static function filtragemPorTipoAlta(){
return self::camposFiltrados(collect([
'profissionais',
'status',
'cids',
'sexos',
]));
}
public static function filtragemPorProfissional(){
return self::camposFiltrados(collect([
'cids',
'sexos',
]));
}
public static function filtragemPorCid(){
return self::camposFiltrados(collect([
'sexos',
]));
}
private static function camposFiltrados(Collection $campos){
$params = request()->all();
$dados = collect();
self::adjustPeriod($params);
if ($campos->contains('dias_semana')) {
$dados->put('dias_semana', self::getDiasSemana($params));
}
if ($campos->contains('tipoAltas')) {
$dados->put('tipoAltas', self::getTipoAltas($params));
}
if ($campos->contains('profissionais')) {
$dados->put('profissionais', self::getProfissionais($params));
}
if ($campos->contains('cids')) {
$dados->put('cids', self::getCids($params));
}
if ($campos->contains('sexos')) {
$dados->put('sexos', self::getSexos($params));
}
return $dados->all();
}
private static function adjustPeriod(&$params)
{
if (is_null($params['periodo']['date']['start'] ?? null) || is_null($params['periodo']['date']['end'] ?? null)) {
return;
}
$dateStart = $params['periodo']['date']['start'];
$dateEnd = $params['periodo']['date']['end'];
$timeStart = $params['periodo']['time']['start'];
$timeEnd = $params['periodo']['time']['end'];
$params['periodo']['date']['start'] = (Carbon::createFromFormat('d/m/Y', "{$dateStart}"))->startOfDay();
$params['periodo']['date']['end'] = (Carbon::createFromFormat('d/m/Y', "{$dateEnd}"))->endOfDay();
if (!is_null($timeStart ?? null)) {
$params['periodo']['date']['start'] = Carbon::createFromFormat('d/m/Y H:i:s', "{$dateStart} {$timeStart}");
}
if (!is_null($timeEnd)) {
$params['periodo']['date']['end'] = Carbon::createFromFormat('d/m/Y H:i:s', "{$dateEnd} {$timeEnd}");
}
$params['periodo']['date']['start'] = $params['periodo']['date']['start']->format('Y-m-d H:i');
$params['periodo']['date']['end'] = $params['periodo']['date']['end']->format('Y-m-d H:i');
}
private static function getDiasSemana($params)
{
$atendimentos = DB::table('integracao_erpsaude_atendimento AS at')
->select(
'at.data_atendimento'
)
->whereRaw("CONCAT(data_atendimento, ' ', horario_atendimento) BETWEEN ? AND ?", [
$params['periodo']['date']['start'],
$params['periodo']['date']['end']
])
->get();
return $atendimentos
->map(function ($atendimento) {
$date = new Carbon($atendimento->data_atendimento);
return [
'valor' => $date->format('w'),
'descricao' => Str::ucfirst($date->translatedFormat('l'))
];
})
->unique('valor')
->sortBy('valor')
->values();
}
private static function getTipoAltas($params)
{
$query = DB::table('integracao_erpsaude_tipo_alta')
->select(
'integracao_erpsaude_tipo_alta.id',
'integracao_erpsaude_tipo_alta.descricao'
)
->join(
'integracao_erpsaude_atendimento',
'integracao_erpsaude_atendimento.tipo_alta_id',
'integracao_erpsaude_tipo_alta.id'
)
->whereNotNull(
'integracao_erpsaude_atendimento.tipo_alta_id',
)
->whereRaw("CONCAT(data_atendimento, ' ', horario_atendimento) BETWEEN ? AND ?", [
$params['periodo']['date']['start'],
$params['periodo']['date']['end']
]);
if (isset($params['dia_semana'])) {
self::addWhereRawDayOfWeek($params['dia_semana'], $query);
}
$query->orderBy('integracao_erpsaude_tipo_alta.descricao');
return $query
->distinct()
->get();
}
private static function getProfissionais($params)
{
$query = DB::table('integracao_erpsaude_atendimento')
->select(
'integracao_erpsaude_atendimento.profissional as nome'
)
->distinct()
->whereRaw("CONCAT(data_atendimento, ' ', horario_atendimento) BETWEEN ? AND ?", [
$params['periodo']['date']['start'],
$params['periodo']['date']['end']
]);
if (isset($params['dia_semana'])) {
self::addWhereRawDayOfWeek($params['dia_semana'], $query);
}
if (self::hasParamId($params, 'tipo_alta_id')) {
$query->where('integracao_erpsaude_atendimento.tipo_alta_id', $params['tipo_alta_id']);
}
return $query->orderBy('nome')->get();
}
private static function getCids($params)
{
$query = DB::table('integracao_erpsaude_atendimento')
->select(
'integracao_erpsaude_atendimento.cid10 as codigo',
DB::raw("IF(cid.id IS NULL, integracao_erpsaude_atendimento.cid10, CONCAT(cid.codigo, ' - ', cid.nome)) AS descricao"),
)
->leftJoin('sigtap.cid AS cid', 'cid.codigo', 'integracao_erpsaude_atendimento.cid10')
->distinct()
->whereRaw("CONCAT(data_atendimento, ' ', horario_atendimento) BETWEEN ? AND ?", [
$params['periodo']['date']['start'],
$params['periodo']['date']['end']
]);
if (isset($params['dia_semana'])) {
self::addWhereRawDayOfWeek($params['dia_semana'], $query);
}
if (self::hasParamId($params, 'tipo_alta_id')) {
$query->where('integracao_erpsaude_atendimento.tipo_alta_id', $params['tipo_alta_id']);
}
if (isset($params['profissional'])) {
$query->where('integracao_erpsaude_atendimento.profissional', $params['profissional']);
}
return $query
->orderBy('descricao')
->get();
}
private static function getSexos($params)
{
$params = request()->all();
self::adjustPeriod($params);
$sexos = DB::table('integracao_erpsaude_paciente')
->select(
DB::raw("
CASE integracao_erpsaude_paciente.sexo
WHEN 'M' THEN 'Masculino'
WHEN 'F' THEN 'Feminino'
ELSE 'Não informado'
END AS descricao
"),
'integracao_erpsaude_paciente.sexo as value'
)
->distinct()
->join('integracao_erpsaude_atendimento', 'integracao_erpsaude_atendimento.paciente_id', 'integracao_erpsaude_paciente.id')
->whereRaw("CONCAT(data_atendimento, ' ', horario_atendimento) BETWEEN ? AND ?", [
$params['periodo']['date']['start'],
$params['periodo']['date']['end']
]);
if (isset($params['dia_semana'])) {
self::addWhereRawDayOfWeek($params['dia_semana'], $sexos);
}
if (self::hasParamId($params, 'alta_tipo_id')) {
$sexos->where('integracao_erpsaude_atendimento.alta_tipo_id', $params['alta_tipo_id']);
}
if (isset($params['cid'])) {
$sexos->where('integracao_erpsaude_atendimento.cid10', $params['cid']);
}
if (isset($params['profissional'])) {
$sexos->where('integracao_erpsaude_atendimento.profissional', $params['profissional']);
}
$idadeDe = $params['idade_de'] ?? null;
$idadeAte = $params['idade_ate'] ?? null;
if (!is_null($idadeDe)) {
$sexos->whereRaw("(TIMESTAMPDIFF(YEAR, integracao_erpsaude_paciente.data_nascimento, CURRENT_DATE)) >= ?", [$idadeDe]);
}
if (!is_null($idadeAte)) {
$sexos->whereRaw("(TIMESTAMPDIFF(YEAR, integracao_erpsaude_paciente.data_nascimento, CURRENT_DATE)) <= ?", [$idadeAte]);
}
if (self::hasParamId($params, 'paciente_id')) {
$sexos->where('integracao_erpsaude_paciente.id', $params['paciente_id']);
}
return $sexos->orderBy('sexo')->get();
}
private static function hasParamId($params, $param)
{
return isset($params[$param]) && $params[$param] > 0;
}
private static function getCidJoinSub() {
return DB::table('pronto_atendimento_atendimento_cid')
->select(
'pronto_atendimento_atendimento_cid.cid_id',
'pronto_atendimento_atendimento_cid.atendimento_id',
)
->union(
DB::table('pronto_atendimento_atendimento_procedimento')
->select(
'pronto_atendimento_atendimento_procedimento.cid_principal_id AS cid_id',
'pronto_atendimento_atendimento_procedimento.atendimento_id'
)
->where('pronto_atendimento_atendimento_procedimento.is_parametrizado', true)
);
}
private static function addWhereRawDayOfWeek($diaSemana, $query)
{
$diaSemana += 1;
$query->whereRaw("
DAYOFWEEK(integracao_erpsaude_atendimento.data_atendimento) = {$diaSemana}
");
}
private static function getModel()
{
return [
'periodo' => [
'date' => [
'start' => null,
'end' => null,
],
'time' => [
'start' => null,
'end' => null,
]
],
'dia_semana' => null,
'tipo_alta_id' => null,
'profissional' => null,
'cid_id' => null,
'paciente_id' => null,
'paciente' => null,
'cns' => null,
'sexo_id' => null,
'idade_de' => null,
'idade_ate' => null,
'quantidade' => null,
];
}
}