Bladeren bron

firma remota rapportino

Roberto Santini 1 jaar geleden
bovenliggende
commit
a34b145cda

+ 151
- 14
app/Http/Controllers/IssueController.php Bestand weergeven

@@ -16,6 +16,8 @@ use Carbon\Carbon;
16 16
 use PDF;
17 17
 use Storage;
18 18
 use Session;
19
+use Notification;
20
+use App\Notifications\InviaLinkPerFirma;
19 21
 
20 22
 class IssueController extends Controller
21 23
 {
@@ -54,7 +56,7 @@ class IssueController extends Controller
54 56
       return view('issue.show')->with(['issue' => $issue, 'author' => $author]);
55 57
     }else{
56 58
       Session::flash('flash_message', "Errore generico");
57
-      dd($response_issue->object());
59
+      // dd($response_issue->object());
58 60
       return redirect()->route('home');
59 61
     }
60 62
   }
@@ -136,6 +138,17 @@ class IssueController extends Controller
136 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 154
     return view('issue.firma')->with([
@@ -147,11 +160,65 @@ class IssueController extends Controller
147 160
       'user' => $user,
148 161
       'sedeCliente' => $sedeCliente,
149 162
       'descrizione' => $descrizione,
150
-      'descrizione_id' => $descrizione_id
163
+      'descrizione_id' => $descrizione_id,
164
+      'helpdeskEmail' => $helpdeskEmail
151 165
     ]);
152 166
   }
153 167
 
154 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 223
     // Controllo orari e durata intervento
157 224
     try{
@@ -173,10 +240,9 @@ class IssueController extends Controller
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 246
       'key' => $redmineUser->api_key,
181 247
     ]);
182 248
     $issue = $response_issue->object()->issue;
@@ -201,6 +267,8 @@ class IssueController extends Controller
201 267
       }
202 268
     }
203 269
 
270
+    // dd($tecnici);
271
+
204 272
     // Firme
205 273
     $sign_path_cliente = 'sign_cliente_'.time().'.png';
206 274
     if($request->has('signature_image_cliente')){
@@ -257,7 +325,7 @@ class IssueController extends Controller
257 325
       'content-type' => 'application/octet-stream'
258 326
     ])
259 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 329
       'filename' => $filename
262 330
     ]);
263 331
 
@@ -291,7 +359,7 @@ class IssueController extends Controller
291 359
           'content-type' => 'application/octet-stream'
292 360
         ])
293 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 363
           'filename' => $originalFilename
296 364
         ]);
297 365
 
@@ -310,13 +378,44 @@ class IssueController extends Controller
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 414
     // Elimino le firme
316 415
     Storage::disk('temp')->delete([$sign_path_cliente]);
317 416
 
