From 1a05a4453cbaaec1c5ee686f3772ad741c9bcc10 Mon Sep 17 00:00:00 2001
From: Damien <damien.burel@maarch.org>
Date: Thu, 15 Nov 2018 18:36:27 +0100
Subject: [PATCH] FEAT #8759 Create documents

---
 rest/index.php                                |  1 +
 sql/structure.sql                             | 15 ++--
 src/app/attachment/models/AttachmentModel.php | 18 ++++
 .../controllers/DocumentController.php        | 84 +++++++++++++++++++
 src/app/document/models/DocumentModel.php     | 27 ++++++
 src/app/status/models/StatusModel.php         | 15 ++++
 6 files changed, 152 insertions(+), 8 deletions(-)

diff --git a/rest/index.php b/rest/index.php
index 1172d47899..adc9e468d2 100755
--- a/rest/index.php
+++ b/rest/index.php
@@ -54,6 +54,7 @@ $app->get('/logout', \SrcCore\controllers\AuthenticationController::class . ':lo
 $app->get('/attachments/{id}', \Attachment\controllers\AttachmentController::class . ':getById');
 
 //Documents
+$app->post('/documents', \Document\controllers\DocumentController::class . ':create');
 $app->get('/documents', \Document\controllers\DocumentController::class . ':get');
 $app->get('/documents/{id}', \Document\controllers\DocumentController::class . ':getById');
 $app->put('/documents/{id}/action', \Document\controllers\DocumentController::class . ':makeAction');
diff --git a/sql/structure.sql b/sql/structure.sql
index e8d1dc2759..2522145c8f 100755
--- a/sql/structure.sql
+++ b/sql/structure.sql
@@ -14,16 +14,15 @@ DROP TABLE IF EXISTS main_documents;
 CREATE TABLE main_documents
 (
   id serial NOT NULL,
-  external_id character varying(255),
-  reference character varying(255),
-  subject text,
-  doc_date timestamp without time zone,
-  status integer NOT NULL,
-  priority character varying(255),
+  reference CHARACTER VARYING(255),
+  subject text NOT NULL,
+  status INTEGER NOT NULL,
+  processing_user INTEGER NOT NULL,
   sender text NOT NULL,
   sender_entity text,
-  processing_user integer NOT NULL,
   recipient text,
+  priority CHARACTER VARYING(64),
+  limit_date timestamp without time zone,
   creation_date timestamp without time zone NOT NULL DEFAULT NOW(),
   modification_date timestamp without time zone DEFAULT NOW(),
   CONSTRAINT main_documents_pkey PRIMARY KEY (id)
@@ -48,7 +47,7 @@ CREATE TABLE status
 (
   id serial,
   reference character varying(10) NOT NULL,
-  label character varying(50) NOT NULL,
+  label character varying(64) NOT NULL,
   CONSTRAINT status_pkey PRIMARY KEY (id),
   CONSTRAINT status_reference_key UNIQUE (reference)
 )
diff --git a/src/app/attachment/models/AttachmentModel.php b/src/app/attachment/models/AttachmentModel.php
index 0647813591..477617a5c2 100755
--- a/src/app/attachment/models/AttachmentModel.php
+++ b/src/app/attachment/models/AttachmentModel.php
@@ -69,4 +69,22 @@ class AttachmentModel
 
         return $attachments;
     }
+
+    public static function create(array $aArgs)
+    {
+        ValidatorModel::notEmpty($aArgs, ['main_document_id', 'subject']);
+        ValidatorModel::stringType($aArgs, ['reference', 'subject']);
+        ValidatorModel::intVal($aArgs, ['main_document_id']);
+
+        DatabaseModel::insert([
+            'table'         => 'attachments',
+            'columnsValues' => [
+                'main_document_id'  => $aArgs['main_document_id'],
+                'reference'         => empty($aArgs['reference']) ? null : $aArgs['reference'],
+                'subject'           => $aArgs['subject']
+            ]
+        ]);
+
+        return true;
+    }
 }
