of($unidades) ->filterColumn('cnpj', function ($query, $keyword) { $query ->whereRaw("cadastro_unidade.cnpj like ?", ["%{$keyword}%"]) ->orWhereRaw( "CONCAT( SUBSTR(cadastro_unidade.cnpj,1,2), '.', SUBSTR(cadastro_unidade.cnpj,3,3), '.', SUBSTR(cadastro_unidade.cnpj,6,3), '/', SUBSTR(cadastro_unidade.cnpj,9,4), '-', SUBSTR(cadastro_unidade.cnpj,13,2) ) like ?", ["%{$keyword}%"] ); }) ->skipTotalRecords() ->toJson(); } public function autocomplete() { $unidades = Unidade::with([]); return datatables()->of($unidades)->toJson(); } public function index() { $this->auth(__FUNCTION__); $where = $this->getWhereFromQueryString([ 'cnpj', 'nome_fantasia', 'cnes', 'unidade_referencia', ['not_id', '<>'] ]); $unidades = $this->get(Unidade::class)->where($where)->orderBy('nome_fantasia')->get(); return response()->json($unidades, Response::HTTP_OK); } public function create() { $this->auth(__FUNCTION__); return response()->json( [ 'form' => $this->getFormData(), ], Response::HTTP_OK ); } public function store(UnidadeRequest $request) { $this->auth(__FUNCTION__); $unidade = $this->save($request->all()); return response()->json($unidade->fresh(), Response::HTTP_CREATED); } public function show($id) { $this->auth(__FUNCTION__); $unidade = $this->get(Unidade::class, $id); return response()->json($unidade, Response::HTTP_OK); } public function edit($id) { $this->auth(__FUNCTION__); $unidade = Unidade::findOrFail($id); $formData = $this->getFormData($id); return response()->json( [ 'form' => $formData, 'model' => [ 'cnpj' => $unidade->cnpj ? MaskUtil::getCnpjMasked($unidade->cnpj) : null, 'nome_fantasia' => $unidade->nome_fantasia, 'razao_social' => $unidade->razao_social, 'site' => $unidade->site, 'email' => $unidade->email, 'tipo_id' => $unidade->tipo_id, 'esfera_administrativa_id' => $unidade->esfera_administrativa_id, 'gestor' => [ 'id' => $unidade->gestor ? $unidade->gestor->id : null, 'cidadao_nome' => $unidade->gestor ? $unidade->gestor->cidadao->nome : null, ], 'natureza_juridica_id' => $unidade->natureza_juridica_id, 'cnes' => $unidade->cnes, 'pertence_sus' => $unidade->pertence_sus, 'unidade_referencia' => $unidade->unidade_referencia, 'unidade_prestadora' => $unidade->unidade_prestadora, 'infraestruturas' => $unidade->infraestruturas->map(fn ($infraestrutura) => [ 'id' => $infraestrutura->id, 'unidade_id' => $infraestrutura->infraestrutura->unidade_id ?? null, 'infraestrutura_id' => $infraestrutura->infraestrutura_id, 'principal' => $infraestrutura->principal, 'nome' => $infraestrutura->nome ?? '', 'telefone' => MaskUtil::getPhoneMasked($infraestrutura->telefone), 'endereco' => [ 'estado_id' => $infraestrutura->endereco->logradouro->municipio->estado->id, 'municipio' => $infraestrutura->endereco->logradouro->municipio, 'logradouro' => $infraestrutura->endereco->logradouro, 'numero' => $infraestrutura->endereco->numero, 'sem_numero' => $infraestrutura->endereco->sem_numero, 'complemento' => $infraestrutura->endereco->complemento ?? '', 'zona_id' => $infraestrutura->endereco->zona_id, ], 'centrosCusto' => $infraestrutura->centrosCusto->map(fn ($centroCusto) => [ 'id' => $centroCusto->id, 'setor_id' => $centroCusto->setor_id, 'setor_nome' => $centroCusto->setor->nome, 'salas' => $centroCusto->salas->map(fn ($sala) => [ 'id' => $sala->id, 'nome' => $sala->nome, ]), ]), ]), 'local' => null ], ], Response::HTTP_OK ); } private function getFormData($id = null) { return [ 'termos_invalidos' => TermoInvalido::all()->map(fn ($termo) => $termo->descricao), 'dados_administrativos' => [ 'tipos' => UnidadeTipo::orderBy('descricao')->get()->map(fn ($tipo) => [ 'id' => $tipo->id, 'descricao' => $tipo->descricao, ]), 'esferas_administrativas' => EsferaAdministrativa::orderBy('descricao')->get()->map(fn ($esfera) => [ 'id' => $esfera->id, 'descricao' => $esfera->descricao, ]), 'naturezas_juridicas' => NaturezaJuridica::orderBy('descricao')->get()->map(fn ($natureza) => [ 'id' => $natureza->id, 'descricao' => $natureza->descricao, ]), ], 'infraestruturas' => [ 'unidades' => Unidade::setEagerLoads([]) ->when($id, fn ($q) => $q->where('id', '<>', $id)) ->whereHas('infraestruturas') ->orderBy('nome_fantasia') ->get(['id', 'nome_fantasia']) ->map(fn ($unidade) => [ 'id' => $unidade->id, 'nome_fantasia' => $unidade->nome_fantasia, 'infraestruturas' => $unidade->infraestruturas()->setEagerLoads([])->with('endereco') ->get() ->sortBy('nome') ->values(), ]), 'estados' => Estado::where('pais_id', 1)->orderBy('nome')->get()->map(fn ($estado) => [ 'id' => $estado->id, 'uf' => $estado->uf, ]), 'zonas' => Zona::orderBy('descricao')->get()->map(fn ($zona) => [ 'id' => $zona->id, 'descricao' => $zona->descricao ]), ], ]; } public function update(UnidadeRequest $request, $id) { $this->auth(__FUNCTION__); $unidade = $this->save($request->all(), (Unidade::findOrFail($id))->id); return response()->json($unidade->fresh(), Response::HTTP_OK); } private function save($params, $id = null) { $unidade = null; DB::transaction(function () use (&$unidade, $params, $id) { $this->prepareUnidadeData($params); $unidade = Unidade::updateOrCreate( ['id' => $id], $params ); $infraestruturas = $params['infraestruturas'] ?? []; $this->deleteInfraestruturasNotPresent($unidade, $infraestruturas); $this->saveInfraestruturas($unidade, $infraestruturas); }); return $unidade; } private function prepareUnidadeData(&$params) { $params['nome_fantasia'] = mb_strtoupper($params['nome_fantasia']); $params['razao_social'] = mb_strtoupper($params['razao_social']); } private function deleteInfraestruturasNotPresent($unidade, $infraestruturas) { $ids = collect($infraestruturas)->pluck('id')->filter(fn ($id) => !is_null($id))->toArray(); $unidade->infraestruturas()->whereNotIn('id', $ids)->each(function ($infraestrutura) { $infraestrutura->centrosCusto()->each(function ($centroCusto) { Sala::destroy($centroCusto->salas()->pluck('id')); $centroCusto->delete(); }); $infraestrutura->delete(); }); } private function saveInfraestruturas($unidade, $infraestruturas) { foreach ($infraestruturas as $infraestrutura) { $this->prepareInfraestruturaData($infraestrutura); $enderecoSaveService = new EnderecoSaveService($infraestrutura['endereco']); $infraestrutura['endereco_id'] = ($enderecoSaveService->save())->id; $infraestruturaSaved = $unidade->infraestruturas()->updateOrCreate( ['id' => $infraestrutura['id'] ?? null], $infraestrutura ); $centrosCusto = $infraestrutura['centros_custo'] ?? []; $this->deleteCentrosCustoNotPresent($infraestruturaSaved, $centrosCusto); $this->saveCentrosCusto($infraestruturaSaved, $centrosCusto); } } private function prepareInfraestruturaData(&$params) { if (array_key_exists('nome', $params) && is_string($params['nome'])) { $params['nome'] = mb_strtoupper($params['nome']); } if (array_key_exists('principal', $params) && (int) $params['principal'] === 1 && array_key_exists('nome', $params) ) { $params['nome'] = null; } } private function deleteCentrosCustoNotPresent($infraestrutura, $centrosCusto) { $ids = collect($centrosCusto)->pluck('id')->filter(fn ($id) => !is_null($id))->toArray(); $infraestrutura->centrosCusto()->whereNotIn('id', $ids)->each(function ($centroCusto) { Sala::destroy($centroCusto->salas()->pluck('id')); $centroCusto->delete(); }); } private function saveCentrosCusto($infraestrutura, $centrosCusto) { foreach ($centrosCusto as $centroCusto) { $centroCustoSaved = $infraestrutura->centrosCusto()->updateOrCreate( ['id' => $centroCusto['id'] ?? null], $centroCusto ); $salas = $centroCusto['salas'] ?? []; $this->deleteSalasNotPresent($centroCustoSaved, $salas); $this->saveSalas($centroCustoSaved, $salas); } } private function deleteSalasNotPresent($centroCusto, $salas) { $ids = collect($salas)->pluck('id')->filter(fn ($id) => !is_null($id))->toArray(); Sala::destroy($centroCusto->salas()->whereNotIn('id', $ids)->pluck('id')); } private function saveSalas($centroCusto, $salas) { foreach ($salas as $sala) { $this->prepareSalaData($sala); $centroCusto->salas()->updateOrCreate( ['id' => $sala['id'] ?? null], $sala ); } } private function prepareSalaData(&$params) { if (array_key_exists('nome', $params) && is_string($params['nome'])) { $params['nome'] = mb_strtoupper($params['nome']); } } public function destroy($id) { $this->auth(__FUNCTION__); $unidade = Unidade::findOrFail($id); DB::transaction(function () use ($unidade) { Infraestrutura::destroy($unidade->infraestruturas()->pluck('id')); $unidade->delete(); }); return response()->json(null, Response::HTTP_NO_CONTENT); } }