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; } }