Proyectos de Subversion LeadersLinked - Backend

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
7218 eleazar 1
<?php
2
 
3
declare(strict_types=1);
4
 
5
namespace LeadersLinked\Controller;
6
 
7
use Laminas\Db\Adapter\AdapterInterface;
16768 efrain 8
 
7218 eleazar 9
use Laminas\Mvc\Controller\AbstractActionController;
10
use Laminas\Log\LoggerInterface;
11
use Laminas\View\Model\ViewModel;
12
use Laminas\View\Model\JsonModel;
13
use LeadersLinked\Mapper\QueryMapper;
14
use Laminas\Db\Sql\Select;
15
use LeadersLinked\Library\Functions;
16
use LeadersLinked\Mapper\OrganizationalClimateTestMapper;
17
use LeadersLinked\Mapper\OrganizationalClimateMapper;
18
use LeadersLinked\Mapper\OrganizationalClimateFormMapper;
19
use LeadersLinked\Form\OrganizationalClimateTestForm;
20
use LeadersLinked\Model\OrganizationalClimateTest;
21
use LeadersLinked\Mapper\UserMapper;
22
use LeadersLinked\Hydrator\ObjectPropertyHydrator;
7530 eleazar 23
use LeadersLinked\Library\SurveyReport;
7218 eleazar 24
use PhpOffice\PhpSpreadsheet\Spreadsheet;
25
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
26
use PhpOffice\PhpSpreadsheet\IOFactory;
27
 
