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,507 @@
<?php
namespace App\Services\ProntoAtendimento\Aih;
use App\Enums\Cadastro\SujeitoAtencao\Classificacao;
use App\Enums\Cadastro\SujeitoAtencao\PreferenciaNome;
use App\Enums\Geral\DocumentoTipo as DocumentoTipoEnum;
use App\Models\Cadastro\Estabelecimento\Unidade;
use App\Models\Cadastro\Parametrizacao\ParametrizacaoPermissaoUsuario;
use App\Models\Cadastro\SujeitoAtencao\PacienteClassificacao;
use App\Models\Cadastro\SujeitoAtencao\Sexo;
use App\Models\Cns\TermoInvalido;
use App\Models\Geral\DocumentoTipo;
use App\Models\ProntoAtendimento\Aih\CaraterInternacao;
use App\Models\ProntoAtendimento\Aih\CausaExterna;
use App\Models\ProntoAtendimento\Aih\Clinica;
use App\Models\ProntoAtendimento\Aih\Internacao;
use App\Models\ProntoAtendimento\Aih\VinculoPrevidencia;
use App\Models\ProntoAtendimento\Atendimento\Faa;
use App\Services\Cadastro\SujeitoAtencao\PacienteDesconhecidoSaveService;
use App\Services\Service;
use App\Utils\DataUtil;
use App\Utils\MaskUtil;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
class AihService extends Service
{
public static function datatable()
{
$builder = DB::table('pronto_atendimento_aih_internacao AS internacao')
->join(
'cadastro_lotacao AS lotacao',
'lotacao.id',
'internacao.created_lotacao_id'
)
->join(
'cadastro_paciente AS paciente',
'paciente.id',
'internacao.paciente_id'
)
->join(
'cadastro_cidadao AS cidadao',
'cidadao.id',
'paciente.cidadao_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(
'intranet.cadastro_municipio AS municipio',
'municipio.id',
'logradouro.municipio_id'
)
->join(
'pronto_atendimento_aih_internacao_procedimento AS procedimento',
'procedimento.internacao_id',
'internacao.id'
)
->leftJoin(
'pronto_atendimento_faa AS faa',
'faa.id',
'internacao.faa_id'
)
->whereNull('internacao.deleted_at')
->where('lotacao.infraestrutura_id', self::getCurrentLotacao()->infraestrutura_id)
->select(
'internacao.id',
'procedimento.data_solicitacao',
'internacao.faa_id',
'faa.numero AS faa_numero',
'cidadao.nome AS paciente_nome',
'cidadao.nome_social AS paciente_nome_social',
'cidadao.preferencia_nome_id as paciente_preferencia_nome_id',
'cidadao.data_nascimento AS paciente_data_nascimento',
'cidadao.nome_mae AS paciente_nome_mae',
'cidadao.caracteristicas_fisicas AS paciente_caracteristicas_fisicas',
'paciente.prontuario AS paciente_prontuario',
'paciente.sequencial_desconhecido_em AS paciente_sequencial_desconhecido_em',
'municipio.nome AS municipio',
);
return datatables()
->of($builder)
->setRowData([
'paciente_prefere_nome_social' => function ($data) {
return $data->paciente_preferencia_nome_id === PreferenciaNome::NOME_SOCIAL;
},
'paciente_is_desconhecido' => function ($data) {
return !is_null($data->paciente_sequencial_desconhecido_em);
}
])
->editColumn('paciente_data_nascimento', function ($data) {
return is_null($data->paciente_data_nascimento)
? 'Não informada'
: (new Carbon($data->paciente_data_nascimento))->format('d/m/Y');
})
->editColumn('paciente_nome_mae', function ($data) {
return $data->paciente_nome_mae ?? 'Não informado';
})
->editColumn('paciente_caracteristicas_fisicas', function ($data) {
return $data->paciente_caracteristicas_fisicas ?? 'Não informado';
})
->removeColumn([
'paciente_preferencia_nome_id',
'paciente_sequencial_desconhecido_em'
])
->addColumn('impressoes', self::getImpressoes())
->filterColumn('procedimento.data_solicitacao', function ($query, $keyword) {
$query
->whereRaw("DATE_FORMAT(procedimento.data_solicitacao, '%d/%m/%Y') like ?", ["%{$keyword}%"])
->orWhereRaw(
"CONCAT(
SUBSTR(procedimento.data_solicitacao,9,2),
SUBSTR(procedimento.data_solicitacao,6,2),
SUBSTR(procedimento.data_solicitacao,1,4)
) like ?",
["%{$keyword}%"]
);
});
}
public static function index()
{
return Internacao::where(self::getWhereFromQueryString(['paciente_id', 'finalizada']))->get();
}
public static function create($pacienteId = null)
{
$internacao = new Internacao;
$internacao->paciente_id = $pacienteId;
return [
'form' => self::getFormData($internacao->paciente),
'model' => self::getModelData($internacao),
'additionals' => self::getAdditionalsData()
];
}
public static function list()
{
$lotacao = self::getCurrentLotacao();
$permissaoUsuario = ParametrizacaoPermissaoUsuario::where('usuario_id', $lotacao->usuario_id)
->where('infraestrutura_id', $lotacao->infraestrutura_id)
->first();
$countUsuario = ParametrizacaoPermissaoUsuario::count();
$classificacoes = $permissaoUsuario
? PacienteClassificacao::orderBy('descricao')
->get()
->filter(function ($classificacao) use ($permissaoUsuario) {
$exibe = false;
switch ($classificacao->id) {
case Classificacao::MUNICIPE:
$exibe = $permissaoUsuario->municipe;
break;
case Classificacao::PROVISORIO:
$exibe = $permissaoUsuario->provisorio;
break;
case Classificacao::OUTRO_MUNICIPIO:
$exibe = $permissaoUsuario->outro_municipio;
break;
}
return $exibe ? [
'id' => $classificacao->id,
'descricao' => $classificacao->descricao
] : null;
})
->values()
: [];
return [
'classificacoes' => $classificacoes,
'is_permissao_cadastro' => $countUsuario === 0 ? true : false,
];
}
public static function store()
{
AihValidator::validateSave();
$internacao = new Internacao();
DB::transaction(function () use ($internacao) {
$params = self::getParams();
self::save($internacao, $params);
});
$internacao->impressoes = self::getImpressoes();
return $internacao;
}
private static function getImpressoes()
{
return [
[
'value' => 'laudo',
'text' => 'Laudo',
'disabled' => false,
],
[
'value' => 'termoResponsabilidade',
'text' => 'Termo de responsabilidade',
'disabled' => false,
]
];
}
public static function edit($id)
{
$internacao = Internacao::findOrFail($id);
return [
'form' => self::getFormData($internacao->paciente),
'model' => self::getModelData($internacao),
'additionals' => self::getAdditionalsData()
];
}
private static function getFormData($paciente = null)
{
$identificacao = null;
$faas = [];
if ($paciente) {
$identificacao = [
'nome_paciente' => $paciente->cidadao->nome,
'nome_mae' => $paciente->cidadao->nome_mae ?? '',
'data_nascimento' => $paciente && $paciente->cidadao->data_nascimento
? $paciente->cidadao->data_nascimento->format('d/m/Y') : null,
'cpf' => $paciente && $paciente->cidadao->cpf
? MaskUtil::getCpfMasked($paciente->cidadao->cpf) : '',
'cns' => $paciente && $paciente->cidadao->cns
? MaskUtil::getCnsMasked($paciente->cidadao->cns) : '',
'idade' => [
'anos' => $paciente->cidadao->idade['anos'] ?? 'Não informada',
'meses' => $paciente->cidadao->idade['meses'] ?? 'Não informada',
'dias' => $paciente->cidadao->idade['dias'] ?? 'Não informada',
],
'sexo' => [
'id' => $paciente->cidadao->sexo->id,
'descricao' => $paciente->cidadao->sexo->descricao,
],
'nome_social' => $paciente->cidadao->nome_social,
'preferencia_nome_id' => $paciente->cidadao->preferencia_nome_id ?? null,
];
$faas = Faa::where('paciente_id', $paciente->id)
->orderByDesc('id')
->take(5)
->get()
->map(fn ($faa) => [
'id' => $faa->id,
'data' => (new Carbon($faa->atendimentos->first()->recepcao->atendido_em))->format('d/m/Y')
]);
}
return [
'paciente' => [
'identificacao' => $identificacao,
'desconhecido' => [
'sexos' => Sexo::orderBy('descricao')->get(['id', 'descricao'])
]
],
'unidades' => Unidade::orderBy('nome_fantasia')->get(['id', 'nome_fantasia']),
'unidade_internacao' => self::getCurrentCentroCusto()->infraestrutura->unidade->nome_fantasia,
'faas' => $faas,
'procedimento' => [
'clinicas' => Clinica::orderBy('nome')->get(['id', 'nome']),
'caraters_internacao' => CaraterInternacao::orderBy('nome')->get(['id', 'nome']),
'documentos' => DocumentoTipo::orderBy('nome')->whereIn('id', [
DocumentoTipoEnum::CPF, DocumentoTipoEnum::CNS
])->get(['id', 'nome']),
],
'causa_externa' => [
'causas_externas' => CausaExterna::orderBy('nome')->get(['id', 'nome'])
->prepend(['id' => null, 'nome' => 'NÃO INFORMADO']),
'vinculos_previdencia' => VinculoPrevidencia::orderBy('nome')->get(['id', 'nome'])
->prepend(['id' => null, 'nome' => 'NÃO INFORMADO']),
],
'autorizacao' => [
'documentos' => DocumentoTipo::orderBy('nome')->whereIn('id', [
DocumentoTipoEnum::CPF, DocumentoTipoEnum::CNS
])->get(['id', 'nome']),
]
];
}
private static function getModelData($internacao)
{
return [
'id' => $internacao->id,
'paciente' => [
'sexo_id' => null,
'caracteristicas_fisicas' => ''
],
'paciente_id' => $internacao->paciente_id,
'unidade_solicitante_id' => $internacao->unidade_solicitante_id,
'cid_principal' => $internacao->cidPrincipal,
'cid_secundario' => $internacao->cidSecundario,
'cid_causas_associadas' => $internacao->cidCausasAssociadas,
'faa_id' => $internacao->faa_id,
'principais_sinais_sintomas_clinicos' => $internacao->principais_sinais_sintomas_clinicos ?? '',
'condicoes_que_justificam_internacao' => $internacao->condicoes_que_justificam_internacao ?? '',
'principais_resultados_de_provas_diagnosticas' => $internacao->principais_resultados_de_provas_diagnosticas ?? '',
'procedimento' => [
'procedimento_solicitado' => $internacao->procedimento->procedimentoSolicitado ?? null,
'data_solicitacao' => $internacao->procedimento && $internacao->procedimento->data_solicitacao
? (new Carbon($internacao->procedimento->data_solicitacao))->format('d/m/Y') : null,
'clinica_id' => $internacao->procedimento->clinica_id ?? null,
'carater_internacao_id' => $internacao->procedimento->carater_internacao_id ?? null,
'profissional_solicitante_assistente' => $internacao->procedimento ? [
'id' => $internacao->procedimento->profissionalSolicitanteAssistente->id,
'cidadao_nome' => $internacao->procedimento->profissionalSolicitanteAssistente->cidadao->nome,
'cidadao_cns' => $internacao->procedimento->profissionalSolicitanteAssistente->cidadao->cns,
'cidadao_cpf' => $internacao->procedimento->profissionalSolicitanteAssistente->cidadao->cpf,
] : null,
'documento_tipo_id' => $internacao->procedimento->documento_tipo_id ?? null,
'documento_numero' => $internacao->procedimento->documento_numero ?? '',
],
'causa_externa' => [
'causa_externa_id' => $internacao->causaExterna->causa_externa_id ?? null,
'cnpj_seguradora' => $internacao->causaExterna && $internacao->causaExterna->cnpj_seguradora
? MaskUtil::getCnpjMasked($internacao->causaExterna->cnpj_seguradora) : '',
'numero_bilhete' => $internacao->causaExterna->numero_bilhete ?? '',
'serie' => $internacao->causaExterna->serie ?? '',
'cnpj_empresa' => $internacao->causaExterna && $internacao->causaExterna->cnpj_empresa
? MaskUtil::getCnpjMasked($internacao->causaExterna->cnpj_empresa) : '',
'cnae_empresa' => $internacao->causaExterna->cnae_empresa ?? '',
'cbor' => $internacao->causaExterna->cbor ?? '',
'vinculo_previdencia_id' => $internacao->causaExterna->vinculo_previdencia_id ?? null
],
'autorizacao' => [
'profissional_autorizador' => $internacao->autorizacao ? [
'id' => $internacao->autorizacao->profissionalAutorizador->id,
'cidadao_nome' => $internacao->autorizacao->profissionalAutorizador->cidadao->nome,
'cidadao_cns' => $internacao->autorizacao->profissionalAutorizador->cidadao->cns,
'cidadao_cpf' => $internacao->autorizacao->profissionalAutorizador->cidadao->cpf,
] : null,
'documento_tipo_id' => $internacao->autorizacao->documento_tipo_id ?? null,
'documento_numero' => $internacao->autorizacao->documento_numero ?? '',
'data_autorizacao' => $internacao->autorizacao && $internacao->autorizacao->data_autorizacao
? (new Carbon($internacao->autorizacao->data_autorizacao))->format('d/m/Y') : null,
'codigo_orgao_emissor' => $internacao->autorizacao->codigo_orgao_emissor ?? ''
],
'finalizada' => $internacao->finalizada ?? false
];
}
private static function getAdditionalsData()
{
return [
'data_atual' => Carbon::now()->format('d/m/Y'),
'termos_invalidos' => TermoInvalido::pluck('descricao'),
];
}
public static function update($id)
{
AihValidator::validateSave();
$internacao = Internacao::findOrFail($id);
DB::transaction(function () use ($internacao) {
$params = self::getParams();
self::save($internacao, $params);
});
return $internacao;
}
private static function getParams()
{
$params = request()->except(['procedimento', 'causa_externa', 'autorizacao']);
$params['paciente'] = isset($params['paciente_id']) ? null : self::getParamsPaciente();
$params['unidade_internacao_id'] = self::getCurrentCentroCusto()->infraestrutura->unidade_id;
$params['procedimento'] = self::getParamsProcedimento();
$params['causa_externa'] = self::getParamsCausaExterna();
$params['autorizacao'] = self::getParamsAutorizacao();
return $params;
}
private static function getParamsPaciente()
{
return request()->get('paciente');
}
private static function getParamsProcedimento()
{
$params = request()->get('procedimento');
if (!DataUtil::hasData($params)) {
return null;
}
if (isset($params['data_solicitacao'])) {
$params['data_solicitacao'] = Carbon::createFromFormat('d/m/Y', $params['data_solicitacao']);
}
return $params;
}
private static function getParamsCausaExterna()
{
$params = request()->get('causa_externa');
if (!DataUtil::hasData($params)) {
return null;
}
return $params;
}
private static function getParamsAutorizacao()
{
$params = request()->get('autorizacao');
if (!DataUtil::hasData($params) || !isset($params['profissional_autorizador_id'])) {
return null;
}
if (isset($params['data_autorizacao'])) {
$params['data_autorizacao'] = Carbon::createFromFormat('d/m/Y', $params['data_autorizacao']);
}
return $params;
}
private static function save($internacao, $params)
{
$internacao->fill($params);
self::savePaciente($internacao, $params['paciente']);
$internacao->save();
self::saveChild($internacao, 'procedimento', $params['procedimento']);
self::saveChild($internacao, 'causaExterna', $params['causa_externa']);
self::saveChild($internacao, 'autorizacao', $params['autorizacao']);
}
private static function savePaciente($internacao, $params)
{
if (is_null($params)) {
return;
}
$internacao->paciente_id = (new PacienteDesconhecidoSaveService(
Carbon::now()->format('Y-m-d H:i:s'),
$params['sexo_id'],
$params['caracteristicas_fisicas']
))->save()->id;
}
private static function saveChild($internacao, $relationName, $params)
{
if (is_null($params)) {
if ($internacao->{$relationName}) {
$internacao->{$relationName}->delete();
}
}
else {
$internacao->{$relationName}()->updateOrCreate(['internacao_id' => $internacao->id], $params);
}
}
}

