Преглед изворни кода

=fix @can in vertical menu, fix piattiDatatable, fix Tomobola controller

marcofalabretti пре 1 дан
родитељ
комит
f79c6910c7

+ 11
- 9
app/DataTables/PiattoDataTable.php Прегледај датотеку

130
             ->editor(
130
             ->editor(
131
                 Editor::make()
131
                 Editor::make()
132
                     ->fields([
132
                     ->fields([
133
-                        Fields\Select2::make('attivita_id')->label('Attività')->options(Attivita::where('is_attiva', true)->pluck('id', 'nome')),
133
+                        Fields\Hidden::make('attivita_id')->label('Attività')->default($this->attivita_id),
134
                         Fields\Text::make('nome')->label('Nome'),
134
                         Fields\Text::make('nome')->label('Nome'),
135
                         Fields\Text::make('descrizione')->label('Descrizione'),
135
                         Fields\Text::make('descrizione')->label('Descrizione'),
136
-                        Fields\Select2::make('cucina_id')->label('cucina')->options(Cucina::where('is_attiva', true)->pluck('id', 'nome')),
136
+                        Fields\Select2::make('cucina_id')->label('cucina')
137
+                        ->options(Cucina::where('is_attiva', true)->where('attivita_id', $this->attivita_id)->pluck('id', 'nome'))
138
+                        ->default(isset($this->cucina_id) ? $this->cucina_id : ''),
137
                         Fields\Text::make('prezzo')->label('Prezzo (€)'),
139
                         Fields\Text::make('prezzo')->label('Prezzo (€)'),
138
-                        Fields\Image::make('immagine')->label('Immagine'),
140
+                        // Fields\Image::make('immagine')->label('Immagine'),
139
                         Fields\Boolean::make('is_attivo')->label('Disponibile')->default(true),
141
                         Fields\Boolean::make('is_attivo')->label('Disponibile')->default(true),
140
                         Fields\Select2::make('allergeni')->label('Allergeni')->multiple(true)
142
                         Fields\Select2::make('allergeni')->label('Allergeni')->multiple(true)
141
                             ->options(Allergene::where('disponibile', true)->pluck('id', 'nome'))
143
                             ->options(Allergene::where('disponibile', true)->pluck('id', 'nome'))
165
         $columns = array_merge($columns, [
167
         $columns = array_merge($columns, [
166
 
168
 
167
             Column::make('nome')->title('Nome')->searchable()->responsivePriority(1),
169
             Column::make('nome')->title('Nome')->searchable()->responsivePriority(1),
168
-            Column::computed('prezzo_display')->title('Prezzo')->addClass('text-center'),
169
-            Column::computed('cucina_id')->data('cucina_id_display')->title('Cucina')->addClass('text-center')->responsivePriority(2), // icona in tabella
170
-            Column::computed('allergeni')->title('Allergeni')->visible(false), // valore grezzo per l'editor (array ID)
171
-            Column::computed('allergeni_display')->title('Allergeni')->visible(true),
172
-            Column::computed('bacheca_id_display')->title('Bacheca')->addClass('text-center'), // icona in tabella
173
-            Column::computed('in_evidenza_display')->title('In evidenza')->addClass('text-center'), // icona in tabella
170
+            Column::make('prezzo')->data('prezzo_display')->title('Prezzo')->addClass('text-center'),
171
+            // Column::computed('cucina_id')->data('cucina_id_display')->title('Cucina')->addClass('text-center')->responsivePriority(2), // icona in tabella
172
+            Column::make('allergeni')->title('Allergeni')->visible(false), // valore grezzo per l'editor (array ID)
173
+            Column::make('allergeni')->data('allergeni_display')->title('Allergeni')->visible(true),
174
+            Column::make('bacheca_id')->data('bacheca_id_display')->title('Bacheca')->addClass('text-center'), // icona in tabella
175
+            Column::make('in_evidenza')->data('in_evidenza_display')->title('In evidenza')->addClass('text-center'), // icona in tabella
174
             Column::computed('action')->title('')->width('10%')->addClass('text-center')->responsivePriority(1),
176
             Column::computed('action')->title('')->width('10%')->addClass('text-center')->responsivePriority(1),
175
 
177
 
176
         ]);
178
         ]);

+ 68
- 0
app/Helpers/Helpers.php Прегледај датотеку

2
 
2
 
3
 namespace App\Helpers;
3
 namespace App\Helpers;
4
 
4
 
5
+use Illuminate\Contracts\Auth\Authenticatable;
6
+use Illuminate\Support\Facades\Auth;
5
 use Illuminate\Support\Facades\Config;
7
 use Illuminate\Support\Facades\Config;
6
 use Illuminate\Support\Str;
8
 use Illuminate\Support\Str;
7
 
9
 
24
     return $attributes;
26
     return $attributes;
25
   }
27
   }
26
 
28
 
29
+  /**
30
+   * Valuta la regola "can" di verticalMenu.json.
31
+   * Formati supportati: permission:nome, role:nome, oppure OR con " | ".
32
+   * Esempio: "role:superadmin | permission:view-code-stampa"
33
+   */
34
+  public static function menuCan(?string $can, ?Authenticatable $user = null): bool
35
+  {
36
+    if ($can === null || trim($can) === '') {
37
+      return true;
38
+    }
39
+
40
+    $user = $user ?? Auth::user();
41
+    if (!$user) {
42
+      return false;
43
+    }
44
+
45
+    foreach (explode('|', $can) as $rule) {
46
+      $rule = trim($rule);
47
+      if ($rule === '') {
48
+        continue;
49
+      }
50
+
51
+      if (str_starts_with($rule, 'role:')) {
52
+        if ($user->hasRole(trim(substr($rule, 5)))) {
53
+          return true;
54
+        }
55
+        continue;
56
+      }
57
+
58
+      if (str_starts_with($rule, 'permission:')) {
59
+        if ($user->can(trim(substr($rule, 11)))) {
60
+          return true;
61
+        }
62
+        continue;
63
+      }
64
+
65
+      if ($user->can($rule)) {
66
+        return true;
67
+      }
68
+    }
69
+
70
+    return false;
71
+  }
72
+
73
+  /**
74
+   * Voce menu visibile se passa "can" e, se ha submenu, almeno un figlio è visibile.
75
+   */
76
+  public static function menuItemVisible(object $item, ?Authenticatable $user = null): bool
77
+  {
78
+    if (!self::menuCan($item->can ?? null, $user)) {
79
+      return false;
80
+    }
81
+
82
+    if (!isset($item->submenu)) {
83
+      return true;
84
+    }
85
+
86
+    foreach ($item->submenu as $child) {
87
+      if (self::menuItemVisible($child, $user)) {
88
+        return true;
89
+      }
90
+    }
91
+
92
+    return false;
93
+  }
94
+
27
   public static function appClasses()
95
   public static function appClasses()
28
   {
96
   {
29
 
97
 

+ 5
- 5
app/Http/Controllers/PiattoController.php Прегледај датотеку

28
         ];
28
         ];
29
     }
29
     }
30
 
30
 
31
-    public function index(PiattoDataTable $dataTable){
31
+    public function index(PiattoDataTable $dataTable , Request $request){
32
       $dataTable->attivita_id = Session::get('attivita_attuale');
32
       $dataTable->attivita_id = Session::get('attivita_attuale');
33
 
33
 
34
-      if(request()->get('cucina_id')){
34
+      if(request()->has('cucina_id')){
35
         $dataTable->cucina_id = request()->get('cucina_id');
35
         $dataTable->cucina_id = request()->get('cucina_id');
36
       }
36
       }
37
 
37
 
52
 
52
 
53
         switch ($action) {
53
         switch ($action) {
54
           case 'create':
54
           case 'create':
55
-            if (! Auth::user()->can('create-user')) return;
55
+            if (! Auth::user()->can('create-piatto')) return;
56
             break;
56
             break;
57
 
57
 
58
           case 'edit':
58
           case 'edit':
59
-            if (! Auth::user()->can('edit-user')) return;
59
+            if (! Auth::user()->can('edit-piatto')) return;
60
             break;
60
             break;
61
 
61
 
62
           case 'remove':
62
           case 'remove':
63
-            if (! Auth::user()->can('remove-user')) return;
63
+            if (! Auth::user()->can('remove-piatto')) return;
64
             break;
64
             break;
65
         }
65
         }
66
       }
66
       }

+ 28
- 12
app/Http/Controllers/TombolaController.php Прегледај датотеку

25
             new Middleware('permission:create-tombola|edit-tombola|delete-tombola', only: ['getTabellone', 'estrai', 'azzera', 'estratti']),
25
             new Middleware('permission:create-tombola|edit-tombola|delete-tombola', only: ['getTabellone', 'estrai', 'azzera', 'estratti']),
26
         ];
26
         ];
