From 7d409d35dae8d728f96a83a97bcfe27cafe334ca Mon Sep 17 00:00:00 2001 From: Vincent BRIDIER Date: Wed, 23 Feb 2022 15:15:47 +0000 Subject: [PATCH] - Add internal tickets flag - Move view share with Internal status - Update .env.example --- .env.example | 1 + app/Http/Controllers/Controller.php | 42 ++++++ app/Http/Controllers/TicketController.php | 35 ++++- app/Models/Ticket.php | 24 +++- app/Policies/TicketPolicy.php | 1 + app/Providers/AppServiceProvider.php | 19 +-- ...21545_add_is_internal_on_tickets_table.php | 32 +++++ resources/views/ticket/form-inputs.blade.php | 10 +- resources/views/ticket/index.blade.php | 106 ++++++++------ resources/views/ticket/show.blade.php | 133 +++++++++--------- 10 files changed, 261 insertions(+), 142 deletions(-) create mode 100644 database/migrations/2022_02_23_121545_add_is_internal_on_tickets_table.php diff --git a/.env.example b/.env.example index 0694f24..86c4f3d 100644 --- a/.env.example +++ b/.env.example @@ -29,3 +29,4 @@ MAIL_ENCRYPTION=null MAIL_FROM_ADDRESS=noreply-sw@ldc.fr MAIL_FROM_NAME="${APP_NAME}" MAIL_LIST_SERVICEWEB=equipe.web@ldc.fr +MAIL_ADMIN=equipe.web@ldc.fr \ No newline at end of file diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index ce1176d..12c5d62 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -7,9 +7,51 @@ use Illuminate\Foundation\Bus\DispatchesJobs; use Illuminate\Foundation\Validation\ValidatesRequests; use Illuminate\Routing\Controller as BaseController; +use App\Enums\TicketStatus; +use App\Models\Ticket; +use Illuminate\Support\Facades\Auth; +use Illuminate\Support\Facades\View; + class Controller extends BaseController { use AuthorizesRequests; use DispatchesJobs; use ValidatesRequests; + + public function __construct() + { + $ignore = [ + 9, // Support Web + 15, // Gen-Game- Web + 19, // Store LDC + 27, // CRM + 55, // LDC - WEB + ]; + + $ticketsNew = Ticket::where('status', TicketStatus::new()); + $ticketsWaiting = Ticket::where('status', TicketStatus::waiting()); + $ticketsInProgress = Ticket::whereNotIn( + 'status', + [ + TicketStatus::new(), + TicketStatus::estimateTodo(), + TicketStatus::estimateValidated(), + TicketStatus::toPlan(), + TicketStatus::planned(), + TicketStatus::waiting(), + TicketStatus::production(), + TicketStatus::archived() + ] + ); + + if (!Auth::user()->isAdmin()) { + $ticketsNew = $ticketsNew->where('is_internal', 0)->whereNotIn('site_id', $ignore); + $ticketsWaiting = $ticketsWaiting->where('is_internal', 0)->whereNotIn('site_id', $ignore); + $ticketsInProgress = $ticketsInProgress->where('is_internal', 0)->whereNotIn('site_id', $ignore); + } + + View::share('ticketsNew', $ticketsNew->count()); + View::share('ticketsWaiting', $ticketsWaiting->count()); + View::share('ticketsInProgress', $ticketsInProgress->count()); + } } diff --git a/app/Http/Controllers/TicketController.php b/app/Http/Controllers/TicketController.php index ba79824..f2815ed 100644 --- a/app/Http/Controllers/TicketController.php +++ b/app/Http/Controllers/TicketController.php @@ -29,6 +29,7 @@ class TicketController extends Controller { public function __construct() { + parent::__construct(); $this->authorizeResource(Ticket::class, 'ticket'); } @@ -39,7 +40,7 @@ class TicketController extends Controller $tickets = Ticket::with('user'); if ($request->s) { $tickets = $tickets->where('text', 'LIKE', "%$request->s%") - ->orWhere('id', $request->s) + ->orWhere('id', $request->s) ->orWhereHas('user', function ($q) use ($request) { $q->where('name', 'LIKE', "%$request->s%"); }); @@ -69,9 +70,10 @@ class TicketController extends Controller $q->whereId($user->id); }); }); + $tickets = $tickets->where('is_internal', 0); } $tickets = $tickets->where('status', ($request->status == TicketStatus::archived()) ? - '=' : '<>', TicketStatus::archived()); + '=' : '<>', TicketStatus::archived()); if ($request->search) { $tickets = $this->searchTicket($tickets, $request); } @@ -184,8 +186,19 @@ class TicketController extends Controller 'value' => $ticket->id ]); } + + $user = Auth::user(); + + if (!$user->can('update', $ticket)) { + abort(403); + } + + if ($ticket->is_internal === 1 && !$user->can('changeInternalStatus', $ticket)) { + abort(403); + } + $messages = $ticket->messages()->orderBy('created_at', 'DESC')->get(); - $isSubscribed = (bool)$ticket->subscriptions()->where('user_id', Auth::user()->id)->count(); + $isSubscribed = (bool)$ticket->subscriptions()->where('user_id', $user->id)->count(); return view('ticket.show', compact('ticket', 'messages', 'isSubscribed')); } @@ -219,6 +232,12 @@ class TicketController extends Controller $ticket->file2 = Ticket::saveFile($site, $ticket, $ticket->type, $request->file_ticket2); } + if ($request->has('is_internal')) { + $ticket->is_internal = 1; + } else { + $ticket->is_internal = 0; + } + $ticket->user()->associate(auth()->user()); $ticket->saveOrFail(); /** @var \App\Models\User */ @@ -266,6 +285,12 @@ class TicketController extends Controller $ticket->file2 = Ticket::saveFile($site, $ticket, $ticket->type, $request->file_ticket2); } + if ($request->has('is_internal')) { + $ticket->is_internal = 1; + } else { + $ticket->is_internal = 0; + } + $ticket->save(); return redirect()->route('ticket.edit', $ticket->id) @@ -309,7 +334,7 @@ class TicketController extends Controller $siteSlug = Str::slug($ticket->site->name); $fileMessage = $request->file_message; $fileName = $siteSlug . '-ticket-' . $ticket->id . - '-message-' . $message->id . '.' . $fileMessage->extension(); + '-message-' . $message->id . '.' . $fileMessage->extension(); $fileMessage->move(public_path('fichiers/' . $siteSlug . '/' . $ticket->id . '/'), $fileName); $filePath = 'fichiers/' . $siteSlug . '/' . $ticket->id . '/' . $fileName; $message->file = $filePath; @@ -326,7 +351,7 @@ class TicketController extends Controller $ticket->status = TicketStatus::archived(); $ticket->saveOrFail(); return redirect()->route('ticket.index') - ->with('warning', trans('Le ticket est archivé')); + ->with('warning', trans('Le ticket est archivé')); } public function subscribe(Ticket $ticket) diff --git a/app/Models/Ticket.php b/app/Models/Ticket.php index c3878ac..5c6bda8 100644 --- a/app/Models/Ticket.php +++ b/app/Models/Ticket.php @@ -31,7 +31,8 @@ class Ticket extends Model 'site_id', 'type', 'status', - 'text' + 'text', + 'is_internal' ]; protected static function booted() @@ -125,11 +126,22 @@ class Ticket extends Model })->orWhere('role', Role::admin()->value) ->orWhere('role', Role::developper()->value); })->firstOrFail(); - $usersNotified->add($user); - SendTicketMentionMail::dispatchAfterResponse( - $user, - new TicketMention($ticket, $message->message) - ); + + if ($ticket->is_internal === 1) { + if ($user->isAdmin()) { + $usersNotified->add($user); + SendTicketMentionMail::dispatchAfterResponse( + $user, + new TicketMention($ticket, $message->message) + ); + } + } else { + $usersNotified->add($user); + SendTicketMentionMail::dispatchAfterResponse( + $user, + new TicketMention($ticket, $message->message) + ); + } } catch (ModelNotFoundException $e) { continue; } diff --git a/app/Policies/TicketPolicy.php b/app/Policies/TicketPolicy.php index 6d36d35..4da1e6e 100644 --- a/app/Policies/TicketPolicy.php +++ b/app/Policies/TicketPolicy.php @@ -38,6 +38,7 @@ class TicketPolicy extends RootPolicy SSR::make('userSitesHasTicket', $user, $model) ]), 'changeStatus' => URR::make('userIsAdmin', $user), + 'changeInternalStatus' => URR::make('userIsAdmin', $user), 'delete' => URR::make('denyEveryOne'), 'forceDelete' => URR::make('denyEveryOne'), 'restore' => StaticRules::or([ diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index b5be80f..e38e5b0 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -2,8 +2,7 @@ namespace App\Providers; -use App\Enums\TicketStatus; -use App\Models\Ticket; + use Illuminate\Pagination\Paginator; use Illuminate\Support\Facades\File; use Illuminate\Support\Facades\URL; @@ -43,21 +42,5 @@ class AppServiceProvider extends ServiceProvider View::share('name', $appInfos->name); View::share('version', $appInfos->version); View::share('license', $appInfos->license); - - View::share('ticketsNew', Ticket::where('status', TicketStatus::new())->count()); - View::share('ticketsWaiting', Ticket::where('status', TicketStatus::waiting())->count()); - View::share('ticketsInProgress', Ticket::whereNotIn( - 'status', - [ - TicketStatus::new(), - TicketStatus::estimateTodo(), - TicketStatus::estimateValidated(), - TicketStatus::toPlan(), - TicketStatus::planned(), - TicketStatus::waiting(), - TicketStatus::production(), - TicketStatus::archived() - ] - )->count()); } } diff --git a/database/migrations/2022_02_23_121545_add_is_internal_on_tickets_table.php b/database/migrations/2022_02_23_121545_add_is_internal_on_tickets_table.php new file mode 100644 index 0000000..51efd88 --- /dev/null +++ b/database/migrations/2022_02_23_121545_add_is_internal_on_tickets_table.php @@ -0,0 +1,32 @@ +tinyInteger('is_internal')->default(0)->after('status'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('tickets', function (Blueprint $table) { + $table->dropColumn('is_internal')->default(0); + }); + } +} diff --git a/resources/views/ticket/form-inputs.blade.php b/resources/views/ticket/form-inputs.blade.php index 256db94..53d7bfb 100644 --- a/resources/views/ticket/form-inputs.blade.php +++ b/resources/views/ticket/form-inputs.blade.php @@ -15,7 +15,7 @@ $userPr = Auth::user()->sites ?? collect([]);
- +
@else - + @endcan @@ -60,3 +60,9 @@ $userPr = Auth::user()->sites ?? collect([]); @endif +@can('changeInternalStatus', App\Model\Ticket::class) +
+ is_internal === 1)) checked @endif> + +
+@endcan \ No newline at end of file diff --git a/resources/views/ticket/index.blade.php b/resources/views/ticket/index.blade.php index fe90c26..6d16d23 100644 --- a/resources/views/ticket/index.blade.php +++ b/resources/views/ticket/index.blade.php @@ -24,9 +24,9 @@ $userPr = Auth::user()->sites ?? collect([]); @foreach($sites as $site) @if (Auth::user()->isAdmin()) - + @elseif ($userPr->filter(function($pr) use($site) { return $pr->id === $site->id; })->count()) - + @endif @endforeach @@ -35,7 +35,7 @@ $userPr = Auth::user()->sites ?? collect([]); @@ -67,15 +67,18 @@ $userPr = Auth::user()->sites ?? collect([]); {{__('Type') }}  - @include('modules.sorter', ['colname' => 'type']) + @include('modules.sorter', ['colname' => 'type']) + {{__('Fichier') }} {{__('Fichier 2') }} {{__('Date de création') }}  - @include('modules.sorter', ['colname' => 'created_at']) + @include('modules.sorter', ['colname' => 'created_at']) + {{__('Créé par') }}  - @include('modules.sorter', ['colname' => 'created_by']) + @include('modules.sorter', ['colname' => 'created_by']) + {{__('Statut') }}  @include('modules.sorter', ['colname' => 'status']) @@ -87,34 +90,39 @@ $userPr = Auth::user()->sites ?? collect([]); @if(!count($tickets)) -

{{ __('Aucun ticket') }}

+ +

{{ __('Aucun ticket') }}

+ @endif @foreach ($tickets as $ticket) @php - $cls = $ticket->status == TicketStatus::archived() ? 'text-secondary' : null; - $cls = (!$cls && $ticket->status == TicketStatus::new()) ? 'text-danger' : $cls; - $cls = (!$cls && $ticket->status == TicketStatus::processed()) ? 'text-info' : $cls; - $cls = (!$cls && $ticket->status == TicketStatus::recette()) ? 'text-primary' : $cls; - $cls = (!$cls && $ticket->status == TicketStatus::production()) ? 'text-success' : $cls; - $cls = (!$cls && $ticket->status == TicketStatus::inprogress()) ? 'text-dark' : $cls; - $cls = (!$cls && $ticket->status == TicketStatus::waiting()) ? 'text-white bg-danger' : $cls; - $ticketClass = 'bg-primary'; - switch($ticket->type) { - case TicketType::bug(): - $ticketClass = 'bg-danger'; - break; - case TicketType::evolution(): - $ticketClass = 'bg-success'; - break; - case TicketType::newsletter(): - $ticketClass = 'bg-warning'; - break; - } + $cls = $ticket->status == TicketStatus::archived() ? 'text-secondary' : null; + $cls = (!$cls && $ticket->status == TicketStatus::new()) ? 'text-danger' : $cls; + $cls = (!$cls && $ticket->status == TicketStatus::processed()) ? 'text-info' : $cls; + $cls = (!$cls && $ticket->status == TicketStatus::recette()) ? 'text-primary' : $cls; + $cls = (!$cls && $ticket->status == TicketStatus::production()) ? 'text-success' : $cls; + $cls = (!$cls && $ticket->status == TicketStatus::inprogress()) ? 'text-dark' : $cls; + $cls = (!$cls && $ticket->status == TicketStatus::waiting()) ? 'text-white bg-danger' : $cls; + $ticketClass = 'bg-primary'; + switch($ticket->type) { + case TicketType::bug(): + $ticketClass = 'bg-danger'; + break; + case TicketType::evolution(): + $ticketClass = 'bg-success'; + break; + case TicketType::newsletter(): + $ticketClass = 'bg-warning'; + break; + } @endphp - {{ $ticket->id }} + {{ $ticket->id }} + @if ($ticket->is_internal === 1) + 🔒 + @endif {{ $ticket->site->name }} @@ -122,12 +130,12 @@ $userPr = Auth::user()->sites ?? collect([]); @if ($ticket->file !== null) - Fichier + Fichier @endif @if ($ticket->file2 !== null) - Fichier 2 + Fichier 2 @endif {{ Carbon\Carbon::parse($ticket->created_at)->format('d/m/Y à H:i') }} @@ -143,23 +151,29 @@ $userPr = Auth::user()->sites ?? collect([]); -@endsection +@endsection \ No newline at end of file diff --git a/resources/views/ticket/show.blade.php b/resources/views/ticket/show.blade.php index 2351233..37a4675 100644 --- a/resources/views/ticket/show.blade.php +++ b/resources/views/ticket/show.blade.php @@ -4,20 +4,20 @@

@php - $back = route('ticket.index'); - $url = parse_url(url()->previous()); - if ( - ($url['host'] ?? '') === parse_url(config('app.url'), PHP_URL_HOST) and - ($url['path'] ?? '') === '/ticket' - ) { - $queries = explode('&', $url['query'] ?? ''); - foreach($queries as $q) { - $q = explode('=', $q); - if(($q[0] ?? '') === 'pr' and ctype_digit(($q[1] ?? ''))) { - $back = route('ticket.index', ['pr' => $q[1]]); - } - } - } + $back = route('ticket.index'); + $url = parse_url(url()->previous()); + if ( + ($url['host'] ?? '') === parse_url(config('app.url'), PHP_URL_HOST) and + ($url['path'] ?? '') === '/ticket' + ) { + $queries = explode('&', $url['query'] ?? ''); + foreach($queries as $q) { + $q = explode('=', $q); + if(($q[0] ?? '') === 'pr' and ctype_digit(($q[1] ?? ''))) { + $back = route('ticket.index', ['pr' => $q[1]]); + } + } + } @endphp ← {{ __('Ticket n° :ticketId : :ticketSiteName - :ticketTypeLabel', [ @@ -25,6 +25,9 @@ 'ticketSiteName' => $ticket->site->name, 'ticketTypeLabel' => $ticket->type->label ]) }} + @if ($ticket->is_internal === 1) + 🔒 + @endif {{ $ticket->status->label }}

@@ -67,66 +70,66 @@