浏览代码

firma remota rapportino

Roberto Santini 1年前
父节点
当前提交
a34b145cda

+ 151
- 14
app/Http/Controllers/IssueController.php 查看文件

16
 use PDF;
16
 use PDF;
17
 use Storage;
17
 use Storage;
18
 use Session;
18
 use Session;
19
+use Notification;
20
+use App\Notifications\InviaLinkPerFirma;
19
 
21
 
20
 class IssueController extends Controller
22
 class IssueController extends Controller
21
 {
23
 {
54
       return view('issue.show')->with(['issue' => $issue, 'author' => $author]);
56
       return view('issue.show')->with(['issue' => $issue, 'author' => $author]);
55
     }else{
57
     }else{
56
       Session::flash('flash_message', "Errore generico");
58
       Session::flash('flash_message', "Errore generico");
57
-      dd($response_issue->object());
59
+      // dd($response_issue->object());
58
       return redirect()->route('home');
60
       return redirect()->route('home');
59
     }
61
     }
60
   }
62
   }
136
     }catch(\Error $e){
138
     }catch(\Error $e){
137
     }
139
     }
138
 
140
 
141
+    //email per invio rapportino
142
+    $response_helpesk = Http::get(session('azienda')->redmine_url.'/helpdesk_tickets/'.$id.'.json', [
143
+      'key' => $redmineUser->api_key,
144
+    ]);
145
+    $helpdeskEmail = "";
146
+    try{
147
+      $helpdesk = $response_helpesk->object()->helpdesk_ticket;
148
+      $helpdeskEmail = $helpdesk->from_address;
149
+    }catch(\Exception $e){
150
+    }
151
+
139
 
152
 
140
 
153
 
141
     return view('issue.firma')->with([
154
     return view('issue.firma')->with([
147
       'user' => $user,
160
       'user' => $user,
148
       'sedeCliente' => $sedeCliente,
161
       'sedeCliente' => $sedeCliente,
149
       'descrizione' => $descrizione,
162
       'descrizione' => $descrizione,
150
-      'descrizione_id' => $descrizione_id
163
+      'descrizione_id' => $descrizione_id,
164
+      'helpdeskEmail' => $helpdeskEmail
151
     ]);
165
     ]);
152
   }
166
   }
153
 
167
 
154
   public function firma_rapporto(Request $request){
168
   public function firma_rapporto(Request $request){
169
+    $redmineUser = session('redmine_user');
170
+    $azienda = session('azienda');
171
+
172
+    if($request->has('token_remoto')){
173
+      $issue = Issue::where('token', $request->token_remoto)->first();
174
+      $redmineUser = json_decode($issue->redmineUser);
175
+      $azienda = $issue->user->azienda;
176
+    }
177
+
178
+    $user = User::where('redmine_id', $redmineUser->id)->first();
179
+
180
+    if($request->has('email_link')){
181
+      $campi = $request->all();
182
+      unset($campi['allegato']);
183
+      unset($campi['_token']);
184
+      $allegati = [];
185
+
186
+      // salvo gli allegati
187
+      if($request->hasFile('allegato')){
188
+        foreach($request->allegato as $allegato){
189
+          $exploded = explode(".", $allegato->getClientOriginalName());
190
+          $originalFilename = "";
191
+          if(count($exploded) > 1){
192
+            $index = count($exploded) - 2;
193
+            $exploded[count($exploded)-1] = ".".$allegato->extension();
194
+          }else{
195
+            $index = 0;
196
+          }
197
+          $exploded[$index] .= '_'.time();
198
+
199
+          $originalFilename = implode($exploded);
200
+          Storage::disk('allegati')->put($originalFilename, $allegato->get());
201
+          $allegati[] = [
202
+            'filename' => $originalFilename,
203
+          ];
204
+        }
205
+      }
206
+
207
+      $campi['allegati'] = $allegati;
208
+
209
+      //salvo issue e invio link per successiva firma
210
+      $issue = new Issue;
211
+      $issue->campi = json_encode($campi);
212
+      $issue->email = $request->email_link;
213
+      $issue->redmineUser = json_encode($redmineUser);
214
+      $issue->user()->associate($user);
215
+      $issue->token = "";
216
+      $issue->save();
217
+      Notification::route('mail', [$request->email_link])->notify(new InviaLinkPerFirma($issue));
218
+
219
+      Session::flash('flash_message', "Email con il link per la firma del rapportino inviata correttamente");
220
+      return redirect()->route('home');
221
+    }
155
 
222
 
156
     // Controllo orari e durata intervento
223
     // Controllo orari e durata intervento
157
     try{
224
     try{
173
 
240
 
174
 
241
 
175
 
242
 
176
-    $redmineUser = session('redmine_user');
177
-    $user = User::where('redmine_id', $redmineUser->id)->first();
178
 
243
 
179
-    $response_issue = Http::get(session('azienda')->redmine_url.'/issues/'.$request->issue_id.'.json?include=attachments,relations', [
244
+
245
+    $response_issue = Http::get($azienda->redmine_url.'/issues/'.$request->issue_id.'.json?include=attachments,relations', [
180
       'key' => $redmineUser->api_key,
246
       'key' => $redmineUser->api_key,
181
     ]);
247
     ]);
182
     $issue = $response_issue->object()->issue;
248
     $issue = $response_issue->object()->issue;
201
       }
267
       }
202
     }
268
     }
203
 
269
 
270
+    // dd($tecnici);
271
+
204
     // Firme
272
     // Firme
205
     $sign_path_cliente = 'sign_cliente_'.time().'.png';
273
     $sign_path_cliente = 'sign_cliente_'.time().'.png';
206
     if($request->has('signature_image_cliente')){
274
     if($request->has('signature_image_cliente')){
257
       'content-type' => 'application/octet-stream'
325
       'content-type' => 'application/octet-stream'
258
     ])
326
     ])
259
     ->withBody($pdf->output(), 'application/pdf')
327
     ->withBody($pdf->output(), 'application/pdf')