27
     }
27
     }
28
-    public function getTabellone(Request $request){
29
-        if(Auth::user()->can('delete-tombola') && Attivita::find($attivita_id)->user_id == Auth::user()->id){
30
-            return redirect()->route('tombola.index')->with('error', 'Non hai permesso di azzerare la tombola.');
28
+    public function getTabellone(Request $request, $attivita_id){
29
+        $attivita = Attivita::find($attivita_id);
30
+        if(!$attivita){
31
+            return redirect()->route('tombola.index')->with('error', 'Attivita non trovata.');
32
+        }
33
+        if(!Auth::user()->can('create-tombola')){
34
+            return redirect()->route('tombola.index')->with('error', 'Non hai permesso di creare il tabellone.');
31
         }
35
         }
32
        
36
        
33
         foreach (range(1, 90) as $numero) {
37
         foreach (range(1, 90) as $numero) {
34
             $tombola = Tombola::firstOrCreate([
38
             $tombola = Tombola::firstOrCreate([
35
-                'attivita_id' => Session::get('attivita_attuale'),
39
+                'attivita_id' => $attivita_id,
36
                 'numero' => $numero,
40
                 'numero' => $numero,
37
                 'estratto' => false,
41
                 'estratto' => false,
38
                 'estratto_at' => null,
42
                 'estratto_at' => null,
67
     }
71
     }
68
 
72
 
69
     public function tabellone(Request $request, $attivita_id){
73
     public function tabellone(Request $request, $attivita_id){
70
-        if(Auth::user()->can('view-tombola') && Attivita::find($attivita_id)->user_id == Auth::user()->id){
74
+        if(!Auth::user()->can('view-tombola')){
71
             return redirect()->route('tombola.index')->with('error', 'Non hai permesso di vedere il tabellone.');
75
             return redirect()->route('tombola.index')->with('error', 'Non hai permesso di vedere il tabellone.');
76
+        }elseif(!Attivita::find($attivita_id)->user_id == Auth::user()->id){
77
+            return redirect()->route('tombola.index')->with('error', 'Non sei autorizzato a vedere il tabellone di questa attività.');
72
         }
78
         }
73
         $attivita = Attivita::find($attivita_id);
79
         $attivita = Attivita::find($attivita_id);
74
         if(!$attivita){
80
         if(!$attivita){
79
         ]);
85
         ]);
80
     }
86
     }
81
 
87
 
82
-    public function estrai(Request $request){
83
-        if(Auth::user()->can('view-tombola') && Attivita::find($attivita_id)->user_id == Auth::user()->id){
84
-            return redirect()->route('tombola.index')->with('error', 'Non hai permesso di azzerare la tombola.');
88
+    public function estrai(Request $request, $attivita_id){
89
+        $attivita = Attivita::find($attivita_id);
90
+        if(!$attivita){
91
+            return redirect()->route('tombola.index')->with('error', 'Attivita non trovata.');
85
         }
92
         }
86
-        $tabellone = Tombola::where('attivita_id', Session::get('attivita_attuale'));
93
+        if(!Auth::user()->can('view-tombola')){
94
+            return redirect()->route('tombola.index')->with('error', 'Non hai permesso di estrarre numeri.');
95
+        }elseif($attivita->user_id != Auth::user()->id){
96
+            return redirect()->route('tombola.index')->with('error', 'Non sei autorizzato a estrarre numeri da questa attività.');
97
+        }
98
+        $tabellone = Tombola::where('attivita_id', $attivita_id);
87
         $tombola = $tabellone->where('estratto', false)->inRandomOrder()->first();
99
         $tombola = $tabellone->where('estratto', false)->inRandomOrder()->first();
100
+
88
         if(!$tombola){
101
         if(!$tombola){
89
             if ($request->expectsJson() || $request->ajax()) {
102
             if ($request->expectsJson() || $request->ajax()) {
90
                 return response()->json([
103
                 return response()->json([
148
     }
161
     }
149
 
162
 
150
     public function azzera(Request $request, $attivita_id){
163
     public function azzera(Request $request, $attivita_id){
151
-        if(Auth::user()->can('delete-tombola') && Attivita::find($attivita_id)->user_id == Auth::user()->id){
152
-            return redirect()->route('tombola.index')->with('error', 'Non hai permesso di azzerare la tombola.');
153
-        }
154
         $attivita = Attivita::find($attivita_id);
164
         $attivita = Attivita::find($attivita_id);
155
         if(!$attivita){
165
         if(!$attivita){
156
             return redirect()->route('tombola.index')->with('error', 'Attivita non trovata.');
166
             return redirect()->route('tombola.index')->with('error', 'Attivita non trovata.');
157
         }
167
         }
168
+        if(!Auth::user()->can('delete-tombola')){
169
+            return redirect()->route('tombola.index')->with('error', 'Non hai permesso di azzerare la tombola.');
170
+        }elseif($attivita->user_id != Auth::user()->id){
171
+            return redirect()->route('tombola.index')->with('error', 'Non sei autorizzato a azzerare la tombola di questa attività.');
172
+        }
173
+
158
         Tombola::where('attivita_id', $attivita_id)->update([
174
         Tombola::where('attivita_id', $attivita_id)->update([
159
             'estratto' => false,
175
             'estratto' => false,
160
             'estratto_at' => null,
176
             'estratto_at' => null,

+ 6
- 0
app/Models/AbstractModels/AbstractPiatto.php Прегледај датотеку

36
      */
36
      */
37
     protected $casts = [
37
     protected $casts = [
38
         'id' => 'integer',  
38
         'id' => 'integer',  
39
+        'attivita_id' => 'integer',
39
         'nome' => 'string',
40
         'nome' => 'string',
40
         'cucina_id' => 'integer',
41
         'cucina_id' => 'integer',
41
         'menu_id' => 'integer',
42
         'menu_id' => 'integer',
57
      */
58
      */
58
     protected $fillable = [
59
     protected $fillable = [
59
         'id',
60
         'id',
61
+        'attivita_id',
60
         'nome',
62
         'nome',
61
         'descrizione',
63
         'descrizione',
62
         'prezzo',
64
         'prezzo',
80
     {
82
     {
81
         return $this->belongsToMany('\App\Models\Allergene', 'piatto_allergene', 'piatto_id', 'allergene_id');
83
         return $this->belongsToMany('\App\Models\Allergene', 'piatto_allergene', 'piatto_id', 'allergene_id');
82
     }
84
     }
85
+    public function attivita()
86
+    {
87
+        return $this->belongsTo('\App\Models\Attivita', 'attivita_id', 'id');
88
+    }
83
 }
89
 }

+ 3
- 3
resources/menu/verticalMenu.json Прегледај датотеку

105
       "icon": "menu-icon icon-base bx bx-chart",
105
       "icon": "menu-icon icon-base bx bx-chart",
106
       "slug": "contabilita.index",
106
       "slug": "contabilita.index",
107
       "url": "admin/contabilita",
107
       "url": "admin/contabilita",
108
-      "can": "permission:view-contabilita",
108
+      "can": "permission:view-contabilita | role:amministratore",
109
       "submenu": [
109
       "submenu": [
110
         {
110
         {
111
           "name": "Prima nota",
111
           "name": "Prima nota",
221
           "icon": "menu-icon icon-base bx bx-play-circle",
221
           "icon": "menu-icon icon-base bx bx-play-circle",
222
           "slug": "contenuto-bacheca.index",
222
           "slug": "contenuto-bacheca.index",
223
           "url": "admin/contenuto-bacheca",
223
           "url": "admin/contenuto-bacheca",
224
-          "can": "permission:view-contenuto_bacheca"
224
+          "can": "permission:view-contenuto_bacheca | role:amministratore"
225
         }
225
         }
226
       ]
226
       ]
227
     },
227
     },
239
       "icon": "menu-icon icon-base bx bx-cog",
239
       "icon": "menu-icon icon-base bx bx-cog",
240
       "slug": "configurazione.index",
240
       "slug": "configurazione.index",
241
       "url": "admin/configurazione",
241
       "url": "admin/configurazione",
242
-      "can": "permission:view-configurazione",
242
+      "can": "permission:view-configurazione | role:amministratore",
243
       "submenu": [
243
       "submenu": [
244
         {
244
         {
245
           "name": "Allergeni",
245
           "name": "Allergeni",

+ 2
- 0
resources/views/layouts/sections/menu/submenu.blade.php Прегледај датотеку

5
 <ul class="menu-sub">
5
 <ul class="menu-sub">
6
   @if (isset($menu))
6
   @if (isset($menu))
7
     @foreach ($menu as $submenu)
7
     @foreach ($menu as $submenu)
8
+    @if (Helper::menuItemVisible($submenu))
8
 
9
 
9
     {{-- active menu method --}}
10
     {{-- active menu method --}}
10
     @php
11
     @php
47
           @include('layouts.sections.menu.submenu',['menu' => $submenu->submenu])
48
           @include('layouts.sections.menu.submenu',['menu' => $submenu->submenu])
48
         @endif
49
         @endif
49
       </li>
50
       </li>
51
+    @endif
50
     @endforeach
52
     @endforeach
51
   @endif
53
   @endif
52
 </ul>
54
 </ul>

+ 1
- 1
resources/views/layouts/sections/menu/verticalMenu.blade.php Прегледај датотеку

48
     <li class="menu-header small">
48
     <li class="menu-header small">
49
       <span class="menu-header-text">{{ __($menu->menuHeader) }}</span>
49
       <span class="menu-header-text">{{ __($menu->menuHeader) }}</span>
50
     </li>
50
     </li>
51
-    @else
51
+    @elseif (Helper::menuItemVisible($menu))
52
     {{-- active menu method --}}
52
     {{-- active menu method --}}
53
     @php
53
     @php
54
     $activeClass = null;
54
     $activeClass = null;

+ 1
- 1
resources/views/piatto/datatable.blade.php Прегледај датотеку

12
 </div>
12
 </div>
13
 
13
 
14
 
14
 
15
-@include('piatto.datatable_script')
15
+ @include('piatto.datatable_script') 

+ 11
- 3
resources/views/piatto/index.blade.php Прегледај датотеку

81
 </div>
81
 </div>
82
 @endif
82
 @endif
83
 
83
 
84
-@include('piatto.datatable')
84
+<div class="row justify-content-center">
85
+  <div class="col-xxl mb-4 mt-2">
86
+    <div class="card">
87
+      <div class="card-body">
88
+        {{ $dataTable_piatto->table(['class' => 'table table-bordered']) }}
89
+      </div>
90
+    </div>
91
+  </div>
92
+</div>
93
+
94
+@endsection
85
 
95
 
86
 @section('page-script')
96
 @section('page-script')
87
 @include('piatto.datatable_script')
97
 @include('piatto.datatable_script')
88
 @endsection
98
 @endsection
89
-
90
-@endsection

+ 31
- 3
resources/views/tombola/index.blade.php Прегледај датотеку

29
     <div class="card h-100">
29
     <div class="card h-100">
30
       <div class="card-header d-flex justify-content-between align-items-center">
30
       <div class="card-header d-flex justify-content-between align-items-center">
31
         <h5 class="mb-0">Situazione Tombola</h5>
31
         <h5 class="mb-0">Situazione Tombola</h5>
32
-        <a href="{{ $urlTabellone }}" class="btn btn-sm btn-outline-primary">Apri tabellone</a>
32
+        
33
       </div>
33
       </div>
34
       <div class="card-body">
34
       <div class="card-body">
35
         <div class="row g-3">
35
         <div class="row g-3">
78
         </div>
78
         </div>
79
 
79
 
80
         <div class="mt-4 col-4">
80
         <div class="mt-4 col-4">
81
-          <form method="POST" action="{{ route('tombola.azzera' , ['attivita_id' => Session::get('attivita_attuale')]) }}" onsubmit="return confirm('Confermi l\'azzeramento completo della tombola?');">
81
+          <form method="POST" action="{{ route('tombola.azzera' , ['attivita_id' => Session::get('attivita_attuale')]) }}" onsubmit="confirmAzzermento(event)">
82
             @csrf
82
             @csrf
83
             <button type="submit" class="btn btn-danger">
83
             <button type="submit" class="btn btn-danger">
84
               <i class="bx bx-refresh me-1"></i> Azzera Tombola
84
               <i class="bx bx-refresh me-1"></i> Azzera Tombola
89
 
89
 
90
         @if( \App\Models\Tombola::where('attivita_id', Session::get('attivita_attuale'))->count() === 0)
90
         @if( \App\Models\Tombola::where('attivita_id', Session::get('attivita_attuale'))->count() === 0)
91
         <div class="mt-4 col-4">
91
         <div class="mt-4 col-4">
92
-          <form method="POST" action="{{ route('tombola.getTabellone') }}">
92
+          <form method="POST" action="{{ route('tombola.getTabellone', ['attivita_id' => Session::get('attivita_attuale')]) }}">
93
             @csrf
93
             @csrf
94
             <button type="submit" class="btn btn-primary">
94
             <button type="submit" class="btn btn-primary">
95
               <i class="bx bx-refresh me-1"></i> Genera Tabellone
95
               <i class="bx bx-refresh me-1"></i> Genera Tabellone
97
           </form>
97
           </form>
98
           <small class="text-muted d-block mt-2">Resetta tutti i numeri come non estratti.</small>
98
           <small class="text-muted d-block mt-2">Resetta tutti i numeri come non estratti.</small>
99
         </div>
99
         </div>
100
+
101
+        @else
102
+        <div class="mt-4 col-4">
103
+        <a href="{{ $urlTabellone }}" class="btn btn-outline-primary">Apri tabellone</a>
104
+        </div>
100
         @endif
105
         @endif
101
 
106
 
102
 
107
 
162
       }
167
       }
163
     });
168
     });
164
   })();
169
   })();
170
+
171
+
172
+  function confirmAzzermento(event) {
173
+    event.preventDefault();
174
+
175
+    Swal.fire({
176
+      title: "Sei sicuro?",
177
+      text: "Confermi l'azzeramento completo della tombola?",
178
+      icon: "warning",
179
+      showCancelButton: true,
180
+      confirmButtonText: "Sì, azzera!",
181
+      cancelButtonText: "No, annulla",
182
+      customClass: {
183
+        confirmButton: 'btn btn-primary me-2',
184
+        cancelButton: 'btn btn-label-secondary'
185
+      },
186
+      buttonsStyling: false
187
+    }).then(function (result) {
188
+      if (result.isConfirmed) {
189
+        event.target.closest('form').submit();
190
+      }
191
+    });
192
+  }
165
 </script>
193
 </script>
166
 @endsection
194
 @endsection

+ 1
- 1
routes/web.php Прегледај датотеку

233
 Route::post('tombola/{attivita_id}/estrai', [TombolaController::class, 'estrai'])->name('tombola.estrai');
233
 Route::post('tombola/{attivita_id}/estrai', [TombolaController::class, 'estrai'])->name('tombola.estrai');
234
 Route::post('tombola/{attivita_id}/azzera', [TombolaController::class, 'azzera'])->name('tombola.azzera');
234
 Route::post('tombola/{attivita_id}/azzera', [TombolaController::class, 'azzera'])->name('tombola.azzera');
235
 Route::get('tombola/{attivita_id}/estratti', [TombolaController::class, 'estratti'])->name('tombola.estratti');
235
 Route::get('tombola/{attivita_id}/estratti', [TombolaController::class, 'estratti'])->name('tombola.estratti');
236
-Route::post('tombola/getTabellone', [TombolaController::class, 'getTabellone'])->name('tombola.getTabellone');
236
+Route::post('tombola/{attivita_id}/getTabellone', [TombolaController::class, 'getTabellone'])->name('tombola.getTabellone');
237
 });
237
 });
238
 
238
 
239
 
239
 

Loading…
Откажи
Сачувај