From 2518980d7795272758643d6e8d1a5a2d05310a89 Mon Sep 17 00:00:00 2001
From: "florian.azizian" <florian.azizian@maarch.org>
Date: Fri, 1 Mar 2019 16:24:53 +0100
Subject: [PATCH] FEAT #9514 display acknowledgement receipt

---
 .../sendmail/acknowledgementReceiptsList.php  |  2 +-
 modules/sendmail/mail_form.php                |  4 +-
 rest/index.php                                |  1 +
 .../models/AcknowledgementReceiptModel.php    | 19 +++++
 .../resource/controllers/ResController.php    | 82 ++++++++++++++++---
 src/core/lang/lang-en.php                     |  1 +
 src/core/lang/lang-fr.php                     |  1 +
 src/core/lang/lang-nl.php                     |  2 +
 8 files changed, 97 insertions(+), 15 deletions(-)

diff --git a/modules/sendmail/acknowledgementReceiptsList.php b/modules/sendmail/acknowledgementReceiptsList.php
index 5db69c62aed..6aa7e862fa9 100644
--- a/modules/sendmail/acknowledgementReceiptsList.php
+++ b/modules/sendmail/acknowledgementReceiptsList.php
@@ -129,7 +129,7 @@ if (!empty($tab)) {
 
     // TO DO : LINK ROUTE
     $download = array(
-        "script"    => "window.open('../../rest/res/".$identifier."/content','_blank');",
+        "script"    => "window.open('../../rest/res/".$identifier."/acknowledgementReceipt/@@id@@','acknowledgementReceipt');",
         "icon"      =>  'eye',
         "tooltip"   =>  _VIEW_DOC,
         "disabledRules" => "empty(@@id@@)"
diff --git a/modules/sendmail/mail_form.php b/modules/sendmail/mail_form.php
index dc34ba2c25c..08b43ac15c5 100755
--- a/modules/sendmail/mail_form.php
+++ b/modules/sendmail/mail_form.php
@@ -906,7 +906,7 @@ if ($mode == 'add') {
 
                     $content .= '</table>';
                     //Filename
-                    $filename = 'notes_'.$identifier.'_'.date(dmY).'.html';
+                    $filename = 'notes_'.$identifier.'_'.date('dmY').'.html';
                     $all_joined_files .= _NOTES.': '.$filename.PHP_EOL;
                 }
             }
@@ -1303,7 +1303,7 @@ if ($mode == 'add') {
 
                     $content .= '</table>';
                     //Filename
-                    $filename = 'notes_'.$identifier.'_'.date(dmY).'.html';
+                    $filename = 'notes_'.$identifier.'_'.date('dmY').'.html';
                     $all_joined_files .= _NOTES.': '.$filename.PHP_EOL;
                 }
             }
diff --git a/rest/index.php b/rest/index.php
index f958e4e280c..b1225666552 100755
--- a/rest/index.php
+++ b/rest/index.php
@@ -253,6 +253,7 @@ $app->post('/res', \Resource\controllers\ResController::class . ':createRes');
 $app->post('/resExt', \Resource\controllers\ResController::class . ':createExt');
 $app->get('/res/{resId}/content', \Resource\controllers\ResController::class . ':getFileContent');
 $app->get('/res/{resId}/thumbnail', \Resource\controllers\ResController::class . ':getThumbnailContent');
+$app->get('/res/{resId}/acknowledgementReceipt/{id}', \Resource\controllers\ResController::class . ':getAcknowledgementReceipt');
 $app->put('/res/resource/status', \Resource\controllers\ResController::class . ':updateStatus');
 $app->post('/res/list', \Resource\controllers\ResController::class . ':getList');
 $app->get('/res/{resId}/notes/count', \Resource\controllers\ResController::class . ':getNotesCountForCurrentUserById');
