Files
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

670 lines
22 KiB
PHP

<?php
namespace App\Services\Manutencao;
use App\Enums\Cadastro\Grupo\GrupoTipo as GrupoEnum;
use App\Enums\Manutencao\StatusOrigem as StatusOrigemEnum;
use App\Enums\Manutencao\StatusTipo as StatusEnum;
use App\Exceptions\Manutencao\CannotStoreSolicitacaoException;
use App\Models\Cadastro\Grupo\Grupo;
use App\Models\Cadastro\ServicoManutencao;
use App\Models\Cadastro\ServicoManutencaoCausasProvaveis;
use App\Models\Cadastro\Subgrupo\Subgrupo;
use App\Models\Manutencao\Solicitacao;
use App\Models\Manutencao\SolicitacaoCausaProvavel;
use App\Models\Manutencao\SolicitacaoMensagem;
use App\Models\Manutencao\SolicitacaoResposta;
use App\Models\Manutencao\SolicitacaoStatusHistorico;
use App\Models\Manutencao\Status;
use App\Services\Service;
use Carbon\Carbon;
use DB;
use DateTimeImmutable;
use Illuminate\Validation\Rule;
class SolicitacaoService extends Service
{
public static function datatable()
{
$solicitacoes = DB::table('manutencao_solicitacao as solicitacao')
->where('solicitacao.infraestrutura_solicitante_id', self::getCurrentLotacao()->infraestrutura->id)
->where('solicitacao.status_id', '<>', StatusEnum::FINALIZADO)
->join('cadastro_grupo as grupo', 'grupo.id', 'solicitacao.grupo_id')
->join('cadastro_servico_manutencao as servico', 'servico.id', 'solicitacao.servico_id')
->join('manutencao_parametrizacao_status as status', 'status.id', 'solicitacao.status_id')
->join('cadastro_usuario as usuario', 'usuario.id', 'solicitacao.usuario_solicitante_id')
->join('cadastro_cidadao as cidadao', 'cidadao.id', 'usuario.cidadao_id')
->join('manutencao_status_tipo as status_tipo', 'status_tipo.id', 'status.tipo_id')
->leftJoin('manutencao_gerenciamento_mensagem as mensagem', 'mensagem.solicitacao_id', 'solicitacao.id')
->leftJoin('manutencao_solicitacao_resposta as resposta', 'resposta.mensagem_id', 'mensagem.id')
->select(
'solicitacao.id',
'solicitacao.codigo',
DB::raw('DATE_FORMAT(solicitacao.created_at, "%d/%m/%Y") as data_solicitacao'),
'grupo.nome as grupo',
'servico.nome as servico',
'solicitacao.assunto',
DB::raw("
CASE
WHEN solicitacao.pendente_finalizacao = TRUE THEN CONCAT(status.nome, ' - FINALIZAÇÃO PEDENTE')
WHEN EXISTS (
SELECT 1
FROM manutencao_gerenciamento_mensagem
WHERE manutencao_gerenciamento_mensagem.solicitacao_id = solicitacao.id
AND manutencao_gerenciamento_mensagem.is_respondida = FALSE
) THEN CONCAT(status.nome, ' - MENSAGEM PENDENTE')
ELSE status.nome
END as status
"),
'cidadao.nome as usuario_solicitante',
'status_tipo.id as tipo_status',
DB::raw("
(
SELECT COUNT(*)
FROM manutencao_gerenciamento_mensagem
WHERE manutencao_gerenciamento_mensagem.solicitacao_id = solicitacao.id
AND manutencao_gerenciamento_mensagem.is_respondida = FALSE
) > 0 AS mensagem_pendente
"),
DB::raw("
EXISTS (
SELECT 1
FROM manutencao_parametrizacao_status
WHERE manutencao_parametrizacao_status.tipo_id = " . StatusEnum::EM_ABERTO . "
AND solicitacao.status_id = manutencao_parametrizacao_status.id
) AS allow_edit
"),
DB::raw("
EXISTS (
SELECT 1
FROM manutencao_parametrizacao_status
WHERE manutencao_parametrizacao_status.tipo_id = " . StatusEnum::EM_ATENDIMENTO . "
AND solicitacao.status_id = manutencao_parametrizacao_status.id
) AS allow_cancel
"),
DB::raw("
EXISTS (
SELECT 1
FROM manutencao_parametrizacao_status
WHERE (manutencao_parametrizacao_status.tipo_id = " . StatusEnum::FINALIZADO . "
OR manutencao_parametrizacao_status.tipo_id = " . StatusEnum::CANCELADO . ")
AND solicitacao.status_id = manutencao_parametrizacao_status.id
) AS allow_reopen
"),
DB::raw("
EXISTS (
SELECT 1
FROM manutencao_parametrizacao_status
WHERE manutencao_parametrizacao_status.tipo_id = " . StatusEnum::EM_ABERTO . "
AND solicitacao.status_id = manutencao_parametrizacao_status.id
) AS allow_destroy
"),
'solicitacao.grupo_id',
'solicitacao.infraestrutura_solicitante_id',
'solicitacao.usuario_solicitante_id',
'solicitacao.pendente_finalizacao',
'mensagem.id as mensagem_id',
'mensagem.mensagem as mensagem_conteudo',
'mensagem.created_at as mensagem_data_envio',
'resposta.id as resposta_id',
'resposta.mensagem as resposta_conteudo',
'resposta.created_at as resposta_data_envio',
'cidadao.nome as usuario_nome_mensagem',
DB::raw('
(
SELECT nome
FROM cadastro_cidadao
WHERE id = (SELECT cidadao_id FROM cadastro_usuario WHERE id = resposta.usuario_id)
) as usuario_nome_resposta
')
)
->orderBy('solicitacao.created_at', 'desc')
->get();
$solicitacoes = $solicitacoes->groupBy('id')->map(function ($group) {
$solicitacao = $group->first();
$mensagens = collect();
$group->each(function ($item) use ($mensagens) {
if ($item->mensagem_id) {
$mensagens->push([
'mensagem' => [
'mensagem_id' => $item->mensagem_id,
'mensagem_conteudo' => $item->mensagem_conteudo,
'mensagem_data' => Carbon::parse($item->mensagem_data_envio)->format('d/m/Y'),
'mensagem_hora' => Carbon::parse($item->mensagem_data_envio)->format('H:i'),
'mensagem_usuario' => $item->usuario_nome_mensagem,
],
'resposta' => $item->resposta_id ? [
'resposta_id' => $item->resposta_id,
'resposta_mensagem' => $item->resposta_conteudo,
'resposta_data' => Carbon::parse($item->resposta_data_envio)->format('d/m/Y'),
'resposta_hora' => Carbon::parse($item->resposta_data_envio)->format('H:i'),
'resposta_usuario' => $item->usuario_nome_resposta,
] : null,
]);
}
});
$solicitacao->mensagens_resposta = $mensagens->values();
return $solicitacao;
})->values();
return $solicitacoes;
}
public static function create()
{
return [
'model' => self::getModelData(),
'form' => self::getFormData(),
];
}
private static function getModelData()
{
return [
'infraestrutura_solicitante_id' => self::getCurrentLotacao()->infraestrutura->id,
'usuario_solicitante' => [
'id' => self::getCurrentLotacao()->usuario->id,
'cidadao_nome' => self::getCurrentLotacao()->usuario->cidadao->nome,
],
'grupo_id' => null,
'sub_grupo_id' => null,
'servico_id' => null,
'causa_provavel_id' => null,
'causa_provavel_lista' => [],
'assunto' => null,
'detalhe' => null,
];
}
private static function getFormData()
{
return [
'unidade_solicitante' => self::getUnidadesSolicitantes(),
'grupo' => Grupo::where('grupo_tipo_id', GrupoEnum::MANUTENCAO)
->get(),
'sub_grupo' => [],
'servico' => [],
'causa_provavel' => [],
];
}
private static function getUnidadesSolicitantes()
{
return DB::table('cadastro_unidade as unidade')
->join(
'cadastro_infraestrutura as infraestrutura',
'infraestrutura.unidade_id',
'unidade.id'
)
->whereNull('unidade.deleted_at')
->orderBy('unidade.nome_fantasia')
->selectRaw("
infraestrutura.id,
unidade.nome_fantasia
")
->get();
}
public static function list()
{
$params = request()->only('params');
switch (request()->listar) {
case 'subGrupo':
return self::getSubgrupos($params);
case 'servico':
return self::getServicos($params);
case 'causaProvavel':
return self::getCausasProvaveis($params);
default:
$data = [];
break;
}
}
private static function getSubgrupos($params)
{
return Subgrupo::where('grupo_id', $params)
->get();
}
private static function getServicos($params)
{
return ServicoManutencao::where('sub_grupo_id', $params)
->get();
}
private static function getCausasProvaveis($params)
{
return ServicoManutencaoCausasProvaveis::where('servico_manutencao_id', $params)
->get();
}
public static function store()
{
self::validate();
$solicitacao = new Solicitacao();
$status_em_aberto_id = Status::where('tipo_id', StatusEnum::EM_ABERTO)
->first()
->id;
if (!$status_em_aberto_id) {
throw new CannotStoreSolicitacaoException();
}
DB::transaction(function () use ($solicitacao, $status_em_aberto_id) {
$solicitacao->fill([
'infraestrutura_solicitante_id' => request('infraestrutura_solicitante_id'),
'usuario_solicitante_id' => request('usuario_solicitante_id'),
'grupo_id' => request('grupo_id'),
'subgrupo_id' => request('sub_grupo_id'),
'assunto' => request('assunto') ?? null,
'detalhe' => request('detalhe') ?? null,
'servico_id' => request('servico_id') ?? null,
'status_id' => $status_em_aberto_id,
'codigo' => self::getNumeroSolicitacao(),
]);
$solicitacao->save();
$solicitacaoStatusHistorico = new SolicitacaoStatusHistorico();
$solicitacaoStatusHistorico->fill([
'solicitacao_id' => $solicitacao->id,
'status_id' => $status_em_aberto_id,
'origem_id' => StatusOrigemEnum::SOLICITANTE,
'usuario_id' => request('usuario_solicitante_id'),
'infraestrutura_id' => request('infraestrutura_solicitante_id'),
'mensagem' => null,
]);
$solicitacaoStatusHistorico->save();
collect(request()->causa_provavel_lista)->each(function ($causaProvavel) use ($solicitacao) {
$solicitacao->causaProvavel()->create([
'solicitacao_id' => $solicitacao->id,
'causa_provavel_id' => $causaProvavel['id'],
]);
});
});
return $solicitacao->refresh();
}
public static function getNumeroSolicitacao()
{
$ultimoCodigoUtilizado = Solicitacao::orderBy('codigo', 'desc')
->first()
->codigo ?? 0;
return $ultimoCodigoUtilizado + 1;
}
public static function edit($id)
{
$solicitacao = Solicitacao::findOrFail($id);
$usuarioSolicitante = DB::table('cadastro_usuario as usuario')
->join('cadastro_cidadao as cidadao', 'cidadao.id', 'usuario.cidadao_id')
->where('usuario.id', $solicitacao->usuario_solicitante_id)
->select('usuario.id', 'cidadao.nome as cidadao_nome')
->first();
return [
'model' => [
'id' => $solicitacao->id,
'infraestrutura_solicitante_id' => $solicitacao->infraestrutura_solicitante_id,
'usuario_solicitante' => [
'id' => $usuarioSolicitante->id,
'cidadao_nome' => $usuarioSolicitante->cidadao_nome,
],
'grupo_id' => $solicitacao->grupo_id,
'sub_grupo_id' => $solicitacao->subgrupo_id,
'servico_id' => $solicitacao->servico_id,
'causa_provavel_id' => null,
'causa_provavel_lista' => $solicitacao->causaProvavel->map(function ($causaProvavel) {
return [
'id' => $causaProvavel->causa_provavel_id,
'nome' => $causaProvavel->causaProvavel->nome,
'observacao' => $causaProvavel->causaProvavel->observacao,
];
}),
'assunto' => $solicitacao->assunto ?? null,
'detalhe' => $solicitacao->detalhe ?? null,
],
'form' => [
'unidade_solicitante' => self::getUnidadesSolicitantes(),
'grupo' => Grupo::where('grupo_tipo_id', GrupoEnum::MANUTENCAO)
->get(),
'sub_grupo' => Subgrupo::where('grupo_id', $solicitacao->grupo_id)
->get(),
'servico' => ServicoManutencao::where('sub_grupo_id', $solicitacao->subgrupo_id)
->get(),
'causa_provavel' => ServicoManutencaoCausasProvaveis::where('servico_manutencao_id', $solicitacao->servico_id)
->get(),
],
];
}
public static function update($id)
{
$solicitacao = Solicitacao::findOrFail($id);
if (request()->filled('acao')) {
switch (request('acao')) {
case 'cancelar':
return self::cancelar($solicitacao);
case 'reabrir':
return self::reabrir($solicitacao);
case 'finalizar':
return self::finalizar($solicitacao);
case 'responder':
return self::responder($solicitacao);
default:
return self::updateSolicitacao($solicitacao);
}
} else {
return self::updateSolicitacao($solicitacao);
}
}
private static function cancelar($solicitacao)
{
self::validateCancelamento();
$status_cancelado_id = Status::where('tipo_id', StatusEnum::CANCELADO)
->first()
->id ?? null;
if (!$status_cancelado_id) {
throw new CannotStoreSolicitacaoException();
}
$solicitacao->status_id = $status_cancelado_id;
$solicitacao->save();
self::storeHistorico($solicitacao);
return $solicitacao->refresh();
}
private static function reabrir($solicitacao)
{
self::validateReabrir();
$status_em_atendimento_id = Status::where('tipo_id', StatusEnum::EM_ATENDIMENTO)
->first()
->id ?? null;
if (!$status_em_atendimento_id) {
throw new CannotStoreSolicitacaoException();
}
$solicitacao->status_id = $status_em_atendimento_id;
$solicitacao->save();
self::storeHistorico($solicitacao);
return $solicitacao->refresh();
}
private static function finalizar($solicitacao)
{
self::validateFInalizar();
$status_finalizado_id = Status::where('tipo_id', StatusEnum::FINALIZADO)
->first()
->id ?? null;
if (!$status_finalizado_id) {
throw new CannotStoreSolicitacaoException();
}
$solicitacao->status_id = $status_finalizado_id;
$solicitacao->pendente_finalizacao = false;
$solicitacao->save();
self::storeHistorico($solicitacao);
return $solicitacao->refresh();
}
private static function responder($solicitacao)
{
self::validateResponder();
$mensagem = new SolicitacaoResposta();
$mensagem->fill([
'solicitacao_id' => $solicitacao->id,
'mensagem_id' => request('mensagem_id'),
'infraestrutura_id' => self::getCurrentCentroCusto()->infraestrutura->id,
'usuario_id' => self::getCurrentLotacao()->usuario->id,
'mensagem' => request('resposta'),
]);
$mensagem->save();
$solicitacaoMensagem = SolicitacaoMensagem::findOrFail(request('mensagem_id'));
$solicitacaoMensagem->is_respondida = true;
$solicitacaoMensagem->save();
self::storeHistorico($solicitacao);
return $solicitacao->refresh();
}
private static function updateSolicitacao($solicitacao)
{
self::validate();
DB::transaction(function () use ($solicitacao) {
$solicitacao->fill([
'infraestrutura_solicitante_id' => request('infraestrutura_solicitante_id'),
'usuario_solicitante_id' => request('usuario_solicitante_id'),
'grupo_id' => request('grupo_id'),
'subgrupo_id' => request('sub_grupo_id') ?? $solicitacao->subgrupo_id,
'assunto' => request('assunto'),
'detalhe' => request('detalhe'),
'servico_id' => request('servico_id') ?? $solicitacao->servico_id,
]);
$solicitacao->save();
$solicitacao->causaProvavel()->delete();
collect(request()->causa_provavel_lista)->each(function ($causaProvavel) use ($solicitacao) {
$solicitacao->causaProvavel()->create([
'solicitacao_id' => $solicitacao->id,
'causa_provavel_id' => $causaProvavel['id'],
]);
});
self::storeHistorico($solicitacao);
});
return $solicitacao->refresh();
}
private static function storeHistorico($solicitacao)
{
$solicitacaoStatusHistorico = new SolicitacaoStatusHistorico();
$solicitacaoStatusHistorico->create([
'solicitacao_id' => $solicitacao->id,
'status_id' => $solicitacao->status_id,
'origem_id' => StatusOrigemEnum::SOLICITANTE,
'usuario_id' => request('usuario_solicitante_id') ?? self::getCurrentLotacao()->usuario->id,
'infraestrutura_id' => request('infraestrutura_solicitante_id') ?? self::getCurrentCentroCusto()->infraestrutura->id,
'mensagem' => request('justificativa') ?? null,
]);
return $solicitacaoStatusHistorico;
}
public static function validate()
{
$rule = [
'infraestrutura_solicitante_id' => [
'required',
'integer',
Rule::exists('cadastro_infraestrutura', 'id'),
],
'usuario_solicitante_id' => [
'required',
'integer',
Rule::exists('cadastro_usuario', 'id'),
],
'grupo_id' => [
'required',
'integer',
Rule::exists('cadastro_grupo', 'id'),
],
'sub_grupo_id' => [
'nullable',
'integer',
Rule::exists('cadastro_subgrupo', 'id'),
],
'servico_id' => [
'nullable',
'integer',
Rule::exists('cadastro_servico_manutencao', 'id'),
],
'assunto' => [
'nullable',
'string',
'max:150',
'min:3',
],
'descricao' => [
'nullable',
'string',
'max:1000',
'min:3',
]
];
request()->validate($rule);
}
private static function validateCancelamento()
{
$rule = [
'justificativa' => [
'required',
'string',
'max:300',
'min:3',
],
];
request()->validate($rule);
}
private static function validateReabrir()
{
$rule = [
'justificativa' => [
'required',
'string',
'max:300',
'min:3',
],
];
request()->validate($rule);
}
private static function validateFInalizar()
{
$rule = [
'observacao' => [
'required',
'string',
'max:300',
'min:3',
],
];
request()->validate($rule);
}
private static function validateResponder()
{
$rule = [
'resposta' => [
'required',
'string',
'max:500',
'min:3',
],
'mensagem_id' => [
'required',
'integer',
Rule::exists('manutencao_gerenciamento_mensagem', 'id'),
],
];
request()->validate($rule);
}
public static function destroy($id)
{
SolicitacaoCausaProvavel::where('solicitacao_id', $id)->delete();
SolicitacaoStatusHistorico::where('solicitacao_id', $id)->delete();
SolicitacaoMensagem::where('solicitacao_id', $id)->delete();
SolicitacaoResposta::where('solicitacao_id', $id)->delete();
Solicitacao::findOrFail($id)->delete();
return null;
}
}