Skip to content
Snippets Groups Projects
Commit 6a4578e1 authored by Stephane Bouvry's avatar Stephane Bouvry
Browse files

- Ajout du commentaire de refus dans l'objet Signature

 - Traitement des Post-its côté ESUP pour isoler les commentaires de refus et les ajouter dans les Signatures
parent 5a5702c0
No related branches found
No related tags found
No related merge requests found
Pipeline #31653 passed
# CHANGELOG
## 16 octobre 2024
### Général
- Ajout de tests unitaires (intégrés dans Gitlab au push)
- Traitement des commentaires dans `SignRequestInfo`
- Ajout des messages de refus : mise à jour du champ information - non testé* - sur `SignatureRecipient` et ajout d'un champ pour le message d'erreur dans `Signature::refused_text`
```sql
ALTER TABLE unicaen_signature_signature ADD refused_text TEXT DEFAULT NULL;
```
### ESUP
- **Prise en charge des commentaires/Post-its ESUP** Cependant, la version actuelle d'ESUP ne permet pas de déterminer l'auteur du Post-it, donc ils seront traité de façon global
- Les commentaires/Post-its sont ignorés pour le moment
\ No newline at end of file
...@@ -194,6 +194,7 @@ class ProcessStep ...@@ -194,6 +194,7 @@ class ProcessStep
'order' => $this->getOrder(), 'order' => $this->getOrder(),
'status' => $this->getStatus(), 'status' => $this->getStatus(),
'status_text' => $this->getStatusText(), 'status_text' => $this->getStatusText(),
'refused_text' => $this->getSignature()->getRefusedText(),
'allSignToComplete' => $this->getSignature()->getAllSignToComplete(), 'allSignToComplete' => $this->getSignature()->getAllSignToComplete(),
'dateSignatureUpdate' => $this->getSignature()->getDateUpdate(), 'dateSignatureUpdate' => $this->getSignature()->getDateUpdate(),
'recipients' => $recipients, 'recipients' => $recipients,
......
...@@ -186,6 +186,14 @@ class Signature ...@@ -186,6 +186,14 @@ class Signature
*/ */
private ?string $context_long; private ?string $context_long;
/**
* Message de refus
*
* @var ?string
* @ORM\Column (type="text", nullable=true)
*/
private ?string $refused_text;
/** /**
* Clef permettant d'identifier le parapheur * Clef permettant d'identifier le parapheur
* *
...@@ -326,6 +334,7 @@ class Signature ...@@ -326,6 +334,7 @@ class Signature
/** /**
* @param ProcessStep|null $processStep * @param ProcessStep|null $processStep
* @return Signature
*/ */
public function setProcessStep(?ProcessStep $processStep): self public function setProcessStep(?ProcessStep $processStep): self
{ {
...@@ -362,6 +371,7 @@ class Signature ...@@ -362,6 +371,7 @@ class Signature
/** /**
* @param DateTime|null $dateSend * @param DateTime|null $dateSend
* @return Signature
*/ */
public function setDateSend(?DateTime $dateSend): self public function setDateSend(?DateTime $dateSend): self
{ {
...@@ -459,6 +469,17 @@ class Signature ...@@ -459,6 +469,17 @@ class Signature
return $this; return $this;
} }
public function getRefusedText(): ?string
{
return $this->refused_text;
}
public function setRefusedText(?string $refused_text): self
{
$this->refused_text = $refused_text;
return $this;
}
/** /**
* @return SignatureRecipient[] * @return SignatureRecipient[]
*/ */
......
...@@ -544,6 +544,7 @@ class SignatureService ...@@ -544,6 +544,7 @@ class SignatureService
): bool { ): bool {
$this->getLoggerService()->debug("### UPDATE STATUS '$signature'"); $this->getLoggerService()->debug("### UPDATE STATUS '$signature'");
try { try {
if (!$signature->isFinished()) { if (!$signature->isFinished()) {
$documentSrc = $this->getSignatureConfigurationService()->getDocumentsLocation() $documentSrc = $this->getSignatureConfigurationService()->getDocumentsLocation()
. DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR
...@@ -555,7 +556,6 @@ class SignatureService ...@@ -555,7 +556,6 @@ class SignatureService
throw new SignatureException($err); throw new SignatureException($err);
} }
$letterFileStrategy = $this->getLetterfileService()->getLetterFileStrategy( $letterFileStrategy = $this->getLetterfileService()->getLetterFileStrategy(
$signature->getLetterfileKey() $signature->getLetterfileKey()
); );
...@@ -598,6 +598,7 @@ class SignatureService ...@@ -598,6 +598,7 @@ class SignatureService
if ($infos->isAccepted($recipient->getEmail()) && $updateRequired) { if ($infos->isAccepted($recipient->getEmail()) && $updateRequired) {
$this->getLoggerService()->debug("$recipient a signé"); $this->getLoggerService()->debug("$recipient a signé");
$recipient->setStatus(Signature::STATUS_SIGNATURE_SIGNED, true); $recipient->setStatus(Signature::STATUS_SIGNATURE_SIGNED, true);
$recipient->setInformations($infos->getCommentByFlat($recipient->getEmail()));
$recipient->setDateFinished($infos->getDateDone($recipient->getEmail())); $recipient->setDateFinished($infos->getDateDone($recipient->getEmail()));
$events[] = [ $events[] = [
'spot' => 'recipient', 'spot' => 'recipient',
...@@ -608,6 +609,10 @@ class SignatureService ...@@ -608,6 +609,10 @@ class SignatureService
} }
if ($infos->isRefused($recipient->getEmail()) && $updateRequired) { if ($infos->isRefused($recipient->getEmail()) && $updateRequired) {
$recipient->setStatus(Signature::STATUS_SIGNATURE_REJECT, true); $recipient->setStatus(Signature::STATUS_SIGNATURE_REJECT, true);
$recipient->setInformations($infos->getRefusedCommentsByFlat($recipient->getEmail()));
$refusedText = $infos->getRefusedCommentsByFlat();
$this->getLoggerService()->debug("COMMENTAIRE de REFUS : '$refusedText'");
$signature->setRefusedText($refusedText);
$this->getLoggerService()->debug("$recipient a REJETé"); $this->getLoggerService()->debug("$recipient a REJETé");
$events[] = [ $events[] = [
'spot' => 'recipient', 'spot' => 'recipient',
...@@ -624,6 +629,7 @@ class SignatureService ...@@ -624,6 +629,7 @@ class SignatureService
->setDateUpdate(new \DateTime()); ->setDateUpdate(new \DateTime());
} }
} }
$this->getObjectManager()->flush(); $this->getObjectManager()->flush();
if ($signature->getStatus() == Signature::STATUS_SIGNATURE_SIGNED) { if ($signature->getStatus() == Signature::STATUS_SIGNATURE_SIGNED) {
......
...@@ -9,6 +9,7 @@ use UnicaenSignature\Exception\SignatureDataMissingException; ...@@ -9,6 +9,7 @@ use UnicaenSignature\Exception\SignatureDataMissingException;
use UnicaenSignature\Service\LoggerServiceAwareTrait; use UnicaenSignature\Service\LoggerServiceAwareTrait;
use UnicaenSignature\Service\ServiceContainerAwareTrait; use UnicaenSignature\Service\ServiceContainerAwareTrait;
use UnicaenSignature\Service\SignatureConfigurationServiceAwareTrait; use UnicaenSignature\Service\SignatureConfigurationServiceAwareTrait;
use UnicaenSignature\Strategy\Letterfile\Esup\Response\SignRequestInfo;
use UnicaenSignature\Strategy\Letterfile\ILetterfileStrategy; use UnicaenSignature\Strategy\Letterfile\ILetterfileStrategy;
use UnicaenSignature\Strategy\Letterfile\ISignRequest; use UnicaenSignature\Strategy\Letterfile\ISignRequest;
use UnicaenSignature\Strategy\Letterfile\Tools\CurlAccess; use UnicaenSignature\Strategy\Letterfile\Tools\CurlAccess;
...@@ -350,68 +351,8 @@ class EsupLetterfileStrategy implements ILetterfileStrategy ...@@ -350,68 +351,8 @@ class EsupLetterfileStrategy implements ILetterfileStrategy
throw new Exception("La signature n'existe plus dans Esup"); throw new Exception("La signature n'existe plus dans Esup");
} }
$responseInfos = new ResponseInfos(); return SignRequestInfo::getFromSignRequestGetId($returned);
// On regarde si une personne a refusée
if (array_key_exists('recipientHasSigned', $returned)) {
foreach ($returned['recipientHasSigned'] as $item) {
if (array_key_exists('actionType', $item) && $item['actionType'] == 'refused') {
$responseInfos->setForceRefuse(true);
}
}
}
// La clef auditTrail permet d'obtenir les personnes qui ont signées
if ($returned['auditTrail'] != null && array_key_exists('auditSteps', $returned['auditTrail'])) {
foreach ($returned['auditTrail']['auditSteps'] as $auditStep) {
$email = $auditStep['email'];
$date = $auditStep['timeStampDate'];
$dateAccepted = new \DateTime($date);
$responseInfos->addAccepted($email, $dateAccepted);
}
}
// Récupération des emails qui ont réagit
if (array_key_exists('parentSignBook', $returned)
&& array_key_exists('liveWorkflow', $returned['parentSignBook'])
&& array_key_exists('currentStep', $returned['parentSignBook']['liveWorkflow'])
&& array_key_exists('recipients', $returned['parentSignBook']['liveWorkflow']['currentStep'])
) {
$allSignToComplete = $returned['parentSignBook']['liveWorkflow']['currentStep']['allSignToComplete'];
$responseInfos->setAllSignToComplete($allSignToComplete);
foreach ($returned['parentSignBook']['liveWorkflow']['currentStep']['recipients'] as $recipient) {
$signed = $recipient['signed'];
$email = $recipient['user']['email'];
$recipients[] = $email;
$responseInfos->addRecipient($email);
if ($signed) {
if (!$responseInfos->isAccepted($email)) {
$responseInfos->addRefused($email);
}
}
else {
$responseInfos->addNone($email);
}
}
}
// Commentaires
foreach ($returned['comments'] as $com) {
var_dump($com);
$responseInfos->addComment("unknow", $email);
}
// Status
$status_remote = $returned['status'];
$responseInfos->setStatusRemote($status_remote);
// Suppression dans le parapheur
if ($status_remote == 'deleted') {
$responseInfos->setStatus(Signature::STATUS_SIGNATURE_DELETE);
}
return $responseInfos;
} catch (Exception $e) { } catch (Exception $e) {
$msg = "Impossible de charger les informations de la SignRequest '$id' dans ESUP"; $msg = "Impossible de charger les informations de la SignRequest '$id' dans ESUP";
$this->getLoggerService()->critical( $this->getLoggerService()->critical(
......
...@@ -11,9 +11,6 @@ use UnicaenSignature\Strategy\Letterfile\Tools\ResponseInfos; ...@@ -11,9 +11,6 @@ use UnicaenSignature\Strategy\Letterfile\Tools\ResponseInfos;
*/ */
class SignRequestInfo class SignRequestInfo
{ {
/**
* @throws \DateMalformedStringException
*/
public static function getFromSignRequestGetId($returned) :ResponseInfos public static function getFromSignRequestGetId($returned) :ResponseInfos
{ {
$responseInfos = new ResponseInfos(); $responseInfos = new ResponseInfos();
...@@ -33,7 +30,7 @@ class SignRequestInfo ...@@ -33,7 +30,7 @@ class SignRequestInfo
$email = $auditStep['email']; $email = $auditStep['email'];
$date = $auditStep['timeStampDate']; $date = $auditStep['timeStampDate'];
$dateAccepted = new \DateTime($date); $dateAccepted = new \DateTime($date);
$responseInfos->addAccepted($email, $dateAccepted); $responseInfos->addAccepted($email, null, $dateAccepted);
} }
} }
...@@ -49,11 +46,11 @@ class SignRequestInfo ...@@ -49,11 +46,11 @@ class SignRequestInfo
foreach ($returned['parentSignBook']['liveWorkflow']['currentStep']['recipients'] as $recipient) { foreach ($returned['parentSignBook']['liveWorkflow']['currentStep']['recipients'] as $recipient) {
$signed = $recipient['signed']; $signed = $recipient['signed'];
$email = $recipient['user']['email']; $email = $recipient['user']['email'];
$recipients[] = $email; $comment = null;
$responseInfos->addRecipient($email); $responseInfos->addRecipient($email);
if ($signed) { if ($signed) {
if (!$responseInfos->isAccepted($email)) { if (!$responseInfos->isAccepted($email)) {
$responseInfos->addRefused($email); $responseInfos->addRefused($email, $comment);
} }
} }
else { else {
...@@ -76,10 +73,14 @@ class SignRequestInfo ...@@ -76,10 +73,14 @@ class SignRequestInfo
$text = $com['text']; $text = $com['text'];
// Dans ESUP, pas d'infos sur l'auteur du commentaire/postit // Dans ESUP, pas d'infos sur l'auteur du commentaire/postit
$author = 'unknown'; $author = ResponseInfos::COMMENT_NO_AUTHOR;
$isRefused = $com['postitColor'] == '#FF7EB9';
if( $isRefused ){
$responseInfos->addCommentRefused($author, $text, $dateCreated);
} else {
$responseInfos->addComment($author, $text, $dateCreated); $responseInfos->addComment($author, $text, $dateCreated);
} }
}
// Status // Status
$status_remote = $returned['status']; $status_remote = $returned['status'];
......
...@@ -9,6 +9,8 @@ use UnicaenSignature\Entity\Db\Signature; ...@@ -9,6 +9,8 @@ use UnicaenSignature\Entity\Db\Signature;
*/ */
class ResponseInfos class ResponseInfos
{ {
// Clef utilisée pour ranger les commentaires sans auteurs
const COMMENT_NO_AUTHOR = 'unknow';
private string $status_remote; private string $status_remote;
private ?int $status = null; private ?int $status = null;
...@@ -67,6 +69,12 @@ class ResponseInfos ...@@ -67,6 +69,12 @@ class ResponseInfos
*/ */
private array $comments; private array $comments;
/**
* Messages de refus
* @var array
*/
private array $refusedComments;
public function __construct() public function __construct()
{ {
$this->allSignToComplete = true; $this->allSignToComplete = true;
...@@ -77,6 +85,7 @@ class ResponseInfos ...@@ -77,6 +85,7 @@ class ResponseInfos
$this->recipients_refused = array(); $this->recipients_refused = array();
$this->recipients_none = array(); $this->recipients_none = array();
$this->comments = array(); $this->comments = array();
$this->refusedComments = array();
} }
/** /**
...@@ -208,20 +217,27 @@ class ResponseInfos ...@@ -208,20 +217,27 @@ class ResponseInfos
} }
} }
public function addAccepted(string $email, \DateTime $date = new \DateTime()): void public function addAccepted(string $email, ?string $comment = null, \DateTime $date = new \DateTime()): void
{ {
$this->addRecipient($email); $this->addRecipient($email);
if (!in_array($email, $this->recipients_accepted)) { if (!in_array($email, $this->recipients_accepted)) {
$this->recipients_accepted[] = $email; $this->recipients_accepted[] = $email;
$this->recipients_response_dates[$email] = $date; $this->recipients_response_dates[$email] = $date;
if ($comment) {
$this->addComment($email, $comment, $date);
}
} }
} }
public function addRefused(string $email): void public function addRefused(string $email, ?string $comment = null, \DateTime $date = new \DateTime()): void
{ {
$this->addRecipient($email); $this->addRecipient($email);
if (!in_array($email, $this->recipients_refused)) { if (!in_array($email, $this->recipients_refused)) {
$this->recipients_refused[] = $email; $this->recipients_refused[] = $email;
$this->recipients_response_dates[$email] = $date;
if ($comment !== null) {
$this->addCommentRefused($email, $comment);
}
} }
} }
...@@ -233,38 +249,127 @@ class ResponseInfos ...@@ -233,38 +249,127 @@ class ResponseInfos
} }
} }
public function addComment(string $email, string $comment, ?\DateTime $date = null): void public function addComment(?string $email, string $comment, ?\DateTime $date = null): void
{ {
if ($date === null) { $this->comment($email, $date, $comment, $this->comments);
$date = new \DateTime();
} }
public function addCommentRefused(?string $email, string $comment, ?\DateTime $date = null): void
{
$this->comment($email, $date, $comment, $this->refusedComments);
}
/**
* @param string|null $email
* @param \DateTime|null $date
* @param string $comment
* @param array $comments
* @return void
*/
private function comment(?string $email, ?\DateTime $date, string $comment, array &$comments): void
{
$key = $email !== null ? $email : self::COMMENT_NO_AUTHOR;
$date = $date !== null ? $date : new \DateTime();
$dateStr = $date->format('Y-m-d H:i:s'); $dateStr = $date->format('Y-m-d H:i:s');
if (!array_key_exists($email, $this->comments)) { if (!array_key_exists($key, $comments)) {
$this->comments[$email] = []; $comments[$key] = [];
}
$comments[$key][] = [
'date' => $dateStr,
'text' => $comment
];
}
/**
* Applati un tableau de commentaire pour retourner une chaine
*
* @param array $comments
* @return string|null
*/
private function flatComments(array $comments): ?string
{
if (count($comments) === 0) {
return null;
}
else {
$separator = ' / ';
$out = [];
foreach ($comments as $comment) {
$out[] = $comment['text'];
}
return implode($separator, $out);
}
}
/**
* @param string $email
* @return array|null
*/
public function getCommentsBy(string $email = self::COMMENT_NO_AUTHOR): ?array
{
return array_key_exists($email, $this->comments) ? $this->comments[$email] : null;
} }
$this->comments[$email][$dateStr] = $comment;
public function getCommentsByFlat(string $email = self::COMMENT_NO_AUTHOR): ?string
{
$comments = $this->getCommentsBy($email);
if ($comments !== null) {
return $this->flatComments($comments);
}
return null;
} }
public function getComment(string $email): ?string public function getRefusedComments(): array
{ {
if (array_key_exists($email, $this->comments)) { return $this->refusedComments;
return implode(' / ', $this->comments[$email]); }
/**
* Retourne la liste des commentaires de refus de la personne.
*
* @param string $mailAuthor
* @return array|null
*/
public function getRefusedCommentsBy(string $mailAuthor = self::COMMENT_NO_AUTHOR): ?array
{
if (array_key_exists($mailAuthor, $this->refusedComments)) {
return $this->refusedComments[$mailAuthor];
}
else {
return null;
}
}
/**
* Retourne la liste des commentaires de la personne sous la forme d'une chaine.
*
* @param string $mailAuthor
* @return string|null
*/
public function getRefusedCommentsByFlat(string $mailAuthor = self::COMMENT_NO_AUTHOR): ?string
{
$comments = $this->getRefusedCommentsBy($mailAuthor);
if ($comments !== null) {
return $this->flatComments($comments);
} }
return null; return null;
} }
public function getAllComments(): array public function getRefusedCommentsFlat(): ?string
{ {
$out = []; $out = [];
foreach ($this->comments as $comments) { foreach ($this->getRefusedComments() as $comments) {
foreach ($comments as $comment) { foreach ($comments as $comment) {
$out[] = $comment; $out[] = $comment;
} }
} }
return $out; return $this->flatComments($out);
} }
public function isAccepted(string $email): bool public function isAccepted(string $email): bool
{ {
return in_array($email, $this->recipients_accepted); return in_array($email, $this->recipients_accepted);
...@@ -336,12 +441,13 @@ class ResponseInfos ...@@ -336,12 +441,13 @@ class ResponseInfos
"refused" => $this->recipients_refused, "refused" => $this->recipients_refused,
"none" => $this->recipients_none, "none" => $this->recipients_none,
"recipients" => $this->recipients, "recipients" => $this->recipients,
"comments" => $this->comments "comments" => $this->comments,
"comments_refused" => $this->refusedComments,
]; ];
return $out; return $out;
} }
public function isWaiting() public function isWaiting(): bool
{ {
return $this->getStatus() == Signature::STATUS_SIGNATURE_WAIT; return $this->getStatus() == Signature::STATUS_SIGNATURE_WAIT;
} }
......
{
"level": "validation",
"recipients": [
{
"firstname": "Jean-Pierre",
"lastname": "Afeuh",
"email": "jeanpierre.afeuh@test-signature.org"
}
]
}
\ No newline at end of file
...@@ -3,6 +3,35 @@ namespace ESUP; ...@@ -3,6 +3,35 @@ namespace ESUP;
class SignRequestsGetTest extends \PHPUnit\Framework\TestCase class SignRequestsGetTest extends \PHPUnit\Framework\TestCase
{ {
public function testSignRequestsGetPostIts()
{
$datas = $this->getJsonData('esup-retour-refused-post-it-comments.json');
$this->assertTrue($datas !== null);
$esupSignRequest = \UnicaenSignature\Strategy\Letterfile\Esup\Response\SignRequestInfo::getFromSignRequestGetId($datas);
$this->assertTrue(
$esupSignRequest->getStatus() === \UnicaenSignature\Entity\Db\Signature::STATUS_SIGNATURE_REJECT
);
$this->assertTrue(
$esupSignRequest->isAccepted('karin.fery@unicaen.fr')
);
$this->assertTrue(
$esupSignRequest->isAccepted('jean-baptiste.oellers@unicaen.fr')
);
$this->assertEquals(
"Commentaire de REFUS à récupérer",
$esupSignRequest->getRefusedCommentsByFlat()
);
$this->assertEquals(
(new \DateTime('2024-10-15 10:05:34'))->format('Y-m-d H:i:s'),
$esupSignRequest->getDateDone(null, false)->format('Y-m-d H:i:s')
);
}
public function testSignRequestsGetWaiting1of3() public function testSignRequestsGetWaiting1of3()
{ {
$datas = $this->getJsonData('esup-retour-waiting-signed-2-of-3.json'); $datas = $this->getJsonData('esup-retour-waiting-signed-2-of-3.json');
...@@ -52,9 +81,8 @@ class SignRequestsGetTest extends \PHPUnit\Framework\TestCase ...@@ -52,9 +81,8 @@ class SignRequestsGetTest extends \PHPUnit\Framework\TestCase
$esupSignRequest->getDateDone(null, false)->format('Y-m-d H:i:s') $esupSignRequest->getDateDone(null, false)->format('Y-m-d H:i:s')
); );
$comments = $esupSignRequest->getAllComments();
$this->assertEquals( $this->assertEquals(
$esupSignRequest->getAllComments()[0], "Commentaire de refus à récupérer" $esupSignRequest->getRefusedCommentsByFlat(), "Commentaire de refus à récupérer"
); );
} }
...@@ -74,7 +102,7 @@ class SignRequestsGetTest extends \PHPUnit\Framework\TestCase ...@@ -74,7 +102,7 @@ class SignRequestsGetTest extends \PHPUnit\Framework\TestCase
); );
$this->assertEquals( $this->assertEquals(
$esupSignRequest->getAllComments()[0], "Il y'a un problème dans ce document" $esupSignRequest->getRefusedCommentsByFlat(), "Il y'a un problème dans ce document"
); );
$this->assertEquals( $this->assertEquals(
...@@ -87,7 +115,7 @@ class SignRequestsGetTest extends \PHPUnit\Framework\TestCase ...@@ -87,7 +115,7 @@ class SignRequestsGetTest extends \PHPUnit\Framework\TestCase
{ {
$file_path = __DIR__.'/../datas/' . $filename; $file_path = __DIR__.'/../datas/' . $filename;
if( !file_exists($file_path) ){ if( !file_exists($file_path) ){
throw new Exception($file_path.' n\'existe pas'); throw new \Exception($file_path.' n\'existe pas');
} }
$content = file_get_contents($file_path); $content = file_get_contents($file_path);
return json_decode($content, true); return json_decode($content, true);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment