Skip to content
Snippets Groups Projects
YousignController.php 14.9 KiB
Newer Older
  • Learn to ignore specific revisions
  • <?php
    
    /**
    * Copyright Maarch since 2008 under license.
    * See LICENSE.txt file at the root folder for more details.
    * This file is part of Maarch software.
    *
    */
    
    /**
    * @brief Yousign Controller
    * @author dev@maarch.org
    */
    
    namespace Workflow\controllers;
    
    
    use Attachment\controllers\AttachmentController;
    use Attachment\models\AttachmentModel;
    
    use Docserver\controllers\DocserverController;
    use Docserver\models\AdrModel;
    use Document\controllers\DocumentController;
    
    use ExternalSignatoryBook\models\ExternalSignatoryBookModel;
    
    use Slim\Http\Request;
    use Slim\Http\Response;
    
    use SrcCore\controllers\UrlController;
    
    use SrcCore\models\CoreConfigModel;
    
    use SrcCore\models\CurlModel;
    
    use SrcCore\models\ValidatorModel;
    
    use Workflow\models\WorkflowExternalInformationModel;
    use Workflow\models\WorkflowModel;
    
    
    class YousignController
    {
        public static function createProcedure(array $args)
        {
    
            $workflowExternalInformations = WorkflowExternalInformationModel::getByWorkflowId(['select' => ['*'], 'workflowId' => $args['workflowId']]);
            if (empty($workflowExternalInformations)) {
                return ['errors' => 'No external informations found'];
            }
    
            $externalSB = ExternalSignatoryBookModel::getById(['select' => ['*'], 'id' => $workflowExternalInformations['external_signatory_book_id']]);
            if (empty($externalSB)) {
                return ['errors' => 'No external signatory book configuration found'];
            } elseif ($externalSB['type'] != 'yousign') {
                return ['errors' => 'External signatory book configuration is invalid'];
            }
            $externalSB['connection_data'] = json_decode($externalSB['connection_data'], true);
    
    
            $workflowExternalInformations['informations'] = json_decode($workflowExternalInformations['informations'], true);
    
    
            $fileResponse = CurlModel::exec([
    
                'url'           => "{$externalSB['connection_data']['apiUri']}/files",
                'bearerAuth'    => ['token' => $externalSB['connection_data']['apiKey']],
    
                'method'        => 'POST',
                'headers'       => ['content-type:application/json'],
                'body'          => json_encode([
                    'name'          => "{$args['name']}.pdf",
                    'content'       => $args['encodedDocument']
                ])
            ]);
            if ($fileResponse['code'] != 201) {
    
                return ['errors' => json_encode($fileResponse['response'])];
    
            }
    
            $fileId = $fileResponse['response']['id'];
    
            $trunkedFileId = str_replace('/files/', '', $fileId);
    
    
            $procedureResponse = CurlModel::exec([
    
                'url'           => "{$externalSB['connection_data']['apiUri']}/procedures",
                'bearerAuth'    => ['token' => $externalSB['connection_data']['apiKey']],
    
                'method'        => 'POST',
                'headers'       => ['content-type:application/json'],
                'body'          => json_encode([
                    'name'          => $args['name'],
                    'description'   => $args['description'],
                    'members'       => [
                        [
    
                            'firstname'             => $workflowExternalInformations['firstname'],
                            'lastname'              => $workflowExternalInformations['lastname'],
                            'email'                 => $workflowExternalInformations['email'],
                            'phone'                 => $workflowExternalInformations['phone'],
                            'operationLevel'        => 'custom',
                            'operationCustomModes'  => [$workflowExternalInformations['informations']['security']],
    
                            'type'                  => $workflowExternalInformations['role'] == 'visa' ? 'validator' : 'signer',
    
                            'fileObjects'   => [
                                [
                                    'file'      => $fileId,
                                    'page'      => 1,
                                    'position'  => $args['position']
                                ]
                            ]
                        ]
                    ],
                    'config'    => [
                        'email'     => [
                            'member.started' => [
                                [
                                    "subject"   => "Hey! You are invited to sign!",
                                    "message"   => "Hello <tag data-tag-type=\"string\" data-tag-name=\"recipient.firstname\"></tag> <tag data-tag-type=\"string\" data-tag-name=\"recipient.lastname\"></tag>, <br><br> You have ben invited to sign a document, please click on the following button to read it: <tag data-tag-type=\"button\" data-tag-name=\"url\" data-tag-title=\"Access to documents\">Access to documents</tag>",
                                    "to"        => ["@member"]
                                ]
                            ]
    
                       'webhook'   => [
                           'procedure.finished' => [
                               [
                                   'url'       => UrlController::getCoreUrl() . "rest/documents/{$args['documentId']}/workflows/{$args['workflowId']}/files/{$trunkedFileId}",
                                   'method'    => 'GET',
                               ]
                           ],
                           'procedure.refused' => [
                               [
                                   'url'       => UrlController::getCoreUrl() . "rest/documents/{$args['documentId']}/workflows/{$args['workflowId']}/files/{$trunkedFileId}",
                                   'method'    => 'GET',
                               ]
                           ]
                       ]
    
                    ]
                ])
            ]);
            if ($procedureResponse['code'] != 201) {
    
                return ['errors' => json_encode($procedureResponse['response'])];
            }
    
            $attachments = AttachmentModel::getByDocumentId(['select' => ['id', 'title'], 'documentId' => $args['documentId']]);
            foreach ($attachments as $attachment) {
                $content = AttachmentController::getContentPath(['id' => $attachment['id']]);
                $content = file_get_contents($content['path']);
    
                $fileResponse = CurlModel::exec([
    
                    'url'           => "{$externalSB['connection_data']['apiUri']}/files",
                    'bearerAuth'    => ['token' => $externalSB['connection_data']['apiKey']],
    
                    'method'        => 'POST',
                    'headers'       => ['content-type:application/json'],
                    'body'          => json_encode([
                        'name'          => "{$attachment['title']}.pdf",
                        'content'       => base64_encode($content),
                        'procedure'     => $procedureResponse['response']['id'],
                        'type'          => 'attachment'
                    ])
                ]);
                if ($fileResponse['code'] != 201) {
                    return ['errors' => json_encode($fileResponse['response'])];
                }
    
    
            $workflowExternalInformations['informations']['yousignFileId'] = $fileId;
    
            $workflowExternalInformations['informations']['yousignProcedureId'] = $procedureResponse['response']['id'];
    
            $informations = json_encode($workflowExternalInformations['informations']);
    
            WorkflowExternalInformationModel::update(['set' => ['informations' => $informations], 'where' => ['workflow_id = ?'], 'data' => [$args['workflowId']]]);
    
            return true;
        }
    
        public function getByFileId(Request $request, Response $response, array $args)
        {
            $workflow = WorkflowModel::get([
                'select' => [1],
                'where'  => ['main_document_id = ?', 'id = ?', 'status is null'],
                'data'   => [$args['id'], $args['workflowId']]
            ]);
            if (empty($workflow[0])) {
                return $response->withStatus(403)->withJson(['errors' => 'Workflow does not exist']);
            }
    
    
            $workflowExternalInformations = WorkflowExternalInformationModel::getByWorkflowId(['select' => ['informations', 'external_signatory_book_id'], 'workflowId' => $args['workflowId']]);
            if (empty($workflowExternalInformations)) {
    
                return $response->withStatus(403)->withJson(['errors' => 'Workflow does not exist']);
            }
    
    
            $informations = json_decode($workflowExternalInformations['informations'], true);
    
            if ($informations['yousignFileId'] != "/files/{$args['fileId']}") {
                return $response->withStatus(403)->withJson(['errors' => 'Unauthorized fileId']);
            }
    
    
            $externalSB = ExternalSignatoryBookModel::getById(['select' => ['*'], 'id' => $workflowExternalInformations['external_signatory_book_id']]);
            if (empty($externalSB)) {
                return $response->withStatus(400)->withJson(['errors' => 'No external signatory book configuration found']);
            } elseif ($externalSB['type'] != 'yousign') {
                return $response->withStatus(400)->withJson(['errors' => 'External signatory book configuration is invalid']);
            }
            $externalSB['connection_data'] = json_decode($externalSB['connection_data'], true);
    
    
            $trunkedProcedureId = str_replace('/procedures/', '', $informations['yousignProcedureId']);
    
            $procedureResponse = CurlModel::exec([
    
                'url'           => "{$externalSB['connection_data']['apiUri']}/procedures/{$trunkedProcedureId}",
                'bearerAuth'    => ['token' => $externalSB['connection_data']['apiKey']],
    
                'method'        => 'GET',
                'headers'       => ['content-type:application/json']
            ]);
    
            if ($procedureResponse['code'] != 200) {
                return ['errors' => json_encode($procedureResponse['response'])];
    
            if (!in_array($procedureResponse['response']['status'], ['finished', 'refused'])) {
                return $response->withStatus(403)->withJson(['errors' => 'Procedure is not finished']);
    
            if ($procedureResponse['response']['status'] == 'finished') {
                $fileResponse = CurlModel::exec([
    
                    'url'           => "{$externalSB['connection_data']['apiUri']}/files/{$args['fileId']}/download",
                    'bearerAuth'    => ['token' => $externalSB['connection_data']['apiKey']],
    
                    'method'        => 'GET',
                    'headers'       => ['content-type:application/json']
                ]);
                if ($fileResponse['code'] != 200) {
    
                    return $response->withStatus(400)->withJson(['errors' => json_encode($fileResponse['response'])]);
    
                }
    
                $storeInfos = DocserverController::storeResourceOnDocServer([
                    'encodedFile'     => $fileResponse['response'],
                    'format'          => 'pdf',
                    'docserverType'   => 'DOC'
                ]);
                if (!empty($storeInfos['errors'])) {
                    return $response->withStatus(500)->withJson(['errors' => $storeInfos['errors']]);
                }
    
                AdrModel::deleteDocumentAdr([
                    'where' => ['main_document_id = ?', 'type = ?'],
                    'data'  => [$args['id'], 'DOC']
                ]);
                AdrModel::createDocumentAdr([
                    'documentId'    => $args['id'],
                    'type'          => 'DOC',
                    'path'          => $storeInfos['path'],
                    'filename'      => $storeInfos['filename'],
                    'fingerprint'   => $storeInfos['fingerprint']
                ]);
    
                $storeInfos = DocserverController::storeResourceOnDocServer([
                    'encodedFile'     => $fileResponse['response'],
                    'format'          => 'pdf',
                    'docserverType'   => 'ESIGN'
                ]);
                if (!empty($storeInfos['errors'])) {
                    return $response->withStatus(500)->withJson(['errors' => $storeInfos['errors']]);
                }
    
                AdrModel::deleteDocumentAdr([
                    'where' => ['main_document_id = ?', 'type = ?'],
                    'data'  => [$args['id'], 'ESIGN']
                ]);
                AdrModel::createDocumentAdr([
                    'documentId'    => $args['id'],
                    'type'          => 'ESIGN',
                    'path'          => $storeInfos['path'],
                    'filename'      => $storeInfos['filename'],
                    'fingerprint'   => $storeInfos['fingerprint']
                ]);
    
    
                AdrModel::deleteDocumentAdr([
                    'where' => ['main_document_id = ?', 'type like ?'],
                    'data'  => [$args['id'], 'TNL%']
                ]);
                $configPath = CoreConfigModel::getConfigPath();
                exec("php src/app/convert/scripts/ThumbnailScript.php '{$configPath}' {$args['id']} 'document' 0 > /dev/null &");
    
            $GLOBALS['webhook'] = 'yousign webhook';
            $GLOBALS['id'] = 0;
    
            DocumentController::endAction([
                'id'            => $args['id'],
    
                'workflowId'    => $args['workflowId'],
    
                'status'        => $procedureResponse['response']['status'] == 'finished' ? 'VAL' : 'REF',
                'note'          => $procedureResponse['response']['members'][0]['comment'] ?? null
    
        public static function deleteProcedureByWorkflowId(array $args)
        {
            $workflowExternalInformations = WorkflowExternalInformationModel::getByWorkflowId(['select' => ['informations', 'external_signatory_book_id'], 'workflowId' => $args['workflowId']]);
            if (empty($workflowExternalInformations)) {
                return ['errors' => 'Workflow does not exist'];
            }
    
            $informations = json_decode($workflowExternalInformations['informations'], true);
    
            $externalSB = ExternalSignatoryBookModel::getById(['select' => ['*'], 'id' => $workflowExternalInformations['external_signatory_book_id']]);
            if (empty($externalSB)) {
                return ['errors' => 'No external signatory book configuration found'];
            } elseif ($externalSB['type'] != 'yousign') {
                return ['errors' => 'External signatory book configuration is invalid'];
            }
            $externalSB['connection_data'] = json_decode($externalSB['connection_data'], true);
    
            $trunkedProcedureId = str_replace('/procedures/', '', $informations['yousignProcedureId']);
    
            $procedureResponse = CurlModel::exec([
                'url'           => "{$externalSB['connection_data']['apiUri']}/procedures/{$trunkedProcedureId}",
                'bearerAuth'    => ['token' => $externalSB['connection_data']['apiKey']],
                'method'        => 'DELETE'
            ]);
            if ($procedureResponse['code'] != 204) {
                return ['errors' => json_encode($procedureResponse['response'])];
            }
    
            return true;
        }
    
    
        public static function formatExternalInformations(array $args)
        {
            ValidatorModel::stringType($args, ['security']);
    
            $informations = [
                'type'      => 'yousign',
    
            ];
    
            if (!empty($args['security']) && $args['security'] == 'email') {
                $informations['security'] = 'email';
            }
    
            if (!empty($args['role']) && $args['role'] == 'visa') {
                $informations['role'] = 'visa';
            }