Files
rkm-conectasus-ci-sandbox/api/app/Services/Farmacia/AltoCustoGerenciamentoProcessoService.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

506 lines
18 KiB
PHP

<?php
namespace App\Services\Farmacia;
use App\Enums\Cadastro\SujeitoAtencao\PreferenciaNome;
use App\Enums\Cadastro\UnidadeMedida as CadastroUnidadeMedida;
use App\Enums\Cadastro\UnidadeMedida as UnidadeMedidaEnum;
use App\Enums\Farmacia\AltoCusto\ProcessoItemMesStatus as AltoCustoProcessoItemMesStatus;
use App\Http\Controllers\Cadastro\SujeitoAtencao\PacienteController;
use App\Models\Cadastro\Estabelecimento\Unidade;
use App\Models\Cadastro\SujeitoAtencao\Paciente;
use App\Models\Cadastro\UnidadeMedida;
use App\Models\Farmacia\AltoCusto\Processo;
use App\Models\Farmacia\AltoCusto\ProcessoItemMesStatus;
use App\Models\Farmacia\AltoCusto\ProcessoNumeroRecebimento;
use App\Models\Farmacia\AltoCusto\ProcessoSubtipo;
use App\Models\Farmacia\AltoCusto\ProcessoTipo;
use App\Services\Service;
use App\Utils\MaskUtil;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\Rule;
class AltoCustoGerenciamentoProcessoService extends Service
{
public static function index($pacienteId)
{
return Processo::where('paciente_id', $pacienteId)
->get()
->map(fn ($processo) => [
'id' => $processo->id,
'solicitado_em' => $processo->solicitado_em,
'tipo' => $processo->tipo->nome,
'materiais' => $processo->itens->map(fn ($item) => $item->material->descricao_completa),
'created_centro_custo_id' => $processo->created_centro_custo_id,
]);
}
public static function create($pacienteId)
{
return [
'additionals' => self::getAdditionalsData(),
'form' => self::getFormData($pacienteId),
'model' => [
'prontuario_unidade' => Paciente::findOrFail($pacienteId)->prontuariosUnidade()
->where('unidade_id', self::getCurrentCentroCusto()->infraestrutura->unidade_id)
->first()->prontuario ?? null,
'peso' => null,
'peso_unidade_medida_id' => CadastroUnidadeMedida::QUILOGRAMAS,
'altura' => null,
'altura_unidade_medida_id' => CadastroUnidadeMedida::METROS,
'tipo_id' => null,
'subtipo_id' => null,
'solicitado_em' => null,
'unidade_solicitante_id' => null,
'usuario_solicitante' => null,
'cid' => null,
'observacoes' => null,
'observacoes_drs' => null,
'processo_devolvido_em' => null,
'motivo_processo_devolvido' => null,
'medicamento_devolvido_em' => null,
'motivo_medicamento_devolvido' => null,
'numero_recebimento' => 0,
'itens' => []
],
];
}
public static function edit($id)
{
$processo = Processo::findOrFail($id);
return [
'additionals' => self::getAdditionalsData($processo->created_centro_custo_id),
'form' => self::getFormData($processo->paciente_id),
'model' => [
'prontuario_unidade' => $processo->paciente->prontuariosUnidade()
->where('unidade_id', self::getCurrentCentroCusto()->infraestrutura->unidade_id)
->first()->prontuario ?? null,
'peso' => $processo->peso_unidade_medida_id == CadastroUnidadeMedida::GRAMAS
? (int) $processo->peso
: $processo->peso,
'peso_unidade_medida_id' => $processo->peso_unidade_medida_id ?? CadastroUnidadeMedida::QUILOGRAMAS,
'altura' => $processo->altura_unidade_medida_id == CadastroUnidadeMedida::CENTIMETROS
? (int) $processo->altura
: $processo->altura,
'altura_unidade_medida_id' => $processo->altura_unidade_medida_id ?? CadastroUnidadeMedida::METROS,
'tipo_id' => $processo->tipo_id,
'subtipo_id' => $processo->subtipo_id,
'solicitado_em' => (new Carbon($processo->solicitado_em))->format('d/m/Y'),
'unidade_solicitante_id' => $processo->unidade_solicitante_id,
'usuario_solicitante' => [
'id' => $processo->usuarioSolicitante->id,
'cidadaoNome' => $processo->usuarioSolicitante->cidadao->nome,
],
'cid' => $processo->cid ? [
'id' => $processo->cid->id,
'codigo' => $processo->cid->codigo,
'nome' => $processo->cid->nome,
] : null,
'observacoes' => $processo->observacoes,
'observacoes_drs' => $processo->observacoes_drs,
'processo_devolvido_em' => $processo->processo_devolvido_em,
'motivo_processo_devolvido' => $processo->motivo_processo_devolvido,
'medicamento_devolvido_em' => $processo->medicamento_devolvido_em,
'motivo_medicamento_devolvido' => $processo->motivo_medicamento_devolvido,
'numero_recebimento' => $processo->numero_recebimento,
'itens' => $processo->itens->map(function ($item) {
return [
'id' => $item->id,
'material' => [
'id' => $item->material->id,
'descricao_completa' => $item->material->descricao_completa,
],
'meses' => $item->meses()->orderBy('mes')->get()->map(fn ($mes) => [
'id' => $mes->id,
'mes' => $mes->mes,
'quantidade_solicitada' => fmod((float) $mes->quantidade_solicitada, 1) == 0
? (int) $mes->quantidade_solicitada
: (float) $mes->quantidade_solicitada,
'enviado_drs_em' => $mes->enviado_drs_em
? (new Carbon($mes->enviado_drs_em))->format('d/m/Y')
: null,
'retirado_drs_em' => $mes->retirado_drs_em
? (new Carbon($mes->retirado_drs_em))->format('d/m/Y')
: null,
'quantidade_retirada' => fmod((float) $mes->quantidade_retirada, 1) == 0
? (int) $mes->quantidade_retirada
: (float) $mes->quantidade_retirada,
'retirado_paciente_em' => $mes->retirado_paciente_em
? (new Carbon($mes->retirado_paciente_em))->format('d/m/Y')
: null,
'usuario_atendente' => [
'id' => $mes->usuarioAtendente->id ?? null,
'cidadao_nome' => $mes->usuarioAtendente->cidadao->nome ?? null,
],
'status' => [
'id' => $mes->status->id,
'nome' => $mes->status->nome,
],
])
];
})
],
];
}
private static function getAdditionalsData($createdCentroCustoId = null)
{
$usuarioLogado = self::getCurrentLotacao()->usuario;
return [
'data_atual' => Carbon::now()->format('d/m/Y'),
'permite_edicao' => is_null($createdCentroCustoId)
|| $createdCentroCustoId === self::getCurrentCentroCusto()->id,
'usuario_logado' => [
'id' => $usuarioLogado->id,
'cidadao_nome' => $usuarioLogado->cidadao->nome,
],
];
}
private static function getFormData($pacienteId)
{
$paciente = Paciente::findOrFail($pacienteId);
return [
'paciente' => [
'nome' => $paciente->cidadao->nome,
'nome_social' => $paciente->cidadao->preferencia_nome_id == PreferenciaNome::NOME_SOCIAL
? $paciente->cidadao->nome_social
: null,
'prontuario' => $paciente->prontuario,
'telefone' => MaskUtil::getPhoneMasked($paciente->cidadao->telefone_principal->numero ?? null),
'sexo' => $paciente->cidadao->sexo->descricao,
'cpf' => MaskUtil::getCpfMasked($paciente->cidadao->cpf),
'data_nascimento' => is_null($paciente->cidadao->data_nascimento)
? null : (new Carbon($paciente->cidadao->data_nascimento))->format('d/m/Y'),
'nome_mae' => $paciente->cidadao->nome_mae,
'cns' => MaskUtil::getCnsMasked($paciente->cidadao->cns),
'idade' => $paciente->cidadao->idade_formatada,
'unidade_referencia' => $paciente->unidade->nome_fantasia ?? null,
'rg' => $paciente->cidadao->carteiraIdentidade->numero ?? null,
],
'unidades_medida' => UnidadeMedida::all(['id', 'sigla']),
'unidades' => Unidade::orderBy('nome_fantasia')->get(['id', 'nome_fantasia']),
'tipos' => ProcessoTipo::orderBy('nome')->get(['id', 'nome']),
'subtipos' => ProcessoSubtipo::orderBy('nome')->get(['id', 'tipo_id', 'nome']),
'status' => ProcessoItemMesStatus::all(['id', 'nome']),
'meses' => self:: getMeses(),
];
}
private static function getMeses()
{
$meses = collect();
for ($i = 1; $i <= 12; $i++) {
$meses->push(['value' => $i, 'text' => $i]);
}
return $meses;
}
public static function store()
{
self::validate();
$processo = new Processo();
DB::transaction(function () use ($processo) {
self::save($processo);
});
return $processo;
}
public static function update($id)
{
$processo = Processo::findOrFail($id);
self::validate();
DB::transaction(function () use ($processo) {
self::save($processo);
});
return $processo;
}
private static function save($processo)
{
$processo->fill(request()->except('itens'));
$processo->save();
$itens = collect(request()->itens);
$processo->itens()
->whereNotIn('id', $itens->filter(fn ($i) => !is_null($i['id']))->pluck('id'))
->get()
->each(function ($item) {
$item->meses()->delete();
$item->delete();
});
PacienteController::saveProntuarioUnidade(
$processo->paciente_id,
self::getCurrentCentroCusto()->infraestrutura->unidade_id,
request()->prontuario_unidade
);
$itens->each(function ($itemData) use ($processo) {
$item = $processo->itens()->firstOrCreate(
['id' => $itemData['id']],
$itemData
);
$meses = collect($itemData['meses']);
$item->meses()
->whereNotIn('id', $meses->filter(fn ($m) => !is_null($m['id']))->pluck('id'))
->delete();
$meses->each(function ($mesData) use ($item) {
$item->meses()->updateOrCreate(
['id' => $mesData['id']],
$mesData
);
});
});
$processo->refresh();
$processo->numero_recebimento = self::getNumeroRecebimento($processo);
$processo->save();
return $processo;
}
private static function getNumeroRecebimento($processo)
{
$hasPendenteRetiradaPaciente = $processo->itens()
->whereHas('meses', function ($query) {
$query->where('status_id', AltoCustoProcessoItemMesStatus::PENDENTE_RETIRADA_PACIENTE);
})
->exists();
if ($hasPendenteRetiradaPaciente) {
if ($processo->numero_recebimento > 0) {
return $processo->numero_recebimento;
}
else {
$outroProcesso = Processo::where('id', '<>', $processo->id)
->where('created_centro_custo_id', self::getCurrentCentroCusto()->id)
->where('paciente_id', $processo->paciente_id)
->whereHas('itens', function ($query) {
$query->whereHas('meses', function ($query) {
$query->where('status_id', AltoCustoProcessoItemMesStatus::PENDENTE_RETIRADA_PACIENTE);
});
})
->first();
if (is_null($outroProcesso)) {
$numeroRecebimento = (ProcessoNumeroRecebimento::where(
'centro_custo_id',
self::getCurrentCentroCusto()->id
)
->first()->numero ?? 0) + 1;
ProcessoNumeroRecebimento::updateOrCreate(
['centro_custo_id' => self::getCurrentCentroCusto()->id],
['numero' => $numeroRecebimento]
);
return $numeroRecebimento;
}
else {
return $outroProcesso->numero_recebimento;
}
}
}
else {
return 0;
}
}
public static function destroy($id)
{
$processo = Processo::findOrFail($id);
DB::transaction(function () use ($processo) {
$processo->delete();
});
}
private static function validate()
{
$rules = [
'paciente_id' => [
'required',
'integer',
],
'prontuario_unidade' => [
'nullable',
'string',
'max:10',
],
'peso' => [
'nullable',
'numeric',
'max:999999.99',
],
'peso_unidade_medida_id' => [
'nullable',
'required_with:peso',
'integer',
Rule::in([UnidadeMedidaEnum::GRAMAS, UnidadeMedidaEnum::QUILOGRAMAS]),
],
'altura' => [
'nullable',
'numeric',
'max:999.99',
],
'altura_unidade_medida_id' => [
'nullable',
'required_with:altura',
'integer',
Rule::in([UnidadeMedidaEnum::CENTIMETROS, UnidadeMedidaEnum::METROS]),
],
'tipo_id' => [
'required',
'integer',
],
'subtipo_id' => [
'nullable',
'integer',
],
'solicitado_em' => [
'required',
'date_format:Y-m-d'
],
'unidade_solicitante_id' => [
'required',
'integer',
],
'usuario_solicitante_id' => [
'required',
'integer',
],
'cid_id' => [
'nullable',
'integer',
],
'observacoes' => [
'nullable',
'string',
'max:5000'
],
'observacoes_drs' => [
'nullable',
'string',
'max:5000'
],
'processo_devolvido_em' => [
'nullable',
'date_format:Y-m-d'
],
'motivo_processo_devolvido' => [
'nullable',
'string',
'max:5000'
],
'medicamento_devolvido_em' => [
'nullable',
'date_format:Y-m-d'
],
'motivo_medicamento_devolvido' => [
'nullable',
'string',
'max:5000'
],
'itens.*.id' => [
'nullable',
'integer',
],
'itens.*.material_id' => [
'required',
'integer',
],
'itens.*.meses' => [
'array',
'required',
],
'itens.*.meses.*.id' => [
'nullable',
'integer',
],
'itens.*.meses.*.mes' => [
'required',
'integer',
'between:1,12',
],
'itens.*.meses.*.quantidade_solicitada' => [
'required',
'numeric',
'min:0.001',
'max:999.999',
],
'itens.*.meses.*.enviado_drs_em' => [
'nullable',
'required_with:itens.*.meses.*.retirado_drs_em',
'date_format:Y-m-d',
],
'itens.*.meses.*.retirado_drs_em' => [
'nullable',
'required_with:itens.*.meses.*.retirado_paciente_em',
'date_format:Y-m-d',
'after_or_equal:itens.*.meses.*.enviado_drs_em',
],
'itens.*.meses.*.quantidade_retirada' => [
'required',
'numeric',
'min:0.001',
'max:999.999',
// 'max:itens.*.meses.*.quantidade_solicitada',
],
'itens.*.meses.*.retirado_paciente_em' => [
'nullable',
'date_format:Y-m-d',
'after_or_equal:itens.*.meses.*.retirado_drs_em',
],
'itens.*.meses.*.usuario_atendente_id' => [
'nullable',
'integer',
],
'itens.*.meses.*.status_id' => [
'required',
'integer',
],
];
$messages = [];
request()->validate($rules, $messages);
}
}