260
-    ->post("https://".$redmineUser->api_key."@".session('azienda')->redmine_url.'/uploads.json', [
328
+    ->post("https://".$redmineUser->api_key."@".$azienda->redmine_url.'/uploads.json', [
261
       'filename' => $filename
329
       'filename' => $filename
262
     ]);
330
     ]);
263
 
331
 
291
           'content-type' => 'application/octet-stream'
359
           'content-type' => 'application/octet-stream'
292
         ])
360
         ])
293
         ->withBody($allegato->get(), $allegato->getMimeType())
361
         ->withBody($allegato->get(), $allegato->getMimeType())
294
-        ->post("https://".$redmineUser->api_key."@".session('azienda')->redmine_url.'/uploads.json', [
362
+        ->post("https://".$redmineUser->api_key."@".$azienda->redmine_url.'/uploads.json', [
295
           'filename' => $originalFilename
363
           'filename' => $originalFilename
296
         ]);
364
         ]);
297
 
365
 
310
       }
378
       }
311
     }
379
     }
312
 
380
 
381
+    // Upload degli alleati già salvati in locale
382
+    if($request->has('token_remoto')){
383
+      $issueRemoto = Issue::where('token', $request->token_remoto)->first();
384
+      $campi = json_decode($issueRemoto->campi);
385
+      if(property_exists($campi, 'allegati')){
386
+        foreach($campi->allegati as $campo){
387
+          $originalFilename = $campo->filename;
388
+
389
+          $response = Http::withHeaders([
390
+            'content-type' => 'application/octet-stream'
391
+          ])
392
+          ->withBody(Storage::disk('allegati')->get($campo->filename), Storage::disk('allegati')->mimeType($campo->filename))
393
+          ->post("https://".$redmineUser->api_key."@".$azienda->redmine_url.'/uploads.json', [
394
+            'filename' => $originalFilename
395
+          ]);
396
+
397
+          // $response->throw(function ($response, $e) {
398
+          //   dd($response->body());
399
+          // });
400
+
401
+          $uploadToken = $response->object()->upload->token;
402
+          $uploads[] = [
403
+            'token' => $uploadToken,
404
+            'filename' => $originalFilename,
405
+            'description' => $originalFilename,
406
+            'content_type' => Storage::disk('allegati')->mimeType($campo->filename)
407
+          ];
408
+        }
409
+      }
410
+    }
411
+
313
 
412
 
314
 
413
 
315
     // Elimino le firme
414
     // Elimino le firme
316
     Storage::disk('temp')->delete([$sign_path_cliente]);
415
     Storage::disk('temp')->delete([$sign_path_cliente]);
317
 
416
 
318
     // Aggiorno lo issue
417
     // Aggiorno lo issue