diff --git a/src/app/acknowledgementReceipt/models/AcknowledgementReceiptModel.php b/src/app/acknowledgementReceipt/models/AcknowledgementReceiptModel.php
index 89bcca179b4..ef66a12f5da 100644
--- a/src/app/acknowledgementReceipt/models/AcknowledgementReceiptModel.php
+++ b/src/app/acknowledgementReceipt/models/AcknowledgementReceiptModel.php
@@ -36,6 +36,25 @@ class AcknowledgementReceiptModel
         return $aTemplates;
     }
 
+    public static function getById(array $aArgs)
+    {
+        ValidatorModel::notEmpty($aArgs, ['id']);
+        ValidatorModel::intVal($aArgs, ['id']);
+
+        $aReturn = DatabaseModel::select([
+            'select'    => empty($aArgs['select']) ? ['*'] : $aArgs['select'],
+            'table'     => ['acknowledgement_receipts'],
+            'where'     => ['id = ?'],
+            'data'      => [$aArgs['id']]
+        ]);
+
+        if (empty($aReturn[0])) {
+            return [];
+        }
+
+        return $aReturn[0];
+    }
+
     public static function getByResIds(array $aArgs = [])
     {
         ValidatorModel::notEmpty($aArgs, ['resIds']);
diff --git a/src/app/resource/controllers/ResController.php b/src/app/resource/controllers/ResController.php
index 352792983f6..5f693a00717 100755
--- a/src/app/resource/controllers/ResController.php
+++ b/src/app/resource/controllers/ResController.php
@@ -38,6 +38,7 @@ use SrcCore\models\CoreConfigModel;
 use SrcCore\models\ValidatorModel;
 use Status\models\StatusModel;
 use User\models\UserModel;
+use AcknowledgementReceipt\models\AcknowledgementReceiptModel;
 
 class ResController
 {
@@ -232,7 +233,7 @@ class ResController
             return $response->withStatus(403)->withJson(['errors' => 'Document out of perimeter']);
         }
 
-        $document = ResModel::getById(['select' => ['docserver_id', 'path', 'filename'], 'resId' => $aArgs['resId']]);
+        $document = ResModel::getById(['select' => ['docserver_id', 'path', 'filename', 'fingerprint'], 'resId' => $aArgs['resId']]);
         $extDocument = ResModel::getExtById(['select' => ['category_id', 'alt_identifier'], 'resId' => $aArgs['resId']]);
         if (empty($document) || empty($extDocument)) {
             return $response->withStatus(400)->withJson(['errors' => 'Document does not exist']);
@@ -296,7 +297,6 @@ class ResController
         if ($loadedXml) {
             $watermark = (array)$loadedXml->FEATURES->watermark;
             if ($watermark['enabled'] == 'true') {
-
                 $text = "watermark by {$GLOBALS['userId']}";
                 if (!empty($watermark['text'])) {
                     $text = $watermark['text'];
@@ -308,7 +308,7 @@ class ResController
                             $tmp = date('d-m-Y');
                         } elseif ($value == 'hour_now') {
                             $tmp = date('H:i');
-                        } elseif($value == 'alt_identifier'){
+                        } elseif ($value == 'alt_identifier') {
                             $tmp = $extDocument['alt_identifier'];
                         } else {
                             $backFromView = ResModel::getOnView(['select' => $value, 'where' => ['res_id = ?'], 'data' => [$aArgs['resId']]]);
@@ -391,6 +391,64 @@ class ResController
         return $response->withHeader('Content-Type', $mimeType);
     }
 
+    public function getAcknowledgementReceipt(Request $request, Response $response, array $aArgs)
+    {
+        if (!Validator::intVal()->validate($aArgs['resId']) || !ResController::hasRightByResId(['resId' => $aArgs['resId'], 'userId' => $GLOBALS['userId']])) {
+            return $response->withStatus(403)->withJson(['errors' => 'Document out of perimeter']);
+        }
+
+        $mainDocument = ResModel::getById(['select' => ['docserver_id', 'path', 'filename', 'fingerprint'], 'resId' => $aArgs['resId']]);
+        $extDocument = ResModel::getExtById(['select' => ['category_id', 'alt_identifier'], 'resId' => $aArgs['resId']]);
+        if (empty($mainDocument) || empty($extDocument)) {
+            return $response->withStatus(400)->withJson(['errors' => 'Document does not exist']);
+        }
+
+        $document = AcknowledgementReceiptModel::getById([
+            'select'  => ['docserver_id', 'path', 'filename', 'fingerprint'],
+            'id'      => $aArgs['id']
+        ]);
+
+        $docserver = DocserverModel::getByDocserverId(['docserverId' => $document['docserver_id'], 'select' => ['path_template', 'docserver_type_id']]);
+        if (empty($docserver['path_template']) || !file_exists($docserver['path_template'])) {
+            return $response->withStatus(400)->withJson(['errors' => 'Docserver does not exist']);
+        }
+
+        $pathToDocument = $docserver['path_template'] . str_replace('#', DIRECTORY_SEPARATOR, $document['path']) . $document['filename'];
+
+        if (!file_exists($pathToDocument)) {
+            return $response->withStatus(404)->withJson(['errors' => 'Document not found on docserver']);
+        }
+
+        $fingerprint = StoreController::getFingerPrint(['filePath' => $pathToDocument, 'mode' => 'SHA256']);
+        if (!empty($document['fingerprint']) && $document['fingerprint'] != $fingerprint) {
+            return $response->withStatus(400)->withJson(['errors' => 'Fingerprints do not match']);
+        }
+
+        $fileContent = file_get_contents($pathToDocument);
+
+        if ($fileContent === false) {
+            return $response->withStatus(404)->withJson(['errors' => 'Document not found on docserver']);
+        }
+
+        $finfo    = new \finfo(FILEINFO_MIME_TYPE);
+        $mimeType = $finfo->buffer($fileContent);
+        $pathInfo = pathinfo($pathToDocument);
+
+        $response->write($fileContent);
+        $response = $response->withAddedHeader('Content-Disposition', "inline; filename=maarch.{$pathInfo['extension']}");
+
+        HistoryController::add([
+            'tableName' => 'res_letterbox',
+            'recordId'  => $aArgs['resId'],
+            'eventType' => 'VIEW',
+            'info'      => _DOC_DISPLAYING . " : {$aArgs['resId']}",
+            'moduleId'  => 'res',
+            'eventId'   => 'resview',
+        ]);
+
+        return $response->withHeader('Content-Type', $mimeType);
+    }
+
     public function getThumbnailContent(Request $request, Response $response, array $aArgs)
     {
         if (!Validator::intVal()->validate($aArgs['resId'])) {
@@ -468,15 +526,15 @@ class ResController
         }
 
         foreach ($data['externalInfos'] as $mail) {
-            if(!Validator::intType()->validate($mail['res_id'])){
+            if (!Validator::intType()->validate($mail['res_id'])) {
                 return $response->withStatus(400)->withJson(['errors' => 'Bad Request: invalid res_id']);
             }
-            if(!Validator::StringType()->notEmpty()->validate($mail['external_id'])){
+            if (!Validator::StringType()->notEmpty()->validate($mail['external_id'])) {
                 return $response->withStatus(400)->withJson(['errors' => 'Bad Request: invalid external_id for element : '.$mail['res_id']]);
             }
-            if(!Validator::StringType()->notEmpty()->validate($mail['external_link'])){
+            if (!Validator::StringType()->notEmpty()->validate($mail['external_link'])) {
                 return $response->withStatus(400)->withJson(['errors' => 'Bad Request:  invalid external_link for element'.$mail['res_id']]);
-            }          
+            }
         }
 
         foreach ($data['externalInfos'] as $mail) {
@@ -488,7 +546,7 @@ class ResController
                 return $response->withStatus(403)->withJson(['errors' => 'Document out of perimeter']);
             }
             ResModel::update(['set' => ['external_id' => $mail['external_id'] , 'external_link' => $mail['external_link'], 'status' => $data['status']], 'where' => ['res_id = ?'], 'data' => [$document['res_id']]]);
-        }        
+        }
 
         return $response->withJson(['success' => 'success']);
     }
@@ -655,15 +713,15 @@ class ResController
             return $response->withStatus(400)->withJson(['errors' => 'Bad Request: clause is not valid']);
         }
         if (!empty($data['withFile'])) {
-            if(!Validator::boolType()->validate($data['withFile'])){
+            if (!Validator::boolType()->validate($data['withFile'])) {
                 return $response->withStatus(400)->withJson(['errors' => 'Bad Request: withFile parameter is not a boolean']);
-            }            
+            }
         }
 
         if (!empty($data['orderBy'])) {
             if (!Validator::arrayType()->notEmpty()->validate($data['orderBy'])) {
                 return $response->withStatus(400)->withJson(['errors' => 'Bad Request: orderBy parameter not valid']);
-            }            
+            }
         }
 
         if (!empty($data['limit'])) {
@@ -687,7 +745,7 @@ class ResController
         }
 
         if ($data['withFile'] === true) {
-            $select[] = 'res_id';            
+            $select[] = 'res_id';
         }
 
         $resources = ResModel::getOnView(['select' => $select, 'where' => $where, 'orderBy' => $data['orderBy'], 'limit' => $data['limit']]);
diff --git a/src/core/lang/lang-en.php b/src/core/lang/lang-en.php
index a70f4bd7196..32bef4a7135 100755
--- a/src/core/lang/lang-en.php
+++ b/src/core/lang/lang-en.php
@@ -135,6 +135,7 @@ define('_MAX_SIZE_UPLOAD_REACHED', 'File maximum size is exceeded');
 define('_PATH_OF_DOCSERVER_UNAPPROACHABLE', 'Inaccessible Docserver path');
 define('_BACK_FROM_VACATION', 'back from vacation');
 define('_DOC_DISPLAYING', 'Displaying document');
+define('_AR_DISPLAYING', 'Displaying acknowledgement receipt');
 define('_DOC_ADDED', 'Document added');
 define('_ATTACH_DISPLAYING', 'Displaying attachment');
 define('_NOTE_ADDED', 'Note added');
diff --git a/src/core/lang/lang-fr.php b/src/core/lang/lang-fr.php
index 987066402dc..691869ff700 100755
--- a/src/core/lang/lang-fr.php
+++ b/src/core/lang/lang-fr.php
@@ -135,6 +135,7 @@ define('_MAX_SIZE_UPLOAD_REACHED', 'Taille maximum de fichier dépassée');
 define('_PATH_OF_DOCSERVER_UNAPPROACHABLE', 'Chemin de la zone de stockage inaccessible');
 define('_BACK_FROM_VACATION', 'de retour de son absence');
 define('_DOC_DISPLAYING', 'Visualisation du document');
+define('_AR_DISPLAYING', 'Visualisation de l\'accusé de réception');
 define('_DOC_ADDED', 'Document ajouté');
 define('_ATTACH_DISPLAYING', 'Visualisation de la pièce jointe');
 define('_NOTE_ADDED', 'Annotation ajoutée');
diff --git a/src/core/lang/lang-nl.php b/src/core/lang/lang-nl.php
index 20e88a3d6db..a0d6fd7d3e1 100644
--- a/src/core/lang/lang-nl.php
+++ b/src/core/lang/lang-nl.php
@@ -444,3 +444,5 @@ define('_ACTION_DATE', 'Action date_TO_TRANSLATE');
 define('_USER_CREATED_IN_MAARCHPARAPHEUR', 'User created in Maarch Parapheur_TO_TRANSLATE');
 
 define('_SEND_ACKNOWLEDGEMENT_RECEIPT', 'Send acknowledgement receipt_TO_TRANSLATE');
+
+define('_AR_DISPLAYING', 'Displaying acknowledgement receipt_TO_TRANSLATE');
-- 
GitLab