select( 'painel_senha_aviso.id', 'painel_senha_aviso.mensagem', DB::raw('GROUP_CONCAT(cadastro_unidade.nome_fantasia) as unidades'), DB::raw('GROUP_CONCAT(cadastro_unidade.id) as ids_unidade'), 'painel_senha_aviso.is_ativo', ) ->join('painel_senha_aviso_unidade', 'painel_senha_aviso_unidade.aviso_id', 'painel_senha_aviso.id') ->leftJoin('cadastro_unidade', 'cadastro_unidade.id', 'painel_senha_aviso_unidade.unidade_id') ->groupBy('painel_senha_aviso.id', 'painel_senha_aviso.mensagem', 'painel_senha_aviso.is_ativo') ->get(); return datatables() ->of($avisos) ->toJson(); } public static function create() { return [ 'additionals' => self::getAdditionalsData(), 'form' => self::getFormData(), 'model' => [ 'mensagem' => null, 'unidades' => null, 'is_ativo' => true, 'unidades' => [], 'periodo' => [ 'start' => null, 'end' => null, ], 'hora_inicial' => null, 'hora_final' => null, 'dias_semana' => [], 'intervalo' => null, ] ]; } public static function edit($id) { $aviso = DB::table('painel_senha_aviso') ->select( 'painel_senha_aviso.id as aviso_id', 'painel_senha_aviso.mensagem', DB::raw('GROUP_CONCAT(painel_senha_aviso_unidade.unidade_id) as unidades'), 'painel_senha_aviso.is_ativo', 'painel_senha_aviso.data_inicial', 'painel_senha_aviso.data_final', 'painel_senha_aviso.hora_inicial', 'painel_senha_aviso.hora_final', 'painel_senha_aviso.dias_semana', 'painel_senha_aviso.intervalo', ) ->join('painel_senha_aviso_unidade', 'painel_senha_aviso_unidade.aviso_id', 'painel_senha_aviso.id') ->groupBy('aviso_id', 'painel_senha_aviso.mensagem') ->where('aviso_id', $id) ->first('aviso_id'); if(!isset($aviso)) { return response()->json([ 'message' => 'Não foi possível localizar esse aviso!' ], Response::HTTP_BAD_REQUEST); } $dados = [ 'additionals' => self::getAdditionalsData(), 'form' => self::getFormData(), 'model' => [ 'mensagem' => $aviso->mensagem, 'unidades' => array_map('intval', explode(',', $aviso->unidades)), 'is_ativo' => (bool) $aviso->is_ativo, 'periodo' => [ 'start' => $aviso->data_inicial, 'end' => $aviso->data_final, ], 'hora_inicial' => $aviso->hora_inicial, 'hora_final' => $aviso->hora_final, 'dias_semana' => explode(',', $aviso->dias_semana), 'intervalo' => $aviso->intervalo, ] ]; return response()->json($dados, Response::HTTP_OK); } public static function store(AvisoRequest $request, $avisoId = null): array { $params = $request->all(); $params['data_inicial'] = Carbon::parse($params["periodo"]["start"])->format('Y-m-d');; $params['data_final'] = Carbon::parse($params["periodo"]["end"])->format('Y-m-d');; $params['dias_semana'] = implode(',', $params['dias_semana']); unset($params['periodo']); $recorrencias = self::calculaRecorrencias($params); if($recorrencias->isEmpty()) { return [['message' => 'Nenhuma data/horário foram contemplados para esse período. Por favor, aumente a data ou os dias da semana!'], Response::HTTP_BAD_REQUEST]; } if($avisoId) { $aviso = Aviso::where('id', $avisoId)->update([ "mensagem" => $params["mensagem"], "is_ativo" => $params["is_ativo"], "data_inicial" => $params["data_inicial"], "data_final" => $params["data_final"], "hora_inicial" => $params["hora_inicial"], "hora_final" => $params["hora_final"], "dias_semana" => $params["dias_semana"], "intervalo" => $params["intervalo"], ]); } else { $aviso = Aviso::create($params); } $avisoId = $aviso->id ?? $avisoId; self::insereRecorrenciaAgendamentos($recorrencias, $avisoId); self::insereUnidades($params, $avisoId); return [$aviso, Response::HTTP_OK]; } public static function update($id, AvisoRequest $request): array { $aviso = Aviso::find($id); if(!isset($aviso)) { return [['message' => 'Não foi possível atualizar esse aviso'], Response::HTTP_BAD_REQUEST]; } AvisoAgendamento::where('aviso_id', $id)->delete(); AvisoUnidade::where('aviso_id', $id)->delete(); return self::store($request, $id); } public static function destroy($id) { AvisoAgendamento::where('aviso_id', $id)->delete(); AvisoUnidade::where('aviso_id', $id)->delete(); Aviso::where('id', $id)->delete(); return [[], Response::HTTP_OK]; } public static function send() { $agora = Carbon::now(); $params = request()->all(); $aviso = Aviso::find($params['id']); if(!$aviso) { return [['message' => 'Não foi possível enviar aviso. Pois o mesmo não foi localizado!'], Response::HTTP_BAD_REQUEST]; } AvisoEvent::dispatch($params['id'], $params); AvisoAgendamento::insert([ "aviso_id" => $aviso->id, "data_hora_executada" => $agora, "is_envio_manual" => true, "created_at" => $agora, ]); return [$aviso, Response::HTTP_OK]; } public static function mudarStatus($id) { $aviso = Aviso::find($id); if(!$aviso) { return [['message' => 'Não foi possível mudar o status do aviso. Pois o mesmo não foi localizado!'], Response::HTTP_BAD_REQUEST]; } $statusAtual = !!$aviso->is_ativo; $statusModificado = !$statusAtual; $aviso->is_ativo = $statusModificado; $aviso->save(); return [$aviso, Response::HTTP_OK]; } private static function getAdditionalsData() { return [ 'min_data' => Carbon::now()->format('d/m/Y'), 'max_data' => Carbon::now()->addYear()->format('d/m/Y'), ]; } private static function getFormData() { return [ 'unidades' => DB::table('cadastro_unidade') ->select([ 'id', 'nome_fantasia as nome', ]) ->orderBy('nome') ->get(), 'dias_semana' => DiaSemana::get() ->map(fn ($feriado) => [ 'id' => $feriado->id, 'descricao' => $feriado->descricao, 'disabled' => false, ]), 'intervalos' => [ [ 'valor' => 15, 'descricao' => '15 minutos', ], [ 'valor' => 30, 'descricao' => '30 minutos', ], [ 'valor' => 60, 'descricao' => '1 hora', ], [ 'valor' => 120, 'descricao' => '2 horas', ], [ 'valor' => 180, 'descricao' => '3 horas', ], [ 'valor' => 240, 'descricao' => '4 horas', ], ], ]; } private static function calculaRecorrencias($params) { $recorrencias = collect(); $start = Carbon::parse($params['data_inicial'] . ' ' . $params['hora_inicial']); $end = Carbon::parse($params['data_final'] . ' ' . $params['hora_final']); $diasSemana = is_array($params['dias_semana']) ? $params['dias_semana'] : explode(',', $params['dias_semana']); $intervalo = CarbonInterval::minutes($params['intervalo']); while ($start <= $end) { if (in_array($start->dayOfWeek + 1, $diasSemana)) { if ($start->format('H:i:s') <= $end->format('H:i:s')) { $recorrencias->push($start->format('Y-m-d H:i:s')); } } $start->add($intervalo); if ($start->greaterThan($end)) { break; } } return $recorrencias; } private static function insereRecorrenciaAgendamentos($recorrencias, $avisoId) { $agora = Carbon::now(); $agendamentos = $recorrencias->map(fn($data) => [ "aviso_id" => $avisoId, "data_hora_agendada" => $data, "data_hora_executada" => null, "is_envio_manual" => false, "created_at" => $agora ])->toArray(); foreach (array_chunk($agendamentos, 500) as $chunk) { AvisoAgendamento::insert($chunk); } } private static function insereUnidades($params, $avisoId) { $unidades = collect($params["unidades"]); $dados = $unidades->map(fn($unidade) => [ "aviso_id" => $avisoId, "unidade_id" => $unidade ])->toArray(); AvisoUnidade::insert($dados); } }