Skip to content

Commit

Permalink
Merge pull request #972 from portabilis/portabilis-patch-2024-10-09
Browse files Browse the repository at this point in the history
Portábilis Patch 09/10/2024
  • Loading branch information
edersoares authored Oct 10, 2024
2 parents 2aeb18f + fc42a35 commit 70850d7
Show file tree
Hide file tree
Showing 39 changed files with 1,215 additions and 44 deletions.
2 changes: 2 additions & 0 deletions app/Exceptions/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use iEducar\Modules\ErrorTracking\Tracker;
use iEducar\Support\Exceptions\DisciplinesWithoutInformedHoursException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Validation\ValidationException;
use Throwable;

class Handler extends ExceptionHandler
Expand All @@ -19,6 +20,7 @@ class Handler extends ExceptionHandler
protected $dontReport = [
App_Model_Exception::class,
DisciplinesWithoutInformedHoursException::class,
ValidationException::class,
];

/**
Expand Down
95 changes: 95 additions & 0 deletions app/Http/Controllers/AnnouncementPublishController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<?php

namespace App\Http\Controllers;

use App\Http\Requests\AnnouncementRequest;
use App\Models\Announcement;
use App\Process;
use iEducar\Support\Exceptions\Exception;
use Illuminate\Support\Facades\DB;

class AnnouncementPublishController extends Controller
{
public function index()
{
$this->menu(Process::ANNOUNCEMENT);
$this->breadcrumb('Publicação de avisos', [
url('/intranet/educar_configuracoes_index.php') => 'Configurações',
]);
$announcements = Announcement::query()
->withTrashed()
->with([
'userTypes',
])
->latest()
->paginate();

return view('announcement.publish.index', [
'announcements' => $announcements,
]);
}

public function update(AnnouncementRequest $request, $announcementId)
{
try {
DB::beginTransaction();
$announcement = Announcement::query()->withTrashed()->findOrFail($announcementId);
$announcement->fill($request->all());
$announcement->save();
$announcement->userTypes()->sync($request->get('tipo_usuario'));
$request->get('active') ? $announcement->restore() : $announcement->delete();
DB::commit();
session()->flash('success', 'Edição efetuada com sucesso.');
} catch (Exception) {
DB::rollBack();
session()->flash('error', 'Edição não realizada.');
}

return redirect()->route('announcement.publish.edit', $announcementId);
}

public function store(AnnouncementRequest $request)
{
try {
DB::beginTransaction();
$announcement = Announcement::create($request->all());
$announcement->userTypes()->sync($request->get('tipo_usuario'));
$request->get('active') ? $announcement->restore() : $announcement->delete();
DB::commit();
session()->flash('success', 'Cadastro efetuado com sucesso.');
} catch (Exception) {
DB::rollBack();
session()->flash('error', 'Cadastro não realizado.');
}

return redirect()->route('announcement.publish.index');
}

public function create()
{
$this->menu(Process::ANNOUNCEMENT);
$this->breadcrumb('Publicação de avisos', [
url('/intranet/educar_configuracoes_index.php') => 'Configurações',
]);

return view('announcement.publish.create', [
'announcement' => new Announcement(),
'userTypes' => null,
]);
}

public function edit($announcementId)
{
$this->menu(Process::ANNOUNCEMENT);
$this->breadcrumb('Publicação de avisos', [
url('/intranet/educar_configuracoes_index.php') => 'Configurações',
]);
$announcement = Announcement::query()->withTrashed()->findOrFail($announcementId);
$userTypes = $announcement->userTypes->pluck('cod_tipo_usuario');

return view('announcement.publish.create', [
'announcement' => $announcement,
'userTypes' => $userTypes,
]);
}
}
80 changes: 80 additions & 0 deletions app/Http/Controllers/AnnouncementUserController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

namespace App\Http\Controllers;

use App\Models\Announcement;
use App\Models\LegacyEnrollment;
use App\Process;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;

class AnnouncementUserController extends Controller
{
public function show(Request $request)
{
$this->breadcrumb('Avisos');
$this->menu(Process::ANNOUNCEMENT);
$announcement = Announcement::query()->latest()->first();
$announcement->users()->sync([
$request->user()->getKey() => ['read_at' => now()],
]);

return view('announcement.user.show', [
'announcement' => $announcement,
'schools' => $this->getUserSchools($announcement->show_vacancy),
]);
}

private function getUserSchools(bool $show)
{
if (!$show) {
return [];
}

return LegacyEnrollment::query()
->selectRaw("
nm_turma,
UPPER(pessoa.nome) as escola,
string_agg(distinct nm_serie, ', ') as serie,
string_agg(distinct nm_curso, ', ') as curso,
max_aluno - COUNT(distinct matricula.cod_matricula) as vagas
")
->join('relatorio.view_situacao', function ($join) {
$join->on('view_situacao.cod_matricula', 'ref_cod_matricula')
->on('view_situacao.cod_turma', 'ref_cod_turma')
->on('view_situacao.sequencial', 'matricula_turma.sequencial');
})
->join('pmieducar.turma', fn ($join) => $join->on('turma.cod_turma', 'ref_cod_turma')->where('turma.ativo', 1)->where('turma.ano', Carbon::now()->year))
->join('pmieducar.escola', fn ($join) => $join->on('cod_escola', 'turma.ref_ref_cod_escola')->where('escola.ativo', 1))
->join('cadastro.pessoa', 'idpes', 'escola.ref_idpes')
->join('pmieducar.matricula', 'matricula.cod_matricula', 'ref_cod_matricula')
->join('pmieducar.serie', fn ($join) => $join->on('cod_serie', 'matricula.ref_ref_cod_serie')->where('matricula.ativo', 1))
->join('pmieducar.curso', fn ($join) => $join->on('cod_curso', 'matricula.ref_cod_curso')->where('curso.ativo', 1))
->when(Auth::user()->isSchooling(), fn ($q) => $q->whereIn('cod_escola', Auth::user()->schools()->pluck('ref_cod_escola')))
->having('max_aluno', '>', DB::raw('COUNT(distinct matricula.cod_matricula)'))
->orderBy('escola')
->orderBy('curso')
->orderBy('serie')
->where('matricula_turma.ativo', 1)
->orderBy('nm_turma')
->groupBy('nm_turma', 'max_aluno', 'pessoa.nome')
->get()
->groupBy([
'escola',
'curso',
'serie',
]);
}

public function confirm(Request $request)
{
$announcement = Announcement::query()->latest()->first();
$announcement->users()->sync([
$request->user()->getKey() => ['confirmed_at' => now()],
]);

return redirect('/');
}
}
37 changes: 37 additions & 0 deletions app/Http/Controllers/Auth/LoginController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Models\Announcement;
use App\Rules\ReCaptchaV3;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
Expand Down Expand Up @@ -77,4 +78,40 @@ public function validateLogin(Request $request)
'password.string' => 'O campo senha é obrigatório.',
]);
}

protected function authenticated(Request $request, $user)
{
$announcement = Announcement::query()
->whereHas('userTypes', fn ($q) => $q->whereKey($user->ref_cod_tipo_usuario))
->latest()->first();

if (!$announcement) {
return;
}

if ($announcement->repeat_on_login) {
$this->resetAnnouncementConfirmation($announcement, $user);

return redirect()->route('announcement.user.show');
}

if (!$this->userReadAnnouncement($announcement, $user)) {
return redirect()->route('announcement.user.show');
}
}

private function resetAnnouncementConfirmation(Announcement $announcement, $user): void
{
if ($announcement->show_confirmation) {
$announcement->users()->updateExistingPivot($user->getKey(), ['confirmed_at' => null]);
}
}

private function userReadAnnouncement(Announcement $announcement, $user): bool
{
return $announcement->users()
->whereKey($user->getKey())
->wherePivotNotNull('read_at')
->exists();
}
}
1 change: 1 addition & 0 deletions app/Http/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class Kernel extends HttpKernel
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\App\Http\Middleware\SetLayoutVariables::class,
\App\Http\Middleware\AnnouncementMiddleware::class,
],

'api' => [
Expand Down
36 changes: 36 additions & 0 deletions app/Http/Middleware/AnnouncementMiddleware.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace App\Http\Middleware;

use App\Models\Announcement;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;

class AnnouncementMiddleware
{
public function handle(Request $request, Closure $next)
{
if ($user = $request->user()) {
$announcement = Announcement::query()
->whereHas('userTypes', fn ($q) => $q->whereKey($user->ref_cod_tipo_usuario)
)->latest()->first();

if ($announcement?->show_confirmation && !$this->userConfirmedAnnouncement($announcement, $user)) {
Session::flash('error', 'Confirme a ciência do aviso antes de prosseguir!');

return redirect()->route('announcement.user.show');
}
}

return $next($request);
}

private function userConfirmedAnnouncement(Announcement $announcement, $user): bool
{
return $announcement->users()
->whereKey($user->getKey())
->wherePivotNotNull('confirmed_at')
->exists();
}
}
56 changes: 56 additions & 0 deletions app/Http/Requests/AnnouncementRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

namespace App\Http\Requests;

use App\Models\Announcement;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Arr;
use Illuminate\Validation\Rule;

class AnnouncementRequest extends FormRequest
{
protected function prepareForValidation()
{
$this->merge([
'repeat_on_login' => $this->has('repeat_on_login'),
'show_confirmation' => $this->has('show_confirmation'),
'show_vacancy' => $this->has('show_vacancy'),
'active' => $this->has('active'),
'tipo_usuario' => Arr::flatten($this->get('tipo_usuario', [])),
'created_by_user_id' => $this->user()->getKey(),
]);
}

public function rules()
{
return [
'name' => ['required', 'max:255'],
'description' => ['required'],
'repeat_on_login' => ['boolean'],
'show_confirmation' => ['boolean'],
'active' => ['boolean', function ($attribute, $value, $fail) {
if ($value) {
$exists = Announcement::query()
->withoutTrashed()
->where('id', '<>', $this->route('announcement'))
->exists();

if ($exists) {
$fail('Já existe um aviso ativo.');
}
}
}],
'show_vacancy' => ['boolean'],
'tipo_usuario' => ['required', 'array'],
'tipo_usuario.*' => ['integer', Rule::exists('tipo_usuario', 'cod_tipo_usuario')],
];
}

public function attributes()
{
return [
'description' => 'Conteúdo do aviso',
'tipo_usuario' => 'Tipos de usuários que serão notificados',
];
}
}
47 changes: 47 additions & 0 deletions app/Models/Announcement.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\SoftDeletes;

class Announcement extends Model
{
use SoftDeletes;

protected $fillable = [
'name',
'description',
'repeat_on_login',
'show_confirmation',
'show_vacancy',
'created_by_user_id',
];

public function userTypes(): BelongsToMany
{
return $this->belongsToMany(LegacyUserType::class, 'announcement_user_types', 'announcement_id', 'user_type_id');
}

public function users(): BelongsToMany
{
return $this->belongsToMany(LegacyUser::class, 'announcement_users', 'announcement_id', 'user_id');
}

public function createdByUser(): BelongsTo
{
return $this->belongsTo(LegacyUser::class);
}

protected function description(): Attribute
{
return Attribute::make(
set: function (string $value) {
return strip_tags($value, '<p><b><i><u><strong><em><a><ul><ol><li><br><span><h1><h2><h3><h4><h5><h6><img><table><tr><th><td><link><video><source>');
},
);
}
}
Loading

0 comments on commit 70850d7

Please sign in to comment.