Files
rkm-conectasus-ci-sandbox/api/app/Services/Raas/ExportacaoService.php
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

1052 lines
47 KiB
PHP

<?php
namespace App\Services\Raas;
use App\Enums\Cadastro\SujeitoAtencao\RacaCor;
use App\Enums\Cadastro\SujeitoAtencao\Sexo;
use App\Enums\Raas\Inconsistencia;
use App\Enums\Raas\Linha;
use App\Enums\Raas\OrigemInformacao;
use App\Enums\Raas\RacaCor as RaasRacaCor;
use App\Enums\Raas\Sexo as RaasSexo;
use App\Enums\Raas\TipoDroga;
use App\Enums\Sigtap\Classificacao;
use App\Enums\Sigtap\Servico;
use App\Models\Cadastro\Estabelecimento\Unidade;
use App\Models\Intranet\Cliente;
use App\Models\Raas\Atendimento;
use App\Models\Raas\AtendimentoProcedimento;
use App\Models\Raas\Exportacao;
use App\Models\Raas\ExportacaoFinanciamento;
use App\Rules\Cep;
use App\Rules\Cnes;
use App\Rules\Cns;
use App\Rules\Cpf;
use App\Rules\IbgeEstado;
use App\Rules\IbgeMunicipio;
use App\Rules\Raas\ExportacaoContainsFinanciamento;
use App\Rules\Sigtap\ClassificacaoIsValidForProcedimento;
use App\Rules\Sigtap\ClassificacaoIsValidForServico;
use App\Rules\Sigtap\CompetenciaIsValid;
use App\Rules\Sigtap\FinanciamentoIsValidForCompetencia;
use App\Rules\Sigtap\ProcedimentoIsValidForCompetencia;
use App\Rules\Sigtap\ProcedimentoIsValidForIdade;
use App\Rules\Sigtap\ProcedimentoIsValidForOcupacao;
use App\Rules\Sigtap\ProcedimentoIsValidForSexo;
use App\Rules\Sigtap\QuantidadeIsValidForProcedimento;
use App\Rules\Telefone;
use App\Services\Geral\AgeService;
use App\Services\Service;
use Carbon\Carbon;
use Exception;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Illuminate\Validation\Rule;
class ExportacaoService extends Service
{
private const EMPTY = '';
private const SPACE_CHAR = ' ';
private static $caminho = 'faturamento' . DIRECTORY_SEPARATOR . 'raas' . DIRECTORY_SEPARATOR;
public static function datatable()
{
return DB::table('raas_exportacao as exportacao')
->join('cadastro_unidade as unidade', 'unidade.id', 'exportacao.unidade_id')
->join('sigtap.competencia as competencia', 'competencia.id', 'exportacao.competencia_id')
->selectRaw("
exportacao.id,
DATE_FORMAT(exportacao.created_at, '%d/%m/%Y às %H:%i') as data_hora_exportacao,
unidade.nome_fantasia as unidade,
competencia.valor as competencia,
(
SELECT GROUP_CONCAT(financiamento.nome SEPARATOR ', ')
FROM raas_exportacao_financiamento as exportacao_financiamento
INNER JOIN sigtap.financiamento as financiamento
ON financiamento.id = exportacao_financiamento.financiamento_id
WHERE exportacao_financiamento.exportacao_id = exportacao.id
) AS financiamentos,
exportacao.encaminhado
");
}
public static function create()
{
return [
'form' => self::getFormData(),
'model' => self::getModelData(),
];
}
private static function getFormData()
{
return [
'unidades' => self::getUnidades(),
'competencias' => self::getCompetencias(),
'financiamentos' => [],
];
}
private static function getUnidades()
{
return DB::table('cadastro_unidade as unidade')
->whereNull('unidade.deleted_at')
->whereNotNull('unidade.cnes')
->whereRaw("TRIM(unidade.cnes) <> ''")
->whereExists(fn ($q) => $q
->selectRaw(1)
->from('raas_atendimento as atendimento')
->whereColumn('atendimento.unidade_id', 'unidade.id')
)
->orderBy('unidade.nome_fantasia')
->selectRaw("
unidade.id,
unidade.nome_fantasia
")
->get();
}
private static function getCompetencias($ateId = null)
{
return DB::table('sigtap.competencia as competencia')
->when($ateId, fn ($q, $id) => $q->where('competencia.id', '<=', $id))
->selectRaw("
competencia.id,
competencia.valor
")
->orderByDesc('competencia.valor')
->take(4)
->get();
}
private static function getModelData()
{
return [
'unidade_id' => null,
'competencia_id' => null,
'financiamentos' => [],
];
}
public static function store()
{
self::validate();
$response = [
'consistencias' => 0,
'inconsistencias' => 0,
];
DB::beginTransaction();
$exportacao = Exportacao::create(request()->only(['unidade_id', 'competencia_id']));
try {
foreach (request()->financiamentos as $financiamentoId) {
ExportacaoFinanciamento::create([
'exportacao_id' => $exportacao->id,
'financiamento_id' => $financiamentoId,
]);
}
$arquivo = self::getArquivo($exportacao, [
'unidade_id' => request()->unidade_id,
'competencia_id' => request()->competencia_id,
'financiamentos' => request()->financiamentos,
]);
$exportacao->update(['arquivo' => $arquivo['nome']]);
Storage::disk('local')->put(self::$caminho . DIRECTORY_SEPARATOR . app('config')->get('database.default') . DIRECTORY_SEPARATOR . $arquivo['nome'], $arquivo['conteudo']);
$response['consistencias'] = $arquivo['consistencias'];
$response['inconsistencias'] = $arquivo['inconsistencias'];
DB::commit();
}
catch (Exception $error) {
if (Storage::disk('local')->exists(self::$caminho . DIRECTORY_SEPARATOR . app('config')->get('database.default') . DIRECTORY_SEPARATOR . $exportacao->arquivo)) {
Storage::disk('local')->delete(self::$caminho . DIRECTORY_SEPARATOR . app('config')->get('database.default') . DIRECTORY_SEPARATOR . $exportacao->arquivo);
}
DB::rollBack();
throw $error;
}
return $response;
}
private static function validate()
{
return request()->validate([
'unidade_id' => [
'required',
'integer',
Rule::exists(Unidade::class, 'id'),
],
'competencia_id' => [
'required',
'integer',
new CompetenciaIsValid(),
],
'financiamentos' => [
'required',
'array',
'distinct',
new FinanciamentoIsValidForCompetencia(request()->competencia_id),
new ExportacaoContainsFinanciamento(request()->unidade_id, request()->competencia_id),
],
]);
}
private static function getArquivo($exportacao, $params)
{
$competencia = DB::table('sigtap.competencia')
->where('id', $params['competencia_id'])
->select('id', 'valor')
->first();
$nome = 'AA' . Carbon::now()->format('dmYhis') . '.'
. Str::upper(Carbon::createFromFormat('Ymd', "{$competencia->valor}01")->translatedFormat('M'));
$atendimentos = self::consistir($exportacao, self::getAtendimentos($params));
$conteudo = self::getLinhaCabecalho(
self::getDadosCabecalho($competencia, $atendimentos['consistentes'])
);
$agrupados = [];
foreach ($atendimentos['consistentes'] as $atendimento) {
$cns = $atendimento->paciente_cns ?? null;
$data = $atendimento->data_admissao ?? null;
$cnes = $atendimento->unidade_cnes ?? null;
if (!$cns || !$data || !$cnes) {
continue;
}
$chave = $cns . '_' . Carbon::parse($data)->format('Y-m-d') . '_' . $cnes;
if (!isset($agrupados[$chave])) {
$agrupados[$chave] = [
'corpo' => self::getLinhaCorpo($atendimento),
'procedimentos' => [],
];
}
foreach ($atendimento->procedimentos as $procedimento) {
$agrupados[$chave]['procedimentos'][] = self::getLinhaProcedimento($procedimento);
}
}
foreach ($agrupados as $registro) {
$conteudo .= $registro['corpo'];
$conteudo .= implode('', $registro['procedimentos']);
}
return [
'nome' => $nome,
'conteudo' => $conteudo,
'consistencias' => $atendimentos['consistentes']->count(),
'inconsistencias' => $atendimentos['inconsistentes']->count(),
];
}
private static function getAtendimentos($params)
{
$atendimentos = collect();
self::getCompetencias($params['competencia_id'])->each(function ($competencia) use ($atendimentos, $params) {
$financiamentosIds = self::getFinanciamentos($competencia->id, $params['financiamentos']);
$servicoPadrao = self::getServicoPadrao($competencia->id);
$classificacaoPadrao = $servicoPadrao->map(function ($servico) {
return self::getClassificacaoPadrao($servico->id);
});
DB::table('raas_atendimento as atendimento')
->join('sigtap.competencia as competencia', 'competencia.id', 'atendimento.competencia_id')
->join('cadastro_unidade as unidade', 'unidade.id', 'atendimento.unidade_id')
->join('cadastro_infraestrutura as infraestrutura', fn ($j) => $j
->on('infraestrutura.unidade_id', 'unidade.id')
->where('infraestrutura.id', '=', fn ($q) => $q
->select('infraestrutura_sub.id')
->from('cadastro_infraestrutura as infraestrutura_sub')
->whereColumn('infraestrutura_sub.unidade_id', 'unidade.id')
->limit(1)
)
)
->join('cadastro_endereco as infraestrutura_endereco', 'infraestrutura_endereco.id', 'infraestrutura.endereco_id')
->join('cadastro_logradouro as infraestrutura_logradouro', 'infraestrutura_logradouro.id', 'infraestrutura_endereco.logradouro_id')
->join('intranet.cadastro_municipio as infraestrutura_municipio', 'infraestrutura_municipio.id', 'infraestrutura_logradouro.municipio_id')
->join('cadastro_paciente as paciente', 'paciente.id', 'atendimento.paciente_id')
->join('cadastro_cidadao as paciente_cidadao', 'paciente_cidadao.id', 'paciente.cidadao_id')
->join('raas_motivo_saida_permanencia as motivo_saida_permanencia', 'motivo_saida_permanencia.id', 'atendimento.motivo_saida_permanencia_id')
->join('raas_origem_paciente as origem_paciente', 'origem_paciente.id', 'atendimento.origem_paciente_id')
->join('raas_destino_paciente as destino_paciente', 'destino_paciente.id', 'atendimento.destino_paciente_id')
->leftJoin('cadastro_domicilio as domicilio', 'domicilio.id', 'paciente_cidadao.domicilio_id')
->leftJoin('cadastro_endereco as paciente_endereco', 'paciente_endereco.id', 'domicilio.endereco_id')
->leftJoin('cadastro_logradouro as paciente_logradouro', 'paciente_logradouro.id', 'paciente_endereco.logradouro_id')
->leftJoin('cadastro_logradouro_tipo as paciente_logradouro_tipo', 'paciente_logradouro_tipo.id', 'paciente_logradouro.tipo_id')
->leftJoin('intranet.cadastro_municipio as paciente_municipio', 'paciente_municipio.id', 'paciente_logradouro.municipio_id')
->leftJoin('intranet.cadastro_pais as paciente_pais_nascimento', 'paciente_pais_nascimento.id', 'paciente_cidadao.pais_nascimento_id')
->leftJoin('cadastro_bairro as paciente_bairro', 'paciente_bairro.id', 'paciente_logradouro.bairro_id')
->leftJoin('cadastro_etnia_indigena as paciente_etnia_indigena', 'paciente_etnia_indigena.id', 'paciente_cidadao.etnia_indigena_id')
->leftJoin('cadastro_cidadao_telefone as paciente_cidadao_telefone', fn ($j) => $j
->on('paciente_cidadao_telefone.cidadao_id', 'paciente_cidadao.id')
->where('paciente_cidadao_telefone.id', '=', fn ($q) => $q
->select('paciente_cidadao_telefone_sub.id')
->from('cadastro_cidadao_telefone as paciente_cidadao_telefone_sub')
->whereColumn('paciente_cidadao_telefone_sub.cidadao_id', 'paciente_cidadao.id')
->where('paciente_cidadao_telefone_sub.principal', true)
->limit(1)
)
)
->leftJoin('sigtap.cid as cid_principal', 'cid_principal.id', 'atendimento.cid_principal_id')
->leftJoin('sigtap.cid as cid_secundario_1', 'cid_secundario_1.id', 'atendimento.cid_secundario_1_id')
->leftJoin('sigtap.cid as cid_secundario_2', 'cid_secundario_2.id', 'atendimento.cid_secundario_2_id')
->leftJoin('sigtap.cid as cid_secundario_3', 'cid_secundario_3.id', 'atendimento.cid_secundario_3_id')
->leftJoin('sigtap.cid as cid_causa_associada', 'cid_causa_associada.id', 'atendimento.cid_causa_associada_id')
->leftJoin('raas_carater_atendimento as carater_atendimento', 'carater_atendimento.id', 'atendimento.carater_atendimento_id')
->leftJoin('cadastro_unidade as unidade_cobertura_esf', 'unidade_cobertura_esf.id', 'atendimento.unidade_cobertura_estrategia_familia_id')
->leftJoin('atencao_basica_cadastro_individual as cadastro_individual', 'cadastro_individual.paciente_id', 'paciente.id')
->where('atendimento.unidade_id', $params['unidade_id'])
->where('atendimento.competencia_id', $competencia->id)
->whereNull('atendimento.exportacao_id')
->whereExists(fn ($q) => $q
->selectRaw(1)
->from('raas_atendimento_procedimento as atendimento_procedimento')
->join('sigtap.procedimento as procedimento', 'procedimento.id', 'atendimento_procedimento.procedimento_id')
->whereColumn('atendimento_procedimento.atendimento_id', 'atendimento.id')
->whereIn('procedimento.financiamento_id', $financiamentosIds)
)
->selectRaw("
atendimento.id,
competencia.id as competencia_id,
competencia.valor as competencia_valor,
SUBSTR(infraestrutura_municipio.ibge, 1, 2) as estado_ibge,
unidade.cnes as unidade_cnes,
paciente_cidadao.cns as paciente_cns,
DATE_FORMAT(atendimento.data_admissao, '%Y%m%d') as data_admissao,
DATE_FORMAT(atendimento.data_conclusao, '%Y%m%d') as data_conclusao,
paciente_cidadao.nome as paciente_nome,
paciente.prontuario as paciente_prontuario,
paciente_cidadao.nome_mae as paciente_nome_mae,
paciente_logradouro.nome as paciente_logradouro_nome,
paciente_logradouro_tipo.codigo as paciente_logradouro_codigo,
paciente_endereco.numero as paciente_endereco_numero,
paciente_endereco.complemento as paciente_endereco_complemento,
paciente_logradouro.cep as paciente_logradouro_cep,
paciente_municipio.ibge as paciente_municipio_residencia_ibge,
DATE_FORMAT(paciente_cidadao.data_nascimento, '%Y%m%d') as paciente_data_nascimento,
TIMESTAMPDIFF(YEAR, paciente_cidadao.data_nascimento, NOW()) AS paciente_idade,
paciente_cidadao.sexo_id as paciente_sexo_id,
paciente_cidadao.raca_cor_id as paciente_raca_cor_id,
paciente_pais_nascimento.codigo as paciente_pais_nascimento_codigo,
paciente_etnia_indigena.codigo_cadsus as paciente_etnia_indigena_codigo,
paciente_cidadao_telefone.numero as paciente_telefone,
motivo_saida_permanencia.codigo as motivo_saida_permanencia_codigo,
DATE_FORMAT(atendimento.data_ocorrencia, '%Y%m%d') as data_ocorrencia,
cid_principal.codigo as cid_principal_codigo,
cid_secundario_1.codigo as cid_secundario_1_codigo,
cid_secundario_2.codigo as cid_secundario_2_codigo,
cid_secundario_3.codigo as cid_secundario_3_codigo,
cid_causa_associada.codigo as cid_causa_associada_codigo,
carater_atendimento.codigo as carater_atendimento_codigo,
origem_paciente.codigo as origem_paciente_codigo,
IF(atendimento.cobertura_estrategia_saude_familia = 1, 'S', 'N') as cobertura_estrategia_saude_familia,
unidade_cobertura_esf.cnes as unidade_cobertura_estrategia_saude_familia_cnes,
destino_paciente.codigo as destino_paciente_codigo,
IF(cadastro_individual.situacao_rua_id IS NOT NULL, 'S', 'N') as paciente_situacao_rua,
IF(cadastro_individual.usa_alcool = 1 OR cadastro_individual.outras_drogas = 1, 'S', 'N') as paciente_usuario_droga,
cadastro_individual.usa_alcool as paciente_usa_alcool,
cadastro_individual.outras_drogas as paciente_outras_drogas,
atendimento.numero_autorizacao as numero_autorizacao,
paciente_bairro.nome as paciente_bairro_nome,
paciente.email as paciente_email,
paciente_cidadao.cpf as paciente_cpf
")
->get()
->each(function ($atendimento) use ($atendimentos, $financiamentosIds, $servicoPadrao, $classificacaoPadrao) {
self::setPacienteSexoIdentificador($atendimento);
self::setPacienteRacaCorCodigo($atendimento);
self::setPacienteNomeResponsavel($atendimento);
self::setPacienteTipoDroga($atendimento);
$atendimento->paciente_celular = null;
$atendimento->quantidade_procedimentos = null;
$atendimento->procedimentos = self::getAtendimentoProcedimentos($atendimento, [
'financiamentos_ids' => $financiamentosIds,
'servico_padrao' => $servicoPadrao,
'classificacao_padrao' => $classificacaoPadrao,
]);
$atendimento->quantidade_procedimentos = $atendimento->procedimentos->count();
unset(
$atendimento->paciente_sexo_id,
$atendimento->paciente_raca_cor_id,
$atendimento->paciente_usa_alcool,
$atendimento->paciente_outras_drogas
);
$atendimentos->push($atendimento);
});
});
return $atendimentos;
}
private static function getServicoPadrao($competenciaId)
{
$competenciasIds = DB::table('sigtap.competencia')
->where('id', '<=', $competenciaId)
->orderByDesc('id')
->limit(3)
->pluck('id');
return DB::table('sigtap.servico as servico')
->whereIn('servico.competencia_id', $competenciasIds)
->where('servico.codigo', Servico::SERVICO_DE_ATENCAO_PSICOSSOCIAL)
->select('id', 'codigo', 'competencia_id')
->orderByDesc('servico.id')
->limit(3)
->get();
}
private static function getClassificacaoPadrao($servicoId)
{
return DB::table('sigtap.classificacao as classificacao')
->where('classificacao.servico_id', $servicoId)
->where('classificacao.codigo', Classificacao::ATENDIMENTO_PSICOSSOCIAL)
->select('id', 'codigo')
->orderByDesc('classificacao.id')
->limit(3)
->get();
}
private static function getFinanciamentos($competenciaId, $financiamentosIds)
{
$financiamentoCodigos = DB::table('sigtap.financiamento')
->whereIn('id', $financiamentosIds)
->pluck('codigo');
return DB::table('sigtap.financiamento')
->whereIn('competencia_id', self::getCompetencias($competenciaId)->pluck('id'))
->whereIn('codigo', $financiamentoCodigos)
->select('id')
->pluck('id');
}
private static function setPacienteSexoIdentificador($atendimento)
{
if ($atendimento->paciente_sexo_id === Sexo::MASCULINO) {
$atendimento->paciente_sexo_identificador = RaasSexo::MASCULINO;
}
else if ($atendimento->paciente_sexo_id === Sexo::FEMININO) {
$atendimento->paciente_sexo_identificador = RaasSexo::FEMININO;
}
else {
$atendimento->paciente_sexo_identificador = null;
}
}
private static function setPacienteRacaCorCodigo($atendimento)
{
if ($atendimento->paciente_raca_cor_id === RacaCor::AMARELA) {
$atendimento->paciente_raca_cor_codigo = RaasRacaCor::AMARELA;
}
else if ($atendimento->paciente_raca_cor_id === RacaCor::BRANCA) {
$atendimento->paciente_raca_cor_codigo = RaasRacaCor::BRANCA;
}
else if ($atendimento->paciente_raca_cor_id === RacaCor::INDIGENA) {
$atendimento->paciente_raca_cor_codigo = RaasRacaCor::INDIGENA;
}
else if ($atendimento->paciente_raca_cor_id === RacaCor::NEGRA) {
$atendimento->paciente_raca_cor_codigo = RaasRacaCor::PRETA;
}
else if ($atendimento->paciente_raca_cor_id === RacaCor::PARDA) {
$atendimento->paciente_raca_cor_codigo = RaasRacaCor::PARDA;
}
else {
$atendimento->paciente_raca_cor_codigo = null;
}
}
private static function setPacienteTipoDroga($atendimento)
{
$atendimento->paciente_tipo_droga = '';
if ($atendimento->paciente_usa_alcool) {
$atendimento->paciente_tipo_droga .= TipoDroga::ALCOOL;
}
if ($atendimento->paciente_outras_drogas) {
$atendimento->paciente_tipo_droga .= TipoDroga::OUTROS;
}
}
private static function setPacienteNomeResponsavel($atendimento)
{
if (isset($atendimento->paciente_data_nascimento)) {
$dataNascimento = Carbon::createFromFormat('Ymd', $atendimento->paciente_data_nascimento);
if (AgeService::getAge($dataNascimento->toDate())->years < 18) {
$atendimento->paciente_nome_responsavel = $atendimento->paciente_nome_mae;
}
else {
$atendimento->paciente_nome_responsavel = $atendimento->paciente_nome;
}
}
else {
$atendimento->paciente_nome_responsavel = null;
}
}
private static function getAtendimentoProcedimentos($atendimento, $params)
{
$atendimentoProcedimentos = DB::table('raas_atendimento_procedimento as atendimento_procedimento')
->join('sigtap.procedimento as procedimento', 'procedimento.id', 'atendimento_procedimento.procedimento_id')
->join('sigtap.ocupacao as ocupacao', 'ocupacao.id', 'atendimento_procedimento.ocupacao_id')
->join('cadastro_usuario as usuario', 'usuario.id', 'atendimento_procedimento.usuario_id')
->join('cadastro_cidadao as usuario_cidadao', 'usuario_cidadao.id', 'usuario.cidadao_id')
->join('raas_local_realizacao_exame as local_realizacao_exame', 'local_realizacao_exame.id', 'atendimento_procedimento.local_realizacao_exame_id')
->leftJoin('sigtap.servico as servico', 'servico.id', 'atendimento_procedimento.servico_id')
->leftJoin('sigtap.classificacao as classificacao', 'classificacao.id', 'atendimento_procedimento.classificacao_id')
->where('atendimento_procedimento.atendimento_id', $atendimento->id)
->whereIn('procedimento.financiamento_id', $params['financiamentos_ids'])
->selectRaw("
atendimento_procedimento.id,
procedimento.id as procedimento_id,
procedimento.codigo as procedimento_codigo,
ocupacao.id as ocupacao_id,
ocupacao.codigo as ocupacao_codigo,
usuario_cidadao.cns as usuario_cns,
DATE_FORMAT(atendimento_procedimento.data_execucao, '%Y%m%d') as data_execucao,
servico.id as servico_id,
servico.codigo as servico_codigo,
classificacao.id as classificacao_id,
classificacao.codigo as classificacao_codigo,
atendimento_procedimento.quantidade as quantidade,
local_realizacao_exame.identificador as local_realizacao_identificador
")
->get();
$atendimentoProcedimentos->each(function ($atendimentoProcedimento) use ($atendimento, $params) {
if (is_null($atendimentoProcedimento->servico_id)) {
$atendimentoProcedimento->servico_id = $params['servico_padrao'];
$atendimentoProcedimento->servico_codigo = $params['servico_padrao'];
}
if (is_null($atendimentoProcedimento->classificacao_id)) {
$atendimentoProcedimento->classificacao_id = $params['classificacao_padrao'];
$atendimentoProcedimento->classificacao_codigo = $params['classificacao_padrao'];
}
$atendimentoProcedimento->estado_ibge = $atendimento->estado_ibge;
$atendimentoProcedimento->competencia_valor = $atendimento->competencia_valor;
$atendimentoProcedimento->unidade_cnes = $atendimento->unidade_cnes;
$atendimentoProcedimento->paciente_cns = $atendimento->paciente_cns;
$atendimentoProcedimento->data_admissao = $atendimento->data_admissao;
$atendimentoProcedimento->paciente_cpf = $atendimento->paciente_cpf;
});
return $atendimentoProcedimentos;
}
private static function consistir($exportacao, $atendimentos)
{
$consistentes = collect();
$inconsistentes = collect();
$atendimentos->each(function ($atendimento) use ($exportacao, $consistentes, $inconsistentes) {
$competencias = self::getCompetencias($atendimento->competencia_id);
$consistente = true;
$inconsistenciasIds = collect();
if (!CompetenciaIsValid::isValid($atendimento->competencia_id)) {
$consistente = false;
$inconsistenciasIds->push(Inconsistencia::COMPENTENCIA_INVALIDA);
}
if (!IbgeEstado::isValid($atendimento->estado_ibge)) {
$consistente = false;
$inconsistenciasIds->push(Inconsistencia::IBGE_DO_ESTADO_DA_UNIDADE_INVALIDO);
}
if (!Cnes::isValid($atendimento->unidade_cnes)) {
$consistente = false;
$inconsistenciasIds->push(Inconsistencia::CNES_DA_UNIDADE_INVALIDO);
}
if (!is_null($atendimento->paciente_cns) && !Cns::isValid($atendimento->paciente_cns)) {
$consistente = false;
$inconsistenciasIds->push(Inconsistencia::CNS_DO_PACIENTE_INVALIDO);
}
if (is_null($atendimento->paciente_nome_mae)) {
$consistente = false;
$inconsistenciasIds->push(Inconsistencia::NOME_DA_MAE_E_OBRIGATORIO);
}
if (!Cep::isValid($atendimento->paciente_logradouro_cep)) {
$consistente = false;
$inconsistenciasIds->push(Inconsistencia::CEP_DO_PACIENTE_INVALIDO);
}
if (!IbgeMunicipio::isValid($atendimento->paciente_municipio_residencia_ibge)) {
$consistente = false;
$inconsistenciasIds->push(Inconsistencia::IBGE_DO_MUNICIPIO_DE_RESIDENCIA_INVALIDO);
}
if (is_null($atendimento->paciente_data_nascimento)) {
$consistente = false;
$inconsistenciasIds->push(Inconsistencia::DATA_DE_NASCIMENTO_E_OBRIGATORIA);
}
if (is_null($atendimento->paciente_sexo_identificador)) {
$consistente = false;
$inconsistenciasIds->push(Inconsistencia::SEXO_E_OBRIGATORIO);
}
if (is_null($atendimento->paciente_raca_cor_codigo)) {
$consistente = false;
$inconsistenciasIds->push(Inconsistencia::RACA_COR_E_OBRIGATORIO);
}
if (is_null($atendimento->paciente_pais_nascimento_codigo)) {
$consistente = false;
$inconsistenciasIds->push(Inconsistencia::PAIS_DE_NASCIMENTO_E_OBRIGATORIO);
}
if ($atendimento->paciente_raca_cor_codigo === RaasRacaCor::INDIGENA
&& is_null($atendimento->paciente_etnia_indigena_codigo)
) {
$consistente = false;
$inconsistenciasIds->push(Inconsistencia::ETNIA_INDIGENA_E_OBRIGATORIA);
}
if (is_null($atendimento->paciente_telefone)) {
$consistente = false;
$inconsistenciasIds->push(Inconsistencia::TELEFONE_DO_PACIENTE_OBRIGATORIO);
}
if (!Telefone::isValid($atendimento->paciente_telefone)) {
$consistente = false;
$inconsistenciasIds->push(Inconsistencia::TELEFONE_DO_PACIENTE_INVALIDO);
}
if (!is_null($atendimento->paciente_celular)
&& !Telefone::isValid($atendimento->paciente_celular)
) {
$consistente = false;
$inconsistenciasIds->push(Inconsistencia::CELULAR_DO_PACIENTE_INVALIDO);
}
if (is_null($atendimento->cid_principal_codigo)) {
$consistente = false;
$inconsistenciasIds->push(Inconsistencia::CID_PRINCIPAL_E_OBRIGATORIO);
}
if ($atendimento->cobertura_estrategia_saude_familia === 'S'
&& !Cnes::isValid($atendimento->unidade_cobertura_estrategia_saude_familia_cnes)
) {
$consistente = false;
$inconsistenciasIds->push(Inconsistencia::CNES_DA_UNIDADE_DE_COBERTURA_DE_ESTRATEGIA_DA_FAMILIA_INVALIDO);
}
if (!is_null($atendimento->paciente_cpf) && !Cpf::isValid($atendimento->paciente_cpf)) {
$consistente = false;
$inconsistenciasIds->push(Inconsistencia::CPF_DO_PACIENTE_INVALIDO);
}
if ($inconsistenciasIds->isNotEmpty()) {
Atendimento::findOrFail($atendimento->id)->inconsistencias()->sync($inconsistenciasIds);
}
$atendimento->procedimentos->each(function ($procedimento) use ($atendimento, $competencias, &$consistente) {
$inconsistenciasIds = collect();
if (!Cns::isValid($procedimento->usuario_cns)) {
$consistente = false;
$inconsistenciasIds->push(Inconsistencia::CNS_DO_USUARIO_INVALIDO);
}
if (!ProcedimentoIsValidForCompetencia::isValid($competencias, $procedimento->procedimento_id)) {
$consistente = false;
$inconsistenciasIds->push(Inconsistencia::PROCEDIMENTO_INVALIDO_PARA_A_COMPETENCIA);
}
if (!ProcedimentoIsValidForSexo::isValid($atendimento->paciente_sexo_identificador, $procedimento->procedimento_id)) {
$consistente = false;
$inconsistenciasIds->push(Inconsistencia::PROCEDIMENTO_INVALIDO_PARA_O_SEXO);
}
if (!ProcedimentoIsValidForOcupacao::isValid($procedimento->ocupacao_id, $procedimento->procedimento_id)) {
$consistente = false;
$inconsistenciasIds->push(Inconsistencia::PROCEDIMENTO_INVALIDO_PARA_O_CBO);
}
if (!is_null($atendimento->paciente_idade)
&& !ProcedimentoIsValidForIdade::isValid($atendimento->paciente_idade, $procedimento->procedimento_id)
) {
$consistente = false;
$inconsistenciasIds->push(Inconsistencia::PROCEDIMENTO_INVALIDO_PARA_A_IDADE_DO_PACIENTE);
}
if (!QuantidadeIsValidForProcedimento::isValid($procedimento->procedimento_id, $procedimento->quantidade)) {
$consistente = false;
$inconsistenciasIds->push(Inconsistencia::QUANTIDADE_DO_PROCEDIMENTO_INVALIDA);
}
if (!is_null($procedimento->classificacao_id)) {
if (!ClassificacaoIsValidForProcedimento::isValid($procedimento->procedimento_id, $procedimento->classificacao_id)) {
$consistente = false;
$inconsistenciasIds->push(Inconsistencia::CLASSIFICACAO_INVALIDA_PARA_O_PROCEDIMENTO);
}
if (!is_null($procedimento->servico_id)
&& !ClassificacaoIsValidForServico::isValid($procedimento->servico_id, $procedimento->classificacao_id)
) {
$consistente = false;
$inconsistenciasIds->push(Inconsistencia::CLASSIFICACAO_INVALIDA_PARA_O_SERVICO);
}
$classificacao = collect($procedimento->classificacao_id)
->flatMap(fn($item) => collect($item))
->first();
$procedimento->classificacao_id = $classificacao->id ?? null;
$procedimento->classificacao_codigo = $classificacao->codigo ?? null;
$servico = collect($procedimento->servico_id)->first();
$procedimento->servico_id = $servico->id ?? null;
$procedimento->servico_codigo = $servico->codigo ?? null;
};
if ($inconsistenciasIds->isNotEmpty()) {
AtendimentoProcedimento::findOrFail($procedimento->id)->inconsistencias()->sync($inconsistenciasIds);
}
});
if ($consistente) {
$consistentes->push($atendimento);
}
else {
$inconsistentes->push($atendimento);
}
DB::table('raas_atendimento')
->where('id', $atendimento->id)
->update(['exportacao_id' => $exportacao->id]);
});
return compact('consistentes', 'inconsistentes');
}
private static function getDadosCabecalho($competencia, $atendimentos)
{
$cliente = Cliente::where('link', app('config')->get('database.default'))->firstOrFail();
$controleDominio = self::getControleDominio($atendimentos);
return (object) [
'competencia_valor' => $competencia->valor,
'quantidade_folhas' => $atendimentos->count(),
'controle_dominio' => $controleDominio,
'orgao_origem_responsavel_nome' => 'CONECTASUS',
'orgao_origem_responsavel_sigla' => 'CSUS',
'cnpj_prestador' => null,
'orgao_destino_nome' => "SECRETARIA DA SAUDE DE {$cliente->municipio->nome}",
'orgao_destino_indicador' => 'M',
'data_geracao_remessa' => Carbon::today()->format('Ymd'),
'versao' => '02.35',
'versao_bdsia' => $competencia->valor,
];
}
private static function getControleDominio($atendimentos)
{
$soma = 0;
$atendimentos->each(function ($atendimento) use (&$soma) {
$soma += (int) $atendimento->procedimentos->sum('procedimento_codigo')
+ $atendimento->quantidade_procedimentos
+ (int) $atendimento->unidade_cnes
+ (int) $atendimento->paciente_cns;
});
return ($soma % 1111) + 1111;
}
private static function getLinhaCabecalho($params)
{
$linha = '';
$dados = [
'cbc-codlinha' => self::padRight(Linha::CABECALHO, 2, self::SPACE_CHAR),
'cbc-hdr' => self::padRight('#RAS#', 5, self::SPACE_CHAR),
'cbc-mvm' => self::padRight($params->competencia_valor, 6, self::SPACE_CHAR),
'cbc-lin' => self::padLeft($params->quantidade_folhas, 6, '0'),
'cbc-smt-vrf' => self::padRight($params->controle_dominio, 4, self::SPACE_CHAR),
'cbc-rsp' => self::padRight($params->orgao_origem_responsavel_nome, 30, self::SPACE_CHAR),
'cbc-sgl' => self::padRight($params->orgao_origem_responsavel_sigla, 6, self::SPACE_CHAR),
'cbc-cgccpf' => self::padLeft($params->cnpj_prestador, 14, '0'),
'cbc-dst' => self::padRight($params->orgao_destino_nome, 40, self::SPACE_CHAR),
'cbc-dst-in' => self::padRight($params->orgao_destino_indicador, 1, self::SPACE_CHAR),
'cbc-dtger' => self::padRight($params->data_geracao_remessa, 8, self::SPACE_CHAR),
'cbc-versao' => self::padRight($params->versao, 15, self::SPACE_CHAR),
// 'cbc-versao' => self::padRight($params->versao, 5, self::SPACE_CHAR), // Sistema RAAS 02.21 não aceita
// 'Filler' => self::padRight(self::EMPTY, 10, '0'), // Sistema RAAS 02.21 não aceita
'cbc-bdversao' => self::padRight($params->versao_bdsia, 7, self::SPACE_CHAR),
'cbc-fim' => chr(13) . chr(10),
];
foreach ($dados as $valor) {
$linha .= $valor;
}
return $linha;
}
private static function getLinhaCorpo($params)
{
$linha = '';
$cnsPreenchido = !empty($params->paciente_cns);
$cpfPreenchido = !empty($params->paciente_cpf);
$dados = [
'ras_codlinha_ad_corpo' => self::padRight(Linha::ATENCAO_PSICOSSOCIAL_CORPO, 2, self::SPACE_CHAR),
'ras_coduf' => self::padRight($params->estado_ibge, 2, self::SPACE_CHAR),
'ras_cmp' => self::padRight($params->competencia_valor, 6, self::SPACE_CHAR),
'ras_codcnes' => self::padRight($params->unidade_cnes, 7, self::SPACE_CHAR),
'ras_cnspct' => self::padRight($params->paciente_cns ?: '0', 15, '0'),
'ras_dtiinval' => self::padRight($params->data_admissao, 8, self::SPACE_CHAR),
'ras_dtfimval' => self::padRight($params->data_conclusao, 8, self::SPACE_CHAR),
'ras_nomepcnte' => self::padRight($params->paciente_nome, 30, self::SPACE_CHAR),
'ras_npront' => self::padLeft($params->paciente_prontuario, 10, '0'),
'ras_nomemae' => self::padRight($params->paciente_nome_mae, 30, self::SPACE_CHAR),
'ras_logpcnte' => self::padRight($params->paciente_logradouro_nome, 30, self::SPACE_CHAR),
'ras_numpcnte' => self::padRight($params->paciente_endereco_numero, 5, self::SPACE_CHAR),
'ras_cplpcnte' => self::padRight($params->paciente_endereco_complemento, 10, self::SPACE_CHAR),
'ras_ceppcnte' => self::padRight($params->paciente_logradouro_cep, 8, self::SPACE_CHAR),
'ras_munpcnte' => self::padRight($params->paciente_municipio_residencia_ibge, 7, self::SPACE_CHAR),
'ras_datanascim' => self::padRight($params->paciente_data_nascimento, 8, self::SPACE_CHAR),
'ras_sexopcnte' => self::padRight($params->paciente_sexo_identificador, 1, self::SPACE_CHAR),
'ras_raca' => self::padRight($params->paciente_raca_cor_codigo, 2, self::SPACE_CHAR),
'ras_nomeresp' => self::padRight($params->paciente_nome_responsavel, 30, self::SPACE_CHAR),
'ras_nascpcnte' => self::padRight($params->paciente_pais_nascimento_codigo, 3, self::SPACE_CHAR),
'ras_etnia' => self::padRight($params->paciente_etnia_indigena_codigo, 4, self::SPACE_CHAR),
'ras_telefone' => self::padRight($params->paciente_telefone, 11, self::SPACE_CHAR),
'ras_celular' => self::padRight($params->paciente_celular, 11, self::SPACE_CHAR),
'ras_motsaida' => self::padRight($params->motivo_saida_permanencia_codigo, 2, self::SPACE_CHAR),
'ras_dtobitoalta' => self::padRight($params->data_ocorrencia, 8, self::SPACE_CHAR),
'pap_cidp' => self::padRight($params->cid_principal_codigo, 4, self::SPACE_CHAR),
'pap_cids1' => self::padRight($params->cid_secundario_1_codigo, 4, self::SPACE_CHAR),
'pap_cids2' => self::padRight($params->cid_secundario_2_codigo, 4, self::SPACE_CHAR),
'pap_cids3' => self::padRight($params->cid_secundario_3_codigo, 4, self::SPACE_CHAR),
'ras_cidca' => self::padRight($params->cid_causa_associada_codigo, 4, self::SPACE_CHAR),
'ras_CARATE' => self::padRight($params->carater_atendimento_codigo, 2, self::SPACE_CHAR),
'ras_origempcn' => self::padRight($params->origem_paciente_codigo, 2, self::SPACE_CHAR),
'ras_cobertura_ESF' => self::padRight($params->cobertura_estrategia_saude_familia, 1, self::SPACE_CHAR),
'ras_cnes_esd' => self::padRight($params->unidade_cobertura_estrategia_saude_familia_cnes, 7, self::SPACE_CHAR),
'ras_total_acoes' => self::padLeft($params->quantidade_procedimentos, 5, '0'),
'ras_dest_paciente' => self::padRight($params->destino_paciente_codigo, 2, self::SPACE_CHAR),
'ras_org' => self::padRight(OrigemInformacao::OUTROS_SISTEMAS, 3, self::SPACE_CHAR),
'ras_situacao_rua' => self::padRight($params->paciente_situacao_rua, 1, self::SPACE_CHAR),
'ras_usu_droga' => self::padRight($params->paciente_usuario_droga, 1, self::SPACE_CHAR),
'ras_usu_tipo_droga' => self::padRight($params->paciente_tipo_droga, 3, self::SPACE_CHAR),
'ras_autorizacao' => self::padRight($params->numero_autorizacao, 13, self::SPACE_CHAR),
'ras_bairro' => self::padRight($params->paciente_bairro_nome, 30, self::SPACE_CHAR),
'ras_cod_logradouro' => self::padRight($params->paciente_logradouro_codigo, 3, self::SPACE_CHAR),
'ras_email' => self::padRight($params->paciente_email, 40, self::SPACE_CHAR),
'ras_cpfpct' => self::padRight($params->paciente_cpf ?: '0', 11, '0'),
// 'ras_filler' => self::padLeft(self::EMPTY, 4, self::SPACE_CHAR), // Sistema RAAS 02.21 não aceita
'as_fim' => chr(13) . chr(10),
];
if ($cnsPreenchido) {
$dados['ras_cpfpct'] = str_repeat('0', 11);
} elseif ($cpfPreenchido) {
$dados['ras_cnspct'] = str_repeat('0', 15);
}
foreach ($dados as $valor) {
$linha .= $valor;
}
return $linha;
}
private static function getLinhaProcedimento($params)
{
$linha = '';
$cnsPreenchido = !empty($params->paciente_cns);
$cpfPreenchido = !empty($params->paciente_cpf);
$dados = [
'ras_codlinha_ad_acoes' => self::padRight(Linha::ATENCAO_PSICOSSOCIAL_PROCEDIMENTO, 2, self::SPACE_CHAR),
'ras_coduf' => self::padRight($params->estado_ibge, 2, self::SPACE_CHAR),
'ras_cmp' => self::padRight($params->competencia_valor, 6, self::SPACE_CHAR),
'ras_codcnes' => self::padRight($params->unidade_cnes, 7, self::SPACE_CHAR),
'ras_cnspct' => self::padRight($params->paciente_cns ?: '0', 15, '0'),
'ras_dtiinval' => self::padRight($params->data_admissao, 8, self::SPACE_CHAR),
'ras_acao' => self::padLeft($params->procedimento_codigo, 10, '0'),
'ras_cbo' => self::padRight($params->ocupacao_codigo, 6, self::SPACE_CHAR),
'ras_cns' => self::padRight($params->usuario_cns, 15, self::SPACE_CHAR),
'ras_dtexec' => self::padRight($params->data_execucao, 8, self::SPACE_CHAR),
'ras_srv' => self::padRight($params->servico_codigo, 3, self::SPACE_CHAR),
'ras_class' => self::padRight($params->classificacao_codigo, 3, self::SPACE_CHAR),
'ras_qtd' => self::padLeft($params->quantidade, 6, '0'),
'ras_org' => self::padRight(OrigemInformacao::OUTROS_SISTEMAS, 3, self::SPACE_CHAR),
'ras_local_realizacao' => self::padRight($params->local_realizacao_identificador, 1, self::SPACE_CHAR),
'ras_cpfpct' => self::padRight($params->paciente_cpf ?: '0', 11, '0'),
// 'ras_filler' => self::padRight(self::EMPTY, 4, self::SPACE_CHAR), // Sistema RAAS 02.21 não aceita
'ras_fim' => chr(13) . chr(10),
];
if ($cnsPreenchido) {
$dados['ras_cpfpct'] = str_repeat('0', 11);
} elseif ($cpfPreenchido) {
$dados['ras_cnspct'] = str_repeat('0', 15);
}
foreach ($dados as $valor) {
$linha .= $valor;
}
return $linha;
}
private static function padLeft($value, $length, $pad)
{
return Str::padLeft(Str::substr((string) $value, 0, $length), $length, $pad);
}
private static function padRight($value, $length, $pad)
{
return Str::padRight(Str::substr((string) $value, 0, $length), $length, $pad);
}
public static function update($id)
{
return Exportacao::findOrFail($id)->update([
'encaminhado' => request()->encaminhado
]);
}
public static function destroy($id)
{
$exportacao = Exportacao::where('id', $id)
->where('encaminhado', false)
->firstOrFail();
DB::transaction(function() use ($exportacao) {
Atendimento::where('exportacao_id', $exportacao->id)->get()->each(function ($atendimento) {
$atendimento->inconsistencias()->sync([]);
$atendimento->procedimentos->each(function ($procedimento) {
$procedimento->inconsistencias()->sync([]);
});
$atendimento->update(['exportacao_id' => null]);
});
if (Storage::disk('local')->exists(self::$caminho . DIRECTORY_SEPARATOR . app('config')->get('database.default') . DIRECTORY_SEPARATOR . $exportacao->arquivo)) {
Storage::disk('local')->delete(self::$caminho . DIRECTORY_SEPARATOR . app('config')->get('database.default') . DIRECTORY_SEPARATOR . $exportacao->arquivo);
}
$exportacao->delete();
});
return $exportacao;
}
public static function download($id)
{
$exportacao = Exportacao::findOrFail($id);
return [
'nome' => $exportacao->arquivo,
'arquivo' => Storage::path(self::$caminho . DIRECTORY_SEPARATOR . app('config')->get('database.default') . DIRECTORY_SEPARATOR . $exportacao->arquivo),
];
}
}