This commit is contained in:
239
api/app/Services/WebService/Laboratorio/Cliente/ExameService.php
Normal file
239
api/app/Services/WebService/Laboratorio/Cliente/ExameService.php
Normal file
@@ -0,0 +1,239 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\WebService\Laboratorio\Cliente;
|
||||
|
||||
use App\Enums\WebService\Laboratorio\Cliente\PedidoStatus;
|
||||
use App\Exceptions\WebService\Laboratorio\Cliente\Exame\CannotDeleteExameException;
|
||||
use App\Exceptions\WebService\Laboratorio\Cliente\Exame\ExameNotFoundException;
|
||||
use App\Models\Parametrizacao\Exame\Exame as CadastroExame;
|
||||
use App\Models\WebService\Laboratorio\Cliente\Exame;
|
||||
use App\Services\Service;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class ExameService extends Service
|
||||
{
|
||||
public static function index($laboratorioId)
|
||||
{
|
||||
$laboratorio = LaboratorioService::getLaboratorioModel($laboratorioId);
|
||||
|
||||
return DB::table('web_service_laboratorio_cliente_exame AS exame')
|
||||
->where('exame.laboratorio_id', $laboratorio->id)
|
||||
->select([
|
||||
'exame.id',
|
||||
'exame.conectasus_exame_id',
|
||||
'exame.nome',
|
||||
])
|
||||
->orderBy('exame.nome')
|
||||
->get();
|
||||
}
|
||||
|
||||
public static function create()
|
||||
{
|
||||
return [
|
||||
'form' => self::getFormData(),
|
||||
'model' => [
|
||||
'laboratorio_id' => null,
|
||||
'conectasus_exame' => null,
|
||||
'nome' => null,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public static function store($request, $laboratorioId)
|
||||
{
|
||||
$laboratorio = LaboratorioService::getLaboratorioModel($laboratorioId);
|
||||
|
||||
self::validate($request);
|
||||
|
||||
return Exame::create(self::getExameData($request, $laboratorio))->fresh();
|
||||
}
|
||||
|
||||
public static function show($laboratorioId, $id)
|
||||
{
|
||||
$laboratorio = LaboratorioService::getLaboratorioModel($laboratorioId);
|
||||
|
||||
return self::getExameModel($id, $laboratorio);
|
||||
}
|
||||
|
||||
public static function edit($id)
|
||||
{
|
||||
$exame = self::getExameModel($id);
|
||||
|
||||
return [
|
||||
'form' => self::getFormData(),
|
||||
'model' => [
|
||||
'laboratorio_id' => $exame->laboratorio_id,
|
||||
'conectasus_exame' => $exame->conectasusExame ? (object) [
|
||||
'id' => $exame->conectasusExame->id,
|
||||
'nome' => $exame->conectasusExame->nome,
|
||||
] : null,
|
||||
'nome' => $exame->nome,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
private static function getFormData()
|
||||
{
|
||||
return [
|
||||
'laboratorios' => self::getLaboratorios(),
|
||||
];
|
||||
}
|
||||
|
||||
private static function getLaboratorios()
|
||||
{
|
||||
return DB::table('web_service_laboratorio_cliente_laboratorio AS laboratorio')
|
||||
->join(
|
||||
'cadastro_infraestrutura AS conectasus_infraestrutura',
|
||||
'conectasus_infraestrutura.id',
|
||||
'laboratorio.conectasus_infraestrutura_id'
|
||||
)
|
||||
->join(
|
||||
'cadastro_unidade AS conectasus_unidade',
|
||||
'conectasus_unidade.id',
|
||||
'conectasus_infraestrutura.unidade_id'
|
||||
)
|
||||
->select([
|
||||
'laboratorio.id',
|
||||
DB::raw("CONCAT(
|
||||
conectasus_unidade.nome_fantasia,
|
||||
IF(conectasus_infraestrutura.nome IS NOT NULL,
|
||||
CONCAT(' - ', conectasus_infraestrutura.nome),
|
||||
''
|
||||
)
|
||||
) AS descricao")
|
||||
])
|
||||
->orderByRaw("CONCAT(
|
||||
conectasus_unidade.nome_fantasia,
|
||||
IF(conectasus_infraestrutura.nome IS NOT NULL,
|
||||
CONCAT(' - ', conectasus_infraestrutura.nome),
|
||||
''
|
||||
)
|
||||
)")
|
||||
->get();
|
||||
}
|
||||
|
||||
public static function update($request, $laboratorioId, $id)
|
||||
{
|
||||
$laboratorio = LaboratorioService::getLaboratorioModel($laboratorioId);
|
||||
$exame = self::getExameModel($id, $laboratorio);
|
||||
|
||||
self::validate($request);
|
||||
|
||||
return tap($exame)->update(self::getExameData($request, $laboratorio))->fresh();
|
||||
}
|
||||
|
||||
private static function getExameData($request, $laboratorio)
|
||||
{
|
||||
$data = $request->only(['conectasus_exame_id', 'nome']);
|
||||
$data['laboratorio_id'] = $laboratorio->id;
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public static function destroy($laboratorioId, $id)
|
||||
{
|
||||
$laboratorio = LaboratorioService::getLaboratorioModel($laboratorioId);
|
||||
$exame = self::getExameModel($id, $laboratorio);
|
||||
|
||||
if (self::hasPedidoEmProcessamento($exame, $laboratorio)) {
|
||||
|
||||
throw new CannotDeleteExameException();
|
||||
}
|
||||
|
||||
$exame->delete();
|
||||
}
|
||||
|
||||
private static function hasPedidoEmProcessamento($exame, $laboratorio)
|
||||
{
|
||||
return $exame->conectasusExame()
|
||||
->whereHas('agendamentoExameLaboratorial', fn ($q) => $q
|
||||
->whereHas('agendamento', fn ($q) => $q
|
||||
->where('laboratorio_infraestrutura_id', $laboratorio->conectasus_infraestrutura_id)
|
||||
->where('web_service_laboratorio_cliente_pedido_status_id', '<>', PedidoStatus::AGUARDANDO_PROCESSAMENTO)
|
||||
)
|
||||
)
|
||||
->exists();
|
||||
}
|
||||
|
||||
public static function datatable()
|
||||
{
|
||||
return DB::table('web_service_laboratorio_cliente_exame AS exame')
|
||||
->join(
|
||||
'web_service_laboratorio_cliente_laboratorio AS laboratorio',
|
||||
'laboratorio.id',
|
||||
'exame.laboratorio_id'
|
||||
)
|
||||
->join(
|
||||
'cadastro_infraestrutura AS conectasus_infraestrutura',
|
||||
'conectasus_infraestrutura.id',
|
||||
'laboratorio.conectasus_infraestrutura_id'
|
||||
)
|
||||
->join(
|
||||
'cadastro_unidade AS conectasus_unidade',
|
||||
'conectasus_unidade.id',
|
||||
'conectasus_infraestrutura.unidade_id'
|
||||
)
|
||||
->leftJoin(
|
||||
'parametrizacao_exame AS conectasus_exame',
|
||||
'conectasus_exame.id',
|
||||
'exame.conectasus_exame_id'
|
||||
)
|
||||
->select([
|
||||
'exame.id',
|
||||
'exame.nome',
|
||||
'conectasus_exame.nome as conectasus_exame_nome',
|
||||
'exame.laboratorio_id',
|
||||
DB::raw("CONCAT(
|
||||
conectasus_unidade.nome_fantasia,
|
||||
IF(conectasus_infraestrutura.nome IS NOT NULL,
|
||||
CONCAT(' - ', conectasus_infraestrutura.nome),
|
||||
''
|
||||
)
|
||||
) AS laboratorio_descricao")
|
||||
]);
|
||||
}
|
||||
|
||||
private static function validate($request)
|
||||
{
|
||||
$request->validate(
|
||||
[
|
||||
'conectasus_exame_id' => [
|
||||
'nullable',
|
||||
'present',
|
||||
'integer',
|
||||
Rule::exists(CadastroExame::class, 'id'),
|
||||
Rule::unique(Exame::class, 'conectasus_exame_id')
|
||||
->where('laboratorio_id', $request->route('laboratorioId'))
|
||||
->ignore($request->route('id')),
|
||||
],
|
||||
'nome' => [
|
||||
'required',
|
||||
'string',
|
||||
'between:3,200',
|
||||
Rule::unique(Exame::class, 'nome')
|
||||
->where('laboratorio_id', $request->route('laboratorioId'))
|
||||
->ignore($request->route('id')),
|
||||
],
|
||||
],
|
||||
[
|
||||
'conectasus_exame_id.exists' => 'O campo Exame (ConectaSUS) selecionado é inválido.',
|
||||
'conectasus_exame_id.unique' => 'O campo Exame (ConectaSUS) já está em uso para este laboratório.',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
private static function getExameModel($id, $laboratorio = null)
|
||||
{
|
||||
$exame = Exame::when($laboratorio, fn ($q) => $q->where('laboratorio_id', $laboratorio->id))
|
||||
->where('id', $id)
|
||||
->first();
|
||||
|
||||
if (is_null($exame)) {
|
||||
|
||||
throw new ExameNotFoundException();
|
||||
}
|
||||
|
||||
return $exame;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\WebService\Laboratorio\Cliente;
|
||||
|
||||
use App\Exceptions\WebService\Laboratorio\Cliente\Laboratorio\CannotDeleteLaboratorioException;
|
||||
use App\Exceptions\WebService\Laboratorio\Cliente\Laboratorio\LaboratorioNotFoundException;
|
||||
use App\Models\Cadastro\Estabelecimento\Infraestrutura as CadastroInfraestrutura;
|
||||
use App\Models\WebService\Laboratorio\Cliente\Laboratorio;
|
||||
use App\Services\Service;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class LaboratorioService extends Service
|
||||
{
|
||||
public static function list()
|
||||
{
|
||||
switch (request()->listar) {
|
||||
case 'conectasus-infraestruturas': {
|
||||
return [
|
||||
'conectasus_infraestruturas' => self::getConectaSusInfraestruturas(request()->conectasus_unidade_id),
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function create()
|
||||
{
|
||||
return [
|
||||
'form' => self::getFormData(),
|
||||
'model' => [
|
||||
'conectasus_unidade_id' => null,
|
||||
'conectasus_infraestrutura_id' => null,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public static function store($request)
|
||||
{
|
||||
self::validate($request);
|
||||
|
||||
return Laboratorio::create(self::getLaboratorioData($request))->fresh();
|
||||
}
|
||||
|
||||
private static function getFormData()
|
||||
{
|
||||
return [
|
||||
'conectasus_unidades' => self::getConectaSusUnidades(),
|
||||
'conectasus_infraestruturas' => collect(),
|
||||
];
|
||||
}
|
||||
|
||||
private static function getConectaSusUnidades()
|
||||
{
|
||||
return DB::table('cadastro_unidade AS unidade')
|
||||
->select([
|
||||
'unidade.id',
|
||||
'unidade.nome_fantasia'
|
||||
])
|
||||
->whereNull('unidade.deleted_at')
|
||||
->whereExists(fn ($q) => $q
|
||||
->selectRaw(1)
|
||||
->from('exame_laboratorial_parametrizacao_unidade AS parametrizacao_unidade')
|
||||
->whereColumn('parametrizacao_unidade.unidade_id', 'unidade.id')
|
||||
->where('parametrizacao_unidade.laboratorio', true)
|
||||
)
|
||||
->orderBy('unidade.nome_fantasia')
|
||||
->get();
|
||||
}
|
||||
|
||||
private static function getConectaSusInfraestruturas($unidadeId)
|
||||
{
|
||||
return DB::table('cadastro_infraestrutura AS infraestrutura')
|
||||
->join('cadastro_unidade AS unidade', 'unidade.id', 'infraestrutura.unidade_id')
|
||||
->select([
|
||||
'infraestrutura.id',
|
||||
DB::raw("COALESCE(infraestrutura.nome, unidade.nome_fantasia) AS nome"),
|
||||
])
|
||||
->whereNull('infraestrutura.deleted_at')
|
||||
->where('infraestrutura.unidade_id', $unidadeId)
|
||||
->whereExists(fn ($q) => $q
|
||||
->selectRaw(1)
|
||||
->from('exame_laboratorial_parametrizacao_unidade AS parametrizacao_unidade')
|
||||
->whereColumn('parametrizacao_unidade.infraestrutura_id', 'infraestrutura.id')
|
||||
->where('parametrizacao_unidade.laboratorio', true)
|
||||
)
|
||||
->orderByRaw("COALESCE(infraestrutura.nome, unidade.nome_fantasia)")
|
||||
->get();
|
||||
}
|
||||
|
||||
private static function getLaboratorioData($request)
|
||||
{
|
||||
return $request->only(['conectasus_infraestrutura_id']);
|
||||
}
|
||||
|
||||
public static function destroy($id)
|
||||
{
|
||||
$laboratorio = self::getLaboratorioModel($id);
|
||||
|
||||
if ($laboratorio->exames()->exists()) {
|
||||
|
||||
throw new CannotDeleteLaboratorioException();
|
||||
}
|
||||
|
||||
$laboratorio->delete();
|
||||
}
|
||||
|
||||
public static function datatable()
|
||||
{
|
||||
return DB::table('web_service_laboratorio_cliente_laboratorio AS laboratorio')
|
||||
->join(
|
||||
'cadastro_infraestrutura AS conectasus_infraestrutura',
|
||||
'conectasus_infraestrutura.id',
|
||||
'laboratorio.conectasus_infraestrutura_id'
|
||||
)
|
||||
->join(
|
||||
'cadastro_unidade AS conectasus_unidade',
|
||||
'conectasus_unidade.id',
|
||||
'conectasus_infraestrutura.unidade_id'
|
||||
)
|
||||
->select([
|
||||
'laboratorio.id',
|
||||
'conectasus_unidade.nome_fantasia AS conectasus_unidade_nome_fantasia',
|
||||
DB::raw("COALESCE(conectasus_infraestrutura.nome, conectasus_unidade.nome_fantasia) AS conectasus_infraestrutura_nome"),
|
||||
]);
|
||||
}
|
||||
|
||||
private static function validate($request)
|
||||
{
|
||||
$request->validate([
|
||||
'conectasus_infraestrutura_id' => [
|
||||
'required',
|
||||
'integer',
|
||||
Rule::exists(CadastroInfraestrutura::class, 'id'),
|
||||
Rule::unique(Laboratorio::class, 'conectasus_infraestrutura_id'),
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public static function getLaboratorioModel($id)
|
||||
{
|
||||
$laboratorio = Laboratorio::find($id);
|
||||
|
||||
if (is_null($laboratorio)) {
|
||||
|
||||
throw new LaboratorioNotFoundException();
|
||||
}
|
||||
|
||||
return $laboratorio;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,552 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\WebService\Laboratorio\Cliente;
|
||||
|
||||
use App\Enums\Cadastro\SujeitoAtencao\Sexo;
|
||||
use App\Enums\Cadastro\SujeitoAtencao\TipoRegistroUsuario;
|
||||
use App\Enums\ExameLaboratorial\Acao;
|
||||
use App\Enums\ExameLaboratorial\ParametrizacaoWebServiceTipo;
|
||||
use App\Enums\ExameLaboratorial\StatusAgendamento;
|
||||
use App\Enums\WebService\Laboratorio\Cliente\PedidoStatus as PedidoStatusEnum;
|
||||
use App\Exceptions\WebService\Laboratorio\Cliente\Pedido\CannotChangeStatusException;
|
||||
use App\Exceptions\WebService\Laboratorio\Cliente\Pedido\IncompleteExameParametrizationException;
|
||||
use App\Exceptions\WebService\Laboratorio\Cliente\Pedido\PedidoNotFoundException;
|
||||
use App\Models\ExameLaboratorial\AgendamentoExame\Agendamento as ExameLaboratorialAgendamento;
|
||||
use App\Models\ExameLaboratorial\AgendamentoExame\AgendamentoLaudo;
|
||||
use App\Models\ExameLaboratorial\Parametrizacao\WebService as ParametrizacaoWebService;
|
||||
use App\Models\WebService\Laboratorio\Cliente\PedidoMovimentacao;
|
||||
use App\Models\WebService\Laboratorio\Cliente\PedidoStatus;
|
||||
use App\Services\ExameLaboratorial\AgendamentoExameHistoricoService;
|
||||
use App\Services\Service;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class PedidoService extends Service
|
||||
{
|
||||
public static function index($request, $laboratorioId)
|
||||
{
|
||||
$laboratorio = LaboratorioService::getLaboratorioModel($laboratorioId);
|
||||
|
||||
self::validateIndex($request);
|
||||
|
||||
return self::getPedidos($laboratorio, (object) $request->all());
|
||||
}
|
||||
|
||||
private static function validateIndex($request)
|
||||
{
|
||||
return $request->validate([
|
||||
'data_solicitacao' => [
|
||||
'nullable',
|
||||
'required_without:data_coleta',
|
||||
'date_format:Y-m-d',
|
||||
'before_or_equal:' . Carbon::now()->format('Y-m-d'),
|
||||
],
|
||||
'data_coleta' => [
|
||||
'nullable',
|
||||
'required_without:data_solicitacao',
|
||||
'date_format:Y-m-d',
|
||||
],
|
||||
'nome_paciente' => [
|
||||
'nullable',
|
||||
'string',
|
||||
'max:150',
|
||||
],
|
||||
'status_id' => [
|
||||
'nullable',
|
||||
'integer',
|
||||
Rule::exists(PedidoStatus::class, 'id'),
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public static function show($laboratorioId, $id)
|
||||
{
|
||||
$laboratorio = LaboratorioService::getLaboratorioModel($laboratorioId);
|
||||
$pedido = self::getPedidoModel($laboratorio, $id);
|
||||
|
||||
$pedidos = self::getPedidos($laboratorio, (object) ['pedido_id' => $pedido->id]);
|
||||
|
||||
if ($pedidos->isEmpty()) {
|
||||
|
||||
throw new PedidoNotFoundException();
|
||||
}
|
||||
|
||||
return $pedidos->first();
|
||||
}
|
||||
|
||||
private static function getPedidos($laboratorio, $params)
|
||||
{
|
||||
$isIntegracaoParcial = (ParametrizacaoWebService::first()->tipo_id ?? null) === ParametrizacaoWebServiceTipo::PARCIAL;
|
||||
|
||||
$pedidos = DB::table('exame_laboratorial_agendamento AS agendamento')
|
||||
->join('cadastro_paciente AS paciente', 'paciente.id', 'agendamento.paciente_id')
|
||||
->join('cadastro_cidadao AS paciente_cidadao', 'paciente_cidadao.id', 'paciente.cidadao_id')
|
||||
->join('cadastro_sexo AS paciente_sexo', 'paciente_sexo.id', 'paciente_cidadao.sexo_id')
|
||||
->join(
|
||||
'cadastro_infraestrutura AS infraestrutura_solicitante',
|
||||
'infraestrutura_solicitante.id',
|
||||
'agendamento.infraestrutura_id'
|
||||
)
|
||||
->join(
|
||||
'cadastro_unidade AS unidade_solicitante',
|
||||
'unidade_solicitante.id',
|
||||
'infraestrutura_solicitante.unidade_id'
|
||||
)
|
||||
->join('cadastro_usuario AS usuario_solicitante', 'usuario_solicitante.id', 'agendamento.medico_id')
|
||||
->join(
|
||||
'cadastro_cidadao AS usuario_cidadao_solicitante',
|
||||
'usuario_cidadao_solicitante.id',
|
||||
'usuario_solicitante.cidadao_id'
|
||||
)
|
||||
->leftJoin('cadastro_cidadao_telefone AS paciente_telefone', fn ($q) => $q
|
||||
->on('paciente_telefone.cidadao_id', 'paciente_cidadao.id')
|
||||
->where('paciente_telefone.id', fn ($q) => $q
|
||||
->select('paciente_telefone2.id')
|
||||
->from('cadastro_cidadao_telefone AS paciente_telefone2')
|
||||
->whereColumn('paciente_telefone2.cidadao_id', 'paciente_cidadao.id')
|
||||
->where('paciente_telefone2.principal', true)
|
||||
->limit(1)
|
||||
)
|
||||
)
|
||||
->leftJoin(
|
||||
'cadastro_domicilio AS paciente_domicilio',
|
||||
'paciente_domicilio.id',
|
||||
'paciente_cidadao.domicilio_id'
|
||||
)
|
||||
->leftJoin(
|
||||
'cadastro_endereco AS paciente_endereco',
|
||||
'paciente_endereco.id',
|
||||
'paciente_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(
|
||||
'cadastro_bairro AS paciente_logradouro_bairro',
|
||||
'paciente_logradouro_bairro.id',
|
||||
'paciente_logradouro.bairro_id'
|
||||
)
|
||||
->leftJoin(
|
||||
'intranet.cadastro_municipio AS paciente_municipio',
|
||||
'paciente_municipio.id',
|
||||
'paciente_logradouro.municipio_id'
|
||||
)
|
||||
->leftJoin(
|
||||
'cadastro_usuario_registro_tipo AS usuario_registro_tipo',
|
||||
'usuario_registro_tipo.id',
|
||||
'usuario_solicitante.registro_tipo_id'
|
||||
)
|
||||
->where('agendamento.laboratorio_infraestrutura_id', $laboratorio->conectasus_infraestrutura_id)
|
||||
->where(fn ($q) => $q
|
||||
->when($params->data_solicitacao ?? null, fn ($q, $data) => $q
|
||||
->orWhereDate('agendamento.created_at', $data)
|
||||
)
|
||||
->when($params->data_coleta ?? null, fn ($q, $data) => $q
|
||||
->orWhere('agendamento.data', $data)
|
||||
)
|
||||
)
|
||||
->when($params->pedido_id ?? null, fn ($q, $id) => $q->where('agendamento.id', $id))
|
||||
->when($params->nome_paciente ?? null, fn ($q, $nome) => $q
|
||||
->where('paciente_cidadao.nome', 'LIKE', "{$nome}%")
|
||||
)
|
||||
->when($params->status_id ?? null, fn ($q, $id) => $q
|
||||
->where('agendamento.web_service_laboratorio_cliente_pedido_status_id', $id)
|
||||
)
|
||||
->when($isIntegracaoParcial, fn ($q) => $q
|
||||
->whereNotExists(fn ($q) => $q
|
||||
->selectRaw(1)
|
||||
->from('exame_laboratorial_agendamento_exame AS agendamento_exame')
|
||||
->whereColumn('agendamento_exame.agendamento_id', 'agendamento.id')
|
||||
->whereNull('agendamento_exame.data_coleta')
|
||||
)
|
||||
)
|
||||
->select(
|
||||
'agendamento.id',
|
||||
'agendamento.agendamento_numero as numero_agendamento',
|
||||
'agendamento.web_service_laboratorio_cliente_pedido_status_id AS status_id',
|
||||
DB::raw("CAST(agendamento.created_at AS DATE) AS data_solicitacao"),
|
||||
'paciente_cidadao.nome AS paciente_nome',
|
||||
'paciente_cidadao.data_nascimento AS paciente_data_nascimento',
|
||||
DB::raw("TIMESTAMPDIFF(YEAR, paciente_cidadao.data_nascimento, NOW()) AS paciente_idade"),
|
||||
'paciente_sexo.id AS paciente_sexo_id',
|
||||
'paciente_sexo.descricao AS paciente_sexo_descricao',
|
||||
DB::raw("LPAD(paciente.prontuario, 7, '0') AS paciente_prontuario"),
|
||||
'agendamento.gestante AS paciente_gestante',
|
||||
'agendamento.ultima_menstruacao AS paciente_data_ultima_menstruacao',
|
||||
'paciente_telefone.numero AS paciente_telefone',
|
||||
DB::raw("CONCAT(paciente_logradouro_tipo.descricao, ' ', paciente_logradouro.nome) AS paciente_logradouro_descricao"),
|
||||
'paciente_endereco.numero AS paciente_logradouro_numero',
|
||||
'paciente_logradouro_bairro.nome AS paciente_bairro_nome',
|
||||
'paciente_logradouro.cep AS paciente_cep',
|
||||
'paciente_municipio.nome AS paciente_municipio_nome',
|
||||
'usuario_cidadao_solicitante.nome AS medico_solicitante_nome',
|
||||
DB::raw("IF(
|
||||
usuario_solicitante.registro_tipo_id = " . TipoRegistroUsuario::OUTRO . ",
|
||||
registro_tipo_outro,
|
||||
usuario_registro_tipo.sigla
|
||||
) AS conselho_profissional_tipo_sigla"),
|
||||
'usuario_solicitante.registro_numero AS conselho_profissional_numero',
|
||||
'unidade_solicitante.id AS unidade_solicitante_id',
|
||||
'unidade_solicitante.nome_fantasia AS unidade_solicitante_nome_fantasia',
|
||||
'infraestrutura_solicitante.id AS local_atendimento_solicitante_id',
|
||||
DB::raw("COALESCE(infraestrutura_solicitante.nome, unidade_solicitante.nome_fantasia) AS local_atendimento_solicitante_nome")
|
||||
)
|
||||
->orderBy('agendamento.created_at')
|
||||
->get();
|
||||
|
||||
$pedidos->each(function ($pedido) use ($laboratorio) {
|
||||
|
||||
$pedido->itens = self::getPedidoItens($pedido, $laboratorio);
|
||||
|
||||
if ($pedido->paciente_sexo_id !== Sexo::FEMININO) {
|
||||
|
||||
unset($pedido->paciente_gestante, $pedido->paciente_data_ultima_menstruacao);
|
||||
}
|
||||
else {
|
||||
|
||||
$pedido->paciente_gestante = (bool) $pedido->paciente_gestante;
|
||||
}
|
||||
|
||||
self::setMovimentacaoFields($pedido);
|
||||
|
||||
unset($pedido->paciente_sexo_id);
|
||||
});
|
||||
|
||||
return $pedidos;
|
||||
}
|
||||
|
||||
private static function getPedidoItens($pedido, $laboratorio)
|
||||
{
|
||||
return DB::table('exame_laboratorial_agendamento_exame AS agendamento_exame')
|
||||
->join(
|
||||
'exame_laboratorial_agendamento AS agendamento',
|
||||
'agendamento.id',
|
||||
'agendamento_exame.agendamento_id'
|
||||
)
|
||||
->leftJoin('web_service_laboratorio_cliente_exame AS cliente_exame', fn ($q) => $q
|
||||
->on('cliente_exame.conectasus_exame_id', 'agendamento_exame.exame_id')
|
||||
->where('cliente_exame.laboratorio_id', $laboratorio->id)
|
||||
)
|
||||
->where('agendamento_exame.agendamento_id', $pedido->id)
|
||||
->select(
|
||||
'agendamento_exame.exame_id AS conectasus_exame_id',
|
||||
'cliente_exame.id AS cliente_exame_id',
|
||||
'agendamento.data AS data_coleta'
|
||||
)
|
||||
->orderBy('agendamento_exame.data_coleta')
|
||||
->get();
|
||||
}
|
||||
|
||||
private static function setMovimentacaoFields($pedido)
|
||||
{
|
||||
$pedido->processado_em = null;
|
||||
$pedido->realizado_em = null;
|
||||
$pedido->cancelado_em = null;
|
||||
$pedido->motivo_cancelamento = null;
|
||||
|
||||
self::getPedidoMovimentacoes($pedido)->each(function ($movimentacao) use ($pedido) {
|
||||
|
||||
if ($movimentacao->status_id === PedidoStatusEnum::PROCESSANDO) {
|
||||
|
||||
$pedido->processado_em = $movimentacao->movimentado_em;
|
||||
}
|
||||
else if ($movimentacao->status_id === PedidoStatusEnum::REALIZADO) {
|
||||
|
||||
$pedido->realizado_em = $movimentacao->movimentado_em;
|
||||
}
|
||||
else if ($movimentacao->status_id === PedidoStatusEnum::CANCELADO_PELO_LABORATORIO) {
|
||||
|
||||
$pedido->cancelado_em = $movimentacao->movimentado_em;
|
||||
$pedido->motivo_cancelamento = $movimentacao->motivo;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static function getPedidoMovimentacoes($pedido)
|
||||
{
|
||||
return DB::table('web_service_laboratorio_cliente_pedido_movimentacao AS movimentacao')
|
||||
->where('movimentacao.conectasus_exame_laboratorial_agendamento_id', $pedido->id)
|
||||
->select(
|
||||
'movimentacao.status_id',
|
||||
'movimentacao.motivo',
|
||||
'movimentacao.movimentado_em',
|
||||
)
|
||||
->orderBy('movimentacao.movimentado_em')
|
||||
->get();
|
||||
}
|
||||
|
||||
public static function process($laboratorioId, $id)
|
||||
{
|
||||
$laboratorio = LaboratorioService::getLaboratorioModel($laboratorioId);
|
||||
$pedido = self::getPedidoModel($laboratorio, $id);
|
||||
|
||||
if ($pedido->web_service_laboratorio_cliente_pedido_status_id !== PedidoStatusEnum::AGUARDANDO_PROCESSAMENTO) {
|
||||
$mensagemStatus = null;
|
||||
|
||||
if ($pedido->web_service_laboratorio_cliente_pedido_status_id === PedidoStatusEnum::CANCELADO_PELO_LABORATORIO) {
|
||||
$mensagemStatus = 'O status não pode ser alterado pois o pedido foi cancelado pelo laboratório.';
|
||||
}
|
||||
else if ($pedido->web_service_laboratorio_cliente_pedido_status_id === PedidoStatusEnum::PROCESSANDO) {
|
||||
$mensagemStatus = 'O status não pode ser alterado pois o pedido já está em processamento.';
|
||||
}
|
||||
else if ($pedido->web_service_laboratorio_cliente_pedido_status_id === PedidoStatusEnum::REALIZADO) {
|
||||
$mensagemStatus = 'O status não pode ser alterado pois o pedido já está realizado.';
|
||||
}
|
||||
|
||||
throw new CannotChangeStatusException($mensagemStatus);
|
||||
}
|
||||
else if (self::vinculoEntreExamesConectasusClienteIncompleto($laboratorio, $pedido)) {
|
||||
|
||||
throw new IncompleteExameParametrizationException();
|
||||
}
|
||||
|
||||
DB::transaction(function () use ($pedido) {
|
||||
|
||||
$pedido->update(['web_service_laboratorio_cliente_pedido_status_id' => PedidoStatusEnum::PROCESSANDO]);
|
||||
$pedido->refresh();
|
||||
|
||||
self::saveMovimentacao($pedido);
|
||||
});
|
||||
}
|
||||
|
||||
private static function vinculoEntreExamesConectasusClienteIncompleto($laboratorio, $pedido)
|
||||
{
|
||||
return $pedido->agendamentoExame()
|
||||
->whereHas('exame', fn ($q) => $q
|
||||
->whereDoesntHave('webServiceLaboratorioClienteExame', fn ($q) => $q
|
||||
->where('laboratorio_id', $laboratorio->id)
|
||||
)
|
||||
)
|
||||
->exists();
|
||||
}
|
||||
|
||||
public static function cancel($request, $laboratorioId, $id)
|
||||
{
|
||||
$laboratorio = LaboratorioService::getLaboratorioModel($laboratorioId);
|
||||
$pedido = self::getPedidoModel($laboratorio, $id);
|
||||
|
||||
self::validateCancel($request);
|
||||
|
||||
if ($pedido->web_service_laboratorio_cliente_pedido_status_id !== PedidoStatusEnum::PROCESSANDO) {
|
||||
$mensagemStatus = null;
|
||||
|
||||
if ($pedido->web_service_laboratorio_cliente_pedido_status_id === PedidoStatusEnum::AGUARDANDO_PROCESSAMENTO) {
|
||||
$mensagemStatus = 'O status não pode ser alterado pois o pedido ainda não está em processamento.';
|
||||
}
|
||||
else if ($pedido->web_service_laboratorio_cliente_pedido_status_id === PedidoStatusEnum::CANCELADO_PELO_LABORATORIO) {
|
||||
$mensagemStatus = 'O status não pode ser alterado pois o pedido já foi cancelado pelo laboratório.';
|
||||
}
|
||||
else if ($pedido->web_service_laboratorio_cliente_pedido_status_id === PedidoStatusEnum::REALIZADO) {
|
||||
$mensagemStatus = 'O status não pode ser alterado pois o pedido já está realizado.';
|
||||
}
|
||||
|
||||
throw new CannotChangeStatusException($mensagemStatus);
|
||||
}
|
||||
|
||||
DB::transaction(function () use ($request, $pedido) {
|
||||
|
||||
$pedido->update(['web_service_laboratorio_cliente_pedido_status_id' => PedidoStatusEnum::CANCELADO_PELO_LABORATORIO]);
|
||||
$pedido->refresh();
|
||||
|
||||
self::saveMovimentacao($pedido, ['motivo' => $request->motivo]);
|
||||
});
|
||||
}
|
||||
|
||||
private static function validateCancel($request)
|
||||
{
|
||||
$request->validate([
|
||||
'motivo' => [
|
||||
'required',
|
||||
'string',
|
||||
'between:3,500',
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public static function storeResult($request, $laboratorioId, $id)
|
||||
{
|
||||
$laboratorio = LaboratorioService::getLaboratorioModel($laboratorioId);
|
||||
$pedido = self::getPedidoModel($laboratorio, $id);
|
||||
|
||||
self::validateStoreResult($request);
|
||||
|
||||
$allowedStatus = collect([
|
||||
PedidoStatusEnum::PROCESSANDO,
|
||||
PedidoStatusEnum::REALIZADO
|
||||
]);
|
||||
|
||||
if (!$allowedStatus->contains($pedido->web_service_laboratorio_cliente_pedido_status_id)) {
|
||||
$mensagemStatus = null;
|
||||
|
||||
if ($pedido->web_service_laboratorio_cliente_pedido_status_id === PedidoStatusEnum::AGUARDANDO_PROCESSAMENTO) {
|
||||
$mensagemStatus = 'O status não pode ser alterado pois o pedido ainda não está em processamento.';
|
||||
}
|
||||
else if ($pedido->web_service_laboratorio_cliente_pedido_status_id === PedidoStatusEnum::CANCELADO_PELO_LABORATORIO) {
|
||||
$mensagemStatus = 'O status não pode ser alterado pois o pedido já foi cancelado pelo laboratório.';
|
||||
}
|
||||
|
||||
throw new CannotChangeStatusException($mensagemStatus);
|
||||
}
|
||||
else if ($pedido->data > Carbon::now()) {
|
||||
throw new CannotChangeStatusException('O status não pode ser alterado pois a data de coleta do pedido é maior que a data atual.');
|
||||
}
|
||||
else if ($pedido->web_service_laboratorio_cliente_pedido_status_id === PedidoStatusEnum::PROCESSANDO && self::hasExameAgendado($pedido)) {
|
||||
throw new CannotChangeStatusException('O status não pode ser alterado pois o pedido está em processamento e existe um ou mais exames com o status agendado.');
|
||||
}
|
||||
|
||||
DB::transaction(function () use ($request, $pedido) {
|
||||
|
||||
$path = 'exame-laboratorial' . DIRECTORY_SEPARATOR . 'laudos' . DIRECTORY_SEPARATOR . app('config')->get('database.default');
|
||||
|
||||
$laudo = AgendamentoLaudo::where('agendamento_id', $pedido->id)->where('is_enviado_webservice', true)->first();
|
||||
|
||||
if ($laudo) {
|
||||
|
||||
if (is_null($laudo->url)) {
|
||||
|
||||
if (Storage::disk('local')->exists($path . DIRECTORY_SEPARATOR . $laudo->arquivo)){
|
||||
|
||||
Storage::disk('local')->delete($path . DIRECTORY_SEPARATOR . $laudo->arquivo);
|
||||
}
|
||||
}
|
||||
|
||||
$laudo->delete();
|
||||
}
|
||||
|
||||
$ordem = AgendamentoLaudo::where('agendamento_id', $pedido->id)->max('ordem') + 1;
|
||||
|
||||
if (isset($request->url)) {
|
||||
|
||||
$urlInfo = pathinfo(parse_url($request->url, PHP_URL_PATH));
|
||||
|
||||
AgendamentoLaudo::create([
|
||||
'agendamento_id' => $pedido->id,
|
||||
'arquivo' => isset($urlInfo['filename']) && isset($urlInfo['extension'])
|
||||
? "{$urlInfo['filename']}.{$urlInfo['extension']}"
|
||||
: $pedido->id . ($ordem === 1 ? '' : "_{$ordem}"),
|
||||
'url' => $request->url,
|
||||
'ordem' => $ordem,
|
||||
'is_enviado_webservice' => true
|
||||
]);
|
||||
}
|
||||
else {
|
||||
|
||||
$base64Decoded = str_contains($request->base64, ',')
|
||||
? base64_decode(explode(',', $request->base64)[1], true)
|
||||
: base64_decode($request->base64, true);
|
||||
|
||||
$finfo = finfo_open();
|
||||
$mime = finfo_buffer($finfo, $base64Decoded, FILEINFO_MIME_TYPE);
|
||||
finfo_close($finfo);
|
||||
$extension = explode('/', $mime)[1];
|
||||
$fileName = $pedido->id . ($ordem === 1 ? '' : "_{$ordem}") . ".{$extension}";
|
||||
|
||||
Storage::disk('local')->put($path . DIRECTORY_SEPARATOR . $fileName, $base64Decoded);
|
||||
|
||||
AgendamentoLaudo::create([
|
||||
'agendamento_id' => $pedido->id,
|
||||
'arquivo' => $fileName,
|
||||
'ordem' => $ordem,
|
||||
'is_enviado_webservice' => true
|
||||
]);
|
||||
}
|
||||
|
||||
if ($pedido->web_service_laboratorio_cliente_pedido_status_id !== PedidoStatusEnum::REALIZADO) {
|
||||
|
||||
$pedido->agendamentoExame->each(function ($agendamentoExame) {
|
||||
|
||||
if ($agendamentoExame->status_id === StatusAgendamento::REALIZADO) {
|
||||
|
||||
$agendamentoExame->update(['status_id' => StatusAgendamento::ASSINADO]);
|
||||
$agendamentoExame->refresh();
|
||||
|
||||
AgendamentoExameHistoricoService::store($agendamentoExame, $agendamentoExame->agendamento, Acao::ALTERACAO);
|
||||
}
|
||||
});
|
||||
|
||||
$pedido->update(['web_service_laboratorio_cliente_pedido_status_id' => PedidoStatusEnum::REALIZADO]);
|
||||
$pedido->refresh();
|
||||
|
||||
self::saveMovimentacao($pedido);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static function validateStoreResult($request)
|
||||
{
|
||||
$request->validate([
|
||||
'url' => [
|
||||
Rule::requiredIf(fn () => !isset($request->base64)),
|
||||
'prohibits:base64',
|
||||
'string',
|
||||
'max:300',
|
||||
],
|
||||
'base64' => [
|
||||
Rule::requiredIf(fn () => !isset($request->url)),
|
||||
'prohibits:url',
|
||||
function ($attribute, $value, $fail) {
|
||||
|
||||
$decoded = str_contains($value, ',')
|
||||
? base64_decode(explode(',', $value)[1], true)
|
||||
: base64_decode($value, true);
|
||||
|
||||
if (!$decoded) {
|
||||
|
||||
return $fail('Base64 inválido');
|
||||
}
|
||||
|
||||
$finfo = finfo_open();
|
||||
$mime = finfo_buffer($finfo, $decoded, FILEINFO_MIME_TYPE);
|
||||
|
||||
if ($mime !== 'application/pdf') {
|
||||
|
||||
return $fail('O arquivo deve estar em um formato PDF válido');
|
||||
}
|
||||
|
||||
finfo_close($finfo);
|
||||
}
|
||||
]
|
||||
], [
|
||||
'url.prohibits' => 'O campo url não é permitido se o campo base64 estiver presente',
|
||||
'base64.prohibits' => 'O campo base64 não é permitido se o campo url estiver presente'
|
||||
]);
|
||||
}
|
||||
|
||||
private static function hasExameAgendado($pedido)
|
||||
{
|
||||
return $pedido->agendamentoExame()->where('status_id', StatusAgendamento::AGENDADO)->exists();
|
||||
}
|
||||
|
||||
private static function getPedidoModel($laboratorio, $id)
|
||||
{
|
||||
$pedido = ExameLaboratorialAgendamento::where('laboratorio_infraestrutura_id', $laboratorio->conectasus_infraestrutura_id)
|
||||
->where('id', $id)
|
||||
->first();
|
||||
|
||||
if (is_null($pedido)) {
|
||||
|
||||
throw new PedidoNotFoundException();
|
||||
}
|
||||
|
||||
return $pedido;
|
||||
}
|
||||
|
||||
private static function saveMovimentacao($pedido, $params = [])
|
||||
{
|
||||
PedidoMovimentacao::create([
|
||||
'conectasus_exame_laboratorial_agendamento_id' => $pedido->id,
|
||||
'status_id' => $pedido->web_service_laboratorio_cliente_pedido_status_id,
|
||||
'motivo' => $params['motivo'] ?? null,
|
||||
'movimentado_em' => Carbon::now(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\WebService\Laboratorio\ConectaSus;
|
||||
|
||||
use App\Enums\Parametrizacao\Exame\Tipo;
|
||||
use App\Exceptions\WebService\Laboratorio\ConectaSus\ExameNotFoundException;
|
||||
use App\Models\Parametrizacao\Exame\Exame;
|
||||
use App\Services\Service;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class ExameService extends Service
|
||||
{
|
||||
public static function index()
|
||||
{
|
||||
return DB::table('parametrizacao_exame AS exame')
|
||||
->whereNull('exame.deleted_at')
|
||||
->where('exame.ativo', true)
|
||||
->where('exame.tipo_id', Tipo::LABORATORIAL)
|
||||
->select([
|
||||
'exame.id',
|
||||
'exame.nome',
|
||||
])
|
||||
->orderBy('exame.nome')
|
||||
->get();
|
||||
}
|
||||
|
||||
public static function show($id)
|
||||
{
|
||||
$exame = self::getExameModel($id);
|
||||
|
||||
return (object) [
|
||||
'id' => $exame->id,
|
||||
'nome' => $exame->nome,
|
||||
];
|
||||
}
|
||||
|
||||
private static function getExameModel($id)
|
||||
{
|
||||
$exame = Exame::find($id);
|
||||
|
||||
if (is_null($exame)) {
|
||||
|
||||
throw new ExameNotFoundException();
|
||||
}
|
||||
|
||||
return $exame;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user