318 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 419
       'issue' => [
321 420
         'notes' => $request->note,
322 421
         'status_id' => $request->status_id,
@@ -335,7 +434,7 @@ class IssueController extends Controller
335 434
 
336 435
     // Aggiorno journal solo se non ho premuto "svuota" nell'interfaccia
337 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 438
         'key' => $redmineUser->api_key,
340 439
         'journal' => [
341 440
           'notes' => '',
@@ -352,7 +451,7 @@ class IssueController extends Controller
352 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 455
         'time_entry' => [
357 456
           'issue_id' => $request->issue_id,
358 457
           'spent_on' => $dataIntervento->toDateString(),
@@ -375,7 +474,7 @@ class IssueController extends Controller
375 474
 
376 475
       // Ore viaggio
377 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 478
           'time_entry' => [
380 479
             'issue_id' => $request->issue_id,
381 480
             'spent_on' => $dataIntervento->toDateString(),
@@ -401,7 +500,7 @@ class IssueController extends Controller
401 500
       // Aggiorno le relazioni
402 501
 
403 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 504
           'relation' => [
406 505
             'issue_to_id' => $segnalazioneCorrelata
407 506
           ]
@@ -412,7 +511,7 @@ class IssueController extends Controller
412 511
         // });
413 512
 
414 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 515
           'issue' => [
417 516
             'status_id' => $request->segnalazioneCorrelataStatus[$segnalazioneCorrelata],
418 517
           ]
@@ -427,7 +526,12 @@ class IssueController extends Controller
427 526
 
428 527
     // Session::flash('flash_message', "Issue aggiornato correttamente!");
429 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 537
   public function success(Request $request){
@@ -439,4 +543,37 @@ class IssueController extends Controller
439 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 Bestand weergeven

@@ -0,0 +1,63 @@
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 Bestand weergeven

@@ -10,37 +10,37 @@ use Illuminate\Database\Eloquent\Model;
10 10
 
11 11
 abstract class AbstractUser extends Model
12 12
 {
13
-    /**
13
+    /**  
14 14
      * The table associated with the model.
15
-     *
15
+     * 
16 16
      * @var string
17 17
      */
18 18
     protected $table = 'user';
19
-
20
-    /**
19
+    
20
+    /**  
21 21
      * Primary key type.
22
-     *
22
+     * 
23 23
      * @var string
24 24
      */
25 25
     protected $keyType = 'bigInteger';
26
-
27
-    /**
26
+    
27
+    /**  
28 28
      * The attributes that should be cast to native types.
29
-     *
29
+     * 
30 30
      * @var array
31 31
      */
32 32
     protected $casts = [
33 33
         'id' => 'integer',
34 34
         'redmine_id' => 'integer',
35 35
         'azienda_id' => 'integer',
36
-        // 'firma' => 'string',
36
+        'firma' => 'string',
37 37
         'created_at' => 'datetime',
38 38
         'updated_at' => 'datetime'
39 39
     ];
40
-
41
-    /**
40
+    
41
+    /**  
42 42
      * The attributes that are mass assignable.
43
-     *
43
+     * 
44 44
      * @var array
45 45
      */
46 46
     protected $fillable = [
@@ -51,9 +51,14 @@ abstract class AbstractUser extends Model
51 51
         'created_at',
52 52
         'updated_at'
53 53
     ];
54
-
54
+    
55 55
     public function azienda()
56 56
     {
57 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 Bestand weergeven

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

+ 64
- 0
app/Notifications/InviaLinkPerFirma.php Bestand weergeven

@@ -0,0 +1,64 @@
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 Bestand weergeven

@@ -0,0 +1,20 @@
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 Bestand weergeven

@@ -23,6 +23,6 @@ class AppServiceProvider extends ServiceProvider
23 23
      */
24 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 Bestand weergeven

@@ -53,6 +53,12 @@ return [
53 53
             'url' => env('APP_URL').'/storage/azienda',
54 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 Bestand weergeven

@@ -0,0 +1,49 @@
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 Bestand weergeven

@@ -13,6 +13,13 @@
13 13
       <div class="card">
14 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 23
           {{ $dataTable_issues->table() }}
17 24
 
18 25
           {{ $dataTable_issues->scripts() }}

+ 27
- 4
resources/views/issue/firma.blade.php Bestand weergeven

@@ -62,11 +62,13 @@ use App\Models\Config;
62 62
             <div class="form-group col-md">
63 63
               {!! Form::label('activity_id', 'Attività') !!}
64 64
               {!! Form::select('activity_id', $attivita, null, ['class' => 'form-control']) !!}
65
+              {!! Form::hidden('activity_label', '') !!}
65 66
             </div>
66 67
 
67 68
             <div class="form-group col-md" id="div_stato_segnalazione" style="display: none">
68 69
               {!! Form::label('status_id', 'Stato segnalazione') !!}
69 70
               {!! Form::select('status_id', $issueStatus, Config::getValue(Config::STATO_DA_COMPLETARE), ['class' => 'form-control']) !!}
71
+              {!! Form::hidden('status_label', '') !!}
70 72
             </div>
71 73
           </div>
72 74
 
@@ -180,7 +182,10 @@ use App\Models\Config;
180 182
             <tr>
181 183
               <td>{!! Form::checkbox('segnalazioneCorrelata[]', $segnalazione->id, false) !!}</td>
182 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 189
               <td>{!! Form::select('segnalazioneCorrelataStatus['.$segnalazione->id.']', $issueStatus, $segnalazione->status->id, ['class' => 'form-control']) !!}</td>
185 190
             </tr>
186 191
             @endforeach
@@ -242,7 +247,9 @@ use App\Models\Config;
242 247
 
243 248
           <div class="form-row">
244 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 253
             </div>
247 254
           </div>
248 255
 
@@ -386,7 +393,23 @@ function submitForm(){
386 393
 }
387 394
 
388 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 415
 </script>

+ 319
- 0
resources/views/issue/firma_remota.blade.php Bestand weergeven

@@ -0,0 +1,319 @@
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 Bestand weergeven

@@ -0,0 +1,22 @@
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 Bestand weergeven

@@ -25,6 +25,7 @@
25 25
   <script src="{{ asset('js/bootstrap-datetimepicker.min.js') }}"></script>
26 26
   <script src="{{ asset('/js/bootbox.all.min.js')}}"></script>
27 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 29
   <!-- <script src="{{ asset('js/sbadmin_pro.js') }}" defer></script> -->
29 30
 
30 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 Bestand weergeven

@@ -28,15 +28,19 @@ Route::get('login', [LoginController::class, 'index'])->name('login');
28 28
 Route::post('login', [LoginController::class, 'login'])->name('login');
29 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 36
 Route::middleware(['redmine_auth'])->group(function () {
33 37
   Route::get('home', [HomeController::class, 'home'])->name('home');
34 38
   Route::get('issue', [IssueController::class, 'index'])->name('issue.index');
35 39
   Route::get('issue/show', [IssueController::class, 'show'])->name('issue.show');
36 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 41
   Route::get('issue/success', [IssueController::class, 'success'])->name('issue.success');
39 42
 
43
+
40 44
   Route::resource('azienda', AziendaController::class, ['only' => ['index', 'store']]);
41 45
 
42 46
   // Config

Laden…
Annuleren
Opslaan