View File

@@ -0,0 +1,224 @@
<?php
namespace App\Services\ProntoAtendimento\Aih;
use App\Enums\Geral\DocumentoTipo;
use App\Models\ProntoAtendimento\Atendimento\Faa;
use App\Rules\Cnpj;
use App\Rules\Cns;
use App\Rules\CnsTermoValido;
use App\Rules\Cpf;
use App\Rules\NomeCompleto;
use Illuminate\Validation\Rule;
class AihValidator
{
public static function validateSave()
{
$rules = [
'paciente_id' => [
'nullable',
'integer'
],
'unidade_solicitante_id' => [
'required',
'integer'
],
'cid_principal_id' => [
'required',
'integer'
],
'cid_secundario_id' => [
'nullable',
'integer'
],
'cid_causas_associadas_id' => [
'nullable',
'integer'
],
'faa_id' => [
'bail',
'nullable',
'integer',
function ($attribute, $value, $fail) {
$faa = Faa::find($value);
if ($faa && $faa->paciente_id != request()->paciente_id) {
$fail('FAA não vinculada ao paciente.');
}
}
],
'principais_sinais_sintomas_clinicos' => [
'required',
'string',
'max:1000'
],
'condicoes_que_justificam_internacao' => [
'required',
'string',
'max:1000'
],
'principais_resultados_de_provas_diagnosticas' => [
'required',
'string',
'max:1000'
],
'finalizada' => [
'required',
'boolean'
]
];
return request()->validate(array_merge(
$rules,
self::getPacienteValidations(),
self::getProcedimentoValidations(),
self::getCausaExternaValidations(),
self::getAutorizacaoValidations()
));
}
private static function getPacienteValidations()
{
return [
'paciente.sexo_id' => [
'nullable',
'required_without:paciente_id',
'integer'
],
'paciente.caracteristicas_fisicas' => [
'nullable',
'required_without:paciente_id',
'string',
'max:500'
],
];
}
private static function getProcedimentoValidations()
{
return [
'procedimento.procedimento_solicitado_id' => [
'bail',
'required',
'integer',
],
'procedimento.data_solicitacao' => [
'required',
'date_format:d/m/Y',
'before_or_equal:now'
],
'procedimento.clinica_id' => [
'required',
'integer'
],
'procedimento.carater_internacao_id' => [
'required',
'integer'
],
'procedimento.profissional_solicitante_assistente_id' => [
'required',
'integer'
],
'procedimento.documento_tipo_id' => [
'required',
'integer'
],
'procedimento.documento_numero' => [
'required',
self::getDocumentoNumeroValidation(request()->documento_tipo_id)
],
];
}
private static function getCausaExternaValidations()
{
return [
'causa_externa.causa_externa_id' => [
'nullable',
'integer'
],
'causa_externa.cnpj_seguradora' => [
'nullable',
new Cnpj
],
'causa_externa.numero_bilhete' => [
'nullable',
'string',
'max:10'
],
'causa_externa.serie' => [
'nullable',
'string',
'max:6'
],
'causa_externa.cnpj_empresa' => [
'nullable',
new Cnpj
],
'causa_externa.cnae_empresa' => [
'nullable',
'string',
'max:10'
],
'causa_externa.cbor' => [
'nullable',
'string',
'max:3'
],
'causa_externa.vinculo_previdencia_id' => [
'nullable',
'integer'
],
];
}
private static function getAutorizacaoValidations()
{
return [
'autorizacao.profissional_autorizador_id' => [
'nullable',
'integer'
],
'autorizacao.documento_tipo_id' => [
'nullable',
'integer'
],
'autorizacao.documento_numero' => [
'nullable',
self::getDocumentoNumeroValidation(request()->documento_tipo_id)
],
'autorizacao.data_autorizacao' => [
'nullable',
'date_format:d/m/Y',
'before_or_equal:now'
],
'autorizacao.codigo_orgao_emissor' => [
'nullable',
'string',
'max:6'
],
];
}
private static function getDocumentoNumeroValidation($documentoTipoId)
{
switch ($documentoTipoId) {
case DocumentoTipo::CPF: {
return new Cpf;
}
case DocumentoTipo::CNS: {
return new Cns;
}
default: {
return null;
}
}
}
}