From 574c2c05e388baf050e90340f4fcf7981b6505f9 Mon Sep 17 00:00:00 2001
From: lvessiller <lvessiller@open-dsi.fr>
Date: Wed, 11 Aug 2021 12:12:16 +0200
Subject: [PATCH] NEW remplacement utilisation Filesystem pour les taches
 planifiess

---
 lib/BackgroundJob/ArchiveProcess.php    |  70 +++++------
 lib/BackgroundJob/IndexationProcess.php |   2 +-
 lib/Controller/PageController.php       | 147 ------------------------
 lib/Db/DematpayslipArchive.php          | 109 +++++++++---------
 lib/Db/DematpayslipProcess.php          |  70 ++++-------
 5 files changed, 115 insertions(+), 283 deletions(-)

diff --git a/lib/BackgroundJob/ArchiveProcess.php b/lib/BackgroundJob/ArchiveProcess.php
index 59bd7d4..195156f 100644
--- a/lib/BackgroundJob/ArchiveProcess.php
+++ b/lib/BackgroundJob/ArchiveProcess.php
@@ -3,15 +3,15 @@
 namespace OCA\Dematpayslip\BackgroundJob;
 
 use OC\BackgroundJob\TimedJob;
-use OCP\AppFramework\Utility\ITimeFactory;
-use OCP\Files\IRootFolder;
-use OCP\Activity\IManager;
 use OCP\IConfig;
 use OCP\IDBConnection;
 use OCP\IL10N;
+use OCP\Activity\IManager;
 use OCP\Notification\IManager as INotificationManager;
-use OC\URLGenerator;
+use OCP\Files\IRootFolder;
+use OCP\AppFramework\Utility\ITimeFactory;
 use OCP\IUserManager;
+
 use DateTime;
 use DateTimeZone;
 use Exception;