diff --git a/src/app/document/controllers/DocumentController.php b/src/app/document/controllers/DocumentController.php
index f90c866d6a..ba17cccb1c 100755
--- a/src/app/document/controllers/DocumentController.php
+++ b/src/app/document/controllers/DocumentController.php
@@ -14,6 +14,7 @@
 
 namespace Document\controllers;
 
+use Respect\Validation\Validator;
 use SrcCore\models\CoreConfigModel;
 use Attachment\models\AttachmentModel;
 use Convert\models\AdrModel;
@@ -105,6 +106,58 @@ class DocumentController
         return $response->withJson(['document' => $document]);
     }
 
+    public function create(Request $request, Response $response)
+    {
+        $data = $request->getParams();
+
+        $check = Validator::stringType()->notEmpty()->validate($data['encodedZipDocument']);
+        $check = $check && Validator::stringType()->notEmpty()->validate($data['subject']);
+        $check = $check && Validator::stringType()->notEmpty()->validate($data['status']);
+        $check = $check && Validator::intVal()->notEmpty()->validate($data['processing_user']);
+        $check = $check && Validator::stringType()->notEmpty()->validate($data['sender']);
+        if (!$check) {
+            return $response->withStatus(400)->withJson(['errors' => 'Bad Request']);
+        }
+
+        $data['attachments'] = empty($data['attachments']) ? [] : $data['attachments'];
+//        foreach ($data['attachments'] as $key => $attachment) {
+//            $check = Validator::stringType()->notEmpty()->validate($attachment['encodedZipDocument']);
+//            $check = $check && Validator::stringType()->notEmpty()->validate($attachment['subject']);
+//            if (!$check) {
+//                return $response->withStatus(400)->withJson(['errors' => "Missing data for attachment {$key}"]);
+//            }
+//        }
+
+        $encodedDocument = DocumentController::getEncodedDocumentFromEncodedZip(['encodedZipDocument' => $data['encodedZipDocument']]);
+        if (!empty($encodedDocument['errors'])) {
+            return $response->withStatus(500)->withJson(['errors' => $encodedDocument['errors']]);
+        }
+
+        $storeInfos = DocserverController::storeResourceOnDocServer([
+            'encodedFile'       => $encodedDocument['encodedDocument'],
+            'format'            => 'pdf',
+            'docserverType'     => 'DOC'
+        ]);
+        if (!empty($storeInfos['errors'])) {
+            return $response->withStatus(500)->withJson(['errors' => $storeInfos['errors']]);
+        }
+
+        $status = StatusModel::get(['select' => ['id'], 'where' => ['reference = ?'], 'data' => [$data['status']]]);
+        $data['status'] = $status[0]['id'];
+
+        $id = DocumentModel::create($data);
+
+        AdrModel::createDocumentAdr([
+            'documentId'     => $id,
+            'type'           => 'DOC',
+            'path'           => $storeInfos['path'],
+            'filename'       => $storeInfos['filename'],
+            'fingerprint'    => $storeInfos['fingerprint']
+        ]);
+
+        return $response->withJson(['documentId' => $id]);
+    }
+
     public function makeAction(Request $request, Response $response, array $args)
     {
         $data = $request->getParams();
@@ -246,4 +299,35 @@ class DocumentController
 
         return true;
     }