319
-    $response = Http::acceptJson()->put("https://".$redmineUser->api_key."@".session('azienda')->redmine_url.'/issues/'.$request->issue_id.'.xml', [
418
+    $response = Http::acceptJson()->put("https://".$redmineUser->api_key."@".$azienda->redmine_url.'/issues/'.$request->issue_id.'.xml', [
320
       'issue' => [
419
       'issue' => [
321
         'notes' => $request->note,
420
         'notes' => $request->note,
322
         'status_id' => $request->status_id,
421
         'status_id' => $request->status_id,
335
 
434
 
336
     // Aggiorno journal solo se non ho premuto "svuota" nell'interfaccia
435
     // Aggiorno journal solo se non ho premuto "svuota" nell'interfaccia
337
     if($request->has('descrizione_id') && intval($request->descrizione_id) != null){
436
     if($request->has('descrizione_id') && intval($request->descrizione_id) != null){
338
-      $response = Http::acceptJson()->put("https://".$redmineUser->api_key."@".session('azienda')->redmine_url.'/journals/'.$request->descrizione_id.'.xml', [
437
+      $response = Http::acceptJson()->put("https://".$redmineUser->api_key."@".$azienda->redmine_url.'/journals/'.$request->descrizione_id.'.xml', [
339
         'key' => $redmineUser->api_key,
438
         'key' => $redmineUser->api_key,
340
         'journal' => [
439
         'journal' => [
341
           'notes' => '',
440
           'notes' => '',
352
         $activity_id = Config::getValue(Config::ATTIVITA_TECNICO_AGGIUNTIVO);
451
         $activity_id = Config::getValue(Config::ATTIVITA_TECNICO_AGGIUNTIVO);
353
       }
452
       }
354
 
453
 
355
-      $response = Http::post("https://".$redmineUser->api_key."@".session('azienda')->redmine_url.'/time_entries.xml', [
454
+      $response = Http::post("https://".$redmineUser->api_key."@".$azienda->redmine_url.'/time_entries.xml', [
356
         'time_entry' => [
455
         'time_entry' => [
357
           'issue_id' => $request->issue_id,
456
           'issue_id' => $request->issue_id,
358
           'spent_on' => $dataIntervento->toDateString(),
457
           'spent_on' => $dataIntervento->toDateString(),
375
 
474
 
376
       // Ore viaggio
475
       // Ore viaggio
377
       if($request->has('ore_viaggio') && is_numeric($request->ore_viaggio)){
476
       if($request->has('ore_viaggio') && is_numeric($request->ore_viaggio)){
378
-        $response = Http::post("https://".$redmineUser->api_key."@".session('azienda')->redmine_url.'/time_entries.xml', [
477
+        $response = Http::post("https://".$redmineUser->api_key."@".$azienda->redmine_url.'/time_entries.xml', [
379
           'time_entry' => [
478
           'time_entry' => [
380
             'issue_id' => $request->issue_id,
479
             'issue_id' => $request->issue_id,
381
             'spent_on' => $dataIntervento->toDateString(),
480
             'spent_on' => $dataIntervento->toDateString(),
401
       // Aggiorno le relazioni
500
       // Aggiorno le relazioni
402
 
501
 
403
       foreach($request->segnalazioneCorrelata as $key => $segnalazioneCorrelata){
502
       foreach($request->segnalazioneCorrelata as $key => $segnalazioneCorrelata){
404
-        $response = Http::post("https://".$redmineUser->api_key."@".session('azienda')->redmine_url.'/issues/'.$request->issue_id.'/relations.xml', [
503
+        $response = Http::post("https://".$redmineUser->api_key."@".$azienda->redmine_url.'/issues/'.$request->issue_id.'/relations.xml', [
405
           'relation' => [
504
           'relation' => [
406
             'issue_to_id' => $segnalazioneCorrelata
505
             'issue_to_id' => $segnalazioneCorrelata
407
           ]
506
           ]
412
         // });
511
         // });
413
 
512
 
414
         // Aggiorno lo stato del ticket correlato
513
         // Aggiorno lo stato del ticket correlato
415
-        $response = Http::acceptJson()->put("https://".$redmineUser->api_key."@".session('azienda')->redmine_url.'/issues/'.$segnalazioneCorrelata.'.xml', [
514
+        $response = Http::acceptJson()->put("https://".$redmineUser->api_key."@".$azienda->redmine_url.'/issues/'.$segnalazioneCorrelata.'.xml', [
416
           'issue' => [
515
           'issue' => [
417
             'status_id' => $request->segnalazioneCorrelataStatus[$segnalazioneCorrelata],
516
             'status_id' => $request->segnalazioneCorrelataStatus[$segnalazioneCorrelata],
418
           ]
517
           ]
427
 
526
 
428
     // Session::flash('flash_message', "Issue aggiornato correttamente!");
527
     // Session::flash('flash_message', "Issue aggiornato correttamente!");
429
     $request->session()->put('success_issue_id', $request->issue_id);
528
     $request->session()->put('success_issue_id', $request->issue_id);
430
-    return redirect()->route('issue.success');
529
+    if($request->has('token_remoto')){
530
+      Issue::where('token', $request->token_remoto)->delete();
531
+      return redirect()->route('issue.success_remoto');
532
+    }else{
533
+      return redirect()->route('issue.success');
534
+    }
431
   }
535
   }
432
 
536
 
433
   public function success(Request $request){
537
   public function success(Request $request){
439
       return redirect()->route('home');
543
       return redirect()->route('home');
440
     }
544
     }
441
   }
545
   }
546
+
547
+  public function success_remoto(Request $request){
548
+    $success_issue_id = session('success_issue_id');
549
+    if($success_issue_id != null){
550
+      $request->session()->forget('success_issue_id');
551
+      return view('issue.success_remoto')->with(['issue_id' => $success_issue_id]);
552
+    }else{
553
+      return redirect()->route('home');
554
+    }
555
+  }
556
+
557
+  public function firma_remota(Request $request, $token){
558
+    $issue = Issue::where('token', $token)->first();
559
+    if($issue == null) return;
560
+
561
+    return view('issue.firma_remota')->with(['issue' => json_decode($issue->campi), 'user' => $issue->user, 'token' => $issue->token]);
562
+  }
563
+
564
+  public function download_allegato(Request $request){
565
+    $issue = Issue::where('token', $request->token)->first();
566
+    if(Storage::disk('allegati')->exists($request->filename)){
567
+      $storagePath  = Storage::disk('allegati')->path($request->filename);
568
+      if($request->has('type') && $request->type == 'file'){
569
+        return response()->file($storagePath);
570
+      }else{
571
+        return response()->download($storagePath);
572
+      }
573
+
574
+    }else{
575
+      Session::flash('flash_message', 'Il file non esiste!');
576
+      return redirect()->route('home');
577
+    }
578
+  }
442
 }
579
 }

+ 63
- 0
app/Models/AbstractModels/AbstractIssue.php 查看文件

1
+<?php
2
+/**
3
+ * Model object generated by: Skipper (http://www.skipper18.com)
4
+ * Do not modify this file manually.
5
+ */
6
+
7
+namespace App\Models\AbstractModels;
8
+
9
+use Illuminate\Database\Eloquent\Model;
10
+
11
+abstract class AbstractIssue extends Model
12
+{
13
+    /**  
14
+     * The table associated with the model.
15
+     * 
16
+     * @var string
17
+     */
18
+    protected $table = 'issue';
19
+    
20
+    /**  
21
+     * Primary key type.
22
+     * 
23
+     * @var string
24
+     */
25
+    protected $keyType = 'bigInteger';
26
+    
27
+    /**  
28
+     * The attributes that should be cast to native types.
29
+     * 
30
+     * @var array
31
+     */
32
+    protected $casts = [
33
+        'id' => 'integer',
34
+        'user_id' => 'integer',
35
+        'email' => 'string',
36
+        'campi' => 'string',
37
+        'token' => 'string',
38
+        'redmineUser' => 'string',
39
+        'created_at' => 'datetime',
40
+        'updated_at' => 'datetime'
41
+    ];
42
+    
43
+    /**  
44
+     * The attributes that are mass assignable.
45
+     * 
46
+     * @var array
47
+     */
48
+    protected $fillable = [
49
+        'id',
50
+        'user_id',
51
+        'email',
52
+        'campi',
53
+        'token',
54
+        'redmineUser',
55
+        'created_at',
56
+        'updated_at'
57
+    ];
58
+    
59
+    public function user()
60
+    {
61
+        return $this->belongsTo('\App\Models\User', 'user_id', 'id');
62
+    }
63
+}

+ 18
- 13
app/Models/AbstractModels/AbstractUser.php 查看文件

10
 
10
 
11
 abstract class AbstractUser extends Model
11
 abstract class AbstractUser extends Model
12
 {
12
 {
13
-    /**
13
+    /**  
14
      * The table associated with the model.
14
      * The table associated with the model.
15
-     *
15
+     * 
16
      * @var string
16
      * @var string
17
      */
17
      */
18
     protected $table = 'user';
18
     protected $table = 'user';
19
-
20
-    /**
19
+    
20
+    /**  
21
      * Primary key type.
21
      * Primary key type.
22
-     *
22
+     * 
23
      * @var string
23
      * @var string
24
      */
24
      */
25
     protected $keyType = 'bigInteger';
25
     protected $keyType = 'bigInteger';
26
-
27
-    /**
26
+    
27
+    /**  
28
      * The attributes that should be cast to native types.
28
      * The attributes that should be cast to native types.
29
-     *
29
+     * 
30
      * @var array
30
      * @var array
31
      */
31
      */
32
     protected $casts = [
32
     protected $casts = [
33
         'id' => 'integer',
33
         'id' => 'integer',
34
         'redmine_id' => 'integer',
34
         'redmine_id' => 'integer',
35
         'azienda_id' => 'integer',
35
         'azienda_id' => 'integer',
36
-        // 'firma' => 'string',
36
+        'firma' => 'string',
37
         'created_at' => 'datetime',
37
         'created_at' => 'datetime',
38
         'updated_at' => 'datetime'
38
         'updated_at' => 'datetime'
39
     ];
39
     ];
40
-
41
-    /**
40
+    
41
+    /**  
42
      * The attributes that are mass assignable.
42
      * The attributes that are mass assignable.
43
-     *
43
+     * 
44
      * @var array
44
      * @var array
45
      */
45
      */
46
     protected $fillable = [
46
     protected $fillable = [
51
         'created_at',
51
         'created_at',
52
         'updated_at'
52
         'updated_at'
53
     ];
53
     ];
54
-
54
+    
55
     public function azienda()
55
     public function azienda()
56
     {
56
     {
57
         return $this->belongsTo('\App\Models\Azienda', 'azienda_id', 'id');
57
         return $this->belongsTo('\App\Models\Azienda', 'azienda_id', 'id');
58
     }
58
     }
59
+    
60
+    public function issues()
61
+    {
62
+        return $this->hasMany('\App\Models\Issue', 'user_id', 'id');
63
+    }
59
 }
64
 }

+ 1
- 1
app/Models/Issue.php 查看文件

6
 use Illuminate\Support\Collection;
6
 use Illuminate\Support\Collection;
7
 use Illuminate\Support\Facades\Log;
7
 use Illuminate\Support\Facades\Log;
8
 
8
 
9
-class Issue{
9
+class Issue extends \App\Models\AbstractModels\AbstractIssue {
10
 
10
 
11
   public static function getCollection($status = []){
11
   public static function getCollection($status = []){
12
     $redmineUser = session('redmine_user');
12
     $redmineUser = session('redmine_user');

+ 64
- 0
app/Notifications/InviaLinkPerFirma.php 查看文件

1
+<?php
2
+
3
+namespace App\Notifications;
4
+
5
+use Illuminate\Bus\Queueable;
6
+use Illuminate\Notifications\Notification;
7
+use Illuminate\Contracts\Queue\ShouldQueue;
8
+use Illuminate\Notifications\Messages\MailMessage;
9
+
10
+class InviaLinkPerFirma extends Notification
11
+{
12
+  // use Queueable;
13
+  public $issue;
14
+
15
+  /**
16
+  * Create a new notification instance.
17
+  *
18
+  * @return void
19
+  */
20
+  public function __construct($issue)
21
+  {
22
+    $this->issue = $issue;
23
+  }
24
+
25
+  /**
26
+  * Get the notification's delivery channels.
27
+  *
28
+  * @param  mixed  $notifiable
29
+  * @return array
30
+  */
31
+  public function via($notifiable)
32
+  {
33
+    return ['mail'];
34
+  }
35
+
36
+  /**
37
+  * Get the mail representation of the notification.
38
+  *
39
+  * @param  mixed  $notifiable
40
+  * @return \Illuminate\Notifications\Messages\MailMessage
41
+  */
42
+  public function toMail($notifiable)
43
+  {
44
+    $message = (new MailMessage)
45
+    ->subject("Firma rapporto d'intervento")
46
+    ->line("clicca sul pulsante per firmare")
47
+    ->action('CLicca qui per firmare', route('issue.firma_remota', ['token' => $this->issue->token]));
48
+
49
+    return $message;
50
+  }
51
+
52
+  /**
53
+  * Get the array representation of the notification.
54
+  *
55
+  * @param  mixed  $notifiable
56
+  * @return array
57
+  */
58
+  public function toArray($notifiable)
59
+  {
60
+    return [
61
+      //
62
+    ];
63
+  }
64
+}

+ 20
- 0
app/Observers/IssueObserver.php 查看文件

1
+<?php
2
+
3
+namespace App\Observers;
4
+use App\Models\Issue;
5
+use Illuminate\Support\Str;
6
+
7
+class IssueObserver
8
+{
9
+  public function created(Issue $issue)
10
+  {
11
+    do{
12
+      $random = Str::random(60);
13
+      $token_db = Issue::where('token', $random)->first();
14
+    }while($token_db != null);
15
+
16
+    $issue->token = $random;
17
+    $issue->save();
18
+
19
+  }
20
+}

+ 1
- 1
app/Providers/AppServiceProvider.php 查看文件

23
      */
23
      */
24
     public function boot()
24
     public function boot()
25
     {
25
     {
26
-        //
26
+        \App\Models\Issue::observe(\App\Observers\IssueObserver::class);
27
     }
27
     }
28
 }
28
 }

+ 6
- 0
config/filesystems.php 查看文件

53
             'url' => env('APP_URL').'/storage/azienda',
53
             'url' => env('APP_URL').'/storage/azienda',
54
             'visibility' => 'public',
54
             'visibility' => 'public',
55
         ],
55
         ],
56
+        'allegati' => [
57
+            'driver' => 'local',
58
+            'root' => storage_path('app/allegati'),
59
+            'url' => env('APP_URL').'/allegati',
60
+            'visibility' => 'public',
61
+        ],
56
 
62
 
57
     ],
63
     ],
58
 
64
 

+ 49
- 0
database/migrations/2024_02_20_233352_skipper_migrations_2024022023335227.php 查看文件

1
+<?php
2
+/* 
3
+ * Migrations generated by: Skipper (http://www.skipper18.com)
4
+ * Migration id: dc8fb6bf-00f9-4254-9481-a6ec529d6b83
5
+ * Migration datetime: 2024-02-20 23:33:52.272720
6
+ */ 
7
+
8
+use Illuminate\Support\Facades\Schema;
9
+use Illuminate\Database\Schema\Blueprint;
10
+use Illuminate\Database\Migrations\Migration;
11
+
12
+class SkipperMigrations2024022023335227 extends Migration
13
+{
14
+    /**
15
+     * Run the migrations.
16
+     *
17
+     * @return void
18
+     */
19
+    public function up()
20
+    {
21
+        Schema::create('issue', function (Blueprint $table) {
22
+            $table->bigInteger('id')->autoIncrement()->unsigned();
23
+            $table->bigInteger('user_id')->nullable(true)->unsigned();
24
+            $table->string('email')->nullable(true);
25
+            $table->longText('campi')->nullable(true);
26
+            $table->string('token')->nullable(true);
27
+            $table->text('redmineUser')->nullable(true);
28
+            $table->timestamp('created_at')->nullable(true);
29
+            $table->timestamp('updated_at')->nullable(true);
30
+        });
31
+        Schema::table('issue', function (Blueprint $table) {
32
+            $table->foreign('user_id')->references('id')->on('user');
33
+        });
34
+    }
35
+    /**
36
+     * Reverse the migrations.
37
+     *
38
+     * @return void
39
+     */
40
+    public function down()
41
+    {
42
+        if (Schema::hasTable('issue')) {
43
+            Schema::table('issue', function (Blueprint $table) {
44
+                $table->dropForeign(['user_id']);
45
+            });
46
+        }
47
+        Schema::dropIfExists('issue');
48
+    }
49
+}

+ 7
- 0
resources/views/home.blade.php 查看文件

13
       <div class="card">
13
       <div class="card">
14
         <div class="card-body">
14
         <div class="card-body">
15
 
15
 
16
+          @if(Session::has('flash_message'))
17
+          <div class="alert alert-success">
18
+            {{ Session::get('flash_message') }}
19
+          </div>
20
+          @endif
21
+          
22
+
16
           {{ $dataTable_issues->table() }}
23
           {{ $dataTable_issues->table() }}
17
 
24
 
18
           {{ $dataTable_issues->scripts() }}
25
           {{ $dataTable_issues->scripts() }}

+ 27
- 4
resources/views/issue/firma.blade.php 查看文件

62
             <div class="form-group col-md">
62
             <div class="form-group col-md">
63
               {!! Form::label('activity_id', 'Attività') !!}
63
               {!! Form::label('activity_id', 'Attività') !!}
64
               {!! Form::select('activity_id', $attivita, null, ['class' => 'form-control']) !!}
64
               {!! Form::select('activity_id', $attivita, null, ['class' => 'form-control']) !!}
65
+              {!! Form::hidden('activity_label', '') !!}
65
             </div>
66
             </div>
66
 
67
 
67
             <div class="form-group col-md" id="div_stato_segnalazione" style="display: none">
68
             <div class="form-group col-md" id="div_stato_segnalazione" style="display: none">
68
               {!! Form::label('status_id', 'Stato segnalazione') !!}
69
               {!! Form::label('status_id', 'Stato segnalazione') !!}
69
               {!! Form::select('status_id', $issueStatus, Config::getValue(Config::STATO_DA_COMPLETARE), ['class' => 'form-control']) !!}
70
               {!! Form::select('status_id', $issueStatus, Config::getValue(Config::STATO_DA_COMPLETARE), ['class' => 'form-control']) !!}
71
+              {!! Form::hidden('status_label', '') !!}
70
             </div>
72
             </div>
71
           </div>
73
           </div>
72
 
74
 
180
             <tr>
182
             <tr>
181
               <td>{!! Form::checkbox('segnalazioneCorrelata[]', $segnalazione->id, false) !!}</td>
183
               <td>{!! Form::checkbox('segnalazioneCorrelata[]', $segnalazione->id, false) !!}</td>
182
               <td>{{ $segnalazione->id }}</td>
184
               <td>{{ $segnalazione->id }}</td>
183
-              <td>{{ $segnalazione->subject }}</td>
185
+              <td>
186
+                {!! Form::hidden('segnalazioneCorrelataLabel[]', $segnalazione->subject, false) !!}
187
+                {{ $segnalazione->subject }}
188
+              </td>
184
               <td>{!! Form::select('segnalazioneCorrelataStatus['.$segnalazione->id.']', $issueStatus, $segnalazione->status->id, ['class' => 'form-control']) !!}</td>
189
               <td>{!! Form::select('segnalazioneCorrelataStatus['.$segnalazione->id.']', $issueStatus, $segnalazione->status->id, ['class' => 'form-control']) !!}</td>
185
             </tr>
190
             </tr>
186
             @endforeach
191
             @endforeach
242
 
247
 
243
           <div class="form-row">
248
           <div class="form-row">
244
             <div class="form-group col-md">
249
             <div class="form-group col-md">
245
-              <button type="button" onclick="submitForm()" class="btn btn-primary">Salva</button>
250
+              {!! Form::hidden('email_link', null, ['id' => 'email_link']) !!}
251
+              <button type="button" onclick="submitForm()" name="salva" class="btn btn-primary">Salva rapportino firmato</button>
252
+              <button type="button" onclick="inviaLink()" name="invia_link" class="btn btn-primary">Invia link per la firma</button>
246
             </div>
253
             </div>
247
           </div>
254
           </div>
248
 
255
 
386
 }
393
 }
387
 
394
 
388
 function svuotaDescrizione(){
395
 function svuotaDescrizione(){
389
-    $('#note').empty();
390
-    $('#descrizione_id').val(null);
396
+  $('#note').empty();
397
+  $('#descrizione_id').val(null);
398
+}
399
+
400
+function inviaLink(){
401
+  bootbox.prompt({
402
+    title: 'Inserisci indirizzo email a cui inviare il link per la firma remota del rapportino',
403
+    inputType: 'email',
404
+    value: "{{ $helpdeskEmail }}",
405
+    callback: function (result) {
406
+      if(result){
407
+        $('#email_link').val(result);
408
+        $("[name='activity_label']").val($("#activity_id option:selected").text());
409
+        $("[name='status_label']").val($("#status_id option:selected").text());
410
+        $('#form_firma').submit();
411
+      }
412
+    }
413
+  });
391
 }
414
 }
392
 </script>
415
 </script>

+ 319
- 0
resources/views/issue/firma_remota.blade.php 查看文件

1
+<?php
2
+use Carbon\Carbon;
3
+use App\Models\Config;
4
+?>
5
+
6
+<style>
7
+[type="file"] {
8
+  height: 0;
9
+  overflow: hidden;
10
+  width: 0;
11
+}
12
+
13
+[type="file"] + label {
14
+  background: #3490dc;
15
+  border: none;
16
+  border-radius: 5px;
17
+  color: #fff;
18
+  cursor: pointer;
19
+  display: inline-block;
20
+  font-family: 'Rubik', sans-serif;
21
+  font-size: inherit;
22
+  font-weight: 500;
23
+  margin-bottom: 1rem;
24
+  outline: none;
25
+  padding: 1rem 10px;
26
+  position: relative;
27
+  transition: all 0.3s;
28
+  vertical-align: middle;
29
+  width: 95%;
30
+  height: 100%;
31
+  display: inline-flex;
32
+  align-items: center;
33
+  justify-content: center;
34
+  overflow-wrap: anywhere;
35
+
36
+}
37
+</style>
38
+
39
+<x-guest-layout>
40
+  <x-slot name="header">
41
+    <h2 class="font-semibold text-xl text-gray-800 leading-tight">
42
+      <i class="fas fa-ticket-alt"></i> Firma rapporto d'intervento issue #{{ $issue->issue_id }}
43
+    </h2>
44
+  </x-slot>
45
+
46
+  {!! Form::open(['route' => 'issue.firma_rapporto', 'files' => true, 'id' => 'form_firma']) !!}
47
+  {!! Form::hidden('issue_id', $issue->issue_id ) !!}
48
+  {!! Form::hidden('token_remoto', $token ) !!}
49
+
50
+  <div class="row justify-content-center mb-4">
51
+    <div class="col-xl-10 col-lg-12 col-md px-md-3 px-2">
52
+      <div class="card">
53
+        <div class="card-header"><i class="fas fa-info"></i> Dettagli intervento</div>
54
+        <div class="card-body">
55
+
56
+          <x-auth-validation-errors class="mb-4" :errors="$errors" />
57
+
58
+          <div class="form-row">
59
+            <div class="form-group col-md">
60
+              {!! Form::label('spent_on', 'Data') !!}
61
+              {!! $issue->spent_on !!}
62
+              {!! Form::hidden('spent_on', $issue->spent_on) !!}
63
+            </div>
64
+
65
+            <div class="form-group col-md">
66
+              {!! Form::label('activity_id', 'Attività') !!}
67
+              {!! $issue->activity_label !!}
68
+              {!! Form::hidden('activity_id', $issue->activity_id) !!}
69
+            </div>
70
+
71
+            <div class="form-group col-md" id="div_stato_segnalazione" style="display: none">
72
+              {!! Form::label('status_id', 'Stato segnalazione') !!}
73
+              {!! $issue->status_id !!}
74
+              {!! Form::hidden('status_id', $issue->status_id) !!}
75
+            </div>
76
+          </div>
77
+
78
+          <div class="form-row">
79
+            <div class="form-group col-md">
80
+              {!! Form::label('persona_riferimento', 'Referente cliente') !!}
81
+              {!! $issue->persona_riferimento !!}
82
+              {!! Form::hidden('persona_riferimento', $issue->persona_riferimento) !!}
83
+            </div>
84
+
85
+            @if($issue->sedeCliente != null)
86
+            <div class="form-group col-md-4">
87
+              {!! Form::label('sedeCliente', 'Sede intervento') !!}
88
+              {!! $issue->sedeCliente !!}
89
+            </div>
90
+            @endif
91
+            {!! Form::hidden('sedeCliente', $issue->sedeCliente) !!}
92
+          </div>
93
+
94
+          <div class="form-row">
95
+            <div class="form-group col-md">
96
+              {!! Form::label('ora_inizio', 'Inizio') !!}
97
+              {!! $issue->ora_inizio !!}
98
+              {!! Form::hidden('ora_inizio', $issue->ora_inizio) !!}
99
+            </div>
100
+
101
+            <div class="form-group col-md">
102
+              {!! Form::label('ora_fine', 'Fine') !!}
103
+              {!! $issue->ora_fine !!}
104
+              {!! Form::hidden('ora_fine', $issue->ora_fine) !!}
105
+            </div>
106
+
107
+            <div class="form-group col-md">
108
+              {!! Form::label('ore_pausa', 'Ore pausa') !!}
109
+              {!! $issue->ore_pausa !!}
110
+              {!! Form::hidden('ore_pausa', $issue->ore_pausa) !!}
111
+            </div>
112
+
113
+            @if($issue->ore_viaggio != null)
114
+            <div class="form-group col-md">
115
+              {!! Form::label('ore_viaggio', 'Ore viaggio') !!}
116
+              {!! $issue->ore_viaggio !!}
117
+            </div>
118
+            @else
119
+            {!! Form::hidden('ore_viaggio', $issue->ore_viaggio) !!}
120
+            @endif
121
+          </div>
122
+
123
+          <div class="form-row">
124
+            <div class="form-group col-md">
125
+              {!! Form::label('descrizione_id', 'Descrizione') !!}
126
+              {!! $issue->descrizione_id !!}
127
+              {!! Form::hidden('descrizione_id', $issue->descrizione_id) !!}
128
+            </div>
129
+          </div>
130
+
131
+          <div class="form-row">
132
+            <div class="form-group col-md">
133
+              {!! Form::label('materiale_utilizzato', 'Materiale utilizzato') !!}
134
+              {!! $issue->materiale_utilizzato !!}
135
+              {!! Form::hidden('materiale_utilizzato', $issue->materiale_utilizzato) !!}
136
+            </div>
137
+          </div>
138
+
139
+          <div class="form-row">
140
+            <div class="form-group col-md">
141
+              {!! Form::label('merce_ritirata', 'Merce ritirata') !!}
142
+              {!! $issue->merce_ritirata !!}
143
+              {!! Form::hidden('merce_ritirata', $issue->merce_ritirata) !!}
144
+            </div>
145
+          </div>
146
+
147
+          <div class="form-row">
148
+            <div class="form-group col-md">
149
+              {!! Form::label('merce_consegnata', 'Merce consegnata') !!}
150
+              {!! $issue->merce_consegnata !!}
151
+              {!! Form::hidden('merce_consegnata', $issue->merce_consegnata) !!}
152
+            </div>
153
+          </div>
154
+
155
+          @if(property_exists($issue, 'altro_tecnico'))
156
+          <div class="form-row">
157
+            <div class="form-group col-md">
158
+              {!! Form::label('altri_tecnici', 'Altri tecnici') !!}
159
+              @foreach($issue->altro_tecnico as $key => $tecnico)
160
+              <input type="hidden" name="altro_tecnico[{{$key}}]" value="{{ $tecnico }}"/> {{ $tecnico }}<br>
161
+              @endforeach
162
+            </div>
163
+          </div>
164
+          @endif
165
+
166
+
167
+        </div>
168
+      </div>
169
+    </div>
170
+  </div>
171
+
172
+  @if(property_exists($issue, 'segnalazioneCorrelata') && count($issue->segnalazioneCorrelata) > 0)
173
+  <div class="row justify-content-center" style="margin-top: 20px;">
174
+    <div class="col-xl-10 col-lg-12 col-md px-md-3 px-2">
175
+      <div class="card">
176
+        <div class="card-header"><i class="fas fa-link"></i> Segnalazioni correlate</div>
177
+        <div class="card-body">
178
+          <table class="table">
179
+            <thead>
180
+              <tr>
181
+                <th>ID</th>
182
+                <th>Segnalazione</th>
183
+                <!-- <th>Stato</th> -->
184
+              </tr>
185
+            </thead>
186
+
187
+            @foreach($issue->segnalazioneCorrelata as $key => $segnalazione_id)
188
+            <tr>
189
+              <td>
190
+                {!! Form::hidden('segnalazioneCorrelata[]', $segnalazione_id) !!}
191
+                {!! Form::hidden('segnalazioneCorrelataStatus['.$segnalazione_id.']', $issue->segnalazioneCorrelataStatus->{$segnalazione_id}) !!}
192
+                {{ $segnalazione_id }}
193
+              </td>
194
+              <td>
195
+                {!! $issue->segnalazioneCorrelataLabel[$key] !!}
196
+              </td>
197
+            </tr>
198
+            @endforeach
199
+
200
+          </table>
201
+        </div>
202
+      </div>
203
+    </div>
204
+  </div>
205
+  @endif
206
+
207
+  @if(property_exists($issue, 'allegati') && count($issue->allegati) > 0)
208
+  <div class="row justify-content-center" style="margin-top: 20px;" id="div_allegati_ext">
209
+    <div class="col-xl-10 col-lg-12 col-md px-md-3 px-2">
210
+      <div class="card">
211
+        <div class="card-header"><i class="fas fa-paperclip"></i> Allegati</div>
212
+        <div class="card-body">
213
+          @foreach($issue->allegati as $allegato)
214
+          <a class="btn btn-primary" href="{{ route('issue.download_allegato') }}?token={{$token}}&filename={{$allegato->filename}}">{{ $allegato->filename }}</a>
215
+          @endforeach
216
+        </div>
217
+      </div>
218
+    </div>
219
+  </div>
220
+  @endif
221
+
222
+  <div class="row justify-content-center" style="margin-top: 20px;" id="div_allegati_ext">
223
+    <div class="col-xl-10 col-lg-12 col-md px-md-3 px-2">
224
+      <div class="card">
225
+        <div class="card-header"><i class="fas fa-signature"></i> Firme</div>
226
+        <div class="card-body">
227
+          <div class="form-row">
228
+            <div class="form-group col-md-6">
229
+              {!! Form::label('firma_tecnico', 'Firma tecnico') !!}
230
+
231
+              @if($user->firma != null)
232
+
233
+              @if(config('database.default') == 'mysql')
234
+              <img src="data:image/png;base64,{!! base64_decode($user->firma) !!}" />
235
+              @else
236
+              <img src="data:image/png;base64,{!! stream_get_contents($user->firma) !!}" />
237
+              @endif
238
+
239
+              @endif
240
+            </div>
241
+
242
+            <div class="form-group col-md-6">
243
+              {!! Form::label('firma_cliente', 'Firma cliente per presa visione') !!}
244
+              <canvas id="signature-pad_cliente" class="signature-pad"></canvas>
245
+              {!! Form::hidden('signature_image_cliente', null, ['id' => 'signature_image_cliente']) !!}
246
+            </div>
247
+          </div>
248
+
249
+          <div class="form-row">
250
+            <div class="form-group col-md">
251
+              <button type="button" onclick="submitForm()" name="salva" class="btn btn-primary">Invia</button>
252
+            </div>
253
+          </div>
254
+
255
+
256
+        </div>
257
+      </div>
258
+    </div>
259
+  </div>
260
+
261
+
262
+
263
+  {!! Form::close() !!}
264
+
265
+</x-app-layout>
266
+
267
+<script>
268
+$(document).ready(function(){
269
+  $.ajaxSetup({
270
+    headers: {
271
+      'X-CSRF-TOKEN': '{{csrf_token()}}'
272
+    }
273
+  });
274
+
275
+  setTimeout(init_canvas(), 2000);
276
+
277
+});
278
+
279
+function init_canvas(){
280
+  $.each(['cliente'], function(index, value){
281
+    try{
282
+      var canvas = document.getElementById("signature-pad_"+value);
283
+      window["signaturePad_"+value] = new SignaturePad(canvas, {
284
+        onEnd: function () {
285
+          $("#signature_image_"+value).val(this.toDataURL());
286
+        }
287
+      });
288
+      window.addEventListener("resize", resizeCanvas(canvas));
289
+      resizeCanvas(canvas);
290
+    }catch(exception){
291
+
292
+    }
293
+  });
294
+}
295
+
296
+function resizeCanvas(canvas){
297
+  var parentWidth = $(canvas).parent().outerWidth();
298
+  canvas.setAttribute("width", parentWidth);
299
+}
300
+
301
+function submitForm(){
302
+  if($('#signature_image_cliente').val() == ''){
303
+    bootbox.alert("Inserisci la tua firma a fondo pagina!");
304
+    return;
305
+  }
306
+  $('#form_firma').submit();
307
+}
308
+
309
+function inviaLink(){
310
+  bootbox.prompt({
311
+    title: 'Inserisci indirizzo email',
312
+    inputType: 'email',
313
+    callback: function (result) {
314
+      $('#email_link').val(result);
315
+      $('#form_firma').submit();
316
+    }
317
+  });
318
+}
319
+</script>

+ 22
- 0
resources/views/issue/success_remoto.blade.php 查看文件

1
+<style>
2
+</style>
3
+
4
+<x-guest-layout>
5
+  <x-slot name="header">
6
+    <h2 class="font-semibold text-xl text-gray-800 leading-tight">
7
+      <i class="fas fa-ticket-alt"></i> Issue #{{ $issue_id }}
8
+    </h2>
9
+  </x-slot>
10
+
11
+  <div class="row justify-content-center mb-4">
12
+    <div class="col-xl-6 col-lg-6">
13
+      <div class="card">
14
+        <div class="card-body" style="text-align: center">
15
+          <h2 style="text-align: center">Rapportino per la segnalazione #{{ $issue_id }} firmato correttamente</h2><br>
16
+          <a href="{{ Storage::disk('temp')->url('issue_'.$issue_id.'.pdf') }}" class="btn btn-primary">Scarica rapporto firmato</a><br><br>
17
+        </div>
18
+      </div>
19
+    </div>
20
+  </div>
21
+
22
+</x-guest-layout>

+ 1
- 0
resources/views/layouts/guest.blade.php 查看文件

25
   <script src="{{ asset('js/bootstrap-datetimepicker.min.js') }}"></script>
25
   <script src="{{ asset('js/bootstrap-datetimepicker.min.js') }}"></script>
26
   <script src="{{ asset('/js/bootbox.all.min.js')}}"></script>
26
   <script src="{{ asset('/js/bootbox.all.min.js')}}"></script>
27
   <script src="{{ asset('/js/bootstrap.bundle-4.5.3.min.js')}}" crossorigin="anonymous"></script>
27
   <script src="{{ asset('/js/bootstrap.bundle-4.5.3.min.js')}}" crossorigin="anonymous"></script>
28
+  <script src="{{ asset('/js/signature_pad.min.js')}}"></script>
28
   <!-- <script src="{{ asset('js/sbadmin_pro.js') }}" defer></script> -->
29
   <!-- <script src="{{ asset('js/sbadmin_pro.js') }}" defer></script> -->
29
 
30
 
30
   <script src="https://cdnjs.cloudflare.com/ajax/libs/feather-icons/4.28.0/feather.min.js" crossorigin="anonymous"></script>
31
   <script src="https://cdnjs.cloudflare.com/ajax/libs/feather-icons/4.28.0/feather.min.js" crossorigin="anonymous"></script>

+ 5
- 1
routes/web.php 查看文件

28
 Route::post('login', [LoginController::class, 'login'])->name('login');
28
 Route::post('login', [LoginController::class, 'login'])->name('login');
29
 Route::post('logout', [LoginController::class, 'logout'])->name('logout');
29
 Route::post('logout', [LoginController::class, 'logout'])->name('logout');
30
 
30
 
31
+Route::get('issue/{token}/firma_remota', [IssueController::class, 'firma_remota'])->name('issue.firma_remota');
32
+Route::post('issue/firma_rapporto', [IssueController::class, 'firma_rapporto'])->name('issue.firma_rapporto');
33
+Route::get('issue/success_remoto', [IssueController::class, 'success_remoto'])->name('issue.success_remoto');
34
+Route::get('issue/download_allegato', [IssueController::class, 'download_allegato'])->name('issue.download_allegato');
31
 
35
 
32
 Route::middleware(['redmine_auth'])->group(function () {
36
 Route::middleware(['redmine_auth'])->group(function () {
33
   Route::get('home', [HomeController::class, 'home'])->name('home');
37
   Route::get('home', [HomeController::class, 'home'])->name('home');
34
   Route::get('issue', [IssueController::class, 'index'])->name('issue.index');
38
   Route::get('issue', [IssueController::class, 'index'])->name('issue.index');
35
   Route::get('issue/show', [IssueController::class, 'show'])->name('issue.show');
39
   Route::get('issue/show', [IssueController::class, 'show'])->name('issue.show');
36
   Route::get('issue/{id}/firma', [IssueController::class, 'firma'])->name('issue.firma');
40
   Route::get('issue/{id}/firma', [IssueController::class, 'firma'])->name('issue.firma');
37
-  Route::post('issue/firma_rapporto', [IssueController::class, 'firma_rapporto'])->name('issue.firma_rapporto');
38
   Route::get('issue/success', [IssueController::class, 'success'])->name('issue.success');
41
   Route::get('issue/success', [IssueController::class, 'success'])->name('issue.success');
39
 
42
 
43
+
40
   Route::resource('azienda', AziendaController::class, ['only' => ['index', 'store']]);
44
   Route::resource('azienda', AziendaController::class, ['only' => ['index', 'store']]);
41
 
45
 
42
   // Config
46
   // Config

正在加载...
取消
保存