Newer
Older
<?php
/**
* Copyright Maarch since 2008 under licence GPLv3.
* See LICENCE.txt file at the root folder for more details.
* This file is part of Maarch software.
*
*/
/**
* @brief fastParapheur Controller
* @author nathan.cheval@edissyum.com
* @author dev@maarch.org
*/
namespace ExternalSignatoryBook\controllers;
use Attachment\models\AttachmentModel;
use Convert\controllers\ConvertPdfController;
use Convert\models\AdrModel;
use Docserver\models\DocserverModel;
use Docserver\models\DocserverTypeModel;

Florian Azizian
committed
use Entity\models\ListInstanceModel;
use Resource\controllers\StoreController;
use Resource\models\ResModel;
use SrcCore\models\CoreConfigModel;
use SrcCore\models\CurlModel;
use SrcCore\models\DatabaseModel;

Florian Azizian
committed
use User\models\UserModel;
class FastParapheurController
{
public static function retrieveSignedMails($aArgs)
{

Florian Azizian
committed
$version = $aArgs['version'];
foreach ($aArgs['idsToRetrieve'][$version] as $resId => $value) {
$xmlPostString = '<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sei="http://sei.ws.fast.cdc.com/">
<soapenv:Header/>
<soapenv:Body>
<sei:history>
<documentId>' . $value['external_id'] . '</documentId>
</sei:history>
</soapenv:Body>
</soapenv:Envelope>';

Florian Azizian
committed
$curlReturn = CurlModel::execSOAP([
'xmlPostString' => $xmlPostString,
'url' => $aArgs['config']['data']['url'],
'options' => [
CURLOPT_SSLCERT => $aArgs['config']['data']['certPath'],
CURLOPT_SSLCERTPASSWD => $aArgs['config']['data']['certPass'],
CURLOPT_SSLCERTTYPE => $aArgs['config']['data']['certType']
]
]);

Florian Azizian
committed
if ($curlReturn['infos']['http_code'] == 404) {
return ['error' => 'Erreur 404 : ' . $curlReturn['raw']];
}

Florian Azizian
committed
$isError = $curlReturn['response']->children('http://schemas.xmlsoap.org/soap/envelope/')->Body;
if (!empty($isError ->Fault[0]) && !empty($value['res_id_master'])) {
echo 'PJ n° ' . $resId . ' et document original n° ' . $value['res_id_master'] . ' : ' . (string)$curlReturn['response']->children('http://schemas.xmlsoap.org/soap/envelope/')->Body->Fault[0]->children()->faultstring . PHP_EOL;
continue;
} elseif (!empty($isError->Fault[0])) {
echo 'Document principal n° ' . $resId . ' : ' . (string)$curlReturn['response']->children('http://schemas.xmlsoap.org/soap/envelope/')->Body->Fault[0]->children()->faultstring . PHP_EOL;
continue;
}

Florian Azizian
committed
$response = $curlReturn['response']->children('http://schemas.xmlsoap.org/soap/envelope/')->Body->children('http://sei.ws.fast.cdc.com/')->historyResponse->children();
foreach ($response->return as $res) { // Loop on all steps of the documents (prepared, send to signature, signed etc...)
$state = (string) $res->stateName;
if ($state == $aArgs['config']['data']['validatedState']) {
$response = FastParapheurController::download(['config' => $aArgs['config'], 'documentId' => $value['external_id']]);
$aArgs['idsToRetrieve'][$version][$resId]['status'] = 'validated';
$aArgs['idsToRetrieve'][$version][$resId]['format'] = 'pdf';
$aArgs['idsToRetrieve'][$version][$resId]['encodedFile'] = $response['b64FileContent'];

Florian Azizian
committed
FastParapheurController::processVisaWorkflow(['res_id_master' => $value['res_id_master'], 'res_id' => $value['res_id'], 'processSignatory' => true]);

Florian Azizian
committed
break;
} elseif ($state == $aArgs['config']['data']['refusedState']) {
$res = DatabaseModel::select([
'select' => ['firstname', 'lastname'],
'table' => ['listinstance', 'users'],
'left_join' => ['listinstance.item_id = users.id'],
'where' => ['res_id = ?', 'item_mode = ?'],
'data' => [$aArgs['idsToRetrieve'][$version][$resId]['res_id_master'], 'sign']
])[0];
$response = FastParapheurController::getRefusalMessage(['config' => $aArgs['config'], 'documentId' => $value['external_id']]);
$aArgs['idsToRetrieve'][$version][$resId]['status'] = 'refused';
$aArgs['idsToRetrieve'][$version][$resId]['noteContent'] = $res['lastname'] . ' ' . $res['firstname'] . ' : ' . $response;
break;
} else {
$aArgs['idsToRetrieve'][$version][$resId]['status'] = 'waiting';
}
}
}
return $aArgs['idsToRetrieve'];
}
public static function processVisaWorkflow($aArgs = [])
{
$resIdMaster = $aArgs['res_id_master'] ?? $aArgs['res_id'];
$attachments = AttachmentModel::get(['select' => ['count(1)'], 'where' => ['res_id_master = ?', 'status = ?'], 'data' => [$resIdMaster, 'FRZ']]);

Florian Azizian
committed
if ((count($attachments) < 2 && $aArgs['processSignatory']) || !$aArgs['processSignatory']) {

Florian Azizian
committed
$visaWorkflow = ListInstanceModel::get([
'select' => ['listinstance_id', 'requested_signature'],
'where' => ['res_id = ?', 'difflist_type = ?', 'process_date IS NULL'],
'data' => [$resIdMaster, 'VISA_CIRCUIT'],
'orderBY' => ['ORDER BY listinstance_id ASC']
]);
if (!empty($visaWorkflow)) {
foreach ($visaWorkflow as $listInstance) {
if ($listInstance['requested_signature']) {

Florian Azizian
committed
// Stop to the first signatory user
if ($aArgs['processSignatory']) {
ListInstanceModel::update(['set' => ['signatory' => 'true', 'process_date' => 'CURRENT_TIMESTAMP'], 'where' => ['listinstance_id = ?'], 'data' => [$listInstance['listinstance_id']]]);
}

Florian Azizian
committed
ListInstanceModel::update(['set' => ['process_date' => 'CURRENT_TIMESTAMP'], 'where' => ['listinstance_id = ?'], 'data' => [$listInstance['listinstance_id']]]);
}
}
}
}
public static function upload($aArgs)
{
$circuitId = $aArgs['circuitId'];
$label = $aArgs['label'];
$subscriberId = $aArgs['businessId'];
// Retrieve the annexes of the attachemnt to sign (other attachment and the original document)
$annexes = [];
$annexes['letterbox'] = ResModel::get([
'select' => ['res_id', 'path', 'filename', 'docserver_id', 'format', 'category_id', 'external_id', 'integrations'],
'where' => ['res_id = ?'],
'data' => [$aArgs['resIdMaster']]
]);
if (!empty($annexes['letterbox'][0]['docserver_id'])) {
$adrMainInfo = ConvertPdfController::getConvertedPdfById(['resId' => $aArgs['resIdMaster'], 'collId' => 'letterbox_coll']);
$letterboxPath = DocserverModel::getByDocserverId(['docserverId' => $adrMainInfo['docserver_id'], 'select' => ['path_template']]);
$annexes['letterbox'][0]['filePath'] = $letterboxPath['path_template'] . str_replace('#', '/', $adrMainInfo['path']) . $adrMainInfo['filename'];
$attachments = AttachmentModel::get([
'select' => [
'res_id', 'docserver_id', 'path', 'filename', 'format', 'attachment_type', 'fingerprint'
],
'where' => ["res_id_master = ?", "attachment_type not in (?)", "status not in ('DEL', 'OBS', 'FRZ', 'TMP', 'SEND_MASS')", "in_signature_book = 'true'"],
'data' => [$aArgs['resIdMaster'], ['signed_response']]
]);
$attachmentTypes = AttachmentModel::getAttachmentsTypesByXML();
foreach ($attachments as $key => $value) {
if (!$attachmentTypes[$value['attachment_type']]['sign']) {
$annexeAttachmentPath = DocserverModel::getByDocserverId(['docserverId' => $value['docserver_id'], 'select' => ['path_template', 'docserver_type_id']]);
$value['filePath'] = $annexeAttachmentPath['path_template'] . str_replace('#', DIRECTORY_SEPARATOR, $value['path']) . $value['filename'];
$docserverType = DocserverTypeModel::getById(['id' => $annexeAttachmentPath['docserver_type_id'], 'select' => ['fingerprint_mode']]);
$fingerprint = StoreController::getFingerPrint(['filePath' => $value['filePath'], 'mode' => $docserverType['fingerprint_mode']]);
if ($value['fingerprint'] != $fingerprint) {
return ['error' => 'Fingerprints do not match'];
}
unset($attachments[$key]);
$annexes['attachments'][] = $value;
}
}
// END annexes
$attachmentToFreeze = [];
foreach ($attachments as $attachment) {
$resId = $attachment['res_id'];
$collId = 'attachments_coll';

Florian Azizian
committed
$response = FastParapheurController::uploadFile([
'resId' => $resId,
'collId' => $collId,
'resIdMaster' => $aArgs['resIdMaster'],
'annexes' => $annexes,
'circuitId' => $circuitId,
'label' => $label,
'subscriberId' => $subscriberId,
'config' => $aArgs['config']
]);

Florian Azizian
committed
if (!empty($response['error'])) {
return $response;

Florian Azizian
committed
$attachmentToFreeze[$collId][$resId] = $response['success'];
}
}
// Send main document if in signature book
if (!empty($annexes['letterbox'][0])) {
$mainDocumentIntegration = json_decode($annexes['letterbox'][0]['integrations'], true);
$externalId = json_decode($annexes['letterbox'][0]['external_id'], true);
if ($mainDocumentIntegration['inSignatureBook'] && empty($externalId['signatureBookId'])) {
$resId = $annexes['letterbox'][0]['res_id'];
$collId = 'letterbox_coll';
unset($annexes['letterbox']);

Florian Azizian
committed
$response = FastParapheurController::uploadFile([
'resId' => $resId,
'collId' => $collId,
'resIdMaster' => $aArgs['resIdMaster'],
'annexes' => $annexes,
'circuitId' => $circuitId,
'label' => $label,
'subscriberId' => $subscriberId,
'config' => $aArgs['config']
]);

Florian Azizian
committed
if (!empty($response['error'])) {
return $response;

Florian Azizian
committed
$attachmentToFreeze[$collId][$resId] = $response['success'];
}
}
return ['sended' => $attachmentToFreeze];
}
public static function uploadFile($aArgs)
{
$adrInfo = ConvertPdfController::getConvertedPdfById(['resId' => $aArgs['resId'], 'collId' => $aArgs['collId']]);
if (empty($adrInfo['docserver_id']) || strtolower(pathinfo($adrInfo['filename'], PATHINFO_EXTENSION)) != 'pdf') {
return ['error' => 'Document ' . $aArgs['resIdMaster'] . ' is not converted in pdf'];
}
$attachmentPath = DocserverModel::getByDocserverId(['docserverId' => $adrInfo['docserver_id'], 'select' => ['path_template']]);
$attachmentFilePath = $attachmentPath['path_template'] . str_replace('#', '/', $adrInfo['path']) . $adrInfo['filename'];
$attachmentFileName = 'projet_courrier_' . $aArgs['resIdMaster'] . '_' . rand(0001, 9999) . '.pdf';
$zip = new \ZipArchive();
$tmpPath = CoreConfigModel::getTmpPath();
$zipFilePath = $tmpPath . DIRECTORY_SEPARATOR
. $attachmentFileName . '.zip'; // The zip file need to have the same name as the attachment we want to sign
if ($zip->open($zipFilePath, \ZipArchive::CREATE)!==true) {
return ['error' => "Can not open file : <$zipFilePath>\n"];
}
$zip->addFile($attachmentFilePath, $attachmentFileName);
if (!empty($aArgs['annexes']['letterbox'])) {
$zip->addFile($aArgs['annexes']['letterbox'][0]['filePath'], 'document_principal.' . $aArgs['annexes']['letterbox'][0]['format']);
}
if (isset($aArgs['annexes']['attachments'])) {
for ($j = 0; $j < count($aArgs['annexes']['attachments']); $j++) {
$zip->addFile(
$aArgs['annexes']['attachments'][$j]['filePath'],
'PJ_' . ($j + 1) . '.' . $aArgs['annexes']['attachments'][$j]['format']
);
}
}
$zip->close();
$b64Attachment = base64_encode(file_get_contents($zipFilePath));
$fileName = $attachmentFileName . '.zip';
$circuitId = str_replace('.', '-', $aArgs['circuitId']);
$xmlPostString = '<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sei="http://sei.ws.fast.cdc.com/">
<soapenv:Header/>
<soapenv:Body>
<sei:upload>
<label>' . $aArgs['label'] . '</label>
<comment></comment>
<subscriberId>' . $aArgs['subscriberId'] . '</subscriberId>
<circuitId>' . $circuitId . '</circuitId>
<dataFileVO>
<dataHandler>' . $b64Attachment . '</dataHandler>
<filename>' . $fileName . '</filename>
</dataFileVO>
</sei:upload>
</soapenv:Body>
</soapenv:Envelope>';
$curlReturn = CurlModel::execSOAP([
'xmlPostString' => $xmlPostString,
'url' => $aArgs['config']['data']['url'],
'options' => [
CURLOPT_SSLCERT => $aArgs['config']['data']['certPath'],
CURLOPT_SSLCERTPASSWD => $aArgs['config']['data']['certPass'],
CURLOPT_SSLCERTTYPE => $aArgs['config']['data']['certType']
]
]);

Florian Azizian
committed
if ($curlReturn['infos']['http_code'] == 404) {
return ['error' => 'Erreur 404 : ' . $curlReturn['raw']];
} elseif (!empty($curlReturn['error'])) {
return ['error' => $curlReturn['error']];
} elseif (!empty($curlReturn['response']->children('http://schemas.xmlsoap.org/soap/envelope/')->Body->Fault[0])) {
$error = (string)$curlReturn['response']->children('http://schemas.xmlsoap.org/soap/envelope/')->Body->Fault[0]->children()->faultstring . PHP_EOL;
return ['error' => $error];
}

Florian Azizian
committed
FastParapheurController::processVisaWorkflow(['res_id_master' => $aArgs['resIdMaster'], 'processSignatory' => false]);

Florian Azizian
committed
$documentId = $curlReturn['response']->children('http://schemas.xmlsoap.org/soap/envelope/')->Body->children('http://sei.ws.fast.cdc.com/')->uploadResponse->children();
return ['success' => (string)$documentId];
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
}
public static function download($aArgs)
{
$xmlPostString = '<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sei="http://sei.ws.fast.cdc.com/">
<soapenv:Header/>
<soapenv:Body>
<sei:download>
<documentId>' . $aArgs['documentId'] . '</documentId>
</sei:download>
</soapenv:Body>
</soapenv:Envelope>';
$curlReturn = CurlModel::execSOAP([
'xmlPostString' => $xmlPostString,
'url' => $aArgs['config']['data']['url'],
'options' => [
CURLOPT_SSLCERT => $aArgs['config']['data']['certPath'],
CURLOPT_SSLCERTPASSWD => $aArgs['config']['data']['certPass'],
CURLOPT_SSLCERTTYPE => $aArgs['config']['data']['certType']
]
]);
$isError = $curlReturn['response']->children('http://schemas.xmlsoap.org/soap/envelope/')->Body;
if (!empty($isError ->Fault[0])) {
echo (string)$curlReturn['response']->children('http://schemas.xmlsoap.org/soap/envelope/')->Body->Fault[0]->children()->faultstring . PHP_EOL;
return false;
} else {
$response = $curlReturn['response']->children('http://schemas.xmlsoap.org/soap/envelope/')->Body->children('http://sei.ws.fast.cdc.com/')->downloadResponse->children()->return;
$returnedDocumentId = (string) $response->documentId;
if ($aArgs['documentId'] !== $returnedDocumentId) {
return false;
} else {
$b64FileContent = $response->content;
return ['b64FileContent' => (string)$b64FileContent, 'documentId' => $returnedDocumentId];
}
}
}
public static function sendDatas($aArgs)
{
$config = $aArgs['config'];
// We need the SIRET field and the user_id of the signatory user's primary entity
$signatory = DatabaseModel::select([
'select' => ['user_id', 'business_id', 'entities.entity_label'],
'table' => ['listinstance', 'users_entities', 'entities'],
'left_join' => ['item_id = user_id', 'users_entities.entity_id = entities.entity_id'],
'where' => ['res_id = ?', 'item_mode = ?'],
'data' => [$aArgs['resIdMaster'], 'sign']
])[0];
$redactor = DatabaseModel::select([
'select' => ['short_label'],
'table' => ['res_view_letterbox', 'users_entities', 'entities'],
'left_join' => ['dest_user = user_id', 'users_entities.entity_id = entities.entity_id'],
'where' => ['res_id = ?'],
'data' => [$aArgs['resIdMaster']]
])[0];
if (empty($signatory['business_id']) || substr($signatory['business_id'], 0, 3) == 'org') {
$signatory['business_id'] = $config['data']['subscriberId'];
}

Florian Azizian
committed
if (!empty($signatory['user_id'])) {
$user = UserModel::getById(['id' => $signatory['user_id'], 'select' => ['user_id']]);
}
return FastParapheurController::upload(['config' => $config, 'resIdMaster' => $aArgs['resIdMaster'], 'businessId' => $signatory['business_id'], 'circuitId' => $user['user_id'], 'label' => $redactor['short_label']]);
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
}
public static function getRefusalMessage($aArgs)
{
$xmlPostString = '<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sei="http://sei.ws.fast.cdc.com/">
<soapenv:Header/>
<soapenv:Body>
<sei:getRefusalMessage>
<nodeRefId>' . $aArgs['documentId'] . '</nodeRefId>
</sei:getRefusalMessage>
</soapenv:Body>
</soapenv:Envelope>';
$curlReturn = CurlModel::execSOAP([
'xmlPostString' => $xmlPostString,
'url' => $aArgs['config']['data']['url'],
'options' => [
CURLOPT_SSLCERT => $aArgs['config']['data']['certPath'],
CURLOPT_SSLCERTPASSWD => $aArgs['config']['data']['certPass'],
CURLOPT_SSLCERTTYPE => $aArgs['config']['data']['certType']
]
]);
$response = $curlReturn['response']->children('http://schemas.xmlsoap.org/soap/envelope/')->Body->children('http://sei.ws.fast.cdc.com/')->getRefusalMessageResponse->children()->return;
return $response;
}
}