+
+    public static function getEncodedDocumentFromEncodedZip(array $args)
+    {
+        ValidatorModel::notEmpty($args, ['encodedZipDocument']);
+        ValidatorModel::stringType($args, ['encodedZipDocument']);
+
+        $tmpPath = CoreConfigModel::getTmpPath();
+
+        $zipDocumentOnTmp = $tmpPath . mt_rand() . '_parapheur.zip';
+        file_put_contents($zipDocumentOnTmp, base64_decode($args['encodedZipDocument']));
+
+        $zipArchive = new \ZipArchive();
+        $open = $zipArchive->open($zipDocumentOnTmp);
+        if ($open != true) {
+            return ['errors' => "getDocumentFromEncodedZip : $open"];
+        }
+
+        $dirOnTmp = $tmpPath . mt_rand() . '_parapheur';
+        if (!$zipArchive->extractTo($dirOnTmp)) {
+            return ['errors' => "getDocumentFromEncodedZip : Extract failed"];
+        }
+
+        $filesOnTmp = scandir($dirOnTmp);
+        foreach ($filesOnTmp as $fileOnTmp) {
+            if ($fileOnTmp != '.' && $fileOnTmp != '..') {
+                return ['encodedDocument' => base64_encode(file_get_contents("{$dirOnTmp}/{$fileOnTmp}"))];
+            }
+        }
+
+        return ['errors' => "getDocumentFromEncodedZip : No document was found in Zip"];
+    }
 }
diff --git a/src/app/document/models/DocumentModel.php b/src/app/document/models/DocumentModel.php
index 5f86591545..5020516cd3 100755
--- a/src/app/document/models/DocumentModel.php
+++ b/src/app/document/models/DocumentModel.php
@@ -75,6 +75,33 @@ class DocumentModel
         return $aDocuments;
     }
 
+    public static function create(array $aArgs)
+    {
+        ValidatorModel::notEmpty($aArgs, ['subject', 'status', 'processing_user', 'sender']);
+        ValidatorModel::stringType($aArgs, ['reference', 'subject', 'sender', 'sender_entity', 'recipient', 'priority']);
+        ValidatorModel::intVal($aArgs, ['status', 'processing_user']);
+
+        $nextSequenceId = DatabaseModel::getNextSequenceValue(['sequenceId' => 'main_documents_id_seq']);
+
+        DatabaseModel::insert([
+            'table'         => 'main_documents',
+            'columnsValues' => [
+                'id'                => $nextSequenceId,
+                'reference'         => empty($aArgs['reference']) ? null : $aArgs['reference'],
+                'subject'           => $aArgs['subject'],
+                'status'            => $aArgs['status'],
+                'processing_user'   => $aArgs['processing_user'],
+                'sender'            => $aArgs['sender'],
+                'sender_entity'     => empty($aArgs['sender_entity']) ? null : $aArgs['sender_entity'],
+                'recipient'         => empty($aArgs['recipient']) ? null : $aArgs['recipient'],
+                'priority'          => empty($aArgs['priority']) ? null : $aArgs['priority'],
+                'limit_date'        => empty($aArgs['limit_date']) ? null : $aArgs['limit_date']
+            ]
+        ]);
+
+        return $nextSequenceId;
+    }
+
     public static function update(array $aArgs)
     {
         ValidatorModel::notEmpty($aArgs, ['set', 'where', 'data']);
diff --git a/src/app/status/models/StatusModel.php b/src/app/status/models/StatusModel.php
index 9f5f15f95b..260b866d54 100755
--- a/src/app/status/models/StatusModel.php
+++ b/src/app/status/models/StatusModel.php
@@ -19,6 +19,21 @@ use SrcCore\models\ValidatorModel;
 
 class StatusModel
 {
+    public static function get(array $aArgs)
+    {
+        ValidatorModel::notEmpty($aArgs, ['select']);
+        ValidatorModel::arrayType($aArgs, ['select', 'where', 'data']);
+
+        $statuses = DatabaseModel::select([
+            'select'    => $aArgs['select'],
+            'table'     => ['status'],
+            'where'     => empty($aArgs['where']) ? [] : $aArgs['where'],
+            'data'      => empty($aArgs['data']) ? [] : $aArgs['data']
+        ]);
+
+        return $statuses;
+    }
+
     public static function getById(array $aArgs)
     {
         ValidatorModel::notEmpty($aArgs, ['id']);
-- 
GitLab