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,599 @@
<?php
namespace App\Services\Farmacia;
use App\Models\Cadastro\Estabelecimento\CentroCusto;
use App\Models\Cadastro\Estabelecimento\Infraestrutura;
use App\Models\Cadastro\Estabelecimento\Unidade;
use App\Models\Cadastro\SujeitoAtencao\Paciente;
use App\Models\Farmacia\AltoCusto\ProcessoSubtipo;
use App\Models\Farmacia\AltoCusto\ProcessoTipo;
use App\Services\Cadastro\Material\MaterialService;
use App\Services\Service;
use App\Utils\DataUtil;
use App\Utils\MaskUtil;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
class RelatorioAltoCustoProcessoService extends Service
{
public static function index()
{
$totalizadores = (object) [
'pacientes' => 0,
'processos' => 0,
'medicamentos' => 0,
];
$processos = collect();
$periodo = [
'start' => Carbon::createFromFormat('d/m/Y', request()->periodo['start'])->setTime(0, 0, 0),
'end' => Carbon::createFromFormat('d/m/Y', request()->periodo['end'])->setTime(23, 59, 59)
];
$dispensacoes = DB::table('farmacia_alto_custo_processo_item_mes as mes')
->join(
'farmacia_alto_custo_processo_item as item',
'item.id',
'mes.item_id'
)
->join(
'cadastro_material as material',
'material.id',
'item.material_id'
)
->join(
'cadastro_apresentacao as apresentacao',
'apresentacao.id',
'material.apresentacao_id'
)
->join(
'farmacia_alto_custo_processo as processo',
'processo.id',
'item.processo_id'
)
->join(
'cadastro_centro_custo as centro_custo',
'centro_custo.id',
'processo.created_centro_custo_id'
)
->join(
'cadastro_setor as setor',
'setor.id',
'centro_custo.setor_id'
)
->join(
'cadastro_infraestrutura as infraestrutura',
'infraestrutura.id',
'centro_custo.infraestrutura_id'
)
->join(
'cadastro_unidade as unidade',
'unidade.id',
'infraestrutura.unidade_id'
)
->join(
'cadastro_paciente as paciente',
'paciente.id',
'processo.paciente_id'
)
->join(
'cadastro_cidadao as cidadao',
'cidadao.id',
'paciente.cidadao_id'
)
->join(
'farmacia_alto_custo_processo_tipo as tipo',
'tipo.id',
'processo.tipo_id'
)
->leftJoin(
'farmacia_alto_custo_processo_subtipo as subtipo',
'subtipo.id',
'processo.subtipo_id'
)
->leftJoin(
'cadastro_unidade_medida as apresentacao_unidade_medida',
'apresentacao_unidade_medida.id',
'material.apresentacao_unidade_medida_id'
)
->leftJoin(
'cadastro_unidade as unidade_referencia',
'unidade_referencia.id',
'paciente.unidade_id'
)
->leftJoin(
'cadastro_domicilio as domicilio',
'domicilio.id',
'cidadao.domicilio_id'
)
->leftJoin(
'cadastro_endereco as endereco',
'endereco.id',
'domicilio.endereco_id'
)
->leftJoin(
'cadastro_logradouro as logradouro',
'logradouro.id',
'endereco.logradouro_id'
)
->leftJoin(
'cadastro_logradouro_tipo as logradouro_tipo',
'logradouro_tipo.id',
'logradouro.tipo_id'
)
->leftJoin(
'cadastro_bairro as bairro',
'bairro.id',
'logradouro.bairro_id'
)
->leftJoin(
'intranet.cadastro_municipio as municipio',
'municipio.id',
'logradouro.municipio_id'
)
->leftJoin(
'intranet.cadastro_estado as estado',
'estado.id',
'municipio.estado_id'
)
->whereBetween('mes.enviado_drs_em', $periodo)
->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()->centro_custo_id, fn ($q, $id) => $q->where('centro_custo.id', $id))
->when(request()->tipo_id, fn ($q, $id) => $q->where('tipo.id', $id))
->when(request()->subtipo_id, fn ($q, $id) => $q->where('subtipo.id', $id))
->when(request()->paciente_id, fn ($q, $id) => $q->where('paciente.id', $id))
->select(DB::raw("
processo.id as processo_id,
unidade.nome_fantasia as unidade,
COALESCE(infraestrutura.nome, unidade.nome_fantasia) as infraestrutura,
setor.nome as setor,
paciente.id as paciente_id,
cidadao.nome as paciente_nome,
cidadao.cpf as paciente_cpf,
cidadao.cns as paciente_cns,
unidade_referencia.nome_fantasia as paciente_unidade_referencia,
CONCAT(
logradouro_tipo.descricao,
' ',
logradouro.nome,
', ',
IF(endereco.numero IS NULL, 'S/N', endereco.numero),
' - ',
bairro.nome,
', ',
municipio.nome,
' - ',
estado.uf
) as paciente_endereco,
tipo.nome as tipo,
subtipo.nome as subtipo,
material.id as material_id,
" . MaterialService::getDescricaoCompletaRaw(
'material',
'apresentacao',
'apresentacao_unidade_medida'
) . " as material_descricao,
mes.quantidade_solicitada
"));
$addSortBy = false;
if (collect(['processo.id', 'cidadao.cpf', 'cidadao.cns'])->contains(request()->sortBy)) {
$addSortBy = true;
} else {
self::setOrderBy($dispensacoes);
}
$query = $dispensacoes->get()->each(function ($data) use ($processos, $totalizadores) {
$processo = $processos->where('id', $data->processo_id)->first();
if (is_null($processo)) {
$processo = (object) [
'id' => $data->processo_id,
'unidade' => $data->unidade,
'infraestrutura' => $data->infraestrutura,
'setor' => $data->setor,
'paciente_id' => $data->paciente_id,
'paciente_nome' => $data->paciente_nome,
'paciente_cpf' => MaskUtil::getCpfMasked($data->paciente_cpf),
'paciente_cns' => MaskUtil::getCnsMasked($data->paciente_cns),
'paciente_unidade_referencia' => $data->paciente_unidade_referencia,
'paciente_endereco' => $data->paciente_endereco,
'tipo' => $data->tipo,
'subtipo' => $data->subtipo,
'materiais' => collect(),
];
$processos->push($processo);
}
$material = $processo->materiais->where('id', $data->material_id)->first();
if (is_null($material)) {
$material = (object) [
'id' => $data->material_id,
'material_descricao' => $data->material_descricao,
'quantidade_solicitada' => 0,
];
$processo->materiais->push($material);
$totalizadores->medicamentos++;
}
$material->quantidade_solicitada += $data->quantidade_solicitada;
});
$processos->each(fn ($processo) => $processo->materiais = $processo->materiais
->sortBy('material_descricao')->values());
$totalizadores->processos = $processos->count();
$totalizadores->pacientes = $processos->unique('paciente_id')->values()->count();
if ($addSortBy) {
$dispensacoes = $dispensacoes->sortBy([[
request()->sortBy,
DataUtil::getBooleanValueFromStringBoolean(request()->sortDesc) ? 'desc' : 'asc'
]])->values();
}
return compact('processos', 'totalizadores');
}
private static function setOrderBy($builder)
{
$columns = [
'paciente_nome' => 'cidadao.nome',
'paciente_cpf' => 'cidadao.cpf',
'paciente_cns' => 'cidadao.cns',
'paciente_unidade_referencia' => 'unidade_referencia.nome_fantasia',
'paciente_endereco' => 'paciente_endereco',
'unidade' => 'unidade.nome_fantasia',
'infraestrutura' => 'COALESCE(infraestrutura.nome, unidade.nome_fantasia)',
'tipo' => 'tipo.nome',
'subtipo' => 'subtipo.nome',
'setor' => 'setor.nome',
];
if (is_null(request()->sortBy)) {
$builder->orderByRaw(join(', ', $columns));
return;
}
$column = $columns[request()->sortBy];
$direction = DataUtil::getBooleanValueFromStringBoolean(request()->sortDesc) ? 'DESC' : 'ASC';
unset($columns[request()->sortBy]);
$builder->orderByRaw(
"{$column} {$direction}, " . join(', ', $columns)
);
}
public static function list()
{
$data = (object) [
'additionals' => [],
'form' => [],
'model' => [],
];
$params = self::getParams();
$sets = [
'periodo' => function () use ($data) {
$data->model['periodo'] = ['start' => null, 'end' => null];
},
'unidade' => function () use ($data, $params) {
$unidadesData = self::getUnidadesData($params);
$data->form['unidades'] = $unidadesData['form'];
$data->model['unidade_id'] = $params->unidade_id = $unidadesData['model'];
},
'infraestrutura' => function () use ($data, $params) {
$infraestruturasData = self::getInfraestruturasData($params);
$data->form['infraestruturas'] = $infraestruturasData['form'];
$data->model['infraestrutura_id'] = $params->infraestrutura_id = $infraestruturasData['model'];
},
'centro_custo' => function () use ($data, $params) {
$centrosDeCustoData = self::getCentrosDeCustoData($params);
$data->form['centros_custo'] = $centrosDeCustoData['form'];
$data->model['centro_custo_id'] = $params->centro_custo_id = $centrosDeCustoData['model'];
},
'tipo' => function () use ($data, $params) {
$tiposData = self::getTiposData($params);
$data->form['tipos'] = $tiposData['form'];
$data->model['tipo_id'] = $params->tipo_id = $tiposData['model'];
},
'subtipo' => function () use ($data, $params) {
$subtiposData = self::getSubtiposData($params);
$data->form['subtipos'] = $subtiposData['form'];
$data->model['subtipo_id'] = $params->subtipo_id = $subtiposData['model'];
},
'paciente' => function () use ($data, $params) {
$pacientesData = self::getPacientesData($params);
$data->form['pacientes'] = $pacientesData['form'];
$data->model['paciente_id'] = $params->paciente_id = $pacientesData['model'];
},
];
$load = is_null(request()->load_from);
if ($load) {
$data->additionals = [
'data_atual' => Carbon::now()->format('d/m/Y'),
];
}
foreach ($sets as $field => $set) {
if ($load) {
$set();
}
else if ($field === request()->load_from) {
$load = true;
}
}
foreach ($data as $property => $itens) {
if (empty($itens)) {
unset($data->{$property});
}
}
return $data;
}
private static function getParams()
{
$params = (object) request()->only([
'periodo',
'unidade_id',
'infraestrutura_id',
'centro_custo_id',
'tipo_id',
'subtipo_id',
'paciente_id',
]);
if (isset($params->periodo)
&& !is_null($params->periodo['start'])
&& !is_null($params->periodo['end'])
) {
$start = Carbon::createFromFormat('d/m/Y', $params->periodo['start'])->setTime(0, 0, 0);
$end = Carbon::createFromFormat('d/m/Y', $params->periodo['end'])->setTime(23, 59, 59);
$params->periodo['start'] = $start;
$params->periodo['end'] = $end;
}
else {
$params->periodo = null;
}
return $params;
}
private static function getUnidadesData($params)
{
$unidades = collect();
$id = null;
if (!is_null($params->periodo)) {
$unidades = Unidade::setEagerLoads([])
->whereHas('infraestruturas', fn ($q) => $q
->whereHas('centrosCusto', fn ($q) => self::setWhereForFilterCentroCusto($q, $params))
)
->orderBy('nome_fantasia')
->get(['id', 'nome_fantasia']);
}
return ['form' => $unidades, 'model' => $id];
}
private static function getInfraestruturasData($params)
{
$infraestruturas = collect();
$id = null;
if (!is_null($params->periodo) && !is_null($params->unidade_id)) {
$infraestruturas = Infraestrutura::setEagerLoads([])
->where('unidade_id', $params->unidade_id)
->whereHas('centrosCusto', fn ($q) => self::setWhereForFilterCentroCusto($q, $params))
->get(['id', 'nome', 'principal', 'unidade_id'])
->map(fn ($i) => [
'id' => $i->id,
'nome' => $i->nome
])
->sortBy('nome')
->values();
}
return ['form' => $infraestruturas, 'model' => $id];
}
private static function getCentrosDeCustoData($params)
{
$centrosCusto = collect();
$id = null;
if (!is_null($params->periodo) && !is_null($params->infraestrutura_id)) {
$centrosCusto = CentroCusto::setEagerLoads([])
->where('infraestrutura_id', $params->infraestrutura_id)
->where(fn ($q) => self::setWhereForFilterCentroCusto($q, $params))
->get(['id', 'setor_id'])
->map(fn ($cc) => [
'id' => $cc->id,
'setor_nome' => $cc->setor()->setEagerLoads([])->first(['nome'])->nome
])
->sortBy('setor_nome')
->values();
}
return ['form' => $centrosCusto, 'model' => $id];
}
private static function setWhereForFilterCentroCusto($query, $params)
{
return $query->whereHas('farmaciaAltoCustoProcessos', fn ($q) => $q
->whereHas('itens', fn ($q) => $q
->whereHas('meses', fn ($q) => $q
->whereBetween('enviado_drs_em', $params->periodo)
)
)
);
}
private static function getTiposData($params)
{
$tipos = collect();
$id = null;
if (!is_null($params->periodo)) {
$tipos = ProcessoTipo::setEagerLoads([])
->whereHas('processos', fn ($q) =>
self::setWhereForSelectedCentroCusto($q, $params)
->whereHas('itens', fn ($q) => $q
->whereHas('meses', fn ($q) => $q
->whereBetween('enviado_drs_em', $params->periodo)
)
)
)
->orderBy('nome')
->get(['id', 'nome']);
}
return ['form' => $tipos, 'model' => $id];
}
private static function getSubtiposData($params)
{
$tipos = collect();
$id = null;
if (!is_null($params->tipo_id)) {
$tipos = ProcessoSubtipo::setEagerLoads([])
->whereHas('processos', fn ($q) =>
self::setWhereForSelectedCentroCusto($q, $params)
->where('tipo_id', $params->tipo_id)
->whereHas('itens', fn ($q) => $q
->whereHas('meses', fn ($q) => $q
->whereBetween('enviado_drs_em', $params->periodo)
)
)
)
->orderBy('nome')
->get(['id', 'nome']);
}
return ['form' => $tipos, 'model' => $id];
}
private static function getPacientesData($params)
{
$pacientes = collect();
$id = null;
if (!is_null($params->periodo)) {
$pacientes = Paciente::setEagerLoads([])
->whereHas('farmaciaAltoCustoProcessos', fn ($q) =>
self::setWhereForSelectedCentroCusto($q, $params)
->when($params->tipo_id, fn ($q, $id) => $q->where('tipo_id', $id))
->when($params->subtipo_id, fn ($q, $id) => $q->where('subtipo_id', $id))
->whereHas('itens', fn ($q) => $q
->whereHas('meses', fn ($q) => $q
->whereBetween('enviado_drs_em', $params->periodo)
)
)
)
->get(['id', 'cidadao_id'])
->map(fn ($p) => [
'id' => $p->id,
'nome' => $p->cidadao()->setEagerLoads([])->first(['nome'])->nome
])
->sortBy('nome')
->values();
}
return ['form' => $pacientes, 'model' => $id];
}
private static function setWhereForSelectedCentroCusto($query, $params)
{
return $query->when($params->centro_custo_id,
fn ($q, $centroCustoId) => $q->where('created_centro_custo_id', $centroCustoId),
fn ($q) => $q->when(!is_null($params->infraestrutura_id) || !is_null($params->unidade_id),
fn ($q) => $q->whereHas('createdCentroCusto', fn ($q) => $q
->when($params->infraestrutura_id,
fn ($q, $infraestruturaId) => $q->where('infraestrutura_id', $infraestruturaId),
fn ($q) => $q->whereHas('infraestrutura', fn ($q) => $q
->where('unidade_id', $params->unidade_id))
)
)
)
);
}
public static function getPrintExportData()
{
$resultado = self::index();
$itens = $resultado['processos'];
$unidade = Unidade::find(request()->unidade_id);
$infraestrutura = Infraestrutura::find(request()->infraestrutura_id);
$centroCusto = CentroCusto::find(request()->centro_custo_id);
$tipo = ProcessoTipo::find(request()->tipo_id);
$subtipo = ProcessoSubtipo::find(request()->subtipo_id);
$paciente = Paciente::find(request()->paciente_id);
return [
'inicio' => request()->periodo['start'],
'fim' => request()->periodo['end'],
'unidade' => $unidade->nome_fantasia ?? 'Todas',
'infraestrutura' => $infraestrutura->nome ?? 'Todos',
'setor' => $centroCusto->setor->nome ?? 'Todos',
'tipo' => $tipo->nome ?? 'Todos',
'subtipo' => $subtipo->nome ?? 'Todos',
'paciente' => $paciente->cidadao->nome ?? 'Todos',
'colunas' => collect(request()->selectedColumns),
'itens' => $itens,
'totalizadores' => $resultado['totalizadores'],
];
}
}