@@ -165,7 +165,7 @@ class ArchiveProcess extends TimedJob {
      *
      * @param   IConfig                     $config                     Config
      * @param   IDBConnection               $dbConnection               DB connection
-     * @param   IL10N                       $l10                        Lang
+     * @param   IL10N                       $l10n                       Lang
      * @param   IManager                    $activityManager            Activity manager
      * @param   INotificationManager        $notificationManager        Notification manager
      * @param   IRootFolder                 $rootFolder                 Root folder
@@ -174,7 +174,7 @@ class ArchiveProcess extends TimedJob {
      * @param   DematpayslipArchiveMapper   $dematpayslipArchiveMapper  Archive mapper
      * @param   DematpayslipUserMapper      $dematpayslipUserMapper     User mapper
      */
-    public function __construct(IConfig $config, IDBConnection $dbConnection, IL10N $l10n, IManager $activityManager, INotificationManager $notificationManager, IRootFolder $rootFolder, ITimeFactory $timeFactory, URLGenerator $urlGenerator, IUserManager $userManager, DematpayslipArchiveMapper $dematpayslipArchiveMapper, DematpayslipUserMapper $dematpayslipUserMapper) {
+    public function __construct(IConfig $config, IDBConnection $dbConnection, IL10N $l10n, IManager $activityManager, INotificationManager $notificationManager, IRootFolder $rootFolder, ITimeFactory $timeFactory, IUserManager $userManager, DematpayslipArchiveMapper $dematpayslipArchiveMapper, DematpayslipUserMapper $dematpayslipUserMapper) {
         //print __METHOD__ . "\n";
 
         $this->_appName = 'dematpayslip';
@@ -195,8 +195,8 @@ class ArchiveProcess extends TimedJob {
         $this->_timeZone = new DateTimeZone($timeZoneName);
 
         // run once by interval
-        $taskDefaultInterval = 120;
-        //$taskDefaultInterval = 3600 * 4; // 4h
+        //$taskDefaultInterval = 120;
+        $taskDefaultInterval = 3600 * 4; // 4h
         $taskInterval = intval($this->_config->getAppValue($this->_appName,$this->_appName . '_archive_cron_interval', $taskDefaultInterval));
         //print __METHOD__ . ' : time_zone_name=' . $timeZoneName . ', cron_interval=' . $taskInterval . "\n";
         $this->setInterval($taskInterval);
@@ -237,8 +237,8 @@ class ArchiveProcess extends TimedJob {
                 $this->_logLevel = $logLevel;
                 $this->_logMode = $logMode;
 
-                // process list
                 $userId = $this->_config->getAppValue($this->_appName, 'user_id', 'demat');
+                // process message list
                 $processMsgList = array(
                     'error'   => array(),
                     'success' => array(),
@@ -252,7 +252,7 @@ class ArchiveProcess extends TimedJob {
                         $operationAskList = explode('+', $operationAsk);
                         if (in_array(DematpayslipArchive::OPERATION_ARCHIVE, $operationAskList)) {
                             $this->_log('Archive process : id=' . $dematpayslipArchive->getId() . ', status=' . $dematpayslipArchive->getStatus());
-                            $result = $dematpayslipArchive->archiveProcess($this->_appName, $this->_config, $this->_dbConnection, $this->_l10n, $this->_dematpayslipArchiveMapper, $this->_dematpayslipUserMapper, $this->_timeZone);
+                            $result = $dematpayslipArchive->archiveProcess($this->_appName, $this->_config, $this->_dbConnection, $this->_l10n, $this->_rootFolder, $this->_dematpayslipArchiveMapper, $this->_dematpayslipUserMapper, $this->_timeZone);
 
                             if ($result < 0) {
                                 $msgErrorList = $dematpayslipArchive->getMsgList('error');
@@ -279,31 +279,31 @@ class ArchiveProcess extends TimedJob {
                         $nbTotal = $nbError + $nbSuccess;
                         $dateTimeNow = new DateTime('now', $this->_timeZone);
 
-                        // activity
-                        $this->_log('Activity add : archives processed');
-                        $event = $this->_activityManager->generateEvent();
-                        $event->setApp($this->_appName)
-                            ->setType('job_processed')
-                            ->setAffectedUser($userId)
-                            ->setTimestamp($dateTimeNow->getTimestamp())
-                            ->setSubject('job_processed', ['nb_success' => $nbSuccess, 'nb_total' => $nbTotal]);
-                        //->setLink($folderLink)
-                        //->setObject('folder', $folder->getId(), $folder->getUuid());
-                        $this->_activityManager->publish($event);
-
-                        // notification
-                        $this->_log('Notification add : archives processed');
-                        $notification = $this->_notificationManager->createNotification();
-                        $notification->setApp($this->_appName)
-                            ->setSubject('job_processed', ['nb_success' => $nbSuccess, 'nb_total' => $nbTotal])
-                            ->setObject('dematpayslip_process', 1)
-                            ->setUser($userId);
-                        //->setIcon($this->_urlGenerator->getAbsoluteURL($this->_urlGenerator->imagePath($this->_appName, 'folder.png')))
-                        //->setLink($folderLink);
-                        if ($this->_notificationManager->getCount($notification) === 0) {
-                            $notification->setDateTime(new DateTime());
-                            $this->_notificationManager->notify($notification);
-                        }
+//                        // activity
+//                        $this->_log('Activity add : archives processed');
+//                        $event = $this->_activityManager->generateEvent();
+//                        $event->setApp($this->_appName)
+//                            ->setType('job_processed')
+//                            ->setAffectedUser($userId)
+//                            ->setTimestamp($dateTimeNow->getTimestamp())
+//                            ->setSubject('job_processed', ['nb_success' => $nbSuccess, 'nb_total' => $nbTotal]);
+//                        //->setLink($folderLink)
+//                        //->setObject('folder', $folder->getId(), $folder->getUuid());
+//                        $this->_activityManager->publish($event);
+//
+//                        // notification
+//                        $this->_log('Notification add : archives processed');
+//                        $notification = $this->_notificationManager->createNotification();
+//                        $notification->setApp($this->_appName)
+//                            ->setSubject('job_processed', ['nb_success' => $nbSuccess, 'nb_total' => $nbTotal])
+//                            ->setObject('dematpayslip_process', 1)
+//                            ->setUser($userId);
+//                        //->setIcon($this->_urlGenerator->getAbsoluteURL($this->_urlGenerator->imagePath($this->_appName, 'folder.png')))
+//                        //->setLink($folderLink);
+//                        if ($this->_notificationManager->getCount($notification) === 0) {
+//                            $notification->setDateTime(new DateTime());
+//                            $this->_notificationManager->notify($notification);
+//                        }
                     }
                 }
                 $this->_log('Archives process : End');
diff --git a/lib/BackgroundJob/IndexationProcess.php b/lib/BackgroundJob/IndexationProcess.php
index 13a6c0b..56fec92 100644
--- a/lib/BackgroundJob/IndexationProcess.php
+++ b/lib/BackgroundJob/IndexationProcess.php
@@ -264,8 +264,8 @@ class IndexationProcess extends TimedJob {
                 $this->_logLevel = $logLevel;
                 $this->_logMode = $logMode;
 
-                // process list
                 $userId = $this->_config->getAppValue($this->_appName, 'user_id', 'demat');
+                // process message list
                 $processMsgList = array(
                     'error'   => array(),
                     'success' => array(),
diff --git a/lib/Controller/PageController.php b/lib/Controller/PageController.php
index 5e907c0..e5e3168 100644
--- a/lib/Controller/PageController.php
+++ b/lib/Controller/PageController.php
@@ -107,153 +107,6 @@ class PageController extends Controller {
     private $_userList;
 
 
-    /**
-     * Archive process
-     *
-     * @param   IDBConnection               $dbConnection                   Database connection
-     * @param   DematpayslipArchiveMapper   $dematpayslipArchiveMapper      Archive table mapper
-     * @param   DematpayslipArchive         $dematpayslipArchive            Archive
-     * @param   DateTimeZone                $dateTimeZone                   [=null] Date time zone
-     */
-//    public function archiveProcess(IDBConnection $dbConnection, DematpayslipArchiveMapper $dematpayslipArchiveMapper, DematpayslipArchive $dematpayslipArchive, DateTimeZone $dateTimeZone = null) {
-//        $archiveFlowNum = 1; // archiving for 5 years by default
-//
-//        // get dematpayslip user
-//        if (!empty($dematpayslipArchive->getDematpayslipIdUser())) {
-//            $dematpayslipUser = $this->_dematpayslipUserMapper->find($dematpayslipArchive->getDematpayslipIdUser());
-//            if ($dematpayslipUser->getDisabled() == 0) {
-//                $archiveFlowNum = 2; // archiving for 50 years
-//            }
-//        }
-//
-//        try {
-//            // Pastell API config
-//            $pastellConfigFlowId = $this->_config->getAppValue($this->appName, 'pastell_config_f' . $archiveFlowNum . '_id', '');
-//            $pastellConfigFlowMapper = new PastellConfigFlowMapper($dbConnection);
-//            $pastellConfigFlow = $pastellConfigFlowMapper->find($pastellConfigFlowId);
-//
-//            // Pastell API connection
-//            $pastellAPI = new PastellAPI($pastellConfigFlow->getIdConfig());
-//
-//            $canModifyArchive = false;
-//            if ($dematpayslipArchive->isArchived() === false) {
-//                $canModifyArchive = true;
-//            } else {
-//                // get and modify document last action
-//                $responseData = $pastellAPI->getEntityDocument($pastellConfigFlow->getIdE(), $dematpayslipArchive->getPastellIdDocument());
-//
-//                $archiveLastAction = $responseData['last_action']['action'];
-//                if (!empty($archiveLastAction)) {
-//                    $dematpayslipArchive->setPastellLastAction($archiveLastAction);
-//                    $dematpayslipArchiveMapper->update($dematpayslipArchive);
-//                }
-//            }
-//
-//            if ($canModifyArchive === false) {
-//                $this->_msgList['error'][] = $this->_l10n->t('L\'archive "' . $dematpayslipArchive->getFilePath() . '" a déjà été créée.');
-//            } else {
-//                // 1. create document
-//                if (empty($dematpayslipArchive->getPastellIdDocument())) {
-//                    $nowDateTime = new DateTime('now', $dateTimeZone);
-//                    $responseData = $pastellAPI->postEntityDocument($pastellConfigFlow->getIdE(), array(
-//                        'type' => 'pdf-generique'
-//                    ));
-//                    $dematpayslipArchive->setPastellIdDocument($responseData['id_d']);
-//                    $dematpayslipArchive->setPastellLastAction($responseData['last_action']['action']);
-//                    $dematpayslipArchive->setStatus(DematpayslipArchive::STATUS_CREATED);
-//                    $dematpayslipArchive->setStatusTime($nowDateTime->getTimestamp());
-//                    $dematpayslipArchiveMapper->update($dematpayslipArchive);
-//                }
-//                // 2. set document title
-//                if ($dematpayslipArchive->getStatus() == DematpayslipArchive::STATUS_CREATED) {
-//                    $nowDateTime = new DateTime('now', $dateTimeZone);
-//                    $responseData = $pastellAPI->patchEntityDocument($pastellConfigFlow->getIdE(), $dematpayslipArchive->getPastellIdDocument(), array(
-//                        'libelle' => $dematpayslipArchive->getId() . '_' . $dematpayslipArchive->getSiret() . '_' . $dematpayslipArchive->getMatricule() . '_' . $dematpayslipArchive->getStartDate() . '_' . $dematpayslipArchive->getEndDate()
-//                    ));
-//                    $dematpayslipArchive->setPastellLastAction($responseData['content']['last_action']['action']);
-//                    $dematpayslipArchive->setStatus(DematpayslipArchive::STATUS_TITLED);
-//                    $dematpayslipArchive->setStatusTime($nowDateTime->getTimestamp());
-//                    $dematpayslipArchiveMapper->update($dematpayslipArchive);
-//                }
-//                // 3. send document file
-//                if ($dematpayslipArchive->getStatus() == DematpayslipArchive::STATUS_TITLED) {
-//                    $nowDateTime = new DateTime('now', $dateTimeZone);
-//                    $fileId = $dematpayslipArchive->getIdFile();
-//                    $filePath = Filesystem::getPath($fileId);
-//                    $file = Filesystem::getFileInfo($filePath);
-//                    $fileName = $file->getName();
-//                    $fileContent = Filesystem::file_get_contents($filePath);
-//                    $responseData = $pastellAPI->postEntityDocumentFile($pastellConfigFlow->getIdE(), $dematpayslipArchive->getPastellIdDocument(), 'document', 0, $fileName, $fileContent);
-//                    $dematpayslipArchive->setPastellLastAction($responseData['content']['last_action']['action']);
-//                    $dematpayslipArchive->setStatus(DematpayslipArchive::STATUS_FILE_SENT);
-//                    $dematpayslipArchive->setStatusTime($nowDateTime->getTimestamp());
-//                    $dematpayslipArchiveMapper->update($dematpayslipArchive);
-//                }
-//                // 4. send to SAE
-//                if ($dematpayslipArchive->getStatus() == DematpayslipArchive::STATUS_FILE_SENT) {
-//                    $nowDateTime = new DateTime('now', $dateTimeZone);
-//                    $responseData = $pastellAPI->patchEntityDocument($pastellConfigFlow->getIdE(), $dematpayslipArchive->getPastellIdDocument(), array(
-//                        'envoi_sae' => true
-//                    ));
-//                    $dematpayslipArchive->setPastellLastAction($responseData['content']['last_action']['action']);
-//                    $dematpayslipArchive->setStatus(DematpayslipArchive::STATUS_SAE_SENT);
-//                    $dematpayslipArchive->setStatusTime($nowDateTime->getTimestamp());
-//                    $dematpayslipArchiveMapper->update($dematpayslipArchive);
-//                }
-//                // 5. create JSON file and add meta-data on document
-//                if ($dematpayslipArchive->getStatus() == DematpayslipArchive::STATUS_SAE_SENT) {
-//                    $saeConfigArr = array(
-//                        'matricule' => $dematpayslipArchive->getMatricule(),
-//                        'mois' => $dematpayslipArchive->getMonth(),
-//                        'annee' => $dematpayslipArchive->getYear(),
-//                        'nom' => $dematpayslipArchive->getLastname(),
-//                        'prenom' => $dematpayslipArchive->getFirstname(),
-//                        'date_edition' => $dematpayslipArchive->getEditionDate(),
-//                        'periode_2_de_paie' => $dematpayslipArchive->getEndDate(),
-//                        'periode_1_de_paie' => $dematpayslipArchive->getStartDate(),
-//                    );
-//                    $jsonFileName = 'sae_config.json';
-//                    $jsonFilePath = $this->_tmpDirUserPath . DIRECTORY_SEPARATOR . $jsonFileName;
-//                    Filesystem::fopen($jsonFilePath, 'w+');
-//                    Filesystem::file_put_contents($jsonFilePath, json_encode($saeConfigArr));
-//                    $nowDateTime = new DateTime('now', $dateTimeZone);
-//                    $jsonFileContent = Filesystem::file_get_contents($jsonFilePath);
-//                    $responseData = $pastellAPI->postEntityDocumentExternalData($pastellConfigFlow->getIdE(), $dematpayslipArchive->getPastellIdDocument(), 'sae_config', array(
-//                        'file_name'    => $jsonFileName,
-//                        'file_content' => $jsonFileContent
-//                    ));
-//                    $dematpayslipArchive->setPastellLastAction($responseData['content']['last_action']['action']);
-//                    $dematpayslipArchive->setStatus(DematpayslipArchive::STATUS_METADATA_SENT);
-//                    $dematpayslipArchive->setStatusTime($nowDateTime->getTimestamp());
-//                    $dematpayslipArchiveMapper->update($dematpayslipArchive);
-//                }
-//                // 6. set orientation action on document
-//                if ($dematpayslipArchive->getStatus() == DematpayslipArchive::STATUS_METADATA_SENT) {
-//                    $nowDateTime = new DateTime('now', $dateTimeZone);
-//                    $responseData = $pastellAPI->postEntityDocumentAction($pastellConfigFlow->getIdE(), $dematpayslipArchive->getPastellIdDocument(), 'orientation');
-//                    $dematpayslipArchive->setStatus(DematpayslipArchive::STATUS_ORIENTATION);
-//                    $dematpayslipArchive->setStatusTime($nowDateTime->getTimestamp());
-//                    if ($responseData['result'] == true) {
-//                        // get and modify document last action
-//                        $responseData = $pastellAPI->getEntityDocument($pastellConfigFlow->getIdE(), $dematpayslipArchive->getPastellIdDocument());
-//                        if (!empty($responseData['last_action']['action'])) {
-//                            $dematpayslipArchive->setPastellLastAction($responseData['last_action']['action']);
-//                        }
-//                    }
-//                    $dematpayslipArchiveMapper->update($dematpayslipArchive);
-//                }
-//
-//                if ($dematpayslipArchive->getStatus() < DematpayslipArchive::STATUS_ORIENTATION) {
-//                    $this->_msgList['error'][] = $this->_l10n->t('L\'archive "' . $dematpayslipArchive->getFilePath() . '" n\'a pas été correctement créée [status=' . $dematpayslipArchive->getStatus() .'].');
-//                } else {
-//                    $this->_msgList['success'][] = $this->_l10n->t('L\'archive "' . $dematpayslipArchive->getFilePath() . '" a été créée.');
-//                }
-//            }
-//        } catch (Exception $e) {
-//            $this->_msgList['error'][] = $e->getMessage();
-//        }
-//    }
-
     /**
      * Assign params for template demat
      *
diff --git a/lib/Db/DematpayslipArchive.php b/lib/Db/DematpayslipArchive.php
index f7e3dcd..506b336 100644
--- a/lib/Db/DematpayslipArchive.php
+++ b/lib/Db/DematpayslipArchive.php
@@ -4,11 +4,14 @@ namespace OCA\Dematpayslip\Db;
 
 use JsonSerializable;
 
-use OC\Files\Filesystem;
 use OCP\AppFramework\Db\Entity;
 use OCP\IConfig;
 use OCP\IDBConnection;
 use OCP\IL10N;
+use OCP\Files\IRootFolder;
+
+use OCP\Files\File;
+//use OC\Files\Filesystem;
 
 use DateTime;
 use DateTimeZone;
@@ -224,14 +227,15 @@ class DematpayslipArchive extends Entity implements JsonSerializable {
     /**
      * Save payslip file to index/archive from path and agent user
      *
+     * @param   File                        $archiveFile                        Archive file
      * @param   DematpayslipArchiveMapper   $dematpayslipArchiveMapper          Archive mapper
-     * @param   string                      $filePath                           Payslip File path
      * @param   DematpayslipUser            $agentUser                          Agent user
      * @param   string                      $startDate                          Payslip start date
      * @param   string                      $endDate                            Payslip end date
      * @param   string                      $year                               Payslip year
      * @param   string                      $month                              Payslip month
      * @param   string                      $editionDate                        Payslip edition date
+     * @param   int                         $status                             [=self::STATUS_INITIALIZED] Status
      * @param   DateTime                    $importDateTime                     [=null] Import date time
      * @param   int                         $idProcess                          [=0] Process id
      * @param   string                      $operationAsk                       [=''] Operation ask
@@ -240,21 +244,11 @@ class DematpayslipArchive extends Entity implements JsonSerializable {
      *
      * @throws  Exception
      */
-    public function saveFromFilePathAndAgent(DematpayslipArchiveMapper $dematpayslipArchiveMapper, $filePath, DematpayslipUser $agentUser, $startDate, $endDate, $year, $month, $editionDate, DateTime $importDateTime = null, $idProcess = 0, $filePagesNum = '', $operationAsk = '', $operationProgress = 0, $timeZone = null) {
-        //if (!$archiveFilePath) {
-        //    $pdfPayslipCopyFileName = $agentUser->getSiret() . '-' . $agentUser->getMatricule() . '_' . $startDate . '-' . $endDate . '.pdf';
-        //    $pdfPayslipCopyFilePath = $this->_tmpDirUserPath . DIRECTORY_SEPARATOR . $pdfPayslipCopyFileName;
-        //    $fileCopied = Filesystem::copy($pdfPayslipCheckFilePath, $pdfPayslipCopyFilePath);
-        //    if (!$fileCopied) {
-        //        return -1;
-        //    }
-        //    $archiveFilePath = $pdfPayslipCopyFilePath;
-        //}
-
+    public function saveFromFilePathAndAgent(File $archiveFile, DematpayslipArchiveMapper $dematpayslipArchiveMapper, DematpayslipUser $agentUser, $startDate, $endDate, $year, $month, $editionDate, $status = self::STATUS_INITIALIZED, DateTime $importDateTime = null, $idProcess = 0, $filePagesNum = '', $operationAsk = '', $operationProgress = 0, $timeZone = null) {
         $statusDateTime = new DateTime('now', $timeZone);
-
-        $archiveFile         = Filesystem::getFileInfo($filePath);
-        $archiveFileChecksum = Filesystem::hash('md5', $filePath);
+        //$archiveFile = Filesystem::getFileInfo($filePath);
+        //$archiveFileChecksum = Filesystem::hash('md5', $filePath);
+        $archiveFileChecksum = $archiveFile->hash('md5');
 
         $this->setIdFile($archiveFile->getId());
         $this->setFilePath($archiveFile->getPath());
@@ -271,7 +265,7 @@ class DematpayslipArchive extends Entity implements JsonSerializable {
         $this->setStartDate($startDate);
         $this->setEndDate($endDate);
         $this->setEditionDate($editionDate);
-        $this->setStatus(DematpayslipArchive::STATUS_INITIALIZED);
+        $this->setStatus($status);
         $this->setStatusTime($statusDateTime->getTimestamp());
         if ($importDateTime) {
             $this->setImportTime($importDateTime->getTimestamp());
@@ -300,7 +294,7 @@ class DematpayslipArchive extends Entity implements JsonSerializable {
     }
 
     /**
-     * Determine if it have already been archived (can't modify)
+     * Determine if it has already been archived (can't modify)
      *
      * @return  bool
      */
@@ -308,7 +302,7 @@ class DematpayslipArchive extends Entity implements JsonSerializable {
         $isArchived = false;
 
         if (!empty($this->getPastellIdDocument())) {
-            if (in_array($this->getStatus(), [self::STEP_STATUS_ARCHIVED])) {
+            if (in_array($this->getStatus(), [self::STATUS_ORIENTATION])) {
                 $isArchived = true;
             }
         }
@@ -322,13 +316,14 @@ class DematpayslipArchive extends Entity implements JsonSerializable {
      * @param   string                      $appName                        App name
      * @param   IConfig                     $config                         Config
      * @param   IDBConnection               $dbConnection                   Database connection
-     * @param   IL10N                       $l                              Lang
+     * @param   IL10N                       $l10n                           Lang
+     * @param   IRootFolder                 $rootFolder                     Root folder
      * @param   DematpayslipArchiveMapper   $dematpayslipArchiveMapper      Archive table mapper
      * @param   DematpayslipUserMapper      $dematpayslipUserMapper         User table mapper
      * @param   DateTimeZone                $dateTimeZone                   [=null] Date time zone
      * @return  int                         <0 if errors else >0 on success
      */
-    public function archiveProcess(string $appName, IConfig $config, IDBConnection $dbConnection, IL10N $l, DematpayslipArchiveMapper $dematpayslipArchiveMapper, DematpayslipUserMapper $dematpayslipUserMapper, DateTimeZone $dateTimeZone = null) {
+    public function archiveProcess(string $appName, IConfig $config, IDBConnection $dbConnection, IL10N $l10n, IRootFolder $rootFolder, DematpayslipArchiveMapper $dematpayslipArchiveMapper, DematpayslipUserMapper $dematpayslipUserMapper, DateTimeZone $dateTimeZone = null) {
         $archiveFlowNum = 1; // archiving for 5 years by default
         // get dematpayslip user
         if (!empty($this->getDematpayslipIdUser())) {
@@ -339,6 +334,10 @@ class DematpayslipArchive extends Entity implements JsonSerializable {
         }
 
         try {
+            // Demat config
+            $dematAppDataDir = $config->getAppValue($appName, 'app_data_dir', 'dematpayslip');
+            $userId = $config->getAppValue($appName, 'user_id', 'demat');
+
             // Pastell API config
             $pastellConfigFlowId = $config->getAppValue($appName, 'pastell_config_f' . $archiveFlowNum . '_id', '');
             $pastellConfigFlowMapper = new PastellConfigFlowMapper($dbConnection);
@@ -362,7 +361,7 @@ class DematpayslipArchive extends Entity implements JsonSerializable {
             }
 
             if ($canModifyArchive === false) {
-                $this->_msgList['error'][] = $l->t('L\'archive "' . $this->getFilePath() . '" a déjà été créée.');
+                $this->_msgList['error'][] = $l10n->t('L\'archive "' . $this->getFilePath() . '" a déjà été créée.');
             } else {
                 // 1. create document
                 if (empty($this->getPastellIdDocument())) {
@@ -391,15 +390,18 @@ class DematpayslipArchive extends Entity implements JsonSerializable {
                 if ($this->getStatus() == self::STATUS_TITLED) {
                     $nowDateTime = new DateTime('now', $dateTimeZone);
                     $fileId = $this->getIdFile();
-                    $filePath = Filesystem::getPath($fileId);
-                    $file = Filesystem::getFileInfo($filePath);
-                    $fileName = $file->getName();
-                    $fileContent = Filesystem::file_get_contents($filePath);
-                    $responseData = $pastellAPI->postEntityDocumentFile($pastellConfigFlow->getIdE(), $this->getPastellIdDocument(), 'document', 0, $fileName, $fileContent);
-                    $this->setPastellLastAction($responseData['content']['last_action']['action']);
-                    $this->setStatus(self::STATUS_FILE_SENT);
-                    $this->setStatusTime($nowDateTime->getTimestamp());
-                    $dematpayslipArchiveMapper->update($this);
+                    //$filePath = Filesystem::getPath($fileId);
+                    //$file = Filesystem::getFileInfo($filePath);
+                    $fileNode = $rootFolder->getById($fileId)[0];
+                    if ($fileNode instanceof File) {
+                        $fileName = $fileNode->getName();
+                        $fileContent = $fileNode->getContent();
+                        $responseData = $pastellAPI->postEntityDocumentFile($pastellConfigFlow->getIdE(), $this->getPastellIdDocument(), 'document', 0, $fileName, $fileContent);
+                        $this->setPastellLastAction($responseData['content']['last_action']['action']);
+                        $this->setStatus(self::STATUS_FILE_SENT);
+                        $this->setStatusTime($nowDateTime->getTimestamp());
+                        $dematpayslipArchiveMapper->update($this);
+                    }
                 }
                 // 4. send to SAE
                 if ($this->getStatus() == self::STATUS_FILE_SENT) {
@@ -426,29 +428,28 @@ class DematpayslipArchive extends Entity implements JsonSerializable {
                     );
                     $jsonFileName = 'sae_config.json';
 
-                    $tmpJsonFilePath = tempnam(sys_get_temp_dir(), 'sae');
+                    //$tmpJsonFilePath = tempnam(sys_get_temp_dir(), 'sae');
+                    $userFolder = $rootFolder->getUserFolder($userId);
+                    $dematAppDataTmpPath = $userFolder->getPath() . DIRECTORY_SEPARATOR . $dematAppDataDir;
+                    $tmpJsonFilePath = tempnam($dematAppDataTmpPath, 'sae');
                     if (!$tmpJsonFilePath) {
-                        $this->_msgList['error'][] = $l->t('Impossible de créer le fichier temporaire "' . $tmpJsonFilePath . '" [status=' . $this->getStatus() .'].');
+                        $this->_msgList['error'][] = $l10n->t('Impossible de créer le nom du fichier temporaire "' . $dematAppDataTmpPath . '" [status=' . $this->getStatus() .'].');
                     } else {
-                        $result = Filesystem::fopen($tmpJsonFilePath, 'w+');
-                        if (!$result) {
-                            $this->_msgList['error'][] = $l->t('Impossible d\'ouvrir le fichier temporaire "' . $tmpJsonFilePath . '" [status=' . $this->getStatus() .'].');
-                        } else {
-                            $result = Filesystem::file_put_contents($tmpJsonFilePath, json_encode($saeConfigArr));
-                            if (!$result) {
-                                $this->_msgList['error'][] = $l->t('Impossible d\'écrire dans le fichier temporaire "' . $tmpJsonFilePath . '" [status=' . $this->getStatus() . '].');
-                            } else {
-                                $nowDateTime = new DateTime('now', $dateTimeZone);
-                                $jsonFileContent = Filesystem::file_get_contents($tmpJsonFilePath);
-                                $responseData = $pastellAPI->postEntityDocumentExternalData($pastellConfigFlow->getIdE(), $this->getPastellIdDocument(), 'sae_config', array(
-                                    'file_name' => $jsonFileName,
-                                    'file_content' => $jsonFileContent
-                                ));
-                                $this->setPastellLastAction($responseData['content']['last_action']['action']);
-                                $this->setStatus(self::STATUS_METADATA_SENT);
-                                $this->setStatusTime($nowDateTime->getTimestamp());
-                                $this->update($this);
-                            }
+                        //$result = Filesystem::fopen($tmpJsonFilePath, 'w+');
+                        try {
+                            //$jsonFileContent = Filesystem::file_get_contents($tmpJsonFilePath);
+                            $tmpJsonFile = $rootFolder->newFile($tmpJsonFilePath, json_encode($saeConfigArr));
+                            $nowDateTime = new DateTime('now', $dateTimeZone);
+                            $responseData = $pastellAPI->postEntityDocumentExternalData($pastellConfigFlow->getIdE(), $this->getPastellIdDocument(), 'sae_config', array(
+                                'file_name' => $jsonFileName,
+                                'file_content' => $tmpJsonFile->getContent()
+                            ));
+                            $this->setPastellLastAction($responseData['content']['last_action']['action']);
+                            $this->setStatus(self::STATUS_METADATA_SENT);
+                            $this->setStatusTime($nowDateTime->getTimestamp());
+                            $this->update($this);
+                        } catch (Exception $e) {
+                            $this->_msgList['error'][] = $l10n->t('Impossible d\'écrire dans le fichier temporaire "' . $tmpJsonFilePath . '" [status=' . $this->getStatus() .'].');
                         }
                     }
                 }
@@ -469,9 +470,9 @@ class DematpayslipArchive extends Entity implements JsonSerializable {
                 }
 
                 if ($this->getStatus() < self::STATUS_ORIENTATION) {
-                    $this->_msgList['error'][] = $l->t('L\'archive "' . $this->getFilePath() . '" n\'a pas été correctement créée [status=' . $this->getStatus() .'].');
+                    $this->_msgList['error'][] = $l10n->t('L\'archive "' . $this->getFilePath() . '" n\'a pas été correctement créée [status=' . $this->getStatus() .'].');
                 } else {
-                    $this->_msgList['success'][] = $l->t('L\'archive "' . $this->getFilePath() . '" a été créée.');
+                    $this->_msgList['success'][] = $l10n->t('L\'archive "' . $this->getFilePath() . '" a été créée.');
                 }
             }
 
diff --git a/lib/Db/DematpayslipProcess.php b/lib/Db/DematpayslipProcess.php
index d26c586..0b49cce 100644
--- a/lib/Db/DematpayslipProcess.php
+++ b/lib/Db/DematpayslipProcess.php
@@ -3,16 +3,19 @@ namespace OCA\Dematpayslip\Db;
 
 use JsonSerializable;
 
-use OC\Files\Filesystem;
 use OCP\AppFramework\Db\Entity;
-use OCP\Files\IRootFolder;
 use OCP\IConfig;
 use OCP\IDateTimeZone;
 use OCP\IDBConnection;
 use OCP\IL10N;
 use OCP\Share\IManager as IShareManager;
+use OCP\Files\IRootFolder;
 use OCP\IUserManager;
 
+use OCP\Files\File;
+use OC\Files\Filesystem;
+use OCP\Files\Folder;
+
 use DateTime;
 use DateTimeZone;
 use Exception;
@@ -515,7 +518,7 @@ class DematpayslipProcess extends Entity implements JsonSerializable {
      * @throws Exception
      */
     private function _initDematFolders() {
-        $appDataDirPath           = (string) $this->_dematpayslipConfigList['app_data_dir']; // app directory of operator user (upload, check, report, etc)
+        $appDataDirPath           = (string) $this->_dematpayslipConfigList['app_data_dir']; // app directory of operator user (upload, check, report, ...)
         $this->_checkDirUserPath  = $appDataDirPath . DIRECTORY_SEPARATOR . 'check';
         $this->_reportDirUserPath = $appDataDirPath . DIRECTORY_SEPARATOR . 'report';
         $this->_uploadDirUserPath = $appDataDirPath . DIRECTORY_SEPARATOR . 'upload';
@@ -643,7 +646,7 @@ class DematpayslipProcess extends Entity implements JsonSerializable {
     /**
      * Get phase name
      *
-     * @param   int         $phaseId    Phase Id
+     * @param   int         $phaseId    Phase id
      * @return  string      Phase name
      */
     private static function _getPhaseName($phaseId) {
@@ -1668,6 +1671,7 @@ class DematpayslipProcess extends Entity implements JsonSerializable {
                     $csvCheckLineNum = 0;
                     if (empty($this->getPhaseStep())) {
                         // get all share with this user
+                        /** @var Folder $payslipShareNode */
                         $payslipShareNode = $userFolder->get($payslipsDirPath);
                         $payslipShareList = $this->_shareManager->getSharesInFolder($this->_userId, $payslipShareNode);
                         $payslipMatriculeShareNodeIdList = array();
@@ -1736,12 +1740,14 @@ class DematpayslipProcess extends Entity implements JsonSerializable {
                                 // pdf check file path
                                 $pdfPayslipCheckFileName = ($csvCheckLineNum + 1) . '_' . $agentUser->getMatricule() . '.pdf';
                                 $pdfPayslipCheckFilePath = $this->_checkDirUserPath . DIRECTORY_SEPARATOR . $pdfPayslipCheckFileName;
+                                /** @var File $pdfPayslipCheckFileNode */
+                                $pdfPayslipCheckFileNode = $userFolder->get($pdfPayslipCheckFilePath);
 
                                 // process skip lines
                                 if (in_array($csvCheckLineNum, $dematpayslipProcessSkipLineIdList)) {
                                     // save PDF temp file path and activate indexation job
                                     $archive = new DematpayslipArchive();
-                                    $archive->saveFromFilePathAndAgent($dematpayslipArchiveMapper, $pdfPayslipCheckFilePath, $agentUser, $startDate, $endDate, $year, $month, $editionDate, null, $this->getId(), $pdfPagesNum, $operationAsk, DematpayslipArchive::OPERATION_INDEXATION);
+                                    $archive->saveFromFilePathAndAgent($pdfPayslipCheckFileNode, $dematpayslipArchiveMapper, $agentUser, $startDate, $endDate, $year, $month, $editionDate, DematpayslipArchive::STATUS_INITIALIZED, null, $this->getId(), $pdfPagesNum, $operationAsk, DematpayslipArchive::OPERATION_INDEXATION);
 
                                     $csvCheckLineNum++;
                                     continue;
@@ -1751,7 +1757,7 @@ class DematpayslipProcess extends Entity implements JsonSerializable {
                                 if (empty($agentUser->getEmail())) {
                                     // save PDF temp file path and activate indexation job
                                     $archive = new DematpayslipArchive();
-                                    $archive->saveFromFilePathAndAgent($dematpayslipArchiveMapper, $pdfPayslipCheckFilePath, $agentUser, $startDate, $endDate, $year, $month, $editionDate, null, $this->getId(), $pdfPagesNum, $operationAsk, DematpayslipArchive::OPERATION_INDEXATION);
+                                    $archive->saveFromFilePathAndAgent($pdfPayslipCheckFileNode, $dematpayslipArchiveMapper, $agentUser, $startDate, $endDate, $year, $month, $editionDate, DematpayslipArchive::STATUS_INITIALIZED, null, $this->getId(), $pdfPagesNum, $operationAsk, DematpayslipArchive::OPERATION_INDEXATION);
 
                                     $csvCheckLineNum++;
                                     continue;
@@ -1819,12 +1825,12 @@ class DematpayslipProcess extends Entity implements JsonSerializable {
                                                 // agent want payslip
                                                 // save PDF temp file path and activate indexation job
                                                 $archive = new DematpayslipArchive();
-                                                $archive->saveFromFilePathAndAgent($dematpayslipArchiveMapper, $pdfPayslipCheckFilePath, $agentUser, $startDate, $endDate, $year, $month, $editionDate, null, $this->getId(), $pdfPagesNum, $operationAsk, DematpayslipArchive::OPERATION_INDEXATION);
+                                                $archive->saveFromFilePathAndAgent($pdfPayslipCheckFileNode, $dematpayslipArchiveMapper, $agentUser, $startDate, $endDate, $year, $month, $editionDate, DematpayslipArchive::STATUS_INITIALIZED, null, $this->getId(), $pdfPagesNum, $operationAsk, DematpayslipArchive::OPERATION_INDEXATION);
                                             } else {
                                                 // agent disabled payslip
                                                 // save PDF temp file path and activate indexation job
                                                 $archive = new DematpayslipArchive();
-                                                $archive->saveFromFilePathAndAgent($dematpayslipArchiveMapper, $pdfPayslipCheckFilePath, $agentUser, $startDate, $endDate, $year, $month, $editionDate, null, $this->getId(), $pdfPagesNum, $operationAsk, DematpayslipArchive::OPERATION_INDEXATION);
+                                                $archive->saveFromFilePathAndAgent($pdfPayslipCheckFileNode, $dematpayslipArchiveMapper, $agentUser, $startDate, $endDate, $year, $month, $editionDate, DematpayslipArchive::STATUS_INITIALIZED, null, $this->getId(), $pdfPagesNum, $operationAsk, DematpayslipArchive::OPERATION_INDEXATION);
                                             }
                                         } else {
                                             $errorMsg = $this->_l10n->t('L\'utilisateur "' . $userFindByEmailId . '" n\'a pas de dossier SIRET-MATRICULE associé [siret="' . $agentUser->getSiret() . '", matricule="' . $agentUser->getMatricule() . '", email="' . $agentUser->getEmail() . '"].');
@@ -1952,6 +1958,7 @@ class DematpayslipProcess extends Entity implements JsonSerializable {
 
                         // get all share with this user
                         $this->_logCsvLine($this->_l10n->t('Récupération des partages de "' . $payslipsDirPath . '".'), self::LOG_DEBUG);
+                        /** @var Folder $payslipShareNode */
                         $payslipShareNode = $userFolder->get($payslipsDirPath);
                         $payslipShareList = $this->_shareManager->getSharesInFolder($this->_userId, $payslipShareNode);
                         $payslipMatriculeShareNodeIdList = array();
@@ -2107,6 +2114,7 @@ class DematpayslipProcess extends Entity implements JsonSerializable {
                                                 $pdfPayslipNoDemat->Output('F', $userHomeFilesDirPath . DIRECTORY_SEPARATOR . $payslipNoDematPDFPath);
                                                 $pdfPayslipFilePath = $payslipNoDematPDFPath . '.pdf';
                                                 try {
+                                                    /** @var File $payslipNoDematPDFNode */
                                                     $payslipNoDematPDFNode = $userFolder->get($payslipNoDematPDFPath);
                                                     $payslipNoDematPDFNode->move($userFolder->getPath() . DIRECTORY_SEPARATOR . $pdfPayslipFilePath);
                                                     $dematpayslipArchive->setFilePath($payslipNoDematPDFNode->getPath());
@@ -2117,17 +2125,6 @@ class DematpayslipProcess extends Entity implements JsonSerializable {
                                                     $this->_logCsvLine($errorMsg, self::LOG_ERROR);
                                                     $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
                                                 }
-
-                                                // save archive and process
-                                                if ($operationAskArchive) {
-                                                    $result = $dematpayslipArchive->saveFromFilePathAndAgent($dematpayslipArchiveMapper, $pdfPayslipFilePath, $agentUser, $startDate, $endDate, $year, $month, $editionDate, $phaseStartDateTime);
-                                                    if ($result < 0) {
-                                                        $archiveError++;
-                                                        $errorMsg = $this->_l10n->t('Impossible de créer le fichier temporaire du bulletin de paie "' . $pdfPayslipCheckFilePath . '".');
-                                                        $this->_logCsvLine($errorMsg, self::LOG_ERROR, $agentUser, $startDate, $endDate);
-                                                        $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
-                                                    }
-                                                }
                                             }
 
                                             if ($archiveError > 0) {
@@ -2204,7 +2201,7 @@ class DematpayslipProcess extends Entity implements JsonSerializable {
 
                                                     // check if user payslip directory is not already shared
                                                     if (!in_array($payslipsMatriculeDirPathNode->getId(), $payslipMatriculeShareNodeIdList)) {
-                                                        //share "MATRICULE" directory in read only with this agent user (found by email)
+                                                        // share "MATRICULE" directory in read only with this agent user (found by email)
                                                         $this->_logCsvLine($this->_l10n->t('Partage du dossier SIRET-MATRICULE [' . $siretMatriculeDirName . '] en lecture seule.'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
                                                         $payslipMatriculeShare = $this->_shareManager->newShare();
                                                         $payslipMatriculeShare->setNode($payslipsMatriculeDirPathNode);
@@ -2217,7 +2214,7 @@ class DematpayslipProcess extends Entity implements JsonSerializable {
                                                         $this->_logCsvLine($this->_l10n->t('Dossier SIRET-MATRICULE [' . $siretMatriculeDirName . '] est déjà partagé.'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
                                                     }
 
-                                                    // directory "SIRET-MATRICULE/ANNEE"
+                                                    // "SIRET-MATRICULE/ANNEE" directory
                                                     $this->_logCsvLine($this->_l10n->t('Vérification de l\'existance du dossier de l\'annéee [' . $year . '].'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
                                                     try {
                                                         $userFolder->get($payslipsMatriculeYearDirPath);
@@ -2254,17 +2251,6 @@ class DematpayslipProcess extends Entity implements JsonSerializable {
                                                                 $this->_logCsvLine($errorMsg, self::LOG_ERROR, $agentUser, $startDate, $endDate);
                                                                 $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
                                                             }
-
-                                                            // save payslip in queue
-                                                            if ($operationAskArchive) {
-                                                                $result = $dematpayslipArchive->saveFromFilePathAndAgent($dematpayslipArchiveMapper, $pdfPayslipFilePath, $agentUser, $startDate, $endDate, $year, $month, $editionDate, $phaseStartDateTime);
-                                                                if ($result < 0) {
-                                                                    $archiveError++;
-                                                                    $errorMsg = $this->_l10n->t('Impossible de créer le fichier temporaire du bulletin de paie "' . $pdfPayslipCheckFilePath . '".');
-                                                                    $this->_logCsvLine($errorMsg, self::LOG_ERROR, $agentUser, $startDate, $endDate);
-                                                                    $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
-                                                                }
-                                                            }
                                                         }
                                                     }
                                                 } else {
@@ -2332,17 +2318,6 @@ class DematpayslipProcess extends Entity implements JsonSerializable {
                                                             $this->_logCsvLine($errorMsg, self::LOG_ERROR);
                                                             $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
                                                         }
-
-                                                        // save payslip in queue
-                                                        if ($operationAskArchive) {
-                                                            $result = $dematpayslipArchive->saveFromFilePathAndAgent($dematpayslipArchiveMapper, $pdfPayslipFilePath, $agentUser, $startDate, $endDate, $year, $month, $editionDate, $phaseStartDateTime);
-                                                            if ($result < 0) {
-                                                                $archiveError++;
-                                                                $errorMsg = $this->_l10n->t('Impossible de créer le fichier temporaire du bulletin de paie "' . $pdfPayslipCheckFilePath . '".');
-                                                                $this->_logCsvLine($errorMsg, self::LOG_ERROR, $agentUser, $startDate, $endDate);
-                                                                $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
-                                                            }
-                                                        }
                                                     }
                                                 }
                                             } else {
@@ -2430,6 +2405,9 @@ class DematpayslipProcess extends Entity implements JsonSerializable {
                         $phaseStep = 'report';
                         $phaseStepNum = 0;
                         $retryPhaseStepNum = $phaseStepNum;
+                        if ($this->getPhaseStep() == $phaseStep) {
+                            $retryPhaseStepNum = $this->getPhaseStepNum();
+                        }
                         if (empty($this->getPhaseStep())) {
                             $reportSubDirName = $phaseStartDateTime->format('Y-m-d_H-i-s');
                             $reportSubDirPath = $this->_reportDirUserPath . DIRECTORY_SEPARATOR . $reportSubDirName;
@@ -2688,7 +2666,7 @@ class DematpayslipProcess extends Entity implements JsonSerializable {
                 foreach ($archiveSelectIdList as $archiveSelectId) {
                     $dematpayslipArchive = $dematpayslipArchiveMapper->find(intval($archiveSelectId));
                     if (!empty($dematpayslipArchive)) {
-                        $dematpayslipArchive->archiveProcess($this->_appName, $this->_config, $this->_dbConnection, $this->_l10n, $dematpayslipArchiveMapper, $this->_dematpayslipUserMapper, $this->_timeZone);
+                        $dematpayslipArchive->archiveProcess($this->_appName, $this->_config, $this->_dbConnection, $this->_l10n, $this->_rootFolder, $dematpayslipArchiveMapper, $this->_dematpayslipUserMapper, $this->_timeZone);
                     }
                 }
             }
@@ -2702,7 +2680,7 @@ class DematpayslipProcess extends Entity implements JsonSerializable {
                     $operationAsk = $dematpayslipArchive->getOperationAsk();
                     $operationAskList = explode('+', $operationAsk);
                     if (in_array(DematpayslipArchive::OPERATION_ARCHIVE, $operationAskList)) {
-                        $dematpayslipArchive->archiveProcess($this->_appName, $this->_config, $this->_dbConnection, $this->_l10n, $dematpayslipArchiveMapper, $this->_dematpayslipUserMapper, $this->_timeZone);
+                        $dematpayslipArchive->archiveProcess($this->_appName, $this->_config, $this->_dbConnection, $this->_l10n, $this->_rootFolder, $dematpayslipArchiveMapper, $this->_dematpayslipUserMapper, $this->_timeZone);
                     }
                 }
             }
@@ -2713,7 +2691,7 @@ class DematpayslipProcess extends Entity implements JsonSerializable {
                 foreach ($archiveSelectIdList as $archiveSelectId) {
                     $dematpayslipArchive = $dematpayslipArchiveMapper->find(intval($archiveSelectId));
                     if (!empty($dematpayslipArchive)) {
-                        $dematpayslipArchive->archiveProcess($this->_appName, $this->_config, $this->_dbConnection, $this->_l10n, $dematpayslipArchiveMapper, $this->_dematpayslipUserMapper, $this->_timeZone);
+                        $dematpayslipArchive->archiveProcess($this->_appName, $this->_config, $this->_dbConnection, $this->_l10n, $this->_rootFolder, $dematpayslipArchiveMapper, $this->_dematpayslipUserMapper, $this->_timeZone);
                     }
                 }
             }
-- 
GitLab