From fe6515be828c2b5718556664160aaab2dd490666 Mon Sep 17 00:00:00 2001
From: lvessiller <lvessiller@open-dsi.fr>
Date: Tue, 10 Aug 2021 18:07:24 +0200
Subject: [PATCH] NEW reprise des traitements indexation/archivage en taches
 planifiees Nextcloud - nouvelle structure des donnees - remplacement de codes
 deprecies

---
 appinfo/info.xml                              |   14 +-
 js/script.js                                  |    8 +-
 lib/Activity/ArchivesProcessed.php            |   99 +
 lib/Activity/ArchivesProcessedFilter.php      |   98 +
 lib/Activity/Provider.php                     |  128 +
 lib/AppInfo/Application.php                   |   52 +
 lib/BackgroundJob/ArchiveProcess.php          |  322 ++
 lib/BackgroundJob/IndexationProcess.php       |  345 ++
 lib/Controller/PageController.php             | 3443 +++++------------
 lib/Db/DematpayslipArchive.php                |  386 +-
 lib/Db/DematpayslipArchiveMapper.php          |   52 +-
 lib/Db/DematpayslipProcess.php                | 2788 +++++++++++++
 .../Version030101Date20210809040000.php       |  112 +
 lib/Notification/Notifier.php                 |  126 +
 lib/Settings/AdminSettings.php                |   95 +-
 lib/Settings/PersonalSettings.php             |   26 +-
 templates/content/agent_list.php              |   29 +-
 templates/content/archive_list.php            |   16 +-
 templates/content/index.php                   |    8 +-
 templates/content/shares.php                  |    8 +-
 templates/content/user_list.php               |   14 +-
 templates/navigation/index.php                |   13 +-
 templates/navigation/shares.php               |    8 +-
 templates/settings/admin.php                  |   78 +-
 templates/settings/index.php                  |    8 +-
 templates/settings/personal.php               |   77 +-
 26 files changed, 5695 insertions(+), 2658 deletions(-)
 create mode 100644 lib/Activity/ArchivesProcessed.php
 create mode 100644 lib/Activity/ArchivesProcessedFilter.php
 create mode 100644 lib/Activity/Provider.php
 create mode 100644 lib/AppInfo/Application.php
 create mode 100644 lib/BackgroundJob/ArchiveProcess.php
 create mode 100644 lib/BackgroundJob/IndexationProcess.php
 create mode 100644 lib/Migration/Version030101Date20210809040000.php
 create mode 100644 lib/Notification/Notifier.php

diff --git a/appinfo/info.xml b/appinfo/info.xml
index 95a6b7f..9679bc1 100644
--- a/appinfo/info.xml
+++ b/appinfo/info.xml
@@ -5,7 +5,7 @@
     <name>Bulletins</name>
     <summary>Dématérialisation des bulletins de paie</summary>
     <description><![CDATA[Dématérialisation des bulletins de paie]]></description>
-    <version>3.0.1</version>
+    <version>3.1.1</version>
     <licence>agpl</licence>
     <author mail="support@open-dsi.fr" >Open-DSI</author>
     <namespace>Dematpayslip</namespace>
@@ -26,4 +26,16 @@
             <route>dematpayslip.page.index</route>
         </navigation>
     </navigations>
+    <background-jobs>
+        <job>OCA\Dematpayslip\BackgroundJob\IndexationProcess</job>
+        <job>OCA\Dematpayslip\BackgroundJob\ArchiveProcess</job>
+    </background-jobs>
+    <activity>
+        <settings>
+            <setting>OCA\Dematpayslip\Activity\ArchivesProcessed</setting>
+        </settings>
+        <providers>
+            <provider>OCA\Dematpayslip\Activity\Provider</provider>
+        </providers>
+    </activity>
 </info>
diff --git a/js/script.js b/js/script.js
index caa4702..b175305 100644
--- a/js/script.js
+++ b/js/script.js
@@ -58,7 +58,7 @@ jQuery(document).ready(function(){
     if (paramStepStatus === 0) {
         buttons.push({
             'id': 'btn_create',
-            'text': 'Archiver',
+            'text': 'Traiter',
             'action': function() {
                 jQuery('#demmatpayslip_archive_action').val('create');
                 jQuery('#demmatpayslip_archive_action_form').submit();
@@ -66,7 +66,7 @@ jQuery(document).ready(function(){
         });
         buttons.push({
             'id': 'btn_create_all',
-            'text': 'Tout archiver',
+            'text': 'Tout traiter',
             'action': function() {
                 jQuery('#demmatpayslip_archive_action').val('create_all');
                 jQuery('#demmatpayslip_archive_action_form').submit();
@@ -74,7 +74,7 @@ jQuery(document).ready(function(){
         });
         buttons.push({
             'id': 'btn_delete',
-            'text': 'Ne pas archiver',
+            'text': 'Enlever du traitement',
             'action': function() {
                 jQuery('#demmatpayslip_archive_action').val('delete');
                 jQuery('#demmatpayslip_archive_action_form').submit();
@@ -84,7 +84,7 @@ jQuery(document).ready(function(){
     if (paramStepStatus === 1) {
         buttons.push({
             'id': 'btn_run_again',
-            'text': 'Reprendre l\'archivage',
+            'text': 'Relancer le traitement',
             'action': function() {
                 jQuery('#demmatpayslip_archive_action').val('run_again');
                 jQuery('#demmatpayslip_archive_action_form').submit();
diff --git a/lib/Activity/ArchivesProcessed.php b/lib/Activity/ArchivesProcessed.php
new file mode 100644
index 0000000..3f29a13
--- /dev/null
+++ b/lib/Activity/ArchivesProcessed.php
@@ -0,0 +1,99 @@
+<?php
+/**
+ * @copyright Copyright (c) 2016 Joas Schilling <coding@schilljs.com>
+ *
+ * @author Joas Schilling <coding@schilljs.com>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\Dematpayslip\Activity;
+
+
+use OCP\Activity\ISetting;
+use OCP\IL10N;
+
+class ArchivesProcessed implements ISetting {
+
+	/** @var IL10N */
+	protected $l;
+
+	/**
+	 * @param IL10N $l
+	 */
+	public function __construct(IL10N $l) {
+		$this->l = $l;
+	}
+
+	/**
+	 * @return string Lowercase a-z and underscore only identifier
+	 * @since 11.0.0
+	 */
+	public function getIdentifier() {
+		return 'job_processed';
+	}
+
+	/**
+	 * @return string A translated string
+	 * @since 11.0.0
+	 */
+	public function getName() {
+		return $this->l->t('Indexation/Archivage terminé');
+	}
+
+	/**
+	 * @return int whether the filter should be rather on the top or bottom of
+	 * the admin section. The filters are arranged in ascending order of the
+	 * priority values. It is required to return a value between 0 and 100.
+	 * @since 11.0.0
+	 */
+	public function getPriority() {
+		return 1;
+	}
+
+	/**
+	 * @return bool True when the option can be changed for the stream
+	 * @since 11.0.0
+	 */
+	public function canChangeStream() {
+		return true;
+	}
+
+	/**
+	 * @return bool True when the option can be changed for the stream
+	 * @since 11.0.0
+	 */
+	public function isDefaultEnabledStream() {
+		return true;
+	}
+
+	/**
+	 * @return bool True when the option can be changed for the mail
+	 * @since 11.0.0
+	 */
+	public function canChangeMail() {
+		return true;
+	}
+
+	/**
+	 * @return bool True when the option can be changed for the stream
+	 * @since 11.0.0
+	 */
+	public function isDefaultEnabledMail() {
+		return false;
+	}
+}
diff --git a/lib/Activity/ArchivesProcessedFilter.php b/lib/Activity/ArchivesProcessedFilter.php
new file mode 100644
index 0000000..7cf7c2a
--- /dev/null
+++ b/lib/Activity/ArchivesProcessedFilter.php
@@ -0,0 +1,98 @@
+<?php
+/**
+ * @copyright Copyright (c) 2016 Joas Schilling <coding@schilljs.com>
+ *
+ * @author Joas Schilling <coding@schilljs.com>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\Dematpayslip\Activity\Filter;
+
+
+use OCP\Activity\IFilter;
+use OCP\IL10N;
+use OCP\IURLGenerator;
+
+class ArchivesProcessed implements IFilter {
+
+	/** @var IL10N */
+	protected $l;
+
+	/** @var IURLGenerator */
+	protected $url;
+
+	/**
+	 * @param IL10N $l
+	 * @param IURLGenerator $url
+	 */
+	public function __construct(IL10N $l, IURLGenerator $url) {
+		$this->l = $l;
+		$this->url = $url;
+	}
+
+	/**
+	 * @return string Lowercase a-z only identifier
+	 * @since 11.0.0
+	 */
+	public function getIdentifier() {
+		return 'dematpayslip';
+	}
+
+	/**
+	 * @return string A translated string
+	 * @since 11.0.0
+	 */
+	public function getName() {
+		return $this->l->t('Archives processed');
+	}
+
+	/**
+	 * @return int
+	 * @since 11.0.0
+	 */
+	public function getPriority() {
+		return 30;
+	}
+
+	/**
+	 * @return string Full URL to an icon, empty string when none is given
+	 * @since 11.0.0
+	 */
+	public function getIcon() {
+		return '';
+	}
+
+	/**
+	 * @param string[] $types
+	 * @return string[] An array of allowed apps from which activities should be displayed
+	 * @since 11.0.0
+	 */
+	public function filterTypes(array $types) {
+		return array_intersect([
+			'dematpayslip',
+		], $types);
+	}
+
+	/**
+	 * @return string[] An array of allowed apps from which activities should be displayed
+	 * @since 11.0.0
+	 */
+	public function allowedApps() {
+		return ['dematpayslip'];
+	}
+}
diff --git a/lib/Activity/Provider.php b/lib/Activity/Provider.php
new file mode 100644
index 0000000..1d5c2df
--- /dev/null
+++ b/lib/Activity/Provider.php
@@ -0,0 +1,128 @@
+<?php
+
+namespace OCA\Dematpayslip\Activity;
+
+use OCP\Activity\IEvent;
+use OCP\Activity\IEventMerger;
+use OCP\Activity\IManager;
+use OCP\Activity\IProvider;
+use OCP\IL10N;
+use OCP\IURLGenerator;
+use OCP\IUser;
+use OCP\IUserManager;
+use OCP\L10N\IFactory;
+
+class Provider implements IProvider {
+
+	/** @var IFactory */
+	protected $languageFactory;
+
+	/** @var IL10N */
+	protected $l;
+
+	/** @var IURLGenerator */
+	protected $url;
+
+	/** @var IManager */
+	protected $activityManager;
+
+	/** @var IUserManager */
+	protected $userManager;
+
+	/** @var IEventMerger */
+	protected $eventMerger;
+
+	/** @var array */
+	protected $displayNames = [];
+
+	/** @var string */
+	protected $lastType = '';
+
+	const SUBJECT_ARCHIVES_PROCESSED = 'job_processed';
+	
+	/**
+	 * @param IFactory $languageFactory
+	 * @param IURLGenerator $url
+	 * @param IManager $activityManager
+	 * @param IUserManager $userManager
+	 * @param IEventMerger $eventMerger
+	 */
+	public function __construct(IFactory $languageFactory, IURLGenerator $url, IManager $activityManager, IUserManager $userManager, IEventMerger $eventMerger) {
+		$this->languageFactory = $languageFactory;
+		$this->url = $url;
+		$this->activityManager = $activityManager;
+		$this->userManager = $userManager;
+		$this->eventMerger = $eventMerger;
+	}
+
+	/**
+	 * @param string $language
+	 * @param IEvent $event
+	 * @param IEvent|null $previousEvent
+	 * @return IEvent
+	 * @throws \InvalidArgumentException
+	 * @since 11.0.0
+	 */
+	public function parse($language, IEvent $event, IEvent $previousEvent = null) {
+		if ($event->getApp() !== 'dematpayslip') {
+			throw new \InvalidArgumentException();
+		}
+
+		$this->l = $this->languageFactory->get('dematpayslip', $language);
+
+		return $this->parseLongVersion($event, $previousEvent);
+	}
+
+	/**
+	 * @param IEvent $event
+	 * @param IEvent $previousEvent
+	 * @return IEvent
+	 * @throws \InvalidArgumentException
+	 * @since 11.0.0
+	 */
+	public function parseLongVersion(IEvent $event, IEvent $previousEvent = null) {
+		$parsedParameters = $this->getParsedParameters($event);
+        $subject = 'Opération terminée : {nb_success}/{nb_total} bulletins de paie ont été traités';
+
+//        if ($this->activityManager->getRequirePNG()) {
+//            $event->setIcon($this->url->getAbsoluteURL($this->url->imagePath('dematpayslip', 'folder.png')));
+//        } else {
+//            $event->setIcon($this->url->getAbsoluteURL($this->url->imagePath('dematpayslip', 'folder.svg')));
+//        }
+
+		$this->setSubjects($event, $subject, $parsedParameters);
+
+		return $event;
+	}
+
+	/**
+	 * @param IEvent $event
+	 * @param string $subject
+	 * @param array $parameters
+	 * @throws \InvalidArgumentException
+	 */
+	protected function setSubjects(IEvent $event, $subject, array $parameters) {
+		$placeholders = $replacements = [];
+		foreach ($parameters as $placeholder => $parameter) {
+			$placeholders[] = '{' . $placeholder . '}';
+			$replacements[] = $parameter;
+		}
+
+		$event->setParsedSubject(str_replace($placeholders, $replacements, $subject));
+	}
+
+	protected function getParsedParameters(IEvent $event) {
+		$subject = $event->getSubject();
+		$parameters = $event->getSubjectParameters();
+
+		switch ($subject) {
+			case self::SUBJECT_ARCHIVES_PROCESSED:
+				return [
+					'nb_success' => $parameters[0],
+					'nb_total' => $parameters[1],
+				];
+			    break;
+		}
+		return [];
+	}
+}
diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php
new file mode 100644
index 0000000..60d3152
--- /dev/null
+++ b/lib/AppInfo/Application.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * @copyright Copyright (c) 2016, Joas Schilling <coding@schilljs.com>
+ *
+ * @author Joas Schilling <coding@schilljs.com>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\Dematpayslip\AppInfo;
+
+use OCA\Dematpayslip\Notification\Notifier;
+use OCP\AppFramework\App;
+use OCP\AppFramework\Bootstrap\IBootContext;
+use OCP\AppFramework\Bootstrap\IBootstrap;
+use OCP\AppFramework\Bootstrap\IRegistrationContext;
+
+class Application extends App implements IBootstrap {
+
+    const APP_ID = 'dematpayslip';
+
+    public function __construct () {
+        parent::__construct(self::APP_ID);
+    }
+
+    public function register(IRegistrationContext $context): void {
+
+    }
+
+    public function boot(IBootContext $context): void {
+        $this->registerNotifier();
+    }
+
+    public function registerNotifier() {
+        $server = $this->getContainer()->getServer();
+        $server->getNotificationManager()->registerNotifierService(Notifier::class);
+    }
+}
diff --git a/lib/BackgroundJob/ArchiveProcess.php b/lib/BackgroundJob/ArchiveProcess.php
new file mode 100644
index 0000000..59bd7d4
--- /dev/null
+++ b/lib/BackgroundJob/ArchiveProcess.php
@@ -0,0 +1,322 @@
+<?php
+
+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\Notification\IManager as INotificationManager;
+use OC\URLGenerator;
+use OCP\IUserManager;
+use DateTime;
+use DateTimeZone;
+use Exception;
+
+use OCA\Dematpayslip\Db\DematpayslipArchive;
+use OCA\Dematpayslip\Db\DematpayslipArchiveMapper;
+use OCA\Dematpayslip\Db\DematpayslipUserMapper;
+
+
+/**
+ * Clean up all file locks that are expired for the DB file locking provider
+ */
+class ArchiveProcess extends TimedJob {
+    /**
+     * Const log levels
+     */
+    const LOG_SUCCESS = 0;
+    const LOG_DEBUG = 1;
+    const LOG_WARNING = 2;
+    const LOG_ERROR = 3;
+
+    /**
+     * Const log modes
+     */
+    const LOG_MODE_NONE = -1;
+    const LOG_MODE_FILE = 0;
+    const LOG_MODE_SCREEN = 1;
+
+    /**
+     * @var IManager activity manager
+     */
+    private $_activityManager;
+
+    /**
+     * @var string app name
+     */
+    private $_appName;
+
+    /**
+     * @var IConfig config
+     */
+    private $_config;
+
+    /**
+     * @var IDBConnection database connection
+     */
+    private $_dbConnection;
+
+    /**
+     * @var DematpayslipArchiveMapper dematpayslip folder mapper
+     */
+    private $_dematpayslipArchiveMapper;
+
+    /**
+     * @var DematpayslipUserMapper
+     */
+    private $_dematpayslipUserMapper;
+
+    /**
+     * @var IL10N lang
+     */
+    private $_l10n;
+
+    /**
+     * @var INotificationManager notification manager
+     */
+    private $_notificationManager;
+
+    /**
+     * @var IRootFolder root folder
+     */
+    private $_rootFolder;
+
+    /**
+     * @var IUserManager user manager
+     */
+    private $_userManager;
+
+    /**
+     * @var ITimeFactory time factory
+     */
+    private $_timeFactory;
+
+    /**
+     * @var DateTimeZone time zone
+     */
+    private $_timeZone;
+
+    /**
+     * @var int Log level
+     */
+    private $_logLevel;
+
+    /**
+     * @var int Log mode
+     */
+    private $_logMode;
+
+    /**
+     * @var resource Log file
+     */
+    private $_logFile;
+
+    /**
+     * Log
+     *
+     * @param   string  $msg            Log message
+     * @param   int     $level          [=1] Log level (Debug by default)
+     *
+     * @throws  Exception
+     */
+    private function _log($msg, $level = self::LOG_DEBUG) {
+        if ($this->_logMode >= self::LOG_MODE_FILE) {
+            if ($this->_logLevel <= $level || $level === self::LOG_SUCCESS) {
+                $dateTimeNow = new DateTime('now', $this->_timeZone);
+                $logLevel = '';
+                switch ($level) {
+                    case self::LOG_SUCCESS :
+                        $logLevel = 'SUCCESS';
+                        break;
+
+                    case self::LOG_DEBUG :
+                        $logLevel = 'DEBUG';
+                        break;
+
+                    case self::LOG_WARNING :
+                        $logLevel = 'WARNING';
+                        break;
+
+                    case self::LOG_ERROR :
+                        $logLevel = 'ERROR';
+                        break;
+
+                    default :
+                        break;
+                }
+
+                $logMsg = $dateTimeNow->format('Y-m-d_H:i:s') . ' [' . $logLevel . '] : ' . $msg . "\n";
+
+                if ($this->_logMode == self::LOG_MODE_FILE && $this->_logFile !== null) {
+                    fwrite($this->_logFile, $logMsg);
+                } elseif ($this->_logMode == self::LOG_MODE_SCREEN) {
+                    print $logMsg;
+                }
+            }
+        }
+    }
+
+    /**
+     * ArchiveProcess constructor.
+     *
+     * @param   IConfig                     $config                     Config
+     * @param   IDBConnection               $dbConnection               DB connection
+     * @param   IL10N                       $l10                        Lang
+     * @param   IManager                    $activityManager            Activity manager
+     * @param   INotificationManager        $notificationManager        Notification manager
+     * @param   IRootFolder                 $rootFolder                 Root folder
+     * @param   ITimeFactory                $timeFactory                Time factory
+     * @param   IUserManager                $userManager                User manager
+     * @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) {
+        //print __METHOD__ . "\n";
+
+        $this->_appName = 'dematpayslip';
+        $this->_config = $config;
+        $this->_dbConnection = $dbConnection;
+        $this->_dematpayslipArchiveMapper = $dematpayslipArchiveMapper;
+        $this->_dematpayslipUserMapper = $dematpayslipUserMapper;
+        $this->_l10n = $l10n;
+        $this->_activityManager = $activityManager;
+        $this->_notificationManager = $notificationManager;
+        $this->_rootFolder = $rootFolder;
+        $this->_timeFactory = $timeFactory;
+        $this->_userManager = $userManager;
+
+        //$timeZoneDefaultName = 'UTC';
+        $timeZoneDefaultName = 'Europe/Paris';
+        $timeZoneName = $this->_config->getAppValue($this->_appName, $this->_appName . '_archive_cron_time_zone', $timeZoneDefaultName);
+        $this->_timeZone = new DateTimeZone($timeZoneName);
+
+        // run once by interval
+        $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);
+	}
+
+    /**
+     * Run
+     *
+     * @param   mixed   $arguments  Arguments
+     *
+     * @throws  Exception
+     */
+	protected function run($arguments) {
+        try {
+            $dateTimeNow = new DateTime('now', $this->_timeZone);
+            print __METHOD__ . ' : cron run start_time=' . $dateTimeNow->getTimestamp() . ", date=" . $dateTimeNow->format('d/m/Y H:i:s') . "\n";
+
+            // log file
+            $logLevel    = $this->_config->getAppValue($this->_appName, $this->_appName . '_archive_cron_log_level', self::LOG_DEBUG);
+            //$logLevel    = $this->_config->getAppValue($this->_appName, $this->_appName . '_archive_cron_log_level', self::LOG_ERROR);
+            $logMode     = $this->_config->getAppValue($this->_appName, $this->_appName . '_archive_cron_log_mode', self::LOG_MODE_FILE);
+            $logFileName = $this->_config->getAppValue($this->_appName, $this->_appName . '_archive_cron_log_file_name', $this->_appName . '_archive_cron.log');
+            $logFilePath = $this->_config->getSystemValue('logfile');
+            if (empty($logFilePath)) {
+                $logDirPath = $this->_config->getSystemValue('datadirectory');
+            } else {
+                $logDirPath = dirname($this->_config->getSystemValue('logfile'));
+            }
+            $logFilePath = $logDirPath . DIRECTORY_SEPARATOR . $logFileName;
+            //print __METHOD__ . ' : level=' . $logLevel . ', mode=' . $logMode . ', file_name=' . $logFileName . ', file_path=' . $logFilePath . "\n";
+
+            $logFile = fopen($logFilePath, 'a+');
+            if ($logFile) {
+                //$dateTimeNow = new DateTime('now', $this->_timeZone);
+                //print __METHOD__ . ' : job start_time=' . $dateTimeNow->getTimestamp() . "\n";
+
+                $this->_logFile = $logFile;
+                $this->_logLevel = $logLevel;
+                $this->_logMode = $logMode;
+
+                // process list
+                $userId = $this->_config->getAppValue($this->_appName, 'user_id', 'demat');
+                $processMsgList = array(
+                    'error'   => array(),
+                    'success' => array(),
+                );
+                $this->_log('Archives process : Begin');
+                $dematpayslipArchiveList = $this->_dematpayslipArchiveMapper->findAllByOperationProgress(DematpayslipArchive::OPERATION_ARCHIVE);
+                if (!empty($dematpayslipArchiveList)) {
+                    foreach ($dematpayslipArchiveList as $dematpayslipArchive) {
+                        // only for operation ask
+                        $operationAsk = $dematpayslipArchive->getOperationAsk();
+                        $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);
+
+                            if ($result < 0) {
+                                $msgErrorList = $dematpayslipArchive->getMsgList('error');
+                                $this->_log('Error : ' . explode("\r\n", $msgErrorList), self::LOG_ERROR);
+                                $processMsgList['error'][] = $dematpayslipArchive;
+                                $dematpayslipArchive->setError(1);
+                                $this->_dematpayslipArchiveMapper->update($dematpayslipArchive);
+                            } else {
+                                $msgSuccessList = $dematpayslipArchive->getMsgList('success');
+                                if (!empty($msgSuccessList)) {
+                                    $this->_log('Success : ' . explode("\r\n", $msgSuccessList), self::LOG_SUCCESS);
+                                    $processMsgList['success'][] = $dematpayslipArchive;
+                                    $dematpayslipArchive->setError(0);
+                                    $dematpayslipArchive->setOrientationProgress(DematpayslipArchive::OPERATION_FINISHED);
+                                    $this->_dematpayslipArchiveMapper->update($dematpayslipArchive);
+                                }
+                            }
+                        }
+                    }
+
+                    $nbError = count($processMsgList['error']);
+                    $nbSuccess = count($processMsgList['success']);
+                    if ($nbError > 0 || $nbSuccess > 0) {
+                        $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);
+                        }
+                    }
+                }
+                $this->_log('Archives process : End');
+
+                //$dateTimeNow = new DateTime('now', $this->_timeZone);
+                //print __METHOD__ . ' : job end_time=' . $dateTimeNow->getTimestamp() . "\n";
+                fclose($logFile);
+            }
+
+            $dateTimeNow = new DateTime('now', $this->_timeZone);
+            print __METHOD__ . ' : cron run end_time=' . $dateTimeNow->getTimestamp() . ", date=" . $dateTimeNow->format("d/m/Y H:i:s") . "\n";
+        } catch (Exception $e) {
+            print 'Exception ' . __METHOD__ . ' : error=' . $e->getMessage();
+        }
+	}
+}
diff --git a/lib/BackgroundJob/IndexationProcess.php b/lib/BackgroundJob/IndexationProcess.php
new file mode 100644
index 0000000..8e84985
--- /dev/null
+++ b/lib/BackgroundJob/IndexationProcess.php
@@ -0,0 +1,345 @@
+<?php
+
+namespace OCA\Dematpayslip\BackgroundJob;
+
+use OC\BackgroundJob\TimedJob;
+use OCA\Dematpayslip\Db\DematpayslipProcess;
+use OCP\AppFramework\Utility\ITimeFactory;
+use OCP\Files\IRootFolder;
+use OCP\Activity\IManager;
+use OCP\IConfig;
+use OCP\IDBConnection;
+use OCP\IL10N;
+use OCP\Notification\IManager as INotificationManager;
+use OCP\Share\IManager as IShareManager;
+use OCP\IUserManager;
+
+use DateTime;
+use DateTimeZone;
+use Exception;
+
+use OCA\Dematpayslip\Db\DematpayslipArchive;
+use OCA\Dematpayslip\Db\DematpayslipArchiveMapper;
+use OCA\Dematpayslip\Db\DematpayslipProcessMapper;
+use OCA\Dematpayslip\Db\DematpayslipProcessSkipMapper;
+use OCA\Dematpayslip\Db\DematpayslipUserMapper;
+
+
+/**
+ * Clean up all file locks that are expired for the DB file locking provider
+ */
+class IndexationProcess extends TimedJob {
+    /**
+     * Const log levels
+     */
+    const LOG_SUCCESS = 0;
+    const LOG_DEBUG = 1;
+    const LOG_WARNING = 2;
+    const LOG_ERROR = 3;
+
+    /**
+     * Const log modes
+     */
+    const LOG_MODE_NONE = -1;
+    const LOG_MODE_FILE = 0;
+    const LOG_MODE_SCREEN = 1;
+
+    /**
+     * @var string app name
+     */
+    private $_appName;
+
+    /**
+     * @var IConfig config
+     */
+    private $_config;
+
+    /**
+     * @var IDBConnection database connection
+     */
+    private $_dbConnection;
+
+    /**
+     * @var IL10N lang
+     */
+    private $_l10n;
+
+    /**
+     * @var IManager activity manager
+     */
+    private $_activityManager;
+
+    /**
+     * @var INotificationManager notification manager
+     */
+    private $_notificationManager;
+
+    /**
+     * @var IRootFolder root folder
+     */
+    private $_rootFolder;
+
+    /**
+     * @var IShareManager share manager
+     */
+    private $_shareManager;
+
+    /**
+     * @var ITimeFactory time factory
+     */
+    private $_timeFactory;
+
+    /**
+     * @var DateTimeZone time zone
+     */
+    private $_timeZone;
+
+    /**
+     * @var IUserManager user manager
+     */
+    private $_userManager;
+
+
+    /**
+     * @var DematpayslipArchiveMapper archive mapper
+     */
+    private $_dematpayslipArchiveMapper;
+
+    /**
+     * @var DematpayslipProcessMapper process mapper
+     */
+    private $_dematpayslipProcessMapper;
+
+    /**
+     * @var DematpayslipProcessSkipMapper process skip mapper
+     */
+    private $_dematpayslipProcessSkipMapper;
+
+    /**
+     * @var DematpayslipUserMapper user mapper
+     */
+    private $_dematpayslipUserMapper;
+
+    /**
+     * @var int log level
+     */
+    private $_logLevel;
+
+    /**
+     * @var int log mode
+     */
+    private $_logMode;
+
+    /**
+     * @var resource log file
+     */
+    private $_logFile;
+
+    /**
+     * Log
+     *
+     * @param   string  $msg            Log message
+     * @param   int     $level          [=1] Log level (Debug by default)
+     *
+     * @throws  Exception
+     */
+    private function _log($msg, $level = self::LOG_DEBUG) {
+        if ($this->_logMode >= self::LOG_MODE_FILE) {
+            if ($this->_logLevel <= $level || $level === self::LOG_SUCCESS) {
+                $dateTimeNow = new DateTime('now', $this->_timeZone);
+                $logLevel = '';
+                switch ($level) {
+                    case self::LOG_SUCCESS :
+                        $logLevel = 'SUCCESS';
+                        break;
+
+                    case self::LOG_DEBUG :
+                        $logLevel = 'DEBUG';
+                        break;
+
+                    case self::LOG_WARNING :
+                        $logLevel = 'WARNING';
+                        break;
+
+                    case self::LOG_ERROR :
+                        $logLevel = 'ERROR';
+                        break;
+
+                    default :
+                        break;
+                }
+
+                $logMsg = $dateTimeNow->format('Y-m-d_H:i:s') . ' [' . $logLevel . '] : ' . $msg . "\n";
+
+                if ($this->_logMode == self::LOG_MODE_FILE && $this->_logFile !== null) {
+                    fwrite($this->_logFile, $logMsg);
+                } elseif ($this->_logMode == self::LOG_MODE_SCREEN) {
+                    print $logMsg;
+                }
+            }
+        }
+    }
+
+    /**
+     * IndexationProcess constructor.
+     *
+     * @param   IConfig                         $config                         Config
+     * @param   IDBConnection                   $dbConnection                   DB connection
+     * @param   IL10N                           $l10n                           Lang
+     * @param   IManager                        $activityManager                Activity manager
+     * @param   IRootFolder                     $rootFolder                     Root folder
+     * @param   INotificationManager            $notificationManager            Notification manager
+     * @param   IShareManager                   $shareManager                   Share manager
+     * @param   ITimeFactory                    $timeFactory                    Time factory
+     * @param   IUserManager                    $userManager                    User manager
+     * @param   DematpayslipArchiveMapper       $dematpayslipArchiveMapper      Archive mapper
+     * @param   DematpayslipProcessMapper       $dematpayslipProcessMapper      Process mapper
+     * @param   DematpayslipProcessSkipMapper   $dematpayslipProcessSkipMapper  Process skip mapper
+     * @param   DematpayslipUserMapper          $dematpayslipUserMapper         User mapper
+     */
+    public function __construct(IConfig $config, IDBConnection $dbConnection, IL10N $l10n, IManager $activityManager, INotificationManager $notificationManager, IRootFolder $rootFolder, IShareManager $shareManager, ITimeFactory $timeFactory, IUserManager $userManager, DematpayslipArchiveMapper $dematpayslipArchiveMapper, DematpayslipProcessMapper $dematpayslipProcessMapper, DematpayslipProcessSkipMapper $dematpayslipProcessSkipMapper, DematpayslipUserMapper $dematpayslipUserMapper) {
+        //print __METHOD__ . "\n";
+
+        $this->_appName = 'dematpayslip';
+        $this->_activityManager = $activityManager;
+        $this->_config = $config;
+        $this->_dbConnection = $dbConnection;
+        $this->_l10n = $l10n;
+        $this->_notificationManager = $notificationManager;
+        $this->_rootFolder = $rootFolder;
+        $this->_shareManager = $shareManager;
+        $this->_timeFactory = $timeFactory;
+        $this->_userManager = $userManager;
+
+        $this->_dematpayslipArchiveMapper = $dematpayslipArchiveMapper;
+        $this->_dematpayslipProcessMapper = $dematpayslipProcessMapper;
+        $this->_dematpayslipProcessSkipMapper = $dematpayslipProcessSkipMapper;
+        $this->_dematpayslipUserMapper = $dematpayslipUserMapper;
+
+        //$timeZoneDefaultName = 'UTC';
+        $timeZoneDefaultName = 'Europe/Paris';
+        $timeZoneName = $this->_config->getAppValue($this->_appName, $this->_appName . '_indexation_cron_time_zone', $timeZoneDefaultName);
+        $this->_timeZone = new DateTimeZone($timeZoneName);
+
+        // run once by interval
+        $taskDefaultInterval = 60;
+        //$taskDefaultInterval = 3600; // 1h
+        $taskInterval = intval($this->_config->getAppValue($this->_appName,$this->_appName . '_indexation_cron_interval', $taskDefaultInterval));
+        //print __METHOD__ . ' : time_zone_name=' . $timeZoneName . ', cron_interval=' . $taskInterval . "\n";
+        $this->setInterval($taskInterval);
+	}
+
+    /**
+     * Run
+     *
+     * @param   mixed   $arguments  Arguments
+     *
+     * @throws  Exception
+     */
+	protected function run($arguments) {
+        try {
+            $dateTimeNow = new DateTime('now', $this->_timeZone);
+            print __METHOD__ . ' : cron run start_time=' . $dateTimeNow->getTimestamp() . ", date=" . $dateTimeNow->format('d/m/Y H:i:s') . "\n";
+
+            // log file
+            $logLevel    = $this->_config->getAppValue($this->_appName, $this->_appName . '_indexation_cron_log_level', self::LOG_DEBUG);
+            //$logLevel    = $this->_config->getAppValue($this->_appName, $this->_appName . '_indexation_cron_log_level', self::LOG_ERROR);
+            //$logMode     = $this->_config->getAppValue($this->_appName, $this->_appName . '_indexation_cron_log_mode', self::LOG_MODE_SCREEN);
+            $logMode     = $this->_config->getAppValue($this->_appName, $this->_appName . '_indexation_cron_log_mode', self::LOG_MODE_FILE);
+            $logFileName = $this->_config->getAppValue($this->_appName, $this->_appName . '_indexation_cron_log_file_name', $this->_appName . '_indexation_cron.log');
+            $logFilePath = $this->_config->getSystemValue('logfile');
+            if (empty($logFilePath)) {
+                $logDirPath = $this->_config->getSystemValue('datadirectory');
+            } else {
+                $logDirPath = dirname($this->_config->getSystemValue('logfile'));
+            }
+            $logFilePath = $logDirPath . DIRECTORY_SEPARATOR . $logFileName;
+            //print __METHOD__ . ' : level=' . $logLevel . ', mode=' . $logMode . ', file_name=' . $logFileName . ', file_path=' . $logFilePath . "\n";
+
+            $logFile = fopen($logFilePath, 'a+');
+            if ($logFile) {
+                //$dateTimeNow = new DateTime('now', $this->_timeZone);
+                //print __METHOD__ . ' : job start_time=' . $dateTimeNow->getTimestamp() . "\n";
+
+                $this->_logFile = $logFile;
+                $this->_logLevel = $logLevel;
+                $this->_logMode = $logMode;
+
+                // process list
+                $userId = $this->_config->getAppValue($this->_appName, 'user_id', 'demat');
+                $processMsgList = array(
+                    'error'   => array(),
+                    'success' => array(),
+                );
+                $this->_log('Indexation process : Begin');
+
+                // find process in indexation step
+                $processList = $this->_dematpayslipProcessMapper->findAll();
+                if (!empty($processList)) {
+                    $process = current($processList);
+                    if ($process->getPhase() == DematpayslipProcess::PHASE_ID_INDEXATION) {
+                        $this->_log('Indexation process : Load');
+                        $process->load($this->_appName, $this->_config, $this->_dbConnection, $this->_l10n, $this->_rootFolder, $this->_shareManager, $this->_userManager, $userId, $this->_dematpayslipProcessMapper, $this->_dematpayslipProcessSkipMapper, $this->_dematpayslipUserMapper, $this->_timeZone);
+
+                        $this->_log('Indexation process : Indexation Begin');
+                        $result = $process->indexation($processMsgList);
+                        $this->_log('Indexation process : Indexation End');
+
+                        if ($result < 0) {
+                            $this->_log('Indexation process : Error : ', self::LOG_ERROR);
+                            $msgList = $process->getMsgList();
+                            if (!empty($msgList['error'])) {
+                                foreach ($msgList['error'] as $msgError) {
+                                    $this->_log("\n" . $msgError, self::LOG_ERROR);
+                                }
+                            }
+                        } else {
+                            $nbError = count($processMsgList['error']);
+                            $nbSuccess = count($processMsgList['success']);
+                            if ($nbError > 0 || $nbSuccess > 0) {
+                                $nbTotal = $nbError + $nbSuccess;
+                                $dateTimeNow = new DateTime('now', $this->_timeZone);
+
+                                // activity
+//                                $this->_log('Activity add : indexation 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 : indexation 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('Indexation process : End');
+
+                //$dateTimeNow = new DateTime('now', $this->_timeZone);
+                //print __METHOD__ . ' : job end_time=' . $dateTimeNow->getTimestamp() . "\n";
+                fclose($logFile);
+            }
+
+            $dateTimeNow = new DateTime('now', $this->_timeZone);
+            print __METHOD__ . ' : cron run end_time=' . $dateTimeNow->getTimestamp() . ", date=" . $dateTimeNow->format("d/m/Y H:i:s") . "\n";
+        } catch (Exception $e) {
+            print 'Exception ' . __METHOD__ . ' : error=' . $e->getMessage();
+        }
+	}
+}
diff --git a/lib/Controller/PageController.php b/lib/Controller/PageController.php
index 7d8e9c5..5e907c0 100644
--- a/lib/Controller/PageController.php
+++ b/lib/Controller/PageController.php
@@ -1,426 +1,258 @@
 <?php
+
 namespace OCA\Dematpayslip\Controller;
 
-use OC\Files\Filesystem;
-use OCP\Files\NotFoundException;
 use OCP\IConfig;
+use OCP\IDateTimeZone;
+use OCP\IDBConnection;
 use OCP\IL10N;
+use OCP\Files\IRootFolder;
+use OCP\Share\IManager as IShareManager;
 use OCP\IURLGenerator;
+use OCP\IUserManager;
 use OCP\IRequest;
 use OCP\AppFramework\Http\TemplateResponse;
 use OCP\AppFramework\Controller;
 
-use OC;
-use OC_App;
-use DateTime;
+use DateTimeZone;
 use Exception;
-use OCP\Files\Folder;
+
 use OCA\Dematpayslip\Db\DematpayslipArchive;
 use OCA\Dematpayslip\Db\DematpayslipArchiveMapper;
 use OCA\Dematpayslip\Db\DematpayslipProcess;
 use OCA\Dematpayslip\Db\DematpayslipProcessMapper;
-use OCA\Dematpayslip\Db\DematpayslipProcessSkip;
 use OCA\Dematpayslip\Db\DematpayslipProcessSkipMapper;
-use OCA\Dematpayslip\Db\DematpayslipUser;
 use OCA\Dematpayslip\Db\DematpayslipUserMapper;
 
-// Pastell
-use OCA\Pastell\Db\PastellConfigFlowMapper;
-use OCA\Pastell\PastellAPI;
-
 class PageController extends Controller {
-    const LOG_SUCCESS = 0;
-    const LOG_DEBUG   = 1;
-    const LOG_WARNING = 2;
-    const LOG_ERROR   = 3;
-
-    const PROCESS_TIME_UNLOCK = 60; // seconds (max execution time)
-
-    const PHASE_ID_UPLOAD = 0;
-    const PHASE_ID_CHECK  = 1;
-    const PHASE_ID_INDEXATION = 2;
-
-    const USER_REMOVE_UNKNOWN = 1; // remove unknown users from list (FIX SAML)
 
     /**
-     * @var array Payslip PDF search field list
+     * @var IConfig
      */
-    private $_payslipPDFSearchFieldList = array(
-        'siret'     => array(3),
-        'matricule' => array(10),
-        'fullname'  => array(9),
-        'zip_city'  => array(19, 20),
-    );
-//    private $_payslipPDFSearchFieldList = array(
-//        'siret'     => array(4, 5),
-//        'matricule' => array(20, 21),
-//        'fullname'  => array(19, 20),
-//        'zip_city'  => array(34, 35, 36, 37),
-//    );
+    private $_config;
 
     /**
-     * @var string CSV delimiter
+     * @var IDateTimeZone
      */
-    private $_csvDelimiter = ';';
+    private $_dateTimeZone;
 
     /**
-     * @var string CSV enclosure
+     * @var IDBConnection
      */
-    private $_csvEnclosure = '"';
+    private $_dbConnection;
 
     /**
-     * @var int CSV length
+     * @var IL10N
      */
-    private $_csvLength = 0;
+    private $_l10n;
 
     /**
-     * @var string CSV encode source
+     * @var IRootFolder
      */
-    private $_csvEncodeFrom = 'UTF-8';
+    private $_rootFolder;
 
     /**
-     * @var string CSV encode destination
+     * @var IShareManager
      */
-    private $_csvEncodeTo = 'UTF-8';
+    private $_shareManager;
 
     /**
-     * @var resource handler Log file
+     * @var IURLGenerator
      */
-    private $_logFile = null;
+    private $_urlGenerator;
 
     /**
-     * @var int Log level
+     * @var IUserManager
      */
-    private $_logLevel = self::LOG_DEBUG;
+    private $_userManager;
 
     /**
-     * @var bool Fail on first error
+     * @var string user id
      */
-    private $_processFailOnFirstError = true;
-
-    /** @var IConfig */
-    private $config;
+    private $_userId;
 
-    /** @var IL10N */
-    private $l;
-
-    /** @var IURLGenerator */
-    private $_urlGenerator;
-
-    /** @var string User Id */
-    private $userId;
+    /**
+     * @var array dematpayslip config
+     */
+    private $_dematpayslipConfigList;
 
-    /**@var array dematpayslip config */
-    private $_dematpayslipConfigList = array();
+    /**
+     * @var DematpayslipProcess
+     */
+    private $_dematpaylsipProcess;
 
-    /** @var DematpayslipProcessMapper */
+    /**
+     * @var DematpayslipProcessMapper
+     */
 	private $_dematpayslipProcessMapper;
-    private $_process;
-    private $_canCancelProcess = false;
-
-    /** @var string folder path */
-    private $_uploadDirUserPath;
-    private $_uploadDirFullPath;
-    private $_checkDirUserPath;
-    private $_checkDirFullPath;
-    private $_reportDirUserPath;
-    private $_reportDirFullPath;
-    private $_exportDirUserPath;
-    private $_exportDirFullPath;
-    private $_tmpDirUserPath;
-    private $_tmpDirFullPath;
 
-    /** @var string payslip no index dir */
-    private $_payslipNoIndexDir = 'BulletinsNoIndex';
-
-    /** @var DematpayslipProcessSkipMapper */
+    /**
+     * @var DematpayslipProcessSkipMapper
+     */
     private $_dematpayslipProcessSkipMapper;
 
-    /** @var DematpayslipUserMapper */
+    /**
+     * @var DematpayslipUserMapper
+     */
     private $_dematpayslipUserMapper;
 
-    // messages
-    private $_msgList = array(
-        'error'   => array(),
-        'success' => array(),
-        'warning' => array(),
-    );
-
-    /** @var array DematpayslipUser */
-    private $_dematpayslipUserList;
-
-    /** @var array User */
-    private $_userList;
-
     /**
-     * Pastell app exists
-     *
-     * @var bool
+     * @var array DematpayslipUser
      */
-    private $_pastellAppExists = false;
-
+    private $_dematpayslipUserList;
 
     /**
-     * Check if payslip file has not been archived yet
-     *
-     * @param   DematpayslipArchiveMapper   $dematpayslipArchiveMapper      Archive table mapper
-     * @param   DematpayslipUser            $agentUser                      Agent user
-     * @param   string                      $startDate                      Period start date
-     * @param   string                      $endDate                        Period end date
-     * @return  mixed|DematpayslipArchive|\OCP\AppFramework\Db\Entity|null
-     *
-     * @throws  Exception
+     * @var array User
      */
-    private function _archiveCheckBeforeSave(DematpayslipArchiveMapper $dematpayslipArchiveMapper, DematpayslipUser $agentUser, $startDate, $endDate) {
-        $dematpayslipArchive = null;
-        $dematpayslipArchiveExistList = $dematpayslipArchiveMapper->findAllByAgentAndPeriod($agentUser->getSiret(), $agentUser->getMatricule(), $agentUser->getLastname(), $agentUser->getFirstname(), $startDate, $endDate);
-
-        if (empty($dematpayslipArchiveExistList)) {
-            $dematpayslipArchive = new DematpayslipArchive();
-        } elseif (count($dematpayslipArchiveExistList) === 1) {
-            if (!empty($dematpayslipArchiveExistList[0]->getPastellIdDocument())) {
-                $warningMsg = $this->l->t('Le bulletin de paie de l\'agent "' . $agentUser->getLastname() . ' ' . $agentUser->getFirstname() . '" pour la période du ' . $startDate . ' au ' . $endDate . ' est déjà en cours d\'archivage.');
-                $this->_logCsvLine($warningMsg, self::LOG_WARNING, $agentUser, $startDate, $endDate);
-                $this->_processWarningMsg($warningMsg);
-            } else {
-                $dematpayslipArchive = $dematpayslipArchiveExistList[0];
-            }
-        } else {
-            $warningMsg = $this->l->t('Plusieurs bulletins de paie de l\'agent "' . $agentUser->getLastname() . ' ' . $agentUser->getFirstname() . '" pour la période du ' . $startDate . ' au ' . $endDate . ' existent déjà.');
-            $this->_logCsvLine($warningMsg, self::LOG_WARNING, $agentUser, $startDate, $endDate);
-            $this->_processWarningMsg($warningMsg);
-        }
+    private $_userList;
 
-        return $dematpayslipArchive;
-    }
 
     /**
      * Archive process
      *
+     * @param   IDBConnection               $dbConnection                   Database connection
      * @param   DematpayslipArchiveMapper   $dematpayslipArchiveMapper      Archive table mapper
      * @param   DematpayslipArchive         $dematpayslipArchive            Archive
+     * @param   DateTimeZone                $dateTimeZone                   [=null] Date time zone
      */
-    private function _archiveProcess(DematpayslipArchiveMapper $dematpayslipArchiveMapper, DematpayslipArchive $dematpayslipArchive) {
-        $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(OC::$server->getDatabaseConnection());
-            $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->l->t('L\'archive "' . $dematpayslipArchive->getFilePath() . '" a déjà été créée.');
-            } else {
-                // 1. create document
-                if (empty($dematpayslipArchive->getPastellIdDocument())) {
-                    $nowDateTime = new DateTime('now', OC::$server->getDateTimeZone()->getTimeZone());
-                    $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', OC::$server->getDateTimeZone()->getTimeZone());
-                    $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', OC::$server->getDateTimeZone()->getTimeZone());
-                    $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', OC::$server->getDateTimeZone()->getTimeZone());
-                    $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', OC::$server->getDateTimeZone()->getTimeZone());
-                    $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', OC::$server->getDateTimeZone()->getTimeZone());
-                    $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->l->t('L\'archive "' . $dematpayslipArchive->getFilePath() . '" n\'a pas été correctement créée [status=' . $dematpayslipArchive->getStatus() .'].');
-                } else {
-                    $this->_msgList['success'][] = $this->l->t('L\'archive "' . $dematpayslipArchive->getFilePath() . '" a été créée.');
-                }
-            }
-        } catch (Exception $e) {
-            $this->_msgList['error'][] = $e->getMessage();
-        }
-    }
-
-    /**
-     * Save archive file for an agent and a period
-     *
-     * @param   DematpayslipArchiveMapper   $dematpayslipArchiveMapper  Archive table mapper
-     * @param   DematpayslipArchive         $dematpayslipArchive        Archive
-     * @param   string                      $archiveFilePath            Archive file path
-     * @param   DematpayslipUser            $agentUser                  Agent user
-     * @param   string                      $startDate                  Period start date
-     * @param   string                      $endDate                    Period end date
-     * @param   string                      $year                       Period year
-     * @param   string                      $month                      Period month
-     * @param   string                      $editionDate                Edition date
-     * @param   int                         $importTime                 Import time
-     *
-     * @throws  Exception
-     */
-    private function _archiveSaveForAgentAndPeriod(DematpayslipArchiveMapper $dematpayslipArchiveMapper, DematpayslipArchive $dematpayslipArchive, $archiveFilePath, DematpayslipUser $agentUser, $startDate, $endDate, $year, $month, $editionDate, $importTime) {
-        $nowDateTime = new DateTime('now', OC::$server->getDateTimeZone()->getTimeZone());
-
-        $archiveFile         = Filesystem::getFileInfo($archiveFilePath);
-        $archiveFileChecksum = Filesystem::hash('md5', $archiveFilePath);
-
-        $dematpayslipArchive->setIdFile($archiveFile->getId());
-        $dematpayslipArchive->setFilePath($archiveFile->getPath());
-        $dematpayslipArchive->setIdUser($agentUser->getUserId());
-        $dematpayslipArchive->setDematpayslipIdUser($agentUser->getId());
-        $dematpayslipArchive->setSiret($agentUser->getSiret());
-        $dematpayslipArchive->setMatricule($agentUser->getMatricule());
-        $dematpayslipArchive->setYear($year);
-        $dematpayslipArchive->setMonth($month);
-        $dematpayslipArchive->setLastname($agentUser->getLastname());
-        $dematpayslipArchive->setFirstname($agentUser->getFirstname());
-        $dematpayslipArchive->setStartDate($startDate);
-        $dematpayslipArchive->setEndDate($endDate);
-        $dematpayslipArchive->setEditionDate($editionDate);
-        $dematpayslipArchive->setStatus(DematpayslipArchive::STATUS_INITIALIZED);
-        $dematpayslipArchive->setStatusTime($nowDateTime->getTimestamp());
-        $dematpayslipArchive->setImportTime($importTime);
-        $dematpayslipArchive->setChecksum($archiveFileChecksum);
-
-        if (empty($dematpayslipArchive->getId())) {
-            // insert new file to archive
-            $dematpayslipArchiveMapper->insert($dematpayslipArchive);
-        } else {
-            // update file to archive
-            $dematpayslipArchiveMapper->update($dematpayslipArchive);
-        }
-    }
-
-    /**
-     * Save archive file for an agent and a period
-     *
-     * @param   string                      $pdfPayslipCheckFilePath    Pdf checked file path
-     * @param   DematpayslipArchiveMapper   $dematpayslipArchiveMapper  Archive table mapper
-     * @param   DematpayslipArchive         $dematpayslipArchive        Archive
-     * @param   string                      $archiveFilePath            Archive file path
-     * @param   DematpayslipUser            $agentUser                  Agent user
-     * @param   string                      $startDate                  Period start date
-     * @param   string                      $endDate                    Period end date
-     * @param   string                      $year                       Period year
-     * @param   string                      $month                      Period month
-     * @param   string                      $editionDate                Edition date
-     * @param   int                         $importTime                 Import time
-     * @return  int                         <0 if KO, >0 if OK
-     *
-     * @throws  Exception
-     */
-    private function _archiveSaveAndProcess($pdfPayslipCheckFilePath, DematpayslipArchiveMapper $dematpayslipArchiveMapper, DematpayslipArchive $dematpayslipArchive, $archiveFilePath, DematpayslipUser $agentUser, $startDate, $endDate, $year, $month, $editionDate, $importTime) {
-        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;
-        }
-        $this->_archiveSaveForAgentAndPeriod($dematpayslipArchiveMapper, $dematpayslipArchive, $archiveFilePath, $agentUser, $startDate, $endDate, $year, $month, $editionDate, $importTime);
-        $this->_archiveProcess($dematpayslipArchiveMapper, $dematpayslipArchive);
-
-        return 1;
-    }
+//    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
@@ -429,12 +261,13 @@ class PageController extends Controller {
      */
     private function _assignParamsDemat() {
         return array(
+            'urlGenerator'           => $this->_urlGenerator,
             'dematpayslipConfigList' => $this->_dematpayslipConfigList,
-            'pastellAppExists'       => $this->_pastellAppExists,
-            'canCancelProcess'       => $this->_canCancelProcess,
-            'msgList'                => $this->_msgList,
-            'processArr'             => $this->_process->jsonSerialize(),
-            'userArr'                => array('id' => $this->userId),
+            'pastellAppExists'       => $this->_dematpaylsipProcess->getPastellAppExists(),
+            'canCancelProcess'       => $this->_dematpaylsipProcess->getCanCancelProcess(),
+            'msgList'                => $this->_dematpaylsipProcess->getMsgList(),
+            'processArr'             => $this->_dematpaylsipProcess->jsonSerialize(),
+            'userArr'                => array('id' => $this->_userId),
         );
     }
 
@@ -445,11 +278,14 @@ class PageController extends Controller {
      */
     private function _assignAgentList() {
         return array(
+            'dateTimeZone'           => $this->_dateTimeZone,
+            'urlGenerator'           => $this->_urlGenerator,
+            'userManager'            => $this->_userManager,
             'dematpayslipConfigList' => $this->_dematpayslipConfigList,
-            'pastellAppExists'       => $this->_pastellAppExists,
+            'pastellAppExists'       => $this->_dematpaylsipProcess->getPastellAppExists(),
             'dematpayslipUserList'   => $this->_dematpayslipUserMapper->findAll(),
-            'exportDirUserPath'      => $this->_exportDirUserPath,
-            'msgList'                => $this->_msgList,
+            'exportDirUserPath'      => $this->_dematpaylsipProcess->getExportDirUserPath(),
+            'msgList'                => $this->_dematpaylsipProcess->getMsgList(),
         );
     }
 
@@ -466,70 +302,15 @@ class PageController extends Controller {
         );
 
         // get archive list
-        $dematpayslipArchiveMapper = new DematpayslipArchiveMapper(OC::$server->getDatabaseConnection());
-
-        if ($refresh === true) {
-            if ($stepStatus === -1) {
-                $dematpayslipArchiveList = $dematpayslipArchiveMapper->findAll(0);
-            } else {
-                $dematpayslipArchiveList = $dematpayslipArchiveMapper->findAllByStepStatus($stepStatus);
-            }
-
-            if (!empty($dematpayslipArchiveList)) {
-                foreach ($dematpayslipArchiveList as $dematpayslipArchive) {
-                    if (empty($dematpayslipArchive->getPastellIdDocument()))  continue;
-
-                    $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
-                        }
-                    }
-
-                    // Pastell API config
-                    $pastellConfigFlowId = $this->config->getAppValue($this->appName, 'pastell_config_f' . $archiveFlowNum . '_id', '');
-                    $pastellConfigFlowMapper = new PastellConfigFlowMapper(OC::$server->getDatabaseConnection());
-                    $pastellConfigFlow = $pastellConfigFlowMapper->find($pastellConfigFlowId);
-
-                    try {
-                        // Pastell API connection
-                        $pastellAPI = new PastellAPI($pastellConfigFlow->getIdConfig());
-
-                        // 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);
-                        }
-                    } catch (Exception $e) {
-                        $this->_msgList['error'][] = $e->getMessage();
-                    }
-
-                    if (count($this->_msgList['error']) > 0)    break;
-                }
-            }
-
-            if (count($this->_msgList['error']) <= 0) {
-                $this->_msgList['success'][] = $this->l->t('Liste actualisée avec succès.');
-            }
-        }
-
-
-        if ($stepStatus === -1) {
-            $dematpayslipArchiveList = $dematpayslipArchiveMapper->findAll(0);
-        } else {
-            $dematpayslipArchiveList = $dematpayslipArchiveMapper->findAllByStepStatus($stepStatus);
-        }
+        $dematpayslipArchiveList = $this->_dematpaylsipProcess->getArchiveList($stepStatus, $refresh);
 
         return array(
+            'urlGenerator'            => $this->_urlGenerator,
             'dematpayslipConfigList'  => $this->_dematpayslipConfigList,
-            'pastellAppExists'        => $this->_pastellAppExists,
+            'pastellAppExists'        => $this->_dematpaylsipProcess->getPastellAppExists(),
             'dematpayslipArchiveList' => $dematpayslipArchiveList,
-            'exportDirUserPath'       => $this->_exportDirUserPath,
-            'msgList'                 => $this->_msgList,
+            'exportDirUserPath'       => $this->_dematpaylsipProcess->getExportDirUserPath(),
+            'msgList'                 => $this->_dematpaylsipProcess->getMsgList(),
             'paramList'               => $paramList,
         );
     }
@@ -542,11 +323,12 @@ class PageController extends Controller {
      */
     private function _assignUserList($searchList) {
         return array(
-            'dematpayslipConfigList'  => $this->_dematpayslipConfigList,
-            'pastellAppExists'        => $this->_pastellAppExists,
-            'msgList' => $this->_msgList,
-            'searchList' => $searchList,
-            'userList' => $this->_userList,
+            'urlGenerator'           => $this->_urlGenerator,
+            'dematpayslipConfigList' => $this->_dematpayslipConfigList,
+            'pastellAppExists'       => $this->_dematpaylsipProcess->getPastellAppExists(),
+            'msgList'                => $this->_dematpaylsipProcess->getMsgList(),
+            'searchList'             => $searchList,
+            'userList'               => $this->_userList,
         );
     }
 
@@ -557,520 +339,85 @@ class PageController extends Controller {
      */
     private function _assignParamsShares() {
         return array(
+            'urlGenerator'         => $this->_urlGenerator,
             'dematpayslipUserList' => $this->_dematpayslipUserList,
-            'msgList'              => $this->_msgList,
+            'msgList'              => $this->_dematpaylsipProcess->getMsgList(),
         );
     }
 
-    /**
-     * Get phase name
-     *
-     * @param   int         $phaseId    Phase Id
-     * @return  string      Phase name
-     */
-    private static function _getPhaseName($phaseId) {
-        $phaseName = '';
-
-        switch ($phaseId) {
-            case self::PHASE_ID_UPLOAD :
-                $phaseName = 'Upload';
-            break;
-
-            case self::PHASE_ID_CHECK :
-                $phaseName = 'Vérification';
-            break;
-
-            case self::PHASE_ID_INDEXATION :
-                $phaseName = 'Indexation';
-            break;
-
-            default : break;
-        }
-
-        return $phaseName;
-    }
-
-    /**
-     * Find CSV and PDF files in uploaded directory
-     *
-     * @return  array   CSV and PDF filenames
-     */
-    private function _findUploadedCSVAndPDF() {
-        $uploadFileCSVName = '';
-        $uploadFilePDFName = '';
-        $uploadDirFullPath = $this->_uploadDirFullPath;
-        if (file_exists($uploadDirFullPath)) {
-            $scanDir = scandir($uploadDirFullPath);
-            if (!empty($scanDir)) {
-                foreach ($scanDir as $fileName) {
-                    if (!in_array($fileName, array('.', '..'))) {
-                        $uploadFilePath = $uploadDirFullPath . DIRECTORY_SEPARATOR . $fileName;
-                        if (is_file($uploadFilePath)) {
-                            $uploadFileType = mime_content_type($uploadFilePath);
-                            if ($uploadFileType == 'application/pdf') {
-                                $uploadFilePDFName = $fileName;
-                            } else if ($uploadFileType == 'text/plain') {
-                                $uploadFileCSVName = $fileName;
-                            }
-                        }
-                    }
-
-                    if (!empty($uploadFileCSVName) && !empty($uploadFilePDFName)) {
-                        break;
-                    }
-                }
-            }
-        }
-
-        return array('csv' => $uploadFileCSVName, 'pdf' => $uploadFilePDFName);
-    }
-
-    /**
-     * Find all files (recursive)
-     *
-     * @param   string      $filePath       File path
-     * @return  array
-     */
-    private function _findAllFiles($filePath, &$fileList = array()) {
-        $isDir = Filesystem::is_dir($filePath);
-
-        if ($isDir) {
-            $payslipPDFFileList = Filesystem::getDirectoryContent($filePath);
-
-            foreach ($payslipPDFFileList as $payslipPDFFile) {
-                $newFilePath = $filePath . DIRECTORY_SEPARATOR . $payslipPDFFile->getName();
-                $isFile = Filesystem::is_file($newFilePath);
-                if ($isFile) {
-                    $fileList[] = $payslipPDFFile;
-                } else {
-                    $this->_findAllFiles($newFilePath, $fileList);
-                }
-            }
-        }
-
-        return $fileList;
-    }
-
-    /**
-     * Remove all files in a directory
-     *
-     * @param   string      $dirPath    Directory path
-     */
-    private static function _removeAllFilesDir($dirPath) {
-        $scanDir = scandir($dirPath);
-        if (!empty($scanDir)) {
-            foreach ($scanDir as $fileName) {
-                if (!in_array($fileName, array('.', '..'))) {
-                    $filePath = $dirPath . DIRECTORY_SEPARATOR . $fileName;
-                    if (is_file($filePath)) {
-                        unlink($filePath);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Remove all unknown users (FIX for multiple users with SAML)
-     *
-     * @param   array   $userFindByEmailList        User list
-     * @return  array   Users list without unknown
-     */
-    private static function _removeUnknownUser($userFindByEmailList) {
-        $userList = $userFindByEmailList;
-
-        foreach ($userList as $key => $user) {
-            if (preg_match('#^[0-9A-F]{8}\-[0-9A-F]{4}\-[0-9A-F]{4}\-[0-9A-F]{4}\-[0-9A-F]{12}#', $user->getDisplayName())) {
-                unset($userList[$key]);
-            }
-        }
-
-        return $userList;
-    }
-
-    /**
-     * Cancel process
-     */
-    private function _processCancel() {
-        if ($this->_process->getMustTerminate()<=0) {
-            // vider le dossier Upload
-            if (is_dir($this->_uploadDirFullPath)) {
-                self::_removeAllFilesDir($this->_uploadDirFullPath);
-            }
-
-            // vider le dossier Check
-            if (is_dir($this->_checkDirFullPath)) {
-                self::_removeAllFilesDir($this->_checkDirFullPath);
-            }
-
-            $this->_processInit();
-            $this->_dematpayslipProcessMapper->update($this->_process);
-        }
-    }
-
-    /**
-     * Set process error message
-     *
-     * @param   int         $errorCode      Error code
-     * @param   string      $errorMsg       Error message
-     * @param   string      $phaseStep      [=''] Phase step
-     * @param   int         $phaseStepNum   [=0] Phase step num
-     */
-    private function _processErrorMsg($errorCode, $errorMsg, $phaseStep = '', $phaseStepNum = 0) {
-        $this->_process->setHasError(1);
-        $this->_msgList['error'][] = $errorMsg;
-        $this->_process->setErrorCode($errorCode);
-        $this->_process->setErrorMsg(implode('<br />', $this->_msgList['error']));
-        $this->_process->setPhaseStep($phaseStep);
-        $this->_process->setPhaseStepNum(intval($phaseStepNum));
-        $this->_dematpayslipProcessMapper->update($this->_process);
-    }
-
-    /**
-     * Set process warning message
-     *
-     * @param   string      $warningMsg       Warning message
-     */
-    private function _processWarningMsg($warningMsg) {
-        $this->_msgList['warning'][] = $warningMsg;
-    }
-
-    /**
-     * Csv log file
-     *
-     * @param   array   $colList    Column name list
-     */
-    private function _logCsvCols($colList) {
-        if ($this->_logFile !== null) {
-            fputcsv($this->_logFile, $colList, $this->_csvDelimiter, $this->_csvEnclosure);
-        }
-    }
-
-    /**
-     * Log csv line
-     *
-     * @param   string                  $msg            Log message
-     * @param   int                     $level          [=LOG_DEBUG] Log level
-     * @param   DematpayslipUser        $agentUser      [=null] Siret
-     * @param   string                  $startDate      [=''] Start date
-     * @param   string                  $endDate        [=''] End date
-     *
-     * @throws  Exception
-     */
-    private function _logCsvLine($msg, $level = self::LOG_DEBUG, DematpayslipUser $agentUser = null, $startDate = '', $endDate = '') {
-        if ($this->_logFile !== null) {
-            if ($this->_logLevel <= $level || $level === self::LOG_SUCCESS) {
-                $dateTimeNow = new DateTime('now', OC::$server->getDateTimeZone()->getTimeZone());
-                $logLevel = '';
-                switch ($level) {
-                    case self::LOG_SUCCESS :
-                        $logLevel = 'SUCCESS';
-                        break;
-
-                    case self::LOG_DEBUG :
-                        $logLevel = 'DEBUG';
-                        break;
-
-                    case self::LOG_WARNING :
-                        $logLevel = 'WARNING';
-                        break;
-
-                    case self::LOG_ERROR :
-                        $logLevel = 'ERROR';
-                        break;
-
-                    default : break;
-                }
-
-                $csvLine = array(
-                    $dateTimeNow->format('Y-m-d'),
-                    $dateTimeNow->format('H:i:s'),
-                    $logLevel,
-                    $msg,
-                    (!empty($agentUser) ? $agentUser->getSiret() : ''),
-                    (!empty($agentUser) ? $agentUser->getMatricule() : ''),
-                    (!empty($agentUser) ? $agentUser->getLastname() . ' ' . $agentUser->getFirstname() : ''),
-                    (!empty($agentUser) ? $agentUser->getZipCity() : ''),
-                    $startDate,
-                    $endDate,
-                    (!empty($agentUser) ? $agentUser->getEmail() : ''),
-                );
-                fputcsv($this->_logFile, $csvLine, $this->_csvDelimiter, $this->_csvEnclosure);
-            }
-        }
-    }
-
-    /**
-     * Init process
-     */
-    private function _processInit() {
-        $this->_process->setPhase(0);
-        $this->_process->setPhaseStartTime(0);
-        $this->_process->setPhaseStep('');
-        $this->_process->setPhaseStepNum(0);
-        $this->_process->setMustTerminate(0);
-        $this->_process->setHasError(0);
-        $this->_process->setErrorCode(0);
-        $this->_process->setErrorMsg('');
-        $this->_process->setCsvOrigin('');
-        $this->_process->setPdfOrigin('');
-        $this->_process->setCsvCheck('');
-        $this->_process->setUserId('');
-    }
-
-    /**
-     * Check if process is locked (processing or locked by user)
-     */
-    private function _processCheck() {
-        // deverrouillage automatique du process si trop de temps passe (ex : max execution time)
-        if ((time() - $this->_process->getPhaseStartTime())>self::PROCESS_TIME_UNLOCK) {
-            $this->_process->setProcessing(0);
-            $this->_dematpayslipProcessMapper->update($this->_process);
-        }
-
-        $this->_canCancelProcess = false;
-        // c'est le process lance par l'utilisteur
-        if (!empty($this->_process->getUserId()) && $this->userId===$this->_process->getUserId()) {
-            if ($this->_process->getProcessing()==0 && $this->_process->getMustTerminate()==0) {
-                $this->_canCancelProcess = true;
-            }
-        } else {
-            // si le temps a depasse le temps de deverouillage possible
-            if ((time() - $this->_process->getPhaseStartTime())>self::PROCESS_TIME_UNLOCK) {
-                if ($this->_process->getProcessing()==0 && $this->_process->getMustTerminate()==0) {
-                    $this->_canCancelProcess = true;
-                }
-            }
-        }
-
-        if ($this->_process->getProcessing()>0) {
-            $this->_msgList['error'][] = $this->l->t('Une opération "' . self::_getPhaseName($this->_process->getPhase()). '" est déjà en cours...');
-
-            if (!empty($this->_process->getUserId()) && $this->userId!==$this->_process->getUserId()) {
-                $this->_msgList['error'][] = $this->l->t('Opération démarrée par l\'utilisateur "' . $this->_process->getUserId() . '".');
-            } else {
-                $this->_msgList['error'][] = $this->l->t('Veuillez patienter');
-            }
-        } else if (!empty($this->_process->getUserId()) && $this->userId!==$this->_process->getUserId()) {
-            $this->_msgList['error'][] = $this->l->t('Une opération "' . self::_getPhaseName($this->_process->getPhase()) . '" a déjà été démarrée par l\'utilisateur "' . $this->_process->getUserId() . '".');
-        } else if ($this->_process->getHasError()>0) {
-            if ($this->_process->getMustTerminate()==1) {
-                // derniere operation terminee avec des erreurs (afficher le rapport)
-                $this->_msgList['error'][] = $this->l->t('L\'opération "' . self::_getPhaseName($this->_process->getPhase()) . '" s\'est terminée avec les erreurs suivantes') . ' : ';
-                $this->_msgList['error'][] = $this->_process->getErrorMsg();
-            }
-        }
-    }
-
-    /**
-     * Init application folders
-     *
-     * @throws  OC\User\NoUserException
-     */
-    private function _initDematFolders() {
-        $appDataDirPath           = $this->_dematpayslipConfigList['app_data_dir']; // dematpayslip directory of user demat (upload, check, report, etc)
-        $this->_checkDirUserPath  = $appDataDirPath . DIRECTORY_SEPARATOR . 'check';
-        $this->_reportDirUserPath = $appDataDirPath . DIRECTORY_SEPARATOR . 'report';
-        $this->_uploadDirUserPath = $appDataDirPath . DIRECTORY_SEPARATOR . 'upload';
-        $this->_exportDirUserPath = $appDataDirPath . DIRECTORY_SEPARATOR . 'export';
-        $this->_tmpDirUserPath    = $appDataDirPath . DIRECTORY_SEPARATOR . 'tmp';
-
-        // recuperer le dossier de l'utilisateur Nextcloud
-        $user = OC::$server->getUserManager()->get($this->userId);
-        if (!$user) {
-            $this->_msgList['error'][] = $this->l->t('Le dossier utilisateur "' . $this->userId . '" n\'existe pas.');
-        }
-
-        // mounter le dossier de l'utilisateur
-        if (count($this->_msgList['error'])<=0) {
-            $userHomeAppFilesFullPath = $user->getHome() . DIRECTORY_SEPARATOR . 'files';
-            $this->_checkDirFullPath  = $userHomeAppFilesFullPath . DIRECTORY_SEPARATOR . $this->_checkDirUserPath;
-            $this->_reportDirFullPath = $userHomeAppFilesFullPath . DIRECTORY_SEPARATOR . $this->_reportDirUserPath;
-            $this->_uploadDirFullPath = $userHomeAppFilesFullPath . DIRECTORY_SEPARATOR . $this->_uploadDirUserPath;
-            $this->_exportDirFullPath = $userHomeAppFilesFullPath . DIRECTORY_SEPARATOR . $this->_exportDirUserPath;
-            $this->_tmpDirFullPath    = $userHomeAppFilesFullPath . DIRECTORY_SEPARATOR . $this->_tmpDirUserPath;
-
-            // monter le dossier de 'utilisateur
-            Filesystem::initMountPoints($this->userId);
-
-            // creer le dossier des bulletins
-            $isDir = Filesystem::is_dir($this->_dematpayslipConfigList['payslip_dir']);
-            if (!$isDir) {
-                // creer le dossier des bulletins
-                $dirCreated = Filesystem::mkdir($this->_dematpayslipConfigList['payslip_dir']);
-                if (!$dirCreated) {
-                    $this->_msgList['error'][] = $this->l->t('Impossible de créeer le dossier des bulletins "' . $this->_dematpayslipConfigList['payslip_dir'] . '".');
-                }
-            }
-
-            // creer le dossier des bulletins a ne pas indexer
-            $isDir = Filesystem::is_dir($this->_payslipNoIndexDir);
-            if (!$isDir) {
-                // creer le dossier des bulletins a ne pas indexer
-                $dirCreated = Filesystem::mkdir($this->_payslipNoIndexDir);
-                if (!$dirCreated) {
-                    $this->_msgList['error'][] = $this->l->t('Impossible de créeer le dossier des bulletins non indexes "' . $this->_payslipNoIndexDir . '".');
-                }
-            }
-
-            // creer le dossier de l'application
-            $isDir = Filesystem::is_dir($appDataDirPath);
-            if (!$isDir) {
-                // creer le dossier de l'application
-                $dirCreated = Filesystem::mkdir($appDataDirPath);
-                if (!$dirCreated) {
-                    $this->_msgList['error'][] = $this->l->t('Impossible de créeer le dossier de l\'application "' . $appDataDirPath . '".');
-                }
-            }
-
-            if (count($this->_msgList['error'])<=0) {
-                // dossier check
-                $isDir = Filesystem::is_dir($this->_checkDirUserPath);
-                if (!$isDir) {
-                    $dirCreated = Filesystem::mkdir($this->_checkDirUserPath);
-                    if (!$dirCreated) {
-                        $this->_msgList['error'][] = $this->l->t('Impossible de créeer le dossier de l\'application "' . $this->_checkDirUserPath . '".');
-                    }
-                }
-
-                // dossier report
-                $isDir = Filesystem::is_dir($this->_reportDirUserPath);
-                if (!$isDir) {
-                    $dirCreated = Filesystem::mkdir($this->_reportDirUserPath);
-                    if (!$dirCreated) {
-                        $this->_msgList['error'][] = $this->l->t('Impossible de créeer le dossier de l\'application "' . $this->_reportDirUserPath . '".');
-                    }
-                }
-
-                // dossier upload
-                $isDir = Filesystem::is_dir($this->_uploadDirUserPath);
-                if (!$isDir) {
-                    $dirCreated = Filesystem::mkdir($this->_uploadDirUserPath);
-                    if (!$dirCreated) {
-                        $this->_msgList['error'][] = $this->l->t('Impossible de créeer le dossier de l\'application "' . $this->_uploadDirUserPath . '".');
-                    }
-                }
-
-                // dossier export
-                $isDir = Filesystem::is_dir($this->_exportDirUserPath);
-                if (!$isDir) {
-                    $dirCreated = Filesystem::mkdir($this->_exportDirUserPath);
-                    if (!$dirCreated) {
-                        $this->_msgList['error'][] = $this->l->t('Impossible de créeer le dossier de l\'application "' . $this->_exportDirUserPath . '".');
-                    }
-                }
-
-                // dossier tmp
-                $isDir = Filesystem::is_dir($this->_tmpDirUserPath);
-                if (!$isDir) {
-                    $dirCreated = Filesystem::mkdir($this->_tmpDirUserPath);
-                    if (!$dirCreated) {
-                        $this->_msgList['error'][] = $this->l->t('Impossible de créeer le dossier de l\'application "' . $this->_exportDirUserPath . '".');
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Init for demat user
-     *
-     * @throws  OC\User\NoUserException
-     */
-    private function _initDematUser() {
-        // init
-        $appPath = OC_App::getAppPath($this->appName);
-        // depends
-        require_once $appPath . '/vendor/autoload.php';
-
-        // creer le process s'il n'existe pas
-        $dematpayslipProcessList = $this->_dematpayslipProcessMapper->findAll();
-        if (empty($dematpayslipProcessList)) {
-            $dematpayslipProcess = new DematpayslipProcess();
-            $dematpayslipProcess->setProcessing(0);
-            $dematpayslipProcess->setPhase(0);
-            $dematpayslipProcess->setPhaseStartTime(0);
-            $dematpayslipProcess->setPhaseStepNum(0);
-            $dematpayslipProcess->setMustTerminate(0);
-            $dematpayslipProcess->setHasError(0);
-            $dematpayslipProcess->setErrorCode(0);
-            $dematpayslipProcess->setErrorMsg('');
-            $dematpayslipProcess->setPdfOrigin('');
-            $dematpayslipProcess->setCsvOrigin('');
-            $dematpayslipProcess->setCsvCheck('');
-            $dematpayslipProcess->setUserId('');
-            $this->_dematpayslipProcessMapper->insert($dematpayslipProcess);
-            $this->_process = $dematpayslipProcess;
-        } else {
-            $this->_process = $dematpayslipProcessList[0];
-        }
-
-        $this->_initDematFolders();
-    }
-
-    /**
-     * Load config
-     */
-    private function _loadConfig() {
-        $this->_dematpayslipConfigList['payslip_dir']  = $this->config->getAppValue($this->appName, 'payslip_dir', 'Bulletins'); // Bulletins
-        $this->_dematpayslipConfigList['user_id']      = $this->config->getAppValue($this->appName, 'user_id', 'demat');     // demat
-        $this->_dematpayslipConfigList['app_data_dir'] = $this->config->getAppValue($this->appName, 'app_data_dir', 'dematpayslip'); // dematpayslip directory of user demat (upload, check, report, etc)
-        if (empty($this->_dematpayslipConfigList['payslip_dir']) || empty($this->_dematpayslipConfigList['user_id'])) {
-            $this->_msgList['error'][] = $this->l->t('Veuillez vérifier la configuration de cette application.');
-        }
-
-        $this->_dematpayslipConfigList['pastell_use'] = $this->config->getAppValue($this->appName, 'pastell_use', '');
-        if (!empty($this->_dematpayslipConfigList['pastell_use'])) {
-            // check Pastell API config
-            $this->_dematpayslipConfigList['pastell_config_f1_id'] = $this->config->getAppValue($this->appName, 'pastell_config_f1_id', '');
-            $this->_dematpayslipConfigList['pastell_config_f2_id'] = $this->config->getAppValue($this->appName, 'pastell_config_f2_id', '');
-            if (!($this->_dematpayslipConfigList['pastell_config_f1_id'] > 0) || !($this->_dematpayslipConfigList['pastell_config_f2_id'] > 0)) {
-                $this->_msgList['error'][] = $this->l->t('Veuillez vérifier la configuration de cette application.');
-            }
-        }
-    }
-
     /**
      * PageController constructor.
      *
      * @param   string                              $AppName                            App name
      * @param   IRequest                            $request                            Request
      * @param   IConfig                             $config                             Config
-     * @param   IL10N                               $l                                  Lang
+     * @param   IDateTimeZone                       $dateTimeZone                       Date time zone
+     * @param   IDBConnection                       $dbConnection                       Database connection
+     * @param   IL10N                               $l10n                               Lang
+     * @param   IRootFolder                         $rootFolder                         Root folder
+     * @param   IShareManager                       $shareManager                       Share manager
      * @param   IURLGenerator                       $urlGenerator                       Url generator
-     * @param   DematpayslipProcessMapper           $dematpayslipProcessMapper          Dematpayslip process mapper
-     * @param   DematpayslipProcessSkipMapper       $dematpayslipProcessSkipMapper      Dematpayslip process skip mapper
-     * @param   DematpayslipUserMapper              $dematpayslipUserMapper             Dematpayslip user mapper
+     * @param   IUserManager                        $userManager                        User manager
+     * @param   DematpayslipProcessMapper           $dematpayslipProcessMapper          Process mapper
+     * @param   DematpayslipProcessSkipMapper       $dematpayslipProcessSkipMapper      Process skip mapper
+     * @param   DematpayslipUserMapper              $dematpayslipUserMapper             User mapper
      * @param   string                              $UserId                             User Id
      */
     public function __construct(
         $AppName,
         IRequest $request,
         IConfig $config,
-        IL10N $l,
+        IDateTimeZone $dateTimeZone,
+        IDBConnection $dbConnection,
+        IL10N $l10n,
+        IRootFolder $rootFolder,
+        IShareManager $shareManager,
         IURLGenerator $urlGenerator,
+        IUserManager $userManager,
         DematpayslipProcessMapper $dematpayslipProcessMapper,
         DematpayslipProcessSkipMapper $dematpayslipProcessSkipMapper,
         DematpayslipUserMapper $dematpayslipUserMapper,
         $UserId
     ) {
 		parent::__construct($AppName, $request);
-		$this->config                          = $config;
-		$this->l                               = $l;
-		$this->_urlGenerator                   = $urlGenerator;
-        $this->userId                          = $UserId;
-
-		// Dematpayslip
-		$this->_dematpayslipProcessMapper      = $dematpayslipProcessMapper;
-        $this->_dematpayslipProcessSkipMapper  = $dematpayslipProcessSkipMapper;
-        $this->_dematpayslipUserMapper         = $dematpayslipUserMapper;
-
-        // check if Pastell app exists
-        $pastellAppDir = __DIR__ . '/../../../pastell';
-        if (is_dir($pastellAppDir)) $this->_pastellAppExists = true;
+		$this->_config       = $config;
+		$this->_dateTimeZone = $dateTimeZone;
+        $this->_dbConnection = $dbConnection;
+		$this->_l10n         = $l10n;
+        $this->_rootFolder   = $rootFolder;
+        $this->_shareManager = $shareManager;
+		$this->_urlGenerator = $urlGenerator;
+        $this->_userManager  = $userManager;
+		$this->_userId       = $UserId;
+
+        $this->_dematpayslipProcessMapper = $dematpayslipProcessMapper;
+        $this->_dematpayslipProcessSkipMapper = $dematpayslipProcessSkipMapper;
+        $this->_dematpayslipUserMapper = $dematpayslipUserMapper;
+
+        // create process if not exists
+        $processList = $this->_dematpayslipProcessMapper->findAll();
+        if (empty($processList)) {
+            $process = new DematpayslipProcess();
+            $process->setProcessing(0);
+            $process->setPhase(0);
+            $process->setPhaseStartTime(0);
+            $process->setPhaseStepNum(0);
+            $process->setMustTerminate(0);
+            $process->setHasError(0);
+            $process->setErrorCode(0);
+            $process->setErrorMsg('');
+            $process->setPdfOrigin('');
+            $process->setCsvOrigin('');
+            $process->setCsvCheck('');
+            $process->setUserId('');
+            $this->_dematpayslipProcessMapper->insert($process);
+            $this->_dematpaylsipProcess = $process;
+        } else {
+            $this->_dematpaylsipProcess = $processList[0];
+        }
 
         // load config
-        $this->_loadConfig();
+        $this->_dematpayslipConfigList = $this->_dematpaylsipProcess->load($this->appName, $this->_config, $this->_dbConnection, $this->_l10n, $this->_rootFolder, $this->_shareManager, $this->_userManager, $this->_userId, $this->_dematpayslipProcessMapper, $this->_dematpayslipProcessSkipMapper, $this->_dematpayslipUserMapper, $this->_dateTimeZone->getTimeZone());
 	}
 
 	/**
@@ -1085,28 +432,11 @@ class PageController extends Controller {
      * @UseSession
 	 */
 	public function index() {
-        // verifier l'utilisateur
-        if ($this->userId === $this->_dematpayslipConfigList['user_id']) {
-            $this->_initDematUser();
+        // check user
+        if ($this->_userId === $this->_dematpayslipConfigList['user_id']) {
+            $this->_dematpaylsipProcess->index();
 
-            $this->_processCheck();
-            if (count($this->_msgList['error'])<=0) {
-                if ($this->_process->getPhase()==0) {
-                    // scan uploaded files
-                    $uploadedCSVAndPDFArr = $this->_findUploadedCSVAndPDF();
-                    $uploadFileCSVName = $uploadedCSVAndPDFArr['csv'];
-                    $uploadFilePDFName = $uploadedCSVAndPDFArr['pdf'];
-
-                    if (!empty($uploadFileCSVName) && !empty($uploadFilePDFName)) {
-                        $this->_process->setPhase(1);
-                        $this->_process->setCsvOrigin($uploadFileCSVName);
-                        $this->_process->setPdfOrigin($uploadFilePDFName);
-                        $this->_dematpayslipProcessMapper->update($this->_process);
-                    }
-                }
-            }
-
-            return new TemplateResponse('dematpayslip', 'index', $this->_assignParamsDemat());  // templates/index.php
+            return new TemplateResponse('dematpayslip', 'index', $this->_assignParamsDemat());
         } else {
             return $this->shares();
         }
@@ -1115,18 +445,17 @@ class PageController extends Controller {
     /**
      * Cancel a process
      * @NoAdminRequired
+     *
+     * @return  TemplateResponse
+     *
+     * @throws  Exception
      */
     public function cancel() {
-        // verifier l'utilisateur
-        if ($this->userId === $this->_dematpayslipConfigList['user_id']) {
-            $this->_initDematUser();
-
-            $this->_processCheck();
-            if ($this->_canCancelProcess === true) {
-                $this->_processCancel();
-            }
+        // check user
+        if ($this->_userId === $this->_dematpayslipConfigList['user_id']) {
+            $this->_dematpaylsipProcess->cancel();
 
-            return new TemplateResponse('dematpayslip', 'index', $this->_assignParamsDemat());  // templates/index.php
+            return new TemplateResponse('dematpayslip', 'index', $this->_assignParamsDemat());
         } else {
             return $this->shares();
         }
@@ -1138,139 +467,14 @@ class PageController extends Controller {
      *
      * @return  TemplateResponse
      *
-     * @throws  OC\User\NoUserException
+     * @throws  Exception
      */
     public function upload() {
         // verifier l'utilisateur
-        if ($this->userId === $this->_dematpayslipConfigList['user_id']) {
-            $this->_initDematUser();
-
-            $this->_processCheck();
-            if (count($this->_msgList['error'])<=0) {
-                $dateTimeNow = new DateTime('now', OC::$server->getDateTimeZone()->getTimeZone());
-
-                $this->_process->setProcessing(1);
-                $this->_process->setPhase(0);
-                $this->_process->setPhaseStartTime($dateTimeNow->getTimestamp());
-                $this->_process->setPhaseStepNum(0);
-                $this->_process->setHasError(0);
-                $this->_process->setErrorCode(0);
-                $this->_process->setErrorMsg('');
-                $this->_process->setMustTerminate(0);
-                $this->_process->setCsvOrigin('');
-                $this->_process->setPdfOrigin('');
-                $this->_dematpayslipProcessMapper->update($this->_process);
+        if ($this->_userId === $this->_dematpayslipConfigList['user_id']) {
+            $this->_dematpaylsipProcess->upload();
 
-                // check upload CSV
-                $uploadFileCSVName    = '';
-                $uploadFileCSVTmpName = '';
-                if (!isset($_FILES['payslips_csv_file'])) {
-                    $errorMsg = $this->l->t('Veuillez sélectionner un fichier CSV.');
-                    $this->_processErrorMsg(-1, $errorMsg);
-                } else {
-                    $uploadFileArr = $_FILES['payslips_csv_file'];
-			        //var_dump($uploadFileArr['type']);
-                    if (empty($uploadFileArr['name'])) {
-                        $errorMsg = $this->l->t('Veuillez sélectionner un fichier CSV.');
-                        $this->_processErrorMsg(-1, $errorMsg);
-                    } else if (!in_array($uploadFileArr['type'], array('text/csv', 'application/octet-stream', 'application/vnd.ms-excel'))) {
-                        $errorMsg = $this->l->t('Veuillez sélectionner un fichier CSV valide.');
-                        $this->_processErrorMsg(-1, $errorMsg);
-                    } else if ($uploadFileArr['size']<=0) {
-                        $errorMsg = $this->l->t('Veuillez sélectionner un fichier CSV non vide.');
-                        $this->_processErrorMsg(-1, $errorMsg);
-                    } else if (empty($uploadFileArr['tmp_name'])) {
-                        $errorMsg = $this->l->t('Impossible d\'uploader ce fichier CSV.');
-                        $this->_processErrorMsg(-1, $errorMsg);
-                    } else if ($uploadFileArr['error']!==UPLOAD_ERR_OK) {
-                        $errorMsg = $this->l->t('Echec d\'upload du fichier CSV [=' . $uploadFileArr['error'] . '].');
-                        $this->_processErrorMsg(-1, $errorMsg);
-                    } else {
-                        // upload success
-                        $uploadFileCSVName    = $uploadFileArr['name'];
-                        $uploadFileCSVTmpName = $uploadFileArr['tmp_name'];
-                    }
-                }
-
-                // check upload PDF
-                $uploadFilePDFName    = '';
-                $uploadFilePDFTmpName = '';
-                if (!isset($_FILES['payslips_pdf_file'])) {
-                    $errorMsg = $this->l->t('Veuillez sélectionner un fichier PDF.');
-                    $this->_processErrorMsg(-1, $errorMsg);
-                } else {
-                    $uploadFileArr = $_FILES['payslips_pdf_file'];
-                    if (empty($uploadFileArr['name'])) {
-                        $errorMsg = $this->l->t('Veuillez sélectionner un fichier PDF.');
-                        $this->_processErrorMsg(-1, $errorMsg);
-                    } else if ($uploadFileArr['type']!='application/pdf') {
-                        $errorMsg = $this->l->t('Veuillez sélectionner un fichier PDF valide.');
-                        $this->_processErrorMsg(-1, $errorMsg);
-                    } else if ($uploadFileArr['size']<=0) {
-                        $errorMsg = $this->l->t('Veuillez sélectionner un fichier PDF non vide.');
-                        $this->_processErrorMsg(-1, $errorMsg);
-                    } else if (empty($uploadFileArr['tmp_name'])) {
-                        $errorMsg = $this->l->t('Impossible d\'uploader ce fichier PDF.');
-                        $this->_processErrorMsg(-1, $errorMsg);
-                    } else if ($uploadFileArr['error']!==UPLOAD_ERR_OK) {
-                        $errorMsg = $this->l->t('Echec d\'upload du fichier PDF [=' . $uploadFileArr['error'] . '].');
-                        $this->_processErrorMsg(-1, $errorMsg);
-                    } else {
-                        // upload success
-                        $uploadFilePDFName    = $uploadFileArr['name'];
-                        $uploadFilePDFTmpName = $uploadFileArr['tmp_name'];
-                    }
-                }
-
-                if ($this->_process->getHasError()<=0) {
-                    // vider le dossier Upload
-                    if (is_dir($this->_uploadDirFullPath)) {
-                        self::_removeAllFilesDir($this->_uploadDirFullPath);
-                    }
-
-                    // upload CSV
-                    $uploadFilePath = $this->_uploadDirFullPath . DIRECTORY_SEPARATOR . $uploadFileCSVName;
-                    if (!move_uploaded_file($uploadFileCSVTmpName, $uploadFilePath)) {
-                        $errorMsg = $this->l->t('Echec d\'upload du fichier CSV dans le répertoire ' . $uploadFilePath . '.');
-                        $this->_processErrorMsg(-1, $errorMsg);
-                    }
-
-                    // upload PDF
-                    $uploadFilePath = $this->_uploadDirFullPath . DIRECTORY_SEPARATOR . $uploadFilePDFName;
-                    if (!move_uploaded_file($uploadFilePDFTmpName, $uploadFilePath)) {
-                        $errorMsg = $this->l->t('Echec d\'upload du fichier PDF dans le répertoire ' . $uploadFilePath . '.');
-                        $this->_processErrorMsg(-1,$errorMsg);
-                    }
-                }
-
-                if ($this->_process->getHasError()>0) {
-                    if ($this->_process->getPhase()==0) {
-                        // scan uploaded files
-                        $uploadedCSVAndPDFArr = $this->_findUploadedCSVAndPDF();
-                        $uploadFileCSVName = $uploadedCSVAndPDFArr['csv'];
-                        $uploadFilePDFName = $uploadedCSVAndPDFArr['pdf'];
-
-                        if (!empty($uploadFileCSVName) && !empty($uploadFilePDFName)) {
-                            $this->_process->setPhase(1);
-                            $this->_process->setCsvOrigin($uploadFileCSVName);
-                            $this->_process->setPdfOrigin($uploadFilePDFName);
-                            $this->_process->setUserId($this->userId);
-                            $this->_dematpayslipProcessMapper->update($this->_process);
-                        }
-                    }
-                } else {
-                    $this->_msgList['success'][] = $this->l->t('Opération "' . self::_getPhaseName($this->_process->getPhase()) . '" terminée avec succès.');
-                    $this->_process->setPhase(1);
-                    $this->_process->setCsvOrigin($uploadFileCSVName);
-                    $this->_process->setPdfOrigin($uploadFilePDFName);
-                    $this->_process->setUserId($this->userId);
-                }
-
-                $this->_process->setProcessing(0);
-                $this->_dematpayslipProcessMapper->update($this->_process);
-            }
-
-            return new TemplateResponse('dematpayslip', 'index', $this->_assignParamsDemat());  // templates/index.php
+            return new TemplateResponse('dematpayslip', 'index', $this->_assignParamsDemat());
         } else {
             return $this->shares();
         }
@@ -1281,485 +485,13 @@ class PageController extends Controller {
      * @NoAdminRequired
      *
      * @return  TemplateResponse
-     * @throws  OC\User\NoUserException
-     * @throws  \setasign\Fpdi\PdfParser\CrossReference\CrossReferenceException
-     * @throws  \setasign\Fpdi\PdfParser\Filter\FilterException
-     * @throws  \setasign\Fpdi\PdfParser\PdfParserException
-     * @throws  \setasign\Fpdi\PdfParser\Type\PdfTypeException
-     * @throws  \setasign\Fpdi\PdfReader\PdfReaderException
+     *
+     * @throws  Exception
      */
     public function check() {
-        // verifier l'utilisateur
-        if ($this->userId === $this->_dematpayslipConfigList['user_id']) {
-            $this->_initDematUser();
-            $this->_processCheck();
-            if ($this->_process->getPhase() < self::PHASE_ID_CHECK) {
-                $this->_msgList['error'][] = $this->l->t('Opération impossible : phase en cours "' . self::_getPhaseName($this->_process->getPhase()) . '".');
-            }
-
-            if (count($this->_msgList['error']) <= 0) {
-                $this->_processFailOnFirstError = false;
-                $dateTimeNow = new DateTime('now', OC::$server->getDateTimeZone()->getTimeZone());
-
-                $this->_process->setProcessing(1);
-                $this->_process->setPhase(1);
-                $this->_process->setPhaseStartTime($dateTimeNow->getTimestamp());
-                $this->_process->setPhaseStepNum(0);
-                $this->_process->setMustTerminate(0);
-                $this->_process->setHasError(0);
-                $this->_process->setErrorCode(0);
-                $this->_process->setErrorMsg('');
-                $this->_process->setUserId($this->userId);
-                $this->_dematpayslipProcessMapper->update($this->_process);
-
-                // vider les lignes du process a sauter
-                $this->_dematpayslipProcessSkipMapper->deleteAllByIdProcess($this->_process->getId());
-
-                // vider le dossier Check
-                if (is_dir($this->_checkDirFullPath)) {
-                    self::_removeAllFilesDir($this->_checkDirFullPath);
-                }
-
-                $uploadFilePDFName = $this->_process->getPdfOrigin();
-                $uploadFileCSVName = $this->_process->getCsvOrigin();
-
-                // log file
-                $logFilePath = $this->_checkDirUserPath . DIRECTORY_SEPARATOR . $this->_process->getPhase() . '_log';
-                $this->_logFile = Filesystem::fopen($logFilePath, 'w+');
-                $this->_logCsvCols(array('date', 'heure', 'niveau', 'message', 'siret', 'matricule', 'nom_prenom', 'zip_city', 'date_debut', 'date_fin', 'email'));
-                $this->_logCsvLine('## ' .$this->l->t('Début du processus de vérification.') . ' ##', self::LOG_DEBUG);
-
-                $csvCheckFileName = $dateTimeNow->format('Y-m-d_H-i-s') . '_' . $uploadFileCSVName;
-
-                $this->_logCsvLine('## ' .$this->l->t('Début de vérification des champs du fichier CSV.') . ' ##', self::LOG_DEBUG);
-                // pdf read and parse
-                $pdfFilePath = $this->_uploadDirFullPath . DIRECTORY_SEPARATOR . $uploadFilePDFName;
-                $pdfPages = array();
-                if ($this->_processFailOnFirstError===false || $this->_process->getHasError()<=0) {
-                    $this->_logCsvLine($this->l->t('Lecture du fichier PDF.'), self::LOG_DEBUG);
-                    $pdfParser = new \Smalot\PdfParser\Parser();
-                    $pdf = $pdfParser->parseFile($pdfFilePath);
-                    $pdfPages = $pdf->getPages();
-                    $pdfPageNb = count($pdfPages);
-                    if ($pdfPageNb <= 0) {
-                        $errorMsg = $this->l->t('Aucune page dans le PDF "' . $uploadFilePDFName . '".');
-                        $this->_logCsvLine($errorMsg, self::LOG_ERROR);
-                        $this->_processErrorMsg(-1, $errorMsg);
-                    }
-                }
-
-                // csv read and load all lines
-                $csvTodoLineList = array();
-                if ($this->_processFailOnFirstError===false || $this->_process->getHasError()<=0) {
-                    $this->_logCsvLine($this->l->t('Ouverture du fichier CSV.'), self::LOG_DEBUG);
-                    $csvFilePath = $this->_uploadDirFullPath . DIRECTORY_SEPARATOR . $uploadFileCSVName;
-                    $csvFile = fopen($csvFilePath, 'r');
-                    if (!$csvFile) {
-                        $errorMsg = $this->l->t('Impossible d\'ouvrir le fichier CSV "' . $uploadFileCSVName . '".');
-                        $this->_logCsvLine($errorMsg, self::LOG_ERROR);
-                        $this->_processErrorMsg(-1, $errorMsg);
-                    } else {
-                        $csvLineNum = 0;
-                        $csvLineNumBegin = 0;
-                        $this->_csvEncodeFrom = 'ISO-8859-1';
-                        $csvConvert = false;
-                        if (!empty($this->_csvEncodeFrom) && $this->_csvEncodeFrom!=$this->_csvEncodeTo) {
-                            $csvConvert = true;
-                        }
-                        $this->_logCsvLine($this->l->t('Lecture des lignes du fichier CSV.'), self::LOG_DEBUG);
-                        while ($csvLine = fgetcsv($csvFile, $this->_csvLength, $this->_csvDelimiter, $this->_csvEnclosure)) {
-                            $this->_logCsvLine('-- ' . $this->l->t('Début de ligne CSV : ' .  ($csvLineNum + 1)) . ' --', self::LOG_DEBUG);
-
-                            if ($csvLineNum >= $csvLineNumBegin) {
-                                if ($csvConvert === true) {
-                                    foreach ($csvLine as $csvColNum => $csvValue) {
-                                        $csvLine[$csvColNum] = mb_convert_encoding(trim($csvValue), $this->_csvEncodeTo,  $this->_csvEncodeFrom);
-                                    }
-                                }
-                                $matriculeOri = $csvLine[1];
-                                $startDate    = date('Y-m-d', strtotime($csvLine[13]));
-                                $endDate      = date('Y-m-d', strtotime($csvLine[14]));
-                                $editionDate  = date('Y-m-d', strtotime($csvLine[17]));
-
-                                // agent user
-                                $agentUser = new DematpayslipUser();
-                                $agentUser->setId(0);
-                                $agentUser->setUserId('');
-                                $agentUser->setSiret($csvLine[0]);
-                                $agentUser->setMatricule(str_pad($matriculeOri, '8', '0', STR_PAD_LEFT));
-                                $agentUser->setLastname($csvLine[3]);
-                                $agentUser->setFirstname($csvLine[4]);
-                                $agentUser->setEmail($csvLine[5]);
-                                $agentUser->setZipCity($csvLine[10]);
-
-                                // verifier l'existance de l'email et autres champs (regex)
-                                $this->_logCsvLine($this->l->t('Ligne CSV'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
-                                if (empty($agentUser->getEmail())) {
-                                    $warningMsg = $this->l->t('Le fichier CSV "' . $uploadFileCSVName . '" contient un champ email vide [ligne=' . ($csvLineNum + 1) . '].');
-                                    $this->_logCsvLine($warningMsg, self::LOG_WARNING, $agentUser, $startDate, $endDate);
-                                    $this->_processWarningMsg($warningMsg);
-
-                                    // sauter cette ligne dans la suite du process de verification et d'indexation
-                                    //$dematpayslipProcessSkipLineArr = $this->_dematpayslipProcessSkipMapper->findAllByIdProcessAndIdLine($this->_process->getId(), $csvLineNum);
-                                    //if (empty($dematpayslipProcessSkipLineArr)) {
-                                    //    $dematpayslipProcessSkip = new DematpayslipProcessSkip();
-                                    //    $dematpayslipProcessSkip->setIdProcess($this->_process->getId());
-                                    //    $dematpayslipProcessSkip->setIdLine($csvLineNum);
-                                    //    $this->_dematpayslipProcessSkipMapper->insert($dematpayslipProcessSkip);
-                                    //}
-                                } else {
-                                    $userManager = OC::$server->getUserManager();
-                                    $userFindByEmailList = $userManager->getByEmail($agentUser->getEmail());
-
-                                    // /!\ remove all users not available (FIX for multiple users with SAML)
-                                    if (self::USER_REMOVE_UNKNOWN == 1) {
-                                        $userFindByEmailList = self::_removeUnknownUser($userFindByEmailList);
-                                    }
-
-                                    if (count($userFindByEmailList) != 1) {
-                                        $warningMsg = $this->l->t('Le fichier CSV "' . $uploadFileCSVName . '" contient un email "' . $agentUser->getEmail() . '" non valide ou non lié à un unique utilisateur Nextcloud [ligne=' . ($csvLineNum + 1) . '].');
-                                        $this->_logCsvLine($warningMsg, self::LOG_WARNING, $agentUser, $startDate, $endDate);
-                                        $this->_processWarningMsg($warningMsg);
-
-                                        $dematpayslipProcessSkipLineArr = $this->_dematpayslipProcessSkipMapper->findAllByIdProcessAndIdLine($this->_process->getId(), $csvLineNum);
-                                        if (empty($dematpayslipProcessSkipLineArr)) {
-                                            $dematpayslipProcessSkip = new DematpayslipProcessSkip();
-                                            $dematpayslipProcessSkip->setIdProcess($this->_process->getId());
-                                            $dematpayslipProcessSkip->setIdLine($csvLineNum);
-                                            $this->_dematpayslipProcessSkipMapper->insert($dematpayslipProcessSkip);
-                                        }
-                                    }
-                                }
-
-                                if ($this->_processFailOnFirstError===false || $this->_process->getHasError()<=0) {
-                                    $csvTodoLineList[] = array(
-                                        'siret'         => $agentUser->getSiret(),
-                                        'matricule_ori' => $matriculeOri,
-                                        'lastname'      => $agentUser->getLastname(),
-                                        'firstname'     => $agentUser->getFirstname(),
-                                        'zip_city'      => $agentUser->getZipCity(),
-                                        'start_date'    => $startDate,
-                                        'end_date'      => $endDate,
-                                        'edition_date'  => $editionDate,
-                                        'matricule'     => $agentUser->getMatricule(),
-                                        'fullname'      => $agentUser->getLastname() . ' ' . $agentUser->getFirstname(),
-                                        'email'         => $agentUser->getEmail(),
-                                        'line_num'      => $csvLineNum + 1,
-                                        'pdf_pages'     => '',
-                                    );
-                                }
-                            }
-
-                            if ($this->_processFailOnFirstError===true && $this->_process->getHasError()>0) {
-                                $this->_logCsvLine('-- ' . $this->l->t('Fin de ligne CSV : ' .  ($csvLineNum + 1)) . ' --', self::LOG_ERROR);
-                                break;
-                            } else {
-                                $this->_logCsvLine('-- ' . $this->l->t('Fin de ligne CSV : ' .  ($csvLineNum + 1)) . ' --', self::LOG_DEBUG);
-                            }
-
-                            $csvLineNum++;
-                        }
-                        fclose($csvFile);
-                    }
-                }
-                if ($this->_processFailOnFirstError===false || $this->_process->getHasError()<=0) {
-                    if (count($csvTodoLineList) <= 0) {
-                        $errorMsg = $this->l->t('Aucune ligne dans le fichier CSV "' . $uploadFileCSVName . '".');
-                        $this->_logCsvLine($errorMsg, self::LOG_ERROR);
-                        $this->_processErrorMsg(-1, $errorMsg);
-                    }
-                }
-                $this->_logCsvLine('## ' .$this->l->t('Fin de vérification des champs du fichier CSV.') . ' ##', self::LOG_DEBUG);
-
-                if ($this->_process->getHasError()>0)   $this->_processFailOnFirstError=true;
-                if ($this->_processFailOnFirstError===false || $this->_process->getHasError()<=0) {
-                    $this->_logCsvLine('## ' .$this->l->t('Début de l\'association des pages du PDF aux différents agents.') . ' ##', self::LOG_DEBUG);
-
-                    $this->_logCsvLine($this->l->t('Création du fichier CSV des assoications des pages de bulletins de paie aux différents agents.'), self::LOG_DEBUG);
-                    $csvCheckFilePath = $this->_checkDirFullPath . DIRECTORY_SEPARATOR . $csvCheckFileName;
-                    $csvCheckFile = fopen($csvCheckFilePath, 'w+');
-                    if (!$csvCheckFile) {
-                        $errorMsg = $this->l->t('Impossible de créer le fichier CSV "' . $csvCheckFileName . '".');
-                        $this->_logCsvLine($errorMsg, self::LOG_ERROR);
-                        $this->_processErrorMsg(-1, $errorMsg);
-                    }
-
-                    if ($this->_processFailOnFirstError===false || $this->_process->getHasError()<=0) {
-                        $checkLastValues = array(
-                            'siret'     => '',
-                            'matricule' => '',
-                            'fullname'  => '',
-                            'zip_city'  => '',
-                        );
-
-                        $checkLastLineNum = -1;
-
-                        // pour chaque page du PDF
-                        $this->_logCsvLine($this->l->t('Lecture des pages du fichier PDF.'), self::LOG_DEBUG);
-                        $pdfPageList = array();
-                        foreach ($pdfPages as $pdfPageNum => $pdfPage) {
-                            $this->_logCsvLine('-- ' . $this->l->t('Page PDF en cours : ' .  ($pdfPageNum + 1) . ' --'), self::LOG_DEBUG);
-
-                            // recuperer les champs textes dans le PDF et enlever les espaces
-                            $this->_logCsvLine($this->l->t('Récupération des champs textes du fichier PDF.'), self::LOG_DEBUG);
-                            $pdfPageTextList = array();
-                            $pdfPageTextArr = $pdfPage->getTextArray();
-                            foreach ($pdfPageTextArr as $pdfPageTextKey => $pdfPageText) {
-                                // formater les champs textes du PDF (enlever les espaces)
-                                $pdfPageTextList[] = trim($pdfPageText);
-                            }
-
-                            // pour chaque ligne du CSV restant a traiter
-                            $this->_logCsvLine($this->l->t('Lecture des lignes fichier CSV.'), self::LOG_DEBUG);
-                            $csvTodoLineNum = 0;
-                            $csvTodoLine = array();
-                            $checkCurrentValues = array();
-                            $pdfPageValues = array();
-                            $agentFound = false;
-                            foreach ($csvTodoLineList as $csvTodoLineNum => $csvTodoLine) {
-                                $this->_logCsvLine('-- ' . $this->l->t('Début de ligne CSV : ' .  ($csvTodoLineNum + 1)) . ' --', self::LOG_DEBUG);
-
-                                // recuperer les valeurs de controle
-                                $checkCurrentValues = array(
-                                    'siret'     => $csvTodoLine['siret'],
-                                    'matricule' => $csvTodoLine['matricule'],
-                                    'fullname'  => $csvTodoLine['fullname'],
-                                    'zip_city'  => $csvTodoLine['zip_city'],
-                                );
-
-                                $pdfPageValues = array();
-
-                                // pour chaque champ CSV a controler
-                                foreach ($checkCurrentValues as $checkField => $checkCurrentValue) {
-                                    // verifier d'abord aux emplacements previsibles du PDF
-                                    if ($checkField == 'siret') {
-                                        // siret
-                                        if (isset($this->_payslipPDFSearchFieldList[$checkField]) && !empty($this->_payslipPDFSearchFieldList[$checkField])) {
-                                            foreach ($this->_payslipPDFSearchFieldList[$checkField] as $payslipPDFSearchFieldIndex) {
-                                                $matchList = array();
-                                                if (preg_match('#SIRET:\s(\d+)\s\d+$#', $pdfPageTextList[$payslipPDFSearchFieldIndex], $matchList)) {
-                                                   if ($matchList[1] == $checkCurrentValue) {
-                                                        $pdfPageValues[$checkField] = $checkCurrentValue;
-                                                        continue;
-                                                    }
-                                                }
-                                            }
-                                        }
-                                    } else {
-                                        // siret, matricule, fullname, zip_city
-                                        if (isset($this->_payslipPDFSearchFieldList[$checkField]) && !empty($this->_payslipPDFSearchFieldList[$checkField])) {
-                                            foreach ($this->_payslipPDFSearchFieldList[$checkField] as $payslipPDFSearchFieldIndex) {
-                                                if ($pdfPageTextList[$payslipPDFSearchFieldIndex] == $checkCurrentValue) {
-                                                    $pdfPageValues[$checkField] = $checkCurrentValue;
-                                                    break;
-                                                }
-                                            }
-                                        }
-                                    }
-
-                                    if (!isset($pdfPageValues[$checkField])) {
-                                        // si on a pas trouve aux emplacement previsibles du PDF
-                                        // pour chaque champ texte de la page du PDF
-                                        foreach ($pdfPageTextList as $pdfPageTextKey => $pdfPageText) {
-                                            // formater les champs textes du PDF (enlever les espaces)
-                                            $pdfPageTextValue = trim($pdfPageText);
-
-                                            if ($checkField == 'siret') {
-                                                $matchList = array();
-                                                if (preg_match('#SIRET:\s(\d+)\s\d+$#', $pdfPageTextValue, $matchList)) {
-                                                    if ($matchList[1] == $checkCurrentValue) {
-                                                        $pdfPageValues[$checkField] = $checkCurrentValue;
-                                                        break;
-                                                    }
-                                                }
-                                            } else {
-                                                // siret, matricule, fullname, zip_city
-                                                if ($pdfPageTextValue == $checkCurrentValue) {
-                                                    $pdfPageValues[$checkField] = $checkCurrentValue;
-                                                    break;
-                                                }
-                                            }
-                                        }
-                                    }
-                                }
-
-                                // verifie si on a trouve un agent correspondant a la ligne du fichier CSV en cours
-                                $agentFound = false;
-                                if (!empty($pdfPageValues)) {
-                                    foreach ($checkCurrentValues as $checkField => $checkCurrentValue) {
-                                        if (!isset($pdfPageValues[$checkField]) || empty($pdfPageValues[$checkField])) {
-                                            $agentFound = false;
-                                            break;
-                                        } else {
-                                            $agentFound = true;
-                                        }
-                                    }
-                                }
-                                if ($agentFound === true) {
-                                    break;
-                                }
-
-                                $this->_logCsvLine('-- ' . $this->l->t('Fin de ligne CSV : ' .  ($csvTodoLineNum + 1)) . ' --', self::LOG_DEBUG);
-                            }
-
-                            if ($agentFound !== true) {
-                                $errorMsg = $this->l->t('Aucun agent trouve dans la page ' . ($pdfPageNum + 1) . ' du PDF correspondant aux lignes du fichier CSV.');
-                                $this->_logCsvLine($errorMsg, self::LOG_ERROR);
-                                $this->_processErrorMsg(-1, $errorMsg);
-                                break;
-                            } else {
-                                // si on a bien trouve l'agent correspondant a la page du PDF
-                                $siret = $csvTodoLine['siret'];
-                                $matricule = $csvTodoLine['matricule'];
-                                $period = $csvTodoLine['start_date'] . '_' . $csvTodoLine['end_date'];
-                                $agentKey = $siret . '-' . $matricule;
-                                $this->_logCsvLine($this->l->t('Agent trouvé [siret=' . $siret . ', matricule=' . $matricule . ', period=' . $period . '].'), self::LOG_DEBUG);
-
-                                $newAgent = false;
-                                foreach ($checkLastValues as $checkLastField => $checLastValue) {
-                                    if ($pdfPageValues[$checkLastField] != $checLastValue) {
-                                        $newAgent = true;
-                                        break;
-                                    }
-                                }
-
-                                if ($newAgent === true) {
-                                    $this->_logCsvLine($this->l->t('C\'est un nouvel agent.'), self::LOG_DEBUG);
-                                    $this->_logCsvLine($this->l->t('Ajout de la page ' . ($pdfPageNum + 1) .' du PDF des bulletins de paie de l\'agent.'), self::LOG_DEBUG);
-
-                                    $pdfPageList[$agentKey] = array('page_num_list' => array($pdfPageNum + 1), 'period' => $period);
-
-                                    if ($checkLastLineNum >= 0) {
-                                        // mettre ligne CSV dans fichier CSV qui va servir pour l'indexation (y ajouter les numeros de pages du fichier PDF)
-                                        $checkAgentKey = $csvTodoLineList[$checkLastLineNum]['siret'] . '-' . $csvTodoLineList[$checkLastLineNum]['matricule'];
-                                        $csvTodoLineList[$checkLastLineNum]['pdf_pages'] = implode('-', $pdfPageList[$checkAgentKey]['page_num_list']);
-                                        fputcsv($csvCheckFile, $csvTodoLineList[$checkLastLineNum], $this->_csvDelimiter, $this->_csvEnclosure);
-                                        unset($csvTodoLineList[$checkLastLineNum]); // enlever ligne de l'ancien agent
-                                    }
-
-                                    // sauvegarder le numero de la ligne CSV lie a l'ancien agent
-                                    $checkLastLineNum = $csvTodoLineNum;
-
-                                    // mettre les nouvelles valeurs dans les anciennes valeurs a verifier
-                                    $checkLastValues = $checkCurrentValues;
-                                } else {
-                                    $this->_logCsvLine($this->l->t('Ajout de la page ' . ($pdfPageNum + 1) .' du PDF des bulletins de paie de l\'agent.'), self::LOG_DEBUG);
-                                    $pdfPageList[$agentKey]['page_num_list'][] = $pdfPageNum + 1;
-                                }
-
-                                // cas de la derniere page du PDF
-                                if ($pdfPageNum == $pdfPageNb - 1) {
-                                    if ($checkLastLineNum >= 0) {
-                                        // mettre ligne CSV dans fichier CSV qui va servir pour l'indexation (y ajouter les numeros de pages du fichier PDF)
-                                        $checkAgentKey = $csvTodoLineList[$checkLastLineNum]['siret'] . '-' . $csvTodoLineList[$checkLastLineNum]['matricule'];
-                                        $csvTodoLineList[$checkLastLineNum]['pdf_pages'] = implode('-', $pdfPageList[$checkAgentKey]['page_num_list']);
-                                        fputcsv($csvCheckFile, $csvTodoLineList[$checkLastLineNum], $this->_csvDelimiter, $this->_csvEnclosure);
-                                        unset($csvTodoLineList[$checkLastLineNum]); // enlever ligne de l'ancien agent
-                                    }
-                                }
-                            }
-
-                            $this->_logCsvLine('-- ' . $this->l->t('Fin de page PDF : ' .  ($pdfPageNum + 1) . ' --'), self::LOG_DEBUG);
-                        }
-                        fclose($csvCheckFile);
-
-                        if ($this->_processFailOnFirstError===false || $this->_process->getHasError()<=0) {
-                            // Si on n'a pas traite toutes les lignes du CSV
-                            if (count($csvTodoLineList) > 0) {
-                                $errorMsgLines = array();
-                                $errorMsgLines[] = $this->l->t('Des lignes du fichier CSV "' . $uploadFileCSVName . '" n\'ont pas été traitées') . ' : ';
-                                foreach ($csvTodoLineList as $csvTodoLineNum => $csvTodoLine) {
-                                    $errorMsgLines[] = ' - ' . $this->l->t('la ligne ' . $csvTodoLine['line_num']);
-                                }
-                                $this->_logCsvLine(implode("\n", $errorMsgLines), self::LOG_ERROR);
-                                $this->_processErrorMsg(-1, implode('<br />', $errorMsgLines));
-                            }
-                        }
-                        $this->_logCsvLine('## ' .$this->l->t('Fin de l\'association des pages du PDF aux différents agents.') . ' ##', self::LOG_DEBUG);
-                    }
-
-                    // Phase - decoupage des pages du fichier PDF
-                    if ($this->_process->getHasError()>0)   $this->_processFailOnFirstError = true;
-                    if ($this->_processFailOnFirstError===false || $this->_process->getHasError()<=0) {
-                        $this->_logCsvLine('## ' . $this->l->t('Début de découpage des pages du fichier PDF.') . ' ##', self::LOG_DEBUG);
-
-                        // ouvrir le fichier CSV du dossier "check"
-                        $this->_logCsvLine($this->l->t('Ouverture des lignes du fichier CSV contenant les pages des bulletins de paie à découper.'), self::LOG_DEBUG);
-                        $csvCheckFilePath = $this->_checkDirFullPath . DIRECTORY_SEPARATOR . $csvCheckFileName;
-                        $csvCheckFile = fopen($csvCheckFilePath, 'r');
-                        if (!$csvCheckFile) {
-                            $errorMsg = $this->l->t('Impossible d\'ouvrir le fichier CSV "' . $csvCheckFileName . '".');
-                            $this->_logCsvLine($errorMsg, self::LOG_ERROR);
-                            $this->_processErrorMsg(-1, $errorMsg);
-                        }
-
-                        if ($this->_processFailOnFirstError===false || $this->_process->getHasError()<=0) {
-                            // pour chaque ligne CSV
-                            $this->_logCsvLine($this->l->t('Lecture des lignes fichier CSV.'), self::LOG_DEBUG);
-                            $csvCheckLineNum = 0;
-                            while ($csvCheckLine = fgetcsv($csvCheckFile, $this->_csvLength, $this->_csvDelimiter, $this->_csvEnclosure)) {
-                                $this->_logCsvLine('-- ' . $this->l->t('Début de ligne CSV : ' .  ($csvCheckLineNum + 1)) . ' --', self::LOG_DEBUG);
-                                //$csvCheckArr[] = array(
-                                //    'siret'         => $csvCheckLine[0],
-                                //    'matricule_ori' => $csvCheckLine[1],
-                                //    'lastname'      => $csvCheckLine[2],
-                                //    'firstname'     => $csvCheckLine[3],
-                                //    'zip_city'      => $csvCheckLine[4],
-                                //    'start_date'    => $csvCheckLine[5],
-                                //    'end_date'      => $csvCheckLine[6],
-                                //    'edition_date'  => $csvCheckLine[7],
-                                //    'matricule'     => $csvCheckLine[8],
-                                //    'fullname'      => $csvCheckLine[9],
-                                //    'email'         => $csvCheckLine[10],
-                                //    'line_num'      => $csvCheckLine[11],
-                                //    'pdf_pages'     => $csvCheckLine[12],
-                                //);
-
-                                // get CSV data values
-                                $csvCheckMatricule = $csvCheckLine[8];
-                                $pdfPageNumList = explode('-', $csvCheckLine[12]);
-                                $this->_logCsvLine($this->l->t('Découpage des pages du PDF pour le bulletin de paie de l\'agent [matricule=' . $csvCheckMatricule . '].'), self::LOG_DEBUG);
-
-                                // ajout des pages
-                                $this->_logCsvLine($this->l->t('Ajout des pages PDF au bulletin de paie.'), self::LOG_DEBUG);
-                                $pdfPayslip = new \setasign\Fpdi\Fpdi();
-                                foreach ($pdfPageNumList as $pdfPageNum) {
-                                    $this->_logCsvLine($this->l->t('Ajout de la page ' . $pdfPageNum . '.'), self::LOG_DEBUG);
-                                    $pdfPayslip->AddPage();
-                                    $pdfPayslip->setSourceFile($pdfFilePath);
-                                    $tplPayslipId = $pdfPayslip->importPage($pdfPageNum);
-                                    $pdfPayslip->useTemplate($tplPayslipId);
-                                }
-
-                                /// mettre la fiche de paie dans le dossier "check"
-                                $this->_logCsvLine($this->l->t('Créer le PDF du bulletin de paie.'), self::LOG_DEBUG);
-                                $pdfPayslip->Output('F', $this->_checkDirFullPath . DIRECTORY_SEPARATOR . ($csvCheckLineNum + 1) . '_' . $csvCheckMatricule . '.pdf');
-
-                                $this->_logCsvLine('-- ' . $this->l->t('Fin de ligne CSV : ' .  ($csvCheckLineNum + 1)) . ' --', self::LOG_DEBUG);
-
-                                $csvCheckLineNum++;
-                            }
-                            fclose($csvCheckFile);
-                        }
-
-                        $this->_logCsvLine('## ' . $this->l->t('Fin de découpage des pages du fichier PDF.') . ' ##', self::LOG_DEBUG);
-                    }
-                }
-
-                if ($this->_process->getHasError() <= 0) {
-                    $successMsg = $this->l->t('Opération "' . self::_getPhaseName($this->_process->getPhase()) . '" terminée avec succès.');
-                    $this->_logCsvLine($successMsg, self::LOG_SUCCESS);
-                    $this->_msgList['success'][] = $successMsg;
-                    $this->_process->setPhase(2);
-                    $this->_process->setCsvCheck($csvCheckFileName);
-                }
-
-                $this->_logCsvLine('## ' .$this->l->t('Fin du processus de vérification.') . ' ##', self::LOG_DEBUG);
-                fclose($this->_logFile);
-                $renamed = Filesystem::rename($logFilePath, $logFilePath . '.csv');
-                $this->_process->setProcessing(0);
-                $this->_dematpayslipProcessMapper->update($this->_process);
-            }
+        // check user
+        if ($this->_userId === $this->_dematpayslipConfigList['user_id']) {
+            $this->_dematpaylsipProcess->check();
 
             return new TemplateResponse('dematpayslip', 'index', $this->_assignParamsDemat());
         } else {
@@ -1768,674 +500,667 @@ class PageController extends Controller {
     }
 
     /**
-     * Phase Indexation
+     * Indexation phase
+     *
      * @NoAdminRequired
      *
-     * @param   int                 $retry
      * @return  TemplateResponse
      *
-     * @throws  NotFoundException
-     * @throws  OC\User\NoUserException
-     * @throws  \OCP\Files\InvalidPathException
-     * @throws  \setasign\Fpdi\PdfParser\CrossReference\CrossReferenceException
-     * @throws  \setasign\Fpdi\PdfParser\Filter\FilterException
-     * @throws  \setasign\Fpdi\PdfParser\PdfParserException
-     * @throws  \setasign\Fpdi\PdfParser\Type\PdfTypeException
-     * @throws  \setasign\Fpdi\PdfReader\PdfReaderException
+     * @throws  Exception
      */
-    public function indexation(int $retry) {
+    public function indexation() {
         // verifier l'utilisateur
-        if ($this->userId === $this->_dematpayslipConfigList['user_id']) {
-            $this->_initDematUser();
-
-            if ($retry > 0) {
-                $this->_process->setHasError(0);
-                $this->_process->setErrorCode(0);
-                $this->_process->setErrorMsg('');
-            }
-
-            $this->_processCheck();
-            if ($this->_process->getPhase() < self::PHASE_ID_INDEXATION) {
-                $this->_msgList['error'][] = $this->l->t('Opération impossible : phase en cours "' . self::_getPhaseName($this->_process->getPhase()) . '".');
-            }
-
-            $launchIndexation = filter_input(INPUT_POST, 'payslip_launch_indexation', FILTER_SANITIZE_NUMBER_INT);
-            $launchArchive    = filter_input(INPUT_POST, 'payslip_launch_archive', FILTER_SANITIZE_NUMBER_INT);
-            $launchIndexation = intval($launchIndexation);
-            $launchArchive    = intval($launchArchive);
-            if ($this->_pastellAppExists === true) {
-                if ($launchIndexation != 1 && $launchArchive != 1) {
-                    $this->_msgList['error'][] = $this->l->t('Veuillez sélectionner au moins un élément entre "Indexation" et "Archivage".');
-                }
-            }
-
-            if (count($this->_msgList['error']) <= 0) {
-                try {
-                    $phaseStartDateTime = new DateTime('now', OC::$server->getDateTimeZone()->getTimeZone());
-                    $phaseStartTime = $phaseStartDateTime->getTimestamp();
-
-                    // log file
-                    $logFilePath = $this->_reportDirUserPath . DIRECTORY_SEPARATOR . $phaseStartDateTime->format('Y-m-d_H-i-s') . '_' . $this->_process->getPhase() . '_log';
-                    $this->_logFile = Filesystem::fopen($logFilePath, 'w+');
-                    $this->_logCsvCols(array('date', 'heure', 'niveau', 'message', 'siret', 'matricule', 'nom_prenom', 'zip_city', 'date_debut', 'date_fin', 'email'));
-                    $this->_logCsvLine('## ' . $this->l->t('Début du processus d\'indexation.') . ' ##', self::LOG_DEBUG);
-
-                    $this->_process->setProcessing(1);
-                    $this->_process->setPhase(2);
-                    $this->_process->setPhaseStartTime($phaseStartTime);
-                    if (!($retry > 0)) {
-                        $this->_process->setPhaseStepNum(0);
-                    }
-                    $this->_process->setMustTerminate(1);
-                    $this->_process->setHasError(0);
-                    $this->_process->setErrorCode(0);
-                    $this->_process->setErrorMsg('');
-                    $this->_process->setUserId($this->userId);
-                    $this->_dematpayslipProcessMapper->update($this->_process);
-
-                    $payslipsDirPath = $this->_dematpayslipConfigList['payslip_dir'];
-                    $csvCheckFileName = $this->_process->getCsvCheck();
-
-                    // recuperer et monter le dossier de l'utilisateur Nextcloud
-                    $this->_logCsvLine($this->l->t('Récupération et montage du dossier de l\'utilisateur Nextcloud.'), self::LOG_DEBUG);
-                    $userHomeFilesDirPath = '';
-                    if ($this->_process->getHasError() <= 0) {
-                        $user = OC::$server->getUserManager()->get($this->userId);
-                        if (!$user) {
-                            $errorMsg = $this->l->t('Le dossier utilisateur "' . $this->userId . '" n\'existe pas.');
-                            $this->_logCsvLine($errorMsg, self::LOG_ERROR);
-                            $this->_processErrorMsg(-1, $errorMsg);
-                        }
-
-                        $userHomeFilesDirPath = $user->getHome() . DIRECTORY_SEPARATOR . 'files';
-                    }
-                    if (empty($userHomeFilesDirPath) || !is_dir($userHomeFilesDirPath)) {
-                        $errorMsg = $this->l->t('Le dossier utilisateur "' . $this->userId . '" est introuvable.');
-                        $this->_logCsvLine($errorMsg, self::LOG_ERROR);
-                        $this->_processErrorMsg(-1, $errorMsg);
-                    }
-
-                    // verifier l'existance du dossier des bulletins
-                    $this->_logCsvLine($this->l->t('Vérification de l\'existance du dossier des bulletins.'), self::LOG_DEBUG);
-                    if ($this->_process->getHasError() <= 0) {
-                        $isDir = Filesystem::is_dir($payslipsDirPath);
-                        if (!$isDir) {
-                            $errorMsg = $this->l->t('Le dossier des bulletins "' . $payslipsDirPath . '" n\'existe pas.');
-                            $this->_logCsvLine($errorMsg, self::LOG_ERROR);
-                            $this->_processErrorMsg(-1, $errorMsg);
-                        }
-                    }
-
-                    // verifier l'existance du dossier des bulletins non indexes
-                    $this->_logCsvLine($this->l->t('Vérification de l\'existance du dossier des bulletins non indexes.'), self::LOG_DEBUG);
-                    if ($this->_process->getHasError() <= 0) {
-                        $isDir = Filesystem::is_dir($this->_payslipNoIndexDir);
-                        if (!$isDir) {
-                            $errorMsg = $this->l->t('Le dossier des bulletins non indexes "' . $this->_payslipNoIndexDir . '" n\'existe pas.');
-                            $this->_logCsvLine($errorMsg, self::LOG_ERROR);
-                            $this->_processErrorMsg(-1, $errorMsg);
-                        }
-                    }
-
-                    if ($this->_process->getHasError() <= 0) {
-                        $phaseStep = 'csv_check';
-                        $this->_logCsvLine($this->l->t('Début de la phase "' . $phaseStep . '".'), self::LOG_DEBUG);
-                        $csvCheckLineNum = 0;
-                        $retryCsvNumLine = 0;
-                        if ($retry > 0) {
-                            if ($this->_process->getPhaseStep() == $phaseStep) {
-                                $this->_process->setPhaseStep('');
-                            }
-                            $retryCsvNumLine = $this->_process->getPhaseStepNum();
-                            $this->_logCsvLine($this->l->t('Reprise à la ligne ' . ($retryCsvNumLine + 1) . ' du fichier CSV créé lors de la phase de vérification.'), self::LOG_DEBUG);
-                        }
-                        if (empty($this->_process->getPhaseStep())) {
-                            $rootFolder = OC::$server->getRootFolder();
-                            $shareManager = OC::$server->getShareManager();
-                            $userManager = OC::$server->getUserManager();
-                            $userFolder = $rootFolder->getUserFolder($this->userId);
-
-                            // recuperer tous les partages realises par cet utilisateur
-                            $this->_logCsvLine($this->l->t('Récupération des partages de "' . $payslipsDirPath . '".'), self::LOG_DEBUG);
-                            $payslipShareNode = $userFolder->get($payslipsDirPath);
-                            $payslipShareList = $shareManager->getSharesInFolder($this->userId, $payslipShareNode);
-                            $payslipMatriculeShareNodeIdList = array();
-                            if (count($payslipShareList) > 0) {
-                                foreach ($payslipShareList as $payslipShareNodeId => $payslipShareArr) {
-                                    $payslipMatriculeShareNodeIdList[] = $payslipShareNodeId;
-                                }
-                            }
-
-                            // ouverture du fichier CSV cree lors de l'etape de verification
-                            $this->_logCsvLine($this->l->t('Ouverture du fichier CSV créé lors de l\'étape de vérification.'), self::LOG_DEBUG);
-                            $csvCheckFilePath = $this->_checkDirFullPath . DIRECTORY_SEPARATOR . $csvCheckFileName;
-                            $csvCheckFile = fopen($csvCheckFilePath, 'r');
-                            if (!$csvCheckFile) {
-                                $errorMsg = $this->l->t('Impossible d\'ouvrir le fichier CSV "' . $csvCheckFileName . '".');
-                                $this->_logCsvLine($errorMsg, self::LOG_ERROR);
-                                $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
-                            }
-
-                            if ($this->_process->getHasError() <= 0) {
-                                $this->_logCsvLine($this->l->t('Lecture du fichier PDF.'), self::LOG_DEBUG);
-                                $pdfOriginFileFullPath = $this->_uploadDirFullPath . DIRECTORY_SEPARATOR . $this->_process->getPdfOrigin();
-
-                                // creer le PDF des bulletins de paie a ne pas indexer (ne pas deposer dans le dossier partage de l'agent)
-                                $pdfPayslipSkip = null;
-                                $payslipSkipPDFPath = $this->_payslipNoIndexDir . DIRECTORY_SEPARATOR . $phaseStartDateTime->format('Y-m-d_H-i-s') . '_skip';
-
-                                // identifier les lignes du fichier CSV a ne pas indexer
-                                $dematpayslipProcessSkipLineIdList = array();
-                                $dematpayslipProcessSkipList = $this->_dematpayslipProcessSkipMapper->findAllByIdProcess($this->_process->getId());
-                                foreach ($dematpayslipProcessSkipList as $dematpayslipProcessSkip) {
-                                    $dematpayslipProcessSkipLineIdList[] = $dematpayslipProcessSkip->getIdLine();
-                                }
-
-                                // payslip archive mapper
-                                $dematpayslipArchiveMapper = new DematpayslipArchiveMapper(OC::$server->getDatabaseConnection());
-
-                                $this->_logCsvLine($this->l->t('Lecture des lignes du fichier CSV créé lors de l\'étape de vérification.'), self::LOG_DEBUG);
-                                while ($csvCheckLine = fgetcsv($csvCheckFile, $this->_csvLength, $this->_csvDelimiter, $this->_csvEnclosure)) {
-                                    $this->_logCsvLine('-- ' . $this->l->t('Début de ligne CSV : ' . ($csvCheckLineNum + 1)) . ' --', self::LOG_DEBUG);
-
-                                    if ($csvCheckLineNum >= $retryCsvNumLine) {
-                                        //$csvCheckArr[] = array(
-                                        //    'siret'         => $csvCheckLine[0],
-                                        //    'matricule_ori' => $csvCheckLine[1],
-                                        //    'lastname'      => $csvCheckLine[2],
-                                        //    'firstname'     => $csvCheckLine[3],
-                                        //    'zip_city'      => $csvCheckLine[4],
-                                        //    'start_date'    => $csvCheckLine[5],
-                                        //    'end_date'      => $csvCheckLine[6],
-                                        //    'edition_date'  => $csvCheckLine[7],
-                                        //    'matricule'     => $csvCheckLine[8],
-                                        //    'fullname'      => $csvCheckLine[9],
-                                        //    'email'         => $csvCheckLine[10],
-                                        //    'line_num'      => $csvCheckLine[11],
-                                        //    'pdf_pages'     => $csvCheckLine[12],
-                                        //);
-
-                                        // get CSV data values
-                                        $startDate = $csvCheckLine[5];
-                                        $endDate = $csvCheckLine[6];
-                                        $editionDate = $csvCheckLine[7];
-                                        $startDateTime = strtotime($startDate);
-                                        $year = date('Y', $startDateTime);
-                                        $month = strtolower(strftime('%B', $startDateTime));
-                                        $pdfPageNumList = explode('-', $csvCheckLine[12]);
-                                        $period = $startDate . '_' . $endDate;
-
-                                        // agent user
-                                        $agentUser = new DematpayslipUser();
-                                        $agentUser->setId(0);
-                                        $agentUser->setUserId('');
-                                        $agentUser->setSiret($csvCheckLine[0]);
-                                        $agentUser->setMatricule($csvCheckLine[8]);
-                                        $agentUser->setLastname($csvCheckLine[2]);
-                                        $agentUser->setFirstname($csvCheckLine[3]);
-                                        $agentUser->setEmail($csvCheckLine[10]);
-                                        $agentUser->setZipCity($csvCheckLine[4]);
-
-                                        // pdf check file path
-                                        $pdfPayslipCheckFileName = ($csvCheckLineNum + 1) . '_' . $agentUser->getMatricule() . '.pdf';
-                                        $pdfPayslipCheckFilePath = $this->_checkDirUserPath . DIRECTORY_SEPARATOR . $pdfPayslipCheckFileName;
-                                        $pdfPayslipFilePath = '';
-
-                                        $this->_logCsvLine($this->l->t('Ligne CSV '), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
-
-                                        // process skip lines
-                                        if (in_array($csvCheckLineNum, $dematpayslipProcessSkipLineIdList)) {
-                                            $this->_logCsvLine('-- ' . $this->l->t('Saut de la ligne CSV : ' . ($csvCheckLineNum + 1)) . ' --', self::LOG_DEBUG, $agentUser, $startDate, $endDate);
-
-                                            if ($launchIndexation == 1) {
-                                                // creer le PDF des bulletins de paie a ne pas indexer
-                                                if ($pdfPayslipSkip === null) {
-                                                    $pdfPayslipSkip = new \setasign\Fpdi\Fpdi();
-                                                }
-                                                // ajout des pages des bulletins de paie de l'agent a ne pas indexer
-                                                $this->_logCsvLine($this->l->t('Ajout des pages PDF au bulletin de paie à ne pas indexer.'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
-                                                foreach ($pdfPageNumList as $pdfPageNum) {
-                                                    $this->_logCsvLine($this->l->t('Ajout de la page ' . $pdfPageNum . '.'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
-                                                    $pdfPayslipSkip->AddPage();
-                                                    $pdfPayslipSkip->setSourceFile($pdfOriginFileFullPath);
-                                                    $tplPayslipSkipId = $pdfPayslipSkip->importPage($pdfPageNum);
-                                                    $pdfPayslipSkip->useTemplate($tplPayslipSkipId);
-                                                }
-                                            }
-
-                                            $csvCheckLineNum++;
-                                            continue;
-                                        }
-
-                                        // no user but archiving for 5 years "BulletinsNoIndex/HORODATE/SIRET-MATRICULE/PERIODE.pdf"
-                                        if (empty($agentUser->getEmail())) {
-                                            $this->_logCsvLine('-- ' . $this->l->t('Création du PDF non dématérialisé de l\'agent (aucun email) : ' . ($csvCheckLineNum + 1)) . ' --', self::LOG_DEBUG, $agentUser, $startDate, $endDate);
-
-                                            // check if not already archived (return null if already archived with warning)
-                                            $dematpayslipArchive = null;
-                                            if ($launchArchive == 1) {
-                                                $dematpayslipArchive = $this->_archiveCheckBeforeSave($dematpayslipArchiveMapper, $agentUser, $startDate, $endDate);
-                                            }
-
-                                            if ($launchArchive != 1 || ($launchArchive == 1 && !empty($dematpayslipArchive))) {
-                                                // add all agent pdf pages
-                                                $pdfPayslipNoDemat = new \setasign\Fpdi\Fpdi();
-                                                $this->_logCsvLine($this->l->t('Ajout des pages PDF au bulletin de paie à ne pas indexer.'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
-                                                foreach ($pdfPageNumList as $pdfPageNum) {
-                                                    $this->_logCsvLine($this->l->t('Ajout de la page ' . $pdfPageNum . '.'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
-                                                    $pdfPayslipNoDemat->AddPage();
-                                                    $pdfPayslipNoDemat->setSourceFile($pdfOriginFileFullPath);
-                                                    $pdfPayslipNoDematId = $pdfPayslipNoDemat->importPage($pdfPageNum);
-                                                    $pdfPayslipNoDemat->useTemplate($pdfPayslipNoDematId);
-                                                }
-
-                                                if ($launchIndexation == 1) {
-                                                    // create PDF payslip
-                                                    $payslipNoDematHorodateDirPath = $this->_payslipNoIndexDir . DIRECTORY_SEPARATOR . $phaseStartDateTime->format('Y-m-d_H-i-s');
-                                                    $isDir = Filesystem::is_dir($payslipNoDematHorodateDirPath);
-                                                    if (!$isDir) {
-                                                        $dirCreated = Filesystem::mkdir($payslipNoDematHorodateDirPath);
-                                                        if (!$dirCreated) {
-                                                            $errorMsg = $this->l->t('Impossible de créeer le dossier "' . $payslipNoDematHorodateDirPath . '".');
-                                                            $this->_logCsvLine($errorMsg, self::LOG_ERROR, $agentUser, $startDate, $endDate);
-                                                            $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
-                                                        }
-                                                    }
-                                                    $payslipNoDematHorodateAgentDirPath = $payslipNoDematHorodateDirPath . DIRECTORY_SEPARATOR . $agentUser->getSiret() . '-' . $agentUser->getMatricule();
-                                                    $isDir = Filesystem::is_dir($payslipNoDematHorodateAgentDirPath);
-                                                    if (!$isDir) {
-                                                        $dirCreated = Filesystem::mkdir($payslipNoDematHorodateAgentDirPath);
-                                                        if (!$dirCreated) {
-                                                            $errorMsg = $this->l->t('Impossible de créeer le dossier "' . $payslipNoDematHorodateAgentDirPath . '".');
-                                                            $this->_logCsvLine($errorMsg, self::LOG_ERROR, $agentUser, $startDate, $endDate);
-                                                            $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
-                                                        }
-                                                    }
-                                                    $payslipNoDematPDFPath = $payslipNoDematHorodateAgentDirPath . DIRECTORY_SEPARATOR . $startDate . '_' . $endDate;
-
-                                                    // create PDF payslip in no index folder
-                                                    $this->_logCsvLine($this->l->t('Créer le PDF du bulletin de paie non dematérialisé.'), self::LOG_DEBUG);
-                                                    $pdfPayslipNoDemat->Output('F', $userHomeFilesDirPath . DIRECTORY_SEPARATOR . $payslipNoDematPDFPath);
-                                                    $pdfPayslipFilePath = $payslipNoDematPDFPath . '.pdf';
-                                                    $renamed = Filesystem::rename($payslipNoDematPDFPath, $pdfPayslipFilePath);
-                                                    if (!$renamed) {
-                                                        $errorMsg = $this->l->t('Impossible de déplacer le PDF du bulletin de paie non dematérialisé "' . $payslipNoDematPDFPath . '".');
-                                                        $this->_logCsvLine($errorMsg, self::LOG_ERROR);
-                                                        $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
-                                                    }
-                                                }
-
-                                                // save archive and process
-                                                if ($launchArchive == 1) {
-                                                    $result = $this->_archiveSaveAndProcess($pdfPayslipCheckFilePath, $dematpayslipArchiveMapper, $dematpayslipArchive, $pdfPayslipFilePath, $agentUser, $startDate, $endDate, $year, $month, $editionDate, $phaseStartDateTime->getTimestamp());
-                                                    if ($result < 0) {
-                                                        $errorMsg = $this->l->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);
-                                                    }
-                                                }
-                                            }
-
-                                            $csvCheckLineNum++;
-                                            continue;
-                                        }
-
-                                        // get agent from email
-                                        $this->_logCsvLine($this->l->t('Récupération de l\'utilisateur Nextcloud à partir de son email [' . $agentUser->getEmail() . '].'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
-                                        $userFindByEmailList = $userManager->getByEmail($agentUser->getEmail());
-
-                                        // /!\ remove all users not available (FIX for multiple users with SAML)
-                                        if (self::USER_REMOVE_UNKNOWN == 1) {
-                                            $userFindByEmailList = self::_removeUnknownUser($userFindByEmailList);
-                                        }
-
-                                        if (count($userFindByEmailList) != 1) {
-                                            $errorMsg = $this->l->t('Impossible de trouver l\'unique utilisateur Nextcloud dont l\'email est "' . $agentUser->getEmail() . '" [matricule="' . $agentUser->getMatricule() . '"].');
-                                            $this->_logCsvLine($errorMsg, self::LOG_ERROR, $agentUser, $startDate, $endDate);
-                                            $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
-                                        }
-                                        $userFindByEmail = current($userFindByEmailList);
-                                        $userFindByEmailId = $userFindByEmail->getUID();
-
-                                        if ($this->_process->getHasError() <= 0) {
-                                            // dossier "SIRET-MATRICULE"
-                                            $siretMatriculeDirName = $agentUser->getSiret() . '-' . $agentUser->getMatricule();
-                                            $this->_logCsvLine($this->l->t('Vérification l\'existance du dossier matricule [' . $siretMatriculeDirName . '].'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
-                                            $payslipsMatriculeDirPath = $payslipsDirPath . DIRECTORY_SEPARATOR . $siretMatriculeDirName;
-                                            $isDir = Filesystem::is_dir($payslipsMatriculeDirPath);
-                                            if (!$isDir) {
-                                                $this->_logCsvLine($this->l->t('Création du dossier matricule [' . $siretMatriculeDirName . '].'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
-                                                $dirCreated = Filesystem::mkdir($payslipsMatriculeDirPath);
-                                                if (!$dirCreated) {
-                                                    $errorMsg = $this->l->t('Impossible de créer le dossier "' . $payslipsMatriculeDirPath . '" [matricule="' . $agentUser->getMatricule() . '"].');
-                                                    $this->_logCsvLine($errorMsg, self::LOG_ERROR, $agentUser, $startDate, $endDate);
-                                                    $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
-                                                }
-
-                                                // inserer l'utilisateur de la fiche de paie (association avec son siret, matricule et email)
-                                                $this->_logCsvLine($this->l->t('Insertion de l\'utilisateur de la fiche de paie : association dossier [' . $siretMatriculeDirName . '] avec email [' . $agentUser->getEmail() . '].'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
-                                                $dematpayslipUserList = $this->_dematpayslipUserMapper->findAllBySiretAndMatricule($agentUser->getSiret(), $agentUser->getMatricule());
-                                                if (empty($dematpayslipUserList)) {
-                                                    $dematpayslipUser = new DematpayslipUser();
-                                                    $dematpayslipUser->setUserId($userFindByEmailId);
-                                                    $dematpayslipUser->setSiret($agentUser->getSiret());
-                                                    $dematpayslipUser->setMatricule($agentUser->getMatricule());
-                                                    $dematpayslipUser->setEmail($agentUser->getEmail());
-                                                    $dematpayslipUser->setLastname($agentUser->getLastname());
-                                                    $dematpayslipUser->setFirstname($agentUser->getFirstname());
-                                                    $dematpayslipUser->setZipCity($agentUser->getZipCity());
-                                                    $this->_dematpayslipUserMapper->insert($dematpayslipUser);
-                                                } else {
-                                                    $errorMsg = $this->l->t('L\'utilisateur "' . $userFindByEmailId . '" est déjà associé à un dossier SIRET-MATRICULE [siret="' . $agentUser->getSiret() . '", matricule="' . $agentUser->getMatricule() . '", email="' . $agentUser->getEmail() . '"].');
-                                                    $this->_logCsvLine($errorMsg, self::LOG_ERROR, $agentUser, $startDate, $endDate);
-                                                    $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
-                                                }
-                                            }
-
-                                            if ($this->_process->getHasError() <= 0) {
-                                                // recuperer l'utilisateur associe au dossier "SIRET-MATRICULE" cree
-                                                $this->_logCsvLine($this->l->t('Récupération de l\'utilisateur associé au dossier SIRET-MATRICULE [' . $siretMatriculeDirName . '].'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
-                                                $dematpayslipUserList = $this->_dematpayslipUserMapper->findAllBySiretAndMatricule($agentUser->getSiret(), $agentUser->getMatricule());
-                                                if (count($dematpayslipUserList) === 1) {
-                                                    $dematpayslipUser = $dematpayslipUserList[0];
-
-                                                    // update user for new version
-                                                    if (empty($dematpayslipUser->getLastname()) || empty($dematpayslipUser->getFirstname()) || empty($dematpayslipUser->getZipCity())) {
-                                                        $dematpayslipUser->setLastname($agentUser->getLastname());
-                                                        $dematpayslipUser->setFirstname($agentUser->getFirstname());
-                                                        $dematpayslipUser->setZipCity($agentUser->getZipCity());
-                                                        $this->_dematpayslipUserMapper->update($dematpayslipUser);
-                                                    }
-
-                                                    // set agent user id
-                                                    $agentUser->setId($dematpayslipUser->getId());
-                                                    $agentUser->setUserId($dematpayslipUser->getUserId());
-
-                                                    // si l'utilisateur n'a pas desactive la dematerialisation de son bulletin de paie
-                                                    if ($dematpayslipUser->getDisabled() != 1) {
-                                                        $payslipsMatriculeYearDirPath = $payslipsMatriculeDirPath . DIRECTORY_SEPARATOR . $year;
-
-                                                        if ($launchIndexation == 1) {
-                                                            // creer le partage du dossier "SIRET-MATRICULE"
-                                                            $payslipsMatriculeDirPathNode = $userFolder->get($payslipsMatriculeDirPath);
-
-                                                            // verifier si le dossier n'est pas deja partage
-                                                            if (!in_array($payslipsMatriculeDirPathNode->getId(), $payslipMatriculeShareNodeIdList)) {
-                                                                // partager le dossier MATRICULE en lecture seule avec l'utilisateur trouve a partir de son email
-                                                                $this->_logCsvLine($this->l->t('Partage du dossier SIRET-MATRICULE [' . $siretMatriculeDirName . '] en lecture seule.'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
-                                                                $payslipMatriculeShare = $shareManager->newShare();
-                                                                $payslipMatriculeShare->setNode($payslipsMatriculeDirPathNode);
-                                                                $payslipMatriculeShare->setShareType(\OC\Share\Share::SHARE_TYPE_USER);
-                                                                $payslipMatriculeShare->setSharedWith($userFindByEmailId);
-                                                                $payslipMatriculeShare->setPermissions(\OCP\Constants::PERMISSION_READ);
-                                                                $payslipMatriculeShare->setSharedBy($this->userId);
-                                                                $payslipMatriculeShare = $shareManager->createShare($payslipMatriculeShare);
-                                                            } else {
-                                                                $this->_logCsvLine($this->l->t('Dossier SIRET-MATRICULE [' . $siretMatriculeDirName . '] est déjà partagé.'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
-                                                            }
-
-                                                            // dossier "SIRET-MATRICULE/ANNEE"
-                                                            $this->_logCsvLine($this->l->t('Vérification de l\'existance du dossier de l\'annéee [' . $year . '].'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
-                                                            $isDir = Filesystem::is_dir($payslipsMatriculeYearDirPath);
-                                                            if (!$isDir) {
-                                                                $this->_logCsvLine($this->l->t('Création du dossier de l\'annéee [' . $year . '].'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
-                                                                $dirCreated = Filesystem::mkdir($payslipsMatriculeYearDirPath);
-                                                                if (!$dirCreated) {
-                                                                    $errorMsg = $this->l->t('Impossible de créer le dossier "' . $payslipsMatriculeYearDirPath . '[siret="' . $agentUser->getSiret() . '", matricule="' . $agentUser->getMatricule() . '", année="' . $year . '"].');
-                                                                    $this->_logCsvLine($errorMsg, self::LOG_ERROR, $agentUser, $startDate, $endDate);
-                                                                    $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
-                                                                }
-                                                            }
-                                                        }
-
-                                                        if ($this->_process->getHasError() <= 0) {
-                                                            // check if not already archived (return null if already archived with warning)
-                                                            $dematpayslipArchive = null;
-                                                            if ($launchArchive == 1) {
-                                                                $dematpayslipArchive = $this->_archiveCheckBeforeSave($dematpayslipArchiveMapper, $agentUser, $startDate, $endDate);
-                                                            }
-
-                                                            if ($launchArchive != 1 || ($launchArchive == 1 && !empty($dematpayslipArchive))) {
-                                                                if ($launchIndexation == 1) {
-                                                                    // deplacer le fichier PDF du bulletin de paie de l'agent dans "SIRET-MATRICULE/ANNEE/PERIODE.pdf"
-                                                                    $pdfPayslipFilePath = $payslipsMatriculeYearDirPath . DIRECTORY_SEPARATOR . $period . '.pdf';
-                                                                    $this->_logCsvLine($this->l->t('Déplacement du fichier PDF du bulletin de paie de la période [' . $period . '].'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
-                                                                    $renamed = Filesystem::rename($pdfPayslipCheckFilePath, $pdfPayslipFilePath);
-                                                                    if (!$renamed) {
-                                                                        $errorMsg = $this->l->t('Impossible de déplacer le bulletin de paie "' . $pdfPayslipCheckFileName . '" dans le dossier "' . $pdfPayslipFilePath . '".');
-                                                                        $this->_logCsvLine($errorMsg, self::LOG_ERROR, $agentUser, $startDate, $endDate);
-                                                                        $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
-                                                                    }
-                                                                }
-
-                                                                // save archive and process
-                                                                if ($launchArchive == 1) {
-                                                                    $result = $this->_archiveSaveAndProcess($pdfPayslipCheckFilePath, $dematpayslipArchiveMapper, $dematpayslipArchive, $pdfPayslipFilePath, $agentUser, $startDate, $endDate, $year, $month, $editionDate, $phaseStartDateTime->getTimestamp());
-                                                                    if ($result < 0) {
-                                                                        $errorMsg = $this->l->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 {
-                                                        // agent disabled payslip
-                                                        $this->_logCsvLine($this->l->t('L\'utlisateur a désactivé la dématérialisation des fiches de paie [email=' . $agentUser->getEmail() . '].'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
-
-                                                        // check if not already archived (return null if already archived with warning)
-                                                        $dematpayslipArchive = null;
-                                                        if ($launchArchive == 1) {
-                                                            $dematpayslipArchive = $this->_archiveCheckBeforeSave($dematpayslipArchiveMapper, $agentUser, $startDate, $endDate);
-                                                        }
-
-                                                        if ($launchArchive != 1 || ($launchArchive == 1 && !empty($dematpayslipArchive))) {
-                                                            if ($launchIndexation == 1) {
-                                                                // create PDF payslip
-                                                                $payslipNoDematHorodateDirPath = $this->_payslipNoIndexDir . DIRECTORY_SEPARATOR . $phaseStartDateTime->format('Y-m-d_H-i-s');
-                                                                $isDir = Filesystem::is_dir($payslipNoDematHorodateDirPath);
-                                                                if (!$isDir) {
-                                                                    $dirCreated = Filesystem::mkdir($payslipNoDematHorodateDirPath);
-                                                                    if (!$dirCreated) {
-                                                                        $this->_msgList['error'][] = $this->l->t('Impossible de créeer le dossier "' . $payslipNoDematHorodateDirPath . '".');
-                                                                    }
-                                                                }
-                                                                $payslipNoDematHorodateAgentDirPath = $payslipNoDematHorodateDirPath . DIRECTORY_SEPARATOR . $agentUser->getSiret() . '-' . $agentUser->getMatricule();
-                                                                $isDir = Filesystem::is_dir($payslipNoDematHorodateAgentDirPath);
-                                                                if (!$isDir) {
-                                                                    $dirCreated = Filesystem::mkdir($payslipNoDematHorodateAgentDirPath);
-                                                                    if (!$dirCreated) {
-                                                                        $this->_msgList['error'][] = $this->l->t('Impossible de créeer le dossier "' . $payslipNoDematHorodateAgentDirPath . '".');
-                                                                    }
-                                                                }
-                                                                $payslipNoDematPDFPath = $payslipNoDematHorodateAgentDirPath . DIRECTORY_SEPARATOR . $startDate . '_' . $endDate;
-                                                                $pdfPayslipNoDemat = new \setasign\Fpdi\Fpdi();
-
-                                                                // add all agent pdf pages
-                                                                $this->_logCsvLine($this->l->t('Ajout des pages PDF au bulletin de paie à ne pas indexer.'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
-                                                                foreach ($pdfPageNumList as $pdfPageNum) {
-                                                                    $this->_logCsvLine($this->l->t('Ajout de la page ' . $pdfPageNum . '.'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
-                                                                    $pdfPayslipNoDemat->AddPage();
-                                                                    $pdfPayslipNoDemat->setSourceFile($pdfOriginFileFullPath);
-                                                                    $pdfPayslipNoDematId = $pdfPayslipNoDemat->importPage($pdfPageNum);
-                                                                    $pdfPayslipNoDemat->useTemplate($pdfPayslipNoDematId);
-                                                                }
-
-                                                                // create PDF payslip in no index folder
-                                                                $this->_logCsvLine($this->l->t('Créer le PDF du bulletin de paie non dematérialisé.'), self::LOG_DEBUG);
-                                                                $pdfPayslipNoDemat->Output('F', $userHomeFilesDirPath . DIRECTORY_SEPARATOR . $payslipNoDematPDFPath);
-                                                                $pdfPayslipFilePath = $payslipNoDematPDFPath . '.pdf';
-                                                                $renamed = Filesystem::rename($payslipNoDematPDFPath, $pdfPayslipFilePath);
-                                                                if (!$renamed) {
-                                                                    $errorMsg = $this->l->t('Impossible de déplacer le PDF du bulletin de paie non dematérialisé "' . $payslipNoDematPDFPath . '".');
-                                                                    $this->_logCsvLine($errorMsg, self::LOG_ERROR);
-                                                                    $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
-                                                                }
-                                                            }
-
-                                                            // save archive and process
-                                                            if ($launchArchive == 1) {
-                                                                $result = $this->_archiveSaveAndProcess($pdfPayslipCheckFilePath, $dematpayslipArchiveMapper, $dematpayslipArchive, $pdfPayslipFilePath, $agentUser, $startDate, $endDate, $year, $month, $editionDate, $phaseStartDateTime->getTimestamp());
-                                                                if ($result < 0) {
-                                                                    $errorMsg = $this->l->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 {
-                                                    $errorMsg = $this->l->t('L\'utilisateur "' . $userFindByEmailId . '" n\'a pas de dossier SIRET-MATRICULE associé [siret="' . $agentUser->getSiret() . '", matricule="' . $agentUser->getMatricule() . '", email="' . $agentUser->getEmail() . '"].');
-                                                    $this->_logCsvLine($errorMsg, self::LOG_ERROR, $agentUser, $startDate, $endDate);
-                                                    $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
-                                                }
-                                            }
-                                        }
-                                    }
-
-                                    if ($this->_process->getHasError() > 0) {
-                                        $this->_logCsvLine('-- ' . $this->l->t('Fin de ligne CSV : ' . ($csvCheckLineNum + 1)) . ' --', self::LOG_ERROR);
-                                        break;
-                                    } else {
-                                        $this->_logCsvLine('-- ' . $this->l->t('Fin de ligne CSV : ' . ($csvCheckLineNum + 1)) . ' --', self::LOG_SUCCESS);
-                                    }
-
-                                    $csvCheckLineNum++;
-                                }
-                                fclose($csvCheckFile);
-
-                                // creer le PDF des bulletins de paie a ne pas indexer
-                                if ($pdfPayslipSkip !== null) {
-                                    $this->_logCsvLine($this->l->t('Créer le PDF des bulletins de paie a ne pas indexer.'), self::LOG_DEBUG);
-                                    $pdfPayslipSkip->Output('F', $userHomeFilesDirPath . DIRECTORY_SEPARATOR . $payslipSkipPDFPath);
-                                    $renamed = Filesystem::rename($payslipSkipPDFPath, $payslipSkipPDFPath . '.pdf');
-                                    if (!$renamed) {
-                                        $errorMsg = $this->l->t('Impossible de déplacer le PDF des bulletins de paie a ne pas indexer "' . $payslipSkipPDFPath . '".');
-                                        $this->_logCsvLine($errorMsg, self::LOG_ERROR);
-                                        $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
-                                    }
-                                }
-                            }
-                        }
-
-                        if ($this->_process->getHasError() <= 0) {
-                            $phaseStep = 'report';
-                            $phaseStepNum = 0;
-                            $retryPhaseStepNum = $phaseStepNum;
-                            if ($retry > 0) {
-                                if ($this->_process->getPhaseStep() == $phaseStep) {
-                                    $this->_process->setPhaseStep('');
-                                }
-                                $retryPhaseStepNum = $this->_process->getPhaseStepNum();
-                            }
-                            if (empty($this->_process->getPhaseStep())) {
-                                $reportSubDirName = $phaseStartDateTime->format('Y-m-d_H-i-s');
-                                $reportSubDirPath = $this->_reportDirUserPath . DIRECTORY_SEPARATOR . $reportSubDirName;
-
-                                // creer le sous dossier du rapport
-                                if ($phaseStepNum >= $retryPhaseStepNum) {
-                                    $this->_logCsvLine($this->l->t('Création du dossier de rapport.'), self::LOG_DEBUG);
-                                    $dirCreated = Filesystem::mkdir($reportSubDirPath);
-                                    if (!$dirCreated) {
-                                        $errorMsg = $this->l->t('Impossible de créer le dossier du rapport "' . $reportSubDirName . '".');
-                                        $this->_logCsvLine($errorMsg, self::LOG_ERROR);
-                                        $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $phaseStepNum);
-                                    }
-                                }
-
-                                if ($this->_process->getHasError() <= 0) {
-                                    // deplacer le fichier CSV Upload dans le dossier Report
-                                    $phaseStepNum++;
-                                    if ($phaseStepNum >= $retryPhaseStepNum) {
-                                        $csvUploadFileName = $this->_process->getCsvOrigin();
-                                        if (!empty($csvUploadFileName)) {
-                                            $this->_logCsvLine($this->l->t('Déplacement du fichier CSV d\'upload dans le dossier du rapport.'), self::LOG_DEBUG);
-                                            $csvUploadFileUserPath = $this->_uploadDirUserPath . DIRECTORY_SEPARATOR . $csvUploadFileName;
-                                            $reportFileUserPath = $reportSubDirPath . DIRECTORY_SEPARATOR . $csvUploadFileName;
-                                            $renamed = Filesystem::rename($csvUploadFileUserPath, $reportFileUserPath);
-                                            if (!$renamed) {
-                                                $errorMsg = $this->l->t('Impossible de déplacer le fichier CSV d\'upload "' . $csvUploadFileName . '" dans le dossier du rapport "' . $reportSubDirName . '".');
-                                                $this->_logCsvLine($errorMsg, self::LOG_ERROR);
-                                                $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $phaseStepNum);
-                                            }
-                                        }
-                                    }
-
-                                    // deplacer le fichier PDF Upload dans le dossier Report
-                                    $phaseStepNum++;
-                                    if ($phaseStepNum >= $retryPhaseStepNum) {
-                                        $pdfUploadFileName = $this->_process->getPdfOrigin();
-                                        if (!empty($pdfUploadFileName)) {
-                                            $this->_logCsvLine($this->l->t('Déplacement du fichier PDF d\'upload dans le dossier du rapport.'), self::LOG_DEBUG);
-                                            $pdfUploadFileUserPath = $this->_uploadDirUserPath . DIRECTORY_SEPARATOR . $pdfUploadFileName;
-                                            $reportFileUserPath = $reportSubDirPath . DIRECTORY_SEPARATOR . $pdfUploadFileName;
-                                            $renamed = Filesystem::rename($pdfUploadFileUserPath, $reportFileUserPath);
-                                            if (!$renamed) {
-                                                $errorMsg = $this->l->t('Impossible de déplacer le fichier PDF d\'upload "' . $pdfUploadFileName . '" dans le dossier du rapport "' . $reportSubDirName . '".');
-                                                $this->_logCsvLine($errorMsg, self::LOG_ERROR);
-                                                $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $phaseStepNum);
-                                            }
-                                        }
-                                    }
-
-                                    // deplacer le fichier CSV de traitement dans le dossier Report
-                                    $phaseStepNum++;
-                                    if ($phaseStepNum >= $retryPhaseStepNum) {
-                                        if (!empty($csvCheckFileName)) {
-                                            $this->_logCsvLine($this->l->t('Déplacement du fichier CSV créé après vérification dans le dossier du rapport.'), self::LOG_DEBUG);
-                                            $csvCheckFileUserPath = $this->_checkDirUserPath . DIRECTORY_SEPARATOR . $csvCheckFileName;
-                                            $reportFileUserPath = $reportSubDirPath . DIRECTORY_SEPARATOR . $csvCheckFileName;
-                                            $renamed = Filesystem::rename($csvCheckFileUserPath, $reportFileUserPath);
-                                            if (!$renamed) {
-                                                $errorMsg = $this->l->t('Impossible de déplacer le fichier CSV de vérification "' . $csvCheckFileName . '" dans le dossier du rapport "' . $reportSubDirName . '".');
-                                                $this->_logCsvLine($errorMsg, self::LOG_ERROR);
-                                                $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $phaseStepNum);
-                                            }
-                                        }
-                                    }
-
-                                    // deplacer le fichier de log cree lors de la phase de verification
-                                    $phaseStepNum++;
-                                    if ($phaseStepNum >= $retryPhaseStepNum) {
-                                        // recuperation du fichier de log cree lors de la phase de verification
-                                        $logCheckFileName = self::PHASE_ID_CHECK . '_log.csv';
-                                        if (!empty($logCheckFileName)) {
-                                            $this->_logCsvLine($this->l->t('Déplacement du fichier de Log créé après vérification dans le dossier du rapport.'), self::LOG_DEBUG);
-                                            $logCheckFileUserPath = $this->_checkDirUserPath . DIRECTORY_SEPARATOR . $logCheckFileName;
-                                            $reportFileUserPath = $reportSubDirPath . DIRECTORY_SEPARATOR . $logCheckFileName;
-                                            $renamed = Filesystem::rename($logCheckFileUserPath, $reportFileUserPath);
-                                            if (!$renamed) {
-                                                $errorMsg = $this->l->t('Impossible de déplacer le fichier de Log de vérification "' . $logCheckFileName . '" dans le dossier du rapport "' . $reportSubDirName . '".');
-                                                $this->_logCsvLine($errorMsg, self::LOG_ERROR);
-                                                $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $phaseStepNum);
-                                            }
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    }
-
-                    if ($this->_process->getHasError() <= 0) {
-                        $successMsg = 'Opération "' . self::_getPhaseName($this->_process->getPhase()) . '" terminée avec succès.';
-                        $this->_logCsvLine($this->l->t($successMsg), self::LOG_SUCCESS);
-                        $this->_msgList['success'][] = $successMsg;
-                        $this->_processInit();
-                    }
-
-                    $this->_logCsvLine('## ' . $this->l->t('Fin du processus d\'indexation.') . ' ##', self::LOG_DEBUG);
-                    fclose($this->_logFile);
-                    // rename (sync file)
-                    $renamed = Filesystem::rename($logFilePath, $logFilePath . '.csv');
-                    $this->_process->setProcessing(0);
-                    $this->_dematpayslipProcessMapper->update($this->_process);
-                    // vider les lignes du process a sauter
-                    $this->_dematpayslipProcessSkipMapper->deleteAllByIdProcess($this->_process->getId());
-                } catch (Exception $e) {
-                    $errorMsg = 'Exception ' . __METHOD__ . ' : error=' . $e->getMessage();
-                    $this->_msgList['error'][] = $errorMsg;
-                }
-            }
+        if ($this->_userId === $this->_dematpayslipConfigList['user_id']) {
+            // add in archive table for job (task)
+            $this->_dematpaylsipProcess->preIndexation();
+
+//            $this->_initDematUser();
+//
+//            if ($retry > 0) {
+//                $this->_process->setHasError(0);
+//                $this->_process->setErrorCode(0);
+//                $this->_process->setErrorMsg('');
+//            }
+//
+//            $this->_processCheck();
+//            if ($this->_process->getPhase() < self::PHASE_ID_INDEXATION) {
+//                $this->_msgList['error'][] = $this->_l10n->t('Opération impossible : phase en cours "' . self::_getPhaseName($this->_process->getPhase()) . '".');
+//            }
+//
+//            $launchIndexation = filter_input(INPUT_POST, 'payslip_launch_indexation', FILTER_SANITIZE_NUMBER_INT);
+//            $launchArchive    = filter_input(INPUT_POST, 'payslip_launch_archive', FILTER_SANITIZE_NUMBER_INT);
+//            $launchIndexation = intval($launchIndexation);
+//            $launchArchive    = intval($launchArchive);
+//            if ($this->_pastellAppExists === true) {
+//                if ($launchIndexation != 1 && $launchArchive != 1) {
+//                    $this->_msgList['error'][] = $this->_l10n->t('Veuillez sélectionner au moins un élément entre "Indexation" et "Archivage".');
+//                }
+//            }
+//
+//            if (count($this->_msgList['error']) <= 0) {
+//                try {
+//                    $phaseStartDateTime = new DateTime('now', $this->_dateTimeZone->getTimeZone());
+//                    $phaseStartTime = $phaseStartDateTime->getTimestamp();
+//
+//                    // log file
+//                    $logFilePath = $this->_reportDirUserPath . DIRECTORY_SEPARATOR . $phaseStartDateTime->format('Y-m-d_H-i-s') . '_' . $this->_process->getPhase() . '_log';
+//                    $this->_logFile = Filesystem::fopen($logFilePath, 'w+');
+//                    $this->_logCsvCols(array('date', 'heure', 'niveau', 'message', 'siret', 'matricule', 'nom_prenom', 'zip_city', 'date_debut', 'date_fin', 'email'));
+//                    $this->_logCsvLine('## ' . $this->_l10n->t('Début du processus d\'indexation.') . ' ##', self::LOG_DEBUG);
+//
+//                    $this->_process->setProcessing(1);
+//                    $this->_process->setPhase(2);
+//                    $this->_process->setPhaseStartTime($phaseStartTime);
+//                    if (!($retry > 0)) {
+//                        $this->_process->setPhaseStepNum(0);
+//                    }
+//                    $this->_process->setMustTerminate(1);
+//                    $this->_process->setHasError(0);
+//                    $this->_process->setErrorCode(0);
+//                    $this->_process->setErrorMsg('');
+//                    $this->_process->setUserId($this->_userId);
+//                    $this->_dematpayslipProcessMapper->update($this->_process);
+//
+//                    $payslipsDirPath = $this->_dematpayslipConfigList['payslip_dir'];
+//                    $csvCheckFileName = $this->_process->getCsvCheck();
+//
+//                    // recuperer et monter le dossier de l'utilisateur Nextcloud
+//                    $this->_logCsvLine($this->_l10n->t('Récupération et montage du dossier de l\'utilisateur Nextcloud.'), self::LOG_DEBUG);
+//                    $userHomeFilesDirPath = '';
+//                    if ($this->_process->getHasError() <= 0) {
+//                        $user = $this->_userManager->get($this->_userId);
+//                        if (!$user) {
+//                            $errorMsg = $this->_l10n->t('Le dossier utilisateur "' . $this->_userId . '" n\'existe pas.');
+//                            $this->_logCsvLine($errorMsg, self::LOG_ERROR);
+//                            $this->_processErrorMsg(-1, $errorMsg);
+//                        }
+//
+//                        $userHomeFilesDirPath = $user->getHome() . DIRECTORY_SEPARATOR . 'files';
+//                    }
+//                    if (empty($userHomeFilesDirPath) || !is_dir($userHomeFilesDirPath)) {
+//                        $errorMsg = $this->_l10n->t('Le dossier utilisateur "' . $this->_userId . '" est introuvable.');
+//                        $this->_logCsvLine($errorMsg, self::LOG_ERROR);
+//                        $this->_processErrorMsg(-1, $errorMsg);
+//                    }
+//
+//                    // verifier l'existance du dossier des bulletins
+//                    $this->_logCsvLine($this->_l10n->t('Vérification de l\'existance du dossier des bulletins.'), self::LOG_DEBUG);
+//                    if ($this->_process->getHasError() <= 0) {
+//                        $isDir = Filesystem::is_dir($payslipsDirPath);
+//                        if (!$isDir) {
+//                            $errorMsg = $this->_l10n->t('Le dossier des bulletins "' . $payslipsDirPath . '" n\'existe pas.');
+//                            $this->_logCsvLine($errorMsg, self::LOG_ERROR);
+//                            $this->_processErrorMsg(-1, $errorMsg);
+//                        }
+//                    }
+//
+//                    // verifier l'existance du dossier des bulletins non indexes
+//                    $this->_logCsvLine($this->_l10n->t('Vérification de l\'existance du dossier des bulletins non indexes.'), self::LOG_DEBUG);
+//                    if ($this->_process->getHasError() <= 0) {
+//                        $isDir = Filesystem::is_dir($this->_payslipNoIndexDir);
+//                        if (!$isDir) {
+//                            $errorMsg = $this->_l10n->t('Le dossier des bulletins non indexes "' . $this->_payslipNoIndexDir . '" n\'existe pas.');
+//                            $this->_logCsvLine($errorMsg, self::LOG_ERROR);
+//                            $this->_processErrorMsg(-1, $errorMsg);
+//                        }
+//                    }
+//
+//                    if ($this->_process->getHasError() <= 0) {
+//                        $phaseStep = 'csv_check';
+//                        $this->_logCsvLine($this->_l10n->t('Début de la phase "' . $phaseStep . '".'), self::LOG_DEBUG);
+//                        $csvCheckLineNum = 0;
+//                        $retryCsvNumLine = 0;
+//                        if ($retry > 0) {
+//                            if ($this->_process->getPhaseStep() == $phaseStep) {
+//                                $this->_process->setPhaseStep('');
+//                            }
+//                            $retryCsvNumLine = $this->_process->getPhaseStepNum();
+//                            $this->_logCsvLine($this->_l10n->t('Reprise à la ligne ' . ($retryCsvNumLine + 1) . ' du fichier CSV créé lors de la phase de vérification.'), self::LOG_DEBUG);
+//                        }
+//                        if (empty($this->_process->getPhaseStep())) {
+//                            $userFolder = $this->_rootFolder->getUserFolder($this->_userId);
+//
+//                            // recuperer tous les partages realises par cet utilisateur
+//                            $this->_logCsvLine($this->_l10n->t('Récupération des partages de "' . $payslipsDirPath . '".'), self::LOG_DEBUG);
+//                            $payslipShareNode = $userFolder->get($payslipsDirPath);
+//                            $payslipShareList = $this->_shareManager->getSharesInFolder($this->_userId, $payslipShareNode);
+//                            $payslipMatriculeShareNodeIdList = array();
+//                            if (count($payslipShareList) > 0) {
+//                                foreach ($payslipShareList as $payslipShareNodeId => $payslipShareArr) {
+//                                    $payslipMatriculeShareNodeIdList[] = $payslipShareNodeId;
+//                                }
+//                            }
+//
+//                            // ouverture du fichier CSV cree lors de l'etape de verification
+//                            $this->_logCsvLine($this->_l10n->t('Ouverture du fichier CSV créé lors de l\'étape de vérification.'), self::LOG_DEBUG);
+//                            $csvCheckFilePath = $this->_checkDirFullPath . DIRECTORY_SEPARATOR . $csvCheckFileName;
+//                            $csvCheckFile = fopen($csvCheckFilePath, 'r');
+//                            if (!$csvCheckFile) {
+//                                $errorMsg = $this->_l10n->t('Impossible d\'ouvrir le fichier CSV "' . $csvCheckFileName . '".');
+//                                $this->_logCsvLine($errorMsg, self::LOG_ERROR);
+//                                $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
+//                            }
+//
+//                            if ($this->_process->getHasError() <= 0) {
+//                                $this->_logCsvLine($this->_l10n->t('Lecture du fichier PDF.'), self::LOG_DEBUG);
+//                                $pdfOriginFileFullPath = $this->_uploadDirFullPath . DIRECTORY_SEPARATOR . $this->_process->getPdfOrigin();
+//
+//                                // creer le PDF des bulletins de paie a ne pas indexer (ne pas deposer dans le dossier partage de l'agent)
+//                                $pdfPayslipSkip = null;
+//                                $payslipSkipPDFPath = $this->_payslipNoIndexDir . DIRECTORY_SEPARATOR . $phaseStartDateTime->format('Y-m-d_H-i-s') . '_skip';
+//
+//                                // identifier les lignes du fichier CSV a ne pas indexer
+//                                $dematpayslipProcessSkipLineIdList = array();
+//                                $dematpayslipProcessSkipList = $this->_dematpayslipProcessSkipMapper->findAllByIdProcess($this->_process->getId());
+//                                foreach ($dematpayslipProcessSkipList as $dematpayslipProcessSkip) {
+//                                    $dematpayslipProcessSkipLineIdList[] = $dematpayslipProcessSkip->getIdLine();
+//                                }
+//
+//                                // payslip archive mapper
+//                                $dematpayslipArchiveMapper = new DematpayslipArchiveMapper($this->_dbConnection);
+//
+//                                $this->_logCsvLine($this->_l10n->t('Lecture des lignes du fichier CSV créé lors de l\'étape de vérification.'), self::LOG_DEBUG);
+//                                while ($csvCheckLine = fgetcsv($csvCheckFile, $this->_csvLength, $this->_csvDelimiter, $this->_csvEnclosure)) {
+//                                    $this->_logCsvLine('-- ' . $this->_l10n->t('Début de ligne CSV : ' . ($csvCheckLineNum + 1)) . ' --', self::LOG_DEBUG);
+//
+//                                    if ($csvCheckLineNum >= $retryCsvNumLine) {
+//                                        //$csvCheckArr[] = array(
+//                                        //    'siret'         => $csvCheckLine[0],
+//                                        //    'matricule_ori' => $csvCheckLine[1],
+//                                        //    'lastname'      => $csvCheckLine[2],
+//                                        //    'firstname'     => $csvCheckLine[3],
+//                                        //    'zip_city'      => $csvCheckLine[4],
+//                                        //    'start_date'    => $csvCheckLine[5],
+//                                        //    'end_date'      => $csvCheckLine[6],
+//                                        //    'edition_date'  => $csvCheckLine[7],
+//                                        //    'matricule'     => $csvCheckLine[8],
+//                                        //    'fullname'      => $csvCheckLine[9],
+//                                        //    'email'         => $csvCheckLine[10],
+//                                        //    'line_num'      => $csvCheckLine[11],
+//                                        //    'pdf_pages'     => $csvCheckLine[12],
+//                                        //);
+//
+//                                        // get CSV data values
+//                                        $startDate = $csvCheckLine[5];
+//                                        $endDate = $csvCheckLine[6];
+//                                        $editionDate = $csvCheckLine[7];
+//                                        $startDateTime = strtotime($startDate);
+//                                        $year = date('Y', $startDateTime);
+//                                        $month = strtolower(strftime('%B', $startDateTime));
+//                                        $pdfPageNumList = explode('-', $csvCheckLine[12]);
+//                                        $period = $startDate . '_' . $endDate;
+//
+//                                        // agent user
+//                                        $agentUser = new DematpayslipUser();
+//                                        $agentUser->setId(0);
+//                                        $agentUser->setUserId('');
+//                                        $agentUser->setSiret($csvCheckLine[0]);
+//                                        $agentUser->setMatricule($csvCheckLine[8]);
+//                                        $agentUser->setLastname($csvCheckLine[2]);
+//                                        $agentUser->setFirstname($csvCheckLine[3]);
+//                                        $agentUser->setEmail($csvCheckLine[10]);
+//                                        $agentUser->setZipCity($csvCheckLine[4]);
+//
+//                                        // pdf check file path
+//                                        $pdfPayslipCheckFileName = ($csvCheckLineNum + 1) . '_' . $agentUser->getMatricule() . '.pdf';
+//                                        $pdfPayslipCheckFilePath = $this->_checkDirUserPath . DIRECTORY_SEPARATOR . $pdfPayslipCheckFileName;
+//                                        $pdfPayslipFilePath = '';
+//
+//                                        $this->_logCsvLine($this->_l10n->t('Ligne CSV '), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
+//
+//                                        // process skip lines
+//                                        if (in_array($csvCheckLineNum, $dematpayslipProcessSkipLineIdList)) {
+//                                            $this->_logCsvLine('-- ' . $this->_l10n->t('Saut de la ligne CSV : ' . ($csvCheckLineNum + 1)) . ' --', self::LOG_DEBUG, $agentUser, $startDate, $endDate);
+//
+//                                            if ($launchIndexation == 1) {
+//                                                // creer le PDF des bulletins de paie a ne pas indexer
+//                                                if ($pdfPayslipSkip === null) {
+//                                                    $pdfPayslipSkip = new \setasign\Fpdi\Fpdi();
+//                                                }
+//                                                // ajout des pages des bulletins de paie de l'agent a ne pas indexer
+//                                                $this->_logCsvLine($this->_l10n->t('Ajout des pages PDF au bulletin de paie à ne pas indexer.'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
+//                                                foreach ($pdfPageNumList as $pdfPageNum) {
+//                                                    $this->_logCsvLine($this->_l10n->t('Ajout de la page ' . $pdfPageNum . '.'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
+//                                                    $pdfPayslipSkip->AddPage();
+//                                                    $pdfPayslipSkip->setSourceFile($pdfOriginFileFullPath);
+//                                                    $tplPayslipSkipId = $pdfPayslipSkip->importPage($pdfPageNum);
+//                                                    $pdfPayslipSkip->useTemplate($tplPayslipSkipId);
+//                                                }
+//                                            }
+//
+//                                            $csvCheckLineNum++;
+//                                            continue;
+//                                        }
+//
+//                                        // no user but archiving for 5 years "BulletinsNoIndex/HORODATE/SIRET-MATRICULE/PERIODE.pdf"
+//                                        if (empty($agentUser->getEmail())) {
+//                                            $this->_logCsvLine('-- ' . $this->_l10n->t('Création du PDF non dématérialisé de l\'agent (aucun email) : ' . ($csvCheckLineNum + 1)) . ' --', self::LOG_DEBUG, $agentUser, $startDate, $endDate);
+//
+//                                            // check if not already archived (return null if already archived with warning)
+//                                            $dematpayslipArchive = null;
+//                                            if ($launchArchive == 1) {
+//                                                $dematpayslipArchive = $this->_archiveCheckBeforeSave($dematpayslipArchiveMapper, $agentUser, $startDate, $endDate);
+//                                            }
+//
+//                                            if ($launchArchive != 1 || ($launchArchive == 1 && !empty($dematpayslipArchive))) {
+//                                                // add all agent pdf pages
+//                                                $pdfPayslipNoDemat = new \setasign\Fpdi\Fpdi();
+//                                                $this->_logCsvLine($this->_l10n->t('Ajout des pages PDF au bulletin de paie à ne pas indexer.'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
+//                                                foreach ($pdfPageNumList as $pdfPageNum) {
+//                                                    $this->_logCsvLine($this->_l10n->t('Ajout de la page ' . $pdfPageNum . '.'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
+//                                                    $pdfPayslipNoDemat->AddPage();
+//                                                    $pdfPayslipNoDemat->setSourceFile($pdfOriginFileFullPath);
+//                                                    $pdfPayslipNoDematId = $pdfPayslipNoDemat->importPage($pdfPageNum);
+//                                                    $pdfPayslipNoDemat->useTemplate($pdfPayslipNoDematId);
+//                                                }
+//
+//                                                if ($launchIndexation == 1) {
+//                                                    // create PDF payslip
+//                                                    $payslipNoDematHorodateDirPath = $this->_payslipNoIndexDir . DIRECTORY_SEPARATOR . $phaseStartDateTime->format('Y-m-d_H-i-s');
+//                                                    $isDir = Filesystem::is_dir($payslipNoDematHorodateDirPath);
+//                                                    if (!$isDir) {
+//                                                        $dirCreated = Filesystem::mkdir($payslipNoDematHorodateDirPath);
+//                                                        if (!$dirCreated) {
+//                                                            $errorMsg = $this->_l10n->t('Impossible de créeer le dossier "' . $payslipNoDematHorodateDirPath . '".');
+//                                                            $this->_logCsvLine($errorMsg, self::LOG_ERROR, $agentUser, $startDate, $endDate);
+//                                                            $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
+//                                                        }
+//                                                    }
+//                                                    $payslipNoDematHorodateAgentDirPath = $payslipNoDematHorodateDirPath . DIRECTORY_SEPARATOR . $agentUser->getSiret() . '-' . $agentUser->getMatricule();
+//                                                    $isDir = Filesystem::is_dir($payslipNoDematHorodateAgentDirPath);
+//                                                    if (!$isDir) {
+//                                                        $dirCreated = Filesystem::mkdir($payslipNoDematHorodateAgentDirPath);
+//                                                        if (!$dirCreated) {
+//                                                            $errorMsg = $this->_l10n->t('Impossible de créeer le dossier "' . $payslipNoDematHorodateAgentDirPath . '".');
+//                                                            $this->_logCsvLine($errorMsg, self::LOG_ERROR, $agentUser, $startDate, $endDate);
+//                                                            $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
+//                                                        }
+//                                                    }
+//                                                    $payslipNoDematPDFPath = $payslipNoDematHorodateAgentDirPath . DIRECTORY_SEPARATOR . $startDate . '_' . $endDate;
+//
+//                                                    // create PDF payslip in no index folder
+//                                                    $this->_logCsvLine($this->_l10n->t('Créer le PDF du bulletin de paie non dematérialisé.'), self::LOG_DEBUG);
+//                                                    $pdfPayslipNoDemat->Output('F', $userHomeFilesDirPath . DIRECTORY_SEPARATOR . $payslipNoDematPDFPath);
+//                                                    $pdfPayslipFilePath = $payslipNoDematPDFPath . '.pdf';
+//                                                    $renamed = Filesystem::rename($payslipNoDematPDFPath, $pdfPayslipFilePath);
+//                                                    if (!$renamed) {
+//                                                        $errorMsg = $this->_l10n->t('Impossible de déplacer le PDF du bulletin de paie non dematérialisé "' . $payslipNoDematPDFPath . '".');
+//                                                        $this->_logCsvLine($errorMsg, self::LOG_ERROR);
+//                                                        $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
+//                                                    }
+//                                                }
+//
+//                                                // save archive and process
+//                                                if ($launchArchive == 1) {
+//                                                    $result = $this->_archiveSaveAndProcess($pdfPayslipCheckFilePath, $dematpayslipArchiveMapper, $dematpayslipArchive, $pdfPayslipFilePath, $agentUser, $startDate, $endDate, $year, $month, $editionDate, $phaseStartDateTime->getTimestamp());
+//                                                    if ($result < 0) {
+//                                                        $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);
+//                                                    }
+//                                                }
+//                                            }
+//
+//                                            $csvCheckLineNum++;
+//                                            continue;
+//                                        }
+//
+//                                        // get agent from email
+//                                        $this->_logCsvLine($this->_l10n->t('Récupération de l\'utilisateur Nextcloud à partir de son email [' . $agentUser->getEmail() . '].'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
+//                                        $userFindByEmailList = $this->_userManager->getByEmail($agentUser->getEmail());
+//
+//                                        // /!\ remove all users not available (FIX for multiple users with SAML)
+//                                        if (self::USER_REMOVE_UNKNOWN == 1) {
+//                                            $userFindByEmailList = self::_removeUnknownUser($userFindByEmailList);
+//                                        }
+//
+//                                        if (count($userFindByEmailList) != 1) {
+//                                            $errorMsg = $this->_l10n->t('Impossible de trouver l\'unique utilisateur Nextcloud dont l\'email est "' . $agentUser->getEmail() . '" [matricule="' . $agentUser->getMatricule() . '"].');
+//                                            $this->_logCsvLine($errorMsg, self::LOG_ERROR, $agentUser, $startDate, $endDate);
+//                                            $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
+//                                        }
+//                                        $userFindByEmail = current($userFindByEmailList);
+//                                        $userFindByEmailId = $userFindByEmail->getUID();
+//
+//                                        if ($this->_process->getHasError() <= 0) {
+//                                            // dossier "SIRET-MATRICULE"
+//                                            $siretMatriculeDirName = $agentUser->getSiret() . '-' . $agentUser->getMatricule();
+//                                            $this->_logCsvLine($this->_l10n->t('Vérification l\'existance du dossier matricule [' . $siretMatriculeDirName . '].'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
+//                                            $payslipsMatriculeDirPath = $payslipsDirPath . DIRECTORY_SEPARATOR . $siretMatriculeDirName;
+//                                            $isDir = Filesystem::is_dir($payslipsMatriculeDirPath);
+//                                            if (!$isDir) {
+//                                                $this->_logCsvLine($this->_l10n->t('Création du dossier matricule [' . $siretMatriculeDirName . '].'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
+//                                                $dirCreated = Filesystem::mkdir($payslipsMatriculeDirPath);
+//                                                if (!$dirCreated) {
+//                                                    $errorMsg = $this->_l10n->t('Impossible de créer le dossier "' . $payslipsMatriculeDirPath . '" [matricule="' . $agentUser->getMatricule() . '"].');
+//                                                    $this->_logCsvLine($errorMsg, self::LOG_ERROR, $agentUser, $startDate, $endDate);
+//                                                    $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
+//                                                }
+//
+//                                                // inserer l'utilisateur de la fiche de paie (association avec son siret, matricule et email)
+//                                                $this->_logCsvLine($this->_l10n->t('Insertion de l\'utilisateur de la fiche de paie : association dossier [' . $siretMatriculeDirName . '] avec email [' . $agentUser->getEmail() . '].'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
+//                                                $dematpayslipUserList = $this->_dematpayslipUserMapper->findAllBySiretAndMatricule($agentUser->getSiret(), $agentUser->getMatricule());
+//                                                if (empty($dematpayslipUserList)) {
+//                                                    $dematpayslipUser = new DematpayslipUser();
+//                                                    $dematpayslipUser->setUserId($userFindByEmailId);
+//                                                    $dematpayslipUser->setSiret($agentUser->getSiret());
+//                                                    $dematpayslipUser->setMatricule($agentUser->getMatricule());
+//                                                    $dematpayslipUser->setEmail($agentUser->getEmail());
+//                                                    $dematpayslipUser->setLastname($agentUser->getLastname());
+//                                                    $dematpayslipUser->setFirstname($agentUser->getFirstname());
+//                                                    $dematpayslipUser->setZipCity($agentUser->getZipCity());
+//                                                    $this->_dematpayslipUserMapper->insert($dematpayslipUser);
+//                                                } else {
+//                                                    $errorMsg = $this->_l10n->t('L\'utilisateur "' . $userFindByEmailId . '" est déjà associé à un dossier SIRET-MATRICULE [siret="' . $agentUser->getSiret() . '", matricule="' . $agentUser->getMatricule() . '", email="' . $agentUser->getEmail() . '"].');
+//                                                    $this->_logCsvLine($errorMsg, self::LOG_ERROR, $agentUser, $startDate, $endDate);
+//                                                    $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
+//                                                }
+//                                            }
+//
+//                                            if ($this->_process->getHasError() <= 0) {
+//                                                // recuperer l'utilisateur associe au dossier "SIRET-MATRICULE" cree
+//                                                $this->_logCsvLine($this->_l10n->t('Récupération de l\'utilisateur associé au dossier SIRET-MATRICULE [' . $siretMatriculeDirName . '].'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
+//                                                $dematpayslipUserList = $this->_dematpayslipUserMapper->findAllBySiretAndMatricule($agentUser->getSiret(), $agentUser->getMatricule());
+//                                                if (count($dematpayslipUserList) === 1) {
+//                                                    $dematpayslipUser = $dematpayslipUserList[0];
+//
+//                                                    // update user for new version
+//                                                    if (empty($dematpayslipUser->getLastname()) || empty($dematpayslipUser->getFirstname()) || empty($dematpayslipUser->getZipCity())) {
+//                                                        $dematpayslipUser->setLastname($agentUser->getLastname());
+//                                                        $dematpayslipUser->setFirstname($agentUser->getFirstname());
+//                                                        $dematpayslipUser->setZipCity($agentUser->getZipCity());
+//                                                        $this->_dematpayslipUserMapper->update($dematpayslipUser);
+//                                                    }
+//
+//                                                    // set agent user id
+//                                                    $agentUser->setId($dematpayslipUser->getId());
+//                                                    $agentUser->setUserId($dematpayslipUser->getUserId());
+//
+//                                                    // si l'utilisateur n'a pas desactive la dematerialisation de son bulletin de paie
+//                                                    if ($dematpayslipUser->getDisabled() != 1) {
+//                                                        $payslipsMatriculeYearDirPath = $payslipsMatriculeDirPath . DIRECTORY_SEPARATOR . $year;
+//
+//                                                        if ($launchIndexation == 1) {
+//                                                            // creer le partage du dossier "SIRET-MATRICULE"
+//                                                            $payslipsMatriculeDirPathNode = $userFolder->get($payslipsMatriculeDirPath);
+//
+//                                                            // verifier si le dossier n'est pas deja partage
+//                                                            if (!in_array($payslipsMatriculeDirPathNode->getId(), $payslipMatriculeShareNodeIdList)) {
+//                                                                // partager le dossier MATRICULE en lecture seule avec l'utilisateur trouve a partir de son 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);
+//                                                                $payslipMatriculeShare->setShareType(\OC\Share\Share::SHARE_TYPE_USER);
+//                                                                $payslipMatriculeShare->setSharedWith($userFindByEmailId);
+//                                                                $payslipMatriculeShare->setPermissions(\OCP\Constants::PERMISSION_READ);
+//                                                                $payslipMatriculeShare->setSharedBy($this->_userId);
+//                                                                $payslipMatriculeShare = $this->_shareManager->createShare($payslipMatriculeShare);
+//                                                            } else {
+//                                                                $this->_logCsvLine($this->_l10n->t('Dossier SIRET-MATRICULE [' . $siretMatriculeDirName . '] est déjà partagé.'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
+//                                                            }
+//
+//                                                            // dossier "SIRET-MATRICULE/ANNEE"
+//                                                            $this->_logCsvLine($this->_l10n->t('Vérification de l\'existance du dossier de l\'annéee [' . $year . '].'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
+//                                                            $isDir = Filesystem::is_dir($payslipsMatriculeYearDirPath);
+//                                                            if (!$isDir) {
+//                                                                $this->_logCsvLine($this->_l10n->t('Création du dossier de l\'annéee [' . $year . '].'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
+//                                                                $dirCreated = Filesystem::mkdir($payslipsMatriculeYearDirPath);
+//                                                                if (!$dirCreated) {
+//                                                                    $errorMsg = $this->_l10n->t('Impossible de créer le dossier "' . $payslipsMatriculeYearDirPath . '[siret="' . $agentUser->getSiret() . '", matricule="' . $agentUser->getMatricule() . '", année="' . $year . '"].');
+//                                                                    $this->_logCsvLine($errorMsg, self::LOG_ERROR, $agentUser, $startDate, $endDate);
+//                                                                    $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
+//                                                                }
+//                                                            }
+//                                                        }
+//
+//                                                        if ($this->_process->getHasError() <= 0) {
+//                                                            // check if not already archived (return null if already archived with warning)
+//                                                            $dematpayslipArchive = null;
+//                                                            if ($launchArchive == 1) {
+//                                                                $dematpayslipArchive = $this->_archiveCheckBeforeSave($dematpayslipArchiveMapper, $agentUser, $startDate, $endDate);
+//                                                            }
+//
+//                                                            if ($launchArchive != 1 || ($launchArchive == 1 && !empty($dematpayslipArchive))) {
+//                                                                if ($launchIndexation == 1) {
+//                                                                    // deplacer le fichier PDF du bulletin de paie de l'agent dans "SIRET-MATRICULE/ANNEE/PERIODE.pdf"
+//                                                                    $pdfPayslipFilePath = $payslipsMatriculeYearDirPath . DIRECTORY_SEPARATOR . $period . '.pdf';
+//                                                                    $this->_logCsvLine($this->_l10n->t('Déplacement du fichier PDF du bulletin de paie de la période [' . $period . '].'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
+//                                                                    $renamed = Filesystem::rename($pdfPayslipCheckFilePath, $pdfPayslipFilePath);
+//                                                                    if (!$renamed) {
+//                                                                        $errorMsg = $this->_l10n->t('Impossible de déplacer le bulletin de paie "' . $pdfPayslipCheckFileName . '" dans le dossier "' . $pdfPayslipFilePath . '".');
+//                                                                        $this->_logCsvLine($errorMsg, self::LOG_ERROR, $agentUser, $startDate, $endDate);
+//                                                                        $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
+//                                                                    }
+//                                                                }
+//
+//                                                                // save archive and process
+//                                                                if ($launchArchive == 1) {
+//                                                                    $result = $this->_archiveSaveAndProcess($pdfPayslipCheckFilePath, $dematpayslipArchiveMapper, $dematpayslipArchive, $pdfPayslipFilePath, $agentUser, $startDate, $endDate, $year, $month, $editionDate, $phaseStartDateTime->getTimestamp());
+//                                                                    if ($result < 0) {
+//                                                                        $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 {
+//                                                        // agent disabled payslip
+//                                                        $this->_logCsvLine($this->_l10n->t('L\'utlisateur a désactivé la dématérialisation des fiches de paie [email=' . $agentUser->getEmail() . '].'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
+//
+//                                                        // check if not already archived (return null if already archived with warning)
+//                                                        $dematpayslipArchive = null;
+//                                                        if ($launchArchive == 1) {
+//                                                            $dematpayslipArchive = $this->_archiveCheckBeforeSave($dematpayslipArchiveMapper, $agentUser, $startDate, $endDate);
+//                                                        }
+//
+//                                                        if ($launchArchive != 1 || ($launchArchive == 1 && !empty($dematpayslipArchive))) {
+//                                                            if ($launchIndexation == 1) {
+//                                                                // create PDF payslip
+//                                                                $payslipNoDematHorodateDirPath = $this->_payslipNoIndexDir . DIRECTORY_SEPARATOR . $phaseStartDateTime->format('Y-m-d_H-i-s');
+//                                                                $isDir = Filesystem::is_dir($payslipNoDematHorodateDirPath);
+//                                                                if (!$isDir) {
+//                                                                    $dirCreated = Filesystem::mkdir($payslipNoDematHorodateDirPath);
+//                                                                    if (!$dirCreated) {
+//                                                                        $this->_msgList['error'][] = $this->_l10n->t('Impossible de créeer le dossier "' . $payslipNoDematHorodateDirPath . '".');
+//                                                                    }
+//                                                                }
+//                                                                $payslipNoDematHorodateAgentDirPath = $payslipNoDematHorodateDirPath . DIRECTORY_SEPARATOR . $agentUser->getSiret() . '-' . $agentUser->getMatricule();
+//                                                                $isDir = Filesystem::is_dir($payslipNoDematHorodateAgentDirPath);
+//                                                                if (!$isDir) {
+//                                                                    $dirCreated = Filesystem::mkdir($payslipNoDematHorodateAgentDirPath);
+//                                                                    if (!$dirCreated) {
+//                                                                        $this->_msgList['error'][] = $this->_l10n->t('Impossible de créeer le dossier "' . $payslipNoDematHorodateAgentDirPath . '".');
+//                                                                    }
+//                                                                }
+//                                                                $payslipNoDematPDFPath = $payslipNoDematHorodateAgentDirPath . DIRECTORY_SEPARATOR . $startDate . '_' . $endDate;
+//                                                                $pdfPayslipNoDemat = new \setasign\Fpdi\Fpdi();
+//
+//                                                                // add all agent pdf pages
+//                                                                $this->_logCsvLine($this->_l10n->t('Ajout des pages PDF au bulletin de paie à ne pas indexer.'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
+//                                                                foreach ($pdfPageNumList as $pdfPageNum) {
+//                                                                    $this->_logCsvLine($this->_l10n->t('Ajout de la page ' . $pdfPageNum . '.'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
+//                                                                    $pdfPayslipNoDemat->AddPage();
+//                                                                    $pdfPayslipNoDemat->setSourceFile($pdfOriginFileFullPath);
+//                                                                    $pdfPayslipNoDematId = $pdfPayslipNoDemat->importPage($pdfPageNum);
+//                                                                    $pdfPayslipNoDemat->useTemplate($pdfPayslipNoDematId);
+//                                                                }
+//
+//                                                                // create PDF payslip in no index folder
+//                                                                $this->_logCsvLine($this->_l10n->t('Créer le PDF du bulletin de paie non dematérialisé.'), self::LOG_DEBUG);
+//                                                                $pdfPayslipNoDemat->Output('F', $userHomeFilesDirPath . DIRECTORY_SEPARATOR . $payslipNoDematPDFPath);
+//                                                                $pdfPayslipFilePath = $payslipNoDematPDFPath . '.pdf';
+//                                                                $renamed = Filesystem::rename($payslipNoDematPDFPath, $pdfPayslipFilePath);
+//                                                                if (!$renamed) {
+//                                                                    $errorMsg = $this->_l10n->t('Impossible de déplacer le PDF du bulletin de paie non dematérialisé "' . $payslipNoDematPDFPath . '".');
+//                                                                    $this->_logCsvLine($errorMsg, self::LOG_ERROR);
+//                                                                    $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
+//                                                                }
+//                                                            }
+//
+//                                                            // save archive and process
+//                                                            if ($launchArchive == 1) {
+//                                                                $result = $this->_archiveSaveAndProcess($pdfPayslipCheckFilePath, $dematpayslipArchiveMapper, $dematpayslipArchive, $pdfPayslipFilePath, $agentUser, $startDate, $endDate, $year, $month, $editionDate, $phaseStartDateTime->getTimestamp());
+//                                                                if ($result < 0) {
+//                                                                    $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 {
+//                                                    $errorMsg = $this->_l10n->t('L\'utilisateur "' . $userFindByEmailId . '" n\'a pas de dossier SIRET-MATRICULE associé [siret="' . $agentUser->getSiret() . '", matricule="' . $agentUser->getMatricule() . '", email="' . $agentUser->getEmail() . '"].');
+//                                                    $this->_logCsvLine($errorMsg, self::LOG_ERROR, $agentUser, $startDate, $endDate);
+//                                                    $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
+//                                                }
+//                                            }
+//                                        }
+//                                    }
+//
+//                                    if ($this->_process->getHasError() > 0) {
+//                                        $this->_logCsvLine('-- ' . $this->_l10n->t('Fin de ligne CSV : ' . ($csvCheckLineNum + 1)) . ' --', self::LOG_ERROR);
+//                                        break;
+//                                    } else {
+//                                        $this->_logCsvLine('-- ' . $this->_l10n->t('Fin de ligne CSV : ' . ($csvCheckLineNum + 1)) . ' --', self::LOG_SUCCESS);
+//                                    }
+//
+//                                    $csvCheckLineNum++;
+//                                }
+//                                fclose($csvCheckFile);
+//
+//                                // creer le PDF des bulletins de paie a ne pas indexer
+//                                if ($pdfPayslipSkip !== null) {
+//                                    $this->_logCsvLine($this->_l10n->t('Créer le PDF des bulletins de paie a ne pas indexer.'), self::LOG_DEBUG);
+//                                    $pdfPayslipSkip->Output('F', $userHomeFilesDirPath . DIRECTORY_SEPARATOR . $payslipSkipPDFPath);
+//                                    $renamed = Filesystem::rename($payslipSkipPDFPath, $payslipSkipPDFPath . '.pdf');
+//                                    if (!$renamed) {
+//                                        $errorMsg = $this->_l10n->t('Impossible de déplacer le PDF des bulletins de paie a ne pas indexer "' . $payslipSkipPDFPath . '".');
+//                                        $this->_logCsvLine($errorMsg, self::LOG_ERROR);
+//                                        $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
+//                                    }
+//                                }
+//                            }
+//                        }
+//
+//                        if ($this->_process->getHasError() <= 0) {
+//                            $phaseStep = 'report';
+//                            $phaseStepNum = 0;
+//                            $retryPhaseStepNum = $phaseStepNum;
+//                            if ($retry > 0) {
+//                                if ($this->_process->getPhaseStep() == $phaseStep) {
+//                                    $this->_process->setPhaseStep('');
+//                                }
+//                                $retryPhaseStepNum = $this->_process->getPhaseStepNum();
+//                            }
+//                            if (empty($this->_process->getPhaseStep())) {
+//                                $reportSubDirName = $phaseStartDateTime->format('Y-m-d_H-i-s');
+//                                $reportSubDirPath = $this->_reportDirUserPath . DIRECTORY_SEPARATOR . $reportSubDirName;
+//
+//                                // creer le sous dossier du rapport
+//                                if ($phaseStepNum >= $retryPhaseStepNum) {
+//                                    $this->_logCsvLine($this->_l10n->t('Création du dossier de rapport.'), self::LOG_DEBUG);
+//                                    $dirCreated = Filesystem::mkdir($reportSubDirPath);
+//                                    if (!$dirCreated) {
+//                                        $errorMsg = $this->_l10n->t('Impossible de créer le dossier du rapport "' . $reportSubDirName . '".');
+//                                        $this->_logCsvLine($errorMsg, self::LOG_ERROR);
+//                                        $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $phaseStepNum);
+//                                    }
+//                                }
+//
+//                                if ($this->_process->getHasError() <= 0) {
+//                                    // deplacer le fichier CSV Upload dans le dossier Report
+//                                    $phaseStepNum++;
+//                                    if ($phaseStepNum >= $retryPhaseStepNum) {
+//                                        $csvUploadFileName = $this->_process->getCsvOrigin();
+//                                        if (!empty($csvUploadFileName)) {
+//                                            $this->_logCsvLine($this->_l10n->t('Déplacement du fichier CSV d\'upload dans le dossier du rapport.'), self::LOG_DEBUG);
+//                                            $csvUploadFileUserPath = $this->_uploadDirUserPath . DIRECTORY_SEPARATOR . $csvUploadFileName;
+//                                            $reportFileUserPath = $reportSubDirPath . DIRECTORY_SEPARATOR . $csvUploadFileName;
+//                                            $renamed = Filesystem::rename($csvUploadFileUserPath, $reportFileUserPath);
+//                                            if (!$renamed) {
+//                                                $errorMsg = $this->_l10n->t('Impossible de déplacer le fichier CSV d\'upload "' . $csvUploadFileName . '" dans le dossier du rapport "' . $reportSubDirName . '".');
+//                                                $this->_logCsvLine($errorMsg, self::LOG_ERROR);
+//                                                $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $phaseStepNum);
+//                                            }
+//                                        }
+//                                    }
+//
+//                                    // deplacer le fichier PDF Upload dans le dossier Report
+//                                    $phaseStepNum++;
+//                                    if ($phaseStepNum >= $retryPhaseStepNum) {
+//                                        $pdfUploadFileName = $this->_process->getPdfOrigin();
+//                                        if (!empty($pdfUploadFileName)) {
+//                                            $this->_logCsvLine($this->_l10n->t('Déplacement du fichier PDF d\'upload dans le dossier du rapport.'), self::LOG_DEBUG);
+//                                            $pdfUploadFileUserPath = $this->_uploadDirUserPath . DIRECTORY_SEPARATOR . $pdfUploadFileName;
+//                                            $reportFileUserPath = $reportSubDirPath . DIRECTORY_SEPARATOR . $pdfUploadFileName;
+//                                            $renamed = Filesystem::rename($pdfUploadFileUserPath, $reportFileUserPath);
+//                                            if (!$renamed) {
+//                                                $errorMsg = $this->_l10n->t('Impossible de déplacer le fichier PDF d\'upload "' . $pdfUploadFileName . '" dans le dossier du rapport "' . $reportSubDirName . '".');
+//                                                $this->_logCsvLine($errorMsg, self::LOG_ERROR);
+//                                                $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $phaseStepNum);
+//                                            }
+//                                        }
+//                                    }
+//
+//                                    // deplacer le fichier CSV de traitement dans le dossier Report
+//                                    $phaseStepNum++;
+//                                    if ($phaseStepNum >= $retryPhaseStepNum) {
+//                                        if (!empty($csvCheckFileName)) {
+//                                            $this->_logCsvLine($this->_l10n->t('Déplacement du fichier CSV créé après vérification dans le dossier du rapport.'), self::LOG_DEBUG);
+//                                            $csvCheckFileUserPath = $this->_checkDirUserPath . DIRECTORY_SEPARATOR . $csvCheckFileName;
+//                                            $reportFileUserPath = $reportSubDirPath . DIRECTORY_SEPARATOR . $csvCheckFileName;
+//                                            $renamed = Filesystem::rename($csvCheckFileUserPath, $reportFileUserPath);
+//                                            if (!$renamed) {
+//                                                $errorMsg = $this->_l10n->t('Impossible de déplacer le fichier CSV de vérification "' . $csvCheckFileName . '" dans le dossier du rapport "' . $reportSubDirName . '".');
+//                                                $this->_logCsvLine($errorMsg, self::LOG_ERROR);
+//                                                $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $phaseStepNum);
+//                                            }
+//                                        }
+//                                    }
+//
+//                                    // deplacer le fichier de log cree lors de la phase de verification
+//                                    $phaseStepNum++;
+//                                    if ($phaseStepNum >= $retryPhaseStepNum) {
+//                                        // recuperation du fichier de log cree lors de la phase de verification
+//                                        $logCheckFileName = self::PHASE_ID_CHECK . '_log.csv';
+//                                        if (!empty($logCheckFileName)) {
+//                                            $this->_logCsvLine($this->_l10n->t('Déplacement du fichier de Log créé après vérification dans le dossier du rapport.'), self::LOG_DEBUG);
+//                                            $logCheckFileUserPath = $this->_checkDirUserPath . DIRECTORY_SEPARATOR . $logCheckFileName;
+//                                            $reportFileUserPath = $reportSubDirPath . DIRECTORY_SEPARATOR . $logCheckFileName;
+//                                            $renamed = Filesystem::rename($logCheckFileUserPath, $reportFileUserPath);
+//                                            if (!$renamed) {
+//                                                $errorMsg = $this->_l10n->t('Impossible de déplacer le fichier de Log de vérification "' . $logCheckFileName . '" dans le dossier du rapport "' . $reportSubDirName . '".');
+//                                                $this->_logCsvLine($errorMsg, self::LOG_ERROR);
+//                                                $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $phaseStepNum);
+//                                            }
+//                                        }
+//                                    }
+//                                }
+//                            }
+//                        }
+//                    }
+//
+//                    if ($this->_process->getHasError() <= 0) {
+//                        $successMsg = 'Opération "' . self::_getPhaseName($this->_process->getPhase()) . '" terminée avec succès.';
+//                        $this->_logCsvLine($this->_l10n->t($successMsg), self::LOG_SUCCESS);
+//                        $this->_msgList['success'][] = $successMsg;
+//                        $this->_processInit();
+//                    }
+//
+//                    $this->_logCsvLine('## ' . $this->_l10n->t('Fin du processus d\'indexation.') . ' ##', self::LOG_DEBUG);
+//                    fclose($this->_logFile);
+//                    // rename (sync file)
+//                    $renamed = Filesystem::rename($logFilePath, $logFilePath . '.csv');
+//                    $this->_process->setProcessing(0);
+//                    $this->_dematpayslipProcessMapper->update($this->_process);
+//                    // vider les lignes du process a sauter
+//                    $this->_dematpayslipProcessSkipMapper->deleteAllByIdProcess($this->_process->getId());
+//                } catch (Exception $e) {
+//                    $errorMsg = 'Exception ' . __METHOD__ . ' : error=' . $e->getMessage();
+//                    $this->_msgList['error'][] = $errorMsg;
+//                }
+//            }
 
             return new TemplateResponse('dematpayslip', 'index', $this->_assignParamsDemat());
         } else {
@@ -2444,27 +1169,23 @@ class PageController extends Controller {
     }
 
     /**
-     * Test page
+     * User list
+     *
      * @NoAdminRequired
      * @NoCSRFRequired
      *
      * @return  TemplateResponse
+     *
+     * @throws  Exception
      */
     public function userList() {
-        // verifier l'utilisateur
-        if ($this->userId === $this->_dematpayslipConfigList['user_id']) {
+        // check user
+        if ($this->_userId === $this->_dematpayslipConfigList['user_id']) {
             $userEmail = filter_input(INPUT_GET, 'user_search_email', FILTER_SANITIZE_EMAIL);
             $searchList = array(
-              'user_search_email' => $userEmail
+                'user_search_email' => $userEmail
             );
-
-            if (!empty($userEmail)) {
-                $userManager = OC::$server->getUserManager();
-                // /!\ remove all users not available (FIX for multiple users with SAML)
-                if (self::USER_REMOVE_UNKNOWN == 1) {
-                    $this->_userList = self::_removeUnknownUser($userManager->getByEmail($userEmail));
-                }
-            }
+            $this->_userList = $this->_dematpaylsipProcess->userList($userEmail);
 
             return new TemplateResponse('dematpayslip', 'user_list', $this->_assignUserList($searchList));
         } else {
@@ -2473,19 +1194,19 @@ class PageController extends Controller {
     }
 
     /**
-     * Liste des agents
+     * Agent list
      *
      * @NoAdminRequired
      * @NoCSRFRequired
      *
      * @return  TemplateResponse
      *
-     * @throws  OC\User\NoUserException
+     * @throws  Exception
      */
     public function agentList() {
-        // verifier l'utilisateur
-        if ($this->userId === $this->_dematpayslipConfigList['user_id']) {
-            $this->_initDematFolders();
+        // check user
+        if ($this->_userId === $this->_dematpayslipConfigList['user_id']) {
+            $this->_dematpaylsipProcess->agentList();
 
             return new TemplateResponse('dematpayslip', 'agent_list', $this->_assignAgentList());
         } else {
@@ -2494,85 +1215,19 @@ class PageController extends Controller {
     }
 
     /**
-     * Exporter la liste des agents au format CSV
+     * Export agent list in CSV
      *
      * @NoAdminRequired
      * @NoCSRFRequired
      *
      * @return  TemplateResponse
      *
-     * @throws  OC\User\NoUserException
+     * @throws  Exception
      */
     public function agentCsv() {
-        // verifier l'utilisateur
-        if ($this->userId === $this->_dematpayslipConfigList['user_id']) {
-            $this->_initDematFolders();
-
-            if (count($this->_msgList['error'])<=0) {
-                $dematpayslipUserList = $this->_dematpayslipUserMapper->findAll(array(array('disabled', 'desc'), array('siret'), array('matricule')));
-
-                if (!empty($dematpayslipUserList)) {
-                    $dateTimeNow = new DateTime('now', OC::$server->getDateTimeZone()->getTimeZone());
-                    $csvFilePath = $this->_exportDirUserPath . DIRECTORY_SEPARATOR .  $dateTimeNow->format('Y-m-d_H-i-s') . '_agent';
-                    $csvFile = Filesystem::fopen($csvFilePath, 'w+');
-
-                    if (!$csvFile) {
-                        $errorMsg = $this->l->t('Ouverture du fichier CSV.');
-                        $this->_msgList['error'][] = $errorMsg;
-                    }
-
-                    if (count($this->_msgList['error']) <= 0) {
-                        $csvDelimiter = $this->_csvDelimiter;
-                        $csvEnclosure = $this->_csvEnclosure;
-
-                        $csvFields   = array();
-                        $csvFields[] = $this->l->t('Utilisateur');
-                        $csvFields[] = $this->l->t('Siret');
-                        $csvFields[] = $this->l->t('Matricule');
-                        $csvFields[] = $this->l->t('Email');
-                        $csvFields[] = $this->l->t('Papier ?');
-
-                        $res = fputcsv($csvFile, $csvFields, $csvDelimiter, $csvEnclosure);
-                        if (!$res) {
-                            $errorMsg = $this->l->t('Ecriture des colonnes dans le fichier CSV.');
-                            $this->_msgList['error'][] = $errorMsg;
-                        }
-
-                        if (count($this->_msgList['error']) <= 0) {
-                            foreach ($dematpayslipUserList as $dematpayslipUser) {
-                                $agent = OC::$server->getUserManager()->get($dematpayslipUser->getUserId());
-
-                                $csvFields = array();
-                                //$csvFields[] = $dematpayslipUser->getUserId();
-                                $csvFields[] = $agent->getDisplayName();
-                                $csvFields[] = $dematpayslipUser->getSiret();
-                                $csvFields[] = $dematpayslipUser->getMatricule();
-                                $csvFields[] = $dematpayslipUser->getEmail();
-                                $csvFields[] = $dematpayslipUser->getDisabled();
-
-                                $res = fputcsv($csvFile, $csvFields, $csvDelimiter, $csvEnclosure);
-                                if (!$res) {
-                                    $errorMsg = $this->l->t('Ecriture de la ligne dans le fichier CSV.');
-                                    $this->_msgList['error'][] = $errorMsg;
-                                    break;
-                                }
-                            }
-                        }
-
-                        $res = fclose($csvFile);
-                        if (!$res) {
-                            $errorMsg = $this->l->t('Fermeture du fichier CSV.');
-                            $this->_msgList['error'][] = $errorMsg;
-                        }
-
-                        if (count($this->_msgList['error']) <= 0) {
-                            // rename (sync files)
-                            $renamed = Filesystem::rename($csvFilePath, $csvFilePath . '.csv');
-                            $this->_msgList['success'][] = $this->l->t('La liste des agents a bien été exporté au format CSV.');
-                        }
-                    }
-                }
-            }
+        // check user
+        if ($this->_userId === $this->_dematpayslipConfigList['user_id']) {
+            $this->_dematpaylsipProcess->agentCsv();
 
             return new TemplateResponse('dematpayslip', 'agent_list', $this->_assignAgentList());
         } else {
@@ -2588,19 +1243,18 @@ class PageController extends Controller {
      *
      * @return  TemplateResponse
      *
-     * @throws  OC\User\NoUserException
+     * @throws  Exception
      */
     public function archiveList() {
-        // verifier l'utilisateur
-        if ($this->userId === $this->_dematpayslipConfigList['user_id']) {
-            $this->_initDematFolders();
-
+        // check user
+        if ($this->_userId === $this->_dematpayslipConfigList['user_id']) {
             $stepStatus = filter_input(INPUT_GET, 'step_status', FILTER_SANITIZE_NUMBER_INT);
             if ($stepStatus === null) {
                 $stepStatus = -1;
             } else {
                 $stepStatus = intval($stepStatus);
             }
+            $this->_dematpaylsipProcess->archiveList();
 
             return new TemplateResponse('dematpayslip', 'archive_list', $this->_assignArchiveList($stepStatus));
         } else {
@@ -2616,80 +1270,20 @@ class PageController extends Controller {
      *
      * @return  TemplateResponse
      *
-     * @throws  OC\User\NoUserException
+     * @throws  Exception
      */
     public function archiveAction() {
-        // verifier l'utilisateur
-        if ($this->userId === $this->_dematpayslipConfigList['user_id']) {
-            $this->_initDematFolders();
-
+        // check user
+        if ($this->_userId === $this->_dematpayslipConfigList['user_id']) {
             $stepStatus = filter_input(INPUT_POST, 'step_status', FILTER_SANITIZE_NUMBER_INT);
             if ($stepStatus === null) {
                 $stepStatus = -1;
             } else {
                 $stepStatus = intval($stepStatus);
             }
-            $refresh = false;
-
             $action = filter_input(INPUT_POST, 'action', FILTER_SANITIZE_STRING);
             $archiveSelectIdList = filter_input(INPUT_POST, 'archive_select', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY);
-
-            if ($action == 'refresh_status') {
-                // refresh all archive status
-                $refresh = true;
-            } elseif ($action == 'create') {
-                $dematpayslipArchiveMapper = new DematpayslipArchiveMapper(OC::$server->getDatabaseConnection());
-
-                if (!empty($archiveSelectIdList)) {
-                    foreach ($archiveSelectIdList as $archiveSelectId) {
-                        $dematpayslipArchive = $dematpayslipArchiveMapper->find(intval($archiveSelectId));
-                        if (!empty($dematpayslipArchive)) {
-                            $this->_archiveProcess($dematpayslipArchiveMapper, $dematpayslipArchive);
-                        }
-                    }
-                }
-            } elseif ($action == 'create_all') {
-                $dematpayslipArchiveMapper = new DematpayslipArchiveMapper(OC::$server->getDatabaseConnection());
-                $dematpayslipArchiveList = $dematpayslipArchiveMapper->findAllByStepStatus(DematpayslipArchive::STEP_STATUS_INIT);
-
-                foreach ($dematpayslipArchiveList as $dematpayslipArchive) {
-                    if (!empty($dematpayslipArchive)) {
-                        $this->_archiveProcess($dematpayslipArchiveMapper, $dematpayslipArchive);
-                    }
-                }
-            } elseif ($action == 'run_again') {
-                $dematpayslipArchiveMapper = new DematpayslipArchiveMapper(OC::$server->getDatabaseConnection());
-
-                if (!empty($archiveSelectIdList)) {
-                    foreach ($archiveSelectIdList as $archiveSelectId) {
-                        $dematpayslipArchive = $dematpayslipArchiveMapper->find(intval($archiveSelectId));
-                        if (!empty($dematpayslipArchive)) {
-                            $this->_archiveProcess($dematpayslipArchiveMapper, $dematpayslipArchive);
-                        }
-                    }
-                }
-            }
-            elseif ($action == 'delete') {
-                $nowDateTime = new DateTime('now', OC::$server->getDateTimeZone()->getTimeZone());
-                $dematpayslipArchiveMapper = new DematpayslipArchiveMapper(OC::$server->getDatabaseConnection());
-
-                if (!empty($archiveSelectIdList)) {
-                    foreach ($archiveSelectIdList as $archiveSelectId) {
-                        $dematpayslipArchive = $dematpayslipArchiveMapper->find(intval($archiveSelectId));
-                        if (!empty($dematpayslipArchive)) {
-                            if (!empty($dematpayslipArchive->getPastellIdDocument())) {
-                                $this->_msgList['error'][] = $this->l->t('Impossible de supprimer le bulletin de paie "' . $dematpayslipArchive->getFilePath() . '" déjà en cours d\'archivage.');;
-                            } else {
-                                $dematpayslipArchive->setStatus(DematpayslipArchive::STATUS_DELETED);
-                                $dematpayslipArchive->setStatusTime($nowDateTime->getTimestamp());
-                                $dematpayslipArchiveMapper->update($dematpayslipArchive);
-                            }
-                        }
-
-                        if (count($this->_msgList['error']) > 0)    break;
-                    }
-                }
-            }
+            $refresh = $this->_dematpaylsipProcess->archiveAction($action, $archiveSelectIdList);
 
             return new TemplateResponse('dematpayslip', 'archive_list', $this->_assignArchiveList($stepStatus, $refresh));
         } else {
@@ -2698,102 +1292,25 @@ class PageController extends Controller {
     }
 
     /**
-     * Archive CSV
+     * Export archive list in CSV
      *
      * @NoAdminRequired
      * @NoCSRFRequired
      *
      * @return  TemplateResponse
      *
-     * @throws  OC\User\NoUserException
+     * @throws  Exception
      */
     public function archiveCsv() {
-        // verifier l'utilisateur
-        if ($this->userId === $this->_dematpayslipConfigList['user_id']) {
-            $this->_initDematFolders();
-
+        // check user
+        if ($this->_userId === $this->_dematpayslipConfigList['user_id']) {
             $stepStatus = filter_input(INPUT_GET, 'step_status', FILTER_SANITIZE_NUMBER_INT);
             if ($stepStatus === null) {
                 $stepStatus = -1;
             } else {
                 $stepStatus = intval($stepStatus);
             }
-
-            $dematpayslipArchiveMapper = new DematpayslipArchiveMapper(OC::$server->getDatabaseConnection());
-            if ($stepStatus === -1) {
-                $dematpayslipArchiveList = $dematpayslipArchiveMapper->findAll(0);
-            } else {
-                $dematpayslipArchiveList = $dematpayslipArchiveMapper->findAllByStepStatus($stepStatus);
-            }
-
-            if (!empty($dematpayslipArchiveList)) {
-                $dateTimeNow = new DateTime('now', OC::$server->getDateTimeZone()->getTimeZone());
-                $csvFilePath = $this->_exportDirUserPath . DIRECTORY_SEPARATOR . $dateTimeNow->format('Y-m-d_H-i-s') . '_archive';
-                $csvFile = Filesystem::fopen($csvFilePath, 'w+');
-
-                if (!$csvFile) {
-                    $errorMsg = $this->l->t('Ouverture du fichier CSV.');
-                    $this->_msgList['error'][] = $errorMsg;
-                }
-
-                if (count($this->_msgList['error']) <= 0) {
-                    $csvDelimiter = $this->_csvDelimiter;
-                    $csvEnclosure = $this->_csvEnclosure;
-
-                    $csvFields = array();
-                    $csvFields[] = $this->l->t('Chemin');
-                    $csvFields[] = $this->l->t('Siret');
-                    $csvFields[] = $this->l->t('Matricule');
-                    $csvFields[] = $this->l->t('Nom');
-                    $csvFields[] = $this->l->t('Prénom');
-                    $csvFields[] = $this->l->t('Début');
-                    $csvFields[] = $this->l->t('Fin');
-                    $csvFields[] = $this->l->t('Edition');
-                    $csvFields[] = $this->l->t('Archive');
-                    $csvFields[] = $this->l->t('Dernière action');
-
-                    $res = fputcsv($csvFile, $csvFields, $csvDelimiter, $csvEnclosure);
-                    if (!$res) {
-                        $errorMsg = $this->l->t('Ecriture des colonnes dans le fichier CSV.');
-                        $this->_msgList['error'][] = $errorMsg;
-                    }
-
-                    if (count($this->_msgList['error']) <= 0) {
-                        foreach ($dematpayslipArchiveList as $dematpayslipArchive) {
-                            $csvFields = array();
-                            $csvFields[] = $dematpayslipArchive->getFilePath();
-                            $csvFields[] = $dematpayslipArchive->getSiret();
-                            $csvFields[] = $dematpayslipArchive->getMatricule();
-                            $csvFields[] = $dematpayslipArchive->getLastname();
-                            $csvFields[] = $dematpayslipArchive->getFirstname();
-                            $csvFields[] = $dematpayslipArchive->getStartDate();
-                            $csvFields[] = $dematpayslipArchive->getEndDate();
-                            $csvFields[] = $dematpayslipArchive->getEditionDate();
-                            $csvFields[] = $dematpayslipArchive->getPastellIdDocument();
-                            $csvFields[] = $dematpayslipArchive->getPastellLastAction();
-
-                            $res = fputcsv($csvFile, $csvFields, $csvDelimiter, $csvEnclosure);
-                            if (!$res) {
-                                $errorMsg = $this->l->t('Ecriture de la ligne dans le fichier CSV.');
-                                $this->_msgList['error'][] = $errorMsg;
-                                break;
-                            }
-                        }
-                    }
-
-                    $res = fclose($csvFile);
-                    if (!$res) {
-                        $errorMsg = $this->l->t('Fermeture du fichier CSV.');
-                        $this->_msgList['error'][] = $errorMsg;
-                    }
-
-                    if (count($this->_msgList['error']) <= 0) {
-                        // rename (sync files)
-                        $renamed = Filesystem::rename($csvFilePath, $csvFilePath . '.csv');
-                        $this->_msgList['success'][] = $this->l->t('La liste des archives a bien été exporté au format CSV.');
-                    }
-                }
-            }
+            $this->_dematpaylsipProcess->archiveCsv($stepStatus);
 
             return new TemplateResponse('dematpayslip', 'archive_list', $this->_assignArchiveList($stepStatus));
         } else {
@@ -2802,26 +1319,14 @@ class PageController extends Controller {
     }
 
     /**
-     * Liste des bulletins de paie
+     * Payslip user list
      *
      * @return  TemplateResponse
+     *
+     * @throws  Exception
      */
     public function shares() {
-        $this->_dematpayslipUserList = $this->_dematpayslipUserMapper->findAllByUserId($this->userId);
-        $nbDematpayslipUserList = count($this->_dematpayslipUserList);
-        if ($nbDematpayslipUserList >= 1) {
-//            foreach ($this->_dematpayslipUserList as $dematpayslipUser) {
-//                if ($dematpayslipUser->getDisabled()==1) {
-//                    $msgWarning =  $this->l->t('Vous avez désactivé la dématérialisation des fiches de paie');
-//                    if ($nbDematpayslipUserList > 1) {
-//                        $msgWarning .= ' (SIRET : ' . $dematpayslipUser->getSiret() . ')';
-//                    }
-//                    $this->_msgList['warning'][] = $msgWarning;
-//                }
-//            }
-        } else {
-            $this->_msgList['error'][] = $this->l->t('Cet utilisateur n\'a pas encore de bulletin de paie dématérialisé.');
-        }
+        $this->_dematpayslipUserList = $this->_dematpaylsipProcess->shares($this->_userId);
 
         return new TemplateResponse('dematpayslip', 'shares', $this->_assignParamsShares());
     }
diff --git a/lib/Db/DematpayslipArchive.php b/lib/Db/DematpayslipArchive.php
index d023653..f7e3dcd 100644
--- a/lib/Db/DematpayslipArchive.php
+++ b/lib/Db/DematpayslipArchive.php
@@ -1,30 +1,59 @@
 <?php
+
 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 DateTime;
+use DateTimeZone;
+use Exception;
+
+use OCA\Pastell\Db\PastellConfigFlowMapper;
+use OCA\Pastell\PastellAPI;
+
 
 class DematpayslipArchive extends Entity implements JsonSerializable {
 
+    /**
+     * Const operation
+     */
+    const OPERATION_INITIALIZED = 0;
+    const OPERATION_INDEXATION  = 1;
+    const OPERATION_ARCHIVE     = 2;
+    const OPERATION_FINISHED    = 3;
+
     /**
      * Const status
      */
     const STATUS_DELETED       = -1;
     const STATUS_INITIALIZED   = 0;
-    const STATUS_CREATED       = 1;
-    const STATUS_TITLED        = 2;
-    const STATUS_FILE_SENT     = 3;
-    const STATUS_SAE_SENT      = 4;
-    const STATUS_METADATA_SENT = 5;
-    const STATUS_ORIENTATION   = 6;
+    const STATUS_INDEXED       = 1;
+    const STATUS_CREATED       = 2;
+    const STATUS_TITLED        = 3;
+    const STATUS_FILE_SENT     = 4;
+    const STATUS_SAE_SENT      = 5;
+    const STATUS_METADATA_SENT = 6;
+    const STATUS_ORIENTATION   = 7;
 
     /**
      * Const step status
      */
-    const STEP_STATUS_INIT     = 0;
+    const STEP_STATUS_TO_DO    = 0;
     const STEP_STATUS_PROGRESS = 1;
-    const STEP_STATUS_ARCHIVED = 2;
+    const STEP_STATUS_FINISHED = 2;
+
+    // messages
+    private $_msgList = array(
+        'error'   => array(),
+        'success' => array(),
+        'warning' => array(),
+    );
 
     protected $idFile;
     protected $idUser;
@@ -37,6 +66,8 @@ class DematpayslipArchive extends Entity implements JsonSerializable {
     protected $month;
     protected $lastname;
     protected $firstname;
+    protected $email;
+    protected $zipCity;
     protected $startDate;
     protected $endDate;
     protected $editionDate;
@@ -46,6 +77,11 @@ class DematpayslipArchive extends Entity implements JsonSerializable {
     protected $pastellLastAction;
     protected $importTime;
     protected $checksum;
+    protected $dematIdProcess;
+    protected $filePagesNum;
+    protected $operationAsk;
+    protected $operationProgress;
+    protected $error;
 
     public function jsonSerialize() {
         return [
@@ -61,6 +97,8 @@ class DematpayslipArchive extends Entity implements JsonSerializable {
             'month'              => $this->month,
             'lastname'           => $this->lastname,
             'firstname'          => $this->firstname,
+            'email'              => $this->email,
+            'zipCity'            => $this->zipCity,
             'startDate'          => $this->startDate,
             'endDate'            => $this->endDate,
             'editionDate'        => $this->editionDate,
@@ -70,31 +108,78 @@ class DematpayslipArchive extends Entity implements JsonSerializable {
             'pastellLastAction'  => $this->pastellLastAction,
             'importTime'         => $this->importTime,
             'checksum'           => $this->checksum,
+            'dematIdProcess'     => $this->dematIdProcess,
+            'filePagesNum'       => $this->filePagesNum,
+            'operationAsk'       => $this->operationAsk,
+            'operationProgress'  => $this->operationProgress,
+            'error'              => $this->error,
         ];
     }
 
     /**
-     * Get status list
+     * Get message list
+     *
+     * @param   string  $type       [=''] Type of message (success, warning, error)
+     * @return  array   Message list
+     */
+    public function getMsgList($type = '') {
+        if (!empty($type) && isset($this->_msgList[$type])) {
+            $msgList = $this->_msgList[$type];
+        } else {
+            $msgList = $this->_msgList;
+        }
+
+        return $msgList;
+    }
+
+    /**
+     * Get operation label from id
      *
-     * @param   int     $stepStatus     Step status
-     * @return  array   Status list
+     * @param   int         $id_operation   Operation id
+     * @return  string      Operation label
      */
-    public static function getStepStatusListFrom($stepStatus) {
-        $stepStatusList = [];
-
-        if ($stepStatus == self::STEP_STATUS_INIT) {
-            $stepStatusList[] =  self::STATUS_INITIALIZED;
-        } else if ($stepStatus == self::STEP_STATUS_PROGRESS) {
-            $stepStatusList[] = self::STATUS_CREATED;
-            $stepStatusList[] = self::STATUS_TITLED;
-            $stepStatusList[] = self::STATUS_FILE_SENT;
-            $stepStatusList[] = self::STATUS_SAE_SENT;
-            $stepStatusList[] = self::STATUS_METADATA_SENT;
-        } else if ($stepStatus == self::STEP_STATUS_ARCHIVED) {
-            $stepStatusList[] = self::STATUS_ORIENTATION;
+    public static function getOperationLabelFrom(int $id_operation) {
+        $label = '';
+
+        $labelList = array(
+            self::OPERATION_INITIALIZED  => 'Initialisation',
+            self::OPERATION_INDEXATION => 'Indexation',
+            self::OPERATION_ARCHIVE => 'Archivage',
+            self::OPERATION_FINISHED  => 'Terminé',
+        );
+
+        if (isset($labelList[$id_operation])) {
+            $label = $labelList[$id_operation];
         }
 
-        return $stepStatusList;
+        return $label;
+    }
+
+    /**
+     * Show operation ask label
+     *
+     * @return  string  Operation ask label
+     */
+    public function showOperationAskLabel() {
+        $operationAskLabelList = array();
+
+        $operationAskList = explode('+', $this->getOperationAsk());
+        if (!empty($operationAskList)) {
+            foreach ($operationAskList as $operationAsk) {
+                $operationAskLabelList[] = self::getOperationLabelFrom($operationAsk);
+            }
+        }
+
+        return implode(' | ', $operationAskLabelList);
+    }
+
+    /**
+     * Show operation progress label
+     *
+     * @return  string  Operation progress label
+     */
+    public function showOperationProgressLabel() {
+        return self::getOperationLabelFrom($this->getOperationProgress());
     }
 
     /**
@@ -108,6 +193,7 @@ class DematpayslipArchive extends Entity implements JsonSerializable {
         $statusLabelList = array(
             self::STATUS_DELETED       => 'Supprimé',
             self::STATUS_INITIALIZED   => 'Aucun',
+            self::STATUS_INDEXED       => 'Indexé',
             self::STATUS_CREATED       => 'Créé',
             self::STATUS_TITLED        => 'Titre ajouté',
             self::STATUS_FILE_SENT     => 'Fichier envoyé',
@@ -135,6 +221,84 @@ class DematpayslipArchive extends Entity implements JsonSerializable {
         return $statusLabel;
     }
 
+    /**
+     * Save payslip file to index/archive from path and agent user
+     *
+     * @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   DateTime                    $importDateTime                     [=null] Import date time
+     * @param   int                         $idProcess                          [=0] Process id
+     * @param   string                      $operationAsk                       [=''] Operation ask
+     * @param   string                      $operationProgress                  [=0] Operation progress
+     * @param   DateTimeZone                $timeZone                           [=null] Time zone
+     *
+     * @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;
+        //}
+
+        $statusDateTime = new DateTime('now', $timeZone);
+
+        $archiveFile         = Filesystem::getFileInfo($filePath);
+        $archiveFileChecksum = Filesystem::hash('md5', $filePath);
+
+        $this->setIdFile($archiveFile->getId());
+        $this->setFilePath($archiveFile->getPath());
+        $this->setIdUser($agentUser->getUserId());
+        $this->setDematpayslipIdUser($agentUser->getId());
+        $this->setSiret($agentUser->getSiret());
+        $this->setMatricule($agentUser->getMatricule());
+        $this->setYear($year);
+        $this->setMonth($month);
+        $this->setLastname($agentUser->getLastname());
+        $this->setFirstname($agentUser->getFirstname());
+        $this->setEmail($agentUser->getEmail());
+        $this->setZipCity($agentUser->getZipCity());
+        $this->setStartDate($startDate);
+        $this->setEndDate($endDate);
+        $this->setEditionDate($editionDate);
+        $this->setStatus(DematpayslipArchive::STATUS_INITIALIZED);
+        $this->setStatusTime($statusDateTime->getTimestamp());
+        if ($importDateTime) {
+            $this->setImportTime($importDateTime->getTimestamp());
+        }
+        $this->setChecksum($archiveFileChecksum);
+        if ($idProcess > 0) {
+            $this->setDematIdProcess($idProcess);
+        }
+        if (!empty($filePagesNum)) {
+            $this->setFilePagesNum($filePagesNum);
+        }
+        if (!empty($operationAsk)) {
+            $this->setOperationAsk($operationAsk);
+        }
+        if ($operationProgress > 0) {
+            $this->setOperationProgress($operationProgress);
+        }
+
+        if (empty($this->getId())) {
+            // insert new file to archive
+            $dematpayslipArchiveMapper->insert($this);
+        } else {
+            // update file to archive
+            $dematpayslipArchiveMapper->update($this);
+        }
+    }
+
     /**
      * Determine if it have already been archived (can't modify)
      *
@@ -144,11 +308,181 @@ class DematpayslipArchive extends Entity implements JsonSerializable {
         $isArchived = false;
 
         if (!empty($this->getPastellIdDocument())) {
-            if (in_array($this->getStatus(), self::getStepStatusListFrom(self::STEP_STATUS_ARCHIVED))) {
+            if (in_array($this->getStatus(), [self::STEP_STATUS_ARCHIVED])) {
                 $isArchived = true;
             }
         }
 
         return $isArchived;
     }
+
+    /**
+     * Archive process
+     *
+     * @param   string                      $appName                        App name
+     * @param   IConfig                     $config                         Config
+     * @param   IDBConnection               $dbConnection                   Database connection
+     * @param   IL10N                       $l                              Lang
+     * @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) {
+        $archiveFlowNum = 1; // archiving for 5 years by default
+        // get dematpayslip user
+        if (!empty($this->getDematpayslipIdUser())) {
+            $dematpayslipUser = $dematpayslipUserMapper->find($this->getDematpayslipIdUser());
+            if ($dematpayslipUser->getDisabled() == 0) {
+                $archiveFlowNum = 2; // archiving for 50 years
+            }
+        }
+
+        try {
+            // Pastell API config
+            $pastellConfigFlowId = $config->getAppValue($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 ($this->isArchived() === false) {
+                $canModifyArchive = true;
+            } else {
+                // get and modify document last action
+                $responseData = $pastellAPI->getEntityDocument($pastellConfigFlow->getIdE(), $this->getPastellIdDocument());
+
+                $archiveLastAction = $responseData['last_action']['action'];
+                if (!empty($archiveLastAction)) {
+                    $this->setPastellLastAction($archiveLastAction);
+                    $dematpayslipArchiveMapper->update($this);
+                }
+            }
+
+            if ($canModifyArchive === false) {
+                $this->_msgList['error'][] = $l->t('L\'archive "' . $this->getFilePath() . '" a déjà été créée.');
+            } else {
+                // 1. create document
+                if (empty($this->getPastellIdDocument())) {
+                    $nowDateTime = new DateTime('now', $dateTimeZone);
+                    $responseData = $pastellAPI->postEntityDocument($pastellConfigFlow->getIdE(), array(
+                        'type' => 'pdf-generique'
+                    ));
+                    $this->setPastellIdDocument($responseData['id_d']);
+                    $this->setPastellLastAction($responseData['last_action']['action']);
+                    $this->setStatus(self::STATUS_CREATED);
+                    $this->setStatusTime($nowDateTime->getTimestamp());
+                    $this->update($this);
+                }
+                // 2. set document title
+                if ($this->getStatus() == self::STATUS_CREATED) {
+                    $nowDateTime = new DateTime('now', $dateTimeZone);
+                    $responseData = $pastellAPI->patchEntityDocument($pastellConfigFlow->getIdE(), $this->getPastellIdDocument(), array(
+                        'libelle' => $this->getId() . '_' . $this->getSiret() . '_' . $this->getMatricule() . '_' . $this->getStartDate() . '_' . $this->getEndDate()
+                    ));
+                    $this->setPastellLastAction($responseData['content']['last_action']['action']);
+                    $this->setStatus(self::STATUS_TITLED);
+                    $this->setStatusTime($nowDateTime->getTimestamp());
+                    $this->update($this);
+                }
+                // 3. send document file
+                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);
+                }
+                // 4. send to SAE
+                if ($this->getStatus() == self::STATUS_FILE_SENT) {
+                    $nowDateTime = new DateTime('now', $dateTimeZone);
+                    $responseData = $pastellAPI->patchEntityDocument($pastellConfigFlow->getIdE(), $this->getPastellIdDocument(), array(
+                        'envoi_sae' => true
+                    ));
+                    $this->setPastellLastAction($responseData['content']['last_action']['action']);
+                    $this->setStatus(self::STATUS_SAE_SENT);
+                    $this->setStatusTime($nowDateTime->getTimestamp());
+                    $dematpayslipArchiveMapper->update($this);
+                }
+                // 5. create JSON file and add meta-data on document
+                if ($this->getStatus() == self::STATUS_SAE_SENT) {
+                    $saeConfigArr = array(
+                        'matricule' => $this->getMatricule(),
+                        'mois' => $this->getMonth(),
+                        'annee' => $this->getYear(),
+                        'nom' => $this->getLastname(),
+                        'prenom' => $this->getFirstname(),
+                        'date_edition' => $this->getEditionDate(),
+                        'periode_2_de_paie' => $this->getEndDate(),
+                        'periode_1_de_paie' => $this->getStartDate(),
+                    );
+                    $jsonFileName = 'sae_config.json';
+
+                    $tmpJsonFilePath = tempnam(sys_get_temp_dir(), 'sae');
+                    if (!$tmpJsonFilePath) {
+                        $this->_msgList['error'][] = $l->t('Impossible de créer le fichier temporaire "' . $tmpJsonFilePath . '" [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);
+                            }
+                        }
+                    }
+                }
+                // 6. set orientation action on document
+                if ($this->getStatus() == self::STATUS_METADATA_SENT) {
+                    $nowDateTime = new DateTime('now', $dateTimeZone);
+                    $responseData = $pastellAPI->postEntityDocumentAction($pastellConfigFlow->getIdE(), $this->getPastellIdDocument(), 'orientation');
+                    $this->setStatus(self::STATUS_ORIENTATION);
+                    $this->setStatusTime($nowDateTime->getTimestamp());
+                    if ($responseData['result'] == true) {
+                        // get and modify document last action
+                        $responseData = $pastellAPI->getEntityDocument($pastellConfigFlow->getIdE(), $this->getPastellIdDocument());
+                        if (!empty($responseData['last_action']['action'])) {
+                            $this->setPastellLastAction($responseData['last_action']['action']);
+                        }
+                    }
+                    $dematpayslipArchiveMapper->update($this);
+                }
+
+                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() .'].');
+                } else {
+                    $this->_msgList['success'][] = $l->t('L\'archive "' . $this->getFilePath() . '" a été créée.');
+                }
+            }
+
+            if (count($this->_msgList['error']) > 0) {
+                return -1;
+            } else {
+                return 1;
+            }
+        } catch (Exception $e) {
+            $this->_msgList['error'][] = $e->getMessage();
+            return -1;
+        }
+    }
 }
diff --git a/lib/Db/DematpayslipArchiveMapper.php b/lib/Db/DematpayslipArchiveMapper.php
index d25b2d0..0501eb1 100644
--- a/lib/Db/DematpayslipArchiveMapper.php
+++ b/lib/Db/DematpayslipArchiveMapper.php
@@ -36,6 +36,21 @@ class DematpayslipArchiveMapper extends QBMapper {
         return $this->findEntities($qb);
     }
 
+    public function findAllByDematIdProcessAndStatus(int $idProcess, int $status) {
+        $qb = $this->db->getQueryBuilder();
+
+        $qb->select('*')
+            ->from($this->getTableName())
+            ->where(
+                $qb->expr()->eq('demat_id_process', $qb->createNamedParameter($idProcess))
+            )
+            ->andWhere(
+                $qb->expr()->eq('status', $qb->createNamedParameter($status))
+            );
+
+        return $this->findEntities($qb);
+    }
+
     public function findAllByFilePath(string $filePath) {
         $qb = $this->db->getQueryBuilder();
 
@@ -99,16 +114,47 @@ class DematpayslipArchiveMapper extends QBMapper {
         $qb->select('*');
         $qb->from($this->getTableName());
 
-        $statusList = DematpayslipArchive::getStepStatusListFrom($stepStatus);
-        if (!empty($statusList)) {
+        if ($stepStatus == DematpayslipArchive::STEP_STATUS_TO_DO) {
+            $qb->where(
+                $qb->expr()->in('status', $qb->createNamedParameter([DematpayslipArchive::STATUS_INITIALIZED], IQueryBuilder::PARAM_STR_ARRAY))
+            );
+            $qb->andWhere(
+                $qb->expr()->notIn('status', $qb->createNamedParameter([DematpayslipArchive::STATUS_DELETED], IQueryBuilder::PARAM_STR_ARRAY))
+            );
+        } else if ($stepStatus == DematpayslipArchive::STEP_STATUS_FINISHED) {
+            $qb->where(
+                $qb->expr()->in('operation_progress', $qb->createNamedParameter([DematpayslipArchive::OPERATION_FINISHED], IQueryBuilder::PARAM_STR_ARRAY))
+            );
+            $qb->andWhere(
+                $qb->expr()->notIn('status', $qb->createNamedParameter([DematpayslipArchive::STATUS_DELETED], IQueryBuilder::PARAM_STR_ARRAY))
+            );
+        } else if ($stepStatus == DematpayslipArchive::STEP_STATUS_PROGRESS) {
             $qb->where(
-                $qb->expr()->in('status', $qb->createNamedParameter($statusList, IQueryBuilder::PARAM_STR_ARRAY))
+                $qb->expr()->notIn('status', $qb->createNamedParameter([DematpayslipArchive::STATUS_INITIALIZED, DematpayslipArchive::STATUS_DELETED], IQueryBuilder::PARAM_STR_ARRAY))
+            );
+            $qb->andWhere(
+                $qb->expr()->notIn('operation_progress', $qb->createNamedParameter([DematpayslipArchive::OPERATION_INITIALIZED, DematpayslipArchive::OPERATION_FINISHED], IQueryBuilder::PARAM_STR_ARRAY))
             );
         }
 
         return $this->findEntities($qb);
     }
 
+    public function findAllByOperationProgress(int $id_operation) {
+        $qb = $this->db->getQueryBuilder();
+
+        $qb->select('*');
+        $qb->from($this->getTableName());
+        $qb->where(
+            $qb->expr()->eq('operation_progress', $qb->createNamedParameter($id_operation))
+        );
+        $qb->andWhere(
+            $qb->expr()->notIn('status', $qb->createNamedParameter([DematpayslipArchive::STATUS_DELETED], IQueryBuilder::PARAM_STR_ARRAY))
+        );
+
+        return $this->findEntities($qb);
+    }
+
     public function findAll($deleted = 0) {
         $qb = $this->db->getQueryBuilder();
 
diff --git a/lib/Db/DematpayslipProcess.php b/lib/Db/DematpayslipProcess.php
index 10dd891..e091379 100644
--- a/lib/Db/DematpayslipProcess.php
+++ b/lib/Db/DematpayslipProcess.php
@@ -3,10 +3,205 @@ 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\IUserManager;
+
+use DateTime;
+use DateTimeZone;
+use Exception;
+
+// Pastell API
+use OCA\Pastell\PastellAPI;
+use OCA\Pastell\Db\PastellConfigFlowMapper;
 
 class DematpayslipProcess extends Entity implements JsonSerializable {
 
+    const LOG_SUCCESS = 0;
+    const LOG_DEBUG   = 1;
+    const LOG_WARNING = 2;
+    const LOG_ERROR   = 3;
+
+    const PROCESS_TIME_UNLOCK = 60; // seconds (max execution time)
+
+    const PHASE_ID_UPLOAD = 0;
+    const PHASE_ID_CHECK  = 1;
+    const PHASE_ID_PRE_INDEXATION = 2;
+    const PHASE_ID_INDEXATION = 3;
+
+    const USER_REMOVE_UNKNOWN = 1; // remove unknown users from list (FIX SAML)
+
+    /**
+     * @var array Payslip PDF search field list
+     */
+    private $_payslipPDFSearchFieldList = array(
+        'siret'     => array(3),
+        'matricule' => array(10),
+        'fullname'  => array(9),
+        'zip_city'  => array(19, 20),
+    );
+//    private $_payslipPDFSearchFieldList = array(
+//        'siret'     => array(4, 5),
+//        'matricule' => array(20, 21),
+//        'fullname'  => array(19, 20),
+//        'zip_city'  => array(34, 35, 36, 37),
+//    );
+
+    /**
+     * @var bool Fail on first error
+     */
+    private $_processFailOnFirstError = true;
+
+    /**
+     * @var string app name
+     */
+    private $_appName;
+
+    /**
+     * @var IConfig config
+     */
+    private $_config;
+
+    /**
+     * @var IDateTimeZone date time zone
+     */
+    private $_dateTimeZone;
+
+    /**
+     * @var IDBConnection database connection
+     */
+    private $_dbConnection;
+
+    /**
+     * @var IL10N lang
+     */
+    private $_l10n;
+
+    /**
+     * @var IRootFolder root folder
+     */
+    private $_rootFolder;
+
+    /**
+     * @var IShareManager share manager
+     */
+    private $_shareManager;
+
+    /**
+     * @var DateTimeZone time zone
+     */
+    private $_timeZone;
+
+    /**
+     * @var string user id
+     */
+    private $_userId;
+
+    /**
+     * @var IUserManager user manager
+     */
+    private $_userManager;
+
+    /**
+     * @var bool can cancel process
+     */
+    private $_canCancelProcess = false;
+
+    /**
+     * @var string CSV delimiter
+     */
+    private $_csvDelimiter = ';';
+
+    /**
+     * @var string CSV enclosure
+     */
+    private $_csvEnclosure = '"';
+
+    /**
+     * @var int CSV length
+     */
+    private $_csvLength = 0;
+
+    /**
+     * @var string CSV encode source
+     */
+    private $_csvEncodeFrom = 'UTF-8';
+
+    /**
+     * @var string CSV encode destination
+     */
+    private $_csvEncodeTo = 'UTF-8';
+
+    /**
+     * @var resource handler Log file
+     */
+    private $_logFile = null;
+
+    /**
+     * @var int log level
+     */
+    private $_logLevel = self::LOG_DEBUG;
+
+    /** @var string folder path */
+    private $_uploadDirUserPath;
+    private $_uploadDirFullPath;
+    private $_checkDirUserPath;
+    private $_checkDirFullPath;
+    private $_reportDirUserPath;
+    private $_reportDirFullPath;
+    private $_exportDirUserPath;
+    private $_exportDirFullPath;
+    private $_tmpDirUserPath;
+    private $_tmpDirFullPath;
+    private $_userDirFullPath;
+
+    /**
+     * @var string payslip no index dir
+     */
+    private $_payslipNoIndexDir = 'BulletinsNoIndex';
+
+    /**
+     * @var DematpayslipProcessMapper
+     */
+    private $_dematpayslipProcessMapper;
+
+    /**
+     * @var DematpayslipProcessSkipMapper
+     */
+    private $_dematpayslipProcessSkipMapper;
+
+    /**
+     * @var DematpayslipUserMapper
+     */
+    private $_dematpayslipUserMapper;
+
+    /**
+     * @var array[] dematpayslip config list
+     */
+    private $_dematpayslipConfigList = array();
+
+    /**
+     * @var array[] message list
+     */
+    private $_msgList = array(
+        'error'   => array(),
+        'success' => array(),
+        'warning' => array(),
+    );
+
+    /**
+     * Pastell app exists
+     *
+     * @var bool
+     */
+    private $_pastellAppExists = false;
+
     protected $processing;
     protected $phase;
     protected $phaseStartTime;
@@ -39,4 +234,2597 @@ class DematpayslipProcess extends Entity implements JsonSerializable {
             'userId'         => $this->userId,
         ];
     }
+
+    /**
+     * Check if payslip file has not been archived yet
+     *
+     * @param   DematpayslipArchiveMapper   $dematpayslipArchiveMapper      Archive table mapper
+     * @param   DematpayslipUser            $agentUser                      Agent user
+     * @param   string                      $startDate                      Period start date
+     * @param   string                      $endDate                        Period end date
+     * @return  mixed|DematpayslipArchive|\OCP\AppFramework\Db\Entity|null
+     *
+     * @throws  Exception
+     */
+    private function _archiveCheckBeforeSave(DematpayslipArchiveMapper $dematpayslipArchiveMapper, DematpayslipUser $agentUser, $startDate, $endDate) {
+        $dematpayslipArchive = null;
+        $dematpayslipArchiveExistList = $dematpayslipArchiveMapper->findAllByAgentAndPeriod($agentUser->getSiret(), $agentUser->getMatricule(), $agentUser->getLastname(), $agentUser->getFirstname(), $startDate, $endDate);
+
+        if (empty($dematpayslipArchiveExistList)) {
+            $dematpayslipArchive = new DematpayslipArchive();
+        } elseif (count($dematpayslipArchiveExistList) === 1) {
+            if (!empty($dematpayslipArchiveExistList[0]->getPastellIdDocument())) {
+                $warningMsg = $this->_l10n->t('Le bulletin de paie de l\'agent "' . $agentUser->getLastname() . ' ' . $agentUser->getFirstname() . '" pour la période du ' . $startDate . ' au ' . $endDate . ' est déjà en cours d\'archivage.');
+                $this->_logCsvLine($warningMsg, self::LOG_WARNING, $agentUser, $startDate, $endDate);
+                $this->_processWarningMsg($warningMsg);
+            } else {
+                $dematpayslipArchive = $dematpayslipArchiveExistList[0];
+            }
+        } else {
+            $warningMsg = $this->_l10n->t('Plusieurs bulletins de paie de l\'agent "' . $agentUser->getLastname() . ' ' . $agentUser->getFirstname() . '" pour la période du ' . $startDate . ' au ' . $endDate . ' existent déjà.');
+            $this->_logCsvLine($warningMsg, self::LOG_WARNING, $agentUser, $startDate, $endDate);
+            $this->_processWarningMsg($warningMsg);
+        }
+
+        return $dematpayslipArchive;
+    }
+
+    /**
+     * Check Pastell app exists
+     */
+    private function _checkPastellAppExists() {
+        $pastellAppExists = false;
+
+        $pastellAppDir = __DIR__ . '/../../../pastell';
+        if (is_dir($pastellAppDir)) $pastellAppExists = true;
+
+        return $pastellAppExists;
+    }
+
+    /**
+     * Find CSV and PDF files in uploaded directory
+     *
+     * @return  array   CSV and PDF filenames
+     */
+    private function _findUploadedCSVAndPDF() {
+        $uploadFileCSVName = '';
+        $uploadFilePDFName = '';
+        $uploadDirFullPath = $this->_uploadDirFullPath;
+        if (file_exists($uploadDirFullPath)) {
+            $scanDir = scandir($uploadDirFullPath);
+            if (!empty($scanDir)) {
+                foreach ($scanDir as $fileName) {
+                    if (!in_array($fileName, array('.', '..'))) {
+                        $uploadFilePath = $uploadDirFullPath . DIRECTORY_SEPARATOR . $fileName;
+                        if (is_file($uploadFilePath)) {
+                            $uploadFileType = mime_content_type($uploadFilePath);
+                            if ($uploadFileType == 'application/pdf') {
+                                $uploadFilePDFName = $fileName;
+                            } else if ($uploadFileType == 'text/plain') {
+                                $uploadFileCSVName = $fileName;
+                            }
+                        }
+                    }
+
+                    if (!empty($uploadFileCSVName) && !empty($uploadFilePDFName)) {
+                        break;
+                    }
+                }
+            }
+        }
+
+        return array('csv' => $uploadFileCSVName, 'pdf' => $uploadFilePDFName);
+    }
+
+    /**
+     * Find all files (recursive)
+     *
+     * @param   string      $filePath       File path
+     * @return  array
+     */
+    private function _findAllFiles($filePath, &$fileList = array()) {
+        $isDir = Filesystem::is_dir($filePath);
+
+        if ($isDir) {
+            $payslipPDFFileList = Filesystem::getDirectoryContent($filePath);
+
+            foreach ($payslipPDFFileList as $payslipPDFFile) {
+                $newFilePath = $filePath . DIRECTORY_SEPARATOR . $payslipPDFFile->getName();
+                $isFile = Filesystem::is_file($newFilePath);
+                if ($isFile) {
+                    $fileList[] = $payslipPDFFile;
+                } else {
+                    $this->_findAllFiles($newFilePath, $fileList);
+                }
+            }
+        }
+
+        return $fileList;
+    }
+
+    /**
+     * Remove all files in a directory
+     *
+     * @param   string      $dirPath    Directory path
+     */
+    private static function _removeAllFilesDir($dirPath) {
+        $scanDir = scandir($dirPath);
+        if (!empty($scanDir)) {
+            foreach ($scanDir as $fileName) {
+                if (!in_array($fileName, array('.', '..'))) {
+                    $filePath = $dirPath . DIRECTORY_SEPARATOR . $fileName;
+                    if (is_file($filePath)) {
+                        unlink($filePath);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Remove all unknown users (FIX for multiple users with SAML)
+     *
+     * @param   array   $userFindByEmailList        User list
+     * @return  array   Users list without unknown
+     */
+    private static function _removeUnknownUser($userFindByEmailList) {
+        $userList = $userFindByEmailList;
+
+        foreach ($userList as $key => $user) {
+            if (preg_match('#^[0-9A-F]{8}\-[0-9A-F]{4}\-[0-9A-F]{4}\-[0-9A-F]{4}\-[0-9A-F]{12}#', $user->getDisplayName())) {
+                unset($userList[$key]);
+            }
+        }
+
+        return $userList;
+    }
+
+    /**
+     * Cancel process
+     */
+    private function _processCancel() {
+        if ($this->getMustTerminate()<=0) {
+            // clean upload directory
+            if (is_dir($this->_uploadDirFullPath)) {
+                self::_removeAllFilesDir($this->_uploadDirFullPath);
+            }
+
+            // clean check directory
+            if (is_dir($this->_checkDirFullPath)) {
+                self::_removeAllFilesDir($this->_checkDirFullPath);
+            }
+
+            // TODO : init process and delete archives links (status initialized and process must terminate = 0)
+            $this->_processInit();
+            $this->_dematpayslipProcessMapper->update($this);
+        }
+    }
+
+    /**
+     * Set process error message
+     *
+     * @param   int         $errorCode      Error code
+     * @param   string      $errorMsg       Error message
+     * @param   string      $phaseStep      [=''] Phase step
+     * @param   int         $phaseStepNum   [=0] Phase step num
+     */
+    private function _processErrorMsg($errorCode, $errorMsg, $phaseStep = '', $phaseStepNum = 0) {
+        $this->setHasError(1);
+        $this->_msgList['error'][] = $errorMsg;
+        $this->setErrorCode($errorCode);
+        $this->setErrorMsg(implode('<br />', $this->_msgList['error']));
+        $this->setPhaseStep($phaseStep);
+        $this->setPhaseStepNum(intval($phaseStepNum));
+        $this->_dematpayslipProcessMapper->update($this);
+    }
+
+    /**
+     * Set process warning message
+     *
+     * @param   string      $warningMsg       Warning message
+     */
+    private function _processWarningMsg($warningMsg) {
+        $this->_msgList['warning'][] = $warningMsg;
+    }
+
+    /**
+     * Csv log file
+     *
+     * @param   array   $colList    Column name list
+     */
+    private function _logCsvCols($colList) {
+        if ($this->_logFile !== null) {
+            fputcsv($this->_logFile, $colList, $this->_csvDelimiter, $this->_csvEnclosure);
+        }
+    }
+
+    /**
+     * Log csv line
+     *
+     * @param   string                  $msg            Log message
+     * @param   int                     $level          [=LOG_DEBUG] Log level
+     * @param   DematpayslipUser        $agentUser      [=null] Agent user
+     * @param   string                  $startDate      [=''] Start date
+     * @param   string                  $endDate        [=''] End date
+     *
+     * @throws  Exception
+     */
+    private function _logCsvLine($msg, $level = self::LOG_DEBUG, DematpayslipUser $agentUser = null, $startDate = '', $endDate = '') {
+        if ($this->_logFile !== null) {
+            if ($this->_logLevel <= $level || $level === self::LOG_SUCCESS) {
+                $dateTimeNow = new DateTime('now', $this->_timeZone);
+                $logLevel = '';
+                switch ($level) {
+                    case self::LOG_SUCCESS :
+                        $logLevel = 'SUCCESS';
+                        break;
+
+                    case self::LOG_DEBUG :
+                        $logLevel = 'DEBUG';
+                        break;
+
+                    case self::LOG_WARNING :
+                        $logLevel = 'WARNING';
+                        break;
+
+                    case self::LOG_ERROR :
+                        $logLevel = 'ERROR';
+                        break;
+
+                    default : break;
+                }
+
+                $csvLine = array(
+                    $dateTimeNow->format('Y-m-d'),
+                    $dateTimeNow->format('H:i:s'),
+                    $logLevel,
+                    $msg,
+                    (!empty($agentUser) ? $agentUser->getSiret() : ''),
+                    (!empty($agentUser) ? $agentUser->getMatricule() : ''),
+                    (!empty($agentUser) ? $agentUser->getLastname() . ' ' . $agentUser->getFirstname() : ''),
+                    (!empty($agentUser) ? $agentUser->getZipCity() : ''),
+                    $startDate,
+                    $endDate,
+                    (!empty($agentUser) ? $agentUser->getEmail() : ''),
+                );
+                fputcsv($this->_logFile, $csvLine, $this->_csvDelimiter, $this->_csvEnclosure);
+            }
+        }
+    }
+
+    /**
+     * Init process
+     */
+    private function _processInit() {
+        $this->setPhase(0);
+        $this->setPhaseStartTime(0);
+        $this->setPhaseStep('');
+        $this->setPhaseStepNum(0);
+        $this->setMustTerminate(0);
+        $this->setHasError(0);
+        $this->setErrorCode(0);
+        $this->setErrorMsg('');
+        $this->setCsvOrigin('');
+        $this->setPdfOrigin('');
+        $this->setCsvCheck('');
+        $this->setUserId('');
+    }
+
+    /**
+     * Init application folders
+     *
+     * @throws Exception
+     */
+    private function _initDematFolders() {
+        $appDataDirPath           = (string) $this->_dematpayslipConfigList['app_data_dir']; // app directory of operator user (upload, check, report, etc)
+        $this->_checkDirUserPath  = $appDataDirPath . DIRECTORY_SEPARATOR . 'check';
+        $this->_reportDirUserPath = $appDataDirPath . DIRECTORY_SEPARATOR . 'report';
+        $this->_uploadDirUserPath = $appDataDirPath . DIRECTORY_SEPARATOR . 'upload';
+        $this->_exportDirUserPath = $appDataDirPath . DIRECTORY_SEPARATOR . 'export';
+        $this->_tmpDirUserPath    = $appDataDirPath . DIRECTORY_SEPARATOR . 'tmp';
+
+        // get user for payslip
+        $user = $this->_userManager->get($this->_userId);
+        if (!$user) {
+            $this->_msgList['error'][] = $this->_l10n->t('L\'utilisateur "' . $this->_userId . '" n\'existe pas.');
+        }
+
+        // mounter le dossier de l'utilisateur
+        if (count($this->_msgList['error'])<=0) {
+            $userHomeAppFilesFullPath = $user->getHome() . DIRECTORY_SEPARATOR . 'files';
+            $this->_checkDirFullPath  = $userHomeAppFilesFullPath . DIRECTORY_SEPARATOR . $this->_checkDirUserPath;
+            $this->_reportDirFullPath = $userHomeAppFilesFullPath . DIRECTORY_SEPARATOR . $this->_reportDirUserPath;
+            $this->_uploadDirFullPath = $userHomeAppFilesFullPath . DIRECTORY_SEPARATOR . $this->_uploadDirUserPath;
+            $this->_exportDirFullPath = $userHomeAppFilesFullPath . DIRECTORY_SEPARATOR . $this->_exportDirUserPath;
+            $this->_tmpDirFullPath    = $userHomeAppFilesFullPath . DIRECTORY_SEPARATOR . $this->_tmpDirUserPath;
+            $this->_userDirFullPath   = $userHomeAppFilesFullPath;
+
+            // mount user directory
+            //Filesystem::initMountPoints($this->_userId);
+            $userFolder = $this->_rootFolder->getUserFolder($this->_userId);
+
+            // create payslip directory
+            $payslipDir = (string) $this->_dematpayslipConfigList['payslip_dir'];
+            try {
+                $userFolder->get($payslipDir);
+            } catch (Exception $e) {
+                $createdFolder = $userFolder->newFolder($payslipDir);
+                if (!$createdFolder) {
+                    $this->_msgList['error'][] = $this->_l10n->t('Impossible de créer le dossier des bulletins "' . $payslipDir . '".');
+                }
+            }
+
+            // create payslip not to be indexed folder
+            try {
+                $userFolder->get($this->_payslipNoIndexDir);
+            } catch (Exception $e) {
+                $createdFolder = $userFolder->newFolder($this->_payslipNoIndexDir);
+                if (!$createdFolder) {
+                    $this->_msgList['error'][] = $this->_l10n->t('Impossible de créer le dossier des bulletins non indexes "' . $this->_payslipNoIndexDir . '".');
+                }
+            }
+
+            // payslip application directory
+            try {
+                $userFolder->get($appDataDirPath);
+            } catch (Exception $e) {
+                $createdFolder = $userFolder->newFolder($appDataDirPath);
+                if (!$createdFolder) {
+                    $this->_msgList['error'][] = $this->_l10n->t('Impossible de créer le dossier de l\'application "' . $appDataDirPath . '".');
+                }
+            }
+
+            if (count($this->_msgList['error'])<=0) {
+                // check directory
+                try {
+                    $userFolder->get($this->_checkDirUserPath);
+                } catch (Exception $e) {
+                    $createdFolder = $userFolder->newFolder($this->_checkDirUserPath);
+                    if (!$createdFolder) {
+                        $this->_msgList['error'][] = $this->_l10n->t('Impossible de créer le dossier de l\'application "' . $this->_checkDirUserPath . '".');
+                    }
+                }
+
+                // report directory
+                try {
+                    $userFolder->get($this->_reportDirUserPath);
+                } catch (Exception $e) {
+                    $createdFolder = $userFolder->newFolder($this->_reportDirUserPath);
+                    if (!$createdFolder) {
+                        $this->_msgList['error'][] = $this->_l10n->t('Impossible de créer le dossier de l\'application "' . $this->_reportDirUserPath . '".');
+                    }
+                }
+
+                // upload directory
+                try {
+                    $userFolder->get($this->_uploadDirUserPath);
+                } catch (Exception $e) {
+                    $createdFolder = $userFolder->newFolder($this->_uploadDirUserPath);
+                    if (!$createdFolder) {
+                        $this->_msgList['error'][] = $this->_l10n->t('Impossible de créer le dossier de l\'application "' . $this->_uploadDirUserPath . '".');
+                    }
+                }
+
+                // export directory
+                try {
+                    $userFolder->get($this->_exportDirUserPath);
+                } catch (Exception $e) {
+                    $createdFolder = $userFolder->newFolder($this->_exportDirUserPath);
+                    if (!$createdFolder) {
+                        $this->_msgList['error'][] = $this->_l10n->t('Impossible de créer le dossier de l\'application "' . $this->_exportDirUserPath . '".');
+                    }
+                }
+
+                // tmp directory
+                try {
+                    $userFolder->get($this->_tmpDirUserPath);
+                } catch (Exception $e) {
+                    $createdFolder = $userFolder->newFolder($this->_tmpDirUserPath);
+                    if (!$createdFolder) {
+                        $this->_msgList['error'][] = $this->_l10n->t('Impossible de créeer le dossier de l\'application "' . $this->_tmpDirUserPath . '".');
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Init for agent user
+     *
+     * @throws  Exception
+     */
+    private function _initDematUser() {
+        // init
+        $appPath = \OC::$server->getAppManager()->getAppPath($this->_appName);
+
+        // depends
+        require_once $appPath . '/vendor/autoload.php';
+
+        $this->_initDematFolders();
+    }
+
+    /**
+     * Get phase name
+     *
+     * @param   int         $phaseId    Phase Id
+     * @return  string      Phase name
+     */
+    private static function _getPhaseName($phaseId) {
+        $phaseName = '';
+
+        switch ($phaseId) {
+            case self::PHASE_ID_UPLOAD :
+                $phaseName = 'Upload';
+                break;
+
+            case self::PHASE_ID_CHECK :
+                $phaseName = 'Vérification';
+                break;
+
+            case self::PHASE_ID_PRE_INDEXATION :
+                $phaseName = 'Pré-indexation';
+                break;
+
+            case self::PHASE_ID_INDEXATION :
+                $phaseName = 'Indexation';
+                break;
+
+            default : break;
+        }
+
+        return $phaseName;
+    }
+
+    /**
+     * Check if process is locked (processing or locked by user)
+     */
+    private function _processCheck() {
+        // automatic unlock process (ex : max execution time)
+        if ((time() - $this->getPhaseStartTime()) > self::PROCESS_TIME_UNLOCK) {
+            $this->setProcessing(0);
+            $this->_dematpayslipProcessMapper->update($this);
+        }
+
+        $this->_canCancelProcess = false;
+        // check if process was launched by the same user
+        if (!empty($this->getUserId()) && $this->_userId===$this->getUserId()) {
+            if ($this->getProcessing()==0 && $this->getMustTerminate()==0) {
+                $this->_canCancelProcess = true;
+            }
+        } else {
+            // time too long and greater than automatic unlock process time
+            if ((time() - $this->getPhaseStartTime()) > self::PROCESS_TIME_UNLOCK) {
+                if ($this->getProcessing()==0 && $this->getMustTerminate()==0) {
+                    $this->_canCancelProcess = true;
+                }
+            }
+        }
+
+        if ($this->getProcessing()>0) {
+            $this->_msgList['error'][] = $this->_l10n->t('Une opération "' . self::_getPhaseName($this->getPhase()). '" est déjà en cours...');
+
+            if (!empty($this->getUserId()) && $this->_userId!==$this->getUserId()) {
+                $this->_msgList['error'][] = $this->_l10n->t('Opération démarrée par l\'utilisateur "' . $this->getUserId() . '".');
+            } else {
+                $this->_msgList['error'][] = $this->_l10n->t('Veuillez patienter');
+            }
+        } else if (!empty($this->getUserId()) && $this->_userId!==$this->getUserId()) {
+            $this->_msgList['error'][] = $this->_l10n->t('Une opération "' . self::_getPhaseName($this->getPhase()) . '" a déjà été démarrée par l\'utilisateur "' . $this->getUserId() . '".');
+        } else if ($this->getHasError()>0) {
+            if ($this->getMustTerminate()==1) {
+                // last process terminate with errors and we have to determine action to unlock it
+                $this->_msgList['error'][] = $this->_l10n->t('L\'opération "' . self::_getPhaseName($this->getPhase()) . '" s\'est terminée avec les erreurs suivantes') . ' : ';
+                $this->_msgList['error'][] = $this->getErrorMsg();
+            }
+        }
+    }
+
+    /**
+     * Get archive list
+     *
+     * @param   int         $stepStatus             [=-1] for all (not deleted), 0 for step init, 1 for step in progress and 2 for step archived
+     * @param   bool        $refresh                [=false] not to refresh list form API, else true
+     * @return  array       Archive list
+     */
+    public function getArchiveList($stepStatus = -1, $refresh = false) {
+        // get archive list
+        $dematpayslipArchiveMapper = new DematpayslipArchiveMapper($this->_dbConnection);
+
+        if ($refresh === true) {
+            if ($stepStatus === -1) {
+                $dematpayslipArchiveList = $dematpayslipArchiveMapper->findAll(0);
+            } else {
+                $dematpayslipArchiveList = $dematpayslipArchiveMapper->findAllByStepStatus($stepStatus);
+            }
+
+            if (!empty($dematpayslipArchiveList)) {
+                foreach ($dematpayslipArchiveList as $dematpayslipArchive) {
+                    if (empty($dematpayslipArchive->getPastellIdDocument()))  continue;
+
+                    $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
+                        }
+                    }
+
+                    // Pastell API config
+                    $pastellConfigFlowId = $this->_config->getAppValue($this->_appName, 'pastell_config_f' . $archiveFlowNum . '_id', '');
+                    $pastellConfigFlowMapper = new PastellConfigFlowMapper($this->_dbConnection);
+                    $pastellConfigFlow = $pastellConfigFlowMapper->find($pastellConfigFlowId);
+
+                    try {
+                        // Pastell API connection
+                        $pastellAPI = new PastellAPI($pastellConfigFlow->getIdConfig());
+
+                        // 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);
+                        }
+                    } catch (Exception $e) {
+                        $this->_msgList['error'][] = $e->getMessage();
+                    }
+
+                    if ($this->hasError())    break;
+                }
+            }
+
+            if (!$this->hasError()) {
+                $this->_msgList['success'][] = $this->_l10n->t('Liste actualisée avec succès.');
+            }
+        }
+
+        if ($stepStatus === -1) {
+            $dematpayslipArchiveList = $dematpayslipArchiveMapper->findAll(0);
+        } else {
+            $dematpayslipArchiveList = $dematpayslipArchiveMapper->findAllByStepStatus($stepStatus);
+        }
+
+        return $dematpayslipArchiveList;
+    }
+
+    /**
+     * Get can cancel process
+     *
+     * @return bool
+     */
+    public function getCanCancelProcess() {
+        return $this->_canCancelProcess;
+    }
+
+    /**
+     * Get export dir user path
+     *
+     * @return mixed
+     */
+    public function getExportDirUserPath() {
+        return $this->_exportDirUserPath;
+    }
+
+    /**
+     * Get message list
+     *
+     * @return array[]
+     */
+    public function getMsgList() {
+        return $this->_msgList;
+    }
+
+    /**
+     * Get Pastell app exists
+     *
+     * @return bool
+     */
+    public function getPastellAppExists() {
+        return $this->_pastellAppExists;
+    }
+
+    /**
+     * Determine if process contains errors
+     *
+     * @return bool
+     */
+    public function hasError() {
+        if (count($this->_msgList['error']) <= 0) {
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    /**
+     * Load
+     *
+     * @param   string                          $appName                            App name
+     * @param   IConfig                         $config                             Config
+     * @param   IDBConnection                   $dbConnection                       Database connection
+     * @param   IL10N                           $l10n                               Lang
+     * @param   IRootFolder                     $rootFolder                         Root folder
+     * @param   IShareManager                   $shareManager                       Share manager
+     * @param   IUserManager                    $userManager                        User manager
+     * @param   string                          $userId                             User id
+     * @param   DematpayslipProcessMapper       $dematpayslipProcessMapper          Process mapper
+     * @param   DematpayslipProcessSkipMapper   $dematpayslipProcessSkipMapper      Process skip mapper
+     * @param   DematpayslipUserMapper          $dematpayslipUserMapper             User mapper
+     * @param   DateTimeZone                    $timeZone                           [=null] Time zone
+     * @return  array[]                         Config list
+     */
+    public function load(string $appName, IConfig $config, IDBConnection $dbConnection, IL10N $l10n, IRootFolder $rootFolder, IShareManager $shareManager, IUserManager $userManager, string $userId, DematpayslipProcessMapper $dematpayslipProcessMapper, DematpayslipProcessSkipMapper $dematpayslipProcessSkipMapper, DematpayslipUserMapper $dematpayslipUserMapper, DateTimeZone $timeZone = null) {
+        $this->_appName = $appName;
+        $this->_config = $config;
+        //$this->_dateTimeZone = $dateTimeZone;
+        $this->_dbConnection = $dbConnection;
+        $this->_l10n = $l10n;
+        $this->_rootFolder = $rootFolder;
+        $this->_shareManager = $shareManager;
+        $this->_timeZone = $timeZone;
+        $this->_userManager = $userManager;
+        $this->_userId = $userId;
+
+        $this->_dematpayslipProcessMapper = $dematpayslipProcessMapper;
+        $this->_dematpayslipProcessSkipMapper = $dematpayslipProcessSkipMapper;
+        $this->_dematpayslipUserMapper = $dematpayslipUserMapper;
+
+        $this->_pastellAppExists = $this->_checkPastellAppExists();
+        $this->_loadConfig();
+
+        return $this->_dematpayslipConfigList;
+    }
+
+    /**
+     * Load config
+     */
+    private function _loadConfig() {
+        $this->_dematpayslipConfigList = self::loadConfigFrom($this->_appName, $this->_config, $this->_l10n,$this->_msgList);
+    }
+
+    /**
+     * Load config from parameters
+     *
+     * @param   string  $appName    App name
+     * @param   IConfig $config     Config
+     * @param   IL10N   $l10n       Lang
+     * @param   array   $msgList    Message list
+     * @return  array
+     */
+    public static function loadConfigFrom(string $appName, IConfig $config, IL10N $l10n, &$msgList) {
+        $configList = array();
+
+        $configList['payslip_dir']  = $config->getAppValue($appName, 'payslip_dir', 'Bulletins');       // Bulletins
+        $configList['user_id']      = $config->getAppValue($appName, 'user_id', 'demat');               // demat
+        $configList['app_data_dir'] = $config->getAppValue($appName, 'app_data_dir', 'dematpayslip');   // dematpayslip directory of user demat (upload, check, report, etc)
+        if (empty($configList['payslip_dir']) || empty($configList['user_id'])) {
+            $msgList['error'][] = $l10n->t('Veuillez vérifier la configuration de cette application.');
+        }
+
+        $configList['pastell_use'] = $config->getAppValue($appName, 'pastell_use', '');
+        if (!empty($configList['pastell_use'])) {
+            // check Pastell API config
+            $configList['pastell_config_f1_id'] = $config->getAppValue($appName, 'pastell_config_f1_id', '');
+            $configList['pastell_config_f2_id'] = $config->getAppValue($appName, 'pastell_config_f2_id', '');
+            if (!($configList['pastell_config_f1_id'] > 0) || !($configList['pastell_config_f2_id'] > 0)) {
+                $msgList['error'][] = $l10n->t('Veuillez vérifier la configuration de cette application.');
+            }
+        }
+
+        return $configList;
+    }
+
+    /**
+     * Cancel a process
+     *
+     * @throws  Exception
+     */
+    public function cancel() {
+        $this->_initDematUser();
+
+        $this->_processCheck();
+        if ($this->_canCancelProcess === true) {
+            $this->_processCancel();
+        }
+    }
+
+    /**
+     * Index
+     *
+     * @throws Exception
+     */
+    public function index() {
+        $this->_initDematUser();
+
+        $this->_processCheck();
+        if (!$this->hasError()) {
+            if ($this->getPhase()==self::PHASE_ID_UPLOAD) {
+                // scan uploaded files
+                $uploadedCSVAndPDFArr = $this->_findUploadedCSVAndPDF();
+                $uploadFileCSVName = $uploadedCSVAndPDFArr['csv'];
+                $uploadFilePDFName = $uploadedCSVAndPDFArr['pdf'];
+
+                if (!empty($uploadFileCSVName) && !empty($uploadFilePDFName)) {
+                    $this->setPhase(self::PHASE_ID_CHECK);
+                    $this->setCsvOrigin($uploadFileCSVName);
+                    $this->setPdfOrigin($uploadFilePDFName);
+                    $this->_dematpayslipProcessMapper->update($this);
+                }
+            }
+        }
+    }
+
+    /**
+     * Upload
+     *
+     * @throws Exception
+     */
+    public function upload() {
+        $this->_initDematUser();
+
+        $this->_processCheck();
+        if (count($this->_msgList['error'])<=0) {
+            $dateTimeNow = new DateTime('now', $this->_timeZone);
+
+            $this->setProcessing(1);
+            $this->setPhase(self::PHASE_ID_UPLOAD);
+            $this->setPhaseStartTime($dateTimeNow->getTimestamp());
+            $this->setPhaseStepNum(0);
+            $this->setHasError(0);
+            $this->setErrorCode(0);
+            $this->setErrorMsg('');
+            $this->setMustTerminate(0);
+            $this->setCsvOrigin('');
+            $this->setPdfOrigin('');
+            $this->_dematpayslipProcessMapper->update($this);
+
+            // check upload CSV
+            $uploadFileCSVName    = '';
+            $uploadFileCSVTmpName = '';
+            if (!isset($_FILES['payslips_csv_file'])) {
+                $errorMsg = $this->_l10n->t('Veuillez sélectionner un fichier CSV.');
+                $this->_processErrorMsg(-1, $errorMsg);
+            } else {
+                $uploadFileArr = $_FILES['payslips_csv_file'];
+                //var_dump($uploadFileArr['type']);
+                if (empty($uploadFileArr['name'])) {
+                    $errorMsg = $this->_l10n->t('Veuillez sélectionner un fichier CSV.');
+                    $this->_processErrorMsg(-1, $errorMsg);
+                } else if (!in_array($uploadFileArr['type'], array('text/csv', 'application/octet-stream', 'application/vnd.ms-excel'))) {
+                    $errorMsg = $this->_l10n->t('Veuillez sélectionner un fichier CSV valide.');
+                    $this->_processErrorMsg(-1, $errorMsg);
+                } else if ($uploadFileArr['size']<=0) {
+                    $errorMsg = $this->_l10n->t('Veuillez sélectionner un fichier CSV non vide.');
+                    $this->_processErrorMsg(-1, $errorMsg);
+                } else if (empty($uploadFileArr['tmp_name'])) {
+                    $errorMsg = $this->_l10n->t('Impossible d\'uploader ce fichier CSV.');
+                    $this->_processErrorMsg(-1, $errorMsg);
+                } else if ($uploadFileArr['error']!==UPLOAD_ERR_OK) {
+                    $errorMsg = $this->_l10n->t('Echec d\'upload du fichier CSV [=' . $uploadFileArr['error'] . '].');
+                    $this->_processErrorMsg(-1, $errorMsg);
+                } else {
+                    // upload success
+                    $uploadFileCSVName    = $uploadFileArr['name'];
+                    $uploadFileCSVTmpName = $uploadFileArr['tmp_name'];
+                }
+            }
+
+            // check upload PDF
+            $uploadFilePDFName    = '';
+            $uploadFilePDFTmpName = '';
+            if (!isset($_FILES['payslips_pdf_file'])) {
+                $errorMsg = $this->_l10n->t('Veuillez sélectionner un fichier PDF.');
+                $this->_processErrorMsg(-1, $errorMsg);
+            } else {
+                $uploadFileArr = $_FILES['payslips_pdf_file'];
+                if (empty($uploadFileArr['name'])) {
+                    $errorMsg = $this->_l10n->t('Veuillez sélectionner un fichier PDF.');
+                    $this->_processErrorMsg(-1, $errorMsg);
+                } else if ($uploadFileArr['type']!='application/pdf') {
+                    $errorMsg = $this->_l10n->t('Veuillez sélectionner un fichier PDF valide.');
+                    $this->_processErrorMsg(-1, $errorMsg);
+                } else if ($uploadFileArr['size']<=0) {
+                    $errorMsg = $this->_l10n->t('Veuillez sélectionner un fichier PDF non vide.');
+                    $this->_processErrorMsg(-1, $errorMsg);
+                } else if (empty($uploadFileArr['tmp_name'])) {
+                    $errorMsg = $this->_l10n->t('Impossible d\'uploader ce fichier PDF.');
+                    $this->_processErrorMsg(-1, $errorMsg);
+                } else if ($uploadFileArr['error']!==UPLOAD_ERR_OK) {
+                    $errorMsg = $this->_l10n->t('Echec d\'upload du fichier PDF [=' . $uploadFileArr['error'] . '].');
+                    $this->_processErrorMsg(-1, $errorMsg);
+                } else {
+                    // upload success
+                    $uploadFilePDFName    = $uploadFileArr['name'];
+                    $uploadFilePDFTmpName = $uploadFileArr['tmp_name'];
+                }
+            }
+
+            if ($this->getHasError()<=0) {
+                // vider le dossier Upload
+                if (is_dir($this->_uploadDirFullPath)) {
+                    self::_removeAllFilesDir($this->_uploadDirFullPath);
+                }
+
+                // upload CSV
+                $uploadFilePath = $this->_uploadDirFullPath . DIRECTORY_SEPARATOR . $uploadFileCSVName;
+                if (!move_uploaded_file($uploadFileCSVTmpName, $uploadFilePath)) {
+                    $errorMsg = $this->_l10n->t('Echec d\'upload du fichier CSV dans le répertoire ' . $uploadFilePath . '.');
+                    $this->_processErrorMsg(-1, $errorMsg);
+                }
+
+                // upload PDF
+                $uploadFilePath = $this->_uploadDirFullPath . DIRECTORY_SEPARATOR . $uploadFilePDFName;
+                if (!move_uploaded_file($uploadFilePDFTmpName, $uploadFilePath)) {
+                    $errorMsg = $this->_l10n->t('Echec d\'upload du fichier PDF dans le répertoire ' . $uploadFilePath . '.');
+                    $this->_processErrorMsg(-1,$errorMsg);
+                }
+            }
+
+            if ($this->getHasError()>0) {
+                if ($this->getPhase()==self::PHASE_ID_UPLOAD) {
+                    // scan uploaded files
+                    $uploadedCSVAndPDFArr = $this->_findUploadedCSVAndPDF();
+                    $uploadFileCSVName = $uploadedCSVAndPDFArr['csv'];
+                    $uploadFilePDFName = $uploadedCSVAndPDFArr['pdf'];
+
+                    if (!empty($uploadFileCSVName) && !empty($uploadFilePDFName)) {
+                        $this->setPhase(self::PHASE_ID_CHECK);
+                        $this->setCsvOrigin($uploadFileCSVName);
+                        $this->setPdfOrigin($uploadFilePDFName);
+                        $this->setUserId($this->_userId);
+                        $this->_dematpayslipProcessMapper->update($this);
+                    }
+                }
+            } else {
+                $this->_msgList['success'][] = $this->_l10n->t('Opération "' . self::_getPhaseName($this->getPhase()) . '" terminée avec succès.');
+                $this->setPhase(self::PHASE_ID_CHECK);
+                $this->setCsvOrigin($uploadFileCSVName);
+                $this->setPdfOrigin($uploadFilePDFName);
+                $this->setUserId($this->_userId);
+            }
+
+            $this->setProcessing(0);
+            $this->_dematpayslipProcessMapper->update($this);
+        }
+    }
+
+    /**
+     * Check
+     *
+     * @throws Exception
+     */
+    public function check() {
+        $this->_initDematUser();
+        $this->_processCheck();
+        if ($this->getPhase() < self::PHASE_ID_CHECK) {
+            $this->_msgList['error'][] = $this->_l10n->t('Opération impossible : phase en cours "' . self::_getPhaseName($this->getPhase()) . '".');
+        }
+
+        if (count($this->_msgList['error']) <= 0) {
+            $this->_processFailOnFirstError = false;
+            $dateTimeNow = new DateTime('now', $this->_timeZone);
+
+            $this->setProcessing(1);
+            $this->setPhase(self::PHASE_ID_CHECK);
+            $this->setPhaseStartTime($dateTimeNow->getTimestamp());
+            $this->setPhaseStepNum(0);
+            $this->setMustTerminate(0);
+            $this->setHasError(0);
+            $this->setErrorCode(0);
+            $this->setErrorMsg('');
+            $this->setUserId($this->_userId);
+            $this->_dematpayslipProcessMapper->update($this);
+
+            // empty process skip lines
+            $this->_dematpayslipProcessSkipMapper->deleteAllByIdProcess($this->getId());
+
+            // clean "check" directory
+            if (is_dir($this->_checkDirFullPath)) {
+                self::_removeAllFilesDir($this->_checkDirFullPath);
+            }
+
+            $uploadFilePDFName = $this->getPdfOrigin();
+            $uploadFileCSVName = $this->getCsvOrigin();
+
+            // log file
+            $logFilePath = $this->_checkDirUserPath . DIRECTORY_SEPARATOR . $this->getPhase() . '_log';
+            $this->_logFile = Filesystem::fopen($logFilePath, 'w+');
+            $this->_logCsvCols(array('date', 'heure', 'niveau', 'message', 'siret', 'matricule', 'nom_prenom', 'zip_city', 'date_debut', 'date_fin', 'email'));
+            $this->_logCsvLine('## ' .$this->_l10n->t('Début du processus de vérification.') . ' ##', self::LOG_DEBUG);
+
+            $csvCheckFileName = $dateTimeNow->format('Y-m-d_H-i-s') . '_' . $uploadFileCSVName;
+
+            $this->_logCsvLine('## ' .$this->_l10n->t('Début de vérification des champs du fichier CSV.') . ' ##', self::LOG_DEBUG);
+            // pdf read and parse
+            $pdfFilePath = $this->_uploadDirFullPath . DIRECTORY_SEPARATOR . $uploadFilePDFName;
+            $pdfPages = array();
+            if ($this->_processFailOnFirstError===false || $this->getHasError()<=0) {
+                $this->_logCsvLine($this->_l10n->t('Lecture du fichier PDF.'), self::LOG_DEBUG);
+                $pdfParser = new \Smalot\PdfParser\Parser();
+                $pdf = $pdfParser->parseFile($pdfFilePath);
+                $pdfPages = $pdf->getPages();
+                $pdfPageNb = count($pdfPages);
+                if ($pdfPageNb <= 0) {
+                    $errorMsg = $this->_l10n->t('Aucune page dans le PDF "' . $uploadFilePDFName . '".');
+                    $this->_logCsvLine($errorMsg, self::LOG_ERROR);
+                    $this->_processErrorMsg(-1, $errorMsg);
+                }
+            }
+
+            // csv read and load all lines
+            $csvTodoLineList = array();
+            if ($this->_processFailOnFirstError===false || $this->getHasError()<=0) {
+                $this->_logCsvLine($this->_l10n->t('Ouverture du fichier CSV.'), self::LOG_DEBUG);
+                $csvFilePath = $this->_uploadDirFullPath . DIRECTORY_SEPARATOR . $uploadFileCSVName;
+                $csvFile = fopen($csvFilePath, 'r');
+                if (!$csvFile) {
+                    $errorMsg = $this->_l10n->t('Impossible d\'ouvrir le fichier CSV "' . $uploadFileCSVName . '".');
+                    $this->_logCsvLine($errorMsg, self::LOG_ERROR);
+                    $this->_processErrorMsg(-1, $errorMsg);
+                } else {
+                    $csvLineNum = 0;
+                    $csvLineNumBegin = 0;
+                    $this->_csvEncodeFrom = 'ISO-8859-1';
+                    $csvConvert = false;
+                    if (!empty($this->_csvEncodeFrom) && $this->_csvEncodeFrom!=$this->_csvEncodeTo) {
+                        $csvConvert = true;
+                    }
+                    $this->_logCsvLine($this->_l10n->t('Lecture des lignes du fichier CSV.'), self::LOG_DEBUG);
+                    while ($csvLine = fgetcsv($csvFile, $this->_csvLength, $this->_csvDelimiter, $this->_csvEnclosure)) {
+                        $this->_logCsvLine('-- ' . $this->_l10n->t('Début de ligne CSV : ' .  ($csvLineNum + 1)) . ' --', self::LOG_DEBUG);
+
+                        if ($csvLineNum >= $csvLineNumBegin) {
+                            if ($csvConvert === true) {
+                                foreach ($csvLine as $csvColNum => $csvValue) {
+                                    $csvLine[$csvColNum] = mb_convert_encoding(trim($csvValue), $this->_csvEncodeTo,  $this->_csvEncodeFrom);
+                                }
+                            }
+                            $matriculeOri = $csvLine[1];
+                            $startDate    = date('Y-m-d', strtotime($csvLine[13]));
+                            $endDate      = date('Y-m-d', strtotime($csvLine[14]));
+                            $editionDate  = date('Y-m-d', strtotime($csvLine[17]));
+
+                            // agent user
+                            $agentUser = new DematpayslipUser();
+                            $agentUser->setId(0);
+                            $agentUser->setUserId('');
+                            $agentUser->setSiret($csvLine[0]);
+                            $agentUser->setMatricule(str_pad($matriculeOri, '8', '0', STR_PAD_LEFT));
+                            $agentUser->setLastname($csvLine[3]);
+                            $agentUser->setFirstname($csvLine[4]);
+                            $agentUser->setEmail($csvLine[5]);
+                            $agentUser->setZipCity($csvLine[10]);
+
+                            // verifier l'existance de l'email et autres champs (regex)
+                            $this->_logCsvLine($this->_l10n->t('Ligne CSV'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
+                            if (empty($agentUser->getEmail())) {
+                                $warningMsg = $this->_l10n->t('Le fichier CSV "' . $uploadFileCSVName . '" contient un champ email vide [ligne=' . ($csvLineNum + 1) . '].');
+                                $this->_logCsvLine($warningMsg, self::LOG_WARNING, $agentUser, $startDate, $endDate);
+                                $this->_processWarningMsg($warningMsg);
+
+                                // sauter cette ligne dans la suite du process de verification et d'indexation
+                                //$dematpayslipProcessSkipLineArr = $this->_dematpayslipProcessSkipMapper->findAllByIdProcessAndIdLine($this->getId(), $csvLineNum);
+                                //if (empty($dematpayslipProcessSkipLineArr)) {
+                                //    $dematpayslipProcessSkip = new DematpayslipProcessSkip();
+                                //    $dematpayslipProcessSkip->setIdProcess($this->getId());
+                                //    $dematpayslipProcessSkip->setIdLine($csvLineNum);
+                                //    $this->_dematpayslipProcessSkipMapper->insert($dematpayslipProcessSkip);
+                                //}
+                            } else {
+                                $userFindByEmailList = $this->_userManager->getByEmail($agentUser->getEmail());
+
+                                // /!\ remove all users not available (FIX for multiple users with SAML)
+                                if (self::USER_REMOVE_UNKNOWN == 1) {
+                                    $userFindByEmailList = self::_removeUnknownUser($userFindByEmailList);
+                                }
+
+                                if (count($userFindByEmailList) != 1) {
+                                    $warningMsg = $this->_l10n->t('Le fichier CSV "' . $uploadFileCSVName . '" contient un email "' . $agentUser->getEmail() . '" non valide ou non lié à un unique utilisateur Nextcloud [ligne=' . ($csvLineNum + 1) . '].');
+                                    $this->_logCsvLine($warningMsg, self::LOG_WARNING, $agentUser, $startDate, $endDate);
+                                    $this->_processWarningMsg($warningMsg);
+
+                                    $dematpayslipProcessSkipLineArr = $this->_dematpayslipProcessSkipMapper->findAllByIdProcessAndIdLine($this->getId(), $csvLineNum);
+                                    if (empty($dematpayslipProcessSkipLineArr)) {
+                                        $dematpayslipProcessSkip = new DematpayslipProcessSkip();
+                                        $dematpayslipProcessSkip->setIdProcess($this->getId());
+                                        $dematpayslipProcessSkip->setIdLine($csvLineNum);
+                                        $this->_dematpayslipProcessSkipMapper->insert($dematpayslipProcessSkip);
+                                    }
+                                }
+                            }
+
+                            if ($this->_processFailOnFirstError===false || $this->getHasError()<=0) {
+                                $csvTodoLineList[] = array(
+                                    'siret'         => $agentUser->getSiret(),
+                                    'matricule_ori' => $matriculeOri,
+                                    'lastname'      => $agentUser->getLastname(),
+                                    'firstname'     => $agentUser->getFirstname(),
+                                    'zip_city'      => $agentUser->getZipCity(),
+                                    'start_date'    => $startDate,
+                                    'end_date'      => $endDate,
+                                    'edition_date'  => $editionDate,
+                                    'matricule'     => $agentUser->getMatricule(),
+                                    'fullname'      => $agentUser->getLastname() . ' ' . $agentUser->getFirstname(),
+                                    'email'         => $agentUser->getEmail(),
+                                    'line_num'      => $csvLineNum + 1,
+                                    'pdf_pages'     => '',
+                                );
+                            }
+                        }
+
+                        if ($this->_processFailOnFirstError===true && $this->getHasError()>0) {
+                            $this->_logCsvLine('-- ' . $this->_l10n->t('Fin de ligne CSV : ' .  ($csvLineNum + 1)) . ' --', self::LOG_ERROR);
+                            break;
+                        } else {
+                            $this->_logCsvLine('-- ' . $this->_l10n->t('Fin de ligne CSV : ' .  ($csvLineNum + 1)) . ' --', self::LOG_DEBUG);
+                        }
+
+                        $csvLineNum++;
+                    }
+                    fclose($csvFile);
+                }
+            }
+            if ($this->_processFailOnFirstError===false || $this->getHasError()<=0) {
+                if (count($csvTodoLineList) <= 0) {
+                    $errorMsg = $this->_l10n->t('Aucune ligne dans le fichier CSV "' . $uploadFileCSVName . '".');
+                    $this->_logCsvLine($errorMsg, self::LOG_ERROR);
+                    $this->_processErrorMsg(-1, $errorMsg);
+                }
+            }
+            $this->_logCsvLine('## ' .$this->_l10n->t('Fin de vérification des champs du fichier CSV.') . ' ##', self::LOG_DEBUG);
+
+            if ($this->getHasError()>0)   $this->_processFailOnFirstError=true;
+            if ($this->_processFailOnFirstError===false || $this->getHasError()<=0) {
+                $this->_logCsvLine('## ' .$this->_l10n->t('Début de l\'association des pages du PDF aux différents agents.') . ' ##', self::LOG_DEBUG);
+
+                $this->_logCsvLine($this->_l10n->t('Création du fichier CSV des assoications des pages de bulletins de paie aux différents agents.'), self::LOG_DEBUG);
+                $csvCheckFilePath = $this->_checkDirFullPath . DIRECTORY_SEPARATOR . $csvCheckFileName;
+                $csvCheckFile = fopen($csvCheckFilePath, 'w+');
+                if (!$csvCheckFile) {
+                    $errorMsg = $this->_l10n->t('Impossible de créer le fichier CSV "' . $csvCheckFileName . '".');
+                    $this->_logCsvLine($errorMsg, self::LOG_ERROR);
+                    $this->_processErrorMsg(-1, $errorMsg);
+                }
+
+                if ($this->_processFailOnFirstError===false || $this->getHasError()<=0) {
+                    $checkLastValues = array(
+                        'siret'     => '',
+                        'matricule' => '',
+                        'fullname'  => '',
+                        'zip_city'  => '',
+                    );
+
+                    $checkLastLineNum = -1;
+
+                    // pour chaque page du PDF
+                    $this->_logCsvLine($this->_l10n->t('Lecture des pages du fichier PDF.'), self::LOG_DEBUG);
+                    $pdfPageList = array();
+                    foreach ($pdfPages as $pdfPageNum => $pdfPage) {
+                        $this->_logCsvLine('-- ' . $this->_l10n->t('Page PDF en cours : ' .  ($pdfPageNum + 1) . ' --'), self::LOG_DEBUG);
+
+                        // recuperer les champs textes dans le PDF et enlever les espaces
+                        $this->_logCsvLine($this->_l10n->t('Récupération des champs textes du fichier PDF.'), self::LOG_DEBUG);
+                        $pdfPageTextList = array();
+                        $pdfPageTextArr = $pdfPage->getTextArray();
+                        foreach ($pdfPageTextArr as $pdfPageTextKey => $pdfPageText) {
+                            // formater les champs textes du PDF (enlever les espaces)
+                            $pdfPageTextList[] = trim($pdfPageText);
+                        }
+
+                        // pour chaque ligne du CSV restant a traiter
+                        $this->_logCsvLine($this->_l10n->t('Lecture des lignes fichier CSV.'), self::LOG_DEBUG);
+                        $csvTodoLineNum = 0;
+                        $csvTodoLine = array();
+                        $checkCurrentValues = array();
+                        $pdfPageValues = array();
+                        $agentFound = false;
+                        foreach ($csvTodoLineList as $csvTodoLineNum => $csvTodoLine) {
+                            $this->_logCsvLine('-- ' . $this->_l10n->t('Début de ligne CSV : ' .  ($csvTodoLineNum + 1)) . ' --', self::LOG_DEBUG);
+
+                            // recuperer les valeurs de controle
+                            $checkCurrentValues = array(
+                                'siret'     => $csvTodoLine['siret'],
+                                'matricule' => $csvTodoLine['matricule'],
+                                'fullname'  => $csvTodoLine['fullname'],
+                                'zip_city'  => $csvTodoLine['zip_city'],
+                            );
+
+                            $pdfPageValues = array();
+
+                            // pour chaque champ CSV a controler
+                            foreach ($checkCurrentValues as $checkField => $checkCurrentValue) {
+                                // verifier d'abord aux emplacements previsibles du PDF
+                                if ($checkField == 'siret') {
+                                    // siret
+                                    if (isset($this->_payslipPDFSearchFieldList[$checkField]) && !empty($this->_payslipPDFSearchFieldList[$checkField])) {
+                                        foreach ($this->_payslipPDFSearchFieldList[$checkField] as $payslipPDFSearchFieldIndex) {
+                                            $matchList = array();
+                                            if (preg_match('#SIRET:\s(\d+)\s\d+$#', $pdfPageTextList[$payslipPDFSearchFieldIndex], $matchList)) {
+                                                if ($matchList[1] == $checkCurrentValue) {
+                                                    $pdfPageValues[$checkField] = $checkCurrentValue;
+                                                    continue;
+                                                }
+                                            }
+                                        }
+                                    }
+                                } else {
+                                    // siret, matricule, fullname, zip_city
+                                    if (isset($this->_payslipPDFSearchFieldList[$checkField]) && !empty($this->_payslipPDFSearchFieldList[$checkField])) {
+                                        foreach ($this->_payslipPDFSearchFieldList[$checkField] as $payslipPDFSearchFieldIndex) {
+                                            if ($pdfPageTextList[$payslipPDFSearchFieldIndex] == $checkCurrentValue) {
+                                                $pdfPageValues[$checkField] = $checkCurrentValue;
+                                                break;
+                                            }
+                                        }
+                                    }
+                                }
+
+                                if (!isset($pdfPageValues[$checkField])) {
+                                    // si on a pas trouve aux emplacement previsibles du PDF
+                                    // pour chaque champ texte de la page du PDF
+                                    foreach ($pdfPageTextList as $pdfPageTextKey => $pdfPageText) {
+                                        // formater les champs textes du PDF (enlever les espaces)
+                                        $pdfPageTextValue = trim($pdfPageText);
+
+                                        if ($checkField == 'siret') {
+                                            $matchList = array();
+                                            if (preg_match('#SIRET:\s(\d+)\s\d+$#', $pdfPageTextValue, $matchList)) {
+                                                if ($matchList[1] == $checkCurrentValue) {
+                                                    $pdfPageValues[$checkField] = $checkCurrentValue;
+                                                    break;
+                                                }
+                                            }
+                                        } else {
+                                            // siret, matricule, fullname, zip_city
+                                            if ($pdfPageTextValue == $checkCurrentValue) {
+                                                $pdfPageValues[$checkField] = $checkCurrentValue;
+                                                break;
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+
+                            // verifie si on a trouve un agent correspondant a la ligne du fichier CSV en cours
+                            $agentFound = false;
+                            if (!empty($pdfPageValues)) {
+                                foreach ($checkCurrentValues as $checkField => $checkCurrentValue) {
+                                    if (!isset($pdfPageValues[$checkField]) || empty($pdfPageValues[$checkField])) {
+                                        $agentFound = false;
+                                        break;
+                                    } else {
+                                        $agentFound = true;
+                                    }
+                                }
+                            }
+                            if ($agentFound === true) {
+                                break;
+                            }
+
+                            $this->_logCsvLine('-- ' . $this->_l10n->t('Fin de ligne CSV : ' .  ($csvTodoLineNum + 1)) . ' --', self::LOG_DEBUG);
+                        }
+
+                        if ($agentFound !== true) {
+                            $errorMsg = $this->_l10n->t('Aucun agent trouve dans la page ' . ($pdfPageNum + 1) . ' du PDF correspondant aux lignes du fichier CSV.');
+                            $this->_logCsvLine($errorMsg, self::LOG_ERROR);
+                            $this->_processErrorMsg(-1, $errorMsg);
+                            break;
+                        } else {
+                            // si on a bien trouve l'agent correspondant a la page du PDF
+                            $siret = $csvTodoLine['siret'];
+                            $matricule = $csvTodoLine['matricule'];
+                            $period = $csvTodoLine['start_date'] . '_' . $csvTodoLine['end_date'];
+                            $agentKey = $siret . '-' . $matricule;
+                            $this->_logCsvLine($this->_l10n->t('Agent trouvé [siret=' . $siret . ', matricule=' . $matricule . ', period=' . $period . '].'), self::LOG_DEBUG);
+
+                            $newAgent = false;
+                            foreach ($checkLastValues as $checkLastField => $checLastValue) {
+                                if ($pdfPageValues[$checkLastField] != $checLastValue) {
+                                    $newAgent = true;
+                                    break;
+                                }
+                            }
+
+                            if ($newAgent === true) {
+                                $this->_logCsvLine($this->_l10n->t('C\'est un nouvel agent.'), self::LOG_DEBUG);
+                                $this->_logCsvLine($this->_l10n->t('Ajout de la page ' . ($pdfPageNum + 1) .' du PDF des bulletins de paie de l\'agent.'), self::LOG_DEBUG);
+
+                                $pdfPageList[$agentKey] = array('page_num_list' => array($pdfPageNum + 1), 'period' => $period);
+
+                                if ($checkLastLineNum >= 0) {
+                                    // mettre ligne CSV dans fichier CSV qui va servir pour l'indexation (y ajouter les numeros de pages du fichier PDF)
+                                    $checkAgentKey = $csvTodoLineList[$checkLastLineNum]['siret'] . '-' . $csvTodoLineList[$checkLastLineNum]['matricule'];
+                                    $csvTodoLineList[$checkLastLineNum]['pdf_pages'] = implode('-', $pdfPageList[$checkAgentKey]['page_num_list']);
+                                    fputcsv($csvCheckFile, $csvTodoLineList[$checkLastLineNum], $this->_csvDelimiter, $this->_csvEnclosure);
+                                    unset($csvTodoLineList[$checkLastLineNum]); // enlever ligne de l'ancien agent
+                                }
+
+                                // sauvegarder le numero de la ligne CSV lie a l'ancien agent
+                                $checkLastLineNum = $csvTodoLineNum;
+
+                                // mettre les nouvelles valeurs dans les anciennes valeurs a verifier
+                                $checkLastValues = $checkCurrentValues;
+                            } else {
+                                $this->_logCsvLine($this->_l10n->t('Ajout de la page ' . ($pdfPageNum + 1) .' du PDF des bulletins de paie de l\'agent.'), self::LOG_DEBUG);
+                                $pdfPageList[$agentKey]['page_num_list'][] = $pdfPageNum + 1;
+                            }
+
+                            // cas de la derniere page du PDF
+                            if ($pdfPageNum == $pdfPageNb - 1) {
+                                if ($checkLastLineNum >= 0) {
+                                    // mettre ligne CSV dans fichier CSV qui va servir pour l'indexation (y ajouter les numeros de pages du fichier PDF)
+                                    $checkAgentKey = $csvTodoLineList[$checkLastLineNum]['siret'] . '-' . $csvTodoLineList[$checkLastLineNum]['matricule'];
+                                    $csvTodoLineList[$checkLastLineNum]['pdf_pages'] = implode('-', $pdfPageList[$checkAgentKey]['page_num_list']);
+                                    fputcsv($csvCheckFile, $csvTodoLineList[$checkLastLineNum], $this->_csvDelimiter, $this->_csvEnclosure);
+                                    unset($csvTodoLineList[$checkLastLineNum]); // enlever ligne de l'ancien agent
+                                }
+                            }
+                        }
+
+                        $this->_logCsvLine('-- ' . $this->_l10n->t('Fin de page PDF : ' .  ($pdfPageNum + 1) . ' --'), self::LOG_DEBUG);
+                    }
+                    fclose($csvCheckFile);
+
+                    if ($this->_processFailOnFirstError===false || $this->getHasError()<=0) {
+                        // Si on n'a pas traite toutes les lignes du CSV
+                        if (count($csvTodoLineList) > 0) {
+                            $errorMsgLines = array();
+                            $errorMsgLines[] = $this->_l10n->t('Des lignes du fichier CSV "' . $uploadFileCSVName . '" n\'ont pas été traitées') . ' : ';
+                            foreach ($csvTodoLineList as $csvTodoLineNum => $csvTodoLine) {
+                                $errorMsgLines[] = ' - ' . $this->_l10n->t('la ligne ' . $csvTodoLine['line_num']);
+                            }
+                            $this->_logCsvLine(implode("\n", $errorMsgLines), self::LOG_ERROR);
+                            $this->_processErrorMsg(-1, implode('<br />', $errorMsgLines));
+                        }
+                    }
+                    $this->_logCsvLine('## ' .$this->_l10n->t('Fin de l\'association des pages du PDF aux différents agents.') . ' ##', self::LOG_DEBUG);
+                }
+
+                // Phase - decoupage des pages du fichier PDF
+                if ($this->getHasError()>0)   $this->_processFailOnFirstError = true;
+                if ($this->_processFailOnFirstError===false || $this->getHasError()<=0) {
+                    $this->_logCsvLine('## ' . $this->_l10n->t('Début de découpage des pages du fichier PDF.') . ' ##', self::LOG_DEBUG);
+
+                    // ouvrir le fichier CSV du dossier "check"
+                    $this->_logCsvLine($this->_l10n->t('Ouverture des lignes du fichier CSV contenant les pages des bulletins de paie à découper.'), self::LOG_DEBUG);
+                    $csvCheckFilePath = $this->_checkDirFullPath . DIRECTORY_SEPARATOR . $csvCheckFileName;
+                    $csvCheckFile = fopen($csvCheckFilePath, 'r');
+                    if (!$csvCheckFile) {
+                        $errorMsg = $this->_l10n->t('Impossible d\'ouvrir le fichier CSV "' . $csvCheckFileName . '".');
+                        $this->_logCsvLine($errorMsg, self::LOG_ERROR);
+                        $this->_processErrorMsg(-1, $errorMsg);
+                    }
+
+                    if ($this->_processFailOnFirstError===false || $this->getHasError()<=0) {
+                        // pour chaque ligne CSV
+                        $this->_logCsvLine($this->_l10n->t('Lecture des lignes fichier CSV.'), self::LOG_DEBUG);
+                        $csvCheckLineNum = 0;
+                        while ($csvCheckLine = fgetcsv($csvCheckFile, $this->_csvLength, $this->_csvDelimiter, $this->_csvEnclosure)) {
+                            $this->_logCsvLine('-- ' . $this->_l10n->t('Début de ligne CSV : ' .  ($csvCheckLineNum + 1)) . ' --', self::LOG_DEBUG);
+                            //$csvCheckArr[] = array(
+                            //    'siret'         => $csvCheckLine[0],
+                            //    'matricule_ori' => $csvCheckLine[1],
+                            //    'lastname'      => $csvCheckLine[2],
+                            //    'firstname'     => $csvCheckLine[3],
+                            //    'zip_city'      => $csvCheckLine[4],
+                            //    'start_date'    => $csvCheckLine[5],
+                            //    'end_date'      => $csvCheckLine[6],
+                            //    'edition_date'  => $csvCheckLine[7],
+                            //    'matricule'     => $csvCheckLine[8],
+                            //    'fullname'      => $csvCheckLine[9],
+                            //    'email'         => $csvCheckLine[10],
+                            //    'line_num'      => $csvCheckLine[11],
+                            //    'pdf_pages'     => $csvCheckLine[12],
+                            //);
+
+                            // get CSV data values
+                            $csvCheckMatricule = $csvCheckLine[8];
+                            $pdfPageNumList = explode('-', $csvCheckLine[12]);
+                            $this->_logCsvLine($this->_l10n->t('Découpage des pages du PDF pour le bulletin de paie de l\'agent [matricule=' . $csvCheckMatricule . '].'), self::LOG_DEBUG);
+
+                            // ajout des pages
+                            $this->_logCsvLine($this->_l10n->t('Ajout des pages PDF au bulletin de paie.'), self::LOG_DEBUG);
+                            $pdfPayslip = new \setasign\Fpdi\Fpdi();
+                            foreach ($pdfPageNumList as $pdfPageNum) {
+                                $this->_logCsvLine($this->_l10n->t('Ajout de la page ' . $pdfPageNum . '.'), self::LOG_DEBUG);
+                                $pdfPayslip->AddPage();
+                                $pdfPayslip->setSourceFile($pdfFilePath);
+                                $tplPayslipId = $pdfPayslip->importPage($pdfPageNum);
+                                $pdfPayslip->useTemplate($tplPayslipId);
+                            }
+
+                            /// mettre la fiche de paie dans le dossier "check"
+                            $this->_logCsvLine($this->_l10n->t('Créer le PDF du bulletin de paie.'), self::LOG_DEBUG);
+                            $pdfPayslip->Output('F', $this->_checkDirFullPath . DIRECTORY_SEPARATOR . ($csvCheckLineNum + 1) . '_' . $csvCheckMatricule . '.pdf');
+
+                            $this->_logCsvLine('-- ' . $this->_l10n->t('Fin de ligne CSV : ' .  ($csvCheckLineNum + 1)) . ' --', self::LOG_DEBUG);
+
+                            $csvCheckLineNum++;
+                        }
+                        fclose($csvCheckFile);
+                    }
+
+                    $this->_logCsvLine('## ' . $this->_l10n->t('Fin de découpage des pages du fichier PDF.') . ' ##', self::LOG_DEBUG);
+                }
+            }
+
+            if ($this->getHasError() <= 0) {
+                $successMsg = $this->_l10n->t('Opération "' . self::_getPhaseName($this->getPhase()) . '" terminée avec succès.');
+                $this->_logCsvLine($successMsg, self::LOG_SUCCESS);
+                $this->_msgList['success'][] = $successMsg;
+                $this->setPhase(self::PHASE_ID_PRE_INDEXATION);
+                $this->setCsvCheck($csvCheckFileName);
+            }
+
+            $this->_logCsvLine('## ' .$this->_l10n->t('Fin du processus de vérification.') . ' ##', self::LOG_DEBUG);
+            fclose($this->_logFile);
+            // rename (log file)
+            try {
+                $userFolder = $this->_rootFolder->getUserFolder($this->_userId);
+                $logFileNode = $userFolder->get($logFilePath);
+                $logFileNode->move($logFileNode->getPath() . '.csv');
+            } catch (Exception $e) {
+                $this->_msgList['error'][] = $this->_l10n->t('Impossible de déplacer le fichier de log "' . $logFilePath . '" .');
+            }
+            $this->setProcessing(0);
+            $this->_dematpayslipProcessMapper->update($this);
+        }
+    }
+
+    /**
+     * Pre-indexation
+     */
+    public function preIndexation() {
+        $this->_initDematUser();
+
+        $this->_processCheck();
+        if ($this->getPhase() < self::PHASE_ID_PRE_INDEXATION) {
+            $this->_msgList['error'][] = $this->_l10n->t('Opération impossible : phase en cours "' . self::_getPhaseName($this->getPhase()) . '".');
+        }
+
+        $launchIndexation = filter_input(INPUT_POST, 'payslip_launch_indexation', FILTER_SANITIZE_NUMBER_INT);
+        $launchArchive = filter_input(INPUT_POST, 'payslip_launch_archive', FILTER_SANITIZE_NUMBER_INT);
+        $launchIndexation = intval($launchIndexation);
+        $launchArchive = intval($launchArchive);
+        if ($launchIndexation != 1) {
+            $this->_msgList['error'][] = $this->_l10n->t('Veuillez sélectionner au moins l\'étape d\'"Indexation".');
+        }
+
+        if (!$this->hasError()) {
+            $operationAskList = array();
+            if ($launchIndexation == 1) {
+                $operationAskList[] = DematpayslipArchive::OPERATION_INDEXATION;
+            }
+            if ($launchArchive == 1) {
+                $operationAskList[] = DematpayslipArchive::OPERATION_ARCHIVE;
+            }
+            $operationAsk = implode('+', $operationAskList);
+
+            try {
+                $phaseStartDateTime = new DateTime('now', $this->_timeZone);
+                $phaseStartTime = $phaseStartDateTime->getTimestamp();
+
+                $this->setProcessing(1);
+                $this->setPhase(self::PHASE_ID_PRE_INDEXATION);
+                $this->setPhaseStartTime($phaseStartTime);
+                $this->setPhaseStepNum(0);
+                $this->setMustTerminate(0);
+                $this->setHasError(0);
+                $this->setErrorCode(0);
+                $this->setErrorMsg('');
+                $this->setUserId($this->_userId);
+                $this->_dematpayslipProcessMapper->update($this);
+
+                $payslipsDirPath = (string) $this->_dematpayslipConfigList['payslip_dir'];
+                $csvCheckFileName = $this->getCsvCheck();
+
+                // check and mount user directory
+                $userHomeFilesDirPath = '';
+                if ($this->getHasError() <= 0) {
+                    $user = $this->_userManager->get($this->_userId);
+                    if (!$user) {
+                        $errorMsg = $this->_l10n->t('Le dossier utilisateur "' . $this->_userId . '" n\'existe pas.');
+                        $this->_processErrorMsg(-1, $errorMsg);
+                    }
+
+                    $userHomeFilesDirPath = $user->getHome() . DIRECTORY_SEPARATOR . 'files';
+                }
+                if (empty($userHomeFilesDirPath) || !is_dir($userHomeFilesDirPath)) {
+                    $errorMsg = $this->_l10n->t('Le dossier utilisateur "' . $this->_userId . '" est introuvable.');
+                    $this->_processErrorMsg(-1, $errorMsg);
+                }
+                $userFolder = $this->_rootFolder->getUserFolder($this->_userId);
+
+                // check user payslip dir exists
+                if ($this->getHasError() <= 0) {
+                    try {
+                        $userFolder->get($payslipsDirPath);
+                    } catch (Exception $e) {
+                        $errorMsg = $this->_l10n->t('Le dossier des bulletins "' . $payslipsDirPath . '" n\'existe pas.');
+                        $this->_processErrorMsg(-1, $errorMsg);
+                    }
+                }
+
+                // check "no indexed payslip" directory exists
+                $this->_logCsvLine($this->_l10n->t('Vérification de l\'existance du dossier des bulletins non indexes.'), self::LOG_DEBUG);
+                if ($this->getHasError() <= 0) {
+                    try {
+                        $userFolder->get($this->_payslipNoIndexDir);
+                    } catch (Exception $e) {
+                        $errorMsg = $this->_l10n->t('Le dossier des bulletins non indexes "' . $this->_payslipNoIndexDir . '" n\'existe pas.');
+                        $this->_processErrorMsg(-1, $errorMsg);
+                    }
+                }
+
+                if ($this->getHasError() <= 0) {
+                    $phaseStep = 'csv_check';
+                    $csvCheckLineNum = 0;
+                    if (empty($this->getPhaseStep())) {
+                        // get all share with this user
+                        $payslipShareNode = $userFolder->get($payslipsDirPath);
+                        $payslipShareList = $this->_shareManager->getSharesInFolder($this->_userId, $payslipShareNode);
+                        $payslipMatriculeShareNodeIdList = array();
+                        if (count($payslipShareList) > 0) {
+                            foreach ($payslipShareList as $payslipShareNodeId => $payslipShareArr) {
+                                $payslipMatriculeShareNodeIdList[] = $payslipShareNodeId;
+                            }
+                        }
+
+                        // open CSV file created in check step
+                        $csvCheckFilePath = $this->_checkDirFullPath . DIRECTORY_SEPARATOR . $csvCheckFileName;
+                        $csvCheckFile = fopen($csvCheckFilePath, 'r');
+                        if (!$csvCheckFile) {
+                            $errorMsg = $this->_l10n->t('Impossible d\'ouvrir le fichier CSV "' . $csvCheckFileName . '".');
+                            $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
+                        }
+
+                        if ($this->getHasError() <= 0) {
+                            // get CSV lines to skip
+                            $dematpayslipProcessSkipLineIdList = array();
+                            $dematpayslipProcessSkipList = $this->_dematpayslipProcessSkipMapper->findAllByIdProcess($this->getId());
+                            foreach ($dematpayslipProcessSkipList as $dematpayslipProcessSkip) {
+                                $dematpayslipProcessSkipLineIdList[] = $dematpayslipProcessSkip->getIdLine();
+                            }
+
+                            // payslip archive mapper
+                            $dematpayslipArchiveMapper = new DematpayslipArchiveMapper($this->_dbConnection);
+
+                            while ($csvCheckLine = fgetcsv($csvCheckFile, $this->_csvLength, $this->_csvDelimiter, $this->_csvEnclosure)) {
+                                //$csvCheckArr[] = array(
+                                //    'siret'         => $csvCheckLine[0],
+                                //    'matricule_ori' => $csvCheckLine[1],
+                                //    'lastname'      => $csvCheckLine[2],
+                                //    'firstname'     => $csvCheckLine[3],
+                                //    'zip_city'      => $csvCheckLine[4],
+                                //    'start_date'    => $csvCheckLine[5],
+                                //    'end_date'      => $csvCheckLine[6],
+                                //    'edition_date'  => $csvCheckLine[7],
+                                //    'matricule'     => $csvCheckLine[8],
+                                //    'fullname'      => $csvCheckLine[9],
+                                //    'email'         => $csvCheckLine[10],
+                                //    'line_num'      => $csvCheckLine[11],
+                                //    'pdf_pages'     => $csvCheckLine[12],
+                                //);
+
+                                // get CSV data values
+                                $startDate = $csvCheckLine[5];
+                                $endDate = $csvCheckLine[6];
+                                $editionDate = $csvCheckLine[7];
+                                $startDateTime = strtotime($startDate);
+                                $year = date('Y', $startDateTime);
+                                $month = strtolower(strftime('%B', $startDateTime));
+                                $pdfPagesNum = $csvCheckLine[12];
+
+                                // agent user
+                                $agentUser = new DematpayslipUser();
+                                $agentUser->setId(0);
+                                $agentUser->setUserId('');
+                                $agentUser->setSiret($csvCheckLine[0]);
+                                $agentUser->setMatricule($csvCheckLine[8]);
+                                $agentUser->setLastname($csvCheckLine[2]);
+                                $agentUser->setFirstname($csvCheckLine[3]);
+                                $agentUser->setEmail($csvCheckLine[10]);
+                                $agentUser->setZipCity($csvCheckLine[4]);
+
+                                // pdf check file path
+                                $pdfPayslipCheckFileName = ($csvCheckLineNum + 1) . '_' . $agentUser->getMatricule() . '.pdf';
+                                $pdfPayslipCheckFilePath = $this->_checkDirUserPath . DIRECTORY_SEPARATOR . $pdfPayslipCheckFileName;
+
+                                // 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);
+
+                                    $csvCheckLineNum++;
+                                    continue;
+                                }
+
+                                // no user but archiving for 5 years "BulletinsNoIndex/HORODATE/SIRET-MATRICULE/PERIODE.pdf"
+                                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);
+
+                                    $csvCheckLineNum++;
+                                    continue;
+                                }
+
+                                // get agent from email
+                                $userFindByEmailList = $this->_userManager->getByEmail($agentUser->getEmail());
+
+                                // /!\ remove all users not available (FIX for multiple users with SAML)
+                                if (self::USER_REMOVE_UNKNOWN == 1) {
+                                    $userFindByEmailList = self::_removeUnknownUser($userFindByEmailList);
+                                }
+
+                                if (count($userFindByEmailList) != 1) {
+                                    $errorMsg = $this->_l10n->t('Impossible de trouver l\'unique utilisateur Nextcloud dont l\'email est "' . $agentUser->getEmail() . '" [matricule="' . $agentUser->getMatricule() . '"].');
+                                    $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
+                                }
+                                $userFindByEmail = current($userFindByEmailList);
+                                $userFindByEmailId = $userFindByEmail->getUID();
+
+                                if ($this->getHasError() <= 0) {
+                                    // directory "SIRET-MATRICULE"
+                                    $siretMatriculeDirName = $agentUser->getSiret() . '-' . $agentUser->getMatricule();
+                                    $payslipsMatriculeDirPath = $payslipsDirPath . DIRECTORY_SEPARATOR . $siretMatriculeDirName;
+
+                                    try {
+                                        $userFolder->get($payslipsMatriculeDirPath);
+                                    } catch (Exception $e) {
+                                        $createdFolder = $userFolder->newFolder($payslipsMatriculeDirPath);
+                                        if (!$createdFolder) {
+                                            $errorMsg = $this->_l10n->t('Impossible de créer le dossier "' . $payslipsMatriculeDirPath . '" [matricule="' . $agentUser->getMatricule() . '"].');
+                                            $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
+                                        }
+
+                                        // create user linked to this payslip
+                                        $dematpayslipUserList = $this->_dematpayslipUserMapper->findAllBySiretAndMatricule($agentUser->getSiret(), $agentUser->getMatricule());
+                                        if (empty($dematpayslipUserList)) {
+                                            $dematpayslipUser = new DematpayslipUser();
+                                            $dematpayslipUser->setUserId($userFindByEmailId);
+                                            $dematpayslipUser->setSiret($agentUser->getSiret());
+                                            $dematpayslipUser->setMatricule($agentUser->getMatricule());
+                                            $dematpayslipUser->setEmail($agentUser->getEmail());
+                                            $dematpayslipUser->setLastname($agentUser->getLastname());
+                                            $dematpayslipUser->setFirstname($agentUser->getFirstname());
+                                            $dematpayslipUser->setZipCity($agentUser->getZipCity());
+                                            $this->_dematpayslipUserMapper->insert($dematpayslipUser);
+                                        } else {
+                                            $errorMsg = $this->_l10n->t('L\'utilisateur "' . $userFindByEmailId . '" est déjà associé à un dossier SIRET-MATRICULE [siret="' . $agentUser->getSiret() . '", matricule="' . $agentUser->getMatricule() . '", email="' . $agentUser->getEmail() . '"].');
+                                            $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
+                                        }
+                                    }
+
+                                    if ($this->getHasError() <= 0) {
+                                        // get created user and linked to "SIRET-MATRICULE" directory
+                                        $dematpayslipUserList = $this->_dematpayslipUserMapper->findAllBySiretAndMatricule($agentUser->getSiret(), $agentUser->getMatricule());
+                                        if (count($dematpayslipUserList) === 1) {
+                                            $dematpayslipUser = $dematpayslipUserList[0];
+
+                                            // set agent user id
+                                            $agentUser->setId($dematpayslipUser->getId());
+                                            $agentUser->setUserId($dematpayslipUser->getUserId());
+
+                                            // chek if user disabled payslip
+                                            if ($dematpayslipUser->getDisabled() != 1) {
+                                                // 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);
+                                            } 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);
+                                            }
+                                        } 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() . '"].');
+                                            $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
+                                        }
+                                    }
+                                }
+
+                                if ($this->getHasError() > 0) {
+                                    break;
+                                }
+
+                                $csvCheckLineNum++;
+                            }
+                            fclose($csvCheckFile);
+                        }
+                    }
+                }
+
+                if ($this->getHasError() <= 0) {
+                    $successMsg = 'Opération "' . self::_getPhaseName($this->getPhase()) . '" terminée avec succès.';
+                    $this->_msgList['success'][] = $successMsg;
+                    //$this->_processInit();
+                }
+                $this->setProcessing(0);
+                $this->setPhase(self::PHASE_ID_INDEXATION);
+                $this->_dematpayslipProcessMapper->update($this);
+            } catch (Exception $e) {
+                $errorMsg = 'Exception ' . __METHOD__ . ' : error=' . $e->getMessage();
+                $this->_msgList['error'][] = $errorMsg;
+            }
+        }
+    }
+
+    /**
+     * Indexation
+     *
+     * @param   array   $processMsgList     Process message list
+     * @return  int                         <0 if errors else >0 on success
+     */
+    public function indexation(&$processMsgList) {
+        try {
+            $this->_initDematUser();
+
+            $this->_processCheck();
+            if ($this->getPhase() < self::PHASE_ID_INDEXATION) {
+                $this->_msgList['error'][] = $this->_l10n->t('Opération impossible : phase en cours "' . self::_getPhaseName($this->getPhase()) . '".');
+            }
+
+            if (!$this->hasError()) {
+                $phaseStartDateTime = new DateTime('now', $this->_timeZone);
+                $phaseStartTime = $phaseStartDateTime->getTimestamp();
+
+                // log file
+                $logFileName = $phaseStartDateTime->format('Y-m-d_H-i-s') . '_' . $this->getPhase() . '_log';
+                $logFilePath = $this->_reportDirFullPath . DIRECTORY_SEPARATOR . $logFileName;
+                $this->_logFile = fopen($logFilePath, 'w+');
+                $this->_logCsvCols(array('date', 'heure', 'niveau', 'message', 'siret', 'matricule', 'nom_prenom', 'zip_city', 'date_debut', 'date_fin', 'email'));
+                $this->_logCsvLine('## ' . $this->_l10n->t('Début du processus d\'indexation.') . ' ##', self::LOG_DEBUG);
+
+                $this->setProcessing(1);
+                $this->setPhase(self::PHASE_ID_INDEXATION);
+                $this->setPhaseStartTime($phaseStartTime);
+                $this->setPhaseStepNum(0);
+                $this->setMustTerminate(1);
+                $this->setHasError(0);
+                $this->setErrorCode(0);
+                $this->setErrorMsg('');
+                $this->setUserId($this->_userId);
+                $this->_dematpayslipProcessMapper->update($this);
+
+                $payslipsDirPath = (string) $this->_dematpayslipConfigList['payslip_dir'];
+                $csvCheckFileName = $this->getCsvCheck();
+
+                // check and mount user directory
+                $this->_logCsvLine($this->_l10n->t('Récupération et montage du dossier de l\'utilisateur Nextcloud.'), self::LOG_DEBUG);
+                $userHomeFilesDirPath = '';
+                if (!$this->hasError()) {
+                    $user = $this->_userManager->get($this->_userId);
+                    if (!$user) {
+                        $errorMsg = $this->_l10n->t('Le dossier utilisateur "' . $this->_userId . '" n\'existe pas.');
+                        $this->_logCsvLine($errorMsg, self::LOG_ERROR);
+                        $this->_processErrorMsg(-1, $errorMsg);
+                    }
+
+                    $userHomeFilesDirPath = $user->getHome() . DIRECTORY_SEPARATOR . 'files';
+                }
+                if (empty($userHomeFilesDirPath) || !is_dir($userHomeFilesDirPath)) {
+                    $errorMsg = $this->_l10n->t('Le dossier utilisateur "' . $this->_userId . '" est introuvable.');
+                    $this->_logCsvLine($errorMsg, self::LOG_ERROR);
+                    $this->_processErrorMsg(-1, $errorMsg);
+                }
+                $userFolder = $this->_rootFolder->getUserFolder($this->_userId);
+
+                // check user payslip dir exists
+                $this->_logCsvLine($this->_l10n->t('Vérification de l\'existance du dossier des bulletins.'), self::LOG_DEBUG);
+                if (!$this->hasError()) {
+                    try {
+                        $userFolder->get($payslipsDirPath);
+                    } catch (Exception $e) {
+                        $errorMsg = $this->_l10n->t('Le dossier des bulletins "' . $payslipsDirPath . '" n\'existe pas.');
+                        $this->_logCsvLine($errorMsg, self::LOG_ERROR);
+                        $this->_processErrorMsg(-1, $errorMsg);
+                    }
+                }
+
+                // check "no indexed payslip" directory exists
+                $this->_logCsvLine($this->_l10n->t('Vérification de l\'existance du dossier des bulletins non indexes.'), self::LOG_DEBUG);
+                if (!$this->hasError()) {
+                    try {
+                        $userFolder->get($this->_payslipNoIndexDir);
+                    } catch (Exception $e) {
+                        $errorMsg = $this->_l10n->t('Le dossier des bulletins non indexes "' . $this->_payslipNoIndexDir . '" n\'existe pas.');
+                        $this->_logCsvLine($errorMsg, self::LOG_ERROR);
+                        $this->_processErrorMsg(-1, $errorMsg);
+                    }
+                }
+
+                if (!$this->hasError()) {
+                    $phaseStep = 'indexation';
+                    $this->_logCsvLine($this->_l10n->t('Début de la phase "' . $phaseStep . '".'), self::LOG_DEBUG);
+                    $csvCheckLineNum = 0;
+                    if (empty($this->getPhaseStep())) {
+                        $userFolder = $this->_rootFolder->getUserFolder($this->_userId);
+
+                        // get all share with this user
+                        $this->_logCsvLine($this->_l10n->t('Récupération des partages de "' . $payslipsDirPath . '".'), self::LOG_DEBUG);
+                        $payslipShareNode = $userFolder->get($payslipsDirPath);
+                        $payslipShareList = $this->_shareManager->getSharesInFolder($this->_userId, $payslipShareNode);
+                        $payslipMatriculeShareNodeIdList = array();
+                        if (count($payslipShareList) > 0) {
+                            foreach ($payslipShareList as $payslipShareNodeId => $payslipShareArr) {
+                                $payslipMatriculeShareNodeIdList[] = $payslipShareNodeId;
+                            }
+                        }
+
+                        if (!$this->hasError()) {
+                            $this->_logCsvLine($this->_l10n->t('Lecture du fichier PDF.'), self::LOG_DEBUG);
+                            $pdfOriginFileFullPath = $this->_uploadDirFullPath . DIRECTORY_SEPARATOR . $this->getPdfOrigin();
+
+                            // create PDF payslip to skip (not indexed)
+                            $pdfPayslipSkip = null;
+                            $payslipSkipPDFPath = $this->_payslipNoIndexDir . DIRECTORY_SEPARATOR . $phaseStartDateTime->format('Y-m-d_H-i-s') . '_skip';
+                            $skipArchiveList = array();
+
+                            // get CSV lines to skip
+                            $dematpayslipProcessSkipLineIdList = array();
+                            $dematpayslipProcessSkipList = $this->_dematpayslipProcessSkipMapper->findAllByIdProcess($this->getId());
+                            foreach ($dematpayslipProcessSkipList as $dematpayslipProcessSkip) {
+                                $dematpayslipProcessSkipLineIdList[] = $dematpayslipProcessSkip->getIdLine();
+                            }
+
+                            // payslip archive mapper
+                            $dematpayslipArchiveMapper = new DematpayslipArchiveMapper($this->_dbConnection);
+
+                            // find all payslip files to be indexed
+                            $this->_logCsvLine($this->_l10n->t('Lecture de la liste des bulletins à traiter.'), self::LOG_DEBUG);
+                            $dematpayslipArchiveList = $dematpayslipArchiveMapper->findAllByDematIdProcessAndStatus($this->getId(), DematpayslipArchive::STATUS_INITIALIZED);
+                            if (!empty($dematpayslipArchiveList)) {
+                                foreach ($dematpayslipArchiveList as $dematpayslipArchive) {
+                                    $archiveError = 0;
+
+                                    // only for operation ask
+                                    $operationAsk = $dematpayslipArchive->getOperationAsk();
+                                    $operationAskList = explode('+', $operationAsk);
+                                    if (in_array(DematpayslipArchive::OPERATION_INDEXATION, $operationAskList)) {
+                                        $this->_logCsvLine('-- ' . $this->_l10n->t('Bulletin en cours : ' . $dematpayslipArchive->getFilePath() . ' [Id = ' . $dematpayslipArchive->getId(). ', File id = ' . $dematpayslipArchive->getIdFile() . ']') . ' --', self::LOG_DEBUG);
+
+                                        $operationAskArchive = in_array(DematpayslipArchive::OPERATION_ARCHIVE, $operationAskList);
+
+                                        // get payslip file values
+                                        $startDate = $dematpayslipArchive->getStartDate();
+                                        $endDate =  $dematpayslipArchive->getEndDate();
+                                        $editionDate = $dematpayslipArchive->getEditionDate();
+                                        $year = $dematpayslipArchive->getYear();;
+                                        $month = $dematpayslipArchive->getMonth();;
+                                        $pdfPageNumList = explode('-', $dematpayslipArchive->getFilePagesNum());
+                                        $period = $startDate . '_' . $endDate;
+
+                                        // agent user
+                                        $agentUser = null;
+                                        if ($dematpayslipArchive->getDematpayslipIdUser() > 0) {
+                                            $agentUser = $this->_dematpayslipUserMapper->find($dematpayslipArchive->getDematpayslipIdUser());
+                                        }
+                                        if (!$agentUser) {
+                                            $agentUser = new DematpayslipUser();
+                                            $agentUser->setId(0);
+                                            $agentUser->setUserId('');
+                                            $agentUser->setSiret($dematpayslipArchive->getSiret());
+                                            $agentUser->setMatricule($dematpayslipArchive->getMatricule());
+                                            $agentUser->setLastname($dematpayslipArchive->getLastname());
+                                            $agentUser->setFirstname($dematpayslipArchive->getFirstname());
+                                            $agentUser->setEmail($dematpayslipArchive->getEmail());
+                                            $agentUser->setZipCity($dematpayslipArchive->getZipCity());
+                                        }
+
+                                        // pdf payslip file path
+                                        $pdfPayslipCheckFilePath = substr($dematpayslipArchive->getFilePath(), strlen($userFolder->getPath() . DIRECTORY_SEPARATOR)); // remove "/user/files/" in archive file path
+                                        $pdfPayslipCheckFileName = basename($pdfPayslipCheckFilePath);
+                                        $pdfCheckFileNames = explode('_', $pdfPayslipCheckFileName);
+                                        $csvCheckLineNum = intval($pdfCheckFileNames[0]) - 1;
+
+                                        $this->_logCsvLine($this->_l10n->t('Bulletin de l\'agent '), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
+
+                                        // process skip lines
+                                        if (in_array($csvCheckLineNum, $dematpayslipProcessSkipLineIdList)) {
+                                            $this->_logCsvLine('-- ' . $this->_l10n->t('Bulletin à ne pas indexer : ' . ($csvCheckLineNum + 1)) . ' --', self::LOG_DEBUG, $agentUser, $startDate, $endDate);
+
+                                            // create PDF for payslip not to be indexed
+                                            if ($pdfPayslipSkip === null) {
+                                                $pdfPayslipSkip = new \setasign\Fpdi\Fpdi();
+                                            }
+                                            // add pages in user payslip not to be indexed
+                                            $this->_logCsvLine($this->_l10n->t('Ajout des pages PDF au bulletin de paie à ne pas indexer.'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
+                                            foreach ($pdfPageNumList as $pdfPageNum) {
+                                                $this->_logCsvLine($this->_l10n->t('Ajout de la page ' . $pdfPageNum . '.'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
+                                                $pdfPayslipSkip->AddPage();
+                                                $pdfPayslipSkip->setSourceFile($pdfOriginFileFullPath);
+                                                $tplPayslipSkipId = $pdfPayslipSkip->importPage($pdfPageNum);
+                                                $pdfPayslipSkip->useTemplate($tplPayslipSkipId);
+                                            }
+
+                                            // not archiving (skip)
+                                            $skipArchiveList[] = $dematpayslipArchive;
+
+                                            continue;
+                                        }
+
+                                        // no user but archiving for 5 years "BulletinsNoIndex/HORODATE/SIRET-MATRICULE/PERIODE.pdf"
+                                        if (empty($agentUser->getEmail())) {
+                                            $this->_logCsvLine('-- ' . $this->_l10n->t('Création du PDF non dématérialisé de l\'agent (aucun email) : ' . ($csvCheckLineNum + 1)) . ' --', self::LOG_DEBUG, $agentUser, $startDate, $endDate);
+
+                                            // check if not already archived (return null if already archived with warning)
+                                            $dematpayslipArchiveCheck = null;
+                                            if ($operationAskArchive) {
+                                                $dematpayslipArchiveCheck = $this->_archiveCheckBeforeSave($dematpayslipArchiveMapper, $agentUser, $startDate, $endDate);
+                                            }
+
+                                            if (!$operationAskArchive || !empty($dematpayslipArchiveCheck)) {
+                                                // add all agent pdf pages
+                                                $pdfPayslipNoDemat = new \setasign\Fpdi\Fpdi();
+                                                $this->_logCsvLine($this->_l10n->t('Ajout des pages PDF au bulletin de paie à ne pas indexer.'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
+                                                foreach ($pdfPageNumList as $pdfPageNum) {
+                                                    $this->_logCsvLine($this->_l10n->t('Ajout de la page ' . $pdfPageNum . '.'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
+                                                    $pdfPayslipNoDemat->AddPage();
+                                                    $pdfPayslipNoDemat->setSourceFile($pdfOriginFileFullPath);
+                                                    $pdfPayslipNoDematId = $pdfPayslipNoDemat->importPage($pdfPageNum);
+                                                    $pdfPayslipNoDemat->useTemplate($pdfPayslipNoDematId);
+                                                }
+
+                                                // create PDF payslip
+                                                $payslipNoDematHorodateDirPath = $this->_payslipNoIndexDir . DIRECTORY_SEPARATOR . $phaseStartDateTime->format('Y-m-d_H-i-s');
+                                                try {
+                                                    $userFolder->get($payslipNoDematHorodateDirPath);
+                                                } catch (Exception $e) {
+                                                    $createdFolder = $userFolder->newFolder($payslipNoDematHorodateDirPath);
+                                                    if (!$createdFolder) {
+                                                        $archiveError++;
+                                                        $errorMsg = $this->_l10n->t('Impossible de créeer le dossier "' . $payslipNoDematHorodateDirPath . '".');
+                                                        $this->_logCsvLine($errorMsg, self::LOG_ERROR, $agentUser, $startDate, $endDate);
+                                                        $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
+                                                    }
+                                                }
+                                                $payslipNoDematHorodateAgentDirPath = $payslipNoDematHorodateDirPath . DIRECTORY_SEPARATOR . $agentUser->getSiret() . '-' . $agentUser->getMatricule();
+                                                try {
+                                                    $userFolder->get($payslipNoDematHorodateAgentDirPath);
+                                                } catch (Exception $e) {
+                                                    $createdFolder = $userFolder->newFolder($payslipNoDematHorodateAgentDirPath);
+                                                    if (!$createdFolder) {
+                                                        $archiveError++;
+                                                        $errorMsg = $this->_l10n->t('Impossible de créeer le dossier "' . $payslipNoDematHorodateAgentDirPath . '".');
+                                                        $this->_logCsvLine($errorMsg, self::LOG_ERROR, $agentUser, $startDate, $endDate);
+                                                        $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
+                                                    }
+                                                }
+                                                $payslipNoDematPDFPath = $payslipNoDematHorodateAgentDirPath . DIRECTORY_SEPARATOR . $startDate . '_' . $endDate;
+
+                                                // create PDF payslip in no index folder
+                                                $this->_logCsvLine($this->_l10n->t('Créer le PDF du bulletin de paie non dematérialisé.'), self::LOG_DEBUG);
+                                                $pdfPayslipNoDemat->Output('F', $userHomeFilesDirPath . DIRECTORY_SEPARATOR . $payslipNoDematPDFPath);
+                                                $pdfPayslipFilePath = $payslipNoDematPDFPath . '.pdf';
+                                                try {
+                                                    $payslipNoDematPDFNode = $userFolder->get($payslipNoDematPDFPath);
+                                                    $payslipNoDematPDFNode->move($userFolder->getPath() . DIRECTORY_SEPARATOR . $pdfPayslipFilePath);
+                                                    $dematpayslipArchive->setFilePath($payslipNoDematPDFNode->getPath());
+                                                    $dematpayslipArchiveMapper->update($dematpayslipArchive);
+                                                } catch (Exception $e) {
+                                                    $archiveError++;
+                                                    $errorMsg = $this->_l10n->t('Impossible de déplacer le PDF du bulletin de paie non dematérialisé "' . $userFolder->getPath() . DIRECTORY_SEPARATOR . $pdfPayslipFilePath . '".');
+                                                    $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) {
+                                                // file finished with errors
+                                                $processMsgList['error'][] = $dematpayslipArchive;
+                                                $dematpayslipArchive->setError(1);
+                                                $dematpayslipArchiveMapper->update($dematpayslipArchive);
+                                            } else {
+                                                $processMsgList['success'][] = $dematpayslipArchive;
+                                                $dematpayslipArchive->setStatus(DematpayslipArchive::STATUS_INDEXED);
+                                                // next operation for this file if asked
+                                                if ($operationAskArchive) {
+                                                    $dematpayslipArchive->setOperationProgress(DematpayslipArchive::OPERATION_ARCHIVE);
+                                                } else {
+                                                    $dematpayslipArchive->setOperationProgress(DematpayslipArchive::OPERATION_FINISHED);
+                                                }
+                                                $dematpayslipArchive->setError(0);
+                                                $dematpayslipArchiveMapper->update($dematpayslipArchive);
+                                            }
+
+                                            continue;
+                                        }
+
+                                        // get agent from email
+                                        $this->_logCsvLine($this->_l10n->t('Récupération de l\'utilisateur Nextcloud à partir de son email [' . $agentUser->getEmail() . '].'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
+                                        $userFindByEmailList = $this->_userManager->getByEmail($agentUser->getEmail());
+
+                                        // /!\ remove all users not available (FIX for multiple users with SAML)
+                                        if (self::USER_REMOVE_UNKNOWN == 1) {
+                                            $userFindByEmailList = self::_removeUnknownUser($userFindByEmailList);
+                                        }
+
+                                        if (count($userFindByEmailList) != 1) {
+                                            $archiveError++;
+                                            $errorMsg = $this->_l10n->t('Impossible de trouver l\'unique utilisateur Nextcloud dont l\'email est "' . $agentUser->getEmail() . '" [matricule="' . $agentUser->getMatricule() . '"].');
+                                            $this->_logCsvLine($errorMsg, self::LOG_ERROR, $agentUser, $startDate, $endDate);
+                                            $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
+                                        }
+                                        $userFindByEmail = current($userFindByEmailList);
+                                        $userFindByEmailId = $userFindByEmail->getUID();
+
+                                        if (!$this->hasError()) {
+                                            // "SIRET-MATRICULE" directory
+                                            $siretMatriculeDirName = $agentUser->getSiret() . '-' . $agentUser->getMatricule();
+                                            $payslipsMatriculeDirPath = $payslipsDirPath . DIRECTORY_SEPARATOR . $siretMatriculeDirName;
+
+                                            // get agent user from "SIRET-MATRICULE" created directory
+                                            $this->_logCsvLine($this->_l10n->t('Récupération de l\'utilisateur associé au dossier SIRET-MATRICULE [' . $siretMatriculeDirName . '].'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
+                                            $dematpayslipUserList = $this->_dematpayslipUserMapper->findAllBySiretAndMatricule($agentUser->getSiret(), $agentUser->getMatricule());
+                                            if (count($dematpayslipUserList) === 1) {
+                                                $dematpayslipUser = current($dematpayslipUserList);
+
+                                                // update user for new version
+                                                if (empty($dematpayslipUser->getLastname()) || empty($dematpayslipUser->getFirstname()) || empty($dematpayslipUser->getZipCity())) {
+                                                    $dematpayslipUser->setLastname($agentUser->getLastname());
+                                                    $dematpayslipUser->setFirstname($agentUser->getFirstname());
+                                                    $dematpayslipUser->setZipCity($agentUser->getZipCity());
+                                                    $this->_dematpayslipUserMapper->update($dematpayslipUser);
+                                                }
+
+                                                // set agent user id
+                                                $agentUser->setId($dematpayslipUser->getId());
+                                                $agentUser->setUserId($dematpayslipUser->getUserId());
+
+                                                // chek if user disabled payslip
+                                                if ($dematpayslipUser->getDisabled() != 1) {
+                                                    $payslipsMatriculeYearDirPath = $payslipsMatriculeDirPath . DIRECTORY_SEPARATOR . $year;
+
+                                                    // create share directory "SIRET-MATRICULE"
+                                                    $payslipsMatriculeDirPathNode = $userFolder->get($payslipsMatriculeDirPath);
+
+                                                    // 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)
+                                                        $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);
+                                                        $payslipMatriculeShare->setShareType(\OC\Share\Share::SHARE_TYPE_USER);
+                                                        $payslipMatriculeShare->setSharedWith($userFindByEmailId);
+                                                        $payslipMatriculeShare->setPermissions(\OCP\Constants::PERMISSION_READ);
+                                                        $payslipMatriculeShare->setSharedBy($this->_userId);
+                                                        $payslipMatriculeShare = $this->_shareManager->createShare($payslipMatriculeShare);
+                                                    } else {
+                                                        $this->_logCsvLine($this->_l10n->t('Dossier SIRET-MATRICULE [' . $siretMatriculeDirName . '] est déjà partagé.'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
+                                                    }
+
+                                                    // directory "SIRET-MATRICULE/ANNEE"
+                                                    $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);
+                                                    } catch (Exception $e) {
+                                                        $this->_logCsvLine($this->_l10n->t('Création du dossier de l\'annéee [' . $year . '].'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
+                                                        $createdFolder = $userFolder->newFolder($payslipsMatriculeYearDirPath);
+                                                        if (!$createdFolder) {
+                                                            $archiveError++;
+                                                            $errorMsg = $this->_l10n->t('Impossible de créer le dossier "' . $payslipsMatriculeYearDirPath . '[siret="' . $agentUser->getSiret() . '", matricule="' . $agentUser->getMatricule() . '", année="' . $year . '"].');
+                                                            $this->_logCsvLine($errorMsg, self::LOG_ERROR, $agentUser, $startDate, $endDate);
+                                                            $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
+                                                        }
+                                                    }
+
+                                                    if (!$this->hasError()) {
+                                                        // check if not already archived (return null if already archived with warning)
+                                                        $dematpayslipArchiveCheck = null;
+                                                        if ($operationAskArchive) {
+                                                            $dematpayslipArchiveCheck = $this->_archiveCheckBeforeSave($dematpayslipArchiveMapper, $agentUser, $startDate, $endDate);
+                                                        }
+
+                                                        if (!$operationAskArchive || !empty($dematpayslipArchiveCheck)) {
+                                                            // move user agent payslip file in "SIRET-MATRICULE/ANNEE/PERIODE.pdf"
+                                                            $pdfPayslipFilePath = $payslipsMatriculeYearDirPath . DIRECTORY_SEPARATOR . $period . '.pdf';
+                                                            $this->_logCsvLine($this->_l10n->t('Déplacement du fichier PDF du bulletin de paie de la période [' . $period . '].'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
+                                                            try {
+                                                                $pdfPayslipCheckFileNode = $userFolder->get($pdfPayslipCheckFilePath);
+                                                                $pdfPayslipCheckFileNode->move($userFolder->getPath() . DIRECTORY_SEPARATOR . $pdfPayslipFilePath);
+                                                                $dematpayslipArchive->setFilePath($pdfPayslipCheckFileNode->getPath());
+                                                                $dematpayslipArchiveMapper->update($dematpayslipArchive);
+                                                            } catch (Exception $e) {
+                                                                $archiveError++;
+                                                                $errorMsg = $this->_l10n->t('Impossible de déplacer le bulletin de paie "' . $pdfPayslipCheckFilePath . '" dans "' . $userFolder->getPath() . DIRECTORY_SEPARATOR . $pdfPayslipFilePath . '".');
+                                                                $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 {
+                                                    // agent disabled payslip
+                                                    $this->_logCsvLine($this->_l10n->t('L\'utlisateur a désactivé la dématérialisation des fiches de paie [email=' . $agentUser->getEmail() . '].'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
+
+                                                    // check if not already archived (return null if already archived with warning)
+                                                    $dematpayslipArchiveCheck = null;
+                                                    if ($operationAskArchive) {
+                                                        $dematpayslipArchiveCheck = $this->_archiveCheckBeforeSave($dematpayslipArchiveMapper, $agentUser, $startDate, $endDate);
+                                                    }
+
+                                                    if (!$operationAskArchive || !empty($dematpayslipArchiveCheck)) {
+                                                        // create PDF payslip
+                                                        $payslipNoDematHorodateDirPath = $this->_payslipNoIndexDir . DIRECTORY_SEPARATOR . $phaseStartDateTime->format('Y-m-d_H-i-s');
+                                                        try {
+                                                            $userFolder->get($payslipNoDematHorodateDirPath);
+                                                        } catch (Exception $e) {
+                                                            $createdFolder = $userFolder->newFolder($payslipNoDematHorodateDirPath);
+                                                            if (!$createdFolder) {
+                                                                $archiveError++;
+                                                                $errorMsg = $this->_l10n->t('Impossible de créeer le dossier "' . $payslipNoDematHorodateDirPath . '".');
+                                                                $this->_logCsvLine($errorMsg, self::LOG_ERROR, $agentUser, $startDate, $endDate);
+                                                                $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
+                                                            }
+                                                        }
+
+                                                        $payslipNoDematHorodateAgentDirPath = $payslipNoDematHorodateDirPath . DIRECTORY_SEPARATOR . $agentUser->getSiret() . '-' . $agentUser->getMatricule();
+                                                        try {
+                                                            $userFolder->get($payslipNoDematHorodateAgentDirPath);
+                                                        } catch (Exception $e) {
+                                                            $createdFolder = $userFolder->newFolder($payslipNoDematHorodateAgentDirPath);
+                                                            if (!$createdFolder) {
+                                                                $archiveError++;
+                                                                $errorMsg = $this->_l10n->t('Impossible de créeer le dossier "' . $payslipNoDematHorodateAgentDirPath . '".');
+                                                                $this->_logCsvLine($errorMsg, self::LOG_ERROR, $agentUser, $startDate, $endDate);
+                                                                $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
+                                                            }
+                                                        }
+                                                        $payslipNoDematPDFPath = $payslipNoDematHorodateAgentDirPath . DIRECTORY_SEPARATOR . $startDate . '_' . $endDate;
+                                                        $pdfPayslipNoDemat = new \setasign\Fpdi\Fpdi();
+
+                                                        // add all agent pdf pages
+                                                        $this->_logCsvLine($this->_l10n->t('Ajout des pages PDF au bulletin de paie à ne pas indexer.'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
+                                                        foreach ($pdfPageNumList as $pdfPageNum) {
+                                                            $this->_logCsvLine($this->_l10n->t('Ajout de la page ' . $pdfPageNum . '.'), self::LOG_DEBUG, $agentUser, $startDate, $endDate);
+                                                            $pdfPayslipNoDemat->AddPage();
+                                                            $pdfPayslipNoDemat->setSourceFile($pdfOriginFileFullPath);
+                                                            $pdfPayslipNoDematId = $pdfPayslipNoDemat->importPage($pdfPageNum);
+                                                            $pdfPayslipNoDemat->useTemplate($pdfPayslipNoDematId);
+                                                        }
+
+                                                        // create PDF payslip in no index folder
+                                                        $this->_logCsvLine($this->_l10n->t('Créer le PDF du bulletin de paie non dematérialisé.'), self::LOG_DEBUG);
+                                                        $pdfPayslipNoDemat->Output('F', $userHomeFilesDirPath . DIRECTORY_SEPARATOR . $payslipNoDematPDFPath);
+                                                        $pdfPayslipFilePath = $payslipNoDematPDFPath . '.pdf';
+                                                        try {
+                                                            $payslipNoDematPDFNode = $userFolder->get($payslipNoDematPDFPath);
+                                                            $payslipNoDematPDFNode->move($userFolder->getPath() . DIRECTORY_SEPARATOR . $pdfPayslipFilePath);
+                                                            $dematpayslipArchive->setFilePath($payslipNoDematPDFNode->getPath());
+                                                            $dematpayslipArchiveMapper->update($dematpayslipArchive);
+                                                        } catch (Exception $e) {
+                                                            $archiveError++;
+                                                            $errorMsg = $this->_l10n->t('Impossible de déplacer le PDF du bulletin de paie non dematérialisé "' . $userFolder->getPath() . DIRECTORY_SEPARATOR . $pdfPayslipFilePath . '".');
+                                                            $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 {
+                                                $archiveError++;
+                                                $errorMsg = $this->_l10n->t('L\'utilisateur "' . $userFindByEmailId . '" n\'a pas de dossier SIRET-MATRICULE associé [siret="' . $agentUser->getSiret() . '", matricule="' . $agentUser->getMatricule() . '", email="' . $agentUser->getEmail() . '"].');
+                                                $this->_logCsvLine($errorMsg, self::LOG_ERROR, $agentUser, $startDate, $endDate);
+                                                $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
+                                            }
+                                        }
+
+                                        if ($archiveError > 0) {
+                                            // file finished with errors
+                                            $processMsgList['error'][] = $dematpayslipArchive;
+                                            $dematpayslipArchive->setError(1);
+                                            $dematpayslipArchiveMapper->update($dematpayslipArchive);
+                                        } else {
+                                            $processMsgList['success'][] = $dematpayslipArchive;
+                                            $dematpayslipArchive->setStatus(DematpayslipArchive::STATUS_INDEXED);
+                                            // next operation for this file if asked
+                                            if ($operationAskArchive) {
+                                                $dematpayslipArchive->setOperationProgress(DematpayslipArchive::OPERATION_ARCHIVE);
+                                            } else {
+                                                $dematpayslipArchive->setOperationProgress(DematpayslipArchive::OPERATION_FINISHED);
+                                            }
+                                            $dematpayslipArchive->setError(0);
+                                            $dematpayslipArchiveMapper->update($dematpayslipArchive);
+                                        }
+                                        if ($this->hasError()) {
+                                            $this->_logCsvLine('-- ' . $this->_l10n->t('Fin du bulletin : ' . ($csvCheckLineNum + 1)) . ' --', self::LOG_ERROR);
+                                            break;
+                                        } else {
+                                            $this->_logCsvLine('-- ' . $this->_l10n->t('Fin du bulletin : ' . ($csvCheckLineNum + 1)) . ' --', self::LOG_SUCCESS);
+                                        }
+                                    }
+                                }
+                            }
+
+                            // create PDF for payslip not to be indexed (skip)
+                            if ($pdfPayslipSkip !== null) {
+                                $this->_logCsvLine($this->_l10n->t('Créer le PDF des bulletins de paie à ne pas indexer.'), self::LOG_DEBUG);
+                                $pdfPayslipSkip->Output('F', $userHomeFilesDirPath . DIRECTORY_SEPARATOR . $payslipSkipPDFPath);
+                                $pdfPayslipSkipPath = $payslipSkipPDFPath . '.pdf';
+                                try {
+                                    $payslipSkipPDFPathNode = $userFolder->get($payslipSkipPDFPath);
+                                    $payslipSkipPDFPathNode->move($userFolder->getPath() . DIRECTORY_SEPARATOR . $pdfPayslipSkipPath);
+
+                                    // update skip archive list
+                                    if (!empty($skipArchiveList)) {
+                                        foreach ($skipArchiveList as $skipArchive) {
+                                            $processMsgList['success'][] = $skipArchive;
+                                            $skipArchive->setFilePath($payslipSkipPDFPathNode->getPath());
+                                            $skipArchive->setStatus(DematpayslipArchive::STATUS_INDEXED);
+                                            $skipArchive->setOperationProgress(DematpayslipArchive::OPERATION_FINISHED); // no next operation
+                                            $skipArchive->setError(0);
+                                            $dematpayslipArchiveMapper->update($skipArchive);
+                                        }
+                                    }
+                                } catch (Exception $e) {
+                                    $errorMsg = $this->_l10n->t('Impossible de déplacer le PDF des bulletins de paie à ne pas indexer "' . $userFolder->getPath() . DIRECTORY_SEPARATOR . $pdfPayslipSkipPath . '".');
+                                    $this->_logCsvLine($errorMsg, self::LOG_ERROR);
+                                    $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $csvCheckLineNum);
+                                }
+                            }
+                        }
+                    }
+
+                    if (!$this->hasError()) {
+                        $phaseStep = 'report';
+                        $phaseStepNum = 0;
+                        $retryPhaseStepNum = $phaseStepNum;
+                        if (empty($this->getPhaseStep())) {
+                            $reportSubDirName = $phaseStartDateTime->format('Y-m-d_H-i-s');
+                            $reportSubDirPath = $this->_reportDirUserPath . DIRECTORY_SEPARATOR . $reportSubDirName;
+
+                            // create report sub-directory
+                            if ($phaseStepNum >= $retryPhaseStepNum) {
+                                $this->_logCsvLine($this->_l10n->t('Création du dossier de rapport.'), self::LOG_DEBUG);
+                                try {
+                                    $userFolder->get($reportSubDirPath);
+                                } catch (Exception $e) {
+                                    $createdFolder = $userFolder->newFolder($reportSubDirPath);
+                                    if (!$createdFolder) {
+                                        $errorMsg = $this->_l10n->t('Impossible de créer le dossier du rapport "' . $reportSubDirName . '".');
+                                        $this->_logCsvLine($errorMsg, self::LOG_ERROR);
+                                        $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $phaseStepNum);
+                                    }
+                                }
+                            }
+
+                            if (!$this->hasError()) {
+                                // move uploaded CSV file in report directory
+                                $phaseStepNum++;
+                                if ($phaseStepNum >= $retryPhaseStepNum) {
+                                    $csvUploadFileName = $this->getCsvOrigin();
+                                    if (!empty($csvUploadFileName)) {
+                                        $this->_logCsvLine($this->_l10n->t('Déplacement du fichier CSV d\'upload dans le dossier du rapport.'), self::LOG_DEBUG);
+                                        $csvUploadFileUserPath = $this->_uploadDirUserPath . DIRECTORY_SEPARATOR . $csvUploadFileName;
+                                        $reportFileUserPath = $reportSubDirPath . DIRECTORY_SEPARATOR . $csvUploadFileName;
+                                        try {
+                                            $csvUploadFileUserNode = $userFolder->get($csvUploadFileUserPath);
+                                            $csvUploadFileUserNode->move($userFolder->getPath() . DIRECTORY_SEPARATOR . $reportFileUserPath);
+                                        } catch (Exception $e) {
+                                            $errorMsg = $this->_l10n->t('Impossible de déplacer le fichier CSV d\'upload "' . $csvUploadFileName . '" dans le dossier du rapport "' . $reportSubDirName . '".');
+                                            $this->_logCsvLine($errorMsg, self::LOG_ERROR);
+                                            $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $phaseStepNum);
+                                        }
+                                    }
+                                }
+
+                                // move uploaded PDF file in report directory
+                                $phaseStepNum++;
+                                if ($phaseStepNum >= $retryPhaseStepNum) {
+                                    $pdfUploadFileName = $this->getPdfOrigin();
+                                    if (!empty($pdfUploadFileName)) {
+                                        $this->_logCsvLine($this->_l10n->t('Déplacement du fichier PDF d\'upload dans le dossier du rapport.'), self::LOG_DEBUG);
+                                        $pdfUploadFileUserPath = $this->_uploadDirUserPath . DIRECTORY_SEPARATOR . $pdfUploadFileName;
+                                        $reportFileUserPath = $reportSubDirPath . DIRECTORY_SEPARATOR . $pdfUploadFileName;
+                                        try {
+                                            $pdfUploadFileUserNode = $userFolder->get($pdfUploadFileUserPath);
+                                            $pdfUploadFileUserNode->move($userFolder->getPath() . DIRECTORY_SEPARATOR . $reportFileUserPath);
+                                        } catch (Exception $e) {
+                                            $errorMsg = $this->_l10n->t('Impossible de déplacer le fichier PDF d\'upload "' . $pdfUploadFileName . '" dans le dossier du rapport "' . $reportSubDirName . '".');
+                                            $this->_logCsvLine($errorMsg, self::LOG_ERROR);
+                                            $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $phaseStepNum);
+                                        }
+                                    }
+                                }
+
+                                // move CSV created in check step in report directory
+                                $phaseStepNum++;
+                                if ($phaseStepNum >= $retryPhaseStepNum) {
+                                    if (!empty($csvCheckFileName)) {
+                                        $this->_logCsvLine($this->_l10n->t('Déplacement du fichier CSV créé après vérification dans le dossier du rapport.'), self::LOG_DEBUG);
+                                        $csvCheckFileUserPath = $this->_checkDirUserPath . DIRECTORY_SEPARATOR . $csvCheckFileName;
+                                        $reportFileUserPath = $reportSubDirPath . DIRECTORY_SEPARATOR . $csvCheckFileName;
+                                        try {
+                                            $csvCheckFileUserNode = $userFolder->get($csvCheckFileUserPath);
+                                            $csvCheckFileUserNode->move($userFolder->getPath() . DIRECTORY_SEPARATOR . $reportFileUserPath);
+                                        } catch (Exception $e) {
+                                            $errorMsg = $this->_l10n->t('Impossible de déplacer le fichier CSV de vérification "' . $csvCheckFileName . '" dans le dossier du rapport "' . $reportSubDirName . '".');
+                                            $this->_logCsvLine($errorMsg, self::LOG_ERROR);
+                                            $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $phaseStepNum);
+                                        }
+                                    }
+                                }
+
+                                // move created log file (during check process) in report directory
+                                $phaseStepNum++;
+                                if ($phaseStepNum >= $retryPhaseStepNum) {
+                                    // get csv log file (during check process)
+                                    $logCheckFileName = self::PHASE_ID_CHECK . '_log.csv';
+                                    if (!empty($logCheckFileName)) {
+                                        $this->_logCsvLine($this->_l10n->t('Déplacement du fichier de Log créé après vérification dans le dossier du rapport.'), self::LOG_DEBUG);
+                                        $logCheckFileUserPath = $this->_checkDirUserPath . DIRECTORY_SEPARATOR . $logCheckFileName;
+                                        $reportFileUserPath = $reportSubDirPath . DIRECTORY_SEPARATOR . $logCheckFileName;
+                                        try {
+                                            $logCheckFileUserNode = $userFolder->get($logCheckFileUserPath);
+                                            $logCheckFileUserNode->move($userFolder->getPath() . DIRECTORY_SEPARATOR . $reportFileUserPath);
+                                        } catch (Exception $e) {
+                                            $errorMsg = $this->_l10n->t('Impossible de déplacer le fichier de Log de vérification "' . $logCheckFileName . '" dans le dossier du rapport "' . $reportSubDirName . '".');
+                                            $this->_logCsvLine($errorMsg, self::LOG_ERROR);
+                                            $this->_processErrorMsg(-1, $errorMsg, $phaseStep, $phaseStepNum);
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+
+                if (!$this->hasError()) {
+                    $successMsg = 'Opération "' . self::_getPhaseName($this->getPhase()) . '" terminée avec succès.';
+                    $this->_logCsvLine($this->_l10n->t($successMsg), self::LOG_SUCCESS);
+                    $this->_msgList['success'][] = $successMsg;
+                    $this->_processInit();
+                }
+
+                $this->_logCsvLine('## ' . $this->_l10n->t('Fin du processus d\'indexation.') . ' ##', self::LOG_DEBUG);
+                fclose($this->_logFile);
+                // rename (log file)
+                try {
+                    $logFileNode = $userFolder->get($logFilePath);
+                    $logFileNode->move($userFolder->getPath() . DIRECTORY_SEPARATOR . $logFilePath . '.csv');
+                } catch (Exception $e) {
+                    $this->_msgList['error'][] = $this->_l10n->t('Impossible de déplacer le fichier de log "' . $logFilePath . '" .');
+                }
+                $this->setProcessing(0);
+                $this->_dematpayslipProcessMapper->update($this);
+                // empty process skip lines
+                $this->_dematpayslipProcessSkipMapper->deleteAllByIdProcess($this->getId());
+
+                return 1;
+            } else {
+                return -1;
+            }
+        } catch (Exception $e) {
+            $this->_msgList['error'][] = $e->getMessage();
+            return -1;
+        }
+    }
+
+    /**
+     * Agent list
+     *
+     * @throws  Exception
+     */
+    public function agentList() {
+        $this->_initDematFolders();
+    }
+
+    /**
+     * Agent CSV
+     *
+     * @throws  Exception
+     */
+    public function agentCsv() {
+        $this->_initDematFolders();
+
+        if (count($this->_msgList['error']) <= 0) {
+            $dematpayslipUserList = $this->_dematpayslipUserMapper->findAll(array(array('disabled', 'desc'), array('siret'), array('matricule')));
+
+            if (!empty($dematpayslipUserList)) {
+                $dateTimeNow = new DateTime('now', $this->_timeZone);
+                $csvFilePath = $this->_exportDirUserPath . DIRECTORY_SEPARATOR . $dateTimeNow->format('Y-m-d_H-i-s') . '_agent';
+                $csvFile = Filesystem::fopen($csvFilePath, 'w+');
+
+                if (!$csvFile) {
+                    $errorMsg = $this->_l10n->t('Ouverture du fichier CSV.');
+                    $this->_msgList['error'][] = $errorMsg;
+                }
+
+                if (count($this->_msgList['error']) <= 0) {
+                    $csvDelimiter = $this->_csvDelimiter;
+                    $csvEnclosure = $this->_csvEnclosure;
+
+                    $csvFields = array();
+                    $csvFields[] = $this->_l10n->t('Utilisateur');
+                    $csvFields[] = $this->_l10n->t('Siret');
+                    $csvFields[] = $this->_l10n->t('Matricule');
+                    $csvFields[] = $this->_l10n->t('Email');
+                    $csvFields[] = $this->_l10n->t('Papier ?');
+
+                    $res = fputcsv($csvFile, $csvFields, $csvDelimiter, $csvEnclosure);
+                    if (!$res) {
+                        $errorMsg = $this->_l10n->t('Ecriture des colonnes dans le fichier CSV.');
+                        $this->_msgList['error'][] = $errorMsg;
+                    }
+
+                    if (count($this->_msgList['error']) <= 0) {
+                        foreach ($dematpayslipUserList as $dematpayslipUser) {
+                            $agent = $this->_userManager->get($dematpayslipUser->getUserId());
+
+                            $csvFields = array();
+                            //$csvFields[] = $dematpayslipUser->getUserId();
+                            $csvFields[] = $agent->getDisplayName();
+                            $csvFields[] = $dematpayslipUser->getSiret();
+                            $csvFields[] = $dematpayslipUser->getMatricule();
+                            $csvFields[] = $dematpayslipUser->getEmail();
+                            $csvFields[] = $dematpayslipUser->getDisabled();
+
+                            $res = fputcsv($csvFile, $csvFields, $csvDelimiter, $csvEnclosure);
+                            if (!$res) {
+                                $errorMsg = $this->_l10n->t('Ecriture de la ligne dans le fichier CSV.');
+                                $this->_msgList['error'][] = $errorMsg;
+                                break;
+                            }
+                        }
+                    }
+
+                    $res = fclose($csvFile);
+                    if (!$res) {
+                        $errorMsg = $this->_l10n->t('Fermeture du fichier CSV.');
+                        $this->_msgList['error'][] = $errorMsg;
+                    }
+
+                    if (count($this->_msgList['error']) <= 0) {
+                        // rename (sync files)
+                        $renamed = Filesystem::rename($csvFilePath, $csvFilePath . '.csv');
+                        $this->_msgList['success'][] = $this->_l10n->t('La liste des agents a bien été exporté au format CSV.');
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Archive list
+     *
+     * @throws Exception
+     */
+    public function archiveList() {
+        $this->_initDematFolders();
+    }
+
+    /**
+     * Archive action
+     *
+     * @param $action
+     * @param $archiveSelectIdList
+     * @return bool
+     *
+     * @throws Exception
+     */
+    public function archiveAction($action, $archiveSelectIdList) {
+        $refresh = false;
+
+        $this->_initDematFolders();
+
+        if ($action == 'refresh_status') {
+            // refresh all archive status
+            $refresh = true;
+        } elseif ($action == 'create') {
+            $dematpayslipArchiveMapper = new DematpayslipArchiveMapper($this->_dbConnection);
+
+            if (!empty($archiveSelectIdList)) {
+                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);
+                    }
+                }
+            }
+        } elseif ($action == 'create_all') {
+            $dematpayslipArchiveMapper = new DematpayslipArchiveMapper($this->_dbConnection);
+            $dematpayslipArchiveList = $dematpayslipArchiveMapper->findAllByOperationProgress(DematpayslipArchive::OPERATION_ARCHIVE);
+
+            if (!empty($dematpayslipArchiveList)) {
+                foreach ($dematpayslipArchiveList as $dematpayslipArchive) {
+                    // only for operation ask
+                    $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);
+                    }
+                }
+            }
+        } elseif ($action == 'run_again') {
+            $dematpayslipArchiveMapper = new DematpayslipArchiveMapper($this->_dbConnection);
+
+            if (!empty($archiveSelectIdList)) {
+                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);
+                    }
+                }
+            }
+        } elseif ($action == 'delete') {
+            $nowDateTime = new DateTime('now', $this->_timeZone);
+            $dematpayslipArchiveMapper = new DematpayslipArchiveMapper($this->_dbConnection);
+
+            if (!empty($archiveSelectIdList)) {
+                foreach ($archiveSelectIdList as $archiveSelectId) {
+                    $dematpayslipArchive = $dematpayslipArchiveMapper->find(intval($archiveSelectId));
+                    if (!empty($dematpayslipArchive)) {
+                        if (!empty($dematpayslipArchive->getPastellIdDocument())) {
+                            $this->_msgList['error'][] = $this->_l10n->t('Impossible de supprimer le bulletin de paie "' . $dematpayslipArchive->getFilePath() . '" déjà en cours d\'archivage.');;
+                        } else {
+                            $dematpayslipArchive->setStatus(DematpayslipArchive::STATUS_DELETED);
+                            $dematpayslipArchive->setStatusTime($nowDateTime->getTimestamp());
+                            $dematpayslipArchiveMapper->update($dematpayslipArchive);
+                        }
+                    }
+
+                    if (count($this->_msgList['error']) > 0) break;
+                }
+            }
+        }
+
+        return $refresh;
+    }
+    
+    /**
+     * Archive CSV
+     *
+     * @param   int         $stepStatus     Step status
+     * 
+     * @throws  Exception
+     */
+    public function archiveCsv($stepStatus) {
+        $this->_initDematFolders();
+
+        $dematpayslipArchiveMapper = new DematpayslipArchiveMapper($this->_dbConnection);
+        if ($stepStatus === -1) {
+            $dematpayslipArchiveList = $dematpayslipArchiveMapper->findAll(0);
+        } else {
+            $dematpayslipArchiveList = $dematpayslipArchiveMapper->findAllByStepStatus($stepStatus);
+        }
+
+        if (!empty($dematpayslipArchiveList)) {
+            $dateTimeNow = new DateTime('now', $this->_timeZone);
+            $csvFilePath = $this->_exportDirUserPath . DIRECTORY_SEPARATOR . $dateTimeNow->format('Y-m-d_H-i-s') . '_archive';
+            $csvFile = Filesystem::fopen($csvFilePath, 'w+');
+
+            if (!$csvFile) {
+                $errorMsg = $this->_l10n->t('Ouverture du fichier CSV.');
+                $this->_msgList['error'][] = $errorMsg;
+            }
+
+            if (count($this->_msgList['error']) <= 0) {
+                $csvDelimiter = $this->_csvDelimiter;
+                $csvEnclosure = $this->_csvEnclosure;
+
+                $csvFields = array();
+                $csvFields[] = $this->_l10n->t('Chemin');
+                $csvFields[] = $this->_l10n->t('Siret');
+                $csvFields[] = $this->_l10n->t('Matricule');
+                $csvFields[] = $this->_l10n->t('Nom');
+                $csvFields[] = $this->_l10n->t('Prénom');
+                $csvFields[] = $this->_l10n->t('Début');
+                $csvFields[] = $this->_l10n->t('Fin');
+                $csvFields[] = $this->_l10n->t('Edition');
+                $csvFields[] = $this->_l10n->t('Archive');
+                $csvFields[] = $this->_l10n->t('Dernière action');
+
+                $res = fputcsv($csvFile, $csvFields, $csvDelimiter, $csvEnclosure);
+                if (!$res) {
+                    $errorMsg = $this->_l10n->t('Ecriture des colonnes dans le fichier CSV.');
+                    $this->_msgList['error'][] = $errorMsg;
+                }
+
+                if (count($this->_msgList['error']) <= 0) {
+                    foreach ($dematpayslipArchiveList as $dematpayslipArchive) {
+                        $csvFields = array();
+                        $csvFields[] = $dematpayslipArchive->getFilePath();
+                        $csvFields[] = $dematpayslipArchive->getSiret();
+                        $csvFields[] = $dematpayslipArchive->getMatricule();
+                        $csvFields[] = $dematpayslipArchive->getLastname();
+                        $csvFields[] = $dematpayslipArchive->getFirstname();
+                        $csvFields[] = $dematpayslipArchive->getStartDate();
+                        $csvFields[] = $dematpayslipArchive->getEndDate();
+                        $csvFields[] = $dematpayslipArchive->getEditionDate();
+                        $csvFields[] = $dematpayslipArchive->getPastellIdDocument();
+                        $csvFields[] = $dematpayslipArchive->getPastellLastAction();
+
+                        $res = fputcsv($csvFile, $csvFields, $csvDelimiter, $csvEnclosure);
+                        if (!$res) {
+                            $errorMsg = $this->_l10n->t('Ecriture de la ligne dans le fichier CSV.');
+                            $this->_msgList['error'][] = $errorMsg;
+                            break;
+                        }
+                    }
+                }
+
+                $res = fclose($csvFile);
+                if (!$res) {
+                    $errorMsg = $this->_l10n->t('Fermeture du fichier CSV.');
+                    $this->_msgList['error'][] = $errorMsg;
+                }
+
+                if (count($this->_msgList['error']) <= 0) {
+                    // rename (sync files)
+                    $renamed = Filesystem::rename($csvFilePath, $csvFilePath . '.csv');
+                    $this->_msgList['success'][] = $this->_l10n->t('La liste des archives a bien été exporté au format CSV.');
+                }
+            }
+        }
+    }
+
+    /**
+     * User list
+     *
+     * @param $userEmail
+     * @return array
+     */
+    public function userList($userEmail) {
+        $userList = array();
+
+        if (!empty($userEmail)) {
+            // /!\ remove all users not available (FIX for multiple users with SAML)
+            if (DematpayslipProcess::USER_REMOVE_UNKNOWN == 1) {
+                $userList = DematpayslipProcess::_removeUnknownUser($this->_userManager->getByEmail($userEmail));
+            }
+        }
+
+        return $userList;
+    }
+
+    /**
+     * Shares (payslip user list)
+     *
+     * @param   int             $userId     User id
+     * @return  array|Entity[]
+     */
+    public function shares($userId) {
+        $dematpayslipUserList = $this->_dematpayslipUserMapper->findAllByUserId($userId);
+        $nbDematpayslipUserList = count($dematpayslipUserList);
+        if ($nbDematpayslipUserList <= 0) {
+            $this->_msgList['error'][] = $this->_l10n->t('Cet utilisateur n\'a pas encore de bulletin de paie dématérialisé.');
+        }
+
+        return $dematpayslipUserList;
+    }
 }
diff --git a/lib/Migration/Version030101Date20210809040000.php b/lib/Migration/Version030101Date20210809040000.php
new file mode 100644
index 0000000..7a4dd86
--- /dev/null
+++ b/lib/Migration/Version030101Date20210809040000.php
@@ -0,0 +1,112 @@
+<?php
+
+namespace OCA\Dematpayslip\Migration;
+
+use Closure;
+use OCP\DB\ISchemaWrapper;
+use OCP\IDBConnection;
+use OCP\Migration\SimpleMigrationStep;
+use OCP\Migration\IOutput;
+
+use OCA\Dematpayslip\Db\DematpayslipArchive;
+
+class Version030101Date20210809040000 extends SimpleMigrationStep {
+
+    /** @var IDBConnection */
+    protected $connection;
+
+    public function __construct(IDBConnection $connection) {
+        $this->connection = $connection;
+    }
+
+    /**
+     * @param IOutput $output
+     * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
+     * @param array $options
+     * @return null|ISchemaWrapper
+     */
+    public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) {
+        /** @var ISchemaWrapper $schema */
+        $schema = $schemaClosure();
+
+        $table = $schema->getTable('dematpayslip_archive');
+        $table->addColumn('email', 'string', [
+            'notnull' => false,
+            'length' => 64,
+        ]);
+        $table->addColumn('zip_city', 'string', [
+            'notnull' => false,
+            'length'  => 64,
+        ]);
+        $table->addColumn('demat_id_process', 'integer', [
+            'notnull' => true,
+            'default' => 0,
+        ]);
+        $table->addColumn('file_pages_num', 'string', [
+            'notnull' => false,
+            'default' => '',
+            'length' => 32,
+        ]);
+        $table->addColumn('operation_ask', 'string', [
+            'notnull' => false,
+            'default' => '',
+            'length' => 32,
+        ]);
+        $table->addColumn('operation_progress', 'integer', [
+            'notnull' => true,
+            'default' => 0,
+        ]);
+        $table->addColumn('error', 'integer', [
+            'notnull' => true,
+            'default' => 0,
+        ]);
+
+        $table->addIndex(['demat_id_process'], 'demat_archive_demat_id_process');
+
+        return $schema;
+    }
+
+    public function postSchemaChange(IOutput $output, \Closure $schemaClosure, array $options) {
+        $qb = $this->connection->getQueryBuilder();
+
+        $qb->update('dematpayslip_archive')
+            ->set('status', $qb->createNamedParameter(DematpayslipArchive::STATUS_ORIENTATION))
+            ->where($qb->expr()->eq('status', $qb->createNamedParameter(DematpayslipArchive::STATUS_METADATA_SENT)));
+        $qb->execute();
+
+        $qb->update('dematpayslip_archive')
+            ->set('status', $qb->createNamedParameter(DematpayslipArchive::STATUS_METADATA_SENT))
+            ->where($qb->expr()->eq('status', $qb->createNamedParameter(DematpayslipArchive::STATUS_SAE_SENT)));
+        $qb->execute();
+
+        $qb->update('dematpayslip_archive')
+            ->set('status', $qb->createNamedParameter(DematpayslipArchive::STATUS_SAE_SENT))
+            ->where($qb->expr()->eq('status', $qb->createNamedParameter(DematpayslipArchive::STATUS_FILE_SENT)));
+        $qb->execute();
+
+        $qb->update('dematpayslip_archive')
+            ->set('status', $qb->createNamedParameter(DematpayslipArchive::STATUS_FILE_SENT))
+            ->where($qb->expr()->eq('status', $qb->createNamedParameter(DematpayslipArchive::STATUS_TITLED)));
+        $qb->execute();
+
+        $qb->update('dematpayslip_archive')
+            ->set('status', $qb->createNamedParameter(DematpayslipArchive::STATUS_TITLED))
+            ->where($qb->expr()->eq('status', $qb->createNamedParameter(DematpayslipArchive::STATUS_CREATED)));
+        $qb->execute();
+
+        $qb->update('dematpayslip_archive')
+            ->set('status', $qb->createNamedParameter(DematpayslipArchive::STATUS_CREATED))
+            ->where($qb->expr()->eq('status', $qb->createNamedParameter(DematpayslipArchive::STATUS_INDEXED)));
+        $qb->execute();
+
+//        $qb->update('dematpayslip_archive')
+//            ->set('operation_ask', $qb->createNamedParameter('1+2'))
+//            ->where($qb->expr()->ge('status', $qb->createNamedParameter(DematpayslipArchive::STATUS_CREATED)));
+//        $qb->execute();
+
+        $qb->update('dematpayslip_archive')
+            ->set('operation_progress', $qb->createNamedParameter(DematpayslipArchive::OPERATION_FINISHED))
+            ->where($qb->expr()->eq('status', $qb->createNamedParameter(DematpayslipArchive::STATUS_ORIENTATION)));
+        $qb->execute();
+    }
+}
diff --git a/lib/Notification/Notifier.php b/lib/Notification/Notifier.php
new file mode 100644
index 0000000..b63258b
--- /dev/null
+++ b/lib/Notification/Notifier.php
@@ -0,0 +1,126 @@
+<?php
+/**
+ * @copyright Copyright (c) 2016 Joas Schilling <coding@schilljs.com>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\Dematpayslip\Notification;
+
+use OCP\IURLGenerator;
+use OCP\IUserManager;
+use OCP\L10N\IFactory;
+use OCP\Notification\IManager as INotificationManager;
+use OCP\Notification\INotification;
+use OCP\Notification\INotifier;
+use OCP\Notification\AlreadyProcessedException;
+
+class Notifier implements INotifier {
+
+	/** @var IFactory */
+	protected $factory;
+
+	/** @var IUserManager */
+	protected $userManager;
+
+	/** @var INotificationManager */
+	protected $notificationManager;
+
+	/** @var IURLGenerator */
+	protected $url;
+
+    const SUBJECT_ARCHIVES_PROCESSED = 'job_processed';
+
+	/**
+	 * @param IFactory $factory
+	 * @param IUserManager $userManager
+	 * @param INotificationManager $notificationManager
+	 * @param IURLGenerator $urlGenerator
+	 */
+	public function __construct(IFactory $factory, IUserManager $userManager, INotificationManager $notificationManager, IURLGenerator $urlGenerator) {
+		$this->factory = $factory;
+		$this->userManager = $userManager;
+		$this->notificationManager = $notificationManager;
+		$this->url = $urlGenerator;
+	}
+
+    /**
+     * Identifier of the notifier, only use [a-z0-9_]
+     *
+     * @return string
+     * @since 17.0.0
+     */
+    public function getID(): string {
+        return 'dematpayslip';
+    }
+
+    /**
+     * Human readable name describing the notifier
+     *
+     * @return string
+     * @since 17.0.0
+     */
+    public function getName(): string {
+        return $this->factory->get('dematpayslip')->t('Dematpayslip');
+    }
+
+    /**
+     * @param INotification $notification
+     * @param string $languageCode The code of the language that should be used to prepare the notification
+     * @return INotification
+     * @throws \InvalidArgumentException When the notification was not prepared by a notifier
+     * @throws AlreadyProcessedException When the notification is not needed anymore and should be deleted
+     * @since 9.0.0
+     */
+	public function prepare(INotification $notification, $languageCode): INotification {
+		if ($notification->getApp() !== 'dematpayslip') {
+			// Not my app => throw
+			throw new \InvalidArgumentException('Unhandled app');
+		}
+
+		switch ($notification->getSubject()) {
+			case self::SUBJECT_ARCHIVES_PROCESSED:
+				$subject = $this->getSubject($notification, $languageCode);
+				if ($subject === '') {
+					// Everything done, mark the notification as processed...
+					$this->notificationManager->markProcessed($notification);
+					throw new \InvalidArgumentException();
+				}
+
+				$notification->setParsedSubject($subject);
+                //$notification->setLink($this->url->linkToRouteAbsolute('settings.PersonalSettings.index'));
+				return $notification;
+
+			default:
+				// Unknown subject => Unknown notification => throw
+				throw new \InvalidArgumentException();
+		}
+	}
+
+	/**
+	 * @param INotification $notification
+	 * @param string $languageCode
+	 * @return string
+	 */
+	protected function getSubject(INotification $notification, $languageCode) {
+		$l = $this->factory->get('dematpayslip', $languageCode);
+		//$user = $this->userManager->get($notification->getUser());
+
+        $subjectParameters = $notification->getSubjectParameters();
+        return $l->t('Opération terminée : %s/%s bulletins de paie ont été traités.', [$subjectParameters['nb_success'], $subjectParameters['nb_total']]);
+	}
+}
diff --git a/lib/Settings/AdminSettings.php b/lib/Settings/AdminSettings.php
index 5fa4e45..8b17831 100644
--- a/lib/Settings/AdminSettings.php
+++ b/lib/Settings/AdminSettings.php
@@ -4,6 +4,7 @@ namespace OCA\Dematpayslip\Settings;
 use OCP\AppFramework\Http\TemplateResponse;
 use OCP\IConfig;
 use OCP\IDateTimeFormatter;
+use OCP\IDBConnection;
 use OCP\IL10N;
 use OCP\Share\IManager as IShareManager;
 use OCP\IUserManager;
@@ -23,14 +24,24 @@ use OCA\Pastell\Db\PastellConfigFlowMapper;
 
 class AdminSettings implements ISettings {
 
+    /**
+     * @var string App name
+     */
+    private $_appName;
+
     /** @var IConfig */
-    private $config;
+    private $_config;
+
+    /**
+     * @var IDBConnection database connection
+     */
+    private $_dbConnection;
 
     /** @var IL10N */
     private $l;
 
     /** @var IDateTimeFormatter */
-    private $dateTimeFormatter;
+    private $_dateTimeFormatter;
 
     /** @var IRootFolder */
     private $_rootFolder;
@@ -41,10 +52,8 @@ class AdminSettings implements ISettings {
     /** @var IUserManager */
     private $_userManager;
 
-    private $appName;
-
     /** @var string User Id */
-    private $userId;
+    private $_userId;
 
     /** @var DematpayslipUserMapper */
     private $_dematpayslipUserMapper;
@@ -73,12 +82,12 @@ class AdminSettings implements ISettings {
      */
     private function _assignParams() {
         // demat config
-        $this->_dematpayslipConfigList['payslip_dir']          = $this->config->getAppValue($this->appName, 'payslip_dir', 'Bulletins'); // Bulletins
-        $this->_dematpayslipConfigList['user_id']              = $this->config->getAppValue($this->appName, 'user_id', 'demat'); // demat user
-        $this->_dematpayslipConfigList['app_data_dir']         = $this->config->getAppValue($this->appName, 'app_data_dir', 'dematpayslip'); // dematpayslip directory of user demat (upload, check, report, etc)
-        $this->_dematpayslipConfigList['pastell_use']          = $this->config->getAppValue($this->appName, 'pastell_use', ''); // uses pastell
-        $this->_dematpayslipConfigList['pastell_config_f1_id'] = $this->config->getAppValue($this->appName, 'pastell_config_f1_id'); // archiving for 5 years
-        $this->_dematpayslipConfigList['pastell_config_f2_id'] = $this->config->getAppValue($this->appName, 'pastell_config_f2_id'); // archiving for 50 years
+        $this->_dematpayslipConfigList['payslip_dir']          = $this->_config->getAppValue($this->_appName, 'payslip_dir', 'Bulletins'); // Bulletins
+        $this->_dematpayslipConfigList['user_id']              = $this->_config->getAppValue($this->_appName, 'user_id', 'demat'); // demat user
+        $this->_dematpayslipConfigList['app_data_dir']         = $this->_config->getAppValue($this->_appName, 'app_data_dir', 'dematpayslip'); // dematpayslip directory of user demat (upload, check, report, etc)
+        $this->_dematpayslipConfigList['pastell_use']          = $this->_config->getAppValue($this->_appName, 'pastell_use', ''); // uses pastell
+        $this->_dematpayslipConfigList['pastell_config_f1_id'] = $this->_config->getAppValue($this->_appName, 'pastell_config_f1_id'); // archiving for 5 years
+        $this->_dematpayslipConfigList['pastell_config_f2_id'] = $this->_config->getAppValue($this->_appName, 'pastell_config_f2_id'); // archiving for 50 years
 
         // pastell config mapper
         $this->_pastellConfigFlowMapper = null;
@@ -86,7 +95,7 @@ class AdminSettings implements ISettings {
         if ($this->_pastellAppExists === true) {
             //$pastellUse = intval($this->_dematpayslipConfigList['pastell_use']);
             //if ($pastellUse === 1) {
-                $this->_pastellConfigFlowMapper = new PastellConfigFlowMapper(\OC::$server->getDatabaseConnection());
+                $this->_pastellConfigFlowMapper = new PastellConfigFlowMapper($this->_dbConnection);
                 $this->_pastellConfigFlowList = $this->_pastellConfigFlowMapper->findAll();
             //}
         }
@@ -107,14 +116,12 @@ class AdminSettings implements ISettings {
     private function _payslipShareList() {
         $payslipShareList = array();
 
-        $payslipDir    = $this->config->getAppValue($this->appName, 'payslip_dir');
-        $payslipUserId = $this->config->getAppValue($this->appName, 'user_id');
+        $payslipDir    = $this->_config->getAppValue($this->_appName, 'payslip_dir');
+        $payslipUserId = $this->_config->getAppValue($this->_appName, 'user_id');
 
-        $rootFolder   = $this->_rootFolder;
-        $shareManager = $this->_shareManager;
         $userFolder   = null;
         try {
-            $userFolder = $rootFolder->getUserFolder($payslipUserId);
+            $userFolder = $this->_rootFolder->getUserFolder($payslipUserId);
         } catch (Exception $e) {
             $this->_msgList['error'][] = $this->l->t('Utilisateur non trouvé') . ' : ' . $payslipUserId . "<br />" . $e->getMessage();
         }
@@ -122,7 +129,7 @@ class AdminSettings implements ISettings {
         if (empty($this->_msgList['error'])) {
             $payslipShareNode = $userFolder->get($payslipDir);
             if ($payslipShareNode instanceof Folder) {
-                $payslipShareList = $shareManager->getSharesInFolder($payslipUserId, $payslipShareNode);
+                $payslipShareList = $this->_shareManager->getSharesInFolder($payslipUserId, $payslipShareNode);
             }
         }
 
@@ -136,16 +143,12 @@ class AdminSettings implements ISettings {
      * @throws  \OCP\Files\NotFoundException
      */
     private function _payslipsReshare() {
-        $payslipDir    = $this->config->getAppValue($this->appName, 'payslip_dir');
-        $payslipUserId = $this->config->getAppValue($this->appName, 'user_id');
-
-        $rootFolder   = $this->_rootFolder;
-        $shareManager = $this->_shareManager;
-        $userManager  = $this->_userManager;
+        $payslipDir    = $this->_config->getAppValue($this->_appName, 'payslip_dir');
+        $payslipUserId = $this->_config->getAppValue($this->_appName, 'user_id');
 
         $userFolder = null;
         try {
-            $userFolder = $rootFolder->getUserFolder($payslipUserId);
+            $userFolder = $this->_rootFolder->getUserFolder($payslipUserId);
         } catch (Exception $e) {
             $this->_msgList['error'][] = $this->l->t('Répertoire utilisateur non trouvé') . ' : ' . $payslipUserId . "<br />" . $e->getMessage();
         }
@@ -181,18 +184,18 @@ class AdminSettings implements ISettings {
                             // s'il l'utilisateur n'a pas desactive la dematerialisation de son bulletin de paie
                             //if ($dematpayslipUser->getDisabled() != 1) {
                             // verifier que l'utilisateur existe toujours
-                            $dematpayslipUserExists = $userManager->userExists($dematpayslipUser->getUserId());
+                            $dematpayslipUserExists = $this->_userManager->userExists($dematpayslipUser->getUserId());
                             if ($dematpayslipUserExists === true) {
                                 // verifier si le dossier n'est pas deja partage
                                 if (!in_array($payslipMatriculeNode->getId(), $payslipMatriculeShareNodeIdList)) {
                                     // reshare
-                                    $payslipMatriculeShare = $shareManager->newShare();
+                                    $payslipMatriculeShare = $this->_shareManager->newShare();
                                     $payslipMatriculeShare->setNode($payslipMatriculeNode);
                                     $payslipMatriculeShare->setShareType(\OC\Share\Share::SHARE_TYPE_USER);
                                     $payslipMatriculeShare->setSharedWith($dematpayslipUser->getUserId());
                                     $payslipMatriculeShare->setPermissions(\OCP\Constants::PERMISSION_READ);
                                     $payslipMatriculeShare->setSharedBy($payslipUserId);
-                                    $payslipMatriculeShare = $shareManager->createShare($payslipMatriculeShare);
+                                    $payslipMatriculeShare = $this->_shareManager->createShare($payslipMatriculeShare);
                                 }
                             }
                             //}
@@ -216,11 +219,10 @@ class AdminSettings implements ISettings {
     private function _payslipsUnshare() {
         $payslipShareList = self::_payslipShareList();
 
-        $shareManager = $this->_shareManager;
         if (count($payslipShareList) > 0) {
             foreach ($payslipShareList as $payslipShareArr) {
                 if (is_array($payslipShareArr) && count($payslipShareArr)>=1) {
-                    $shareManager->deleteShare($payslipShareArr[0]);
+                    $this->_shareManager->deleteShare($payslipShareArr[0]);
                 }
             }
         }
@@ -233,6 +235,7 @@ class AdminSettings implements ISettings {
      * @param   IConfig                 $config                     Config
      * @param   IL10N                   $l                          Lang
      * @param   IDateTimeFormatter      $dateTimeFormatter          Date formatter
+     * @param   IDBConnection           $dbConnection               DB connection
      * @param   IRootFolder             $rootFolder                 Root folder
      * @param   IShareManager           $shareManager               Share manager
      * @param   IUserManager            $userManager                User manager
@@ -243,21 +246,23 @@ class AdminSettings implements ISettings {
                                 IConfig $config,
                                 IL10N $l,
                                 IDateTimeFormatter $dateTimeFormatter,
+                                IDBConnection $dbConnection,
                                 IRootFolder $rootFolder,
                                 IShareManager $shareManager,
                                 IUserManager $userManager,
                                 DematpayslipUserMapper $dematpayslipUserMapper,
                                 $UserId
     ) {
-        $this->appName = $AppName;
-        $this->config = $config;
+        $this->_appName = $AppName;
+        $this->_config = $config;
         $this->l = $l;
-        $this->dateTimeFormatter = $dateTimeFormatter;
+        $this->_dateTimeFormatter = $dateTimeFormatter;
+        $this->_dbConnection = $dbConnection;
         $this->_rootFolder = $rootFolder;
         $this->_shareManager = $shareManager;
         $this->_userManager = $userManager;
         $this->_dematpayslipUserMapper = $dematpayslipUserMapper;
-        $this->userId = $UserId;
+        $this->_userId = $UserId;
 
         // check if Pastell app exists
         $pastellAppDir = __DIR__ . '/../../../pastell';
@@ -280,9 +285,9 @@ class AdminSettings implements ISettings {
             $dematpayslipDir = filter_input(INPUT_GET, 'dematpayslip_payslip_dir', FILTER_SANITIZE_STRING);
             $dematpayslipUserUserId = filter_input(INPUT_GET, 'dematpayslip_user_user_id', FILTER_SANITIZE_STRING);
             $dematpayslipAppDataDir = filter_input(INPUT_GET, 'dematpayslip_app_data_dir', FILTER_SANITIZE_STRING);
-            $this->config->setAppValue($this->appName, 'payslip_dir', $dematpayslipDir);
-            $this->config->setAppValue($this->appName, 'user_id', $dematpayslipUserUserId);
-            $this->config->setAppValue($this->appName, 'app_data_dir', $dematpayslipAppDataDir);
+            $this->_config->setAppValue($this->_appName, 'payslip_dir', $dematpayslipDir);
+            $this->_config->setAppValue($this->_appName, 'user_id', $dematpayslipUserUserId);
+            $this->_config->setAppValue($this->_appName, 'app_data_dir', $dematpayslipAppDataDir);
         } elseif ($action === 'payslips_unshare') {
             $this->_payslipsUnshare();
         } elseif ($action === 'payslips_reshare') {
@@ -292,9 +297,9 @@ class AdminSettings implements ISettings {
             $pastellConfigFlow1Id = filter_input(INPUT_GET, 'pastell_config_f1_id', FILTER_SANITIZE_NUMBER_INT);
             $pastellConfigFlow2Id = filter_input(INPUT_GET, 'pastell_config_f2_id', FILTER_SANITIZE_NUMBER_INT);
 
-            $configPastellUse = $this->config->getAppValue($this->appName, 'pastell_use', '');
+            $configPastellUse = $this->_config->getAppValue($this->_appName, 'pastell_use', '');
 
-            $this->config->setAppValue($this->appName, 'pastell_use', intval($pastellUse));
+            $this->_config->setAppValue($this->_appName, 'pastell_use', intval($pastellUse));
 
             if ($pastellUse == 1 && $configPastellUse == 1) {
                 // check parameters
@@ -307,18 +312,18 @@ class AdminSettings implements ISettings {
             }
 
             if (count($this->_msgList['error']) <= 0) {
-                $pastellConfigF1Id = $this->config->getAppValue($this->appName, 'pastell_config_f1_id');
+                $pastellConfigF1Id = $this->_config->getAppValue($this->_appName, 'pastell_config_f1_id');
                 // FIX -- Pastell config flow is NULL
                 if (empty($pastellConfigF1Id)) {
-                    $this->config->deleteAppValue($this->appName,'pastell_config_f1_id');
+                    $this->_config->deleteAppValue($this->_appName,'pastell_config_f1_id');
                 }
-                $pastellConfigF2Id = $this->config->getAppValue($this->appName, 'pastell_config_f2_id');
+                $pastellConfigF2Id = $this->_config->getAppValue($this->_appName, 'pastell_config_f2_id');
                 // FIX -- Pastell config flow is NULL
                 if (empty($pastellConfigF2Id)) {
-                    $this->config->deleteAppValue($this->appName,'pastell_config_f2_id');
+                    $this->_config->deleteAppValue($this->_appName,'pastell_config_f2_id');
                 }
-                $this->config->setAppValue($this->appName, 'pastell_config_f1_id', $pastellConfigFlow1Id);
-                $this->config->setAppValue($this->appName, 'pastell_config_f2_id', $pastellConfigFlow2Id);
+                $this->_config->setAppValue($this->_appName, 'pastell_config_f1_id', $pastellConfigFlow1Id);
+                $this->_config->setAppValue($this->_appName, 'pastell_config_f2_id', $pastellConfigFlow2Id);
             }
         }
 
diff --git a/lib/Settings/PersonalSettings.php b/lib/Settings/PersonalSettings.php
index 50280cd..6737a9f 100644
--- a/lib/Settings/PersonalSettings.php
+++ b/lib/Settings/PersonalSettings.php
@@ -2,21 +2,28 @@
 namespace OCA\Dematpayslip\Settings;
 
 use OCP\AppFramework\Http\TemplateResponse;
-use OCP\Settings\ISettings;
+use OCP\IDateTimeZone;
 use OCP\IL10N;
+use OCP\Settings\ISettings;
 
 use OCA\Dematpayslip\Db\DematpayslipUserMapper;
 use OCA\Dematpayslip\Db\DematpayslipUser;
 
 class PersonalSettings implements ISettings {
 
-    private $appName;
+    /**
+     * @var string App name
+     */
+    private $_appName;
+
+    /** @var IDateTimeZone */
+    private $_dateTimeZone;
 
     /** @var IL10N */
     private $l;
 
     /** @var string User Id */
-    private $userId;
+    private $_userId;
 
     /** @var DematpayslipUserMapper*/
     private $_dematpayslipUserMapper;
@@ -47,22 +54,25 @@ class PersonalSettings implements ISettings {
      * PersonalSettings constructor.
      *
      * @param   string                  $AppName                    App name
+     * @param   IDateTimeZone           $dateTimeZone               Date time zone
      * @param   IL10N                   $l                          Lang
      * @param   DematpayslipUserMapper  $dematpayslipUserMapper     Dematpayslip user mapper
      * @param   string                  $UserId                     User Id
      */
 	public function __construct(
 	    $AppName,
+        IDateTimeZone $dateTimeZone,
         IL10N $l,
         DematpayslipUserMapper $dematpayslipUserMapper,
         $UserId
     ) {
-        $this->appName                 = $AppName;
+        $this->_appName                = $AppName;
+        $this->_dateTimeZone           = $dateTimeZone;
         $this->l                       = $l;
         $this->_dematpayslipUserMapper = $dematpayslipUserMapper;
-        $this->userId                  = $UserId;
+        $this->_userId                 = $UserId;
 
-        $dematpayslipUserList = $this->_dematpayslipUserMapper->findAllByUserId($this->userId);
+        $dematpayslipUserList = $this->_dematpayslipUserMapper->findAllByUserId($this->_userId);
         if (count($dematpayslipUserList) >= 1) {
             $this->_dematpayslipUserList = $dematpayslipUserList;
         } else {
@@ -79,7 +89,7 @@ class PersonalSettings implements ISettings {
         if ($action === 'dematpayslip_user') {
             $dematpayslipUserDisabledList = filter_input(INPUT_GET, 'dematpayslip_user_disabled', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY);
             if (count($this->_dematpayslipUserList) >= 1) {
-                $dateTimeNow = new \DateTime('now', \OC::$server->getDateTimeZone()->getTimeZone());
+                $dateTimeNow = new \DateTime('now', $this->_dateTimeZone->getTimeZone());
 
                 foreach ($this->_dematpayslipUserList as $dematpayslipUser) {
                     if (isset($dematpayslipUserDisabledList[$dematpayslipUser->getSiret()])) {
@@ -102,7 +112,7 @@ class PersonalSettings implements ISettings {
             }
         }
 
-		return new TemplateResponse($this->appName, 'settings/personal', $this->_assignParams(), '');
+		return new TemplateResponse($this->_appName, 'settings/personal', $this->_assignParams(), '');
 	}
 
 	/**
diff --git a/templates/content/agent_list.php b/templates/content/agent_list.php
index 6dbe0fd..1b5e4ef 100644
--- a/templates/content/agent_list.php
+++ b/templates/content/agent_list.php
@@ -1,11 +1,17 @@
+<?php
+    /** @var array $_ */
+    /** @var \OCP\IL10N $l */
+    /** @var \OCP\IURLGenerator $urlGenerator */
+?>
 <?php
     // assigned
+    $dateTimeZone         = (isset($_['dateTimeZone']) ? $_['dateTimeZone'] : null);
+    $urlGenerator         = $_['urlGenerator'];
+    $userManager          = (isset($_['userManager']) ? $_['userManager'] : null);
     $dematpayslipUserList = (isset($_['dematpayslipUserList']) ? $_['dematpayslipUserList'] : array());
     $exportDirUserPath    = (isset($_['exportDirUserPath']) ? $_['exportDirUserPath'] : '');
     $msgList              = (isset($_['msgList']) ? $_['msgList'] : array());
 
-    $urlGenerator = OC::$server->getURLGenerator();
-
     // alert messages
     $htmlAlert = '';
     if (!empty($msgList)) {
@@ -75,12 +81,19 @@
                                 ?>
                                 <tbody>
                                 <?php
+                                    $serverTimeZone = null;
+                                    if ($dateTimeZone !== null) {
+                                        $serverTimeZone = $dateTimeZone->getTimeZone();
+                                    }
+
                                     foreach ($dematpayslipUserList as $dematpayslipUser) {
                                         $dematpayslipUserId = $dematpayslipUser->getUserId();
                                         $dematpayslipUserDisplayName = $dematpayslipUserId;
-                                        $user = OC::$server->getUserManager()->get($dematpayslipUserId);
-                                        if ($user) {
-                                            $dematpayslipUserDisplayName = $user->getDisplayName();
+                                        if ($userManager) {
+                                            $user = $userManager->get($dematpayslipUserId);
+                                            if ($user) {
+                                                $dematpayslipUserDisplayName = $user->getDisplayName();
+                                            }
                                         }
                                         ?>
                                         <tr>
@@ -99,9 +112,9 @@
                                             </td>
                                             <td><?php
                                                 if ($dematpayslipUser->getLastmodified() != null) {
-                                                    $dateTimeLastmodified = new \DateTime('', \OC::$server->getDateTimeZone()->getTimeZone());
-                                                    $dateTimeLastmodified->setTimestamp($dematpayslipUser->getLastmodified());
-                                                    print $dateTimeLastmodified->format('d/m/Y H:i:s');
+                                                    $dateTimeLastModified = new \DateTime('', $serverTimeZone);
+                                                    $dateTimeLastModified->setTimestamp($dematpayslipUser->getLastmodified());
+                                                    print $dateTimeLastModified->format('d/m/Y H:i:s');
                                                 }
                                                 ?>
                                             </td>
diff --git a/templates/content/archive_list.php b/templates/content/archive_list.php
index 3d4b8c2..a279021 100644
--- a/templates/content/archive_list.php
+++ b/templates/content/archive_list.php
@@ -1,7 +1,11 @@
 <?php
-    $urlGenerator = OC::$server->getURLGenerator();
-
+    /** @var array $_ */
+    /** @var \OCP\IL10N $l */
+    /** @var \OCP\IURLGenerator $urlGenerator */
+?>
+<?php
     // assigned
+    $urlGenerator            = $_['urlGenerator'];
     $dematpayslipArchiveList = (isset($_['dematpayslipArchiveList']) ? $_['dematpayslipArchiveList'] : array());
     $exportDirUserPath       = (isset($_['exportDirUserPath']) ? $_['exportDirUserPath'] : '');
     $msgList                 = (isset($_['msgList']) ? $_['msgList'] : array());
@@ -49,7 +53,7 @@
         <?php if (!empty($htmlAlert)) { ?>
             <div id="dematpayslip_alert"><?php print $htmlAlert; ?></div>
         <?php } ?>
-        <h2><?php p($l->t('Liste des archives')); ?> &nbsp;<a href="<?php print $urlGenerator->linkToRoute('dematpayslip.page.archive_csv', $paramList); ?>" class="button" title="<?php p($l->t('Export CSV')); ?>"><?php p($l->t('CSV')); ?></a></h2>
+        <h2><?php p($l->t('Liste des bulletins')); ?> &nbsp;<a href="<?php print $urlGenerator->linkToRoute('dematpayslip.page.archive_csv', $paramList); ?>" class="button" title="<?php p($l->t('Export CSV')); ?>"><?php p($l->t('CSV')); ?></a></h2>
         <br />
 
         <div>
@@ -76,7 +80,10 @@
                         <th scope="col"><?php p($l->t('Fin')); ?></th>
                         <th scope="col"><?php p($l->t('Edition')); ?></th>
                         <th scope="col"><?php p($l->t('Archive')); ?></th>
+                        <th scope="col"><?php p($l->t('Opérations demandées')); ?></th>
+                        <th scope="col"><?php p($l->t('Opération en cours')); ?></th>
                         <th scope="col"><?php p($l->t('Etat')); ?></th>
+                        <th scope="col"><?php p($l->t('Erreur')); ?></th>
                     </tr>
                     </thead>
                     <?php if (!empty($dematpayslipArchiveList)) { ?>
@@ -93,7 +100,10 @@
                                 <td><?php print $dematpayslipArchive->getEndDate(); ?></td>
                                 <td><?php print $dematpayslipArchive->getEditionDate(); ?></td>
                                 <td><?php if (!empty($dematpayslipArchive->getPastellUrl())) { print $dematpayslipArchive->getPastellUrl(); } else { print $dematpayslipArchive->getPastellIdDocument(); } ?></td>
+                                <td><?php print  $dematpayslipArchive->showOperationAskLabel(); ?></td>
+                                <td><?php print  $dematpayslipArchive->showOperationProgressLabel(); ?></td>
                                 <td><?php print  $dematpayslipArchive->showStatusLabel(); ?></td>
+                                <td><?php print  $dematpayslipArchive->getError(); ?></td>
                             </tr>
                         <?php } ?>
                     </tbody>
diff --git a/templates/content/index.php b/templates/content/index.php
index 77c9dce..fc0107a 100644
--- a/templates/content/index.php
+++ b/templates/content/index.php
@@ -1,7 +1,11 @@
 <?php
-    $urlGenerator = OC::$server->getURLGenerator();
-
+    /** @var array $_ */
+    /** @var \OCP\IL10N $l */
+    /** @var \OCP\IURLGenerator $urlGenerator */
+?>
+<?php
     // assigned
+    $urlGenerator           = $_['urlGenerator'];
     $canCancelProcess       = (isset($_['canCancelProcess']) ? $_['canCancelProcess'] : false);
     $msgList                = (isset($_['msgList']) ? $_['msgList'] : array());
     $processArr             = (isset($_['processArr']) ? $_['processArr'] : array());
diff --git a/templates/content/shares.php b/templates/content/shares.php
index f275de5..882cbd3 100644
--- a/templates/content/shares.php
+++ b/templates/content/shares.php
@@ -1,7 +1,11 @@
 <?php
-    $urlGenerator = OC::$server->getURLGenerator();
-
+    /** @var array $_ */
+    /** @var \OCP\IL10N $l */
+    /** @var \OCP\IURLGenerator $urlGenerator */
+?>
+<?php
     // assigned
+    $urlGenerator         = $_['urlGenerator'];
     $dematpayslipUserList = (isset($_['dematpayslipUserList']) ? $_['dematpayslipUserList'] : array());
     $msgList              = (isset($_['msgList']) ? $_['msgList'] : array());
 
diff --git a/templates/content/user_list.php b/templates/content/user_list.php
index 87119e1..c507eae 100644
--- a/templates/content/user_list.php
+++ b/templates/content/user_list.php
@@ -1,10 +1,14 @@
 <?php
-    $urlGenerator = OC::$server->getURLGenerator();
-
+    /** @var array $_ */
+    /** @var \OCP\IL10N $l */
+    /** @var \OCP\IURLGenerator $urlGenerator */
+?>
+<?php
     // assigned
-    $msgList = (isset($_['msgList']) ? $_['msgList'] : array());
-    $searchList = (isset($_['searchList']) ? $_['searchList'] : array());
-    $userList = (isset($_['userList']) ? $_['userList'] : array());
+    $urlGenerator = $_['urlGenerator'];
+    $msgList      = (isset($_['msgList']) ? $_['msgList'] : array());
+    $searchList   = (isset($_['searchList']) ? $_['searchList'] : array());
+    $userList     = (isset($_['userList']) ? $_['userList'] : array());
 
     // alert messages
     $htmlAlert = '';
diff --git a/templates/navigation/index.php b/templates/navigation/index.php
index 0215fa5..c667a6a 100644
--- a/templates/navigation/index.php
+++ b/templates/navigation/index.php
@@ -1,6 +1,11 @@
 <?php
-    $urlGenerator = OC::$server->getURLGenerator();
-
+    /** @var array $_ */
+    /** @var \OCP\IL10N $l */
+    /** @var \OCP\IURLGenerator $urlGenerator */
+?>
+<?php
+    // assigned
+    $urlGenerator     = $_['urlGenerator'];
     $pastellAppExists = (isset($_['pastellAppExists']) ? $_['pastellAppExists'] : false);
 ?>
 <ul>
@@ -10,9 +15,9 @@
     <li><a href="<?php echo $urlGenerator->linkToRoute('dematpayslip.page.archive_list'); ?>">Liste des bulletins</a></li>
     <li>
         <ul>
-            <li><a href="<?php echo $urlGenerator->linkToRoute('dematpayslip.page.archive_list', ['step_status' => \OCA\Dematpayslip\Db\DematpayslipArchive::STEP_STATUS_INIT]); ?>">A archiver</a></li>
+            <li><a href="<?php echo $urlGenerator->linkToRoute('dematpayslip.page.archive_list', ['step_status' => \OCA\Dematpayslip\Db\DematpayslipArchive::STEP_STATUS_TO_DO]); ?>">A traiter</a></li>
             <li><a href="<?php echo $urlGenerator->linkToRoute('dematpayslip.page.archive_list', ['step_status' => \OCA\Dematpayslip\Db\DematpayslipArchive::STEP_STATUS_PROGRESS]); ?>">En cours</a></li>
-            <li><a href="<?php echo $urlGenerator->linkToRoute('dematpayslip.page.archive_list', ['step_status' => \OCA\Dematpayslip\Db\DematpayslipArchive::STEP_STATUS_ARCHIVED]); ?>">Archivés</a></li>
+            <li><a href="<?php echo $urlGenerator->linkToRoute('dematpayslip.page.archive_list', ['step_status' => \OCA\Dematpayslip\Db\DematpayslipArchive::STEP_STATUS_FINISHED]); ?>">Traités</a></li>
         </ul>
     </li>
     <?php } ?>
diff --git a/templates/navigation/shares.php b/templates/navigation/shares.php
index 334faa8..9b10a80 100644
--- a/templates/navigation/shares.php
+++ b/templates/navigation/shares.php
@@ -1,5 +1,11 @@
 <?php
-    $urlGenerator = OC::$server->getURLGenerator();
+    /** @var array $_ */
+    /** @var \OCP\IL10N $l */
+    /** @var \OCP\IURLGenerator $urlGenerator */
+?>
+<?php
+    // assigned
+    $urlGenerator = $_['urlGenerator'];
 ?>
 <ul>
 	<li><a href="<?php echo $urlGenerator->linkToRoute('dematpayslip.page.shares'); ?>">Dématérialisation</a></li>
diff --git a/templates/settings/admin.php b/templates/settings/admin.php
index 3f09b31..97e89fe 100644
--- a/templates/settings/admin.php
+++ b/templates/settings/admin.php
@@ -1,50 +1,52 @@
 <?php
+    /** @var array $_ */
+    /** @var \OCP\IL10N $l */
+?>
+<?php
+    // assigned
+    $msgList                = (isset($_['msgList']) ? $_['msgList'] : array());
+    $dematpayslipConfigList = (isset($_['dematpayslipConfigList']) ? $_['dematpayslipConfigList'] : array());
+    $pastellConfigFlowList  = (isset($_['pastellConfigFlowList']) ? $_['pastellConfigFlowList'] : array());
 
-// assigned
-$msgList                = (isset($_['msgList']) ? $_['msgList'] : array());
-$dematpayslipConfigList = (isset($_['dematpayslipConfigList']) ? $_['dematpayslipConfigList'] : array());
-$pastellConfigFlowList  = (isset($_['pastellConfigFlowList']) ? $_['pastellConfigFlowList'] : array());
-
-// alert messages
-$htmlAlert = '';
-if (!empty($msgList)) {
-    if (count($msgList['error'])>0) {
-        $htmlAlert .= '<div class="alert alert-danger alert-dismissible fade show" id="dematpayslip_alert_danger" role="alert">';
-        foreach ($msgList['error'] as $msg) {
-            $htmlAlert .= '<div class="text-center">' .  $msg . '</div>';
+    // alert messages
+    $htmlAlert = '';
+    if (!empty($msgList)) {
+        if (count($msgList['error'])>0) {
+            $htmlAlert .= '<div class="alert alert-danger alert-dismissible fade show" id="dematpayslip_alert_danger" role="alert">';
+            foreach ($msgList['error'] as $msg) {
+                $htmlAlert .= '<div class="text-center">' .  $msg . '</div>';
+            }
+            $htmlAlert .= '<a class="close" id="dematpayslip_alert_danger_btn">';
+            $htmlAlert .= '<span aria-hidden="true">&times;</span>';
+            $htmlAlert .= '</a>';
+            $htmlAlert .= '</div>';
         }
-        $htmlAlert .= '<a class="close" id="dematpayslip_alert_danger_btn">';
-        $htmlAlert .= '<span aria-hidden="true">&times;</span>';
-        $htmlAlert .= '</a>';
-        $htmlAlert .= '</div>';
-    }
 
-    if (count($msgList['warning'])>0) {
-        $htmlAlert .= '<div class="alert alert-warning alert-dismissible fade show" id="dematpayslip_alert_warning" role="alert">';
-        foreach ($msgList['warning'] as $msg) {
-            $htmlAlert .= '<div class="text-center">' .  $msg . '</div>';
+        if (count($msgList['warning'])>0) {
+            $htmlAlert .= '<div class="alert alert-warning alert-dismissible fade show" id="dematpayslip_alert_warning" role="alert">';
+            foreach ($msgList['warning'] as $msg) {
+                $htmlAlert .= '<div class="text-center">' .  $msg . '</div>';
+            }
+            $htmlAlert .= '<a class="close" id="dematpayslip_alert_warning_btn">';
+            $htmlAlert .= '<span aria-hidden="true">&times;</span>';
+            $htmlAlert .= '</a>';
+            $htmlAlert .= '</div>';
         }
-        $htmlAlert .= '<a class="close" id="dematpayslip_alert_warning_btn">';
-        $htmlAlert .= '<span aria-hidden="true">&times;</span>';
-        $htmlAlert .= '</a>';
-        $htmlAlert .= '</div>';
-    }
 
-    if (count($msgList['success'])>0) {
-        $htmlAlert .= '<div class="alert alert-success alert-dismissible fade show" id="dematpayslip_alert_success" role="alert">';
-        foreach ($msgList['success'] as $msg) {
-            $htmlAlert .= '<div class="text-center">' .  $msg . '</div>';
+        if (count($msgList['success'])>0) {
+            $htmlAlert .= '<div class="alert alert-success alert-dismissible fade show" id="dematpayslip_alert_success" role="alert">';
+            foreach ($msgList['success'] as $msg) {
+                $htmlAlert .= '<div class="text-center">' .  $msg . '</div>';
+            }
+            $htmlAlert .= '<a class="close" id="dematpayslip_alert_success_btn">';
+            $htmlAlert .= '<span aria-hidden="true">&times;</span>';
+            $htmlAlert .= '</a>';
+            $htmlAlert .= '</div>';
         }
-        $htmlAlert .= '<a class="close" id="dematpayslip_alert_success_btn">';
-        $htmlAlert .= '<span aria-hidden="true">&times;</span>';
-        $htmlAlert .= '</a>';
-        $htmlAlert .= '</div>';
     }
-}
-
-style('dematpayslip', 'admin');
-script('dematpayslip', 'admin');
 
+    style('dematpayslip', 'admin');
+    script('dematpayslip', 'admin');
 ?>
 <div id="dematpayslip">
     <?php if (!empty($htmlAlert)) { ?>
diff --git a/templates/settings/index.php b/templates/settings/index.php
index 3668755..febf321 100644
--- a/templates/settings/index.php
+++ b/templates/settings/index.php
@@ -1,5 +1,11 @@
 <?php
-    $urlGenerator = OC::$server->getURLGenerator();
+    /** @var array $_ */
+    /** @var \OCP\IL10N $l */
+    /** @var \OCP\IURLGenerator $urlGenerator */
+?>
+<?php
+    // assigned
+    $urlGenerator = $_['urlGenerator'];
 ?>
 <div id="app-settings">
 	<div id="app-settings-header">
diff --git a/templates/settings/personal.php b/templates/settings/personal.php
index 4db90cf..a0a3582 100644
--- a/templates/settings/personal.php
+++ b/templates/settings/personal.php
@@ -1,50 +1,51 @@
 <?php
+    /** @var array $_ */
+    /** @var \OCP\IL10N $l */
+?>
+<?php
+    // assigned
+    $dematpayslipUserList = (isset($_['dematpayslipUserList']) ? $_['dematpayslipUserList'] : array());
+    $msgList              = (isset($_['msgList']) ? $_['msgList'] : array());
 
-// assigned
-$dematpayslipUserList = (isset($_['dematpayslipUserList']) ? $_['dematpayslipUserList'] : array());
-$msgList              = (isset($_['msgList']) ? $_['msgList'] : array());
-
-// alert messages
-$htmlAlert = '';
-if (!empty($msgList)) {
-    if (count($msgList['error'])>0) {
-        $htmlAlert .= '<div class="alert alert-danger alert-dismissible fade show" id="dematpayslip_alert_danger" role="alert">';
-        foreach ($msgList['error'] as $msg) {
-            $htmlAlert .= '<div class="text-center">' .  $msg . '</div>';
+    // alert messages
+    $htmlAlert = '';
+    if (!empty($msgList)) {
+        if (count($msgList['error'])>0) {
+            $htmlAlert .= '<div class="alert alert-danger alert-dismissible fade show" id="dematpayslip_alert_danger" role="alert">';
+            foreach ($msgList['error'] as $msg) {
+                $htmlAlert .= '<div class="text-center">' .  $msg . '</div>';
+            }
+            $htmlAlert .= '<a class="close" id="dematpayslip_alert_danger_btn">';
+            $htmlAlert .= '<span aria-hidden="true">&times;</span>';
+            $htmlAlert .= '</a>';
+            $htmlAlert .= '</div>';
         }
-        $htmlAlert .= '<a class="close" id="dematpayslip_alert_danger_btn">';
-        $htmlAlert .= '<span aria-hidden="true">&times;</span>';
-        $htmlAlert .= '</a>';
-        $htmlAlert .= '</div>';
-    }
 
-    if (count($msgList['warning'])>0) {
-        $htmlAlert .= '<div class="alert alert-warning alert-dismissible fade show" id="dematpayslip_alert_warning" role="alert">';
-        foreach ($msgList['warning'] as $msg) {
-            $htmlAlert .= '<div class="text-center">' .  $msg . '</div>';
+        if (count($msgList['warning'])>0) {
+            $htmlAlert .= '<div class="alert alert-warning alert-dismissible fade show" id="dematpayslip_alert_warning" role="alert">';
+            foreach ($msgList['warning'] as $msg) {
+                $htmlAlert .= '<div class="text-center">' .  $msg . '</div>';
+            }
+            $htmlAlert .= '<a class="close" id="dematpayslip_alert_warning_btn">';
+            $htmlAlert .= '<span aria-hidden="true">&times;</span>';
+            $htmlAlert .= '</a>';
+            $htmlAlert .= '</div>';
         }
-        $htmlAlert .= '<a class="close" id="dematpayslip_alert_warning_btn">';
-        $htmlAlert .= '<span aria-hidden="true">&times;</span>';
-        $htmlAlert .= '</a>';
-        $htmlAlert .= '</div>';
-    }
 
-    if (count($msgList['success'])>0) {
-        $htmlAlert .= '<div class="alert alert-success alert-dismissible fade show" id="dematpayslip_alert_success" role="alert">';
-        foreach ($msgList['success'] as $msg) {
-            $htmlAlert .= '<div class="text-center">' .  $msg . '</div>';
+        if (count($msgList['success'])>0) {
+            $htmlAlert .= '<div class="alert alert-success alert-dismissible fade show" id="dematpayslip_alert_success" role="alert">';
+            foreach ($msgList['success'] as $msg) {
+                $htmlAlert .= '<div class="text-center">' .  $msg . '</div>';
+            }
+            $htmlAlert .= '<a class="close" id="dematpayslip_alert_success_btn">';
+            $htmlAlert .= '<span aria-hidden="true">&times;</span>';
+            $htmlAlert .= '</a>';
+            $htmlAlert .= '</div>';
         }
-        $htmlAlert .= '<a class="close" id="dematpayslip_alert_success_btn">';
-        $htmlAlert .= '<span aria-hidden="true">&times;</span>';
-        $htmlAlert .= '</a>';
-        $htmlAlert .= '</div>';
     }
-}
-
-
-style('dematpayslip', 'personal');
-script('dematpayslip', 'personal');
 
+    style('dematpayslip', 'personal');
+    script('dematpayslip', 'personal');
 ?>
 <div id="dematpayslip" class="section">
     <h2><?php p($l->t('Dématérialisation des bulletins de paie')); ?></h2>
-- 
GitLab