28
class OrganizationalClimateReportController extends AbstractActionController {
29
 
30
    /**
31
     *
32
     * @var AdapterInterface
33
     */
34
    private $adapter;
16768 efrain 35
 
7218 eleazar 36
    /**
37
     *
38
     * @var  LoggerInterface
39
     */
40
    private $logger;
16768 efrain 41
 
7218 eleazar 42
    /**
43
     *
44
     * @var array
45
     */
46
    private $config;
16768 efrain 47
 
7218 eleazar 48
    /**
49
     *
50
     * @param AdapterInterface $adapter
51
     * @param LoggerInterface $logger
52
     * @param array $config
53
     */
16768 efrain 54
    public function __construct($adapter, $logger, $config)
55
    {
7218 eleazar 56
        $this->adapter = $adapter;
57
        $this->logger = $logger;
58
        $this->config = $config;
59
    }
60
 
61
    public function indexAction() {
62
 
63
        $request = $this->getRequest();
64
        $currentUserPlugin = $this->plugin('currentUserPlugin');
65
        $currentCompany = $currentUserPlugin->getCompany();
66
        $currentUser = $currentUserPlugin->getUser();
67
 
68
        try{
69
        $request = $this->getRequest();
70
        if ($request->isGet()) {
71
 
72
            $headers = $request->getHeaders();
73
 
74
            $isJson = false;
75
            if ($headers->has('Accept')) {
76
                $accept = $headers->get('Accept');
77
 
78
                $prioritized = $accept->getPrioritized();
79
 
80
                foreach ($prioritized as $key => $value) {
81
                    $raw = trim($value->getRaw());
82
 
83
                    if (!$isJson) {
84
                        $isJson = strpos($raw, 'json');
85
                    }
86
                }
87
            }
88
 
89
            if ($isJson) {
90
 
91
                $search = $this->params()->fromQuery('search', []);
16766 efrain 92
                $search = empty($search['value']) ? '' :  Functions::sanitizeFilterString($search['value']);
7218 eleazar 93
 
15371 efrain 94
                $start = intval($this->params()->fromQuery('start', 0), 10);
7218 eleazar 95
                $records_x_page = intval($this->params()->fromQuery('length', 10), 10);
15371 efrain 96
                $page =  intval($start / $records_x_page);
97
                $page++;
98
 
7218 eleazar 99
                $order = $this->params()->fromQuery('order', []);
100
                $order_field = empty($order[0]['column']) ? 99 : intval($order[0]['column'], 10);
16766 efrain 101
                $order_direction = empty($order[0]['dir']) ? 'ASC' : Functions::sanitizeFilterString(filter_var($order[0]['dir']));
7218 eleazar 102
 
103
                $fields = ['name'];
104
                $order_field = isset($fields[$order_field]) ? $fields[$order_field] : 'name';
105
 
106
                if (!in_array($order_direction, ['ASC', 'DESC'])) {
107
                    $order_direction = 'ASC';
108
                }
109
 
110
                $organizationalClimateMapper = OrganizationalClimateMapper::getInstance($this->adapter);
111
                $paginator = $organizationalClimateMapper->fetchAllDataTableByCompanyId($currentCompany->id, $search, $page, $records_x_page, $order_field, $order_direction);
112
 
113
                $organizationalClimateFormMapper = OrganizationalClimateFormMapper::getInstance($this->adapter);
114
 
115
                $items = [];
116
                $records = $paginator->getCurrentItems();
117
 
118
                foreach ($records as $record) {
119
                    $organizationalClimateForm = $organizationalClimateFormMapper->fetchOne($record->form_id);
120
                    $params = [
121
 
122
                        'id' => $record->uuid,
123
                    ];
124
                    $item = [
125
                        'id' => $record->id,
126
                        'name' => $record->name,
127
                        'form' => $organizationalClimateForm->name,
128
                        'status' => $record->status,
129
                        'actions' => [
12997 efrain 130
                            'link_report_all' => $this->url()->fromRoute('organizational-climate/report/all', ['organizational_climate_id' => $record->uuid]),
131
                            'link_report_csv' => $this->url()->fromRoute('organizational-climate/report/csv', ['organizational_climate_id' => $record->uuid]),
132
                            'link_overview' => $this->url()->fromRoute('organizational-climate/report/overview', ['organizational_climate_id' => $record->uuid])
7218 eleazar 133
                        ]
134
                    ];
135
 
136
                    array_push($items, $item);
137
                }
138
 
139
                return new JsonModel([
140
                    'success' => true,
141
                    'data' => [
142
                        'items' => $items,
143
                        'total' => $paginator->getTotalItemCount(),
144
                    ]
145
                ]);
146
            } else {
147
                $organizationalClimateMapper = OrganizationalClimateMapper::getInstance($this->adapter);
148
                $survies = $organizationalClimateMapper->fetchAllByCompanyId($currentCompany->id);
149
 
150
                $form = new OrganizationalClimateTestForm($this->adapter, $currentCompany->id);
151
 
152
                $this->layout()->setTemplate('layout/layout-backend');
153
                $viewModel = new ViewModel();
154
                $viewModel->setTemplate('leaders-linked/organizational-climate-report/index.phtml');
155
                $viewModel->setVariables([
156
                    'form'      => $form,
157
                    'survies' => $survies
158
                ]);
159
                return $viewModel;
160
            }
161
        } else {
162
            return new JsonModel([
163
                'success' => false,
164
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
165
            ]);
166
 
167
        }
168
        } catch (\Throwable $e) {
169
            $e->getMessage();
170
            return new JsonModel([
171
                'success' => false,
172
                'data' => $e
173
            ]);
174
        }
175
 
176
    }
177
 
178
    public function overviewAction(){
179
        $request = $this->getRequest();
180
        $currentUserPlugin = $this->plugin('currentUserPlugin');
181
        $currentCompany = $currentUserPlugin->getCompany();
182
        $currentUser = $currentUserPlugin->getUser();
183
 
184
        $request = $this->getRequest();
12997 efrain 185
        $uuid = $this->params()->fromRoute('organizational_climate_id');
7218 eleazar 186
 
187
        if (!$uuid) {
188
            $data = [
189
                'success' => false,
190
                'data' => 'ERROR_INVALID_PARAMETER'
191
            ];
192
 
193
            return new JsonModel($data);
194
        }
195
 
196
        $organizationalClimateMapper = OrganizationalClimateMapper::getInstance($this->adapter);
197
        $organizationalClimate = $organizationalClimateMapper->fetchOneByUuid($uuid);
198
 
199
        $organizationalClimateMapper = OrganizationalClimateMapper::getInstance($this->adapter);
200
        $organizationalClimate = $organizationalClimateMapper->fetchOneByUuid($uuid);
201
 
202
        $organizationalClimateTestMapper = OrganizationalClimateTestMapper::getInstance($this->adapter);
7532 eleazar 203
        $organizationalClimateTests = $organizationalClimateTestMapper->fetchAllBySurveyId($organizationalClimate->id);
7218 eleazar 204
 
205
        $organizationalClimateFormMapper = OrganizationalClimateFormMapper::getInstance($this->adapter);
206
        $organizationalClimateForm = $organizationalClimateFormMapper->fetchOne($organizationalClimate->form_id);
207
 
208
        $sections = json_decode($organizationalClimateForm->content, true);
209
 
210
        $allTests = array_map(
211
            function($response) {
212
                return json_decode($response->content, true);
213
            },
214
            $organizationalClimateTests,
215
        );
216
 
217
        $averages = [];
218
 
219
        foreach($sections as $section) {
220
            foreach($section['questions'] as $question) {
221
                switch ($question['type']) {
222
                    case 'multiple':
223
                        $totals = [];
224
 
225
                        foreach($question['options'] as $option) {
226
                            $totals[$option['slug_option']] = 0;
227
                        }
228
 
229
                        foreach($question['options'] as $option) {
230
                            $totals[$option['slug_option']] = count(array_filter(
231
                                $allTests,
232
                                function ($test) use($option, $question) {
233
                                    return in_array($option['slug_option'], $test[$question['slug_question']]);
234
                                }
235
                            ));
236
                        }
237
 
238
                        $averages[$question['slug_question']] = $totals;
239
 
240
                        break;
241
 
242
                    case 'simple':
243
                        $totals = [];
244
 
245
                        foreach($question['options'] as $option) {
246
                            $totals[$option['slug_option']] = 0;
247
                        }
248
 
249
                        foreach ($allTests as $test) {
250
                            $totals[$test[$question['slug_question']]]++;
251
                        }
252
 
253
                        foreach($totals as $slug => $amount) {
254
                            $totals[$slug] = ($amount / count($allTests)) * 100;
255
                        }
256
 
257
                        $averages[$question['slug_question']] = $totals;
258
                    break;
259
 
260
                }
261
            }
262
        }
263
 
264
        $this->layout()->setTemplate('layout/layout-backend.phtml');
265
        $viewModel = new ViewModel();
266
        $viewModel->setTemplate('leaders-linked/organizational-climate-report/overview.phtml');
267
        $viewModel->setVariables([
268
            'sections' => $sections,
269
            'averages' => $averages,
270
        ]);
271
        return $viewModel ;
272
 
273
    }
274
 
275
    public function allAction() {
276
        $request = $this->getRequest();
277
        $currentUserPlugin = $this->plugin('currentUserPlugin');
278
        $currentCompany = $currentUserPlugin->getCompany();
279
        $currentUser = $currentUserPlugin->getUser();
280
 
281
        $request = $this->getRequest();
12997 efrain 282
        $uuid = $this->params()->fromRoute('organizational_climate_id');
7218 eleazar 283
 
284
 
285
 
286
        if (!$uuid) {
287
            $data = [
288
                'success' => false,
289
                'data' => 'ERROR_INVALID_PARAMETER'
290
            ];
291
 
292
            return new JsonModel($data);
293
        }
294
 
295
        $organizationalClimateMapper = OrganizationalClimateMapper::getInstance($this->adapter);
296
        $organizationalClimate = $organizationalClimateMapper->fetchOneByUuid($uuid);
297
 
298
        $organizationalClimateTestMapper = OrganizationalClimateTestMapper::getInstance($this->adapter);
7528 eleazar 299
        $organizationalClimateTests = $organizationalClimateTestMapper->fetchAllBySurveyId($organizationalClimate->id);
7218 eleazar 300
 
301
        if (!$organizationalClimateTests) {
302
            $data = [
303
                'success' => false,
304
                'data' => 'ERROR_RECORD_NOT_FOUND'
305
            ];
306
 
307
            return new JsonModel($data);
308
        }
309
 
310
 
311
        if ($request->isGet()) {
312
            $hydrator = new ObjectPropertyHydrator();
313
 
314
            //get form data
315
            $organizationalClimateFormMapper = OrganizationalClimateFormMapper::getInstance($this->adapter);
316
            $organizationalClimateForm = $organizationalClimateFormMapper->fetchOne($organizationalClimate->form_id);
317
 
318
            if ($organizationalClimateForm) {
319
 
320
                return $this->renderPDF($organizationalClimateForm, $organizationalClimateTests, $organizationalClimate);
321
            } else {
322
 
323
                $data = [
324
                    'success' => false,
325
                    'data' => 'ERROR_METHOD_NOT_ALLOWED'
326
                ];
327
 
328
                return new JsonModel($data);
329
            }
330
        } else {
331
            $data = [
332
                'success' => false,
333
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
334
            ];
335
 
336
            return new JsonModel($data);
337
        }
338
 
339
        return new JsonModel($data);
340
    }
341
 
342
 
343
    public function renderPDF($organizationalClimateForm, $organizationalClimateTests, $organizationalClimate) {
344
 
345
        $target_path = $this->config['leaderslinked.fullpath.company'] . DIRECTORY_SEPARATOR . $organizationalClimate->uuid;
346
 
347
 
348
        if(file_exists($target_path)) {
349
            Functions::deleteFiles($target_path);
350
        } else {
351
            @mkdir($target_path, 0755, true);
352
        }
353
 
354
        // Set Data
16768 efrain 355
        $headerFormName = Functions::utf8_decode($organizationalClimateForm->name);
356
        $headerSurveyName = Functions::utf8_decode('Informe de Encuesta: ' . trim($organizationalClimate->name) . ' al ' . date("m-d-Y H:i:s", strtotime($organizationalClimate->added_on)));
7218 eleazar 357
        $sections = json_decode($organizationalClimateForm->content, true);
358
 
359
        $allTests = array_map(
360
            function($response) {
361
                return json_decode($response->content, true);
362
            },
363
            $organizationalClimateTests,
364
        );
365
 
366
        $averages = [];
367
 
368
        foreach($sections as $section) {
369
            foreach($section['questions'] as $question) {
370
                switch ($question['type']) {
371
                    case 'multiple':
372
                        $totals = [];
373
 
374
                        foreach($question['options'] as $option) {
375
                            $totals[$option['slug_option']] = 0;
376
                        }
377
 
378
                        foreach($question['options'] as $option) {
379
                            $totals[$option['slug_option']] = count(array_filter(
380
                                $allTests,
381
                                function ($test) use($option, $question) {
382
                                    return in_array($option['slug_option'], $test[$question['slug_question']]);
383
                                }
384
                            ));
385
                        }
386
 
387
                        $averages[$question['slug_question']] = $totals;
388
 
389
                        break;
390
 
391
                    case 'simple':
392
                        $totals = [];
393
 
394
                        foreach($question['options'] as $option) {
395
                            $totals[$option['slug_option']] = 0;
396
                        }
397
 
398
                        foreach ($allTests as $test) {
399
                            $totals[$test[$question['slug_question']]]++;
400
                        }
401
 
402
                        foreach($totals as $slug => $amount) {
403
                            $totals[$slug] = ($amount / count($allTests)) * 100;
404
                        }
405
 
406
                        $averages[$question['slug_question']] = $totals;
407
                    break;
408
 
409
                }
410
            }
411
        }
412
 
413
        //Generate New PDF
7529 eleazar 414
        $pdf = new SurveyReport();
7218 eleazar 415
 
416
        $pdf->AliasNbPages();
417
        $pdf->AddPage();
418
 
419
        // Set header secundary
7529 eleazar 420
        $pdf->customHeader($headerFormName, $headerSurveyName);
7218 eleazar 421
 
422
        $countSection = 0;
423
 
424
        for ($i = 0; $i < count($sections); $i++) {
425
            if ($countSection > 1) {
426
                $countSection = 0;
427
                $pdf->AddPage();
428
                $pdf->customHeader($headerFormName, $headerUserName);
429
            }
430
            $section = $sections[$i];
431
 
432
            foreach ($section['questions'] as $question) {
433
 
434
                    switch ($question['type']) {
435
                        case 'simple':
436
                            $labels = [];
437
                            $values = [];
438
 
439
                            foreach($question['options'] as $option) {
440
                                $labels []= strip_tags($option['text']) . "\n(%.1f%%)";
441
 
442
                                $values []= $averages[$question['slug_question']][$option['slug_option']];
443
                            }
444
 
445
                            $filename = $target_path . DIRECTORY_SEPARATOR .  $question['slug_question'] . '.png';
446
                            $pdf->Cell(0,10,strip_tags(trim(str_replace(' ', ' ', html_entity_decode($question['text'])))),0,1);
447
                            $pdf->pieChart($labels, $values, '', $filename);
448
                            $pdf->SetFont('Arial', '', 12);
449
                            $pdf->Image($filename, 45, $pdf->getY(), 120);
450
                            $pdf->setY($pdf->getY() + 90);
451
 
452
 
453
                            break;
454
 
455
                        case 'multiple':
456
                            $labels = [];
457
                            $values = [];
458
 
459
                            foreach($question['options'] as $option) {
460
                                $labels []= strip_tags($option['text']);
461
 
462
                                $values []= $averages[$question['slug_question']][$option['slug_option']];
463
                            }
464
 
465
                            $filename = $target_path . DIRECTORY_SEPARATOR .  $question['slug_question'] . '.png';
466
                            $pdf->Cell(0,10,strip_tags($question['text']),0,1);
467
                            $pdf->barChart($labels, $values, '', $filename);
468
                            $pdf->SetFont('Arial', '', 12);
469
                            $pdf->Image($filename, 12, $pdf->getY());
470
                            $pdf->setY($pdf->getY() + (count($values) * 13) + 10);
471
 
472
                            break;
473
                    }
474
                $countSection++;
475
            }
476
 
477
 
478
        }
479
 
480
        return $pdf->Output();
481
    }
482
 
483
    public function csvAction() {
484
        $request = $this->getRequest();
485
        $currentUserPlugin = $this->plugin('currentUserPlugin');
486
        $currentCompany = $currentUserPlugin->getCompany();
487
        $currentUser = $currentUserPlugin->getUser();
488
 
489
        $request = $this->getRequest();
12997 efrain 490
        $uuid = $this->params()->fromRoute('organizational_climate_id');
7218 eleazar 491
 
492
 
493
 
494
        if (!$uuid) {
495
            $data = [
496
                'success' => false,
497
                'data' => 'ERROR_INVALID_PARAMETER'
498
            ];
499
 
500
            return new JsonModel($data);
501
        }
502
 
503
        $organizationalClimateMapper = OrganizationalClimateMapper::getInstance($this->adapter);
504
        $organizationalClimate = $organizationalClimateMapper->fetchOneByUuid($uuid);
505
 
506
        $organizationalClimateTestMapper = OrganizationalClimateTestMapper::getInstance($this->adapter);
7529 eleazar 507
        $organizationalClimateTests = $organizationalClimateTestMapper->fetchAllBySurveyId($organizationalClimate->id);
7218 eleazar 508
 
509
        if (!$organizationalClimateTests) {
510
            $data = [
511
                'success' => false,
512
                'data' => 'ERROR_RECORD_NOT_FOUND'
513
            ];
514
 
515
            return new JsonModel($data);
516
        }
517
 
518
 
519
        if ($request->isGet()) {
520
            $hydrator = new ObjectPropertyHydrator();
521
 
522
            //get form data
523
            $organizationalClimateFormMapper = OrganizationalClimateFormMapper::getInstance($this->adapter);
524
            $organizationalClimateForm = $organizationalClimateFormMapper->fetchOne($organizationalClimate->form_id);
525
 
526
            if ($organizationalClimateForm) {
527
 
528
                return $this->csvRender($organizationalClimateForm, $organizationalClimateTests, $organizationalClimate);
529
            } else {
530
 
531
                $data = [
532
                    'success' => false,
533
                    'data' => 'ERROR_METHOD_NOT_ALLOWED'
534
                ];
535
 
536
                return new JsonModel($data);
537
            }
538
        } else {
539
            $data = [
540
                'success' => false,
541
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
542
            ];
543
 
544
            return new JsonModel($data);
545
        }
546
 
547
        return new JsonModel($data);
548
    }
549
 
550
 
551
    public function csvRender($organizationalClimateForm, $organizationalClimateTests, $organizationalClimate)
552
    {
553
        $sections = json_decode($organizationalClimateForm->content, true);
554
 
555
        $spreadsheet = new Spreadsheet();
556
        $sheet = $spreadsheet->getActiveSheet();
557
 
558
        $allTests = array_map(
559
            function($response) {
560
                return json_decode($response->content, true);
561
            },
562
            $organizationalClimateTests,
563
        );
564
 
565
        $averages = [];
566
 
567
        foreach($sections as $section) {
568
            foreach($section['questions'] as $question) {
569
                switch ($question['type']) {
570
                    case 'multiple':
571
                        $totals = [];
572
 
573
                        foreach($question['options'] as $option) {
574
                            $totals[$option['slug_option']] = 0;
575
                        }
576
 
577
                        foreach($question['options'] as $option) {
578
                            $totals[$option['slug_option']] = count(array_filter(
579
                                $allTests,
580
                                function ($test) use($option, $question) {
581
                                    return in_array($option['slug_option'], $test[$question['slug_question']]);
582
                                }
583
                            ));
584
                        }
585
 
586
                        $averages[$question['slug_question']] = $totals;
587
 
588
                        break;
589
 
590
                    case 'simple':
591
                        $totals = [];
592
 
593
                        foreach($question['options'] as $option) {
594
                            $totals[$option['slug_option']] = 0;
595
                        }
596
 
597
                        foreach ($allTests as $test) {
598
                            $totals[$test[$question['slug_question']]]++;
599
                        }
600
 
601
                        foreach($totals as $slug => $amount) {
602
                            $totals[$slug] = ($amount / count($allTests)) * 100;
603
                        }
604
 
605
                        $averages[$question['slug_question']] = $totals;
606
                    break;
607
 
608
                }
609
            }
610
        }
611
 
612
        $row = 1;
613
 
614
        for ($i = 0; $i < count($sections); $i++) {
615
            $section = $sections[$i];
616
 
617
           for($j = 0; $j < count($section['questions']); $j++) {
618
                $question = $section['questions'][$j];
619
 
620
                if (!in_array($question['type'], ['simple', 'multiple'])){
621
                    continue;
622
                }
623
                $sheet->setCellValueByColumnAndRow(1, $row++, strip_tags($question['text']));
624
 
625
                switch ($question['type']) {
626
                    case 'simple':
627
                        for($k = 0; $k < count($question['options']); $k++) {
628
                            $option = $question['options'][$k];
629
                            $sheet->setCellValueByColumnAndRow(1, $row, strip_tags($option['text']));
630
                            $sheet->setCellValueByColumnAndRow(2, $row, round($averages[$question['slug_question']][$option['slug_option']], 2) . '%');
631
                            $row++;
632
                        }
633
 
634
                        break;
635
 
636
                    case 'multiple':
637
                        for($k = 0; $k < count($question['options']); $k++) {
638
                            $option = $question['options'][$k];
639
                            $sheet->setCellValueByColumnAndRow(1, $row, strip_tags($option['text']));
640
                            $sheet->setCellValueByColumnAndRow(2, $row,$averages[$question['slug_question']][$option['slug_option']]);
641
                            $row++;
642
                        }
643
 
644
                        break;
645
                }
646
            }
647
 
648
 
649
        }
650
 
651
        header('Content-Description: File Transfer');
652
        header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
653
        header('Content-Disposition: attachment; filename=report.xls');
654
        header('Content-Transfer-Encoding: binary');
655
        header('Expires: 0');
656
        header('Cache-Control: must-revalidate');
657
        header('Pragma: public');
658
 
659
        $writer = new Xlsx($spreadsheet);
660
 
661
        ob_clean();
662
        flush();
663
        $writer->save('php://output');
664
        return;
665
    }
666
}